From ab4e151f846a88fffb5285fe4cda6288f464e38d Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Sat, 21 Sep 2013 13:19:35 +0530 Subject: [PATCH 1/4] add notes everywhere --- itf/app/models.py | 46 +++++++++++-------- itf/itfprofiles/views.py | 2 +- itf/scriptbank/models.py | 3 +- itf/templates/modules/events/event.html | 2 +- .../modules/itfprofiles/production.html | 2 +- itf/templates/modules/scriptbank/script.html | 34 +------------- 6 files changed, 33 insertions(+), 56 deletions(-) diff --git a/itf/app/models.py b/itf/app/models.py index 5c3b38c..dbd418c 100755 --- a/itf/app/models.py +++ b/itf/app/models.py @@ -24,7 +24,7 @@ def splitSearch(string): def get_real_ctype(module_name): for c in ContentType.objects.filter(model=module_name): try: - if c.model_class().is_itf_model == True: + if c.model_class() is not None: return c except: pass @@ -80,6 +80,7 @@ class ItfModel(models.Model): def add_note(self, user, text): + from itfprofiles.models import Note if self.user_has_perms(user): n = Note(user=user, text=text, content_object=self) n.save() @@ -113,7 +114,7 @@ class ItfModel(models.Model): # d['add_form'] = self.__class__.get_add_form() d['forms'] = self.__class__.get_forms() d['obj'] = self - d['content_type'] = ContentType.objects.filter(model=self.__class__._meta.module_name)[0] + d['content_type'] = self.get_content_type() try: edit_url = self.get_edit_url() d['edit_url'] = edit_url @@ -122,6 +123,11 @@ class ItfModel(models.Model): pass return d + def get_content_type(self): + for c in ContentType.objects.filter(model=self.__class__._meta.module_name): + if c.model_class() is not None: + return c + raise def get_gallery_image(self): from mediagallery.models import Photo @@ -246,34 +252,36 @@ class ItfModel(models.Model): Get the main image thumbnail for this object - checks if object has either a field or custom method called 'main_image', then checks for default_images on the ModelExtra for this model. ''' def get_main_image(self, size="142x150"): + if hasattr(self, 'main_image'): - main_image_getter = self.main_image - if type(main_image_getter).__name__ == 'instancemethod': - imgfield = main_image_getter() - else: - imgfield = main_image_getter + main_image_getter = self.main_image + if type(main_image_getter).__name__ == 'instancemethod': + imgfield = main_image_getter() + else: + imgfield = main_image_getter else: imgfield = self.get_modelextra().default_image #FIXME!! - if imgfield is None or imgfield.name == '': + if imgfield is None or imgfield.name == '' and self.get_modelextra(): imgfield = self.get_modelextra().default_image if imgfield: - #try: - thumb = get_thumbnail(imgfield, size, crop="center").url - #except: - # print imgfield.url - # thumb = 'http://placehold.it/%s' % size + try: + thumb = get_thumbnail(imgfield, size, crop="center").url + except: + thumb = self.get_placeholder(size) + else: - thumb = 'http://placehold.it/%s' % size # Add default image for site + thumb = self.get_placeholder(size) # Add default image for site + return { - 'thumb': thumb + 'thumb': thumb } - ''' - def main_image(self): - return None - ''' + + def get_placeholder(self, size): + return 'http://placehold.it/%s' % size + ''' The templates for objects are stored following the convention templates/modules//.html diff --git a/itf/itfprofiles/views.py b/itf/itfprofiles/views.py index 018eea0..ca25a35 100644 --- a/itf/itfprofiles/views.py +++ b/itf/itfprofiles/views.py @@ -183,7 +183,7 @@ def contact_group(request): send_mail("Contact on theatreforum.in", message, frm, [to_email]) return HttpResponse("Your message has been sent, thanks.") - +@csrf_exempt def add_note(request, content_type, object_id): model_class = ContentType.objects.get(pk=content_type).model_class() obj = model_class.objects.get(pk=object_id) diff --git a/itf/scriptbank/models.py b/itf/scriptbank/models.py index 5721153..378dc70 100755 --- a/itf/scriptbank/models.py +++ b/itf/scriptbank/models.py @@ -4,7 +4,7 @@ from tagging.fields import TagField from django.core.paginator import Paginator, InvalidPage, EmptyPage from django.contrib.contenttypes import generic from app.models import ItfModel -from itfprofiles.models import TheatreGroup +from itfprofiles.models import TheatreGroup, Note from mediagallery.models import GalleryAlbum GENRES = ( @@ -47,6 +47,7 @@ class Script(ItfModel): theatre_group = models.ForeignKey(TheatreGroup, help_text="Theatre Group, if any") related_scripts = models.ManyToManyField("Script", through="ScriptScript", related_name='related_script') galleries = generic.GenericRelation(GalleryAlbum) + notes = generic.GenericRelation(Note) # add_form = 'ScriptForm' #Meta diff --git a/itf/templates/modules/events/event.html b/itf/templates/modules/events/event.html index 416ef3a..6dab660 100644 --- a/itf/templates/modules/events/event.html +++ b/itf/templates/modules/events/event.html @@ -167,7 +167,7 @@ $(function() {
-

Kindly refer to notes in script archive. But instead of Posted by Name, Date, Time, make it - date, time

+ {% include 'includes/notes.html' %}
diff --git a/itf/templates/modules/itfprofiles/production.html b/itf/templates/modules/itfprofiles/production.html index d362657..f5cf3a1 100644 --- a/itf/templates/modules/itfprofiles/production.html +++ b/itf/templates/modules/itfprofiles/production.html @@ -215,7 +215,7 @@ $(function() {
-

Kindly refer to notes in script archive. But instead of Posted by Name, Date, Time, make it - date, time

+ {% include 'includes/notes.html' %}
diff --git a/itf/templates/modules/scriptbank/script.html b/itf/templates/modules/scriptbank/script.html index 86a0d02..064ee03 100755 --- a/itf/templates/modules/scriptbank/script.html +++ b/itf/templates/modules/scriptbank/script.html @@ -181,39 +181,7 @@ $(function() {
- -
-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, - quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit - esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis - dolore te feugait nulla facilisi.

- -
- -
-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, - quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit - esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis - dolore te feugait nulla facilisi.

- -
- -
-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, - quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit - esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis - dolore te feugait nulla facilisi.

- -
- -
-

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, - quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit - esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis - dolore te feugait nulla facilisi.

- -
- + {% include 'includes/notes.html' %}
From 13e307ec5cd1927fe74d8719eb6b40b516d62f22 Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Sat, 21 Sep 2013 14:33:53 +0530 Subject: [PATCH 2/4] if statement for notes; display workshops / events in group template --- itf/itfprofiles/models.py | 3 + itf/templates/modules/events/event.html | 2 + .../modules/itfprofiles/production.html | 2 + .../modules/itfprofiles/theatregroup.html | 131 ++++++++---------- itf/templates/modules/scriptbank/script.html | 2 + 5 files changed, 65 insertions(+), 75 deletions(-) diff --git a/itf/itfprofiles/models.py b/itf/itfprofiles/models.py index 3f4fde2..d370218 100644 --- a/itf/itfprofiles/models.py +++ b/itf/itfprofiles/models.py @@ -366,6 +366,7 @@ class TheatreGroup(ItfModel): return False def get_dict(self): + return { #'object':self, 'name': self.name, @@ -383,6 +384,8 @@ class TheatreGroup(ItfModel): 'resources': [obj for obj in self.resources.all()], 'buzzitems': [obj for obj in self.buzzitems.all()], 'productions': [obj for obj in self.production_set.all() ], + 'workshops': [obj for obj in self.event_set.filter(event_type='workshop')], + 'other_events': [obj for obj in self.event_set.exclude(event_type='workshop')], 'scripts': [obj for obj in self.script_set.all() ], 'people' : [obj for obj in self.persongroup_set.all() ], 'worked_with_people': self.worked_with_people() diff --git a/itf/templates/modules/events/event.html b/itf/templates/modules/events/event.html index 6dab660..cadd744 100644 --- a/itf/templates/modules/events/event.html +++ b/itf/templates/modules/events/event.html @@ -22,7 +22,9 @@ $(function() {
  • Gallery
  • {% endif %}
  • Buzz
  • + {% if user_has_perms or notes %}
  • Notes
  • + {% endif %}
  • Contact
  • diff --git a/itf/templates/modules/itfprofiles/production.html b/itf/templates/modules/itfprofiles/production.html index f5cf3a1..58b985a 100644 --- a/itf/templates/modules/itfprofiles/production.html +++ b/itf/templates/modules/itfprofiles/production.html @@ -15,7 +15,9 @@ $(function() {
  • Cast and Crew
  • Gallery
  • Buzz
  • + {% if user_has_perms or notes %}
  • Notes
  • + {% endif %} {% if shows %} diff --git a/itf/templates/modules/itfprofiles/theatregroup.html b/itf/templates/modules/itfprofiles/theatregroup.html index 430c13f..83bde64 100644 --- a/itf/templates/modules/itfprofiles/theatregroup.html +++ b/itf/templates/modules/itfprofiles/theatregroup.html @@ -7,7 +7,9 @@
  • Plays & more
  • Gallery
  • {% if resources %}
  • Resources
  • {% endif %} + {% if user_has_perms or notes %}
  • Notes
  • + {% endif %}
    @@ -174,6 +176,7 @@
    + {% if productions %}

    Plays & more

    {% for p in productions %} @@ -182,87 +185,65 @@ {{ p.name }}
    + +
    + +
    + {% endfor %} + {% endif %} + + {% if workshops %} +

    Workshops

    + + {% for w in workshops %} +
    +
    + +
    +
    -
    {{ p.name }} {% if p.debut_date %} {{ debut_date|date:"Y" }} {% endif %}
    - - + +
    {{ w.oneliner }}
    +
    +
    + +
    + {% endfor %} + + {% endif %} + {% if other_events %} +

    Other Events

    + + {% for o in other_events %} +
    +
    + {{ o.title }} +
    + +
    + +
    {{ o.oneliner }}
    +
    {% endfor %} - - - -

    Workshops (not implemented)

    - -
    -
    - /static/images/150x150.jpg -
    - -
    -
    Name of workshops
    -
    One line desc
    -
    Current
    -
    -
    - -
    - -
    -
    - /static/images/150x150.jpg -
    - -
    -
    Name of workshops
    -
    One line desc
    -
    -
    - -
    - -
    - - More>> - -
    - - -

    More

    - -
    -
    - /static/images/150x150.jpg -
    - -
    -
    Name of activity (talk, whatever)
    -
    One line desc
    -
    Current
    -
    -
    - -
    - -
    -
    - /static/images/150x150.jpg -
    - -
    -
    Name of activity (talk, whatever)
    -
    One line desc
    -
    Current
    -
    -
    - -
    - + {% endif %} + ]]> + + + option + select + + + 1 + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/cssQuery-p.js b/itf/static/js/html5Forms.js/shared/js/cssQuery-p.js new file mode 100644 index 0000000..4a7eb88 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/cssQuery-p.js @@ -0,0 +1,6 @@ +/* + cssQuery, version 2.0.2 (2005-08-19) + Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/) + License: http://creativecommons.org/licenses/LGPL/2.1/ +*/ +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 x=6(){7 1D="2.0.2";7 C=/\\s*,\\s*/;7 x=6(s,A){33{7 m=[];7 u=1z.32.2c&&!A;7 b=(A)?(A.31==22)?A:[A]:[1g];7 1E=18(s).1l(C),i;9(i=0;i<1E.y;i++){s=1y(1E[i]);8(U&&s.Z(0,3).2b("")==" *#"){s=s.Z(2);A=24([],b,s[1])}1A A=b;7 j=0,t,f,a,c="";H(j+~]/;7 20=/[\\s#.:>+~()@]|[^\\s#.:>+~()@]+/g;6 1y(s){8(S.l(s))s=" "+s;5 s.P(20)||[]};7 W=/\\s*([\\s>+~(),]|^|$)\\s*/g;7 I=/([\\s>+~,]|[^(]\\+|^)([#.:@])/g;7 18=6(s){5 s.O(W,"$1").O(I,"$1*$2")};7 1u={1Z:6(){5"\'"},P:/^(\'[^\']*\')|("[^"]*")$/,l:6(s){5 o.P.l(s)},1S:6(s){5 o.l(s)?s:o+s+o},1Y:6(s){5 o.l(s)?s.Z(1,-1):s}};7 1s=6(t){5 1u.1Y(t)};7 E=/([\\/()[\\]?{}|*+-])/g;6 R(s){5 s.O(E,"\\\\$1")};x.15("1j-2H",6(){D[">"]=6(r,f,t,n){7 e,i,j;9(i=0;i=c);5(c%m)==s}});x.15("1j-2m",6(){U=1i("L;/*@2l@8(@\\2k)U=K@2j@*/");8(!U){X=6(e,t,n){5 n?e.2i("*",t):e.X(t)};14=6(e,n){5!n||(n=="*")||(e.2h==n)};1h=1g.1I?6(e){5/1J/i.l(Q(e).1I)}:6(e){5 Q(e).1H.1f!="2g"};1e=6(e){5 e.2f||e.1G||1b(e)};6 1b(e){7 t="",n,i;9(i=0;(n=e.1F[i]);i++){1d(n.1c){F 11:F 1:t+=1b(n);1a;F 3:t+=n.2e;1a}}5 t}}});19=K;5 x}();',62,190,'|||||return|function|var|if|for||||||||pseudoClasses||||test|||this||AttributeSelector|||||||cssQuery|length|push|fr|id||selectors||case|nextElementSibling|while||tests|true|false|thisElement||replace|match|getDocument|regEscape||attributeSelectors|isMSIE|cache||getElementsByTagName|isNaN|slice|child||new|getAttribute|compareNamespace|addModule|previousElementSibling|compareTagName|parseSelector|loaded|break|_0|nodeType|switch|getTextContent|tagName|document|isXML|eval|css|_1|split|ch|parentNode|childElements|nthChild|disabled|firstElementChild|getText|RegExp|Quote|x22|PREFIX|lang|_2|arguments|else|all|links|version|se|childNodes|innerText|documentElement|contentType|xml|parseInt|indeterminate|checked|last|nth|lastElementChild|parse|_3|add|href|String|className|create|NS_IE|remove|toString|ST|select|Array|null|_4|mimeType|lastChild|firstChild|continue|modules|delete|join|caching|error|nodeValue|textContent|HTML|prefix|getElementsByTagNameNS|end|x5fwin32|cc_on|standard||odd|even|enabled|hash|location|target|not|only|empty|root|contains|level3|outerHTML|htmlFor|class|toLowerCase|Function|name|first|level2|prototype|item|scopeName|toUpperCase|ownerDocument|Document|XML|Boolean|URL|unknown|typeof|nextSibling|previousSibling|visited|link|valueOf|clearCache|catch|concat|constructor|callee|try'.split('|'),0,{})) diff --git a/itf/static/js/html5Forms.js/shared/js/frequency-decoder.com/slider.js b/itf/static/js/html5Forms.js/shared/js/frequency-decoder.com/slider.js new file mode 100644 index 0000000..fb1f129 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/frequency-decoder.com/slider.js @@ -0,0 +1,797 @@ +/* + Unobtrusive Slider Control by frequency decoder v2.6 (http://www.frequency-decoder.com/) + + Released under a creative commons Attribution-Share Alike 3.0 Unported license (http://creativecommons.org/licenses/by-sa/3.0/) + + You are free: + + * to copy, distribute, display, and perform the work + * to make derivative works + * to make commercial use of the work + + Under the following conditions: + + by Attribution. + -------------- + You must attribute the work in the manner specified by the author or licensor. + + sa + -- + Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. + + * For any reuse or distribution, you must make clear to others the license terms of this work. + * Any of these conditions can be waived if you get permission from the copyright holder. +*/ + +var fdSliderController = (function() { + var sliders = {}, + uniqueid = 0, + mouseWheelEnabled = true; + + var removeMouseWheelSupport = function() { + mouseWheelEnabled = false; + }; + var addEvent = function(obj, type, fn) { + if( obj.attachEvent ) { + obj["e"+type+fn] = fn; + obj[type+fn] = function(){obj["e"+type+fn]( window.event );}; + obj.attachEvent( "on"+type, obj[type+fn] ); + } else { obj.addEventListener( type, fn, true ); } + }; + var removeEvent = function(obj, type, fn) { + if( obj.detachEvent ) { + try { + obj.detachEvent( "on"+type, obj[type+fn] ); + obj[type+fn] = null; + } catch(err) { }; + } else { obj.removeEventListener( type, fn, true ); } + }; + var stopEvent = function(e) { + if(e == null) e = document.parentWindow.event; + if(e.stopPropagation) { + e.stopPropagation(); + e.preventDefault(); + }; + + /*@cc_on@*/ + /*@if(@_win32) + e.cancelBubble = true; + e.returnValue = false; + /*@end@*/ + + return false; + }; + var joinNodeLists = function() { + if(!arguments.length) { return []; }; + var nodeList = []; + for (var i = 0; i < arguments.length; i++) { + for (var j = 0, item; item = arguments[i][j]; j++) { nodeList[nodeList.length] = item; }; + }; + return nodeList; + }; + + // Function by Artem B. with a minor change by f.d. + var parseCallbacks = function(cbs) { + if(cbs == null) { return {}; }; + var func, + type, + cbObj = {}, + parts, + obj; + for(var i = 0, fn; fn = cbs[i]; i++) { + type = fn.match(/(fd_slider_cb_(update|create|destroy|redraw|move|focus|blur|enable|disable)_)([^\s|$]+)/i)[1]; + fn = fn.replace(new RegExp("^"+type), "").replace(/-/g, "."); + type = type.replace(/^fd_slider_cb_/i, "").replace(/_$/, ""); + + try { + if(fn.indexOf(".") != -1) { + parts = fn.split('.'); + obj = window; + for (var x = 0, part; part = obj[parts[x]]; x++) { + if(part instanceof Function) { + (function() { + var method = part; + func = function (data) { method.apply(obj, [data]) }; + })(); + } else { + obj = part; + }; + }; + } else { + func = window[fn]; + }; + + if(!(func instanceof Function)) continue; + if(!(type in cbObj)) { cbObj[type] = []; }; + cbObj[type][cbObj[type].length] = func; + } catch (err) {}; + }; + return cbObj; + }; + + var parseClassNames = function(cbs) { + if(cbs == null) { return ""; }; + var cns = []; + for(var i = 0, cn; cn = cbs[i]; i++) { + cns[cns.length] = cn.replace(/^fd_slider_cn_/, ""); + }; + return cns.join(" "); + }; + var createSlider = function(options) { + if(!options || !options.inp || !options.inp.id) { return false; }; + destroySingleSlider(options.inp.id); + sliders[options.inp.id] = new fdSlider(options); + return true; + }; + var init = function( elem ) { + var ranges = /fd_range_([-]{0,1}[0-9]+(d[0-9]+){0,1}){1}_([-]{0,1}[0-9]+(d[0-9]+){0,1}){1}/i, + increment = /fd_inc_([-]{0,1}[0-9]+(d[0-9]+){0,1}){1}/, + kIncrement = /fd_maxinc_([-]{0,1}[0-9]+(d[0-9]+){0,1}){1}/, + callbacks = /((fd_slider_cb_(update|create|destroy|redraw|move|focus|blur|enable|disable)_)([^\s|$]+))/ig, + classnames = /(fd_slider_cn_([a-zA-Z0-9_\-]+))/ig, + inputs = elem && elem.tagName && elem.tagName.search(/input|select/i) != -1 ? [elem] : joinNodeLists(document.getElementsByTagName('input'), document.getElementsByTagName('select')), + range, + tmp, + options; + + for(var i = 0, inp; inp = inputs[i]; i++) { + if((inp.tagName.toLowerCase() == "input" && inp.type == "text" && (inp.className.search(ranges) != -1 || inp.className.search(/fd_slider/) != -1)) || (inp.tagName.toLowerCase() == "select" && inp.className.search(/fd_slider/) != -1)) { + // If we haven't been passed a specific id and the slider exists then continue + if(!elem && inp.id && document.getElementById("fd-slider-"+inp.id)) { continue; }; + + // Create an id if necessary + if(!inp.id) { inp.id == "sldr" + uniqueid++; }; + + options = { + inp: inp, + inc: inp.className.search(increment) != -1 ? inp.className.match(increment)[0].replace("fd_inc_", "").replace("d",".") : "1", + maxInc: inp.className.search(kIncrement) != -1 ? inp.className.match(kIncrement)[0].replace("fd_maxinc_", "").replace("d",".") : false, + range: [0,100], + callbacks: parseCallbacks(inp.className.match(callbacks)), + classNames: parseClassNames(inp.className.match(classnames)), + tween: inp.className.search(/fd_tween/i) != -1, + vertical: inp.className.search(/fd_vertical/i) != -1, + hideInput: inp.className.search(/fd_hide_input/i) != -1, + clickJump: inp.className.search(/fd_jump/i) != -1, + fullARIA: inp.className.search(/fd_full_aria/i) != -1, + noMouseWheel: inp.className.search(/fd_disable_mousewheel/i) != -1 + }; + + if(inp.tagName.toLowerCase() == "select") { + options.range = [0, inp.options.length - 1]; + } else if(inp.className.search(ranges) != -1) { + range = inp.className.match(ranges)[0].replace("fd_range_", "").replace(/d/g,".").split("_"); + options.range = [range[0], range[1]]; + }; + + createSlider(options); + }; + }; + + return true; + }; + var destroySingleSlider = function(id) { + if(id in sliders) { + sliders[id].destroy(); + delete sliders[id]; + return true; + }; + return false; + }; + var destroyAllsliders = function(e) { + for(slider in sliders) { sliders[slider].destroy(); }; + }; + var unload = function(e) { + destroyAllsliders(); + sliders = null; + removeEvent(window, "unload", unload); + removeEvent(window, "resize", resize); + removeOnloadEvent(); + }; + var resize = function(e) { + for(slider in sliders) { sliders[slider].onResize(); }; + }; + var removeOnloadEvent = function() { + removeEvent(window, "load", init); + /*@cc_on@*/ + /*@if(@_win32) + removeEvent(window, "load", function() { setTimeout(onload, 200) }); + /*@end@*/ + }; + function fdSlider(options) { + + var inp = options.inp, + disabled = false, + tagName = inp.tagName.toLowerCase(), + min = +options.range[0], + max = +options.range[1], + range = Math.abs(max - min), + inc = tagName == "select" ? 1 : +options.inc||1, + maxInc = options.maxInc && options.maxInc != 'undefined' ? options.maxInc : inc * 2; + // alert(options.maxInc + "," + maxInc) + + var precision = options.inc.search(".") != -1 ? options.inc.substr(options.inc.indexOf(".")+1, options.inc.length - 1).length : 0, + steps = Math.ceil(range / inc), + useTween = !!options.tween, + fullARIA = !!options.fullARIA, + hideInput = !!options.hideInput, + clickJump = useTween ? false : !!options.clickJump, + vertical = !!options.vertical, + callbacks = options.callbacks, + classNames = options.classNames, + noMWheel = !!options.noMouseWheel, + timer = null, + kbEnabled = true, + sliderH = 0, + sliderW = 0, + tweenX = 0, + tweenB = 0, + tweenC = 0, + tweenD = 0, + frame = 0, + x = 0, + y = 0, + maxPx = 0, + handlePos = 0, + destPos = 0, + mousePos = 0, + deltaPx = 0, + stepPx = 0, + self = this, + changeList = {}, + initVal = null, + outerWrapper, + wrapper, + handle, + bar; + + if(max < min) { + inc = -inc; + maxInc = -maxInc; + }; + + function disableSlider(noCallback) { + if(disabled && !noCallback) { return; }; + + try { + removeEvent(outerWrapper, "mouseover", onMouseOver); + removeEvent(outerWrapper, "mouseout", onMouseOut); + removeEvent(outerWrapper, "mousedown", onMouseDown); + removeEvent(handle, "focus", onFocus); + removeEvent(handle, "blur", onBlur); + if(!window.opera) { + removeEvent(handle, "keydown", onKeyDown); + removeEvent(handle, "keypress", onKeyPress); + } else { + removeEvent(handle, "keypress", onKeyDown); + }; + removeEvent(handle, "mousedown", onHandleMouseDown); + removeEvent(handle, "mouseup", onHandleMouseUp); + + if(mouseWheelEnabled && !noMWheel) { + if (window.addEventListener && !window.devicePixelRatio) window.removeEventListener('DOMMouseScroll', trackMouseWheel, false); + else { + removeEvent(document, "mousewheel", trackMouseWheel); + removeEvent(window, "mousewheel", trackMouseWheel); + }; + }; + } catch(err) {}; + + clearTimeout(timer); + outerWrapper.className = outerWrapper.className.replace("slider-disabled", "") + " slider-disabled"; + outerWrapper.setAttribute("aria-disabled", true); + inp.disabled = disabled = true; + + if(!noCallback) { + callback("disable"); + }; + }; + + function enableSlider(noCallback) { + if(!disabled && !noCallback) return; + addEvent(outerWrapper, "mouseover", onMouseOver); + addEvent(outerWrapper, "mouseout", onMouseOut); + addEvent(outerWrapper, "mousedown", onMouseDown); + if(!window.opera) { + addEvent(handle, "keydown", onKeyDown); + addEvent(handle, "keypress", onKeyPress); + } else { + addEvent(handle, "keypress", onKeyDown); + }; + addEvent(handle, "focus", onFocus); + addEvent(handle, "blur", onBlur); + addEvent(handle, "mousedown", onHandleMouseDown); + addEvent(handle, "mouseup", onHandleMouseUp); + + outerWrapper.className = outerWrapper.className.replace("slider-disabled", ""); + outerWrapper.setAttribute("aria-disabled", false); + inp.disabled = disabled = false; + + if(!noCallback) { + callback("enable"); + }; + }; + + function destroySlider() { + try { + disableSlider(); + outerWrapper.parentNode.removeChild(outerWrapper); + } catch(err) {}; + + wrapper = bar = handle = outerWrapper = timer = null; + callback("destroy"); + callbacks = null; + }; + + function redraw() { + locate(); + // Internet Explorer requires the try catch + try { + var sW = outerWrapper.offsetWidth, + sH = outerWrapper.offsetHeight, + hW = handle.offsetWidth, + hH = handle.offsetHeight, + bH = bar.offsetHeight, + bW = bar.offsetWidth; + + maxPx = vertical ? sH - hH : sW - hW; + stepPx = maxPx / steps; + deltaPx = maxPx / Math.ceil(range / maxInc); + + + sliderW = sW; + sliderH = sH; + + valueToPixels(); + } catch(err) { }; + callback("redraw"); + }; + + function callback(type) { + var cbObj = {"elem":inp, "value":tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value}; + if(type in callbacks) { + for(var i = 0, func; func = callbacks[type][i]; i++) { + func(cbObj); + }; + }; + }; + + function onFocus(e) { + outerWrapper.className = outerWrapper.className.replace('focused','') + ' focused'; + if(mouseWheelEnabled && !noMWheel) { + addEvent(window, 'DOMMouseScroll', trackMouseWheel); + addEvent(document, 'mousewheel', trackMouseWheel); + if(!window.opera) addEvent(window, 'mousewheel', trackMouseWheel); + }; + callback("focus"); + }; + + function onBlur(e) { + outerWrapper.className = outerWrapper.className.replace(/focused|fd-fc-slider-hover|fd-slider-hover/g,''); + if(mouseWheelEnabled && !noMWheel) { + removeEvent(document, 'mousewheel', trackMouseWheel); + removeEvent(window, 'DOMMouseScroll', trackMouseWheel); + if(!window.opera) removeEvent(window, 'mousewheel', trackMouseWheel); + }; + callback("blur"); + }; + + function trackMouseWheel(e) { + if(!kbEnabled) return; + e = e || window.event; + var delta = 0; + + if (e.wheelDelta) { + delta = e.wheelDelta/120; + if (window.opera && window.opera.version() < 9.2) delta = -delta; + } else if(e.detail) { + delta = -e.detail/3; + }; + + if(vertical) { delta = -delta; }; + + if(delta) { + var xtmp = vertical ? handle.offsetTop : handle.offsetLeft; + xtmp = (delta < 0) ? Math.ceil(xtmp + deltaPx) : Math.floor(xtmp - deltaPx); + pixelsToValue(Math.min(Math.max(xtmp, 0), maxPx)); + } + return stopEvent(e); + }; + + function onKeyPress(e) { + e = e || document.parentWindow.event; + if ((e.keyCode >= 33 && e.keyCode <= 40) || !kbEnabled || e.keyCode == 45 || e.keyCode == 46) { + return stopEvent(e); + }; + return true; + }; + + function onKeyDown(e) { + if(!kbEnabled) return true; + + e = e || document.parentWindow.event; + var kc = e.keyCode != null ? e.keyCode : e.charCode; + + if ( kc < 33 || (kc > 40 && (kc != 45 && kc != 46))) return true; + + var value = tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex; + if(isNaN(value) || value < Math.min(min,max)) value = Math.min(min,max); + + if( kc == 37 || kc == 40 || kc == 46 || kc == 34) { + // left, down, ins, page down + value -= (e.ctrlKey || kc == 34 ? maxInc : inc) + } else if( kc == 39 || kc == 38 || kc == 45 || kc == 33) { + // right, up, del, page up + value += (e.ctrlKey || kc == 33 ? maxInc : inc) + } else if( kc == 35 ) { + // max + value = max; + } else if( kc == 36 ) { + // min + value = min; + }; + + valueToPixels(value); + callback("update"); + + // Opera doesn't let us cancel key events so the up/down arrows and home/end buttons will scroll the screen - which sucks + return stopEvent(e); + }; + + function onMouseOver( e ) { + /*@cc_on@*/ + /*@if(@_jscript_version <= 5.6) + if(this.className.search(/focused/) != -1) { + this.className = this.className.replace("fd-fc-slider-hover", "") +' fd-fc-slider-hover'; + return; + } + /*@end@*/ + this.className = this.className.replace(/fd\-slider\-hover/g,"") +' fd-slider-hover'; + }; + + function onMouseOut( e ) { + /*@cc_on@*/ + /*@if(@_jscript_version <= 5.6) + if(this.className.search(/focused/) != -1) { + this.className = this.className.replace("fd-fc-slider-hover", ""); + return; + } + /*@end@*/ + this.className = this.className.replace(/fd\-slider\-hover/g,""); + }; + + function onHandleMouseUp(e) { + e = e || window.event; + removeEvent(document, 'mousemove', trackMouse); + removeEvent(document, 'mouseup', onHandleMouseUp); + + kbEnabled = true; + + // Opera fires the blur event when the mouseup event occurs on a button, so we attept to force a focus + if(window.opera) try { setTimeout(function() { onfocus(); }, 0); } catch(err) {}; + document.body.className = document.body.className.replace(/slider-drag-vertical|slider-drag-horizontal/g, ""); + + return stopEvent(e); + }; + + function onHandleMouseDown(e) { + e = e || window.event; + mousePos = vertical ? e.clientY : e.clientX; + handlePos = parseInt(vertical ? handle.offsetTop : handle.offsetLeft)||0; + kbEnabled = false; + + clearTimeout(timer); + timer = null; + + addEvent(document, 'mousemove', trackMouse); + addEvent(document, 'mouseup', onHandleMouseUp); + + // Force a "focus" on the button on mouse events + if(window.devicePixelRatio || (document.all && !window.opera)) try { setTimeout(function() { handle.focus(); }, 0); } catch(err) {}; + + document.body.className += " slider-drag-" + (vertical ? "vertical" : "horizontal"); + }; + + function onMouseUp( e ) { + e = e || window.event; + removeEvent(document, 'mouseup', onMouseUp); + if(!useTween) { + clearTimeout(timer); + timer = null; + kbEnabled = true; + }; + return stopEvent(e); + }; + + function trackMouse( e ) { + e = e || window.event; + pixelsToValue(snapToNearestValue(handlePos + (vertical ? e.clientY - mousePos : e.clientX - mousePos))); + }; + + function onMouseDown( e ) { + e = e || window.event; + var targ; + if (e.target) targ = e.target; + else if (e.srcElement) targ = e.srcElement; + if (targ.nodeType == 3) targ = targ.parentNode; + + if(targ.className.search("fd-slider-handle") != -1) { return true; }; + + try { setTimeout(function() { handle.focus(); }, 0); } catch(err) { }; + + clearTimeout(timer); + locate(); + + timer = null; + kbEnabled = false; + + var posx = 0, + sLft = 0, + sTop = 0; + + // Internet Explorer doctype woes + if (document.documentElement && document.documentElement.scrollTop) { + sTop = document.documentElement.scrollTop; + sLft = document.documentElement.scrollLeft; + } else if (document.body) { + sTop = document.body.scrollTop; + sLft = document.body.scrollLeft; + }; + + if (e.pageX) posx = vertical ? e.pageY : e.pageX; + else if (e.clientX) posx = vertical ? e.clientY + sTop : e.clientX + sLft; + posx -= vertical ? y + Math.round(handle.offsetHeight / 2) : x + Math.round(handle.offsetWidth / 2); + posx = snapToNearestValue(posx); + + if(useTween) { + tweenTo(posx); + } else if(clickJump) { + pixelsToValue(posx); + } else { + addEvent(document, 'mouseup', onMouseUp); + destPos = posx; + onTimer(); + }; + }; + + function incrementHandle(numOfSteps) { + var value = tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex; + if(isNaN(value) || value < Math.min(min,max)) value = Math.min(min,max); + value += inc * numOfSteps; + valueToPixels(value); + }; + + function snapToNearestValue(px) { + var rem = px % stepPx; + if(rem && rem >= (stepPx / 2)) { px += (stepPx - rem); } + else { px -= rem; }; + return Math.min(Math.max(parseInt(px, 10), 0), maxPx); + }; + + function locate(){ + var curleft = 0, + curtop = 0, + obj = outerWrapper; + + // Try catch for IE's benefit + try { + while (obj.offsetParent) { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + obj = obj.offsetParent; + }; + } catch(err) {}; + x = curleft; + y = curtop; + }; + + function onTimer() { + var xtmp = vertical ? handle.offsetTop : handle.offsetLeft; + xtmp = Math.round((destPos < xtmp) ? Math.max(destPos, Math.floor(xtmp - deltaPx)) : Math.min(destPos, Math.ceil(xtmp + deltaPx))); + pixelsToValue(xtmp); + if(xtmp != destPos) timer = setTimeout(onTimer, steps > 20 ? 50 : 100); + else kbEnabled = true; + }; + + var tween = function(){ + frame++; + var c = tweenC, + d = 20, + t = frame, + b = tweenB, + x = Math.ceil((t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b); + + pixelsToValue(t == d ? tweenX : x); + callback("move"); + if(t!=d) timer = setTimeout(tween, 20); + else { + clearTimeout(timer); + timer = null; + kbEnabled = true; + }; + }; + + function tweenTo(tx){ + kbEnabled = false; + tweenX = parseInt(tx, 10); + tweenB = parseInt(vertical ? handle.style.top : handle.style.left, 10); + tweenC = tweenX - tweenB; + tweenD = 20; + frame = 0; + if(!timer) timer = setTimeout(tween, 20); + }; + + function pixelsToValue(px) { + //jslog.debug(DebugHelpers.getStackTrace()) + handle.style[vertical ? "top" : "left"] = px + "px"; + var val = min + (Math.round(px / stepPx) * inc); + setInputValue((tagName == "select" || inc == 1) ? Math.round(val) : val); + }; + + function valueToPixels(val) { + var value = isNaN(val) ? tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex : val; + if(isNaN(value) || value < Math.min(min,max)) value = Math.min(min,max); + else if(value > Math.max(min,max)) value = Math.max(min,max); + setInputValue(value); + handle.style[vertical ? "top" : "left"] = Math.round(((value - min) / inc) * stepPx) + "px"; + }; + + function setInputValue(val) { + val = isNaN(val) ? min : val; + if(tagName == "select") { + try { + val = parseInt(val, 10); + if(inp.selectedIndex == val) return; + inp.options[val].selected = true; + } catch (err) {}; + } else { + val = (min + (Math.round((val - min) / inc) * inc)).toFixed(precision); + if(inp.value == val) return; + inp.value = val; + }; + updateAriaValues(); + callback("update"); + }; + + function findLabel() { + var label; + if(inp.parentNode && inp.parentNode.tagName.toLowerCase() == "label") label = inp.parentNode; + else { + var labelList = document.getElementsByTagName('label'); + // loop through label array attempting to match each 'for' attribute to the id of the current element + for(var i = 0, lbl; lbl = labelList[i]; i++) { + // Internet Explorer requires the htmlFor test + if((lbl['htmlFor'] && lbl['htmlFor'] == inp.id) || (lbl.getAttribute('for') == inp.id)) { + label = lbl; + break; + }; + }; + }; + if(label && !label.id) { label.id = inp.id + "_label"; }; + return label; + }; + + function updateAriaValues() { + handle.setAttribute("aria-valuenow", tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value); + handle.setAttribute("aria-valuetext", tagName == "select" ? inp.options[inp.selectedIndex].text : inp.value); + }; + + function onChange( e ) { + valueToPixels(); + callback("update"); + return true; + }; + + (function() { + if(hideInput) { inp.className += " fd_hide_slider_input"; } + else { addEvent(inp, 'change', onChange); }; + + outerWrapper = document.createElement('div'); + outerWrapper.className = "fd-slider" + (vertical ? "-vertical " : " ") + classNames; + outerWrapper.id = "fd-slider-" + inp.id; + + wrapper = document.createElement('span'); + wrapper.className = "fd-slider-inner"; + + bar = document.createElement('span'); + bar.className = "fd-slider-bar"; + + if(fullARIA) { + handle = document.createElement('span'); + handle.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", "0"); + } else { + handle = document.createElement('button'); + handle.setAttribute("type", "button"); + }; + + handle.className = "fd-slider-handle"; + handle.appendChild(document.createTextNode(String.fromCharCode(160))); + + outerWrapper.appendChild(wrapper); + outerWrapper.appendChild(bar); + outerWrapper.appendChild(handle); + + inp.parentNode.insertBefore(outerWrapper, inp); + + /*@cc_on@*/ + /*@if(@_win32) + handle.unselectable = "on"; + bar.unselectable = "on"; + wrapper.unselectable = "on"; + outerWrapper.unselectable = "on"; + /*@end@*/ + + // Add ARIA accessibility info programmatically + handle.setAttribute("role", "slider"); + handle.setAttribute("aria-valuemin", min); + handle.setAttribute("aria-valuemax", max); + + var lbl = findLabel(); + if(lbl) { + handle.setAttribute("aria-labelledby", lbl.id); + handle.id = "fd-slider-handle-" + inp.id; + /*@cc_on + /*@if(@_win32) + lbl.setAttribute("htmlFor", handle.id); + @else @*/ + lbl.setAttribute("for", handle.id); + /*@end + @*/ + }; + + // Are there page instructions - the creation of the instructions has been left up to you fine reader... + if(document.getElementById("fd_slider_describedby")) { + handle.setAttribute("aria-describedby", "fd_slider_describedby"); // aaa:describedby + }; + + if(inp.getAttribute("disabled") == true) { + disableSlider(true); + } else { + enableSlider(true); + }; + + updateAriaValues(); + callback("create"); + redraw(); + })(); + + return { + onResize: function(e) { if(outerWrapper.offsetHeight != sliderH || outerWrapper.offsetWidth != sliderW) { redraw(); }; }, + destroy: function() { destroySlider(); }, + reset: function() { valueToPixels(); }, + increment: function(n) { incrementHandle(n); }, + disable: function() { disableSlider(); }, + enable: function() { enableSlider(); } + }; + }; + + addEvent(window, "load", init); + addEvent(window, "unload", unload); + addEvent(window, "resize", resize); + /*@cc_on@*/ + /*@if(@_win32) + var onload = function(e) { + for(slider in sliders) { sliders[slider].reset(); } + }; + addEvent(window, "load", function() { setTimeout(onload, 200) }); + /*@end@*/ + + return { + create: function(elem) { init(elem) }, + createSlider: function(opts) { createSlider(opts); }, + destroyAll: function() { destroyAllsliders(); }, + destroySlider: function(id) { return destroySingleSlider(id); }, + redrawAll: function() { resize(); }, + increment: function(id, numSteps) { if(!(id in sliders)) { return false; }; sliders[id].increment(numSteps); }, + addEvent: addEvent, + removeEvent: removeEvent, + stopEvent: stopEvent, + updateSlider: function(id) { if(!(id in sliders)) { return false; }; sliders[id].reset(); }, + disableMouseWheel: function() { removeMouseWheelSupport(); }, + removeOnLoadEvent: function() { removeOnloadEvent(); }, + disableSlider: function(id) { if(!(id in sliders)) { return false; }; sliders[id].disable(); }, + enableSlider: function(id) { if(!(id in sliders)) { return false; }; sliders[id].enable(); } + } +})(); + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/html5.js b/itf/static/js/html5Forms.js/shared/js/html5.js new file mode 100644 index 0000000..84e74f4 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/html5.js @@ -0,0 +1,121 @@ +// For discussion and comments, see: http://remysharp.com/2009/01/07/html5-enabling-script/ +(function(){if(!/*@cc_on!@*/0)return;var e = "abbr,article,aside,audio,canvas,datalist,details,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video".split(','),i=e.length;while(i--){document.createElement(e[i])}})() + +var html5 = new function () { + var me = this; + + /** + * Given an HTML or XML object, find the an attribute by name. + * + * @param {Object} obj - a DOM object. + * @param {String} attrName - the name of an attribute inside the DOM object. + * @return {Object} - the attribute object or null if there isn't one. + */ + me.getAttributeByName = function (obj, attrName) { + var i; + + var attributes = obj.attributes; + for (i=0; i 534, + hasBadValidationImplementation = !hasNativeBubbles; // making another var for this in case we have more criteria in the future. + + + var globalEvent = document.addEventListener?document.createEvent("HTMLEvents"):null; + + function getBrowserLanguage() { + var r = navigator.language; + if (!r) { + r = navigator.browserLanguage; + } + return r; + } + + + me.start = function () { + + var split = navigator.userAgent.split('Firefox/'); + + //Firefox 3.6 gives a wierd error when using the Twitter API + //unless you do this onload. + if (split.length>=1 && parseFloat(split[1]) <= 3.6) { + EventHelpers.addEvent(window, 'load', me.init); + } else { + me.init(); + } + } + + me.init = function () { + var scriptNodes = document.getElementsByTagName('script'); + + for (var i=0; i= 0) { + isScriptCompressed = true; + } + break; + } + } + + if (scriptNode) { + if (window.yepnope) { + var inputSupport = Modernizr.inputtypes; + /* let's load the supporting scripts according to what is in data-webforms2-support */ + var supportArray = scriptNode.getAttribute('data-webforms2-support'); + me.forceJSValidation = (scriptNode.getAttribute('data-webforms2-force-js-validation') == 'true'); + me.turnOffValidation = (scriptNode.getAttribute('data-webforms2-turn-off-validation') == 'true'); + me.forceJSDatePicker = (scriptNode.getAttribute('data-webforms2-force-js-date-picker') == 'true'); + if (!supportArray) { + return; + } else if (trim(supportArray) == 'all') { + supportArray="validation,number,color,date,ouput,range,placeholder"; + } + + supportArray = supportArray.split(','); + var toLoad = []; + var toRunAfterLoad = []; + var loadHTML5Widgets = false; + + + for (var i=0; i<\/script>'); + + var script = document.getElementById("__ie_onload"); + + me.addEvent(script, 'readystatechange', me.runPageLoadEvents); + + /*@end @*/ + + } + if (!window.html5Forms) { + init(); + } +} + +html5Forms.start(); diff --git a/itf/static/js/html5Forms.js/shared/js/html5Widgets.js b/itf/static/js/html5Forms.js/shared/js/html5Widgets.js new file mode 100644 index 0000000..0e571d5 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/html5Widgets.js @@ -0,0 +1,1417 @@ +/******************************************************************************* + * This notice must be untouched at all times. + * + * This javascript library contains helper routines to assist with event + * handling consinstently among browsers + * + * html5Widgets.js v.1.1 by Zoltan Hawryluk + * latest version and documentation available at http://www.useragentman.com/ + * + * Changelog: + * version 1.0: initial release + * version 1.1: implemented oninput method for form elements for unsupported browsers + * fix IE9 to ensure backspace and delete keys fire an oninput event. + * version 1.2: Added Number Element Widget + * + * released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + *******************************************************************************/ + +var html5Widgets = new function(){ + var me = this; + + + var delayEventTimeout = null; + + me.inputNodes = new Array(); + me.outputNodes = new Array(); + me.formElements = null; + me.placeholderNodes = new Array(); + me.dummyLink = document.createElement('input'); + var quoteRe = /\"/g; + + var dummyIDCount = 0; + var supportsNatively = new Object(); + + var isBadChrome = navigator.userAgent.indexOf('Chrome'); + var valueRe = /this\.value/g; + var varRe = /([a-zA-Z][a-zA-Z0-9]*\.value)/g; + var isDebug; + + var isIE9 = false; + + /*@cc_on + @if (@_jscript_version == 9) + isIE9 = true; + @end + @*/ + + + + me.init = function(){ + + if (EventHelpers.hasPageLoadHappened(arguments)) { + return; + } + + supportsNatively['oninput'] = EventHelpers.isSupported('input', 'form'); + + isDebug = CSSHelpers.isMemberOfClass(document.body, 'html5Widgets-debug') + + // dummy link setup + me.type = 'text' + me.dummyLink.style.position = 'absolute'; + me.dummyLink.style.top = '-200px'; + document.body.appendChild(me.dummyLink) + + var inputSupport = Modernizr.input + + if (!inputSupport['placeholder']) { + setPlaceholders(); + } + indexOutputNodes(); + insertElements(); + + me.resolveOutputs(); + + /* document.getElementById('supports').innerHTML = + DebugHelpers.getProperties(Modernizr.inputtypes, 'inputtypes') + " " + + DebugHelpers.getProperties(Modernizr.input, 'input') + " " + + DebugHelpers.getProperties(Modernizr, 'Modernizr'); */ + + } + + + + function supports_input_placeholder() { + var i = document.createElement('input'); + return 'placeholder' in i; + } + + function setPlaceholders() { + + var nodes = [document.getElementsByTagName('input'), document.getElementsByTagName('textarea')]; + + for (var i=0; i= 0, + cache : true, + inputField : me.node.id, // ID of the input field + ifFormat : formatString, // the date format + button : me.node.id // ID of the button + } + ); + + + + + + EventHelpers.addEvent(me.node, 'click', forceCalToTop); + EventHelpers.addEvent(me.node, 'focus', focusEvent) + EventHelpers.addEvent(me.node, 'keypress', openCalendar); + EventHelpers.addEvent(me.node, 'blur', closeCalendar); + + EventHelpers.addEvent(me.node, 'keypress', keydownEvent) + //me.node.type = "text"; + + // this will call submitEvent() after the form has been validated by + // webforms2.js + if (window.$wf2) { + $wf2.callBeforeValidation.push(prepareForSubmission); + $wf2.callAfterValidation.push(validationEvent); + } + + } + + function placeUTCInfo() { + + var label = document.createElement('span'); + label.innerHTML = "UTC"; + label.style.paddingLeft = "5px"; + + DOMHelpers.insertAfter(me.node, label); + + var width = label.offsetWidth; + + me.node.style.width = (me.node.offsetWidth - 5 - width) + 'px'; + + } + + function prepareForSubmission() { + var splitVals; + + switch (me.type) { + case "datetime": + case "datetime-local": + + originalVisibilityState = me.node.style.visibility; + me.node.style.visibility = 'hidden'; + if (me.node.value.match(displayDateTimeValueRe)) { + splitVals = me.node.value.split(' '); + me.node.value = splitVals[0] + "T" + splitVals[1]; + } + + switch (me.type) { + case "datetime-local": + break; + case "datetime": + if (me.node.value != "") { + me.node.value += "Z"; + } + } + + } + } + + function prepareForDisplay() { + switch(me.type) { + case "datetime": + case "datetime-local": + if ( me.node.value.match(badDateTimeValueRe)) { + me.node.value = me.node.value.replace(/T/, ' ').replace(/Z/, ''); + } + if (originalVisibilityState != null) { + me.node.style.visibility = originalVisibilityState; + } + + } + + + } + + function validationEvent(e, hasValidated) { + if (!hasValidated) { + prepareForDisplay(); + } + } + + function forceCalToTop(e) { + var cal = window.calendar; + + cal.element.style.zIndex = 100; + } + + function focusEvent(e) { + var el = EventHelpers.getEventTarget(e); + EventHelpers.fireEvent(el, 'click') + } + + function openCalendar(e) { + + var cal = window.calendar; + + cal.element.style.zIndex = 100; + if (cal.open != undefined) { + cal.open(); + } + //EventHelpers.fireEvent(this, 'blur'); + //EventHelpers.fireEvent(this, 'focus'); + } + + function closeCalendar(e){ + + var cal = window.calendar; + if (cal) { + cal.hide(); + } + } + + function keydownEvent(e) { + + var c = EventHelpers.getKey(e); + + switch(c){ + case 13: + html5Widgets.dummyLink.focus(); + this.focus(); + EventHelpers.preventDefault(e); + openCalendar(e); + break; + case 9: + closeCalendar(e); + break; + default: + EventHelpers.preventDefault(e); + break; + } + + + } + + function submitEvent(e) { + prepareForSubmission(); + } + + init(); + + } + + + + + + + + /* + * Output Element + */ + function OutputElement (node) { + var me = this; + me.node = node; + + var value; + var valueFormula; + var parentForm; + + + + function init () { + parentForm = DOMHelpers.getAncestorByTagName(node, 'form'); + if (!parentForm.id) { + parentForm.id = getNextDummyID(); + } + + valueFormula = html5Widgets.getValueFormula(DOMHelpers.getAttributeValue(me.node, 'onforminput'), parentForm); + } + + + + me.resolve = function () { + if (valueFormula == null) { + return; + } else { + eval(valueFormula); + me.node.innerHTML = value; + me.node.value = value; + } + + } + + + init(); + } + + function ColorElement (node) { + var me = this; + + /* note: color picker setPad() is what you are looking for */ + me.node = node; + + function init () { + if (!window.jscolor) { + showError('jscolor script must be included in order for the color input type to work in this browser. See documentation for more details.') + } + CSSHelpers.addClass(me.node, 'color'); + CSSHelpers.addClass(me.node, '{hash:true,caps:false}'); + me.node.type = "text"; + } + + + init(); + } + + /* + * NumberElement: refactored from http://www.kethinov.com/jsstepper.php. + */ + + function NumberElement (node) { + var me = this, + min = parseFloat(DOMHelpers.getAttributeValue(node, 'min')), + max = parseFloat(DOMHelpers.getAttributeValue(node, 'max')), + step = parseFloat(DOMHelpers.getAttributeValue(node, 'step')); + + me.node = node; + + + + if (isNaN(step)) { + // we don't have to create the up and down arraw widgets + return; + } + + EventHelpers.addEvent(node, 'keyup', keyUpEvent); + + + function keyUpEvent() { + + if (isNumeric(this.value)) { + + /* if (this.value > max) this.value = max; + else if (this.value < min) this.value = this.min; */ + + } else if (this.value != '') { + var val = parseFloat(this.value); + if (isNaN(val)) { + this.value = ''; + } else { + this.value = val; + } + } + + } + + + + function nearestValid(value, direction) { + + var n = (value - min)/step, + r; + //alert(StringHelpers.sprintf("n: %s, value: %s, min: %s, step: %s", n, value, min, step)) + if (n == parseInt(n)) { + r = value; + } else { + + if (direction < 0) { + n = Math.floor(n + 1); + } else { + n = Math.ceil(n -1); + } + + r = min + step * n; + } + + if (r > max) { + r -= step; + } else if (r < min) { + r+= step + } + + return r; + } + + function buttonMouseDownEvent(e) { + + var buttonType = this.className; + var stepMult = step; + if (buttonType == 'dnbutton') { + stepMult = -step; + } + + + var min = this.min; + var max = this.max; + if ( + (stepMult < 0 && (node.value > min || isNaN(min))) || + (stepMult > 0 && (node.value < max || isNaN(max))) + ) { + setValue(me.node, nearestValid(parseFloat(node.value) + stepMult, stepMult)); + } + + var delayedOnce = false; + var date = new Date(); + var curDate = null; + + this.interval = setInterval(function() { + if (!delayedOnce) { + curDate = new Date(); + if (curDate - date > 500) delayedOnce = true; + } + else if ( + (stepMult < 0 && (node.value > min || isNaN(min))) || + (stepMult > 0 && (node.value < max || isNaN(max))) + ) { + setValue(me.node, nearestValid(parseFloat(node.value) + stepMult, stepMult)); + } + }, 50); + EventHelpers.preventDefault(e); + } + + function setValue(node, value) { + if (isNaN(value)) { + node.value = ''; + } else { + node.value = value; + } + } + + function buttonClickEvent(e) { + clearInterval(this.interval); + EventHelpers.preventDefault(e); + } + function buttonMouseUpEvent(e) { + clearInterval(this.interval); + EventHelpers.preventDefault(e); + } + + function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); + } + + + function hasNativeSpinner() { + try { + return window.getComputedStyle(me.node, '-webkit-inner-spin-button').WebkitAppearance != undefined; + } catch (ex) { + return false; + } + } + + function init () { + var upbutton = document.createElement('a'); + upbutton.className = 'upbutton'; + upbutton.appendChild(document.createTextNode("\u25B2")); + upbutton.targInput = node; + upbutton.max = max; + + var dnbutton = document.createElement('a'); + dnbutton.className = 'dnbutton'; + dnbutton.appendChild(document.createTextNode("\u25BC")); + dnbutton.targInput = node; + dnbutton.min = min; + dnbutton.max = max; + + EventHelpers.addEvent(upbutton, 'mousedown', buttonMouseDownEvent); + EventHelpers.addEvent(dnbutton, 'mousedown', buttonMouseDownEvent); + + EventHelpers.addEvent(upbutton, 'click', buttonClickEvent); + EventHelpers.addEvent(upbutton, 'mouseup', buttonMouseUpEvent); + EventHelpers.addEvent(dnbutton, 'click', buttonClickEvent); + EventHelpers.addEvent(dnbutton, 'mouseup', buttonMouseUpEvent); + + + if (!hasNativeSpinner()) { + var controlsNode = document.createElement('div'); + controlsNode.className = 'html5-numberControls'; + controlsNode.appendChild(upbutton); + controlsNode.appendChild(dnbutton); + + var wrapperNode = document.createElement('div') + wrapperNode.className = 'html5-numberWrapper'; + wrapperNode.appendChild(controlsNode); + var parentNode = node.parentNode; + + + + + parentNode.insertBefore(wrapperNode, node); + + + var nodeWidth = node.offsetWidth; + var nodeStyle = CSSHelpers.getCurrentStyle(node); + + node.style.width = (nodeWidth - upbutton.offsetWidth -9) + 'px'; + wrapperNode.style.width = nodeWidth + 'px'; + wrapperNode.style.marginTop = nodeStyle.marginTop; + wrapperNode.style.height = (node.offsetHeight) + 'px'; + } + + + + } + /* Finally: if the form field has a value onload that is not a number, remove it + if (!isNumeric(node.value)) { + node.value = ''; + EventHelpers.fireEvent(node, 'change'); + }*/ + init(); + } + + function PlaceholderInput (node) { + var me = this; + + me.node = node; + + var form, defaultText; + + function init () { + defaultText = DOMHelpers.getAttributeValue(node, 'placeholder'); + form = DOMHelpers.getAncestorByTagName(node, 'form'); + + me.setPlaceholderText(true); + EventHelpers.addEvent(me.node, 'blur', blurEvent); + EventHelpers.addEvent(me.node, 'focus', focusEvent); + + if (me.node.form) { + EventHelpers.addEvent(me.node.form, 'submit', removePlaceholderText); + } + + if (window.$wf2) { + if ($wf2.callBeforeValidation != undefined) { + $wf2.callBeforeValidation.push(removePlaceholderText); + } + + if ($wf2.callAfterValidation != undefined) { + $wf2.callAfterValidation.push(postValidationEvent); + } + } + } + + me.setPlaceholderText = function (isLoadEvent) { + //jslog.debug(StringHelpers.sprintf('initiator: %s', this)); + var isAutofocus = DOMHelpers.getAttributeValue(me.node, 'autofocus') != null; + + + if (me.node.value == "" || (isLoadEvent && me.node.value == defaultText)) { + CSSHelpers.addClass(me.node, 'html5-hasPlaceholderText'); + me.node.value = defaultText; + + } + + if (isLoadEvent && isAutofocus && me.node.value == defaultText ) { + CSSHelpers.removeClass(me.node, 'html5-hasPlaceholderText'); + me.node.value = ''; + } + + + + } + + function focusEvent(e) { + + CSSHelpers.addClass(me.node, 'html5-hasFocus'); + removePlaceholderText(); + } + + function blurEvent(e) { + //jslog.debug('removed focus on ' + me.node.name) + CSSHelpers.removeClass(me.node, 'html5-hasFocus'); + me.setPlaceholderText(); + } + + function removePlaceholderText() { + //jslog.debug('removePlaceholderText() for ' + me.node.name) + if (CSSHelpers.isMemberOfClass(me.node, 'html5-hasPlaceholderText')) { + me.node.value = ""; + CSSHelpers.removeClass(me.node, 'html5-hasPlaceholderText'); + } + } + + function postValidationEvent(e, didValidate) { + ////jslog.debug(StringHelpers.sprintf('post Validation: %s, didValidate = %s, has focus = %s', me.node.name, didValidate, CSSHelpers.isMemberOfClass(me.node, 'html5-hasFocus') ) ) + if (!didValidate && !CSSHelpers.isMemberOfClass(me.node, 'html5-hasFocus')) { + me.setPlaceholderText(); + } + } + + init(); + } + + var CSSHelpers = new function () { + var me = this; + + var blankRe = new RegExp('\\s'); + + /** + * Generates a regular expression string that can be used to detect a class name + * in a tag's class attribute. It is used by a few methods, so I + * centralized it. + * + * @param {String} className - a name of a CSS class. + */ + + function getClassReString(className) { + return '\\s'+className+'\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className +'$'; + } + + function getClassPrefixReString(className) { + return '\\s'+className+'-[0-9a-zA-Z_]+\\s|^' + className + '[0-9a-zA-Z_]+\\s|\\s' + className + '[0-9a-zA-Z_]+$|' + '^' + className +'[0-9a-zA-Z_]+$'; + } + + + /** + * Make an HTML object be a member of a certain class. + * + * @param {Object} obj - an HTML object + * @param {String} className - a CSS class name. + */ + me.addClass = function (obj, className) { + + if (blankRe.test(className)) { + return; + } + + // only add class if the object is not a member of it yet. + if (!me.isMemberOfClass(obj, className)) { + obj.className += " " + className; + } + + } + + /** + * Make an HTML object *not* be a member of a certain class. + * + * @param {Object} obj - an HTML object + * @param {Object} className - a CSS class name. + */ + me.removeClass = function (obj, className) { + + if (blankRe.test(className)) { + return; + } + + + var re = new RegExp(getClassReString(className) , "g"); + + var oldClassName = obj.className; + + + if (obj.className) { + obj.className = oldClassName.replace(re, ' '); + } + + } + + /** + * Determines if an HTML object is a member of a specific class. + * @param {Object} obj - an HTML object. + * @param {Object} className - the CSS class name. + */ + me.isMemberOfClass = function (obj, className) { + + if (blankRe.test(className)) + return false; + + var re = new RegExp(getClassReString(className) , "g"); + + return (re.test(obj.className)); + + + } + + /* from http://blog.stchur.com/2006/06/21/css-computed-style/ */ + me.getCurrentStyle = function(obj) + { + var computedStyle; + if (typeof obj.currentStyle != 'undefined') + { computedStyle = obj.currentStyle; } + else + { computedStyle = document.defaultView.getComputedStyle(obj, null); } + + return computedStyle; + } + } + + + + var DOMHelpers = new function () { + var me = this; + + /** + * Given an HTML or XML object, find the an attribute by name. + * + * @param {Object} obj - a DOM object. + * @param {String} attrName - the name of an attribute inside the DOM object. + * @return {Object} - the attribute object or null if there isn't one. + */ + me.getAttributeByName = function (obj, attrName) { + var i; + + var attributes = obj.attributes; + for (i=0; i')[0].match(typeRe); + //jslog.debug(typeVal) + if (typeVal && typeVal.length >= 1) { + return typeVal[1].replace(quoteRe, ''); + } else { + return null; + } + + } + } + + me.insertAfter = function (refNode, nodeToInsert) { + var parent = refNode.parentNode; + + var nextSibling = refNode.nextSibling; + if (nextSibling) { + parent.insertBefore(nodeToInsert, nextSibling); + } else { + parent.appendChild(nodeToInsert); + } + } + + /** + * Given an tag, find the first ancestor tag of a given tag name. + * + * @param {Object} obj - a HTML or XML tag. + * @param {String} tagName - the name of the ancestor tag to find. + * @return {Object} - the ancestor tag, or null if not found. + */ + me.getAncestorByTagName = function(obj, tagName) { + + for (var node = obj.parentNode; + node.nodeName.toLowerCase() != 'body'; + node = node.parentNode) { + + if (tagName.toLowerCase() == node.nodeName.toLowerCase()) { + return node; + } + + } + return null; + } + + me.removeNode = function (node) { + var parentNode = node.parentNode; + if (parentNode) { + parentNode.removeChild(node); + } + } + + } + + var StringHelpers = new function () { + var me = this; + + /******************************************************************************* + * Function sprintf(format_string,arguments...) Javascript emulation of the C + * printf function (modifiers and argument types "p" and "n" are not supported + * due to language restrictions) + * + * Copyright 2003 K&L Productions. All rights reserved + * http://www.klproductions.com + * + * Terms of use: This function can be used free of charge IF this header is not + * modified and remains with the function code. + * + * Legal: Use this code at your own risk. K&L Productions assumes NO + * resposibility for anything. + ******************************************************************************/ + me.sprintf = function (fstring) + { var pad = function(str,ch,len) + { var ps=''; + for(var i=0; i0?str+ps:ps+str; + } + var processFlags = function(flags,width,rs,arg) + { var pn = function(flags,arg,rs) + { if(arg>=0) + { if(flags.indexOf(' ')>=0) rs = ' ' + rs; + else if(flags.indexOf('+')>=0) rs = '+' + rs; + } + else + rs = '-' + rs; + return rs; + } + var iWidth = parseInt(width,10); + if(width.charAt(0) == '0') + { var ec=0; + if(flags.indexOf(' ')>=0 || flags.indexOf('+')>=0) ec++; + if(rs.length<(iWidth-ec)) rs = pad(rs,'0',rs.length-(iWidth-ec)); + return pn(flags,arg,rs); + } + rs = pn(flags,arg,rs); + if(rs.length=0) rs = rs.replace(/^(.*)(e.*)$/,'$1.$2'); + return processFlags(flags,width,rs,arg); + } + converters['f'] = function(flags,width,precision,arg) + { iPrecision = parseInt(precision); + if(isNaN(iPrecision)) iPrecision = 6; + rs = (Math.abs(arg)).toFixed(iPrecision); + if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs + '.'; + return processFlags(flags,width,rs,arg); + } + converters['G'] = function(flags,width,precision,arg) + { return (converters['g'](flags,width,precision,arg)).toUpperCase(); + } + converters['g'] = function(flags,width,precision,arg) + { iPrecision = parseInt(precision); + absArg = Math.abs(arg); + rse = absArg.toExponential(); + rsf = absArg.toFixed(6); + if(!isNaN(iPrecision)) + { rsep = absArg.toExponential(iPrecision); + rse = rsep.length < rse.length ? rsep : rse; + rsfp = absArg.toFixed(iPrecision); + rsf = rsfp.length < rsf.length ? rsfp : rsf; + } + if(rse.indexOf('.')<0 && flags.indexOf('#')>=0) rse = rse.replace(/^(.*)(e.*)$/,'$1.$2'); + if(rsf.indexOf('.')<0 && flags.indexOf('#')>=0) rsf = rsf + '.'; + rs = rse.length=0) rs='0'+rs; + return processFlags(flags,width,rs,arg); + } + converters['X'] = function(flags,width,precision,arg) + { return (converters['x'](flags,width,precision,arg)).toUpperCase(); + } + converters['x'] = function(flags,width,precision,arg) + { var iPrecision=parseInt(precision); + arg = Math.abs(arg); + var rs = Math.round(arg).toString(16); + if(rs.length=0) rs='0x'+rs; + return processFlags(flags,width,rs,arg); + } + converters['s'] = function(flags,width,precision,arg) + { var iPrecision=parseInt(precision); + var rs = arg; + if(rs.length > iPrecision) rs = rs.substring(0,iPrecision); + return processFlags(flags,width,rs,0); + } + farr = fstring.split('%'); + retstr = farr[0]; + fpRE = /^([-+ #]*)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/; + for(var i=1; i, to . + * @return {String} - the XML String inside the object. + */ + me.getOuterXML = function (node, options) { + var r; + // Internet Explorer + if (node.xml) { + r = node.xml; + + // Everyone else + } else if (node.outerHTML) { + r = node.outerHTML; + } else if (window.XMLSerializer) { + + var serializer = new XMLSerializer(); + var text = serializer.serializeToString(node); + r = text; + } else { + return null; + } + + /* + * If the XML is actually HTML and you are inserting it into an HTML + * document, you must use the "insertClosingTags" option, otherwise + * Opera will not like you, especially if you have empty tags. + */ + if (options) { + if (options.insertClosingTags) { + r = r.replace(selfClosingTagRe, "<$1>"); + } + } + return r; + } + } + + + // default styles + var placeholderCSS = 'color: #999999; font-style: italic'; + var placeholderRequiredCSS = 'color: #ffcccc !important;' + + var sb = ""; + + // has to be two seperate rules, or some browsers, like firefox, will not use the rule. + if (document.getElementsByTagName('body').length == 0) { + sb = ''; + + + document.write(sb); + } +} + + + +EventHelpers.addPageLoadEvent('html5Widgets.init'); + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/.DS_Store b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b42dd969bbfb7a5f87121ebe8d3ae71324300f5e GIT binary patch literal 6148 zcmeHKO>7%Q6n@Wf+TCQAP6{mzP+<}TMMPC>XsGxRi{sLkwlu1p+NA+^?H!sGn_c5s z+Yynep;vwcCnN--CnUHa=-;sdfsiJ_6-=!w(i<)~NoJ>GEJ&ni83 zevee_Vp?Z13(@QNl5>6}qwCpd)jr2M&#Ky;IHDD&ZP9X}4&VUCSk_DzSMIuj5#l^t$I;X<2Bf1OP<-JsbC+?YQR1ZDpvE~?Ea=&Xc7 zMmO705G+K(m(!f8#e6lEF&kX9XGGMF=T%~zv5w#;IL+yId5LBgHJ?h#L#(bMo?^Oh4F9vRd2bC9S ztEyeSq)O_tE4R*;?=DqfPHp`Hyy)*V+i;Wn})!w}IfXzlt=4tPowclb{lL_s8 z#CptTTTFIDd7W{qXbmgMdOGNUeb8ox!M--8omEF|^|Z4`Z~3$a0CU=zO>_fxLjg)q zgEP>EHFzD~fsf%LT!t%f6~2M%a07mUU*R|S9Y=8tCvgh*U;+1|gGHRjC-ERI;0Y|_ zBA&!Ly4XMuIfmH67g1o0eLRN)d=<~*YxoAfiErWC_%6PO@8bt}0YAb|@iV-PSMVBs zj$h!H_!WMO-{TGZNk3s``15^w`1Bg_=k@mHSjoc}ItdOml7|F!Dxprr+21c~Wf|xXh^%1flX!L4?6Js AJpcdz literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/ChangeLog b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/ChangeLog new file mode 100644 index 0000000..712f773 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/ChangeLog @@ -0,0 +1,761 @@ +2005-03-07 Mihai Bazon + + * skins/aqua/theme.css: *** empty log message *** + + * release-notes.html: updated release notes + + * calendar-setup.js: + use a better approach to initialize the calendar--don't call _init twice, + it's the most time consuming function in the calendar. Instead, determine + the date beforehand if possible and pass it to the calendar at constructor. + + * calendar.js: + avoid keyboard operation when 'multiple dates' is set (very buggy for now) + + * calendar.js: + fixed keyboard handling problems: now it works fine when "showsOtherMonths" + is passed; it also seems to be fine with disabled dates (won't normally + allow selection)--however this area is still likely to be buggy, i.e. in a + month that has all the dates disabled. + + * calendar.js: + some trivial performance improvements in the _init function + Added Date.parseDate (old Calendar.prototype.parseDate now calls this one) + +2005-03-05 Mihai Bazon + + * release-notes.html: updated release notes + + * dayinfo.html: *** empty log message *** + + * calendar-setup.js: + bugfix--update an inputField even if flat calendar is selected + + * calendar.js: + fixed bugs in parseDate function (if for some reason the input string is + totally broken, then check numbers for NaN and use values from the current + date instead) + + * make-release.pl: copy the skins subdirectory and all skins + + * index.html: added Aqua skin + + * skins/aqua/active-bg.gif, skins/aqua/dark-bg.gif, skins/aqua/hover-bg.gif, skins/aqua/menuarrow.gif, skins/aqua/normal-bg.gif, skins/aqua/rowhover-bg.gif, skins/aqua/status-bg.gif, skins/aqua/theme.css, skins/aqua/title-bg.gif, skins/aqua/today-bg.gif: + in the future, skins will go to this directory, each in a separate subdir; for now there's only Aqua, an excellent new skin + + * calendar.js: workaround IE bug, needed in the Aqua theme + don't hide select elements unless browser is IE or Opera + + * lang/calendar-bg.js, lang/calendar-big5-utf8.js, lang/calendar-big5.js, lang/calendar-br.js, lang/calendar-ca.js, lang/calendar-cs-utf8.js, lang/calendar-cs-win.js, lang/calendar-da.js, lang/calendar-de.js, lang/calendar-el.js, lang/calendar-en.js, lang/calendar-es.js, lang/calendar-fi.js, lang/calendar-fr.js, lang/calendar-he-utf8.js, lang/calendar-hu.js, lang/calendar-it.js, lang/calendar-ko-utf8.js, lang/calendar-ko.js, lang/calendar-lt-utf8.js, lang/calendar-lt.js, lang/calendar-lv.js, lang/calendar-nl.js, lang/calendar-no.js, lang/calendar-pl-utf8.js, lang/calendar-pl.js, lang/calendar-pt.js, lang/calendar-ro.js, lang/calendar-ru.js, lang/calendar-ru_win_.js, lang/calendar-si.js, lang/calendar-sk.js, lang/calendar-sp.js, lang/calendar-sv.js, lang/calendar-zh.js, lang/cn_utf8.js: + updated urls, copyright notices + + * doc/reference.tex: updated documentation + + * calendar.js, index.html: + renamed the global variable to _dynarch_popupCalendar to avoid name clashes + + * multiple-dates.html: start with an empty array + + * calendar.js: + fixed bugs in the time selector (12:XX pm was wrongfully understood as 12:XX am) + + * calendar.js: + using innerHTML instead of text nodes; works better in Safari and also makes + a smaller, cleaner code + +2005-03-04 Mihai Bazon + + * calendar.js: + fixed a performance regression that occurred after adding support for multiple dates + fixed the time selection bug (now it keeps time correctly) + clicking today will close the calendar if "today" is already selected + + * lang/cn_utf8.js: new translation + +2005-02-17 Mihai Bazon + + * lang/calendar-ar-utf8.zip: Added arabic translation + +2004-10-19 Mihai Bazon + + * lang/calendar-zh.js: updated + +2004-09-20 Mihai Bazon + + * lang/calendar-no.js: updated (Daniel Holmen) + +2004-09-20 Mihai Bazon + + * lang/calendar-no.js: updated (Daniel Holmen) + +2004-08-11 Mihai Bazon + + * lang/calendar-nl.js: updated language file (thanks to Arjen Duursma) + + * lang/calendar-sp.js: updated (thanks to Rafael Velasco) + +2004-07-21 Mihai Bazon + + * lang/calendar-br.js: updated + + * calendar-setup.js: fixed bug (dateText) + +2004-07-21 Mihai Bazon + + * lang/calendar-br.js: updated + + * calendar-setup.js: fixed bug (dateText) + +2004-07-04 Mihai Bazon + + * lang/calendar-lv.js: + added LV translation (thanks to Juris Valdovskis) + +2004-06-25 Mihai Bazon + + * calendar.js: + fixed bug in IE (el.calendar.tooltips is null or not an object) + +2004-06-24 Mihai Bazon + + * doc/reference.tex: fixed latex compilation + + * index.html: linking other sample files + + * calendar-setup.js, calendar.js, dayinfo.html: + ability to display day info (dateText parameter) + sample file + +2004-06-23 Mihai Bazon + + * doc/reference.tex, lang/calendar-bg.js, lang/calendar-br.js, lang/calendar-ca.js, lang/calendar-en.js, lang/calendar-es.js, lang/calendar-fr.js, lang/calendar-it.js, lang/calendar-ko-utf8.js, lang/calendar-ko.js, lang/calendar-nl.js, lang/calendar-sv.js, README, calendar.js, index.html: + email address changed + +2004-06-14 Mihai Bazon + + * lang/calendar-cs-utf8.js, lang/calendar-cs-win.js: + updated translations + + * calendar-system.css: added z-index to drop downs + + * lang/calendar-en.js: + first day of week can now be part of the language file + + * lang/calendar-es.js: + updated language file (thanks to Servilio Afre Puentes) + + * calendar-blue2.css, calendar-brown.css, calendar-green.css, calendar-tas.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css, calendar-blue.css: + added z-index property to drop downs (fixes bug) + +2004-06-13 Mihai Bazon + + * calendar-setup.js: fixed bug (apply showOthers to flat calendars too) + +2004-06-06 Mihai Bazon + + * calendar-setup.js: + firstDay defaults to "null", in which case the value in the language file + will be used + + * calendar.js: + firstDayOfWeek can now default to a value specified in the language definition file + + * index.html: first day of week is now numeric + +2004-06-02 Mihai Bazon + + * calendar.js: added date tooltip function + +2004-05-28 Mihai Bazon + + * lang/calendar-br.js: updated (thanks to Marcos Pont) + + * calendar-setup.js: fixed small bug + +2004-05-01 Mihai Bazon + + * calendar-setup.js: returns the calendar object + +2004-04-28 Mihai Bazon + + * calendar-setup.js: + patch to read the date value from the inputField, according to ifFormat (if + both are passed), for flat calendars. (thanks Colin T. Hill) + +2004-04-20 Mihai Bazon + + * calendar-setup.js, calendar.js, multiple-dates.html: + added support for multiple dates selection + + * lang/calendar-nl.js: + updated Dutch translation, thanks to Jeroen Wolsink + + * lang/calendar-big5-utf8.js, lang/calendar-big5.js: + Traditional Chinese language (thanks GaryFu) + +2004-03-26 Mihai Bazon + + * lang/calendar-fr.js, lang/calendar-pt.js: updated + + * lang/calendar-ru_win_.js, lang/calendar-ru.js: + updated, thanks to Sly Golovanov + +2004-03-25 Mihai Bazon + + * lang/calendar-fr.js: updated (thanks to David Duret) + +2004-03-24 Mihai Bazon + + * lang/calendar-da.js: updated (thanks to Michael Thingmand Henriksen) + +2004-03-21 Mihai Bazon + + * lang/calendar-ca.js: updated (thanks to David Valls) + +2004-03-17 Mihai Bazon + + * lang/calendar-de.js: updated to UTF8 (thanks to Jack (tR)) + +2004-03-09 Mihai Bazon + + * lang/calendar-bg.js: Bulgarian translation + +2004-03-08 Mihai Bazon + + * lang/calendar-he-utf8.js: Hebrew translation (thanks to Idan Sofer) + + * lang/calendar-hu.js: updated (thanks to Istvan Karaszi) + +2004-02-27 Mihai Bazon + + * lang/calendar-it.js: updated (thanks to Fabio Di Bernardini) + +2004-02-25 Mihai Bazon + + * calendar.js: fix for Safari (thanks to Olivier Chirouze / XPWeb) + +2004-02-22 Mihai Bazon + + * lang/calendar-al.js: Albanian language file + +2004-02-17 Mihai Bazon + + * lang/calendar-fr.js: fixed + + * lang/calendar-fr.js: + FR translation updated (thanks to SIMON Alexandre) + + * lang/calendar-es.js: ES translation updated, thanks to David Gonzales + +2004-02-10 Mihai Bazon + + * lang/calendar-pt.js: + updated Portugese translation, thanks to Elcio Ferreira + +2004-02-09 Mihai Bazon + + * TODO: updated + +2004-02-06 Mihai Bazon + + * README: describe the PHP files + + * make-release.pl: includes php files + + * make-release.pl: ChangeLog included in the distribution (if found) + + * calendar.js, doc/reference.tex, index.html: switched to version 0.9.6 + + * doc/Calendar.setup.tex, doc/reference.tex: updated documentation + + * release-notes.html: updated release notes + + * calendar.js: Fixed bug: Feb/29 and year change now keeps Feb in view + + * calendar.js: fixed the "ESC" problem (call the close handler) + + * calendar.js: fixed day of year range (1 to 366 instead of 0 to 365) + + * calendar.js: fixed week number calculations + + * doc/reference.tex: fixed (date input format) + + * calendar.php: removed comment + + * calendar-blue.css, calendar-blue2.css, calendar-brown.css, calendar-green.css, calendar-system.css, calendar-tas.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css, calendar.js: + workaround for IE bug (you can't normally specify through CSS the style for + an element having two classes or more; we had to change a classname) + + * calendar-blue.css, calendar-blue2.css, calendar-brown.css, calendar-green.css, calendar-system.css, calendar-tas.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css: + smaller fonts on days that are in neighbor months + +2004-02-04 Mihai Bazon + + * index.html: first demo shows the "showOtherMonths" capability + + * calendar-setup.js: support new parameters in the calendar. + added: firstDay, showOthers, cache. + + * calendar-blue.css, calendar-blue2.css, calendar-brown.css, calendar-green.css, calendar-system.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css, calendar.js, lang/calendar-en.js, lang/calendar-ro.js: + new parameters: firstDayOfWeek, showsOtherMonths; removed mondayFirst. + This adds support for setting any day to be the first day of week (by just + clicking the day name in the display); also, if showsOtherMonths is enabled + then dates belonging to adjacent months that are in the current view will be + displayed and the calendar will have a fixed height. + + all themes updated. + + * test.php: test for calendar.php + + * calendar.php: fixed bug (pass numeric values as numbers) + +2004-02-01 Mihai Bazon + + * calendar.php: added PHP wrapper + + * img.gif: icon updated + + * TODO: updated TODO list + +2004-01-27 Mihai Bazon + + * calendar.js: + Janusz Piwowarski sent over a patch for IE5 compatibility which is much more + elegant than the atrocities that I had wrote :-D I'm gettin' old.. Thanks Janusz! + + * lang/calendar-fi.js: updated + +2004-01-15 Mihai Bazon + + * TODO: updated TODO list + + * calendar-setup.js: default align changed to "Br" + + * doc/reference.tex: changed default value for "align" + + * calendar-setup.js: calling onchange event handler, if available + + * calendar-setup.js: added "position" option + + * simple-1.html: demonstrates "step" option + + * calendar-setup.js: added "step" option + + * calendar.js: added yearStep config parameter + + * calendar.js: + fixed parseDate routine (the NaN bug which occurred when there was a space + after the date and no time) + +2004-01-14 Mihai Bazon + + * lang/calendar-en.js: added "Time:" + + * test-position.html: test for the new position algorithm + + * index.html: do not destroy() the calendar + avoid bug in parseDate (%p must be separated by non-word characters) + + * menuarrow2.gif: for calendar-blue2.css + + * calendar-setup.js: honor "date" parameter if passed + + * calendar.js: IE5 support is back + performance improvements in IE6 (mouseover combo boxes) + display "Time:" beside the clock area, if defined in the language file + new positioning algorithm (try to keep the calendar in page) + rewrote parseDate a little cleaner + + * lang/calendar-el.js: + updated Greek translation (thanks Alexandros Pappas) + +2004-01-13 Mihai Bazon + + * index.html: added style blue2, using utf-8 instead of iso-8859-2 + + * calendar.js: performance under IE (which sucks, by the way) + + * doc/reference.tex: Sunny added to sponsor list + + * doc/Calendar.setup.tex: documenting parameter 'electric' + + * calendar-blue.css, calendar-blue2.css, calendar-brown.css, calendar-green.css, calendar-system.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css: + fixed IE text size problems + +2004-01-08 Mihai Bazon + + * lang/calendar-pl.js: + Polish translation updated to UTF-8 (thanks to Artur Filipiak) + +2004-01-07 Mihai Bazon + + * lang/calendar-si.js: updated (David Milost) + + * lang/calendar-si.js: Slovenian translation (thanks to David Milost) + +2003-12-21 Mihai Bazon + + * TODO: updated TODO list + + * lang/calendar-de.js: German translation (thanks to Peter Strotmann) + +2003-12-19 Mihai Bazon + + * doc/reference.tex: Thank you, Ian Barrak + +2003-12-18 Mihai Bazon + + * doc/reference.tex: fixed documentation bug (thanks Mike) + +2003-12-05 Mihai Bazon + + * lang/calendar-ko-utf8.js: + UTF8 version of the Korean language (hopefully correct) + + * lang/calendar-pl-utf8.js, lang/calendar-pl.js: + updated Polish translation (thanks to Janusz Piwowarski) + +2003-12-04 Mihai Bazon + + * lang/calendar-fr.js: + French translation updated (thanks to Angiras Rama) + +2003-11-22 Mihai Bazon + + * lang/calendar-da.js: updated (thanks to Jesper M. Christensen) + +2003-11-20 Mihai Bazon + + * calendar-blue2.css, calendar-tas.css: + new styles (thanks to Wendall Mosemann for blue2, Mark Lynch for tas) + + * lang/calendar-lt-utf8.js, lang/calendar-lt.js: + Lithuanian translation (thanks to Martynas Majeris) + + * lang/calendar-sp.js: updated + +2003-11-17 Mihai Bazon + + * TODO: added TODO list + +2003-11-14 Mihai Bazon + + * lang/calendar-ko.js: Korean translation (thanks to Yourim Yi) + +2003-11-12 Mihai Bazon + + * lang/calendar-jp.js: small bug fixed (thanks to TAHARA Yusei) + +2003-11-10 Mihai Bazon + + * lang/calendar-fr.js: translation updated, thanks to Florent Ramiere + + * calendar-setup.js: + added new parameter: electric (if false then the field will not get updated on each move) + + * index.html: fixed DOCTYPE + +2003-11-07 Mihai Bazon + + * calendar-setup.js: + fixed minor problem (maybe we're passing object reference instead of ID for + the flat calendar parent) + +2003-11-06 Mihai Bazon + + * lang/calendar-fi.js: + added Finnish translation (thanks to Antti Tuppurainen) + +2003-11-05 Mihai Bazon + + * release-notes.html: fixed typo + + * doc/reference.tex, index.html, calendar.js: 0.9.5 + + * README: fixed license statement + + * release-notes.html: updated release notes (0.9.5) + +2003-11-03 Mihai Bazon + + * lang/calendar-de.js: + updated German translation (thanks to Gerhard Neiner) + + * calendar-setup.js: fixed license statement + + * calendar.js: whitespace + + * calendar.js: fixed license statement + + * calendar.js: + fixed positioning problem when input field is inside scrolled divs + +2003-11-01 Mihai Bazon + + * lang/calendar-af.js: Afrikaan language (thanks to Derick Olivier) + +2003-10-31 Mihai Bazon + + * lang/calendar-it.js: + updated IT translation (thanks to Christian Blaser) + + * lang/calendar-es.js: updated ES translation, thanks to Raul + +2003-10-30 Mihai Bazon + + * lang/calendar-hu.js: updated thanks to Istvan Karaszi + + * index.html, simple-1.html, simple-2.html, simple-3.html: + switched to utf-8 all encodings + + * lang/calendar-sk.js: + added Slovak translation (thanks to Peter Valach) + + * lang/calendar-ro.js: switched to utf-8 + +2003-10-29 Mihai Bazon + + * lang/calendar-es.js: + updated translation, thanks to Jose Ma. Martinez Miralles + + * doc/reference.tex: + fixed the footnote problem (thanks Dominique de Waleffe for the tip) + + * lang/calendar-ro.js: fixed typo + + * lang/calendar-sv.js: oops, license should be LGPL + + * lang/calendar-sw.js: new swedish translation is calendar-sv.js + + * menuarrow.gif, menuarrow.png: + oops, forgot little drop-down menu arrows + + * lang/calendar-sv.js: swedish translation thanks to Leonard Norrgard + + * index.html: oops, some other minor changes + + * index.html, release-notes.html: + latest changes in release-notes and index page for 0.9.4 + + * doc/reference.tex, calendar.js: + added %s date format (# of seconds since Epoch) + + * calendar.js: + A click on TODAY will not close the calendar, even in single-click mode + +2003-10-28 Mihai Bazon + + * index.html: previous cal.html + + * cal.html: moved to index.html + + * README, cal.html, doc/reference.tex, lang/calendar-de.js, lang/calendar-en.js, lang/calendar-ro.js, release-notes.html: + LGPL license, forever. + + * doc/Calendar.setup.tex, simple-1.html: + doc updated for the onUpdate parameter to Calendar.setup + +2003-10-26 Mihai Bazon + + * calendar.js: fixed bug (correct display of the dropdown menus) + + * doc/Calendar.setup.tex, doc/reference.tex, lang/calendar-de.js, lang/calendar-en.js, lang/calendar-ro.js, README, cal.html, calendar-blue.css, calendar-brown.css, calendar-green.css, calendar-setup.js, calendar-system.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css, calendar.js, release-notes.html, simple-1.html, simple-3.html: + lots of changes for the 0.9.4 release (see the release-notes.html) + +2003-10-15 Mihai Bazon + + * doc/reference.tex: + documentation updated for 0.9.4 (not yet finished though) + +2003-10-07 Mihai Bazon + + * calendar.js, doc/reference.tex, release-notes.html, README, cal.html, calendar-setup.js: + modified project website + +2003-10-06 Mihai Bazon + + * calendar-setup.js: + added some properties (onSelect, onClose, date) (thanks altblue) + +2003-09-24 Mihai Bazon + + * simple-3.html: dateIsSpecial does not need the "date" argument ;-) + +2003-09-24 fsoft + + * calendar.js, simple-3.html: + added year, month, day to getDateStatus() function + +2003-09-24 Mihai Bazon + + * simple-3.html: example on how to use special dates + + * calendar-setup.js, calendar.js, simple-1.html: + support for special dates (thanks fabio) + +2003-09-17 Mihai Bazon + + * doc/reference.tex: fixed error in section 3. + +2003-08-01 Mihai Bazon + + * lang/calendar-jp.js: added Japanese translation + +2003-07-16 Mihai Bazon + + * simple-1.html: fixed problem with first example [IE,Opera] + +2003-07-09 Mihai Bazon + + * doc/Calendar.setup.tex: fixed typo (closing parenthesis) + + * lang/calendar-de.js: + added German translation, thanks to Hartwig Weinkauf + +2003-07-08 Mihai Bazon + + * cal.html: added link to release-notes + + * release-notes.html: 0.9.3 release notes + + * make-release.pl: + Script to create distribution archive. It needs some additional packages: + + - LaTeX + - tex2page + - jscrunch (JS compressor) + + * doc/html/makedoc.sh, doc/html/reference.css, doc/reference.tex, doc/makedoc.sh: + documentation updates... + + * calendar.js: added semicolon to make the code "compressible" + +2003-07-06 Mihai Bazon + + * doc/reference.tex: spell checked + + * doc/reference.tex: [minor] changed credits order + + * doc/reference.tex: various improvements and additions + + * doc/html/reference.css: minor eye-candy tweaks + +2003-07-05 Mihai Bazon + + * doc/html/Calendar.setup.html.tex, doc/html/makedoc.sh, doc/html/reference.css, doc/html/reference.t2p, doc/hyperref.cfg, doc/makedoc.sh, doc/reference.tex, doc/Calendar.setup.tex, doc/Calendar.setup.pdf.tex: + full documentation in LaTeX, for PDF and HTML formats + + * simple-2.html: + added demonstration of flat calendar with Calendar.setup + + * simple-1.html: + modified some links, added link to documentation, added demonstration of + disableFunc property + + * calendar-setup.js: added the ability to create flat calendar too + + * cal.html: added links to documentation and simple-[12].html pages + + * README: up-to-date... + + * calendar-setup.html: removed: the documentation is unified + +2003-07-03 Mihai Bazon + + * cal.html: some links to newly added files + + * calendar-setup.html, calendar-setup.js, img.gif, simple-1.html: + added some files to simplify calendar creation for non-(JS)-programmers + + * lang/calendar-zh.js: added simplified chinese (thanks ATang) + +2003-07-02 Mihai Bazon + + * calendar.js: * "yy"-related... [small fix] + + * calendar.js: + * #721833 fixed (yy format will understand years prior to 29 as 20xx) + + * calendar.js: * added refresh() function + + * calendar.js: * fixed bug when in single click mode + * added alignment options to "showAtElement" member function + +2003-06-25 Mihai Bazon + + * lang/calendar-pt.js: + added portugese translation (thanks Nuno Barreto) + +2003-06-24 Mihai Bazon + + * calendar.js: + call user handler when the date was changed using the keyboard + + * bugtest-hidden-selects.html: + file to test bug with hidden select-s (thanks Ying Zhang for reporting and for this test file) + + * lang/calendar-hr-utf8.js: + added croatian translation in utf8 (thanks Krunoslav Zubrinic) + +2003-06-23 Mihai Bazon + + * lang/calendar-hu.js: added hungarian translation + + * lang/calendar-hr.js: + added croatian translation (thanks to Krunoslav Zubrinic) + +2003-06-22 Mihai Bazon + + * calendar.js: + * #723335 fixed (clicking TODAY will not select the today date if the + disabledHandler rejects it) + + * cal.html: * new code for to work with fix for bug #703238 + * switch to new version + + * calendar.js: + * some patches to make code compatible with Opera 7 (well, almost compatible) + * bug #703238 fixed (fix breaks compatibility with older code that uses + calendar in single-click mode) + * bug #703814 fixed + +2003-04-09 Mihai Bazon + + * lang/calendar-tr.js: added turkish lang file + +2003-03-19 Mihai Bazon + + * lang/calendar-ru.js: russian translation added + + * lang/calendar-no.js: norwegian translation added + +2003-03-15 Mihai Bazon + + * lang/calendar-no.js: norwegian translation + +2003-03-12 Mihai Bazon + + * lang/calendar-pl.js: added polish translation + +2003-03-11 Mihai Bazon + + * calendar.js: + bugfix in parseDate (added base to parseInt, thanks Alan!) + +2003-03-05 Mihai Bazon + + * calendar.js, lang/calendar-br.js, lang/calendar-ca.js, lang/calendar-cs-win.js, lang/calendar-da.js, lang/calendar-du.js, lang/calendar-el.js, lang/calendar-en.js, lang/calendar-es.js, lang/calendar-fr.js, lang/calendar-it.js, lang/calendar-nl.js, lang/calendar-ro.js, lang/calendar-sp.js, lang/calendar-sw.js: + New file. + + * calendar.js, lang/calendar-br.js, lang/calendar-ca.js, lang/calendar-cs-win.js, lang/calendar-da.js, lang/calendar-du.js, lang/calendar-el.js, lang/calendar-en.js, lang/calendar-es.js, lang/calendar-fr.js, lang/calendar-it.js, lang/calendar-nl.js, lang/calendar-ro.js, lang/calendar-sp.js, lang/calendar-sw.js: + moved to CVS at sourceforge.net + release: 0.9.2 + new language packs + + + * README, cal.html, calendar-blue.css, calendar-brown.css, calendar-green.css, calendar-system.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css: + New file. + + * README, cal.html, calendar-blue.css, calendar-brown.css, calendar-green.css, calendar-system.css, calendar-win2k-1.css, calendar-win2k-2.css, calendar-win2k-cold-1.css, calendar-win2k-cold-2.css: + moved to CVS at sourceforge.net + release: 0.9.2 + new language packs + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/README b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/README new file mode 100644 index 0000000..455ab3d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/README @@ -0,0 +1,33 @@ +The DHTML Calendar +------------------- + + Author: Mihai Bazon, + http://dynarch.com/mishoo/ + + This program is free software published under the + terms of the GNU Lesser General Public License. + + For the entire license text please refer to + http://www.gnu.org/licenses/lgpl.html + +Contents +--------- + + calendar.js -- the main program file + lang/*.js -- internalization files + *.css -- color themes + cal.html -- example usage file + doc/ -- documentation, in PDF and HTML + simple-1.html -- quick setup examples [popup calendars] + simple-2.html -- quick setup example for flat calendar + calendar.php -- PHP wrapper + test.php -- test file for the PHP wrapper + +Homepage +--------- + + For details and latest versions please refer to calendar + homepage, located on my website: + + http://dynarch.com/mishoo/calendar.epl + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/altblue.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/altblue.html new file mode 100644 index 0000000..1de7463 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/altblue.html @@ -0,0 +1,23 @@ + + + + + calendar test + + + + + + + + +
    +
    + + + + click the button for a calendar +
    +
    + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/bugtest-hidden-selects.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/bugtest-hidden-selects.html new file mode 100644 index 0000000..fd955c0 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/bugtest-hidden-selects.html @@ -0,0 +1,108 @@ + + + +Bug + + + + + + + + + + + + + +
    +Date: +
    + + +

    +
    +
    Visible <select>, hides and unhides as expected +
    + + +

    +
    Hidden <select>, it should stay hidden (but doesn't) +
    + + +

    +
    Hidden textbox below, it stays hidden as expected +
    + +

    + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-blue.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-blue.css new file mode 100644 index 0000000..62ecf99 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-blue.css @@ -0,0 +1,232 @@ +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #556; + font-size: 11px; + color: #000; + cursor: default; + background: #eef; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ +} + +.calendar .nav { + background: #778 url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + background: #fff; + color: #000; + padding: 2px; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ + background: #778; + color: #fff; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #bdf; +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #556; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #a66; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #aaf; + color: #000; + border: 1px solid #04f; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #77c; + padding: 2px 0px 0px 2px; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + color: #456; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { + color: #fbb; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #bdf; +} + +.calendar tbody .rowhilite td { + background: #def; +} + +.calendar tbody .rowhilite td.wn { + background: #eef; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #def; + padding: 1px 3px 1px 1px; + border: 1px solid #bbb; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #cde; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #fff; + color: #000; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #a66; +} + +.calendar tbody td.today { /* Cell showing selected date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #556; + color: #fff; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: #fff; + color: #445; + border-top: 1px solid #556; + padding: 1px; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #aaf; + border: 1px solid #04f; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #77c; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #655; + background: #def; + color: #000; + font-size: 90%; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: #acf; +} + +.calendar .combo .active { + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + background: #eef; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #667; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-blue2.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-blue2.css new file mode 100644 index 0000000..8570aff --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-blue2.css @@ -0,0 +1,236 @@ +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #206A9B; + font-size: 11px; + color: #000; + cursor: default; + background: #F1F8FC; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ +} + +.calendar .nav { + background: #007ED1 url(menuarrow2.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + background: #000; + color: #fff; + padding: 2px; +} + +.calendar thead tr { /* Row containing navigation buttons */ + background: #007ED1; + color: #fff; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #C7E1F3; +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #206A9B; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #a66; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #34ABFA; + color: #000; + border: 1px solid #016DC5; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #006AA9; + border: 1px solid #008AFF; + padding: 2px 0px 0px 2px; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + color: #456; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { + color: #fbb; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #C7E1F3; +} + +.calendar tbody .rowhilite td { + background: #def; +} + +.calendar tbody .rowhilite td.wn { + background: #F1F8FC; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #def; + padding: 1px 3px 1px 1px; + border: 1px solid #8FC4E8; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #cde; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #fff; + color: #000; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #a66; +} + +.calendar tbody td.today { /* Cell showing selected date */ + font-weight: bold; + color: #D50000; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #206A9B; + color: #fff; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: #000; + color: #fff; + border-top: 1px solid #206A9B; + padding: 1px; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #B8DAF0; + border: 1px solid #178AEB; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #006AA9; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #655; + background: #def; + color: #000; + font-size: 90%; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: #34ABFA; + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + font-weight: bold; +} + +.calendar .combo .active { + border-top: 1px solid #46a; + border-bottom: 1px solid #46a; + background: #F1F8FC; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #E3F0F9; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #F1F8FC; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #267DB7; + color: #fff; +} + +.calendar td.time span.active { + border-color: red; + background-color: #000; + color: #A5FF00; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-brown.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-brown.css new file mode 100644 index 0000000..e7b6285 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-brown.css @@ -0,0 +1,225 @@ +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #655; + font-size: 11px; + color: #000; + cursor: default; + background: #ffd; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ +} + +.calendar .nav { + background: #edc url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + background: #654; + color: #fed; + padding: 2px; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ + background: #edc; + color: #000; +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #655; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #faa; + color: #000; + border: 1px solid #f40; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #c77; + padding: 2px 0px 0px 2px; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #fed; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { + color: #fbb; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #fed; +} + +.calendar tbody .rowhilite td { + background: #ddf; +} + +.calendar tbody .rowhilite td.wn { + background: #efe; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #ffe; + padding: 1px 3px 1px 1px; + border: 1px solid #bbb; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #ddc; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #fea; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { font-weight: bold; } + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #988; + color: #000; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + border-top: 1px solid #655; + background: #dcb; + color: #840; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #faa; + border: 1px solid #f40; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #c77; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #655; + background: #ffe; + color: #000; + font-size: 90%; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: #fc8; +} + +.calendar .combo .active { + border-top: 1px solid #a64; + border-bottom: 1px solid #a64; + background: #fee; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #a88; + padding: 1px 0px; + text-align: center; + background-color: #fed; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #988; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #866; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-green.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-green.css new file mode 100644 index 0000000..564666d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-green.css @@ -0,0 +1,229 @@ +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #565; + font-size: 11px; + color: #000; + cursor: default; + background: #efe; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ + background: #676; + color: #fff; + font-size: 90%; +} + +.calendar .nav { + background: #676 url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + padding: 2px; + background: #250; + color: #efa; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #565; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #a66; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #afa; + color: #000; + border: 1px solid #084; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #7c7; + padding: 2px 0px 0px 2px; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #dfb; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + color: #564; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #bbb; +} +.calendar tbody .day.othermonth.oweekend { + color: #fbb; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #8a8; + background: #dfb; +} + +.calendar tbody .rowhilite td { + background: #dfd; +} + +.calendar tbody .rowhilite td.wn { + background: #efe; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #efd; + padding: 1px 3px 1px 1px; + border: 1px solid #bbb; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #dec; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #f8fff8; + color: #000; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #a66; +} + +.calendar tbody td.today { font-weight: bold; color: #0a0; } + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #565; + color: #fff; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + padding: 2px; + background: #250; + color: #efa; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #afa; + border: 1px solid #084; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #7c7; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #565; + background: #efd; + color: #000; + font-size: 90%; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: #af8; +} + +.calendar .combo .active { + border-top: 1px solid #6a4; + border-bottom: 1px solid #6a4; + background: #efe; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #8a8; + padding: 1px 0px; + text-align: center; + background-color: #dfb; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #898; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #686; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-handler.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-handler.js new file mode 100644 index 0000000..92df58e --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-handler.js @@ -0,0 +1,42 @@ +var DateDisabled = { + 0 : [ 21, 25, 28, 29, 30 ], + 1 : [ 15, 16, 17, 19 ] +}; + +var CDate = {}; +(function (date) { + CDate = { + w: date.getDay(), + d: date.getDate(), + m: date.getMonth(), + y: date.getFullYear(), + date: date, + }; + })(new Date); + +function dateStatus (date, y, m, d) { + var diff = date - CDate.date; + if (diff < 172800000 || diff > 5356800000) return true; + + if (DateDisabled && DateDisabled[m]) { + for (var i in DateDisabled[m]) + if (DateDisabled[m][i] == d) + return true; + } + + return false; +}; + +window.onload = function () { + Calendar.setup({ + inputField: 'f_date', + ifFormat: '%u, %e, %m, %Y', + displayArea: 'f_date_show', + daFormat: '%A, %B %e, %Y', + button: 'f_date_trigger', + firstDay: 1, + weekNumbers: false, + range: [CDate.y, CDate.y], + dateStatusFunc: dateStatus + }); +}; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-handler_stripped.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-handler_stripped.js new file mode 100644 index 0000000..3f2c865 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-handler_stripped.js @@ -0,0 +1 @@ +var DateDisabled={0:[21,25,28,29,30],1:[15,16,17,19]};var CDate={};(function(date){CDate={w:date.getDay(),d:date.getDate(),m:date.getMonth(),y:date.getFullYear(),date:date,};})(new Date);function dateStatus(date,y,m,d){var diff=date-CDate.date;if(diff<172800000||diff>5356800000)return true;if(DateDisabled&&DateDisabled[m]){for(var i in DateDisabled[m])if(DateDisabled[m][i]==d)return true;}return false;};window.onload=function(){Calendar.setup({inputField:'f_date',ifFormat:'%u, %e, %m, %Y',displayArea:'f_date_show',daFormat:'%A, %B %e, %Y',button:'f_date_trigger',firstDay:1,weekNumbers:false,range:[CDate.y,CDate.y],dateStatusFunc:dateStatus});}; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-old.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-old.js new file mode 100644 index 0000000..e958eae --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-old.js @@ -0,0 +1,1843 @@ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- + * + * The DHTML Calendar, version 1.0 "It is happening again" + * + * Details and latest version at: + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + +// $Id: calendar-old.js,v 1.1 2010-07-16 02:56:33 tv Exp $ + +/** The Calendar object constructor. */ +Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { + // member variables + this.activeDiv = null; + this.currentDateEl = null; + this.getDateStatus = null; + this.getDateToolTip = null; + this.getDateText = null; + this.timeout = null; + this.onSelected = onSelected || null; + this.onClose = onClose || null; + this.dragging = false; + this.hidden = false; + this.minYear = 1970; + this.maxYear = 2050; + this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"]; + this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"]; + this.isPopup = true; + this.weekNumbers = true; + this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc. + this.showsOtherMonths = false; + this.dateStr = dateStr; + this.ar_days = null; + this.showsTime = false; + this.time24 = true; + this.yearStep = 1; + this.hiliteToday = true; + this.multiple = null; + // HTML elements + this.table = null; + this.element = null; + this.tbody = null; + this.firstdayname = null; + // Combo boxes + this.monthsCombo = null; + this.yearsCombo = null; + this.hilitedMonth = null; + this.activeMonth = null; + this.hilitedYear = null; + this.activeYear = null; + // Information + this.dateClicked = false; + + // one-time initializations + if (typeof Calendar._SDN == "undefined") { + // table of short day names + if (typeof Calendar._SDN_len == "undefined") + Calendar._SDN_len = 3; + var ar = new Array(); + for (var i = 8; i > 0;) { + ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len); + } + Calendar._SDN = ar; + // table of short month names + if (typeof Calendar._SMN_len == "undefined") + Calendar._SMN_len = 3; + ar = new Array(); + for (var i = 12; i > 0;) { + ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len); + } + Calendar._SMN = ar; + } +}; + +// ** constants + +/// "static", needed for event handlers. +Calendar._C = null; + +/// detect a special case of "web browser" +Calendar.is_ie = ( /msie/i.test(navigator.userAgent) && + !/opera/i.test(navigator.userAgent) ); + +Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) ); + +/// detect Opera browser +Calendar.is_opera = /opera/i.test(navigator.userAgent); + +/// detect KHTML-based browsers +Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent); + +// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate +// library, at some point. + +Calendar.getAbsolutePos = function(el) { + var SL = 0, ST = 0; + var is_div = /^div$/i.test(el.tagName); + if (is_div && el.scrollLeft) + SL = el.scrollLeft; + if (is_div && el.scrollTop) + ST = el.scrollTop; + var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST }; + if (el.offsetParent) { + var tmp = this.getAbsolutePos(el.offsetParent); + r.x += tmp.x; + r.y += tmp.y; + } + return r; +}; + +Calendar.isRelated = function (el, evt) { + var related = evt.relatedTarget; + if (!related) { + var type = evt.type; + if (type == "mouseover") { + related = evt.fromElement; + } else if (type == "mouseout") { + related = evt.toElement; + } + } + while (related) { + if (related == el) { + return true; + } + related = related.parentNode; + } + return false; +}; + +Calendar.removeClass = function(el, className) { + if (!(el && el.className)) { + return; + } + var cls = el.className.split(" "); + var ar = new Array(); + for (var i = cls.length; i > 0;) { + if (cls[--i] != className) { + ar[ar.length] = cls[i]; + } + } + el.className = ar.join(" "); +}; + +Calendar.addClass = function(el, className) { + Calendar.removeClass(el, className); + el.className += " " + className; +}; + +// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately. +Calendar.getElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget; + while (f.nodeType != 1 || /^div$/i.test(f.tagName)) + f = f.parentNode; + return f; +}; + +Calendar.getTargetElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.target; + while (f.nodeType != 1) + f = f.parentNode; + return f; +}; + +Calendar.stopEvent = function(ev) { + ev || (ev = window.event); + if (Calendar.is_ie) { + ev.cancelBubble = true; + ev.returnValue = false; + } else { + ev.preventDefault(); + ev.stopPropagation(); + } + return false; +}; + +Calendar.addEvent = function(el, evname, func) { + if (el.attachEvent) { // IE + el.attachEvent("on" + evname, func); + } else if (el.addEventListener) { // Gecko / W3C + el.addEventListener(evname, func, true); + } else { + el["on" + evname] = func; + } +}; + +Calendar.removeEvent = function(el, evname, func) { + if (el.detachEvent) { // IE + el.detachEvent("on" + evname, func); + } else if (el.removeEventListener) { // Gecko / W3C + el.removeEventListener(evname, func, true); + } else { + el["on" + evname] = null; + } +}; + +Calendar.createElement = function(type, parent) { + var el = null; + if (document.createElementNS) { + // use the XHTML namespace; IE won't normally get here unless + // _they_ "fix" the DOM2 implementation. + el = document.createElementNS("http://www.w3.org/1999/xhtml", type); + } else { + el = document.createElement(type); + } + if (typeof parent != "undefined") { + parent.appendChild(el); + } + return el; +}; + +// END: UTILITY FUNCTIONS + +// BEGIN: CALENDAR STATIC FUNCTIONS + +/** Internal -- adds a set of events to make some element behave like a button. */ +Calendar._add_evs = function(el) { + with (Calendar) { + addEvent(el, "mouseover", dayMouseOver); + addEvent(el, "mousedown", dayMouseDown); + addEvent(el, "mouseout", dayMouseOut); + if (is_ie) { + addEvent(el, "dblclick", dayMouseDblClick); + el.setAttribute("unselectable", true); + } + } +}; + +Calendar.findMonth = function(el) { + if (typeof el.month != "undefined") { + return el; + } else if (typeof el.parentNode.month != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.findYear = function(el) { + if (typeof el.year != "undefined") { + return el; + } else if (typeof el.parentNode.year != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.showMonthsCombo = function () { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var mc = cal.monthsCombo; + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + if (cal.activeMonth) { + Calendar.removeClass(cal.activeMonth, "active"); + } + var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()]; + Calendar.addClass(mon, "active"); + cal.activeMonth = mon; + var s = mc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var mcw = mc.offsetWidth; + if (typeof mcw == "undefined") + // Konqueror brain-dead techniques + mcw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; +}; + +Calendar.showYearsCombo = function (fwd) { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var yc = cal.yearsCombo; + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + if (cal.activeYear) { + Calendar.removeClass(cal.activeYear, "active"); + } + cal.activeYear = null; + var Y = cal.date.getFullYear() + (fwd ? 1 : -1); + var yr = yc.firstChild; + var show = false; + for (var i = 12; i > 0; --i) { + if (Y >= cal.minYear && Y <= cal.maxYear) { + yr.innerHTML = Y; + yr.year = Y; + yr.style.display = "block"; + show = true; + } else { + yr.style.display = "none"; + } + yr = yr.nextSibling; + Y += fwd ? cal.yearStep : -cal.yearStep; + } + if (show) { + var s = yc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var ycw = yc.offsetWidth; + if (typeof ycw == "undefined") + // Konqueror brain-dead techniques + ycw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; + } +}; + +// event handlers + +Calendar.tableMouseUp = function(ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + if (cal.timeout) { + clearTimeout(cal.timeout); + } + var el = cal.activeDiv; + if (!el) { + return false; + } + var target = Calendar.getTargetElement(ev); + ev || (ev = window.event); + Calendar.removeClass(el, "active"); + if (target == el || target.parentNode == el) { + Calendar.cellClick(el, ev); + } + var mon = Calendar.findMonth(target); + var date = null; + if (mon) { + date = new Date(cal.date); + if (mon.month != date.getMonth()) { + date.setMonth(mon.month); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } else { + var year = Calendar.findYear(target); + if (year) { + date = new Date(cal.date); + if (year.year != date.getFullYear()) { + date.setFullYear(year.year); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } + } + with (Calendar) { + removeEvent(document, "mouseup", tableMouseUp); + removeEvent(document, "mouseover", tableMouseOver); + removeEvent(document, "mousemove", tableMouseOver); + cal._hideCombos(); + _C = null; + return stopEvent(ev); + } +}; + +Calendar.tableMouseOver = function (ev) { + var cal = Calendar._C; + if (!cal) { + return; + } + var el = cal.activeDiv; + var target = Calendar.getTargetElement(ev); + if (target == el || target.parentNode == el) { + Calendar.addClass(el, "hilite active"); + Calendar.addClass(el.parentNode, "rowhilite"); + } else { + if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2))) + Calendar.removeClass(el, "active"); + Calendar.removeClass(el, "hilite"); + Calendar.removeClass(el.parentNode, "rowhilite"); + } + ev || (ev = window.event); + if (el.navtype == 50 && target != el) { + var pos = Calendar.getAbsolutePos(el); + var w = el.offsetWidth; + var x = ev.clientX; + var dx; + var decrease = true; + if (x > pos.x + w) { + dx = x - pos.x - w; + decrease = false; + } else + dx = pos.x - x; + + if (dx < 0) dx = 0; + var range = el._range; + var current = el._current; + var count = Math.floor(dx / 10) % range.length; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + while (count-- > 0) + if (decrease) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + + cal.onUpdateTime(); + } + var mon = Calendar.findMonth(target); + if (mon) { + if (mon.month != cal.date.getMonth()) { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + Calendar.addClass(mon, "hilite"); + cal.hilitedMonth = mon; + } else if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + } else { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + var year = Calendar.findYear(target); + if (year) { + if (year.year != cal.date.getFullYear()) { + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + Calendar.addClass(year, "hilite"); + cal.hilitedYear = year; + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.tableMouseDown = function (ev) { + if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) { + return Calendar.stopEvent(ev); + } +}; + +Calendar.calDragIt = function (ev) { + var cal = Calendar._C; + if (!(cal && cal.dragging)) { + return false; + } + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posX = ev.pageX; + posY = ev.pageY; + } + cal.hideShowCovered(); + var st = cal.element.style; + st.left = (posX - cal.xOffs) + "px"; + st.top = (posY - cal.yOffs) + "px"; + return Calendar.stopEvent(ev); +}; + +Calendar.calDragEnd = function (ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + cal.dragging = false; + with (Calendar) { + removeEvent(document, "mousemove", calDragIt); + removeEvent(document, "mouseup", calDragEnd); + tableMouseUp(ev); + } + cal.hideShowCovered(); +}; + +Calendar.dayMouseDown = function(ev) { + var el = Calendar.getElement(ev); + if (el.disabled) { + return false; + } + var cal = el.calendar; + cal.activeDiv = el; + Calendar._C = cal; + if (el.navtype != 300) with (Calendar) { + if (el.navtype == 50) { + el._current = el.innerHTML; + addEvent(document, "mousemove", tableMouseOver); + } else + addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver); + addClass(el, "hilite active"); + addEvent(document, "mouseup", tableMouseUp); + } else if (cal.isPopup) { + cal._dragStart(ev); + } + if (el.navtype == -1 || el.navtype == 1) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250); + } else if (el.navtype == -2 || el.navtype == 2) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250); + } else { + cal.timeout = null; + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseDblClick = function(ev) { + Calendar.cellClick(Calendar.getElement(ev), ev || window.event); + if (Calendar.is_ie) { + document.selection.empty(); + } +}; + +Calendar.dayMouseOver = function(ev) { + var el = Calendar.getElement(ev); + if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) { + return false; + } + if (el.ttip) { + if (el.ttip.substr(0, 1) == "_") { + el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1); + } + el.calendar.tooltips.innerHTML = el.ttip; + } + if (el.navtype != 300) { + Calendar.addClass(el, "hilite"); + if (el.caldate) { + Calendar.addClass(el.parentNode, "rowhilite"); + var cal = el.calendar; + if (cal && cal.getDateToolTip) { + var d = el.caldate; + window.status = d; + el.title = cal.getDateToolTip(d, d.getFullYear(), d.getMonth(), d.getDate()); + } + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseOut = function(ev) { + with (Calendar) { + var el = getElement(ev); + if (isRelated(el, ev) || _C || el.disabled) + return false; + removeClass(el, "hilite"); + if (el.caldate) + removeClass(el.parentNode, "rowhilite"); + if (el.calendar) + el.calendar.tooltips.innerHTML = _TT["SEL_DATE"]; + // return stopEvent(ev); + } +}; + +/** + * A generic "click" handler :) handles all types of buttons defined in this + * calendar. + */ +Calendar.cellClick = function(el, ev) { + var cal = el.calendar; + var closing = false; + var newdate = false; + var date = null; + if (typeof el.navtype == "undefined") { + if (cal.currentDateEl) { + Calendar.removeClass(cal.currentDateEl, "selected"); + Calendar.addClass(el, "selected"); + closing = (cal.currentDateEl == el); + if (!closing) { + cal.currentDateEl = el; + } + } + cal.date.setDateOnly(el.caldate); + date = cal.date; + var other_month = !(cal.dateClicked = !el.otherMonth); + if (!other_month && !cal.currentDateEl && cal.multiple) + cal._toggleMultipleDate(new Date(date)); + else + newdate = !el.disabled; + // a date was clicked + if (other_month) + cal._init(cal.firstDayOfWeek, date); + } else { + // None button (clear form) + if (el.navtype == 10000) { + cal.params.inputField.value= ""; + cal.callCloseHandler(); + return; + } + + + if (el.navtype == 200) { + Calendar.removeClass(el, "hilite"); + cal.callCloseHandler(); + return; + } + date = new Date(cal.date); + if (el.navtype == 0) { + if (CSSHelpers.isMemberOfClass(cal.params.inputField, 'pastInvalid')) { + date.setDateOnly(addToDate(new Date(), 1)); + } else { + date.setDateOnly(new Date()); // TODAY + } + } + // unless "today" was clicked, we assume no date was clicked so + // the selected handler will know not to close the calenar when + // in single-click mode. + // cal.dateClicked = (el.navtype == 0); + cal.dateClicked = false; + var year = date.getFullYear(); + var mon = date.getMonth(); + function setMonth(m) { + var day = date.getDate(); + var max = date.getMonthDays(m); + if (day > max) { + date.setDate(max); + } + date.setMonth(m); + }; + switch (el.navtype) { + case 400: + Calendar.removeClass(el, "hilite"); + var text = Calendar._TT["ABOUT"]; + if (typeof text != "undefined") { + text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : ""; + } else { + // FIXME: this should be removed as soon as lang files get updated! + text = "Help and about box text is not translated into this language.\n" + + "If you know this language and you feel generous please update\n" + + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" + + "and send it back to to get it into the distribution ;-)\n\n" + + "Thank you!\n" + + "http://dynarch.com/mishoo/calendar.epl\n"; + } + alert(text); + return; + case -2: + if (year > cal.minYear) { + date.setFullYear(year - 1); + } + break; + case -1: + if (mon > 0) { + setMonth(mon - 1); + } else if (year-- > cal.minYear) { + date.setFullYear(year); + setMonth(11); + } + break; + case 1: + if (mon < 11) { + setMonth(mon + 1); + } else if (year < cal.maxYear) { + date.setFullYear(year + 1); + setMonth(0); + } + break; + case 2: + if (year < cal.maxYear) { + date.setFullYear(year + 1); + } + break; + case 100: + cal.setFirstDayOfWeek(el.fdow); + return; + case 50: + var range = el._range; + var current = el.innerHTML; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + if (ev && ev.shiftKey) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + cal.onUpdateTime(); + return; + case 0: + // TODAY will bring us here + if ((typeof cal.getDateStatus == "function") && + cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { + return false; + } + break; + } + if (!date.equalsTo(cal.date)) { + cal.setDate(date); + newdate = true; + } else if (el.navtype == 0) + newdate = closing = true; + } + if (newdate) { + ev && cal.callHandler(); + } + if (closing) { + Calendar.removeClass(el, "hilite"); + ev && cal.callCloseHandler(); + } +}; + +// END: CALENDAR STATIC FUNCTIONS + +// BEGIN: CALENDAR OBJECT FUNCTIONS + +/** + * This function creates the calendar inside the given parent. If _par is + * null than it creates a popup calendar inside the BODY element. If _par is + * an element, be it BODY, then it creates a non-popup calendar (still + * hidden). Some properties need to be set before calling this function. + */ +Calendar.prototype.create = function (_par) { + var parent = null; + if (! _par) { + // default parent is the document body, in which case we create + // a popup calendar. + parent = document.getElementsByTagName("body")[0]; + this.isPopup = true; + } else { + parent = _par; + this.isPopup = false; + } + this.date = this.dateStr ? new Date(this.dateStr) : new Date(); + + var table = Calendar.createElement("table"); + this.table = table; + table.cellSpacing = 0; + table.cellPadding = 0; + table.calendar = this; + Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown); + + var div = Calendar.createElement("div"); + this.element = div; + div.className = "calendar"; + if (this.isPopup) { + div.style.position = "absolute"; + div.style.display = "none"; + } + div.appendChild(table); + + var thead = Calendar.createElement("thead", table); + var cell = null; + var row = null; + + var cal = this; + var hh = function (text, cs, navtype) { + cell = Calendar.createElement("td", row); + cell.colSpan = cs; + cell.className = "button"; + if (navtype != 0 && Math.abs(navtype) <= 2) + cell.className += " nav"; + Calendar._add_evs(cell); + cell.calendar = cal; + cell.navtype = navtype; + cell.innerHTML = "
    " + text + "
    "; + return cell; + }; + + row = Calendar.createElement("tr", thead); + var title_length = 6; + (this.isPopup) && --title_length; + (this.weekNumbers) && ++title_length; + + hh("?", 1, 400).ttip = Calendar._TT["INFO"]; + this.title = hh("", title_length, 300); + this.title.className = "title"; + if (this.isPopup) { + this.title.ttip = Calendar._TT["DRAG_TO_MOVE"]; + this.title.style.cursor = "move"; + hh("×", 1, 200).ttip = Calendar._TT["CLOSE"]; + } + + row = Calendar.createElement("tr", thead); + row.className = "headrow"; + + this._nav_py = hh("«", 1, -2); + this._nav_py.ttip = Calendar._TT["PREV_YEAR"]; + + this._nav_pm = hh("‹", 1, -1); + this._nav_pm.ttip = Calendar._TT["PREV_MONTH"]; + + + if (CSSHelpers.isMemberOfClass(this.params.inputField, 'pastInvalid')) { + this._nav_now = hh(Calendar._TT["TOMORROW"], this.weekNumbers ? 2 : 1, 0); + this._nav_now.ttip = Calendar._TT["GO_TOMORROW"]; + } else { + this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 2 : 1, 0); + this._nav_now.ttip = Calendar._TT["GO_TODAY"]; + } + + this._nav_none = hh(Calendar._TT["NONE"],this.weekNumbers ? 2 : 1, 10000) + this._nav_none.ttip = Calendar._TT["GO_NONE"]; + + + this._nav_nm = hh("›", 1, 1); + this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"]; + + this._nav_ny = hh("»", 1, 2); + this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"]; + + // day names + row = Calendar.createElement("tr", thead); + row.className = "daynames"; + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + cell.className = "name wn"; + cell.innerHTML = Calendar._TT["WK"]; + } + for (var i = 7; i > 0; --i) { + cell = Calendar.createElement("td", row); + if (!i) { + cell.navtype = 100; + cell.calendar = this; + Calendar._add_evs(cell); + } + } + this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild; + this._displayWeekdays(); + + var tbody = Calendar.createElement("tbody", table); + this.tbody = tbody; + + for (i = 6; i > 0; --i) { + row = Calendar.createElement("tr", tbody); + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + } + for (var j = 7; j > 0; --j) { + cell = Calendar.createElement("td", row); + cell.calendar = this; + Calendar._add_evs(cell); + } + } + + if (this.showsTime) { + row = Calendar.createElement("tr", tbody); + row.className = "time"; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + cell.innerHTML = Calendar._TT["TIME"] || " "; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = this.weekNumbers ? 4 : 3; + + (function(){ + function makeTimePart(className, init, range_start, range_end) { + var part = Calendar.createElement("span", cell); + part.className = className; + part.innerHTML = init; + part.calendar = cal; + part.ttip = Calendar._TT["TIME_PART"]; + part.navtype = 50; + part._range = []; + if (typeof range_start != "number") + part._range = range_start; + else { + for (var i = range_start; i <= range_end; ++i) { + var txt; + if (i < 10 && range_end >= 10) txt = '0' + i; + else txt = '' + i; + part._range[part._range.length] = txt; + } + } + Calendar._add_evs(part); + return part; + }; + var hrs = cal.date.getHours(); + var mins = cal.date.getMinutes(); + var t12 = !cal.time24; + var pm = (hrs > 12); + if (t12 && pm) hrs -= 12; + var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23); + var span = Calendar.createElement("span", cell); + span.innerHTML = ":"; + span.className = "colon"; + var M = makeTimePart("minute", mins, 0, 59); + var AP = null; + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + if (t12) + AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]); + else + cell.innerHTML = " "; + + cal.onSetTime = function() { + var pm, hrs = this.date.getHours(), + mins = this.date.getMinutes(); + if (t12) { + pm = (hrs >= 12); + if (pm) hrs -= 12; + if (hrs == 0) hrs = 12; + AP.innerHTML = pm ? "pm" : "am"; + } + H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs; + M.innerHTML = (mins < 10) ? ("0" + mins) : mins; + }; + + cal.onUpdateTime = function() { + var date = this.date; + var h = parseInt(H.innerHTML, 10); + if (t12) { + if (/pm/i.test(AP.innerHTML) && h < 12) + h += 12; + else if (/am/i.test(AP.innerHTML) && h == 12) + h = 0; + } + var d = date.getDate(); + var m = date.getMonth(); + var y = date.getFullYear(); + date.setHours(h); + date.setMinutes(parseInt(M.innerHTML, 10)); + date.setFullYear(y); + date.setMonth(m); + date.setDate(d); + this.dateClicked = false; + this.callHandler(); + }; + })(); + } else { + this.onSetTime = this.onUpdateTime = function() {}; + } + + var tfoot = Calendar.createElement("tfoot", table); + + row = Calendar.createElement("tr", tfoot); + row.className = "footrow"; + + cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300); + cell.className = "ttip"; + if (this.isPopup) { + cell.ttip = Calendar._TT["DRAG_TO_MOVE"]; + cell.style.cursor = "move"; + } + this.tooltips = cell; + + div = Calendar.createElement("div", this.element); + this.monthsCombo = div; + div.className = "combo"; + for (i = 0; i < Calendar._MN.length; ++i) { + var mn = Calendar.createElement("div"); + mn.className = Calendar.is_ie ? "label-IEfix" : "label"; + mn.month = i; + mn.innerHTML = Calendar._SMN[i]; + div.appendChild(mn); + } + + div = Calendar.createElement("div", this.element); + this.yearsCombo = div; + div.className = "combo"; + for (i = 12; i > 0; --i) { + var yr = Calendar.createElement("div"); + yr.className = Calendar.is_ie ? "label-IEfix" : "label"; + div.appendChild(yr); + } + + this._init(this.firstDayOfWeek, this.date); + parent.appendChild(this.element); +}; + +/** keyboard navigation, only for popup calendars */ +Calendar._keyEvent = function(ev) { + var cal = window._dynarch_popupCalendar; + if (!cal || cal.multiple) + return false; + (Calendar.is_ie) && (ev = window.event); + var act = (Calendar.is_ie || ev.type == "keypress"), + K = ev.keyCode; + if (ev.ctrlKey) { + switch (K) { + case 37: // KEY left + act && Calendar.cellClick(cal._nav_pm); + break; + case 38: // KEY up + act && Calendar.cellClick(cal._nav_py); + break; + case 39: // KEY right + act && Calendar.cellClick(cal._nav_nm); + break; + case 40: // KEY down + act && Calendar.cellClick(cal._nav_ny); + break; + default: + return false; + } + } else switch (K) { + case 32: // KEY space (now) + Calendar.cellClick(cal._nav_now); + break; + case 27: // KEY esc + act && cal.callCloseHandler(); + break; + case 37: // KEY left + case 38: // KEY up + case 39: // KEY right + case 40: // KEY down + if (act) { + var prev, x, y, ne, el, step; + prev = K == 37 || K == 38; + step = (K == 37 || K == 39) ? 1 : 7; + function setVars() { + el = cal.currentDateEl; + + // Bug fix by Zoltan: if el is null, then set it + // to today's date. + if (!el) { + cal.setDate(new Date()); + el = cal.currentDateEl; + alert(el); + } + + var p = el.pos; + x = p & 15; + y = p >> 4; + ne = cal.ar_days[y][x]; + };setVars(); + function prevMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() - step); + cal.setDate(date); + }; + function nextMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() + step); + cal.setDate(date); + }; + while (1) { + switch (K) { + case 37: // KEY left + if (--x >= 0) + ne = cal.ar_days[y][x]; + else { + x = 6; + K = 38; + continue; + } + break; + case 38: // KEY up + if (--y >= 0) + ne = cal.ar_days[y][x]; + else { + prevMonth(); + setVars(); + } + break; + case 39: // KEY right + if (++x < 7) + ne = cal.ar_days[y][x]; + else { + x = 0; + K = 40; + continue; + } + break; + case 40: // KEY down + if (++y < cal.ar_days.length) + ne = cal.ar_days[y][x]; + else { + nextMonth(); + setVars(); + } + break; + } + break; + } + if (ne) { + if (!ne.disabled) + Calendar.cellClick(ne); + else if (prev) + prevMonth(); + else + nextMonth(); + } + } + break; + case 13: // KEY enter + if (act) + Calendar.cellClick(cal.currentDateEl, ev); + break; + default: + return false; + } + return Calendar.stopEvent(ev); +}; + +/** + * (RE)Initializes the calendar to the given date and firstDayOfWeek + */ +Calendar.prototype._init = function (firstDayOfWeek, date) { + var today = new Date(), + TY = today.getFullYear(), + TM = today.getMonth(), + TD = today.getDate(); + this.table.style.visibility = "hidden"; + var year = date.getFullYear(); + if (year < this.minYear) { + year = this.minYear; + date.setFullYear(year); + } else if (year > this.maxYear) { + year = this.maxYear; + date.setFullYear(year); + } + this.firstDayOfWeek = firstDayOfWeek; + this.date = new Date(date); + var month = date.getMonth(); + var mday = date.getDate(); + var no_days = date.getMonthDays(); + + // calendar voodoo for computing the first day that would actually be + // displayed in the calendar, even if it's from the previous month. + // WARNING: this is magic. ;-) + date.setDate(1); + var day1 = (date.getDay() - this.firstDayOfWeek) % 7; + if (day1 < 0) + day1 += 7; + date.setDate(-day1); + date.setDate(date.getDate() + 1); + + var row = this.tbody.firstChild; + var MN = Calendar._SMN[month]; + var ar_days = this.ar_days = new Array(); + var weekend = Calendar._TT["WEEKEND"]; + var dates = this.multiple ? (this.datesCells = {}) : null; + for (var i = 0; i < 6; ++i, row = row.nextSibling) { + var cell = row.firstChild; + if (this.weekNumbers) { + cell.className = "day wn"; + cell.innerHTML = date.getWeekNumber(); + cell = cell.nextSibling; + } + row.className = "daysrow"; + var hasdays = false, iday, dpos = ar_days[i] = []; + for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) { + iday = date.getDate(); + var wday = date.getDay(); + cell.className = "day"; + cell.pos = i << 4 | j; + dpos[j] = cell; + var current_month = (date.getMonth() == month); + if (!current_month) { + if (this.showsOtherMonths) { + cell.className += " othermonth"; + cell.otherMonth = true; + } else { + cell.className = "emptycell"; + cell.innerHTML = " "; + cell.disabled = true; + continue; + } + } else { + cell.otherMonth = false; + hasdays = true; + } + cell.disabled = false; + cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday; + if (dates) + dates[date.print("%Y%m%d")] = cell; + if (this.getDateStatus) { + var status = this.getDateStatus(date, year, month, iday); + if (status === true) { + cell.className += " disabled"; + cell.disabled = true; + } else { + if (/disabled/i.test(status)) + cell.disabled = true; + cell.className += " " + status; + } + } + if (!cell.disabled) { + cell.caldate = new Date(date); + cell.ttip = "_"; + if (!this.multiple && current_month + && iday == mday && this.hiliteToday) { + cell.className += " selected"; + this.currentDateEl = cell; + } + if (date.getFullYear() == TY && + date.getMonth() == TM && + iday == TD) { + cell.className += " today"; + cell.ttip += Calendar._TT["PART_TODAY"]; + } + if (weekend.indexOf(wday.toString()) != -1) + cell.className += cell.otherMonth ? " oweekend" : " weekend"; + } + } + if (!(hasdays || this.showsOtherMonths)) + row.className = "emptyrow"; + } + this.title.innerHTML = Calendar._MN[month] + ", " + year; + this.onSetTime(); + this.table.style.visibility = "visible"; + this._initMultipleDates(); + // PROFILE + // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms"; +}; + +Calendar.prototype._initMultipleDates = function() { + if (this.multiple) { + for (var i in this.multiple) { + var cell = this.datesCells[i]; + var d = this.multiple[i]; + if (!d) + continue; + if (cell) + cell.className += " selected"; + } + } +}; + +Calendar.prototype._toggleMultipleDate = function(date) { + if (this.multiple) { + var ds = date.print("%Y%m%d"); + var cell = this.datesCells[ds]; + if (cell) { + var d = this.multiple[ds]; + if (!d) { + Calendar.addClass(cell, "selected"); + this.multiple[ds] = date; + } else { + Calendar.removeClass(cell, "selected"); + delete this.multiple[ds]; + } + } + } +}; + +Calendar.prototype.setDateToolTipHandler = function (unaryFunction) { + this.getDateToolTip = unaryFunction; +}; + +/** + * Calls _init function above for going to a certain date (but only if the + * date is different than the currently selected one). + */ +Calendar.prototype.setDate = function (date) { + if (!date.equalsTo(this.date)) { + this._init(this.firstDayOfWeek, date); + } +}; + +/** + * Refreshes the calendar. Useful if the "disabledHandler" function is + * dynamic, meaning that the list of disabled date can change at runtime. + * Just * call this function if you think that the list of disabled dates + * should * change. + */ +Calendar.prototype.refresh = function () { + this._init(this.firstDayOfWeek, this.date); +}; + +/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */ +Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) { + this._init(firstDayOfWeek, this.date); + this._displayWeekdays(); +}; + +/** + * Allows customization of what dates are enabled. The "unaryFunction" + * parameter must be a function object that receives the date (as a JS Date + * object) and returns a boolean value. If the returned value is true then + * the passed date will be marked as disabled. + */ +Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) { + this.getDateStatus = unaryFunction; +}; + +/** Customization of allowed year range for the calendar. */ +Calendar.prototype.setRange = function (a, z) { + this.minYear = a; + this.maxYear = z; +}; + +/** Calls the first user handler (selectedHandler). */ +Calendar.prototype.callHandler = function () { + if (this.onSelected && this.dateClicked) { + this.onSelected(this, this.date.print(this.dateFormat)); + } +}; + +/** Calls the second user handler (closeHandler). */ +Calendar.prototype.callCloseHandler = function () { + if (this.onClose) { + this.onClose(this); + } + this.hideShowCovered(); +}; + +/** Removes the calendar object from the DOM tree and destroys it. */ +Calendar.prototype.destroy = function () { + var el = this.element.parentNode; + el.removeChild(this.element); + Calendar._C = null; + window._dynarch_popupCalendar = null; +}; + +/** + * Moves the calendar element to a different section in the DOM tree (changes + * its parent). + */ +Calendar.prototype.reparent = function (new_parent) { + var el = this.element; + el.parentNode.removeChild(el); + new_parent.appendChild(el); +}; + +// This gets called when the user presses a mouse button anywhere in the +// document, if the calendar is shown. If the click was outside the open +// calendar this function closes it. +Calendar._checkCalendar = function(ev) { + var calendar = window._dynarch_popupCalendar; + if (!calendar) { + return false; + } + var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev); + for (; el != null && el != calendar.element; el = el.parentNode); + if (el == null) { + // calls closeHandler which should hide the calendar. + window._dynarch_popupCalendar.callCloseHandler(); + return Calendar.stopEvent(ev); + } +}; + +/** Shows the calendar. */ +Calendar.prototype.show = function () { + var rows = this.table.getElementsByTagName("tr"); + for (var i = rows.length; i > 0;) { + var row = rows[--i]; + Calendar.removeClass(row, "rowhilite"); + var cells = row.getElementsByTagName("td"); + for (var j = cells.length; j > 0;) { + var cell = cells[--j]; + Calendar.removeClass(cell, "hilite"); + Calendar.removeClass(cell, "active"); + } + } + this.element.style.display = "block"; + this.hidden = false; + if (this.isPopup) { + window._dynarch_popupCalendar = this; + Calendar.addEvent(document, "keydown", Calendar._keyEvent); + Calendar.addEvent(document, "keypress", Calendar._keyEvent); + Calendar.addEvent(document, "mousedown", Calendar._checkCalendar); + } + this.hideShowCovered(); +}; + +/** + * Hides the calendar. Also removes any "hilite" from the class of any TD + * element. + */ +Calendar.prototype.hide = function () { + if (this.isPopup) { + Calendar.removeEvent(document, "keydown", Calendar._keyEvent); + Calendar.removeEvent(document, "keypress", Calendar._keyEvent); + Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar); + } + this.element.style.display = "none"; + this.hidden = true; + this.hideShowCovered(); +}; + +/** + * Shows the calendar at a given absolute position (beware that, depending on + * the calendar element style -- position property -- this might be relative + * to the parent's containing rectangle). + */ +Calendar.prototype.showAt = function (x, y) { + var s = this.element.style; + s.left = x + "px"; + s.top = y + "px"; + this.show(); +}; + +/** Shows the calendar near a given element. */ +Calendar.prototype.showAtElement = function (el, opts) { + if (window.calendarHelpers && !window.calendarHelpers.canShowCalendar(el)) { + return; + } + var self = this; + var p = Calendar.getAbsolutePos(el); + if (!opts || typeof opts != "string") { + this.showAt(p.x, p.y + el.offsetHeight); + return true; + } + function fixPosition(box) { + if (box.x < 0) + box.x = 0; + if (box.y < 0) + box.y = 0; + var cp = document.createElement("div"); + var s = cp.style; + s.position = "absolute"; + s.right = s.bottom = s.width = s.height = "0px"; + document.body.appendChild(cp); + var br = Calendar.getAbsolutePos(cp); + document.body.removeChild(cp); + /* if (Calendar.is_ie) { + br.y += document.body.scrollTop; + br.x += document.body.scrollLeft; + } else { */ + br.y += window.scrollY; + br.x += window.scrollX; + //} + var tmp = box.x + box.width - br.x; + if (tmp > 0) box.x -= tmp; + tmp = box.y + box.height - br.y; + if (tmp > 0) box.y -= tmp; + }; + this.element.style.display = "block"; + Calendar.continuation_for_the_fucking_khtml_browser = function() { + var w = self.element.offsetWidth; + var h = self.element.offsetHeight; + self.element.style.display = "none"; + var valign = opts.substr(0, 1); + var halign = "l"; + if (opts.length > 1) { + halign = opts.substr(1, 1); + } + // vertical alignment + switch (valign) { + case "T": p.y -= h; break; + case "B": p.y += el.offsetHeight; break; + case "C": p.y += (el.offsetHeight - h) / 2; break; + case "t": p.y += el.offsetHeight - h; break; + case "b": break; // already there + } + // horizontal alignment + switch (halign) { + case "L": p.x -= w; break; + case "R": p.x += el.offsetWidth; break; + case "C": p.x += (el.offsetWidth - w) / 2; break; + case "l": p.x += el.offsetWidth - w; break; + case "r": break; // already there + } + p.width = w; + p.height = h + 40; + self.monthsCombo.style.display = "none"; + fixPosition(p); + self.showAt(p.x, p.y); + }; + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10); + else + Calendar.continuation_for_the_fucking_khtml_browser(); +}; + +/** Customizes the date format. */ +Calendar.prototype.setDateFormat = function (str) { + this.dateFormat = str; +}; + +/** Customizes the tooltip date format. */ +Calendar.prototype.setTtDateFormat = function (str) { + this.ttDateFormat = str; +}; + +/** + * Tries to identify the date represented in a string. If successful it also + * calls this.setDate which moves the calendar to the given date. + */ +Calendar.prototype.parseDate = function(str, fmt) { + if (!fmt) + fmt = this.dateFormat; + this.setDate(Date.parseDate(str, fmt)); +}; + +Calendar.prototype.hideShowCovered = function () { + if (!Calendar.is_ie && !Calendar.is_opera) + return; + function getVisib(obj){ + var value = obj.style.visibility; + if (!value) { + if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C + if (!Calendar.is_khtml) + value = document.defaultView. + getComputedStyle(obj, "").getPropertyValue("visibility"); + else + value = ''; + } else if (obj.currentStyle) { // IE + value = obj.currentStyle.visibility; + } else + value = ''; + } + return value; + }; + + var tags = new Array("applet", "iframe", "select"); + var el = this.element; + + var p = Calendar.getAbsolutePos(el); + var EX1 = p.x; + var EX2 = el.offsetWidth + EX1; + var EY1 = p.y; + var EY2 = el.offsetHeight + EY1; + + for (var k = tags.length; k > 0; ) { + var ar = document.getElementsByTagName(tags[--k]); + var cc = null; + + for (var i = ar.length; i > 0;) { + cc = ar[--i]; + + p = Calendar.getAbsolutePos(cc); + var CX1 = p.x; + var CX2 = cc.offsetWidth + CX1; + var CY1 = p.y; + var CY2 = cc.offsetHeight + CY1; + + if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = cc.__msh_save_visibility; + } else { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = "hidden"; + } + } + } +}; + +/** Internal function; it displays the bar with the names of the weekday. */ +Calendar.prototype._displayWeekdays = function () { + var fdow = this.firstDayOfWeek; + var cell = this.firstdayname; + var weekend = Calendar._TT["WEEKEND"]; + for (var i = 0; i < 7; ++i) { + cell.className = "day name"; + var realday = (i + fdow) % 7; + if (i) { + cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); + cell.navtype = 100; + cell.calendar = this; + cell.fdow = realday; + Calendar._add_evs(cell); + } + if (weekend.indexOf(realday.toString()) != -1) { + Calendar.addClass(cell, "weekend"); + } + cell.innerHTML = Calendar._SDN[(i + fdow) % 7]; + cell = cell.nextSibling; + } +}; + +/** Internal function. Hides all combo boxes that might be displayed. */ +Calendar.prototype._hideCombos = function () { + this.monthsCombo.style.display = "none"; + this.yearsCombo.style.display = "none"; +}; + +/** Internal function. Starts dragging the element. */ +Calendar.prototype._dragStart = function (ev) { + if (this.dragging) { + return; + } + this.dragging = true; + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posY = ev.clientY + window.scrollY; + posX = ev.clientX + window.scrollX; + } + var st = this.element.style; + this.xOffs = posX - parseInt(st.left); + this.yOffs = posY - parseInt(st.top); + with (Calendar) { + addEvent(document, "mousemove", calDragIt); + addEvent(document, "mouseup", calDragEnd); + } +}; + +// BEGIN: DATE OBJECT PATCHES + +/** Adds the number of days array to the Date object. */ +Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); + +/** Constants used for time computations */ +Date.SECOND = 1000 /* milliseconds */; +Date.MINUTE = 60 * Date.SECOND; +Date.HOUR = 60 * Date.MINUTE; +Date.DAY = 24 * Date.HOUR; +Date.WEEK = 7 * Date.DAY; + +Date.parseDate = function(str, fmt) { + var today = new Date(); + var y = 0; + var m = -1; + var d = 0; + var a = str.split(/\W+/); + var b = fmt.match(/%./g); + var i = 0, j = 0; + var hr = 0; + var min = 0; + for (i = 0; i < a.length; ++i) { + if (!a[i]) + continue; + switch (b[i]) { + case "%d": + case "%e": + d = parseInt(a[i], 10); + break; + + case "%m": + m = parseInt(a[i], 10) - 1; + break; + + case "%Y": + case "%y": + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + break; + + case "%b": + case "%B": + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; } + } + break; + + case "%H": + case "%I": + case "%k": + case "%l": + hr = parseInt(a[i], 10); + break; + + case "%P": + case "%p": + if (/pm/i.test(a[i]) && hr < 12) + hr += 12; + else if (/am/i.test(a[i]) && hr >= 12) + hr -= 12; + break; + + case "%M": + min = parseInt(a[i], 10); + break; + } + } + if (isNaN(y)) y = today.getFullYear(); + if (isNaN(m)) m = today.getMonth(); + if (isNaN(d)) d = today.getDate(); + if (isNaN(hr)) hr = today.getHours(); + if (isNaN(min)) min = today.getMinutes(); + if (y != 0 && m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + y = 0; m = -1; d = 0; + for (i = 0; i < a.length; ++i) { + if (a[i].search(/[a-zA-Z]+/) != -1) { + var t = -1; + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; } + } + if (t != -1) { + if (m != -1) { + d = m+1; + } + m = t; + } + } else if (parseInt(a[i], 10) <= 12 && m == -1) { + m = a[i]-1; + } else if (parseInt(a[i], 10) > 31 && y == 0) { + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + } else if (d == 0) { + d = a[i]; + } + } + if (y == 0) + y = today.getFullYear(); + if (m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + return today; +}; + +/** Returns the number of days in the current month */ +Date.prototype.getMonthDays = function(month) { + var year = this.getFullYear(); + if (typeof month == "undefined") { + month = this.getMonth(); + } + if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) { + return 29; + } else { + return Date._MD[month]; + } +}; + +/** Returns the number of day in the year. */ +Date.prototype.getDayOfYear = function() { + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); + var time = now - then; + return Math.floor(time / Date.DAY); +}; + +/** Returns the number of the week in year, as defined in ISO 8601. */ +Date.prototype.getWeekNumber = function() { + var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var DoW = d.getDay(); + d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu + var ms = d.valueOf(); // GMT + d.setMonth(0); + d.setDate(4); // Thu in Week 1 + return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1; +}; + +/** Checks date and time equality */ +Date.prototype.equalsTo = function(date) { + return ((this.getFullYear() == date.getFullYear()) && + (this.getMonth() == date.getMonth()) && + (this.getDate() == date.getDate()) && + (this.getHours() == date.getHours()) && + (this.getMinutes() == date.getMinutes())); +}; + +/** Set only the year, month, date parts (keep existing time) */ +Date.prototype.setDateOnly = function(date) { + var tmp = new Date(date); + this.setDate(1); + this.setFullYear(tmp.getFullYear()); + this.setMonth(tmp.getMonth()); + this.setDate(tmp.getDate()); +}; + +/** Prints the date in a string according to the given format. */ +Date.prototype.print = function (str) { + var m = this.getMonth(); + var d = this.getDate(); + var y = this.getFullYear(); + var wn = this.getWeekNumber(); + var w = this.getDay(); + var s = {}; + var hr = this.getHours(); + var pm = (hr >= 12); + var ir = (pm) ? (hr - 12) : hr; + var dy = this.getDayOfYear(); + if (ir == 0) + ir = 12; + var min = this.getMinutes(); + var sec = this.getSeconds(); + s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N] + s["%A"] = Calendar._DN[w]; // full weekday name + s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N] + s["%B"] = Calendar._MN[m]; // full month name + // FIXME: %c : preferred date and time representation for the current locale + s["%C"] = 1 + Math.floor(y / 100); // the century number + s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) + s["%e"] = d; // the day of the month (range 1 to 31) + // FIXME: %D : american date style: %m/%d/%y + // FIXME: %E, %F, %G, %g, %h (man strftime) + s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) + s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) + s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) + s["%k"] = hr; // hour, range 0 to 23 (24h format) + s["%l"] = ir; // hour, range 1 to 12 (12h format) + s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12 + s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 + s["%n"] = "\n"; // a newline character + s["%p"] = pm ? "PM" : "AM"; + s["%P"] = pm ? "pm" : "am"; + // FIXME: %r : the time in am/pm notation %I:%M:%S %p + // FIXME: %R : the time in 24-hour notation %H:%M + s["%s"] = Math.floor(this.getTime() / 1000); + s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 + s["%t"] = "\t"; // a tab character + // FIXME: %T : the time in 24-hour notation (%H:%M:%S) + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) + // FIXME: %x : preferred date representation for the current locale without the time + // FIXME: %X : preferred time representation for the current locale without the date + s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99) + s["%Y"] = y; // year with the century + s["%%"] = "%"; // a literal '%' character + + var re = /%./g; + if (!Calendar.is_ie5 && !Calendar.is_khtml) + return str.replace(re, function (par) { return s[par] || par; }); + + var a = str.match(re); + + for (var i = 0; i < a.length; i++) { + var tmp = s[a[i]]; + if (tmp) { + re = new RegExp(a[i], 'g'); + str = str.replace(re, tmp); + } + } + + return str; +}; + +Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear; +Date.prototype.setFullYear = function(y) { + var d = new Date(this); + d.__msh_oldSetFullYear(y); + if (d.getMonth() != this.getMonth()) + this.setDate(28); + this.__msh_oldSetFullYear(y); +}; + +// END: DATE OBJECT PATCHES + + +// global object that remembers the calendar +window._dynarch_popupCalendar = null; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-setup.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-setup.js new file mode 100644 index 0000000..42e3dc6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-setup.js @@ -0,0 +1,203 @@ +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * --------------------------------------------------------------------------- + * + * The DHTML Calendar + * + * Details and latest version at: + * http://dynarch.com/mishoo/calendar.epl + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + * + * This file defines helper functions for setting up the calendar. They are + * intended to help non-programmers get a working calendar on their site + * quickly. This script should not be seen as part of the calendar. It just + * shows you what one can do with the calendar, while in the same time + * providing a quick and simple method for setting it up. If you need + * exhaustive customization of the calendar creation process feel free to + * modify this code to suit your needs (this is recommended and much better + * than modifying calendar.js itself). + */ + +// $Id: calendar-setup.js,v 1.1 2010-06-01 04:29:24 tv Exp $ + +/** + * This function "patches" an input field (or other element) to use a calendar + * widget for date selection. + * + * The "params" is a single object that can have the following properties: + * + * prop. name | description + * ------------------------------------------------------------------------------------------------- + * inputField | the ID of an input field to store the date + * displayArea | the ID of a DIV or other element to show the date + * button | ID of a button or other element that will trigger the calendar + * eventName | event that will trigger the calendar, without the "on" prefix (default: "click") + * ifFormat | date format that will be stored in the input field + * daFormat | the date format that will be used to display the date in displayArea + * singleClick | (true/false) wether the calendar is in single click mode or not (default: true) + * firstDay | numeric: 0 to 6. "0" means display Sunday first, "1" means display Monday first, etc. + * align | alignment (default: "Br"); if you don't know what's this see the calendar documentation + * range | array with 2 elements. Default: [1900, 2999] -- the range of years available + * weekNumbers | (true/false) if it's true (default) the calendar will display week numbers + * flat | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID + * flatCallback | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar) + * disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar + * onSelect | function that gets called when a date is selected. You don't _have_ to supply this (the default is generally okay) + * onClose | function that gets called when the calendar is closed. [default] + * onUpdate | function that gets called after the date is updated in the input field. Receives a reference to the calendar. + * date | the date that the calendar will be initially displayed to + * showsTime | default: false; if true the calendar will include a time selector + * timeFormat | the time format; can be "12" or "24", default is "12" + * electric | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close + * step | configures the step of the years in drop-down boxes; default: 1 (it was 2 ... have no idea why) + * position | configures the calendar absolute position; default: null + * cache | if "true" (but default: "false") it will reuse the same calendar object, where possible + * showOthers | if "true" (but default: "false") it will show days from other months too + * + * None of them is required, they all have default values. However, if you + * pass none of "inputField", "displayArea" or "button" you'll get a warning + * saying "nothing to setup". + */ +Calendar.setup = function (params) { + function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } }; + + param_default("inputField", null); + param_default("displayArea", null); + param_default("button", null); + param_default("eventName", "click"); + param_default("ifFormat", "%Y/%m/%d"); + param_default("daFormat", "%Y/%m/%d"); + param_default("singleClick", true); + param_default("disableFunc", null); + param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined + param_default("dateTooltipFunc", null); + param_default("dateText", null); + param_default("firstDay", null); + param_default("align", "Br"); + param_default("range", [1900, 2999]); + param_default("weekNumbers", true); + param_default("flat", null); + param_default("flatCallback", null); + param_default("onSelect", null); + param_default("onClose", null); + param_default("onUpdate", null); + param_default("date", null); + param_default("showsTime", false); + param_default("timeFormat", "24"); + param_default("electric", true); + param_default("step", 1); + param_default("position", null); + param_default("cache", false); + param_default("showOthers", false); + param_default("multiple", null); + + var tmp = ["inputField", "displayArea", "button"]; + for (var i in tmp) { + if (typeof params[tmp[i]] == "string") { + params[tmp[i]] = document.getElementById(params[tmp[i]]); + } + } + if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) { + alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code"); + return false; + } + + function onSelect(cal) { + var p = cal.params; + var update = (cal.dateClicked || p.electric); + if (update && p.inputField) { + p.inputField.value = cal.date.print(p.ifFormat); + if (typeof p.inputField.onchange == "function") + p.inputField.onchange(); + } + if (update && p.displayArea) + p.displayArea.innerHTML = cal.date.print(p.daFormat); + if (update && typeof p.onUpdate == "function") + p.onUpdate(cal); + if (update && p.flat) { + if (typeof p.flatCallback == "function") + p.flatCallback(cal); + } + if (update && p.singleClick && cal.dateClicked) + cal.callCloseHandler(); + }; + + if (params.flat != null) { + if (typeof params.flat == "string") + params.flat = document.getElementById(params.flat); + if (!params.flat) { + alert("Calendar.setup:\n Flat specified but can't find parent."); + return false; + } + var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect); + cal.setDateToolTipHandler(params.dateTooltipFunc); + cal.showsOtherMonths = params.showOthers; + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.params = params; + cal.weekNumbers = params.weekNumbers; + cal.setRange(params.range[0], params.range[1]); + cal.setDateStatusHandler(params.dateStatusFunc); + cal.getDateText = params.dateText; + if (params.ifFormat) { + cal.setDateFormat(params.ifFormat); + } + if (params.inputField && typeof params.inputField.value == "string") { + cal.parseDate(params.inputField.value); + } + cal.create(params.flat); + cal.show(); + return false; + } + + var triggerEl = params.button || params.displayArea || params.inputField; + triggerEl["on" + params.eventName] = function() { + var dateEl = params.inputField || params.displayArea; + var dateFmt = params.inputField ? params.ifFormat : params.daFormat; + var mustCreate = false; + var cal = window.calendar; + if (dateEl) + params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt); + if (!(cal && params.cache)) { + window.calendar = cal = new Calendar(params.firstDay, + params.date, + params.onSelect || onSelect, + params.onClose || function(cal) { cal.hide(); }); + cal.setDateToolTipHandler(params.dateTooltipFunc); + cal.showsTime = params.showsTime; + cal.time24 = (params.timeFormat == "24"); + cal.weekNumbers = params.weekNumbers; + mustCreate = true; + } else { + if (params.date) + cal.setDate(params.date); + cal.hide(); + } + if (params.multiple) { + cal.multiple = {}; + for (var i = params.multiple.length; --i >= 0;) { + var d = params.multiple[i]; + var ds = d.print("%Y%m%d"); + cal.multiple[ds] = d; + } + } + cal.showsOtherMonths = params.showOthers; + cal.yearStep = params.step; + cal.setRange(params.range[0], params.range[1]); + cal.params = params; + cal.setDateStatusHandler(params.dateStatusFunc); + cal.getDateText = params.dateText; + cal.setDateFormat(dateFmt); + if (mustCreate) + cal.create(); + cal.refresh(); + if (!params.position) + cal.showAtElement(params.button || params.displayArea || params.inputField, params.align); + else + cal.showAt(params.position[0], params.position[1]); + return false; + }; + + return cal; +}; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-setup_stripped.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-setup_stripped.js new file mode 100644 index 0000000..0b78430 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-setup_stripped.js @@ -0,0 +1,21 @@ +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/ + * --------------------------------------------------------------------------- + * + * The DHTML Calendar + * + * Details and latest version at: + * http://dynarch.com/mishoo/calendar.epl + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + * + * This file defines helper functions for setting up the calendar. They are + * intended to help non-programmers get a working calendar on their site + * quickly. This script should not be seen as part of the calendar. It just + * shows you what one can do with the calendar, while in the same time + * providing a quick and simple method for setting it up. If you need + * exhaustive customization of the calendar creation process feel free to + * modify this code to suit your needs (this is recommended and much better + * than modifying calendar.js itself). + */ + Calendar.setup=function(params){function param_default(pname,def){if(typeof params[pname]=="undefined"){params[pname]=def;}};param_default("inputField",null);param_default("displayArea",null);param_default("button",null);param_default("eventName","click");param_default("ifFormat","%Y/%m/%d");param_default("daFormat","%Y/%m/%d");param_default("singleClick",true);param_default("disableFunc",null);param_default("dateStatusFunc",params["disableFunc"]);param_default("dateTooltipFunc",null);param_default("dateText",null);param_default("firstDay",null);param_default("align","Br");param_default("range",[1900,2999]);param_default("weekNumbers",true);param_default("flat",null);param_default("flatCallback",null);param_default("onSelect",null);param_default("onClose",null);param_default("onUpdate",null);param_default("date",null);param_default("showsTime",false);param_default("timeFormat","24");param_default("electric",true);param_default("step",2);param_default("position",null);param_default("cache",false);param_default("showOthers",false);param_default("multiple",null);var tmp=["inputField","displayArea","button"];for(var i in tmp){if(typeof params[tmp[i]]=="string"){params[tmp[i]]=document.getElementById(params[tmp[i]]);}}if(!(params.flat||params.multiple||params.inputField||params.displayArea||params.button)){alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");return false;}function onSelect(cal){var p=cal.params;var update=(cal.dateClicked||p.electric);if(update&&p.inputField){p.inputField.value=cal.date.print(p.ifFormat);if(typeof p.inputField.onchange=="function")p.inputField.onchange();}if(update&&p.displayArea)p.displayArea.innerHTML=cal.date.print(p.daFormat);if(update&&typeof p.onUpdate=="function")p.onUpdate(cal);if(update&&p.flat){if(typeof p.flatCallback=="function")p.flatCallback(cal);}if(update&&p.singleClick&&cal.dateClicked)cal.callCloseHandler();};if(params.flat!=null){if(typeof params.flat=="string")params.flat=document.getElementById(params.flat);if(!params.flat){alert("Calendar.setup:\n Flat specified but can't find parent.");return false;}var cal=new Calendar(params.firstDay,params.date,params.onSelect||onSelect);cal.setDateToolTipHandler(params.dateTooltipFunc);cal.showsOtherMonths=params.showOthers;cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.params=params;cal.weekNumbers=params.weekNumbers;cal.setRange(params.range[0],params.range[1]);cal.setDateStatusHandler(params.dateStatusFunc);cal.getDateText=params.dateText;if(params.ifFormat){cal.setDateFormat(params.ifFormat);}if(params.inputField&&typeof params.inputField.value=="string"){cal.parseDate(params.inputField.value);}cal.create(params.flat);cal.show();return false;}var triggerEl=params.button||params.displayArea||params.inputField;triggerEl["on"+params.eventName]=function(){var dateEl=params.inputField||params.displayArea;var dateFmt=params.inputField?params.ifFormat:params.daFormat;var mustCreate=false;var cal=window.calendar;if(dateEl)params.date=Date.parseDate(dateEl.value||dateEl.innerHTML,dateFmt);if(!(cal&¶ms.cache)){window.calendar=cal=new Calendar(params.firstDay,params.date,params.onSelect||onSelect,params.onClose||function(cal){cal.hide();});cal.setDateToolTipHandler(params.dateTooltipFunc);cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.weekNumbers=params.weekNumbers;mustCreate=true;}else{if(params.date)cal.setDate(params.date);cal.hide();}if(params.multiple){cal.multiple={};for(var i=params.multiple.length;--i>=0;){var d=params.multiple[i];var ds=d.print("%Y%m%d");cal.multiple[ds]=d;}}cal.showsOtherMonths=params.showOthers;cal.yearStep=params.step;cal.setRange(params.range[0],params.range[1]);cal.params=params;cal.setDateStatusHandler(params.dateStatusFunc);cal.getDateText=params.dateText;cal.setDateFormat(dateFmt);if(mustCreate)cal.create();cal.refresh();if(!params.position)cal.showAtElement(params.button||params.displayArea||params.inputField,params.align);else cal.showAt(params.position[0],params.position[1]);return false;};return cal;}; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-system.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-system.css new file mode 100644 index 0000000..f64493b --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-system.css @@ -0,0 +1,251 @@ +/* The main calendar widget. DIV containing a table. */ + +.calendar { + position: relative; + display: none; + border: 1px solid; + border-color: #fff #000 #000 #fff; + font-size: 11px; + cursor: default; + background: Window; + color: WindowText; + font-family: tahoma,verdana,sans-serif; +} + +.calendar table { + border: 1px solid; + border-color: #fff #000 #000 #fff; + font-size: 11px; + cursor: default; + background: Window; + color: WindowText; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; + padding: 1px; + border: 1px solid; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; + background: ButtonFace; +} + +.calendar .nav { + background: ButtonFace url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; + padding: 1px; + border: 1px solid #000; + background: ActiveCaption; + color: CaptionText; + text-align: center; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .daynames { /* Row containing the day names */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid ButtonShadow; + padding: 2px; + text-align: center; + background: ButtonFace; + color: ButtonText; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + border: 2px solid; + padding: 0px; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + border-width: 1px; + padding: 2px 0px 0px 2px; + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #aaa; +} +.calendar tbody .day.othermonth.oweekend { + color: #faa; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid ButtonShadow; + background: ButtonFace; + color: ButtonText; +} + +.calendar tbody .rowhilite td { + background: Highlight; + color: HighlightText; +} + +.calendar tbody td.hilite { /* Hovered cells */ + padding: 1px 3px 1px 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + padding: 2px 2px 0px 2px; + border: 1px solid; + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + border: 1px solid; + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; + padding: 2px 2px 0px 2px; + background: ButtonFace; + color: ButtonText; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { /* Cell showing today date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody td.disabled { color: GrayText; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: ButtonFace; + padding: 1px; + border: 1px solid; + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow; + color: ButtonText; + text-align: center; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + padding: 1px; + background: #e4e0d8; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + width: 4em; + top: 0px; + left: 0px; + cursor: default; + border: 1px solid; + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; + background: Menu; + color: MenuText; + font-size: 90%; + padding: 1px; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .active { + padding: 0px; + border: 1px solid #000; +} + +.calendar .combo .hilite { + background: Highlight; + color: HighlightText; +} + +.calendar td.time { + border-top: 1px solid ButtonShadow; + padding: 1px 0px; + text-align: center; + background-color: ButtonFace; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: Menu; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: Highlight; + color: HighlightText; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-tas.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-tas.css new file mode 100644 index 0000000..a0c9c9d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-tas.css @@ -0,0 +1,239 @@ +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #655; + font-size: 11px; + color: #000; + cursor: default; + background: #ffd; + font-family: tahoma,verdana,sans-serif; + filter: +progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#DDDCCC,EndColorStr=#FFFFFF); +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ + color:#363636; +} + +.calendar .nav { + background: #edc url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + background: #654; + color: #363636; + padding: 2px; + filter: +progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#ffffff,EndColorStr=#dddccc); +} + +.calendar thead .headrow { /* Row containing navigation buttons */ + /*background: #3B86A0;*/ + color: #363636; + font-weight: bold; +filter: +progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#ffffff,EndColorStr=#3b86a0); +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #655; + padding: 2px; + text-align: center; + color: #363636; + filter: +progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#DDDCCC,EndColorStr=#FFFFFF); +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background-color: #ffcc86; + color: #000; + border: 1px solid #b59345; + padding: 1px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background-color: #c77; + padding: 2px 0px 0px 2px; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: #fed; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #aaa; +} +.calendar tbody .day.othermonth.oweekend { + color: #faa; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #fed; +} + +.calendar tbody .rowhilite td { + background: #ddf; + +} + +.calendar tbody .rowhilite td.wn { + background: #efe; +} + +.calendar tbody td.hilite { /* Hovered cells */ + background: #ffe; + padding: 1px 3px 1px 1px; + border: 1px solid #bbb; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + background: #ddc; + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.selected { /* Cell showing today date */ + font-weight: bold; + border: 1px solid #000; + padding: 1px 3px 1px 1px; + background: #fea; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { font-weight: bold; } + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #988; + color: #000; + +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + border-top: 1px solid #655; + background: #dcb; + color: #363636; + font-weight: bold; + filter: +progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#FFFFFF,EndColorStr=#DDDCCC); +} +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #faa; + border: 1px solid #f40; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #c77; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border: 1px solid #655; + background: #ffe; + color: #000; + font-size: smaller; + z-index: 100; +} + +.combo .label, +.combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.combo .label-IEfix { + width: 4em; +} + +.combo .hilite { + background: #fc8; +} + +.combo .active { + border-top: 1px solid #a64; + border-bottom: 1px solid #a64; + background: #fee; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #a88; + padding: 1px 0px; + text-align: center; + background-color: #fed; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #988; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #866; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-1.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-1.css new file mode 100644 index 0000000..56ffdf2 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-1.css @@ -0,0 +1,271 @@ +/* The main calendar widget. DIV containing a table. */ + +.calendar { + position: relative; + display: none; + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + font-size: 11px; + color: #000; + cursor: default; + background: #d4d0c8; + font-family: tahoma,verdana,sans-serif; +} + +.calendar table { + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + font-size: 11px; + color: #000; + cursor: default; + background: #d4d0c8; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; + padding: 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; + padding: 1px; + border: 1px solid #000; + background: #848078; + color: #fff; + text-align: center; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .daynames { /* Row containing the day names */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #000; + padding: 2px; + text-align: center; + background: #f4f0e8; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + padding: 0px; + background-color: #e4e0d8; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + background-color: #c4c0b8; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #aaa; +} +.calendar tbody .day.othermonth.oweekend { + color: #faa; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #f4f0e8; +} + +.calendar tbody .rowhilite td { + background: #e4e0d8; +} + +.calendar tbody .rowhilite td.wn { + background: #d4d0c8; +} + +.calendar tbody td.hilite { /* Hovered cells */ + padding: 1px 3px 1px 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + padding: 2px 2px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + padding: 2px 2px 0px 2px; + background: #e4e0d8; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { /* Cell showing today date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: #f4f0e8; + padding: 1px; + border: 1px solid #000; + background: #848078; + color: #fff; + text-align: center; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + padding: 1px; + background: #e4e0d8; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + width: 4em; + top: 0px; + left: 0px; + cursor: default; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + background: #e4e0d8; + font-size: 90%; + padding: 1px; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .active { + background: #c4c0b8; + padding: 0px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar .combo .hilite { + background: #048; + color: #fea; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #766; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-2.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-2.css new file mode 100644 index 0000000..ccb85a0 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-2.css @@ -0,0 +1,271 @@ +/* The main calendar widget. DIV containing a table. */ + +.calendar { + position: relative; + display: none; + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + font-size: 11px; + color: #000; + cursor: default; + background: #d4c8d0; + font-family: tahoma,verdana,sans-serif; +} + +.calendar table { + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + font-size: 11px; + color: #000; + cursor: default; + background: #d4c8d0; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; + padding: 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; + padding: 1px; + border: 1px solid #000; + background: #847880; + color: #fff; + text-align: center; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .daynames { /* Row containing the day names */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #000; + padding: 2px; + text-align: center; + background: #f4e8f0; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + padding: 0px; + background-color: #e4d8e0; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + background-color: #c4b8c0; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #aaa; +} +.calendar tbody .day.othermonth.oweekend { + color: #faa; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #f4e8f0; +} + +.calendar tbody .rowhilite td { + background: #e4d8e0; +} + +.calendar tbody .rowhilite td.wn { + background: #d4c8d0; +} + +.calendar tbody td.hilite { /* Hovered cells */ + padding: 1px 3px 1px 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + padding: 2px 2px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + padding: 2px 2px 0px 2px; + background: #e4d8e0; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { /* Cell showing today date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: #f4e8f0; + padding: 1px; + border: 1px solid #000; + background: #847880; + color: #fff; + text-align: center; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + padding: 1px; + background: #e4d8e0; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + width: 4em; + top: 0px; + left: 0px; + cursor: default; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + background: #e4d8e0; + font-size: 90%; + padding: 1px; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .active { + background: #d4c8d0; + padding: 0px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar .combo .hilite { + background: #408; + color: #fea; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #f4f0e8; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #766; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-cold-1.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-cold-1.css new file mode 100644 index 0000000..09a1a80 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-cold-1.css @@ -0,0 +1,265 @@ +/* The main calendar widget. DIV containing a table. */ + +.calendar { + position: relative; + display: none; + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + font-size: 11px; + color: #000; + cursor: default; + background: #c8d0d4; + font-family: tahoma,verdana,sans-serif; +} + +.calendar table { + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + font-size: 11px; + color: #000; + cursor: default; + background: #c8d0d4; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; + padding: 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; + padding: 1px; + border: 1px solid #000; + background: #788084; + color: #fff; + text-align: center; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .daynames { /* Row containing the day names */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #000; + padding: 2px; + text-align: center; + background: #e8f0f4; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + padding: 0px; + background-color: #d8e0e4; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + background-color: #b8c0c4; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #aaa; +} +.calendar tbody .day.othermonth.oweekend { + color: #faa; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #e8f4f0; +} + +.calendar tbody .rowhilite td { + background: #d8e4e0; +} + +.calendar tbody .rowhilite td.wn { + background: #c8d4d0; +} + +.calendar tbody td.hilite { /* Hovered cells */ + padding: 1px 3px 1px 1px; + border: 1px solid; + border-color: #fff #000 #000 #fff; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + padding: 2px 2px 0px 2px; + border: 1px solid; + border-color: #000 #fff #fff #000; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + padding: 2px 2px 0px 2px; + border: 1px solid; + border-color: #000 #fff #fff #000; + background: #d8e0e4; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { /* Cell showing today date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: #e8f0f4; + padding: 1px; + border: 1px solid #000; + background: #788084; + color: #fff; + text-align: center; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + padding: 1px; + background: #d8e0e4; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + width: 4em; + top: 0px; + left: 0px; + cursor: default; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + background: #d8e0e4; + font-size: 90%; + padding: 1px; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .active { + background: #c8d0d4; + padding: 0px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar .combo .hilite { + background: #048; + color: #aef; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #e8f0f4; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #667; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-cold-2.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-cold-2.css new file mode 100644 index 0000000..0ae6b08 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar-win2k-cold-2.css @@ -0,0 +1,271 @@ +/* The main calendar widget. DIV containing a table. */ + +.calendar { + position: relative; + display: none; + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + font-size: 11px; + color: #000; + cursor: default; + background: #c8d4d0; + font-family: tahoma,verdana,sans-serif; +} + +.calendar table { + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + font-size: 11px; + color: #000; + cursor: default; + background: #c8d4d0; + font-family: tahoma,verdana,sans-serif; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; + padding: 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar .nav { + background: transparent url(menuarrow.gif) no-repeat 100% 100%; +} + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; + padding: 1px; + border: 1px solid #000; + background: #788480; + color: #fff; + text-align: center; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .daynames { /* Row containing the day names */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #000; + padding: 2px; + text-align: center; + background: #e8f4f0; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #f00; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + border-top: 2px solid #fff; + border-right: 2px solid #000; + border-bottom: 2px solid #000; + border-left: 2px solid #fff; + padding: 0px; + background-color: #d8e4e0; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + background-color: #b8c4c0; +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + width: 2em; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #aaa; +} +.calendar tbody .day.othermonth.oweekend { + color: #faa; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #000; + background: #e8f4f0; +} + +.calendar tbody .rowhilite td { + background: #d8e4e0; +} + +.calendar tbody .rowhilite td.wn { + background: #c8d4d0; +} + +.calendar tbody td.hilite { /* Hovered cells */ + padding: 1px 3px 1px 1px; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + padding: 2px 2px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; + padding: 2px 2px 0px 2px; + background: #d8e4e0; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #f00; +} + +.calendar tbody td.today { /* Cell showing today date */ + font-weight: bold; + color: #00f; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + background: #e8f4f0; + padding: 1px; + border: 1px solid #000; + background: #788480; + color: #fff; + text-align: center; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + padding: 1px; + background: #d8e4e0; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + padding: 2px 0px 0px 2px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + width: 4em; + top: 0px; + left: 0px; + cursor: default; + border-top: 1px solid #fff; + border-right: 1px solid #000; + border-bottom: 1px solid #000; + border-left: 1px solid #fff; + background: #d8e4e0; + font-size: 90%; + padding: 1px; + z-index: 100; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .active { + background: #c8d4d0; + padding: 0px; + border-top: 1px solid #000; + border-right: 1px solid #fff; + border-bottom: 1px solid #fff; + border-left: 1px solid #000; +} + +.calendar .combo .hilite { + background: #048; + color: #aef; +} + +.calendar td.time { + border-top: 1px solid #000; + padding: 1px 0px; + text-align: center; + background-color: #e8f0f4; +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 3px 0px 4px; + border: 1px solid #889; + font-weight: bold; + background-color: #fff; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + border-color: #000; + background-color: #667; + color: #fff; +} + +.calendar td.time span.active { + border-color: #f00; + background-color: #000; + color: #0f0; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar.js new file mode 100644 index 0000000..eddb43b --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar.js @@ -0,0 +1,1853 @@ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- + * + * The DHTML Calendar, version 1.0 "It is happening again" + * + * Details and latest version at: + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + +// $Id: calendar.js,v 1.3 2010-07-27 04:41:27 tv Exp $ + +/** The Calendar object constructor. */ +Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) { + // member variables + this.activeDiv = null; + this.currentDateEl = null; + this.getDateStatus = null; + this.getDateToolTip = null; + this.getDateText = null; + this.timeout = null; + this.onSelected = onSelected || null; + this.onClose = onClose || null; + this.dragging = false; + this.hidden = false; + this.minYear = 1970; + this.maxYear = 2050; + this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"]; + this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"]; + this.isPopup = true; + this.weekNumbers = true; + this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc. + this.showsOtherMonths = false; + this.dateStr = dateStr; + this.ar_days = null; + this.showsTime = false; + this.time24 = true; + this.yearStep = 2; + this.hiliteToday = true; + this.multiple = null; + // HTML elements + this.table = null; + this.element = null; + this.tbody = null; + this.firstdayname = null; + // Combo boxes + this.monthsCombo = null; + this.yearsCombo = null; + this.hilitedMonth = null; + this.activeMonth = null; + this.hilitedYear = null; + this.activeYear = null; + // Information + this.dateClicked = false; + + // one-time initializations + if (typeof Calendar._SDN == "undefined") { + // table of short day names + if (typeof Calendar._SDN_len == "undefined") + Calendar._SDN_len = 3; + var ar = new Array(); + for (var i = 8; i > 0;) { + ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len); + } + Calendar._SDN = ar; + // table of short month names + if (typeof Calendar._SMN_len == "undefined") + Calendar._SMN_len = 3; + ar = new Array(); + for (var i = 12; i > 0;) { + ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len); + } + Calendar._SMN = ar; + } +}; + +// ** constants + +/// "static", needed for event handlers. +Calendar._C = null; + +/// detect a special case of "web browser" +Calendar.is_ie = ( /msie/i.test(navigator.userAgent) && + !/opera/i.test(navigator.userAgent) ); + +Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) ); +Calendar.is_ie7up = ( Calendar.is_ie && parseFloat(navigator.userAgent.replace(/.*msie ([0-9]+).*/i, "$1" )) >= 7 ); + +/// detect Opera browser +Calendar.is_opera = /opera/i.test(navigator.userAgent); + +/// detect KHTML-based browsers +Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent); + +// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate +// library, at some point. + +Calendar.getAbsolutePos = function(el) { + var SL = 0, ST = 0; + var is_div = /^div$/i.test(el.tagName); + if (is_div && el.scrollLeft) + SL = el.scrollLeft; + if (is_div && el.scrollTop) + ST = el.scrollTop; + var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST }; + if (el.offsetParent) { + var tmp = this.getAbsolutePos(el.offsetParent); + r.x += tmp.x; + r.y += tmp.y; + } + return r; +}; + +Calendar.isRelated = function (el, evt) { + var related = evt.relatedTarget; + if (!related) { + var type = evt.type; + if (type == "mouseover") { + related = evt.fromElement; + } else if (type == "mouseout") { + related = evt.toElement; + } + } + while (related) { + if (related == el) { + return true; + } + related = related.parentNode; + } + return false; +}; + +Calendar.removeClass = function(el, className) { + if (!(el && el.className)) { + return; + } + var cls = el.className.split(" "); + var ar = new Array(); + for (var i = cls.length; i > 0;) { + if (cls[--i] != className) { + ar[ar.length] = cls[i]; + } + } + el.className = ar.join(" "); +}; + +Calendar.addClass = function(el, className) { + Calendar.removeClass(el, className); + el.className += " " + className; +}; + +// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately. +Calendar.getElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget; + while (f.nodeType != 1 || /^div$/i.test(f.tagName)) + f = f.parentNode; + return f; +}; + +Calendar.getTargetElement = function(ev) { + var f = Calendar.is_ie ? window.event.srcElement : ev.target; + while (f.nodeType != 1) + f = f.parentNode; + return f; +}; + +Calendar.stopEvent = function(ev) { + ev || (ev = window.event); + if (Calendar.is_ie) { + ev.cancelBubble = true; + ev.returnValue = false; + } else { + ev.preventDefault(); + ev.stopPropagation(); + } + return false; +}; + +Calendar.addEvent = function(el, evname, func) { + if (el.attachEvent) { // IE + el.attachEvent("on" + evname, func); + } else if (el.addEventListener) { // Gecko / W3C + el.addEventListener(evname, func, true); + } else { + el["on" + evname] = func; + } +}; + +Calendar.removeEvent = function(el, evname, func) { + if (el.detachEvent) { // IE + el.detachEvent("on" + evname, func); + } else if (el.removeEventListener) { // Gecko / W3C + el.removeEventListener(evname, func, true); + } else { + el["on" + evname] = null; + } +}; + +Calendar.createElement = function(type, parent) { + var el = null; + if (document.createElementNS) { + // use the XHTML namespace; IE won't normally get here unless + // _they_ "fix" the DOM2 implementation. + el = document.createElementNS("http://www.w3.org/1999/xhtml", type); + } else { + el = document.createElement(type); + } + if (typeof parent != "undefined") { + parent.appendChild(el); + } + return el; +}; + +// END: UTILITY FUNCTIONS + +// BEGIN: CALENDAR STATIC FUNCTIONS + +/** Internal -- adds a set of events to make some element behave like a button. */ +Calendar._add_evs = function(el) { + with (Calendar) { + addEvent(el, "mouseover", dayMouseOver); + addEvent(el, "mousedown", dayMouseDown); + addEvent(el, "mouseout", dayMouseOut); + if (is_ie) { + addEvent(el, "dblclick", dayMouseDblClick); + el.setAttribute("unselectable", true); + } + } +}; + +Calendar.findMonth = function(el) { + if (typeof el.month != "undefined") { + return el; + } else if (typeof el.parentNode.month != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.findYear = function(el) { + if (typeof el.year != "undefined") { + return el; + } else if (typeof el.parentNode.year != "undefined") { + return el.parentNode; + } + return null; +}; + +Calendar.showMonthsCombo = function () { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var mc = cal.monthsCombo; + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + if (cal.activeMonth) { + Calendar.removeClass(cal.activeMonth, "active"); + } + var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()]; + Calendar.addClass(mon, "active"); + cal.activeMonth = mon; + var s = mc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var mcw = mc.offsetWidth; + if (typeof mcw == "undefined") + // Konqueror brain-dead techniques + mcw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; +}; + +Calendar.showYearsCombo = function (fwd) { + var cal = Calendar._C; + if (!cal) { + return false; + } + var cal = cal; + var cd = cal.activeDiv; + var yc = cal.yearsCombo; + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + if (cal.activeYear) { + Calendar.removeClass(cal.activeYear, "active"); + } + cal.activeYear = null; + var Y = cal.date.getFullYear() + (fwd ? 1 : -1); + var yr = yc.firstChild; + var show = false; + for (var i = 12; i > 0; --i) { + if (Y >= cal.minYear && Y <= cal.maxYear) { + yr.innerHTML = Y; + yr.year = Y; + yr.style.display = "block"; + show = true; + } else { + yr.style.display = "none"; + } + yr = yr.nextSibling; + Y += fwd ? cal.yearStep : -cal.yearStep; + } + if (show) { + var s = yc.style; + s.display = "block"; + if (cd.navtype < 0) + s.left = cd.offsetLeft + "px"; + else { + var ycw = yc.offsetWidth; + if (typeof ycw == "undefined") + // Konqueror brain-dead techniques + ycw = 50; + s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px"; + } + s.top = (cd.offsetTop + cd.offsetHeight) + "px"; + } +}; + +// event handlers + +Calendar.tableMouseUp = function(ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + if (cal.timeout) { + clearTimeout(cal.timeout); + } + var el = cal.activeDiv; + if (!el) { + return false; + } + var target = Calendar.getTargetElement(ev); + ev || (ev = window.event); + Calendar.removeClass(el, "active"); + if (target == el || target.parentNode == el) { + Calendar.cellClick(el, ev); + } + var mon = Calendar.findMonth(target); + var date = null; + if (mon) { + date = new Date(cal.date); + if (mon.month != date.getMonth()) { + date.setMonth(mon.month); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } else { + var year = Calendar.findYear(target); + if (year) { + date = new Date(cal.date); + if (year.year != date.getFullYear()) { + date.setFullYear(year.year); + cal.setDate(date); + cal.dateClicked = false; + cal.callHandler(); + } + } + } + with (Calendar) { + removeEvent(document, "mouseup", tableMouseUp); + removeEvent(document, "mouseover", tableMouseOver); + removeEvent(document, "mousemove", tableMouseOver); + cal._hideCombos(); + _C = null; + return stopEvent(ev); + } +}; + +Calendar.tableMouseOver = function (ev) { + var cal = Calendar._C; + if (!cal) { + return; + } + var el = cal.activeDiv; + var target = Calendar.getTargetElement(ev); + if (target == el || target.parentNode == el) { + Calendar.addClass(el, "hilite active"); + Calendar.addClass(el.parentNode, "rowhilite"); + } else { + if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2))) + Calendar.removeClass(el, "active"); + Calendar.removeClass(el, "hilite"); + Calendar.removeClass(el.parentNode, "rowhilite"); + } + ev || (ev = window.event); + if (el.navtype == 50 && target != el) { + var pos = Calendar.getAbsolutePos(el); + var w = el.offsetWidth; + var x = ev.clientX; + var dx; + var decrease = true; + if (x > pos.x + w) { + dx = x - pos.x - w; + decrease = false; + } else + dx = pos.x - x; + + if (dx < 0) dx = 0; + var range = el._range; + var current = el._current; + var count = Math.floor(dx / 10) % range.length; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + while (count-- > 0) + if (decrease) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + + cal.onUpdateTime(); + } + var mon = Calendar.findMonth(target); + if (mon) { + if (mon.month != cal.date.getMonth()) { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + Calendar.addClass(mon, "hilite"); + cal.hilitedMonth = mon; + } else if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + } else { + if (cal.hilitedMonth) { + Calendar.removeClass(cal.hilitedMonth, "hilite"); + } + var year = Calendar.findYear(target); + if (year) { + if (year.year != cal.date.getFullYear()) { + if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + Calendar.addClass(year, "hilite"); + cal.hilitedYear = year; + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } else if (cal.hilitedYear) { + Calendar.removeClass(cal.hilitedYear, "hilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.tableMouseDown = function (ev) { + if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) { + return Calendar.stopEvent(ev); + } +}; + +Calendar.calDragIt = function (ev) { + var cal = Calendar._C; + if (!(cal && cal.dragging)) { + return false; + } + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posX = ev.pageX; + posY = ev.pageY; + } + cal.hideShowCovered(); + var st = cal.element.style; + st.left = (posX - cal.xOffs) + "px"; + st.top = (posY - cal.yOffs) + "px"; + return Calendar.stopEvent(ev); +}; + +Calendar.calDragEnd = function (ev) { + var cal = Calendar._C; + if (!cal) { + return false; + } + cal.dragging = false; + with (Calendar) { + removeEvent(document, "mousemove", calDragIt); + removeEvent(document, "mouseup", calDragEnd); + tableMouseUp(ev); + } + cal.hideShowCovered(); +}; + +Calendar.dayMouseDown = function(ev) { + var el = Calendar.getElement(ev); + if (el.disabled) { + return false; + } + var cal = el.calendar; + cal.activeDiv = el; + Calendar._C = cal; + if (el.navtype != 300) with (Calendar) { + if (el.navtype == 50) { + el._current = el.innerHTML; + addEvent(document, "mousemove", tableMouseOver); + } else + addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver); + addClass(el, "hilite active"); + addEvent(document, "mouseup", tableMouseUp); + } else if (cal.isPopup) { + cal._dragStart(ev); + } + if (el.navtype == -1 || el.navtype == 1) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250); + } else if (el.navtype == -2 || el.navtype == 2) { + if (cal.timeout) clearTimeout(cal.timeout); + cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250); + } else { + cal.timeout = null; + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseDblClick = function(ev) { + Calendar.cellClick(Calendar.getElement(ev), ev || window.event); + if (Calendar.is_ie) { + document.selection.empty(); + } +}; + +Calendar.dayMouseOver = function(ev) { + var el = Calendar.getElement(ev); + if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) { + return false; + } + if (el.ttip) { + if (el.ttip.substr(0, 1) == "_") { + el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1); + } + el.calendar.tooltips.innerHTML = el.ttip; + } + if (el.navtype != 300) { + Calendar.addClass(el, "hilite"); + if (el.caldate) { + Calendar.addClass(el.parentNode, "rowhilite"); + } + } + return Calendar.stopEvent(ev); +}; + +Calendar.dayMouseOut = function(ev) { + with (Calendar) { + var el = getElement(ev); + if (isRelated(el, ev) || _C || el.disabled) + return false; + removeClass(el, "hilite"); + if (el.caldate) + removeClass(el.parentNode, "rowhilite"); + if (el.calendar) + el.calendar.tooltips.innerHTML = _TT["SEL_DATE"]; + return stopEvent(ev); + } +}; + +/** + * A generic "click" handler :) handles all types of buttons defined in this + * calendar. + */ +Calendar.cellClick = function(el, ev) { + var cal = el.calendar; + var closing = false; + var newdate = false; + var date = null; + if (typeof el.navtype == "undefined") { + if (cal.currentDateEl) { + Calendar.removeClass(cal.currentDateEl, "selected"); + Calendar.addClass(el, "selected"); + closing = (cal.currentDateEl == el); + if (!closing) { + cal.currentDateEl = el; + } + } + cal.date.setDateOnly(el.caldate); + date = cal.date; + var other_month = !(cal.dateClicked = !el.otherMonth); + if (!other_month && !cal.currentDateEl) + cal._toggleMultipleDate(new Date(date)); + else + newdate = !el.disabled; + // a date was clicked + if (other_month) + cal._init(cal.firstDayOfWeek, date); + } else { + if (el.navtype == 200) { + Calendar.removeClass(el, "hilite"); + cal.callCloseHandler(); + return; + } + date = new Date(cal.date); + if (el.navtype == 0) + date.setDateOnly(new Date()); // TODAY + // unless "today" was clicked, we assume no date was clicked so + // the selected handler will know not to close the calenar when + // in single-click mode. + // cal.dateClicked = (el.navtype == 0); + cal.dateClicked = false; + var year = date.getFullYear(); + var mon = date.getMonth(); + function setMonth(m) { + var day = date.getDate(); + var max = date.getMonthDays(m); + if (day > max) { + date.setDate(max); + } + date.setMonth(m); + }; + switch (el.navtype) { + case 400: + Calendar.removeClass(el, "hilite"); + var text = Calendar._TT["ABOUT"]; + if (typeof text != "undefined") { + text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : ""; + } else { + // FIXME: this should be removed as soon as lang files get updated! + text = "Help and about box text is not translated into this language.\n" + + "If you know this language and you feel generous please update\n" + + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" + + "and send it back to to get it into the distribution ;-)\n\n" + + "Thank you!\n" + + "http://dynarch.com/mishoo/calendar.epl\n"; + } + alert(text); + return; + case -2: + if (year > cal.minYear) { + date.setFullYear(year - 1); + } + break; + case -1: + if (mon > 0) { + setMonth(mon - 1); + } else if (year-- > cal.minYear) { + date.setFullYear(year); + setMonth(11); + } + break; + case 1: + if (mon < 11) { + setMonth(mon + 1); + } else if (year < cal.maxYear) { + date.setFullYear(year + 1); + setMonth(0); + } + break; + case 2: + if (year < cal.maxYear) { + date.setFullYear(year + 1); + } + break; + case 100: + cal.setFirstDayOfWeek(el.fdow); + return; + case 50: + var range = el._range; + var current = el.innerHTML; + for (var i = range.length; --i >= 0;) + if (range[i] == current) + break; + if (ev && ev.shiftKey) { + if (--i < 0) + i = range.length - 1; + } else if ( ++i >= range.length ) + i = 0; + var newval = range[i]; + el.innerHTML = newval; + cal.onUpdateTime(); + return; + case 0: + // TODAY will bring us here + if ((typeof cal.getDateStatus == "function") && + cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) { + return false; + } + break; + } + if (!date.equalsTo(cal.date)) { + cal.setDate(date); + newdate = true; + } else if (el.navtype == 0) + newdate = closing = true; + } + if (newdate) { + ev && cal.callHandler(); + } + if (closing) { + Calendar.removeClass(el, "hilite"); + ev && cal.callCloseHandler(); + } +}; + +// END: CALENDAR STATIC FUNCTIONS + +// BEGIN: CALENDAR OBJECT FUNCTIONS + +/** + * This function creates the calendar inside the given parent. If _par is + * null than it creates a popup calendar inside the BODY element. If _par is + * an element, be it BODY, then it creates a non-popup calendar (still + * hidden). Some properties need to be set before calling this function. + */ +Calendar.prototype.create = function (_par) { + var parent = null; + if (! _par) { + // default parent is the document body, in which case we create + // a popup calendar. + parent = document.getElementsByTagName("body")[0]; + this.isPopup = true; + } else { + parent = _par; + this.isPopup = false; + } + this.date = this.dateStr ? new Date(this.dateStr) : new Date(); + + var table = Calendar.createElement("table"); + this.table = table; + table.cellSpacing = 0; + table.cellPadding = 0; + table.calendar = this; + Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown); + + var div = Calendar.createElement("div"); + this.element = div; + div.className = "calendar"; + if (this.isPopup) { + div.style.position = "absolute"; + div.style.display = "none"; + } + div.appendChild(table); + + var thead = Calendar.createElement("thead", table); + var cell = null; + var row = null; + + var cal = this; + var hh = function (text, cs, navtype) { + cell = Calendar.createElement("td", row); + cell.colSpan = cs; + cell.className = "button"; + if (navtype != 0 && Math.abs(navtype) <= 2) + cell.className += " nav"; + Calendar._add_evs(cell); + cell.calendar = cal; + cell.navtype = navtype; + cell.innerHTML = "
    " + text + "
    "; + return cell; + }; + + row = Calendar.createElement("tr", thead); + var title_length = 6; + (this.isPopup) && --title_length; + (this.weekNumbers) && ++title_length; + + hh("?", 1, 400).ttip = Calendar._TT["INFO"]; + this.title = hh("", title_length, 300); + this.title.className = "title"; + if (this.isPopup) { + this.title.ttip = Calendar._TT["DRAG_TO_MOVE"]; + this.title.style.cursor = "move"; + hh("×", 1, 200).ttip = Calendar._TT["CLOSE"]; + } + + row = Calendar.createElement("tr", thead); + row.className = "headrow"; + + this._nav_py = hh("«", 1, -2); + this._nav_py.ttip = Calendar._TT["PREV_YEAR"]; + + this._nav_pm = hh("‹", 1, -1); + this._nav_pm.ttip = Calendar._TT["PREV_MONTH"]; + + this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0); + this._nav_now.ttip = Calendar._TT["GO_TODAY"]; + + this._nav_nm = hh("›", 1, 1); + this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"]; + + this._nav_ny = hh("»", 1, 2); + this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"]; + + // day names + row = Calendar.createElement("tr", thead); + row.className = "daynames"; + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + cell.className = "name wn"; + cell.innerHTML = Calendar._TT["WK"]; + } + for (var i = 7; i > 0; --i) { + cell = Calendar.createElement("td", row); + if (!i) { + cell.navtype = 100; + cell.calendar = this; + Calendar._add_evs(cell); + } + } + this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild; + this._displayWeekdays(); + + var tbody = Calendar.createElement("tbody", table); + this.tbody = tbody; + + for (i = 6; i > 0; --i) { + row = Calendar.createElement("tr", tbody); + if (this.weekNumbers) { + cell = Calendar.createElement("td", row); + } + for (var j = 7; j > 0; --j) { + cell = Calendar.createElement("td", row); + cell.calendar = this; + Calendar._add_evs(cell); + } + } + + if (this.showsTime) { + row = Calendar.createElement("tr", tbody); + row.className = "time"; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + cell.innerHTML = Calendar._TT["TIME"] || " "; + + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = this.weekNumbers ? 4 : 3; + + (function(){ + function makeTimePart(className, init, range_start, range_end) { + var part = Calendar.createElement("span", cell); + part.className = className; + part.innerHTML = init; + part.calendar = cal; + part.ttip = Calendar._TT["TIME_PART"]; + part.navtype = 50; + part._range = []; + if (typeof range_start != "number") + part._range = range_start; + else { + for (var i = range_start; i <= range_end; ++i) { + var txt; + if (i < 10 && range_end >= 10) txt = '0' + i; + else txt = '' + i; + part._range[part._range.length] = txt; + } + } + Calendar._add_evs(part); + return part; + }; + var hrs = cal.date.getHours(); + var mins = cal.date.getMinutes(); + var t12 = !cal.time24; + var pm = (hrs > 12); + if (t12 && pm) hrs -= 12; + var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23); + var span = Calendar.createElement("span", cell); + span.innerHTML = ":"; + span.className = "colon"; + var M = makeTimePart("minute", mins, 0, 59); + var AP = null; + cell = Calendar.createElement("td", row); + cell.className = "time"; + cell.colSpan = 2; + if (t12) + AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]); + else + cell.innerHTML = " "; + + cal.onSetTime = function() { + var pm, hrs = this.date.getHours(), + mins = this.date.getMinutes(); + if (t12) { + pm = (hrs >= 12); + if (pm) hrs -= 12; + if (hrs == 0) hrs = 12; + AP.innerHTML = pm ? "pm" : "am"; + } + H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs; + M.innerHTML = (mins < 10) ? ("0" + mins) : mins; + }; + + cal.onUpdateTime = function() { + var date = this.date; + var h = parseInt(H.innerHTML, 10); + if (t12) { + if (/pm/i.test(AP.innerHTML) && h < 12) + h += 12; + else if (/am/i.test(AP.innerHTML) && h == 12) + h = 0; + } + var d = date.getDate(); + var m = date.getMonth(); + var y = date.getFullYear(); + date.setHours(h); + date.setMinutes(parseInt(M.innerHTML, 10)); + date.setFullYear(y); + date.setMonth(m); + date.setDate(d); + this.dateClicked = false; + this.callHandler(); + }; + })(); + } else { + this.onSetTime = this.onUpdateTime = function() {}; + } + + var tfoot = Calendar.createElement("tfoot", table); + + row = Calendar.createElement("tr", tfoot); + row.className = "footrow"; + + cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300); + cell.className = "ttip"; + if (this.isPopup) { + cell.ttip = Calendar._TT["DRAG_TO_MOVE"]; + cell.style.cursor = "move"; + } + this.tooltips = cell; + + div = Calendar.createElement("div", this.element); + this.monthsCombo = div; + div.className = "combo"; + for (i = 0; i < Calendar._MN.length; ++i) { + var mn = Calendar.createElement("div"); + mn.className = Calendar.is_ie ? "label-IEfix" : "label"; + mn.month = i; + mn.innerHTML = Calendar._SMN[i]; + div.appendChild(mn); + } + + div = Calendar.createElement("div", this.element); + this.yearsCombo = div; + div.className = "combo"; + for (i = 12; i > 0; --i) { + var yr = Calendar.createElement("div"); + yr.className = Calendar.is_ie ? "label-IEfix" : "label"; + div.appendChild(yr); + } + + this._init(this.firstDayOfWeek, this.date); + parent.appendChild(this.element); +}; + +/** keyboard navigation, only for popup calendars */ +Calendar._keyEvent = function(ev) { + var cal = window._dynarch_popupCalendar; + if (!cal || cal.multiple) + return false; + (Calendar.is_ie) && (ev = window.event); + var act = (Calendar.is_ie || ev.type == "keypress"), + K = ev.keyCode; + if (ev.ctrlKey) { + switch (K) { + case 37: // KEY left + act && Calendar.cellClick(cal._nav_pm); + break; + case 38: // KEY up + act && Calendar.cellClick(cal._nav_py); + break; + case 39: // KEY right + act && Calendar.cellClick(cal._nav_nm); + break; + case 40: // KEY down + act && Calendar.cellClick(cal._nav_ny); + break; + default: + return false; + } + } else switch (K) { + case 32: // KEY space (now) + Calendar.cellClick(cal._nav_now); + break; + case 27: // KEY esc + act && cal.callCloseHandler(); + break; + case 37: // KEY left + case 38: // KEY up + case 39: // KEY right + case 40: // KEY down + if (act) { + var prev, x, y, ne, el, step; + prev = K == 37 || K == 38; + step = (K == 37 || K == 39) ? 1 : 7; + function setVars() { + el = cal.currentDateEl; + var p = el.pos; + x = p & 15; + y = p >> 4; + ne = cal.ar_days[y][x]; + };setVars(); + function prevMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() - step); + cal.setDate(date); + }; + function nextMonth() { + var date = new Date(cal.date); + date.setDate(date.getDate() + step); + cal.setDate(date); + }; + while (1) { + switch (K) { + case 37: // KEY left + if (--x >= 0) + ne = cal.ar_days[y][x]; + else { + x = 6; + K = 38; + continue; + } + break; + case 38: // KEY up + if (--y >= 0) + ne = cal.ar_days[y][x]; + else { + prevMonth(); + setVars(); + } + break; + case 39: // KEY right + if (++x < 7) + ne = cal.ar_days[y][x]; + else { + x = 0; + K = 40; + continue; + } + break; + case 40: // KEY down + if (++y < cal.ar_days.length) + ne = cal.ar_days[y][x]; + else { + nextMonth(); + setVars(); + } + break; + } + break; + } + if (ne) { + if (!ne.disabled) + Calendar.cellClick(ne); + else if (prev) + prevMonth(); + else + nextMonth(); + } + } + break; + case 13: // KEY enter + if (act) + Calendar.cellClick(cal.currentDateEl, ev); + break; + default: + return false; + } + return Calendar.stopEvent(ev); +}; + +/** + * (RE)Initializes the calendar to the given date and firstDayOfWeek + */ +Calendar.prototype._init = function (firstDayOfWeek, date) { + var today = new Date(), + TY = today.getFullYear(), + TM = today.getMonth(), + TD = today.getDate(); + this.table.style.visibility = "hidden"; + var year = date.getFullYear(); + if (year < this.minYear) { + year = this.minYear; + date.setFullYear(year); + } else if (year > this.maxYear) { + year = this.maxYear; + date.setFullYear(year); + } + this.firstDayOfWeek = firstDayOfWeek; + this.date = new Date(date); + var month = date.getMonth(); + var mday = date.getDate(); + var no_days = date.getMonthDays(); + + // calendar voodoo for computing the first day that would actually be + // displayed in the calendar, even if it's from the previous month. + // WARNING: this is magic. ;-) + date.setDate(1); + var day1 = (date.getDay() - this.firstDayOfWeek) % 7; + if (day1 < 0) + day1 += 7; + date.setDate(-day1); + date.setDate(date.getDate() + 1); + + var row = this.tbody.firstChild; + var MN = Calendar._SMN[month]; + var ar_days = this.ar_days = new Array(); + var weekend = Calendar._TT["WEEKEND"]; + var dates = this.multiple ? (this.datesCells = {}) : null; + for (var i = 0; i < 6; ++i, row = row.nextSibling) { + var cell = row.firstChild; + if (this.weekNumbers) { + cell.className = "day wn"; + cell.innerHTML = date.getWeekNumber(); + cell = cell.nextSibling; + } + row.className = "daysrow"; + var hasdays = false, iday, dpos = ar_days[i] = []; + for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) { + iday = date.getDate(); + var wday = date.getDay(); + cell.className = "day"; + cell.pos = i << 4 | j; + dpos[j] = cell; + var current_month = (date.getMonth() == month); + if (!current_month) { + if (this.showsOtherMonths) { + cell.className += " othermonth"; + cell.otherMonth = true; + } else { + cell.className = "emptycell"; + cell.innerHTML = " "; + cell.disabled = true; + continue; + } + } else { + cell.otherMonth = false; + hasdays = true; + } + cell.disabled = false; + cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday; + if (dates) + dates[date.print("%Y%m%d")] = cell; + if (this.getDateStatus) { + var status = this.getDateStatus(date, year, month, iday); + if (this.getDateToolTip) { + var toolTip = this.getDateToolTip(date, year, month, iday); + if (toolTip) + cell.title = toolTip; + } + if (status === true) { + cell.className += " disabled"; + cell.disabled = true; + } else { + if (/disabled/i.test(status)) + cell.disabled = true; + cell.className += " " + status; + } + } + if (!cell.disabled) { + cell.caldate = new Date(date); + cell.ttip = "_"; + if (!this.multiple && current_month + && iday == mday && this.hiliteToday) { + cell.className += " selected"; + this.currentDateEl = cell; + } + if (date.getFullYear() == TY && + date.getMonth() == TM && + iday == TD) { + cell.className += " today"; + cell.ttip += Calendar._TT["PART_TODAY"]; + } + if (weekend.indexOf(wday.toString()) != -1) + cell.className += cell.otherMonth ? " oweekend" : " weekend"; + } + } + if (!(hasdays || this.showsOtherMonths)) + row.className = "emptyrow"; + } + this.title.innerHTML = Calendar._MN[month] + ", " + year; + this.onSetTime(); + this.table.style.visibility = "visible"; + this._initMultipleDates(); + // PROFILE + // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms"; +}; + +Calendar.prototype._initMultipleDates = function() { + if (this.multiple) { + for (var i in this.multiple) { + var cell = this.datesCells[i]; + var d = this.multiple[i]; + if (!d) + continue; + if (cell) + cell.className += " selected"; + } + } +}; + +Calendar.prototype._toggleMultipleDate = function(date) { + if (this.multiple) { + var ds = date.print("%Y%m%d"); + var cell = this.datesCells[ds]; + if (cell) { + var d = this.multiple[ds]; + if (!d) { + Calendar.addClass(cell, "selected"); + this.multiple[ds] = date; + } else { + Calendar.removeClass(cell, "selected"); + delete this.multiple[ds]; + } + } + } +}; + +Calendar.prototype.setDateToolTipHandler = function (unaryFunction) { + this.getDateToolTip = unaryFunction; +}; + +/** + * Calls _init function above for going to a certain date (but only if the + * date is different than the currently selected one). + */ +Calendar.prototype.setDate = function (date) { + if (!date.equalsTo(this.date)) { + this._init(this.firstDayOfWeek, date); + } +}; + +/** + * Refreshes the calendar. Useful if the "disabledHandler" function is + * dynamic, meaning that the list of disabled date can change at runtime. + * Just * call this function if you think that the list of disabled dates + * should * change. + */ +Calendar.prototype.refresh = function () { + this._init(this.firstDayOfWeek, this.date); +}; + +/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */ +Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) { + this._init(firstDayOfWeek, this.date); + this._displayWeekdays(); +}; + +/** + * Allows customization of what dates are enabled. The "unaryFunction" + * parameter must be a function object that receives the date (as a JS Date + * object) and returns a boolean value. If the returned value is true then + * the passed date will be marked as disabled. + */ +Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) { + this.getDateStatus = unaryFunction; +}; + +/** Customization of allowed year range for the calendar. */ +Calendar.prototype.setRange = function (a, z) { + this.minYear = a; + this.maxYear = z; +}; + +/** Calls the first user handler (selectedHandler). */ +Calendar.prototype.callHandler = function () { + if (this.onSelected) { + this.onSelected(this, this.date.print(this.dateFormat)); + } +}; + +/** Calls the second user handler (closeHandler). */ +Calendar.prototype.callCloseHandler = function () { + if (this.onClose) { + this.onClose(this); + } + this.hideShowCovered(); +}; + +/** Removes the calendar object from the DOM tree and destroys it. */ +Calendar.prototype.destroy = function () { + var el = this.element.parentNode; + el.removeChild(this.element); + Calendar._C = null; + window._dynarch_popupCalendar = null; +}; + +/** + * Moves the calendar element to a different section in the DOM tree (changes + * its parent). + */ +Calendar.prototype.reparent = function (new_parent) { + var el = this.element; + el.parentNode.removeChild(el); + new_parent.appendChild(el); +}; + +// This gets called when the user presses a mouse button anywhere in the +// document, if the calendar is shown. If the click was outside the open +// calendar this function closes it. +Calendar._checkCalendar = function(ev) { + var calendar = window._dynarch_popupCalendar; + if (!calendar) { + return false; + } + var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev); + for (; el != null && el != calendar.element; el = el.parentNode); + if (el == null) { + // calls closeHandler which should hide the calendar. + window._dynarch_popupCalendar.callCloseHandler(); + return Calendar.stopEvent(ev); + } +}; + +/** Shows the calendar. */ +Calendar.prototype.show = function () { + var rows = this.table.getElementsByTagName("tr"); + for (var i = rows.length; i > 0;) { + var row = rows[--i]; + Calendar.removeClass(row, "rowhilite"); + var cells = row.getElementsByTagName("td"); + for (var j = cells.length; j > 0;) { + var cell = cells[--j]; + Calendar.removeClass(cell, "hilite"); + Calendar.removeClass(cell, "active"); + } + } + this.element.style.display = "block"; + this.hidden = false; + if (this.isPopup) { + window._dynarch_popupCalendar = this; + Calendar.addEvent(document, "keydown", Calendar._keyEvent); + Calendar.addEvent(document, "keypress", Calendar._keyEvent); + Calendar.addEvent(document, "mousedown", Calendar._checkCalendar); + } + this.hideShowCovered(); +}; + +/** + * Hides the calendar. Also removes any "hilite" from the class of any TD + * element. + */ +Calendar.prototype.hide = function () { + if (this.isPopup) { + Calendar.removeEvent(document, "keydown", Calendar._keyEvent); + Calendar.removeEvent(document, "keypress", Calendar._keyEvent); + Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar); + } + this.element.style.display = "none"; + this.hidden = true; + this.hideShowCovered(); +}; + +/** + * Shows the calendar at a given absolute position (beware that, depending on + * the calendar element style -- position property -- this might be relative + * to the parent's containing rectangle). + */ +Calendar.prototype.showAt = function (x, y) { + var s = this.element.style; + s.left = x + "px"; + s.top = y + "px"; + this.show(); +}; + +/** Shows the calendar near a given element. */ +Calendar.prototype.showAtElement = function (el, opts) { + var self = this; + var p = Calendar.getAbsolutePos(el); + if (!opts || typeof opts != "string") { + this.showAt(p.x, p.y + el.offsetHeight); + return true; + } + + function getScrollPos() { + var r = new Object(); + + // All except that I know of except IE + if (window.pageXOffset != null) { + + r.x = window.pageXOffset; + r.y = window.pageYOffset; + // IE 6.x strict + } else if (document.documentElement != null + && (parseInt(document.documentElement.scrollLeft) != 0 + || parseInt(document.documentElement.scrollTop) != 0)) { + + r.x = document.documentElement.scrollLeft; + r.y = document.documentElement.scrollTop; + // all other IE + } else if (document.body != null && + document.body.scrollLeft != null) { + + r.x = document.body.scrollLeft; + r.y = document.body.scrollTop; + // if for some reason none of the above work, this should. + } else if (window.scrollX != null) { + + r.x = window.scrollX; + r.y = window.scrollY; + } + + + return r; + } + + function fixPosition(box) { + + if (box.x < 0) + box.x = 0; + if (box.y < 0) + box.y = 0; + var cp = document.createElement("div"); + var s = cp.style; + s.position = "absolute"; + s.right = s.bottom = s.width = s.height = "0px"; + document.body.appendChild(cp); + var br = Calendar.getAbsolutePos(cp); + document.body.removeChild(cp); + /* if (Calendar.is_ie && !Calendar.is_ie7up) { + br.y += document.body.scrollTop; + br.x += document.body.scrollLeft; + } else { + br.y += window.scrollY; + br.x += window.scrollX; + } */ + var scrollPos = getScrollPos(); + + + br.y += scrollPos.y; + br.x += scrollPos.x; + + var tmp = box.x + box.width - br.x; + + if (tmp > 0) box.x -= tmp; + tmp = box.y + box.height - br.y; + + if (tmp > 0) box.y -= tmp; + }; + this.element.style.display = "block"; + Calendar.continuation_for_the_fucking_khtml_browser = function() { + var w = self.element.offsetWidth; + var h = self.element.offsetHeight; + self.element.style.display = "none"; + var valign = opts.substr(0, 1); + var halign = "l"; + if (opts.length > 1) { + halign = opts.substr(1, 1); + } + // vertical alignment + switch (valign) { + case "T": p.y -= h; break; + case "B": p.y += el.offsetHeight; break; + case "C": p.y += (el.offsetHeight - h) / 2; break; + case "t": p.y += el.offsetHeight - h; break; + case "b": break; // already there + } + // horizontal alignment + switch (halign) { + case "L": p.x -= w; break; + case "R": p.x += el.offsetWidth; break; + case "C": p.x += (el.offsetWidth - w) / 2; break; + case "l": p.x += el.offsetWidth - w; break; + case "r": break; // already there + } + p.width = w; + p.height = h + 40; + self.monthsCombo.style.display = "none"; + fixPosition(p); + self.showAt(p.x, p.y); + }; + if (Calendar.is_khtml) + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10); + else + Calendar.continuation_for_the_fucking_khtml_browser(); +}; + +/** Customizes the date format. */ +Calendar.prototype.setDateFormat = function (str) { + this.dateFormat = str; +}; + +/** Customizes the tooltip date format. */ +Calendar.prototype.setTtDateFormat = function (str) { + this.ttDateFormat = str; +}; + +/** + * Tries to identify the date represented in a string. If successful it also + * calls this.setDate which moves the calendar to the given date. + */ +Calendar.prototype.parseDate = function(str, fmt) { + if (!fmt) + fmt = this.dateFormat; + this.setDate(Date.parseDate(str, fmt)); +}; + +Calendar.prototype.hideShowCovered = function () { + if (!Calendar.is_ie && !Calendar.is_opera) + return; + function getVisib(obj){ + var value = obj.style.visibility; + if (!value) { + if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C + if (!Calendar.is_khtml) + value = document.defaultView. + getComputedStyle(obj, "").getPropertyValue("visibility"); + else + value = ''; + } else if (obj.currentStyle) { // IE + value = obj.currentStyle.visibility; + } else + value = ''; + } + return value; + }; + + var tags = new Array("applet", "iframe", "select"); + var el = this.element; + + var p = Calendar.getAbsolutePos(el); + var EX1 = p.x; + var EX2 = el.offsetWidth + EX1; + var EY1 = p.y; + var EY2 = el.offsetHeight + EY1; + + for (var k = tags.length; k > 0; ) { + var ar = document.getElementsByTagName(tags[--k]); + var cc = null; + + for (var i = ar.length; i > 0;) { + cc = ar[--i]; + + p = Calendar.getAbsolutePos(cc); + var CX1 = p.x; + var CX2 = cc.offsetWidth + CX1; + var CY1 = p.y; + var CY2 = cc.offsetHeight + CY1; + + if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = cc.__msh_save_visibility; + } else { + if (!cc.__msh_save_visibility) { + cc.__msh_save_visibility = getVisib(cc); + } + cc.style.visibility = "hidden"; + } + } + } +}; + +/** Internal function; it displays the bar with the names of the weekday. */ +Calendar.prototype._displayWeekdays = function () { + var fdow = this.firstDayOfWeek; + var cell = this.firstdayname; + var weekend = Calendar._TT["WEEKEND"]; + for (var i = 0; i < 7; ++i) { + cell.className = "day name"; + var realday = (i + fdow) % 7; + if (i) { + cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]); + cell.navtype = 100; + cell.calendar = this; + cell.fdow = realday; + Calendar._add_evs(cell); + } + if (weekend.indexOf(realday.toString()) != -1) { + Calendar.addClass(cell, "weekend"); + } + cell.innerHTML = Calendar._SDN[(i + fdow) % 7]; + cell = cell.nextSibling; + } +}; + +/** Internal function. Hides all combo boxes that might be displayed. */ +Calendar.prototype._hideCombos = function () { + this.monthsCombo.style.display = "none"; + this.yearsCombo.style.display = "none"; +}; + +/** Internal function. Starts dragging the element. */ +Calendar.prototype._dragStart = function (ev) { + if (this.dragging) { + return; + } + this.dragging = true; + var posX; + var posY; + if (Calendar.is_ie) { + posY = window.event.clientY + document.body.scrollTop; + posX = window.event.clientX + document.body.scrollLeft; + } else { + posY = ev.clientY + window.scrollY; + posX = ev.clientX + window.scrollX; + } + var st = this.element.style; + this.xOffs = posX - parseInt(st.left); + this.yOffs = posY - parseInt(st.top); + with (Calendar) { + addEvent(document, "mousemove", calDragIt); + addEvent(document, "mouseup", calDragEnd); + } +}; + +// BEGIN: DATE OBJECT PATCHES + +/** Adds the number of days array to the Date object. */ +Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); + +/** Constants used for time computations */ +Date.SECOND = 1000 /* milliseconds */; +Date.MINUTE = 60 * Date.SECOND; +Date.HOUR = 60 * Date.MINUTE; +Date.DAY = 24 * Date.HOUR; +Date.WEEK = 7 * Date.DAY; + +Date.parseDate = function(str, fmt) { + var today = new Date(); + var y = 0; + var m = -1; + var d = 0; + var a = str.split(/\W+/); + var b = fmt.match(/%./g); + var i = 0, j = 0; + var hr = 0; + var min = 0; + for (i = 0; i < a.length; ++i) { + if (!a[i]) + continue; + switch (b[i]) { + case "%d": + case "%e": + d = parseInt(a[i], 10); + break; + + case "%m": + m = parseInt(a[i], 10) - 1; + break; + + case "%Y": + case "%y": + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + break; + + case "%b": + case "%B": + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; } + } + break; + + case "%H": + case "%I": + case "%k": + case "%l": + hr = parseInt(a[i], 10); + break; + + case "%P": + case "%p": + if (/pm/i.test(a[i]) && hr < 12) + hr += 12; + else if (/am/i.test(a[i]) && hr >= 12) + hr -= 12; + break; + + case "%M": + min = parseInt(a[i], 10); + break; + } + } + if (isNaN(y)) y = today.getFullYear(); + if (isNaN(m)) m = today.getMonth(); + if (isNaN(d)) d = today.getDate(); + if (isNaN(hr)) hr = today.getHours(); + if (isNaN(min)) min = today.getMinutes(); + if (y != 0 && m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + y = 0; m = -1; d = 0; + for (i = 0; i < a.length; ++i) { + if (a[i].search(/[a-zA-Z]+/) != -1) { + var t = -1; + for (j = 0; j < 12; ++j) { + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; } + } + if (t != -1) { + if (m != -1) { + d = m+1; + } + m = t; + } + } else if (parseInt(a[i], 10) <= 12 && m == -1) { + m = a[i]-1; + } else if (parseInt(a[i], 10) > 31 && y == 0) { + y = parseInt(a[i], 10); + (y < 100) && (y += (y > 29) ? 1900 : 2000); + } else if (d == 0) { + d = a[i]; + } + } + if (y == 0) + y = today.getFullYear(); + if (m != -1 && d != 0) + return new Date(y, m, d, hr, min, 0); + return today; +}; + +/** Returns the number of days in the current month */ +Date.prototype.getMonthDays = function(month) { + var year = this.getFullYear(); + if (typeof month == "undefined") { + month = this.getMonth(); + } + if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) { + return 29; + } else { + return Date._MD[month]; + } +}; + +/** Returns the number of day in the year. */ +Date.prototype.getDayOfYear = function() { + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0); + var time = now - then; + return Math.floor(time / Date.DAY); +}; + +/** Returns the number of the week in year, as defined in ISO 8601. */ +Date.prototype.getWeekNumber = function() { + var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0); + var DoW = d.getDay(); + d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu + var ms = d.valueOf(); // GMT + d.setMonth(0); + d.setDate(4); // Thu in Week 1 + return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1; +}; + +/** Checks date and time equality */ +Date.prototype.equalsTo = function(date) { + return ((this.getFullYear() == date.getFullYear()) && + (this.getMonth() == date.getMonth()) && + (this.getDate() == date.getDate()) && + (this.getHours() == date.getHours()) && + (this.getMinutes() == date.getMinutes())); +}; + +/** Set only the year, month, date parts (keep existing time) */ +Date.prototype.setDateOnly = function(date) { + var tmp = new Date(date); + this.setDate(1); + this.setFullYear(tmp.getFullYear()); + this.setMonth(tmp.getMonth()); + this.setDate(tmp.getDate()); +}; + +/** Prints the date in a string according to the given format. */ +Date.prototype.print = function (str) { + var m = this.getMonth(); + var d = this.getDate(); + var y = this.getFullYear(); + var wn = this.getWeekNumber(); + var w = this.getDay(); + var s = {}; + var hr = this.getHours(); + var pm = (hr >= 12); + var ir = (pm) ? (hr - 12) : hr; + var dy = this.getDayOfYear(); + if (ir == 0) + ir = 12; + var min = this.getMinutes(); + var sec = this.getSeconds(); + s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N] + s["%A"] = Calendar._DN[w]; // full weekday name + s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N] + s["%B"] = Calendar._MN[m]; // full month name + // FIXME: %c : preferred date and time representation for the current locale + s["%C"] = 1 + Math.floor(y / 100); // the century number + s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31) + s["%e"] = d; // the day of the month (range 1 to 31) + // FIXME: %D : american date style: %m/%d/%y + // FIXME: %E, %F, %G, %g, %h (man strftime) + s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format) + s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format) + s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366) + s["%k"] = hr; // hour, range 0 to 23 (24h format) + s["%l"] = ir; // hour, range 1 to 12 (12h format) + s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12 + s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59 + s["%n"] = "\n"; // a newline character + s["%p"] = pm ? "PM" : "AM"; + s["%P"] = pm ? "pm" : "am"; + // FIXME: %r : the time in am/pm notation %I:%M:%S %p + // FIXME: %R : the time in 24-hour notation %H:%M + s["%s"] = Math.floor(this.getTime() / 1000); + s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59 + s["%t"] = "\t"; // a tab character + // FIXME: %T : the time in 24-hour notation (%H:%M:%S) + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn; + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON) + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN) + // FIXME: %x : preferred date representation for the current locale without the time + // FIXME: %X : preferred time representation for the current locale without the date + s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99) + s["%Y"] = y; // year with the century + s["%%"] = "%"; // a literal '%' character + + var re = /%./g; + if (!Calendar.is_ie5 && !Calendar.is_khtml) + return str.replace(re, function (par) { return s[par] || par; }); + + var a = str.match(re); + for (var i = 0; i < a.length; i++) { + var tmp = s[a[i]]; + if (tmp) { + re = new RegExp(a[i], 'g'); + str = str.replace(re, tmp); + } + } + + return str; +}; + +Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear; +Date.prototype.setFullYear = function(y) { + var d = new Date(this); + d.__msh_oldSetFullYear(y); + if (d.getMonth() != this.getMonth()) + this.setDate(28); + this.__msh_oldSetFullYear(y); +}; + +// END: DATE OBJECT PATCHES + + + + +// global object that remembers the calendar +window._dynarch_popupCalendar = null; + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar.php b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar.php new file mode 100644 index 0000000..2e563e9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar.php @@ -0,0 +1,124 @@ +calendar_file = 'calendar_stripped.js'; + $this->calendar_setup_file = 'calendar-setup_stripped.js'; + } else { + $this->calendar_file = 'calendar.js'; + $this->calendar_setup_file = 'calendar-setup.js'; + } + $this->calendar_lang_file = 'lang/calendar-' . $lang . '.js'; + $this->calendar_theme_file = $theme.'.css'; + $this->calendar_lib_path = preg_replace('/\/+$/', '/', $calendar_lib_path); + $this->calendar_options = array('ifFormat' => '%Y/%m/%d', + 'daFormat' => '%Y/%m/%d'); + } + + function set_option($name, $value) { + $this->calendar_options[$name] = $value; + } + + function load_files() { + echo $this->get_load_files_code(); + } + + function get_load_files_code() { + $code = ( '' . NEWLINE ); + $code .= ( '' . NEWLINE ); + $code .= ( '' . NEWLINE ); + $code .= ( '' ); + return $code; + } + + function _make_calendar($other_options = array()) { + $js_options = $this->_make_js_hash(array_merge($this->calendar_options, $other_options)); + $code = ( '' ); + return $code; + } + + function make_input_field($cal_options = array(), $field_attributes = array(), $output = true) { + $result = ""; + $id = $this->_gen_id(); + $attrstr = $this->_make_html_attr(array_merge($field_attributes, + array('id' => $this->_field_id($id), + 'type' => 'text'))); + $result.= ''; + $result.= '
    ' . + ''; + + $options = array_merge($cal_options, + array('inputField' => $this->_field_id($id), + 'button' => $this->_trigger_id($id))); + $result.= $this->_make_calendar($options); + + if ($output) + echo $output; + return $output; + } + + /// PRIVATE SECTION + + function _field_id($id) { return 'f-calendar-field-' . $id; } + function _trigger_id($id) { return 'f-calendar-trigger-' . $id; } + function _gen_id() { static $id = 0; return ++$id; } + + function _make_js_hash($array) { + $jstr = ''; + reset($array); + while (list($key, $val) = each($array)) { + if (is_bool($val)) + $val = $val ? 'true' : 'false'; + else if (!is_numeric($val)) + $val = '"'.$val.'"'; + if ($jstr) $jstr .= ','; + $jstr .= '"' . $key . '":' . $val; + } + return $jstr; + } + + function _make_html_attr($array) { + $attrstr = ''; + reset($array); + while (list($key, $val) = each($array)) { + $attrstr .= $key . '="' . $val . '" '; + } + return $attrstr; + } +}; + +?> diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar_stripped.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar_stripped.js new file mode 100644 index 0000000..d5e5b29 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/calendar_stripped.js @@ -0,0 +1,14 @@ +/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo + * ----------------------------------------------------------- + * + * The DHTML Calendar, version 1.0 "It is happening again" + * + * Details and latest version at: + * www.dynarch.com/projects/calendar + * + * This script is developed by Dynarch.com. Visit us at www.dynarch.com. + * + * This script is distributed under the GNU Lesser General Public License. + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html + */ + Calendar=function(firstDayOfWeek,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=null;this.timeout=null;this.onSelected=onSelected||null;this.onClose=onClose||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=typeof firstDayOfWeek=="number"?firstDayOfWeek:Calendar._FD;this.showsOtherMonths=false;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined")Calendar._SDN_len=3;var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,Calendar._SDN_len);}Calendar._SDN=ar;if(typeof Calendar._SMN_len=="undefined")Calendar._SMN_len=3;ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,Calendar._SMN_len);}Calendar._SMN=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(el){var SL=0,ST=0;var is_div=/^div$/i.test(el.tagName);if(is_div&&el.scrollLeft)SL=el.scrollLeft;if(is_div&&el.scrollTop)ST=el.scrollTop;var r={x:el.offsetLeft-SL,y:el.offsetTop-ST};if(el.offsetParent){var tmp=this.getAbsolutePos(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;}return r;};Calendar.isRelated=function(el,evt){var related=evt.relatedTarget;if(!related){var type=evt.type;if(type=="mouseover"){related=evt.fromElement;}else if(type=="mouseout"){related=evt.toElement;}}while(related){if(related==el){return true;}related=related.parentNode;}return false;};Calendar.removeClass=function(el,className){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=className){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,className){Calendar.removeClass(el,className);el.className+=" "+className;};Calendar.getElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.currentTarget;while(f.nodeType!=1||/^div$/i.test(f.tagName))f=f.parentNode;return f;};Calendar.getTargetElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.target;while(f.nodeType!=1)f=f.parentNode;return f;};Calendar.stopEvent=function(ev){ev||(ev=window.event);if(Calendar.is_ie){ev.cancelBubble=true;ev.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,evname,func){if(el.attachEvent){el.attachEvent("on"+evname,func);}else if(el.addEventListener){el.addEventListener(evname,func,true);}else{el["on"+evname]=func;}};Calendar.removeEvent=function(el,evname,func){if(el.detachEvent){el.detachEvent("on"+evname,func);}else if(el.removeEventListener){el.removeEventListener(evname,func,true);}else{el["on"+evname]=null;}};Calendar.createElement=function(type,parent){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",type);}else{el=document.createElement(type);}if(typeof parent!="undefined"){parent.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else if(typeof el.parentNode.month!="undefined"){return el.parentNode;}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else if(typeof el.parentNode.year!="undefined"){return el.parentNode;}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;var s=mc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var mcw=mc.offsetWidth;if(typeof mcw=="undefined")mcw=50;s.left=(cd.offsetLeft+cd.offsetWidth-mcw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var show=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.innerHTML=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?cal.yearStep:-cal.yearStep;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var ycw=yc.offsetWidth;if(typeof ycw=="undefined")ycw=50;s.left=(cd.offsetLeft+cd.offsetWidth-ycw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev);}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var target=Calendar.getTargetElement(ev);if(target==el||target.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{if(typeof el.navtype=="undefined"||(el.navtype!=50&&(el.navtype==0||Math.abs(el.navtype)>2)))Calendar.removeClass(el,"active");Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}ev||(ev=window.event);if(el.navtype==50&&target!=el){var pos=Calendar.getAbsolutePos(el);var w=el.offsetWidth;var x=ev.clientX;var dx;var decrease=true;if(x>pos.x+w){dx=x-pos.x-w;decrease=false;}else dx=pos.x-x;if(dx<0)dx=0;var range=el._range;var current=el._current;var count=Math.floor(dx/10)%range.length;for(var i=range.length;--i>=0;)if(range[i]==current)break;while(count-->0)if(decrease){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=newval;cal.onUpdateTime();}var mon=Calendar.findMonth(target);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}var year=Calendar.findYear(target);if(year){if(year.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(year,"hilite");cal.hilitedYear=year;}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posX=ev.pageX;posY=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(posX-cal.xOffs)+"px";st.top=(posY-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300)with(Calendar){if(el.navtype==50){el._current=el.innerHTML;addEvent(document,"mousemove",tableMouseOver);}else addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver);addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp);}else if(cal.isPopup){cal._dragStart(ev);}if(el.navtype==-1||el.navtype==1){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else if(el.navtype==-2||el.navtype==2){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev),ev||window.event);if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){el.ttip=el.caldate.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.innerHTML=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");var cal=el.calendar;if(cal&&cal.getDateToolTip){var d=el.caldate;window.status=d;el.title=cal.getDateToolTip(d,d.getFullYear(),d.getMonth(),d.getDate());}}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled)return false;removeClass(el,"hilite");if(el.caldate)removeClass(el.parentNode,"rowhilite");if(el.calendar)el.calendar.tooltips.innerHTML=_TT["SEL_DATE"];}};Calendar.cellClick=function(el,ev){var cal=el.calendar;var closing=false;var newdate=false;var date=null;if(typeof el.navtype=="undefined"){if(cal.currentDateEl){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}}cal.date.setDateOnly(el.caldate);date=cal.date;var other_month=!(cal.dateClicked=!el.otherMonth);if(!other_month&&!cal.currentDateEl&&cal.multiple)cal._toggleMultipleDate(new Date(date));else newdate=!el.disabled;if(other_month)cal._init(cal.firstDayOfWeek,date);}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=new Date(cal.date);if(el.navtype==0)date.setDateOnly(new Date());cal.dateClicked=false;var year=date.getFullYear();var mon=date.getMonth();function setMonth(m){var day=date.getDate();var max=date.getMonthDays(m);if(day>max){date.setDate(max);}date.setMonth(m);};switch(el.navtype){case 400:Calendar.removeClass(el,"hilite");var text=Calendar._TT["ABOUT"];if(typeof text!="undefined"){text+=cal.showsTime?Calendar._TT["ABOUT_TIME"]:"";}else{text="Help and about box text is not translated into this language.\n"+"If you know this language and you feel generous please update\n"+"the corresponding file in \"lang\" subdir to match calendar-en.js\n"+"and send it back to to get it into the distribution ;-)\n\n"+"Thank you!\n"+"http://dynarch.com/mishoo/calendar.epl\n";}alert(text);return;case-2:if(year>cal.minYear){date.setFullYear(year-1);}break;case-1:if(mon>0){setMonth(mon-1);}else if(year-->cal.minYear){date.setFullYear(year);setMonth(11);}break;case 1:if(mon<11){setMonth(mon+1);}else if(year=0;)if(range[i]==current)break;if(ev&&ev.shiftKey){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=newval;cal.onUpdateTime();return;case 0:if((typeof cal.getDateStatus=="function")&&cal.getDateStatus(date,date.getFullYear(),date.getMonth(),date.getDate())){return false;}break;}if(!date.equalsTo(cal.date)){cal.setDate(date);newdate=true;}else if(el.navtype==0)newdate=closing=true;}if(newdate){ev&&cal.callHandler();}if(closing){Calendar.removeClass(el,"hilite");ev&&cal.callCloseHandler();}};Calendar.prototype.create=function(_par){var parent=null;if(!_par){parent=document.getElementsByTagName("body")[0];this.isPopup=true;}else{parent=_par;this.isPopup=false;}this.date=this.dateStr?new Date(this.dateStr):new Date();var table=Calendar.createElement("table");this.table=table;table.cellSpacing=0;table.cellPadding=0;table.calendar=this;Calendar.addEvent(table,"mousedown",Calendar.tableMouseDown);var div=Calendar.createElement("div");this.element=div;div.className="calendar";if(this.isPopup){div.style.position="absolute";div.style.display="none";}div.appendChild(table);var thead=Calendar.createElement("thead",table);var cell=null;var row=null;var cal=this;var hh=function(text,cs,navtype){cell=Calendar.createElement("td",row);cell.colSpan=cs;cell.className="button";if(navtype!=0&&Math.abs(navtype)<=2)cell.className+=" nav";Calendar._add_evs(cell);cell.calendar=cal;cell.navtype=navtype;cell.innerHTML="
    "+text+"
    ";return cell;};row=Calendar.createElement("tr",thead);var title_length=6;(this.isPopup)&&--title_length;(this.weekNumbers)&&++title_length;hh("?",1,400).ttip=Calendar._TT["INFO"];this.title=hh("",title_length,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT["DRAG_TO_MOVE"];this.title.style.cursor="move";hh("×",1,200).ttip=Calendar._TT["CLOSE"];}row=Calendar.createElement("tr",thead);row.className="headrow";this._nav_py=hh("«",1,-2);this._nav_py.ttip=Calendar._TT["PREV_YEAR"];this._nav_pm=hh("‹",1,-1);this._nav_pm.ttip=Calendar._TT["PREV_MONTH"];this._nav_now=hh(Calendar._TT["TODAY"],this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT["GO_TODAY"];this._nav_nm=hh("›",1,1);this._nav_nm.ttip=Calendar._TT["NEXT_MONTH"];this._nav_ny=hh("»",1,2);this._nav_ny.ttip=Calendar._TT["NEXT_YEAR"];row=Calendar.createElement("tr",thead);row.className="daynames";if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.className="name wn";cell.innerHTML=Calendar._TT["WK"];}for(var i=7;i>0;--i){cell=Calendar.createElement("td",row);if(!i){cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var tbody=Calendar.createElement("tbody",table);this.tbody=tbody;for(i=6;i>0;--i){row=Calendar.createElement("tr",tbody);if(this.weekNumbers){cell=Calendar.createElement("td",row);}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);cell.calendar=this;Calendar._add_evs(cell);}}if(this.showsTime){row=Calendar.createElement("tr",tbody);row.className="time";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;cell.innerHTML=Calendar._TT["TIME"]||" ";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=this.weekNumbers?4:3;(function(){function makeTimePart(className,init,range_start,range_end){var part=Calendar.createElement("span",cell);part.className=className;part.innerHTML=init;part.calendar=cal;part.ttip=Calendar._TT["TIME_PART"];part.navtype=50;part._range=[];if(typeof range_start!="number")part._range=range_start;else{for(var i=range_start;i<=range_end;++i){var txt;if(i<10&&range_end>=10)txt='0'+i;else txt=''+i;part._range[part._range.length]=txt;}}Calendar._add_evs(part);return part;};var hrs=cal.date.getHours();var mins=cal.date.getMinutes();var t12=!cal.time24;var pm=(hrs>12);if(t12&&pm)hrs-=12;var H=makeTimePart("hour",hrs,t12?1:0,t12?12:23);var span=Calendar.createElement("span",cell);span.innerHTML=":";span.className="colon";var M=makeTimePart("minute",mins,0,59);var AP=null;cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;if(t12)AP=makeTimePart("ampm",pm?"pm":"am",["am","pm"]);else cell.innerHTML=" ";cal.onSetTime=function(){var pm,hrs=this.date.getHours(),mins=this.date.getMinutes();if(t12){pm=(hrs>=12);if(pm)hrs-=12;if(hrs==0)hrs=12;AP.innerHTML=pm?"pm":"am";}H.innerHTML=(hrs<10)?("0"+hrs):hrs;M.innerHTML=(mins<10)?("0"+mins):mins;};cal.onUpdateTime=function(){var date=this.date;var h=parseInt(H.innerHTML,10);if(t12){if(/pm/i.test(AP.innerHTML)&&h<12)h+=12;else if(/am/i.test(AP.innerHTML)&&h==12)h=0;}var d=date.getDate();var m=date.getMonth();var y=date.getFullYear();date.setHours(h);date.setMinutes(parseInt(M.innerHTML,10));date.setFullYear(y);date.setMonth(m);date.setDate(d);this.dateClicked=false;this.callHandler();};})();}else{this.onSetTime=this.onUpdateTime=function(){};}var tfoot=Calendar.createElement("tfoot",table);row=Calendar.createElement("tr",tfoot);row.className="footrow";cell=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);cell.className="ttip";if(this.isPopup){cell.ttip=Calendar._TT["DRAG_TO_MOVE"];cell.style.cursor="move";}this.tooltips=cell;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";div.appendChild(yr);}this._init(this.firstDayOfWeek,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){var cal=window._dynarch_popupCalendar;if(!cal||cal.multiple)return false;(Calendar.is_ie)&&(ev=window.event);var act=(Calendar.is_ie||ev.type=="keypress"),K=ev.keyCode;if(ev.ctrlKey){switch(K){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else switch(K){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.callCloseHandler();break;case 37:case 38:case 39:case 40:if(act){var prev,x,y,ne,el,step;prev=K==37||K==38;step=(K==37||K==39)?1:7;function setVars(){el=cal.currentDateEl;var p=el.pos;x=p&15;y=p>>4;ne=cal.ar_days[y][x];};setVars();function prevMonth(){var date=new Date(cal.date);date.setDate(date.getDate()-step);cal.setDate(date);};function nextMonth(){var date=new Date(cal.date);date.setDate(date.getDate()+step);cal.setDate(date);};while(1){switch(K){case 37:if(--x>=0)ne=cal.ar_days[y][x];else{x=6;K=38;continue;}break;case 38:if(--y>=0)ne=cal.ar_days[y][x];else{prevMonth();setVars();}break;case 39:if(++x<7)ne=cal.ar_days[y][x];else{x=0;K=40;continue;}break;case 40:if(++ythis.maxYear){year=this.maxYear;date.setFullYear(year);}this.firstDayOfWeek=firstDayOfWeek;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var day1=(date.getDay()-this.firstDayOfWeek)%7;if(day1<0)day1+=7;date.setDate(-day1);date.setDate(date.getDate()+1);var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var ar_days=this.ar_days=new Array();var weekend=Calendar._TT["WEEKEND"];var dates=this.multiple?(this.datesCells={}):null;for(var i=0;i<6;++i,row=row.nextSibling){var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.innerHTML=date.getWeekNumber();cell=cell.nextSibling;}row.className="daysrow";var hasdays=false,iday,dpos=ar_days[i]=[];for(var j=0;j<7;++j,cell=cell.nextSibling,date.setDate(iday+1)){iday=date.getDate();var wday=date.getDay();cell.className="day";cell.pos=i<<4|j;dpos[j]=cell;var current_month=(date.getMonth()==month);if(!current_month){if(this.showsOtherMonths){cell.className+=" othermonth";cell.otherMonth=true;}else{cell.className="emptycell";cell.innerHTML=" ";cell.disabled=true;continue;}}else{cell.otherMonth=false;hasdays=true;}cell.disabled=false;cell.innerHTML=this.getDateText?this.getDateText(date,iday):iday;if(dates)dates[date.print("%Y%m%d")]=cell;if(this.getDateStatus){var status=this.getDateStatus(date,year,month,iday);if(status===true){cell.className+=" disabled";cell.disabled=true;}else{if(/disabled/i.test(status))cell.disabled=true;cell.className+=" "+status;}}if(!cell.disabled){cell.caldate=new Date(date);cell.ttip="_";if(!this.multiple&¤t_month&&iday==mday&&this.hiliteToday){cell.className+=" selected";this.currentDateEl=cell;}if(date.getFullYear()==TY&&date.getMonth()==TM&&iday==TD){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(weekend.indexOf(wday.toString())!=-1)cell.className+=cell.otherMonth?" oweekend":" weekend";}}if(!(hasdays||this.showsOtherMonths))row.className="emptyrow";}this.title.innerHTML=Calendar._MN[month]+", "+year;this.onSetTime();this.table.style.visibility="visible";this._initMultipleDates();};Calendar.prototype._initMultipleDates=function(){if(this.multiple){for(var i in this.multiple){var cell=this.datesCells[i];var d=this.multiple[i];if(!d)continue;if(cell)cell.className+=" selected";}}};Calendar.prototype._toggleMultipleDate=function(date){if(this.multiple){var ds=date.print("%Y%m%d");var cell=this.datesCells[ds];if(cell){var d=this.multiple[ds];if(!d){Calendar.addClass(cell,"selected");this.multiple[ds]=date;}else{Calendar.removeClass(cell,"selected");delete this.multiple[ds];}}}};Calendar.prototype.setDateToolTipHandler=function(unaryFunction){this.getDateToolTip=unaryFunction;};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.firstDayOfWeek,date);}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date);};Calendar.prototype.setFirstDayOfWeek=function(firstDayOfWeek){this._init(firstDayOfWeek,this.date);this._displayWeekdays();};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(unaryFunction){this.getDateStatus=unaryFunction;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;window._dynarch_popupCalendar=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){var calendar=window._dynarch_popupCalendar;if(!calendar){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=calendar.element;el=el.parentNode);if(el==null){window._dynarch_popupCalendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var rows=this.table.getElementsByTagName("tr");for(var i=rows.length;i>0;){var row=rows[--i];Calendar.removeClass(row,"rowhilite");var cells=row.getElementsByTagName("td");for(var j=cells.length;j>0;){var cell=cells[--j];Calendar.removeClass(cell,"hilite");Calendar.removeClass(cell,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window._dynarch_popupCalendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,opts){var self=this;var p=Calendar.getAbsolutePos(el);if(!opts||typeof opts!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}function fixPosition(box){if(box.x<0)box.x=0;if(box.y<0)box.y=0;var cp=document.createElement("div");var s=cp.style;s.position="absolute";s.right=s.bottom=s.width=s.height="0px";document.body.appendChild(cp);var br=Calendar.getAbsolutePos(cp);document.body.removeChild(cp);if(Calendar.is_ie){br.y+=document.body.scrollTop;br.x+=document.body.scrollLeft;}else{br.y+=window.scrollY;br.x+=window.scrollX;}var tmp=box.x+box.width-br.x;if(tmp>0)box.x-=tmp;tmp=box.y+box.height-br.y;if(tmp>0)box.y-=tmp;};this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var w=self.element.offsetWidth;var h=self.element.offsetHeight;self.element.style.display="none";var valign=opts.substr(0,1);var halign="l";if(opts.length>1){halign=opts.substr(1,1);}switch(valign){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(halign){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "l":p.x+=el.offsetWidth-w;break;case "r":break;}p.width=w;p.height=h+40;self.monthsCombo.style.display="none";fixPosition(p);self.showAt(p.x,p.y);};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){if(!fmt)fmt=this.dateFormat;this.setDate(Date.parseDate(str,fmt));};Calendar.prototype.hideShowCovered=function(){if(!Calendar.is_ie&&!Calendar.is_opera)return;function getVisib(obj){var value=obj.style.visibility;if(!value){if(document.defaultView&&typeof(document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml)value=document.defaultView. getComputedStyle(obj,"").getPropertyValue("visibility");else value='';}else if(obj.currentStyle){value=obj.currentStyle.visibility;}else value='';}return value;};var tags=new Array("applet","iframe","select");var el=this.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=tags.length;k>0;){var ar=document.getElementsByTagName(tags[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(this.hidden||(CX1>EX2)||(CX2EY2)||(CY229)?1900:2000);break;case "%b":case "%B":for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}break;case "%H":case "%I":case "%k":case "%l":hr=parseInt(a[i],10);break;case "%P":case "%p":if(/pm/i.test(a[i])&&hr<12)hr+=12;else if(/am/i.test(a[i])&&hr>=12)hr-=12;break;case "%M":min=parseInt(a[i],10);break;}}if(isNaN(y))y=today.getFullYear();if(isNaN(m))m=today.getMonth();if(isNaN(d))d=today.getDate();if(isNaN(hr))hr=today.getHours();if(isNaN(min))min=today.getMinutes();if(y!=0&&m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);y=0;m=-1;d=0;for(i=0;i31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0)y=today.getFullYear();if(m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);return today;};Date.prototype.getMonthDays=function(month){var year=this.getFullYear();if(typeof month=="undefined"){month=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&month==1){return 29;}else{return Date._MD[month];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,0,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var d=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var DoW=d.getDay();d.setDate(d.getDate()-(DoW+6)%7+3);var ms=d.valueOf();d.setMonth(0);d.setDate(4);return Math.round((ms-d.valueOf())/(7*864e5))+1;};Date.prototype.equalsTo=function(date){return((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate())&&(this.getHours()==date.getHours())&&(this.getMinutes()==date.getMinutes()));};Date.prototype.setDateOnly=function(date){var tmp=new Date(date);this.setDate(1);this.setFullYear(tmp.getFullYear());this.setMonth(tmp.getMonth());this.setDate(tmp.getDate());};Date.prototype.print=function(str){var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s={};var hr=this.getHours();var pm=(hr>=12);var ir=(pm)?(hr-12):hr;var dy=this.getDayOfYear();if(ir==0)ir=12;var min=this.getMinutes();var sec=this.getSeconds();s["%a"]=Calendar._SDN[w];s["%A"]=Calendar._DN[w];s["%b"]=Calendar._SMN[m];s["%B"]=Calendar._MN[m];s["%C"]=1+Math.floor(y/100);s["%d"]=(d<10)?("0"+d):d;s["%e"]=d;s["%H"]=(hr<10)?("0"+hr):hr;s["%I"]=(ir<10)?("0"+ir):ir;s["%j"]=(dy<100)?((dy<10)?("00"+dy):("0"+dy)):dy;s["%k"]=hr;s["%l"]=ir;s["%m"]=(m<9)?("0"+(1+m)):(1+m);s["%M"]=(min<10)?("0"+min):min;s["%n"]="\n";s["%p"]=pm?"PM":"AM";s["%P"]=pm?"pm":"am";s["%s"]=Math.floor(this.getTime()/1000);s["%S"]=(sec<10)?("0"+sec):sec;s["%t"]="\t";s["%U"]=s["%W"]=s["%V"]=(wn<10)?("0"+wn):wn;s["%u"]=w+1;s["%w"]=w;s["%y"]=(''+y).substr(2,2);s["%Y"]=y;s["%%"]="%";var re=/%./g;if(!Calendar.is_ie5&&!Calendar.is_khtml)return str.replace(re,function(par){return s[par]||par;});var a=str.match(re);for(var i=0;i + +How to include additional info in day cells + + + + + + + + +

    How to include additional info in day cells

    + +
    + + + +

    The idea is simple:

    + +
      +
    1. +

      Define a callback that takes two parameters like this:

      +
      function getDateText(date, d)
      +

      + This function will receive the date object as the first + parameter and the current date number (1..31) as the second (you + can get it as well by calling date.getDate() but since it's very + probably useful I thought I'd pass it too so that we can avoid a + function call). +

      +

      + This function must return the text to be inserted in + the cell of the passed date. That is, one should at least + "return d;". +

      +
    2. +
    3. + Pass the above function as the "dateText" parameter to + Calendar.setup. +
    4. +
    + +

    + The function could simply look like: +

    + +
      function getDateText(date, d) {
    +    if (d == 12) {
    +      return "12th";
    +    } else if (d == 13) {
    +      return "bad luck";
    +    } /* ... etc ... */
    +  }
    + +

    + but it's easy to imagine that this approach sucks. For a better + way, see the source of this page and note the usage of an externally + defined "dateText" object which maps "date" to "date info", also + taking into account the year and month. This object can be easily + generated from a database, and the getDateText function becomes + extremely simple (and static). +

    + +

    + Cheers! +

    + +
    +
    mishoo
    + Last modified: Sat Mar 5 17:18:06 EET 2005 + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/field-button.jpg b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/field-button.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ecbe9d8d45a7a4657baad518781aa4599555f112 GIT binary patch literal 2509 zcmb7EdpOkT7yr(cTt+jD%Y>K=MO1Esl@?<#2C+j~myNB=Xl=$Nx~Qbwr(B!HC7FiI zsIcxM3AvlqxMvJqTq;DC`fZAxZR__uzu)h#-+7<+Jn!?K=X}ojoaghtn`4{LfUP8= zGZ6rRK)^Z40ydum$__EK;{f353g`m>AT8Mv+Y|xz01N_!LLo4TgTY{MDLH8=i7Cj+ zZjnPOpioE!BvMgXT}4p|gGM4%wN)`18r!#TS5(33U^R8rHMeX24FZy+O2MTN($WY` zC8Uz(|81L(0Hida1w4a*umBhdf*?Vgj{$W6fJjLE&EuOv;V>`=A|)+}+H3_t5HJ)1 z2g78fzQiRFC=3oDQHp5oKq>4#?_!~nvWczd@f;mvQ@ou=d{Nbl9XK=lAbOl6U->_P zzW{*1l6wuLq#gtSL%!7n01#4p*&~pi(Xu%X$U#7o4k1Y30IOyHaoA(z{mcfDbDQcTE=4ejlGlhR&a1{gj_jNy{OY*jy}_fw#2n z=1&_ilA?NZ3x2%S-oPpj9nH5`xU5Y_sK*6%zVAxP(a?}EB2>*z2!f!unvNz8O*YOU4k4OR2rgxMkxQGlkLGwHVC1>}rSqvksd zl%|-}a9r)DXkdhrz*fWKT1<7edgzJ=WN>A6$L-4+%kT-uM%?IUr@Cw^`fCw;&i*Mi zqV~Qu%4L8rKs3d)2j#6SA_%opSD#^e(ueGIr|WeuUy{)g@ofn;RB~5TbcD|2Ft_RU zgn9LMD{Z%$!MFOHDC0TSQ+YaWI?;7V)XyZRl6NUssf8HcT(Wtc>&Dj-E#LT!H5r6+ z4F{eN`UH;W1jMu?J}j$-Rln>AW}4ZCGG$4}xE_l8`b`-Rmc|#W9PbkfjpCHc$mi4j zoZri9rTGkcny)j;*mgxlYaZg>dIPQrg|N-CpT=@5@IVC%jp!Ep)$WrBP;YG z!T`QXuc2`gUexLkpRjvQYlJnHVpFU?MF@;Ln#xlc2dX>o9WVFQ9XYz|;OxFmtYSYo zYOWY0dm+b|C9_vOV@pItyJcWp%7-j-bb zVD@mVFbmOjW-v};&cO4zMqmS#M0s_;FJ#-r(iBUZYmK)e1SYiM?#Sow#3|9Sy!x;2 zN9t?UpeZO*G_Y~nYm7O;ijwZ?X#J4mZ&`9~ zm z*T@?8#M?$rn}#vkcV%u#RGrY)CQu`--@J0LIa;ug*i=p_A#g3BGs(;rlA5cGveSJT zeMBtM#k%>7-f*tb)px6pN>8Vk>+wv-*97pZhQ4S2h`&_7zM`*NS#W};rYrPCJ1V7b zo$%6zcJ@qE8)WlwWrtFi9q28odP$YLTH!}6Ops89JlW{Ly2zHeJ<{2=3+h`nY6hf9a7BnKXWCZirqy1^Hc-Y z_nK3f0OuIula=YK{Dk7_lppQPMHJ9(T)+9p{-P&u=h^6hF{hCa0B>*Q0Ie(XSQ{!7 zn)ahei~bmgMU71QPm;K~W0JnNbq;P}FXo&U;=J;T`%3t2QTl|{0)yWtYAdF zEczY6=_m1w9Im^tlo?SbMs*QVFxdpj2XnVWPs4)Yc=cBl$dW@&s+;nsN+;ilK16y` zDrp&itwhmb+%C($aYs|c#FWDK@!?*(1jI!7I`R3fR;@PoEavk7s^3h-`6%05fn~NM$gBSo=F(5>*$| zJM!D+x+`Z%@+iGMX!5XPF3x+QC%rey*?h=bd&ocqW?X)dJ}T?Xq4jm`Q_lz&fCdP? zI6T_x2Qy0TKSR;0f>#9kzkD4pA%bbS5`C>i{^je7M>hepu-nZ}_46?wgMzprId->J z+Zx^y(F6S<){jFg+_}($r?Gk)pF?;LmN83oH@r&lvwt0G+yBn0=H$|w6TyxPuLhgT zY)&uE^m?N>=Y$*X?e+MNH2Q@r6QA*)G`_<$KmEL8f9%rjP2jqTjq|$r)cGBs>;HX_ z>2rQ>|FN-n6WI2#Gk&_TX*Br70TH7yJOdL?49bz4G*=zw6i__<37m%Mq?`K9-jL0w Fe*qKRb9w*( literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference-Z-S.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference-Z-S.css new file mode 100644 index 0000000..812b3fb --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference-Z-S.css @@ -0,0 +1,195 @@ + + body { + color: black; + /* background-color: #e5e5e5;*/ + background-color: #ffffff; + /*background-color: beige;*/ + margin-top: 2em; + margin-left: 8%; + margin-right: 8%; + } + + h1,h2,h3,h4,h5,h6 { + margin-top: .5em; + } + + .title { + font-size: 200%; + font-weight: normal; + margin-top: 2.8em; + text-align: center; + } + + .partheading { + font-size: 100%; + } + + .chapterheading { + font-size: 100%; + } + + .beginsection { + font-size: 110%; + } + + .tiny { + font-size: 40%; + } + + .scriptsize { + font-size: 60%; + } + + .footnotesize { + font-size: 75%; + } + + .small { + font-size: 90%; + } + + .normalsize { + font-size: 100%; + } + + .large { + font-size: 120%; + } + + .largecap { + font-size: 150%; + } + + .largeup { + font-size: 200%; + } + + .huge { + font-size: 300%; + } + + .hugecap { + font-size: 350%; + } + + pre { + margin-left: 2em; + } + + blockquote { + margin-left: 2em; + } + + ol { + list-style-type: decimal; + } + + ol ol { + list-style-type: lower-alpha; + } + + ol ol ol { + list-style-type: lower-roman; + } + + ol ol ol ol { + list-style-type: upper-alpha; + } + + tt i { + font-family: serif; + } + + .verbatim em { + font-family: serif; + } + + /* + .verbatim { + color: #4d0000; + } + */ + + .scheme em { + color: black; + font-family: serif; + } + + .scheme { + color: brown; + } + + .scheme .keyword { + color: #990000; + font-weight: bold; + } + + .scheme .builtin { + color: #990000; + } + + .scheme .variable { + color: navy; + } + + .scheme .global { + color: purple; + } + + .scheme .selfeval { + color: green; + } + + .scheme .comment { + color: teal; + } + + .schemeresponse { + color: green; + } + + .navigation { + color: red; + text-align: right; + font-size: medium; + font-style: italic; + } + + .disable { + /* color: #e5e5e5; */ + color: gray; + } + + .smallcaps { + font-size: 75%; + } + + .smallprint { + color: gray; + font-size: 75%; + text-align: right; + } + + /* + .smallprint hr { + text-align: left; + width: 40%; + } + */ + + .footnoterule { + text-align: left; + width: 40%; + } + + .colophon { + color: gray; + font-size: 80%; + font-style: italic; + text-align: right; + } + + .colophon a { + color: gray; + } + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference.css b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference.css new file mode 100644 index 0000000..4c5e126 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference.css @@ -0,0 +1,34 @@ +html { margin: 0px; padding: 0px; background-color: #08f; color: #444; font-family: georgia,serif; } +body { margin: 2em 8%; background-color: #fff; padding: 1em; border: 2px ridge #048; } + +a:link, a:visited { text-decoration: none; color: #00f; } +a:hover { color: #f00; text-decoration: underline; } +a:active { color: #f84; } + +h1, h2, h3, h4, h5, h6 { font-family: tahoma,verdana,sans-serif; } + +h2, h3 { font-weight: normal; } + +h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover { text-decoration: none; } + +h1 { font-size: 170%; border: 2px ridge #048; letter-spacing: 2px; color: #000; margin-left: -2em; margin-right: -2em; +background-color: #fff; padding: 2px 1em; background-color: #def; } +h2 { font-size: 140%; color: #222; } +h3 { font-size: 120%; color: #444; } + +h1.title { font-size: 300%; font-family: georgia,serif; font-weight: normal; color: #846; letter-spacing: -1px; +border: none; +padding: none; +background-color: #fff; +border-bottom: 3px double #624; padding-bottom: 2px; margin-left: 8%; margin-right: 8%; } + +.colophon { padding-top: 2em; color: #999; font-size: 90%; font-family: georgia,"times new roman",serif; } +.colophon a:link, .colophon a:visited { color: #755; } +.colophon a:hover { color: #422; text-decoration: underline; } + +.footnote { font-size: 90%; font-style: italic; font-family: georgia,"times new roman",serif; margin: 0px 3em; } +.footnote sup { font-size: 120%; padding: 0px 0.3em; position: relative; top: -0.2em; } + +.small { font-size: 90%; } + +.verbatim { background-color: #eee; padding: 0.2em 1em; border: 1px solid #aaa; } diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference.html new file mode 100644 index 0000000..0275fbd --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/html/reference.html @@ -0,0 +1,1739 @@ + + + + + +DHTML Calendar Widget + + + + + + +
    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    +

    + + + + +

    +

    + + +

    +

    +

    +

    +

    +

    DHTML Calendar Widget

    +

    +
    +Mihai Bazon, <mihai_bazon@yahoo.com>
    +© Dynarch.com 2002-2005, www.dynarch.com

    February 11, 2006

    +

    +

    +calendar version: 1.0 ``It is happening again'' +

    +
    +

    +

    +$Id: reference.html,v 1.1 2010-06-01 04:30:47 tv Exp $ +

    +
    +
    + +
    + +
    + +

    Contents

    +

    +

    +    1  Overview
    +        1.1  How does this thing work?
    +        1.2  Project files
    +        1.3  License
    +

    +

    +    2  Quick startup
    +        2.1  Installing a popup calendar
    +        2.2  Installing a flat calendar
    +        2.3  Calendar.setup in detail
    +

    +

    +    3  Recipes
    +        3.1  Popup calendars
    +            3.1.1  Simple text field with calendar attached to a button
    +            3.1.2  Simple field with calendar attached to an image
    +            3.1.3  Hidden field, plain text triggers
    +            3.1.4  2 Linked fields, no trigger buttons
    +        3.2  Flat calendars
    +        3.3  Highlight special dates
    +        3.4  Select multiple dates
    +

    +

    +    4  The Calendar object overview
    +        4.1  Creating a calendar
    +        4.2  Order does matter ;-)
    +        4.3  Caching the object
    +        4.4  Callback functions
    +

    +

    +    5  The Calendar object API reference
    +        5.1  Calendar constructor
    +        5.2  Useful member variables (properties)
    +        5.3  Public methods
    +            5.3.1  Calendar.create
    +            5.3.2  Calendar.callHandler
    +            5.3.3  Calendar.callCloseHandler
    +            5.3.4  Calendar.hide
    +            5.3.5  Calendar.setDateFormat
    +            5.3.6  Calendar.setTtDateFormat
    +            5.3.7  Calendar.setDisabledHandler
    +            5.3.8  Calendar.setDateStatusHandler
    +            5.3.9  Calendar.show
    +            5.3.10  Calendar.showAt
    +            5.3.11  Calendar.showAtElement
    +            5.3.12  Calendar.setDate
    +            5.3.13  Calendar.setFirstDayOfWeek
    +            5.3.14  Calendar.parseDate
    +            5.3.15  Calendar.setRange
    +

    +

    +    6  Side effects
    +

    +

    +    7  Credits
    +

    +

    +

    +

    +

    + +

    1  Overview

    +

    The DHTML Calendar widget1 +is an (HTML) user interface element that gives end-users a friendly way to +select date and time. It works in a web browser. The first versions only provided +support for popup calendars, while starting with version 0.9 it also supports +``flat'' display. A ``flat'' calendar is a calendar that stays visible in the +page all the time. In this mode it could be very useful for ``blog'' pages and +other pages that require the calendar to be always present.

    +

    +The calendar is compatible with most popular browsers nowadays. While it's +created using web standards and it should generally work with any compliant +browser, the following browsers were found to work: Mozilla/Firefox (the +development platform), Netscape 6.0 or better, all other Gecko-based browsers, +Internet Explorer 5.0 or better for Windows2, Opera 73, Konqueror 3.1.2 and Apple Safari for +MacOSX.

    +

    +You can find the latest info and version at the calendar homepage:

    +

    +

    + +

    +

    + +

    1.1  How does this thing work?

    +

    DHTML is not ``another kind of HTML''. It's merely a naming convention. DHTML +refers to the combination of HTML, CSS, JavaScript and DOM. DOM (Document +Object Model) is a set of interfaces that glues the other three together. In +other words, DOM allows dynamic modification of an HTML page through a program. +JavaScript is our programming language, since that's what browsers like. CSS +is a way to make it look good ;-). So all this soup is generically known as +DHTML.

    +

    +Using DOM calls, the program dynamically creates a <table> element +that contains a calendar for the given date and then inserts it in the document +body. Then it shows this table at a specified position. Usually the position +is related to some element in which the date needs to be displayed/entered, +such as an input field.

    +

    +By assigning a certain CSS class to the table we can control the look of the +calendar through an external CSS file; therefore, in order to change the +colors, backgrounds, rollover effects and other stuff, you can only change a +CSS file -- modification of the program itself is not necessary.

    +

    +

    + +

    1.2  Project files

    +

    Here's a description of the project files, excluding documentation and example +files.

    +

    +

    +

      +

      +
    • the main program file (calendar.js). This defines all the logic +behind the calendar widget.

      +

      +

      +
    • the CSS files (calendar-*.css). Loading one of them is +necessary in order to see the calendar as intended.

      +

      +

      +
    • the language definition files (lang/calendar-*.js). They are +plain JavaScript files that contain all texts that are displayed by the +calendar. Loading one of them is necessary.

      +

      +

      +
    • helper functions for quick setup of the calendar +(calendar-setup.js). You can do fine without it, but starting with +version 0.9.3 this is the recommended way to setup a calendar.

      +

      +

      +

    +

    +

    + +

    1.3  License

    +

    +
    + +© Dynarch.com 2002-2005, +www.dynarch.com +Author: Mihai Bazon +
    +

    +The calendar is released under the +GNU Lesser General Public License.

    +

    +

    + +

    2  Quick startup

    +

    +

    +Installing the calendar used to be quite a task until version 0.9.3. Starting +with 0.9.3 I have included the file calendar-setup.js whose goal is to +assist you to setup a popup or flat calendar in minutes. You are +encouraged to modify this file and not calendar.js if you need +extra customization, but you're on your own.

    +

    +First you have to include the needed scripts and style-sheet. Make sure you do +this in your document's <head> section, also make sure you put the +correct paths to the scripts.

    +

    +

    +
    <style type="text/css">@import url(calendar-win2k-1.css);</style>
    +<script type="text/javascript" src="calendar.js"></script>
    +<script type="text/javascript" src="lang/calendar-en.js"></script>
    +<script type="text/javascript" src="calendar-setup.js"></script>
    +

    +

    +

    + +

    2.1  Installing a popup calendar

    +

    +

    +Now suppose you have the following HTML:

    +

    +

    +
    <form ...>
    +  <input type="text" id="data" name="data" />
    +  <button id="trigger">...</button>
    +</form>
    +

    +

    +You want the button to popup a calendar widget when clicked? Just +insert the following code immediately after the HTML form:

    +

    +

    +
    <script type="text/javascript">
    +  Calendar.setup(
    +    {
    +      inputField  : "data",         // ID of the input field
    +      ifFormat    : "%m %d, %Y",    // the date format
    +      button      : "trigger"       // ID of the button
    +    }
    +  );
    +</script>
    +

    +

    +The Calendar.setup function, defined in calendar-setup.js +takes care of ``patching'' the button to display a calendar when clicked. The +calendar is by default in single-click mode and linked with the given input +field, so that when the end-user selects a date it will update the input field +with the date in the given format and close the calendar. If you are a +long-term user of the calendar you probably remember that for doing this you +needed to write a couple functions and add an ``onclick'' handler for the +button by hand.

    +

    +By looking at the example above we can see that the function +Calendar.setup receives only one parameter: a JavaScript object. +Further, that object can have lots of properties that tell to the setup +function how would we like to have the calendar. For instance, if we would +like a calendar that closes at double-click instead of single-click we would +also include the following: singleClick:false.

    +

    +For a list of all supported parameters please see the section +2.3.

    +

    +

    + +

    2.2  Installing a flat calendar

    +

    +

    +Here's how to configure a flat calendar, using the same Calendar.setup +function. First, you should have an empty element with an ID. This element +will act as a container for the calendar. It can be any block-level element, +such as DIV, TABLE, etc. We will use a DIV in this example.

    +

    +

    +
    <div id="calendar-container"></div>
    +

    +

    +Then there is the JavaScript code that sets up the calendar into the +``calendar-container'' DIV. The code can occur anywhere in HTML +after the DIV element.

    +

    +

    +
    <script type="text/javascript">
    +  function dateChanged(calendar) {
    +    // Beware that this function is called even if the end-user only
    +    // changed the month/year.  In order to determine if a date was
    +    // clicked you can use the dateClicked property of the calendar:
    +    if (calendar.dateClicked) {
    +      // OK, a date was clicked, redirect to /yyyy/mm/dd/index.php
    +      var y = calendar.date.getFullYear();
    +      var m = calendar.date.getMonth();     // integer, 0..11
    +      var d = calendar.date.getDate();      // integer, 1..31
    +      // redirect...
    +      window.location = "/" + y + "/" + m + "/" + d + "/index.php";
    +    }
    +  };
    +
    +  Calendar.setup(
    +    {
    +      flat         : "calendar-container", // ID of the parent element
    +      flatCallback : dateChanged           // our callback function
    +    }
    +  );
    +</script>
    +

    +

    +

    + +

    2.3  Calendar.setup in detail

    +

    +

    +Following there is the complete list of properties interpreted by +Calendar.setup. All of them have default values, so you can pass only those +which you would like to customize. Anyway, you must pass at least one +of inputField, displayArea or button, for a popup +calendar, or flat for a flat calendar. Otherwise you will get a +warning message saying that there's nothing to setup.

    +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    property type description default +
    inputField +string The ID of your input field. +null +
    displayArea +string This is the ID of a <span>, <div>, or any other element that you would like to use to display the current date. This is generally useful only if the input field is hidden, as an area to display the date. +null +
    button +string The ID of the calendar ``trigger''. This is an element (ordinarily a button or an image) that will dispatch a certain event (usually ``click'') to the function that creates and displays the calendar. +null +
    eventName +string The name of the event that will trigger the calendar. The name should be without the ``on'' prefix, such as ``click'' instead of ``onclick''. Virtually all users will want to let this have the default value (``click''). Anyway, it could be useful if, say, you want the calendar to appear when the input field is focused and have no trigger button (in this case use ``focus'' as the event name). +``click'' +
    ifFormat +string The format string that will be used to enter the date in the input field. This format will be honored even if the input field is hidden. +``%Y/%m/%d'' +
    daFormat +string Format of the date displayed in the displayArea (if specified). +``%Y/%m/%d'' +
    singleClick +boolean Wether the calendar is in ``single-click mode'' or ``double-click mode''. If true (the default) the calendar will be created in single-click mode. +true +
    disableFunc +function A function that receives a JS Date object. It should return +true if that date has to be disabled, false otherwise. +DEPRECATED (see below). +null +
    dateStatusFunc +function A function that receives a JS Date object and returns a boolean +or a string. This function allows one to set a certain CSS class to some +date, therefore making it look different. If it returns true then +the date will be disabled. If it returns false nothing special +happens with the given date. If it returns a string then that will be taken +as a CSS class and appended to the date element. If this string is +``disabled'' then the date is also disabled (therefore is like returning +true). For more information please also refer to section +5.3.8. +null +
    firstDay +integer Specifies which day is to be displayed as the first day of +week. Possible values are 0 to 6; 0 means Sunday, 1 means Monday, ..., 6 +means Saturday. The end user can easily change this too, by clicking on the +day name in the calendar header. +0 +
    weekNumbers +boolean If ``true'' then the calendar will display week numbers. +true +
    align +string Alignment of the calendar, relative to the reference element. The +reference element is dynamically chosen like this: if a displayArea is +specified then it will be the reference element. Otherwise, the input field +is the reference element. For the meaning of the alignment characters +please section 5.3.11. +``Bl'' +
    range +array An array having exactly 2 elements, integers. (!) The first [0] element is the minimum year that is available, and the second [1] element is the maximum year that the calendar will allow. +[1900, 2999] +
    flat +string If you want a flat calendar, pass the ID of the parent object in +this property. If not, pass null here (or nothing at all as +null is the default value). +null +
    flatCallback +function You should provide this function if the calendar is flat. It +will be called when the date in the calendar is changed with a reference to +the calendar object. See section 2.2 for an example +of how to setup a flat calendar. +null +
    onSelect +function If you provide a function handler here then you have to manage +the ``click-on-date'' event by yourself. Look in the calendar-setup.js and +take as an example the onSelect handler that you can see there. +null +
    onClose +function This handler will be called when the calendar needs to close. +You don't need to provide one, but if you do it's your responsibility to +hide/destroy the calendar. You're on your own. Check the calendar-setup.js +file for an example. +null +
    onUpdate +function If you supply a function handler here, it will be called right +after the target field is updated with a new date. You can use this to +chain 2 calendars, for instance to setup a default date in the second just +after a date was selected in the first. +null +
    date +date This allows you to setup an initial date where the calendar will be +positioned to. If absent then the calendar will open to the today date. +null +
    showsTime +boolean If this is set to true then the calendar will also +allow time selection. +false +
    timeFormat +string Set this to ``12'' or ``24'' to configure the way that the +calendar will display time. +``24'' +
    electric +boolean Set this to ``false'' if you want the calendar to update the +field only when closed (by default it updates the field at each date change, +even if the calendar is not closed) true +
    position +array Specifies the [x, y] position, relative to page's top-left corner, +where the calendar will be displayed. If not passed then the position will +be computed based on the ``align'' parameter. Defaults to ``null'' (not +used). null +
    cache +boolean Set this to ``true'' if you want to cache the calendar object. +This means that a single calendar object will be used for all fields that +require a popup calendar false +
    showOthers +boolean If set to ``true'' then days belonging to months overlapping +with the currently displayed month will also be displayed in the calendar +(but in a ``faded-out'' color) false + +
    + +

    +

    + +

    3  Recipes

    +

    This section presents some common ways to setup a calendar using the +Calendar.setup function detailed in the previous section.

    +

    +We don't discuss here about loading the JS or CSS code -- so make sure you +add the proper <script> and <style> or <link> elements in your +HTML code. Also, when we present input fields, please note that they should +be embedded in some form in order for data to be actually sent to server; we +don't discuss these things here because they are not related to our +calendar.

    +

    +

    + +

    3.1  Popup calendars

    +

    These samples can be found in the file “simple-1.html†from the +calendar package.

    +

    +

    + +

    3.1.1  Simple text field with calendar attached to a button

    +

    +

    +This piece of code will create a calendar for a simple input field with a +button that will open the calendar when clicked.

    +

    +

    +
    <input type="text" name="date" id="f_date_b"
    +       /><button type="reset" id="f_trigger_b"
    +       >...</button>
    +<script type="text/javascript">
    +    Calendar.setup({
    +        inputField     :    "f_date_b",           //*
    +        ifFormat       :    "%m/%d/%Y %I:%M %p",
    +        showsTime      :    true,
    +        button         :    "f_trigger_b",        //*
    +        step           :    1
    +    });
    +</script>
    +

    +

    +Note that this code does more actually; the only required fields are +those marked with “//*†-- that is, the ID of the input field and the ID of +the button need to be passed to Calendar.setup in order for the +calendar to be properly assigned to this input field. As one can easily +guess from the argument names, the other arguments configure a certain date +format, instruct the calendar to also include a time selector and display +every year in the drop-down boxes (the “step†parameter) -- instead of showing +every other year as the default calendar does.

    +

    +

    + +

    3.1.2  Simple field with calendar attached to an image

    +

    Same as the above, but the element that triggers the calendar is this time +an image, not a button.

    +

    +

    +
    <input type="text" name="date" id="f_date_c" readonly="1" />
    +<img src="img.gif" id="f_trigger_c"
    +     style="cursor: pointer; border: 1px solid red;"
    +     title="Date selector"
    +     onmouseover="this.style.background='red';"
    +     onmouseout="this.style.background=''" />
    +<script type="text/javascript">
    +    Calendar.setup({
    +        inputField     :    "f_date_c",
    +        ifFormat       :    "%B %e, %Y",
    +        button         :    "f_trigger_c",
    +        align          :    "Tl",
    +        singleClick    :    false
    +    });
    +</script>
    +

    +

    +Note that the same 2 parameters are required as in the previous case; the +difference is that the 'button' parameter now gets the ID of the image +instead of the ID of the button. But the event is the same: at 'onclick' on +the element that is passed as 'button', the calendar will be shown.

    +

    +The above code additionally sets an alignment mode -- the parameters are +described in 5.3.11.

    +

    +

    + +

    3.1.3  Hidden field, plain text triggers

    +

    Sometimes, to assure that the date is well formatted, you might want not to +allow the end user to write a date manually. This can easily be achieved +with an input field by setting its readonly attribute, which is +defined by the HTML4 standard; however, here's an even nicer approach: our +calendar widget allows you to use a hidden field as the way to pass data to +server, and a “display area†to show the end user the selected date. The +“display area†can be any HTML element, such as a DIV or a SPAN or +whatever -- we will use a SPAN in our sample.

    +

    +

    +
    <input type="hidden" name="date" id="f_date_d" />
    +
    +<p>Your birthday:
    +   <span style="background-color: #ff8; cursor: default;"
    +         onmouseover="this.style.backgroundColor='#ff0';"
    +         onmouseout="this.style.backgroundColor='#ff8';"
    +         id="show_d"
    +   >Click to open date selector</span>.</p>
    +
    +<script type="text/javascript">
    +    Calendar.setup({
    +        inputField     :    "f_date_d",
    +        ifFormat       :    "%Y/%d/%m",
    +        displayArea    :    "show_d",
    +        daFormat       :    "%A, %B %d, %Y",
    +    });
    +</script>
    +

    +

    +The above code will configure a calendar attached to the hidden field and to +the SPAN having the id=“show_dâ€. When the SPAN element is clicked, the +calendar opens and allows the end user to chose a date. When the date is +chosen, the input field will be updated with the value in the format +“%Y/%d/%mâ€, and the SPAN element will display the date in a +friendlier format (defined by “daFormatâ€).

    +

    +Beware that using this approach will make your page unfunctional in browsers +that do not support JavaScript or our calendar.

    +

    +

    + +

    3.1.4  2 Linked fields, no trigger buttons

    +

    Supposing you want to create 2 fields that hold an interval of exactly one +week. The first is the starting date, and the second is the ending date. +You want the fields to be automatically updated when some date is clicked in +one or the other, in order to keep exactly one week difference between them.

    +

    +

    +
    <input type="text" name="date" id="f_date_a" />
    +<input type="text" name="date" id="f_calcdate" />
    +
    +<script type="text/javascript">
    +    function catcalc(cal) {
    +        var date = cal.date;
    +        var time = date.getTime()
    +        // use the _other_ field
    +        var field = document.getElementById("f_calcdate");
    +        if (field == cal.params.inputField) {
    +            field = document.getElementById("f_date_a");
    +            time -= Date.WEEK; // substract one week
    +        } else {
    +            time += Date.WEEK; // add one week
    +        }
    +        var date2 = new Date(time);
    +        field.value = date2.print("%Y-%m-%d %H:%M");
    +    }
    +    Calendar.setup({
    +        inputField     :    "f_date_a",
    +        ifFormat       :    "%Y-%m-%d %H:%M",
    +        showsTime      :    true,
    +        timeFormat     :    "24",
    +        onUpdate       :    catcalc
    +    });
    +    Calendar.setup({
    +        inputField     :    "f_calcdate",
    +        ifFormat       :    "%Y-%m-%d %H:%M",
    +        showsTime      :    true,
    +        timeFormat     :    "24",
    +        onUpdate       :    catcalc
    +    });
    +</script>
    +

    +

    +The above code will configure 2 input fields with calendars attached, as +usual. The first thing to note is that there's no trigger button -- in such +case, the calendar will popup when one clicks into the input field. Using +the onUpdate parameter, we pass a reference to a function of ours +that will get called after a date was selected. In that function we +determine what field was updated and we compute the date in the other input +field such that it keeps a one week difference between the two. Enjoy! :-)

    +

    +

    + +

    3.2  Flat calendars

    +

    This sample can be found in “simple-2.htmlâ€. It will configure a +flat calendar that is always displayed in the page, in the DIV having the +id=“calendar-containerâ€. When a date is clicked our function hander gets +called (dateChanged) and it will compute an URL to jump to based on +the selected date, then use window.location to visit the new link.

    +

    +

    +
    <div style="float: right; margin-left: 1em; margin-bottom: 1em;"
    +id="calendar-container"></div>
    +
    +<script type="text/javascript">
    +  function dateChanged(calendar) {
    +    // Beware that this function is called even if the end-user only
    +    // changed the month/year.  In order to determine if a date was
    +    // clicked you can use the dateClicked property of the calendar:
    +    if (calendar.dateClicked) {
    +      // OK, a date was clicked, redirect to /yyyy/mm/dd/index.php
    +      var y = calendar.date.getFullYear();
    +      var m = calendar.date.getMonth();     // integer, 0..11
    +      var d = calendar.date.getDate();      // integer, 1..31
    +      // redirect...
    +      window.location = "/" + y + "/" + m + "/" + d + "/index.php";
    +    }
    +  };
    +
    +  Calendar.setup(
    +    {
    +      flat         : "calendar-container", // ID of the parent element
    +      flatCallback : dateChanged           // our callback function
    +    }
    +  );
    +</script>
    +

    +

    +

    + +

    3.3  Highlight special dates

    +

    So you want to display certain dates in a different color, or with bold +font, or whatever, right? Well, no problem -- our calendar can do this as +well. It doesn't matter if it's a flat or popup calendar -- we'll use a flat +one for this sample. The idea, however, is that you need to have the dates +in an array or a JavaScript object -- whatever is suitable for your way of +thinking -- and use it from a function that returns a value, telling the +calendar what kind of date is the passed one.

    +

    +Too much talking, here's the code ;-)

    +

    +

    +
    <!-- this goes into the <head> tag -->
    +<style type="text/css">
    +  .special { background-color: #000; color: #fff; }
    +</style>
    +
    +<!-- and the rest inside the <body> -->
    +<div style="float: right; margin-left: 1em; margin-bottom: 1em;"
    +id="calendar-container"></div>
    +
    +<script type="text/javascript">
    +  var SPECIAL_DAYS = {
    +    0 : [ 13, 24 ],		// special days in January
    +    2 : [ 1, 6, 8, 12, 18 ],	// special days in March
    +    8 : [ 21, 11 ]		// special days in September
    +  };
    +
    +  function dateIsSpecial(year, month, day) {
    +    var m = SPECIAL_DAYS[month];
    +    if (!m) return false;
    +    for (var i in m) if (m[i] == day) return true;
    +    return false;
    +  };
    +
    +  function dateChanged(calendar) {
    +    // Beware that this function is called even if the end-user only
    +    // changed the month/year.  In order to determine if a date was
    +    // clicked you can use the dateClicked property of the calendar:
    +    if (calendar.dateClicked) {
    +      // OK, a date was clicked, redirect to /yyyy/mm/dd/index.php
    +      var y = calendar.date.getFullYear();
    +      var m = calendar.date.getMonth();     // integer, 0..11
    +      var d = calendar.date.getDate();      // integer, 1..31
    +      // redirect...
    +      window.location = "/" + y + "/" + m + "/" + d + "/index.php";
    +    }
    +  };
    +
    +  function ourDateStatusFunc(date, y, m, d) {
    +    if (dateIsSpecial(y, m, d))
    +      return "special";
    +    else
    +      return false; // other dates are enabled
    +      // return true if you want to disable other dates
    +  };
    +
    +  Calendar.setup(
    +    {
    +      flat         : "calendar-container", // ID of the parent element
    +      flatCallback : dateChanged,          // our callback function
    +      dateStatusFunc : ourDateStatusFunc
    +    }
    +  );
    +</script>
    +

    +

    +So the above code creates a normal flat calendar, like in the previous +sample. We hook into it with the function “ourDateStatusFuncâ€, +which receives a date object as the first argument, and also the year, +month, date as the next 3 arguments (normally, you can extract year, month, +date from the first parameter too, but we pass them separately for +convenience, as it's very likely that they are going to be used in this +function).

    +

    +So, this function receives a date. It can return false if you want +no special action to be taken on that date, true if that date +should be disabled (unselectable), or a string if you want to assign a +special CSS class to that date. We return “special†for the dates that we +want to highlight -- and note that we defined a “special†look for them in +the CSS section.

    +

    +I used a simple approach here to define what dates are special. There's a +JavaScript object (the SPECIAL_DAYS global variable) which holds an array +of dates for each month. Month numbers start at zero (January). Months +that don't contain special dates can be absent from this object. Note that +the way to implement this is completely separated from the calendar +code -- therefore, feel free to use your imagination if you have better +ideas. :-)

    +

    +

    + +

    3.4  Select multiple dates

    +

    Starting version 1.0, the calendar is able to handle multiple dates +selection. You just need to pass the “multiple†parameter to +Calendar.setup and add some special code that interprets the +selection once the calendar is closed.

    +

    +

    +
    <a id="trigger" href="#">[open calendar...]</a>
    +<div id="output"></div>
    +<script type="text/javascript">//<![CDATA[
    +    // the default multiple dates selected,
    +    // first time the calendar is displayed
    +    var MA = [];
    +
    +    function closed(cal) {
    +
    +      // here we'll write the output; this is only for example.  You
    +      // will normally fill an input field or something with the dates.
    +      var el = document.getElementById("output");
    +
    +      // reset initial content.
    +      el.innerHTML = "";
    +
    +      // Reset the "MA", in case one triggers the calendar again.
    +      // CAREFUL!  You don't want to do "MA = [];".  We need to modify
    +      // the value of the current array, instead of creating a new one.
    +      // Calendar.setup is called only once! :-)  So be careful.
    +      MA.length = 0;
    +
    +      // walk the calendar's multiple dates selection hash
    +      for (var i in cal.multiple) {
    +        var d = cal.multiple[i];
    +        // sometimes the date is not actually selected,
    +        // so let's check
    +        if (d) {
    +          // OK, selected.  Fill an input field or something.
    +          el.innerHTML += d.print("%A, %Y %B %d") + "<br />";
    +          // and push it in the "MA", in case one triggers the calendar again.
    +          MA[MA.length] = d;
    +        }
    +      }
    +      cal.hide();
    +      return true;
    +    };
    +
    +    Calendar.setup({
    +      align      : "BR",
    +      showOthers : true,
    +      multiple   : MA, // pass the initial or computed array of multiple dates
    +      onClose    : closed,
    +      button     : "trigger"
    +    });
    +//]]></script>
    +

    +

    +The above code creates a popup calendar and passes to it an array of dates, +which is initially empty, in the “multiple†argument. When the calendar is +closed it will call our “closed†function handler; in this handler +we determine what dates were actually selected, inspecting the +“cal.multiple†property, we display them in a DIV element right +next to the <a> element that opens the calendar, and we reinitialize the +global array of selected dates (which will be used if the end user opens the +calendar again). I guess the code speaks for itself, right? :-)

    +

    +

    + +

    4  The Calendar object overview

    +

    +

    +Basically you should be able to setup the calendar with the function presented +in the previous section. However, if for some reason Calendar.setup +doesn't provide all the functionality that you need and you want to tweak into +the process of creating and configuring the calendar ``by hand'', then this +section is the way to go.

    +

    +The file calendar.js implements the functionality of the calendar. +All (well, almost all) functions and variables are embedded in the JavaScript +object ``Calendar''.

    +

    +You can instantiate a Calendar object by calling the constructor, like +this: var cal = new Calendar(...). We will discuss the parameters +later. After creating the object, the variable cal will contain a +reference to it. You can use this reference to access further options of the +calendar, for instance:

    +

    +

    +
    cal.weekNumbers = false; // do not display week numbers
    +cal.showsTime = true;    // include a time selector
    +cal.setDateFormat("%Y.%m.%d %H:%M"); // set this format: 2003.12.31 23:59
    +cal.setDisabledHandler(function(date, year, month, day) {
    +  // verify date and return true if it has to be disabled
    +  // ``date'' is a JS Date object, but if you only need the
    +  // year, month and/or day you can get them separately as
    +  // next 3 parameters, as you can see in the declaration
    +  if (year == 2004) {
    +    // disable all dates from 2004
    +    return true;
    +  }
    +  return false;
    +});
    +

    +

    +etc. Prior to version +0.9.3 this was the only way to configure it. The Calendar.setup +function, documented in section 2, basically does the same +things (actually more) in order to setup the calendar, based on the parameters +that you provided.

    +

    +

    + +

    4.1  Creating a calendar

    +

    The calendar is created by following some steps (even the function +Calendar.setup, described in section 2, does the +same). While you can skip optional (marked ``opt'') steps if you're happy with +the defaults, please respect the order below.

    +

    +

    +

      +

      +
    1. Instantiate a Calendar object. Details about this in +section 5.1.

      +

      +

      +
    2. opt   Set the weekNumbers property to false if you don't want +the calendar to display week numbers.

      +

      +

      +
    3. opt   Set the showsTime property to true if you +want the calendar to also provide a time selector.

      +

      +

      +
    4. opt   Set the time24 property to false if you want +the time selector to be in 12-hour format. Default is 24-hour format. This +property only has effect if you also set showsTime to +true.

      +

      +

      +
    5. opt   Set the range of years available for selection (see section +5.3.15). The default range is [1970..2050].

      +

      +

      +
    6. opt   Set the getDateStatus property. You should pass +here a function that receives a JavaScript Date object and returns +true if the given date should be disabled, false otherwise (details in +section 5.3.7).

      +

      +

      +
    7. opt   Set a date format. Your handler function, passed to the +calendar constructor, will be called when a date is selected with a reference +to the calendar and a date string in this format.

      +

      +

      +
    8. Create the HTML elements related to the calendar. This step +practically puts the calendar in your HTML page. You simply call +Calendar.create(). You can give an optional parameter if you wanna +create a flat calendar (details in section 5.3.1).

      +

      +

      +
    9. opt   Initialize the calendar to a certain date, for instance from +the input field.

      +

      +

      +
    10. Show the calendar (details in section 5.3.9).

      +

      +

      +

    +

    +

    + +

    4.2  Order does matter ;-)

    +

    As you could see in the previous section, there are more steps to be followed +in order to setup the calendar. This happens because there are two different +things that need to be accomplished: first there is the JavaScript object, that +is created with new Calendar(...). Secondly there are the HTML +elements that actually lets you see and manipulate the calendar.

    +

    +

    +[ Those that did UI4 programming, no matter in what +language and on what platform, may be familiar with this concept. First there +is the object in memory that lets you manipulate the UI element, and secondly +there is the UI element (known as ``control'', ``window'', ``widget'', etc.), +also in memory but you don't usually access it directly. ] +

    +By instantiating the calendar we create the JavaScript object. It lets us +configure some properties and it also knows how to create the UI element (the +HTML elements actually) that will eventually be what the end-user sees on +screen. Creation of the HTML element is accomplished by the function +Calendar.create. It knows how to create popup or flat calendars. +This function is described in section 5.3.1.

    +

    +Some properties need to be set prior to creating the HTML elements, because +otherwise they wouldn't have any effect. Such a property is +weekNumbers -- it has the default value ``true'', and if you don't +want the calendar to display the week numbers you have to set it to false. If, +however, you do that after calling Calendar.create the calendar +would still display the week numbers, because the HTML elements are already +created (including the <td>-s in the <table> element that +should contain the week numbers). For this reason the order of the steps above +is important.

    +

    +Another example is when you want to show the calendar. The ``create'' function +does create the HTML elements, but they are initially hidden (have the style +``display: none'') unless the calendar is a flat calendar that should be always +visible in the page. Obviously, the Calendar.show function should be +called after calling Calendar.create.

    +

    +

    + +

    4.3  Caching the object

    +

    Suppose the end-user has popped up a calendar and selects a date. The calendar +then closes. What really happens now?

    +

    +There are two approaches. The first (used in very old versions of the +calendar) was to drop completely the Calendar object and when the end-user pops +up the calendar again to create another one. This approach is bad for more +reasons:

    +

    +

    +

      +

      +
    • creating the JavaScript object and HTML elements is time-consuming

      +

      +

      +
    • we may loose some end-user preferences (i.e. he might prefer to have +Monday for the first day of week and probably already clicked it the first time +when the calendar was opened, but now he has to do it again)

      +

      +

      +

    +

    +The second approach, implemented by the Calendar.setup function, is to +cache the JavaScript object. It does this by checking the global variable +window.calendar and if it is not null it assumes it is the created +Calendar object. When the end-user closes the calendar, our code will only +call ``hide'' on it, therefore keeping the JavaScript object and the +HTML elements in place.

    +

    +CAVEAT:     Since time selection support was introduced, this +``object caching'' mechanism has the following drawback: if you once created +the calendar with the time selection support, then other items that may not +require this functionality will still get a calendar with the time selection +support enabled. And reciprocal. ;-) Hopefully this will be corrected in a +later version, but for now it doesn't seem such a big problem.

    +

    +

    + +

    4.4  Callback functions

    +

    You might rightfully wonder how is the calendar related to the input field? +Who tells it that it has to update that input field when a date is +selected, or that it has to jump to that URL when a date is clicked in +flat mode?

    +

    +All this magic is done through callback functions. The calendar doesn't know +anything about the existence of an input field, nor does it know where to +redirect the browser when a date is clicked in flat mode. It just calls your +callback when a particular event is happening, and you're responsible to handle +it from there. For a general purpose library I think this is the best model of +making a truly reusable thing.

    +

    +The calendar supports the following user callbacks:

    +

    +

    +

      +

      +
    • onSelect   -- this gets called when the end-user changes the date in the +calendar. Documented in section IGNORE.

      +

      +

      +
    • onClose   -- this gets called when the calendar should close. It's +user's responsibility to close the calendar. Details in section +IGNORE.

      +

      +

      +
    • getDateStatus   -- this function gets called for any day in a month, +just before displaying the month. It is called with a JavaScript Date +object and should return true if that date should be disabled, false +if it's an ordinary date and no action should be taken, or it can return a +string in which case the returned value will be appended to the element's CSS +class (this way it provides a powerful way to make some dates ``special'', +i.e. highlight them differently). Details in section +5.3.8.

      +

      +

      +

    +

    +

    + +

    5  The Calendar object API reference

    +

    +

    +

    + +

    5.1  Calendar constructor

    +

    +

    +Synopsis:

    +

    +

    +
    var calendar = Calendar(firstDayOfWeek, date, onSelect, onClose);
    +

    +

    +Parameters are as follows:

    +

    +

    +

      +

      +
    • firstDayOfWeek   -- specifies which day is to be displayed as the first +day of week. Possible values are 0 to 6; 0 means Sunday, 1 means Monday, +..., 6 means Saturday.

      +

      +

      +
    • date   -- a JavaScript Date object or null. If null +is passed then the calendar will default to today date. Otherwise it will +initialize on the given date.

      +

      +

      +
    • onSelect   -- your callback for the ``onChange'' event. See above.

      +

      +

      +
    • onClose   -- your callback for the ``onClose'' event. See above.

      +

      +

      +

    +

    +

    + +

    The onSelect event

    +

    +

    +Here is a typical implementation of this function:

    +

    +

    +
    function onSelect(calendar, date) {
    +  var input_field = document.getElementById("date");
    +  input_field.value = date;
    +};
    +

    +

    +date is in the format selected with calendar.setDateFormat +(see section 5.3.5). This code simply updates the +input field. If you want the calendar to be in single-click mode then you +should also close the calendar after you updated the input field, so we come to +the following version:

    +

    +

    +
    function onSelect(calendar, date) {
    +  var input_field = document.getElementById("date");
    +  input_field.value = date;
    +  if (calendar.dateClicked) {
    +    calendar.callCloseHandler(); // this calls "onClose" (see above)
    +  }
    +};
    +

    +

    +Note that we checked the member variable dateClicked and +only hide the calendar if it's true. If this variable is false it +means that no date was actually selected, but the user only changed the +month/year using the navigation buttons or the menus. We don't want to hide +the calendar in that case.

    +

    +

    + +

    The onClose event

    +

    +

    +This event is triggered when the calendar should close. It should hide or +destroy the calendar object -- the calendar itself just triggers the event, but +it won't close itself.

    +

    +A typical implementation of this function is the following:

    +

    +

    +
    function onClose(calendar) {
    +  calendar.hide();
    +  // or calendar.destroy();
    +};
    +

    +

    +

    + +

    5.2  Useful member variables (properties)

    +

    +

    +After creating the Calendar object you can access the following properties:

    +

    +

    +

      +

      +
    • date -- is a JavaScript Date object. It will always +reflect the date shown in the calendar (yes, even if the calendar is hidden).

      +

      +

      +
    • isPopup -- if this is true then the current Calendar object is +a popup calendar. Otherwise (false) we have a flat calendar. This variable is +set from Calendar.create and has no meaning before this function was +called.

      +

      +

      +
    • dateClicked -- particularly useful in the onSelect +handler, this variable tells us if a date was really clicked. That's because +the onSelect handler is called even if the end-user only changed the +month/year but did not select a date. We don't want to close the calendar in +that case.

      +

      +

      +
    • weekNumbers -- if true (default) then the calendar +displays week numbers. If you don't want week numbers you have to set this +variable to false before calling Calendar.create.

      +

      +

      +
    • showsTime - if you set this to true (it is +false by default) then the calendar will also include a time selector.

      +

      +

      +
    • time24 - if you set this to false then the time +selector will be in 12-hour format. It is in 24-hour format by default.

      +

      +

      +
    • firstDayOfWeek -- specifies the first day of week (0 to 6, pass +0 for Sunday, 1 for Monday, ..., 6 for Saturday). This variable is set from +constructor, but you still have a chance to modify it before calling +Calendar.create.

      +

      +

      +

    +

    +There are lots of other member variables, but one should access them only +through member functions so I won't document them here.

    +

    +

    + +

    5.3  Public methods

    +

    + +

    5.3.1  Calendar.create

    +

    +

    +This function creates the afferent HTML elements that are needed to display the +calendar. You should call it after setting the calendar properties. Synopsis: +

    +
    calendar.create(); // creates a popup calendar
    +  // -- or --
    +calendar.create(document.getElementById(parent_id)); // makes a flat calendar
    +

    +

    +It can create a popup calendar or a flat calendar. If the ``parent'' argument +is present (it should be a reference -- not ID -- to an HTML element) then +a flat calendar is created and it is inserted in the given element.

    +

    +At any moment, given a reference to a calendar object, we can inspect if it's a +popup or a flat calendar by checking the boolean member variable +isPopup:

    +

    +

    +
    if (calendar.isPopup) {
    +   // this is a popup calendar
    +} else {
    +   // this is a flat calendar
    +}
    +

    +

    +

    + +

    5.3.2  Calendar.callHandler

    +

    +

    +This function calls the first user callback (the +onSelect handler) with the required parameters.

    +

    +

    + +

    5.3.3  Calendar.callCloseHandler

    +

    +

    +This function calls the second user callback (the +onClose handler). It's useful when you want to have a +``single-click'' calendar -- just call this in your onSelect handler, +if a date was clicked.

    +

    +

    + +

    5.3.4  Calendar.hide

    +

    +

    +Call this function to hide the calendar. The calendar object and HTML elements +will not be destroyed, thus you can later call one of the show +functions on the same element.

    +

    +

    + +

    5.3.5  Calendar.setDateFormat

    +

    +

    +This function configures the format in which the calendar reports the date to +your ``onSelect'' handler. Call it like this:

    +

    +

    +
    calendar.setDateFormat("%y/%m/%d");
    +

    +

    +As you can see, it receives only one parameter, the required format. The magic +characters are the following:

    +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    %a abbreviated weekday name
    %A full weekday name
    %b abbreviated month name
    %B full month name
    %C century number
    %d the day of the month ( 00 .. 31 )
    %e the day of the month ( 0 .. 31 )
    %H hour ( 00 .. 23 )
    %I hour ( 01 .. 12 )
    %j day of the year ( 000 .. 366 )
    %k hour ( 0 .. 23 )
    %l hour ( 1 .. 12 )
    %m month ( 01 .. 12 )
    %M minute ( 00 .. 59 )
    %n a newline character
    %p ``PM'' or ``AM''
    %P ``pm'' or ``am''
    %S second ( 00 .. 59 )
    %s number of seconds since Epoch (since Jan 01 1970 00:00:00 UTC)
    %t a tab character
    %U, %W, %V the week number
    %u the day of the week ( 1 .. 7, 1 = MON )
    %w the day of the week ( 0 .. 6, 0 = SUN )
    %y year without the century ( 00 .. 99 )
    %Y year including the century ( ex. 1979 )
    %% a literal % character +

    +There are more algorithms for computing the week number. All +three specifiers currently implement the same one, as defined by ISO 8601: +``the week 01 is the week that has the Thursday in the current year, which is +equivalent to the week that contains the fourth day of January. Weeks start on +Monday.''

    +

    +

    + +

    5.3.6  Calendar.setTtDateFormat

    +

    +

    +Has the same prototype as Calendar.setDateFormat, but refers to the +format of the date displayed in the ``status bar'' when the mouse is over some +date.

    +

    +

    + +

    5.3.7  Calendar.setDisabledHandler

    +

    +

    +This function allows you to specify a callback function that checks if a +certain date must be disabled by the calendar. You are responsible to write +the callback function. Synopsis:

    +

    +

    +
    function disallowDate(date) {
    +  // date is a JS Date object
    +  if (  date.getFullYear() == 2003 &&
    +        date.getMonth()    == 6 /* July, it's zero-based */ &&
    +        date.getDate()     == 5  ) {
    +    return true; // disable July 5 2003
    +  }
    +  return false; // enable other dates
    +};
    +
    +calendar.setDisabledHandler(disallowDate);
    +

    +

    +If you change this function in ``real-time'', meaning, without creating a new +calendar, then you have to call calendar.refresh() to make it +redisplay the month and take into account the new disabledHandler. +Calendar.setup does this, so you have no such trouble with it.

    +

    +Note that disallowDate should be very fast, as it is called for each +date in the month. Thus, it gets called, say, 30 times before displaying the +calendar, and 30 times when the month is changed. Tests I've done so far show +that it's still good, but in the future I might switch it to a different design +(for instance, to call it once per month and to return an array of dates that +must be disabled).

    +

    +This function should be considered deprecated in the favor of +Calendar.setDateStatusHandler, described below.

    +

    +

    + +

    5.3.8  Calendar.setDateStatusHandler

    +

    +

    +This function obsoletes Calendar.setDisabledHandler. You call it with +a function parameter, but this function can return a boolean +or a string. If the return value is a boolean (true or +false) then it behaves just like setDisabledHandler, +therefore disabling the date if the return value is true.

    +

    +If the returned value is a string then the given date will gain an additional +CSS class, namely the returned value. You can use this to highlight some dates +in some way. Note that you are responsible for defining the CSS class that you +return. If you return the string ``disabled'' then that date will be disabled, +just as if you returned true.

    +

    +Here is a simple scenario that shows what you can do with this function. The +following should be present in some of your styles, or in the document head in +a STYLE tag (but put it after the place where the calendar styles were +loaded):

    +

    +

    +
    .special { background-color: #000; color: #fff; }
    +

    +

    +And you would use the following code before calling Calendar.create():

    +

    +

    +
    // this table holds your special days, so that we can automatize
    +// things a bit:
    +var SPECIAL_DAYS = {
    +    0 : [ 13, 24 ],             // special days in January
    +    2 : [ 1, 6, 8, 12, 18 ],    // special days in March
    +    8 : [ 21, 11 ],             // special days in September
    +   11 : [ 25, 28 ]              // special days in December
    +};
    +
    +// this function returns true if the passed date is special
    +function dateIsSpecial(year, month, day) {
    +    var m = SPECIAL_DAYS[month];
    +    if (!m) return false;
    +    for (var i in m) if (m[i] == day) return true;
    +    return false;
    +}
    +
    +// this is the actual date status handler.  Note that it receives the
    +// date object as well as separate values of year, month and date, for
    +// your confort.
    +function dateStatusHandler(date, y, m, d) {
    +    if (dateIsSpecial(y, m, d)) return ``special'';
    +    else return false;
    +    // return true above if you want to disable other dates
    +}
    +
    +// configure it to the calendar
    +calendar.setDateStatusHandler(dateStatusHandler);
    +

    +

    +The above code adds the ``special'' class name to some dates that are defined +in the SPECIAL_DAYS table. Other dates will simply be displayed as default, +enabled.

    +

    +

    + +

    5.3.9  Calendar.show

    +

    +

    +Call this function do show the calendar. It basically sets the CSS ``display'' +property to ``block''. It doesn't modify the calendar position.

    +

    +This function only makes sense when the calendar is in popup mode.

    +

    +

    + +

    5.3.10  Calendar.showAt

    +

    +

    +Call this to show the calendar at a certain (x, y) position. Prototype:

    +

    +

    +
    calendar.showAt(x, y);
    +

    +

    +The parameters are absolute coordinates relative to the top left +corner of the page, thus they are page coordinates not screen +coordinates.

    +

    +After setting the given coordinates it calls Calendar.show. This function only +makes sense when the calendar is in popup mode.

    +

    +

    + +

    5.3.11  Calendar.showAtElement

    +

    +

    +This function is useful if you want to display the calendar near some element. +You call it like this:

    +

    +

    +
    calendar.showAtElement(element, align);
    +

    +

    +where element is a reference to your element (for instance it can be the input +field that displays the date) and align is an optional parameter, of type string, +containing one or two characters. For instance, if you pass "Br" as +align, the calendar will appear below the element and with its right +margin continuing the element's right margin.

    +

    +As stated above, align may contain one or two characters. The first character +dictates the vertical alignment, relative to the element, and the second +character dictates the horizontal alignment. If the second character is +missing it will be assumed "l" (the left margin of the calendar will +be at the same horizontal position as the left margin of the element).

    +

    +The characters given for the align parameters are case sensitive. This +function only makes sense when the calendar is in popup mode. After computing +the position it uses Calendar.showAt to display the calendar there.

    +

    +

    + +

    Vertical alignment

    +

    The first character in ``align'' can take one of the following values:

    +

    +

    +

      +

      +
    • T -- completely above the reference element (bottom margin of +the calendar aligned to the top margin of the element).

      +

      +

      +
    • t -- above the element but may overlap it (bottom margin of the calendar aligned to +the bottom margin of the element).

      +

      +

      +
    • c -- the calendar displays vertically centered to the reference +element. It might overlap it (that depends on the horizontal alignment).

      +

      +

      +
    • b -- below the element but may overlap it (top margin of the calendar aligned to +the top margin of the element).

      +

      +

      +
    • B -- completely below the element (top margin of the calendar +aligned to the bottom margin of the element).

      +

      +

      +

    +

    +

    + +

    Horizontal alignment

    +

    The second character in ``align'' can take one of the following values:

    +

    +

    +

      +

      +
    • L -- completely to the left of the reference element (right +margin of the calendar aligned to the left margin of the element).

      +

      +

      +
    • l -- to the left of the element but may overlap it (left margin +of the calendar aligned to the left margin of the element).

      +

      +

      +
    • c -- horizontally centered to the element. Might overlap it, +depending on the vertical alignment.

      +

      +

      +
    • r -- to the right of the element but may overlap it (right +margin of the calendar aligned to the right margin of the element).

      +

      +

      +
    • R -- completely to the right of the element (left margin of the +calendar aligned to the right margin of the element).

      +

      +

      +

    +

    +

    + +

    Default values

    +

    If the ``align'' parameter is missing the calendar will choose +``Br''.

    +

    +

    + +

    5.3.12  Calendar.setDate

    +

    +

    +Receives a JavaScript Date object. Sets the given date in the +calendar. If the calendar is visible the new date is displayed immediately.

    +

    +

    +
    calendar.setDate(new Date()); // go today
    +

    +

    +

    + +

    5.3.13  Calendar.setFirstDayOfWeek

    +

    +

    +Changes the first day of week. The parameter has to be a numeric value ranging +from 0 to 6. Pass 0 for Sunday, 1 for Monday, ..., 6 for Saturday.

    +

    +

    +
    calendar.setFirstDayOfWeek(5); // start weeks on Friday
    +

    +

    +

    + +

    5.3.14  Calendar.parseDate

    +

    +

    +Use this function to parse a date given as string and to move the calendar to +that date.

    +

    +The algorithm tries to parse the date according to the format that was +previously set with Calendar.setDateFormat; if that fails, it still +tries to get some valid date out of it (it doesn't read your thoughts, though).

    +

    +

    +
    calendar.parseDate("2003/07/06");
    +

    +

    +

    + +

    5.3.15  Calendar.setRange

    +

    +

    +Sets the range of years that are allowed in the calendar. Synopsis:

    +

    +

    +
    calendar.setRange(1970, 2050);
    +

    +

    +

    + +

    6  Side effects

    +

    The calendar code was intentionally embedded in an object to make it have as +less as possible side effects. However, there are some -- not harmful, after +all. Here is a list of side effects; you can count they already happened after +calendar.js was loaded.

    +

    +

    +

      +

      +
    1. The global variable window.calendar will be set to null. This +variable is used by the calendar code, especially when doing drag & drop for +moving the calendar. In the future I might get rid of it, but for now it +didn't harm anyone.

      +

      +

      +
    2. The JavaScript Date object is modified. We add some properties +and functions that are very useful to our calendar. It made more sense to add +them directly to the Date object than to the calendar itself. +Complete list:

      +

      +

      +

        +

        +
      1. Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31); +

        +
      2. Date.SECOND = 1000 /* milliseconds */; +

        +
      3. Date.MINUTE = 60 * Date.SECOND; +

        +
      4. Date.HOUR = 60 * Date.MINUTE; +

        +
      5. Date.DAY = 24 * Date.HOUR; +

        +
      6. Date.WEEK = 7 * Date.DAY;

        +

        +

        +
      7. Date.prototype.getMonthDays(month) -- returns the number of days +of the given month, or of the current date object if no month was given.

        +

        +

        +
      8. Date.prototype.getWeekNumber() -- returns the week number of the +date in the current object.

        +

        +

        +
      9. Date.prototype.equalsTo(other_date) -- compare the current date +object with other_date and returns true if the dates are +equal. It ignores time.

        +

        +

        +
      10. Date.prototype.print(format) -- returns a string with the +current date object represented in the given format. It implements the format +specified in section 5.3.5.

        +

        +

        +

      +

      +

      +

    +

    +

    + +

    7  Credits

    +

    The following people either sponsored, donated money to the project or bought +commercial licenses (listed in reverse chronological order). Your name could +be here too! If you wish to sponsor the project (for instance request a +feature and pay me for implementing it) or donate some money please +please contact me at mihai_bazon@yahoo.com.

    +

    +

    +

    +

    +

    +
    + +Thank you!
    + -- mihai_bazon@yahoo.com +
    +

    +

    +

    +

    1 +by the term ``widget'' I understand a single element of user interface. +But that's in Linux world. For those that did lots of Windows +programming the term ``control'' might be more familiar +

    +

    2 people report that the calendar does +not work with IE5/Mac. However, this browser was discontinued and we +believe that supporting it doesn't worth the efforts, given the fact that +it has the worst, buggiest implementation for DOM I've ever seen.

    +

    3 under Opera 7 the calendar still lacks some functionality, such as +keyboard navigation; also Opera doesn't seem to allow disabling text +selection when one drags the mouse on the page; despite all that, the +calendar is still highly functional under Opera 7 and looks as good as +in other supported browsers.

    +

    4 user interface

    +
    +

    +
    Last modified: Saturday, March 5th, 2005 1:37:14pm
    +
    + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/reference.pdf b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/doc/reference.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1e96fa0a18871656d59abb7579f37cf2c176736b GIT binary patch literal 265125 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Ξ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

    &>*qd&o%$*$t9@8H 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 literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/img.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/img.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd2c4a521774c70473f11c88642543751a812d6f GIT binary patch literal 223 zcmY+8F$w}P5Jmsu1X2mY7Pj^lfoWE3A`H5AX$H3SCIQzYcmogOL2?Q^tGEd(=x;uM z{$plN=VQ0Kv{>RraL#2QrIhnCSD|Y2rlx_xwxq&h@fcKZs#?v!0&(grG%|C?d}R)U zD^^qZLqwz(8AZb2F@n7Ht1*~)C_QN;j~*1;!-N#FcEOM(A3fUjg#2vzUPlb`OU3Tk Fe*i=yIHv#r literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/index.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/index.html new file mode 100644 index 0000000..1b02750 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/index.html @@ -0,0 +1,333 @@ + + + + + + + +The Coolest DHTML Calendar - Online Demo + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    + +

    +

    +Theme:
    +Aqua +| +Tiger +| +winter +| +blue +| +summer +| +green +
    +win2k-1 +| +win2k-2 +| +win2k-cold-1 +| +win2k-cold-2 +
    +system + +
    +Release notes. +
    +Set it up in minutes: + popup calendar, + flat calendar. +Other samples: + special days, + day info, + multiple dates selection +
    +Documentation: + HTML, + PDF. +
    +

    + +
    + +
    + + + + + + + + +
    + +
    +
    +Popup examples +
    + +
    + +Date #1: %Y-%m-%d [%W] %H:%M -- single +click
    + +Date #2: %a, %b %e, %Y [%I:%M %p] +-- double click + +

    + + +this select should hide when the calendar is above it. +

    + +Date #3: %d/%m/%Y +-- single click +
    + +Date #4: %A, %B %e, %Y -- +double click + +
    + +

    This is release 1.0. Works on MSIE/Win 5.0 or better (really), +Opera 7+, Mozilla, Firefox, Netscape 6.x, 7.0 and all other Gecko-s, +Konqueror and Safari.

    + +

    Keyboard navigation

    + +

    Starting with version 0.9.2, you can also use the keyboard to select +dates (only for popup calendars; does not work with Opera +7 or Konqueror/Safari). The following keys are available:

    + +
      + +
    • , , + , -- select date
    • +
    • CTRL + , + -- select month
    • +
    • CTRL + , + -- select year
    • +
    • SPACE -- go to today date
    • +
    • ENTER -- accept the currently selected date
    • +
    • ESC -- cancel selection
    • + +
    + +
    + +
    + Flat calendar +
    + +

    A non-popup version will appear below as soon + as the page is loaded. Note that it doesn't show the week number.

    + + +
    +
     
    + +

    + The example above uses the setDisabledHandler() member function + to setup a handler that would only enable days withing a range of 10 days, + forward or backward, from the current date. +

    + + + +
    + +
    dynarch.com 2002-2005
    +Author: Mihai +Bazon
    Distributed under the GNU LGPL.
    + +

    If you use this script on a public page we +would love it if you would let us +know.

    + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-af.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-af.js new file mode 100644 index 0000000..aeda581 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-af.js @@ -0,0 +1,39 @@ +// ** I18N Afrikaans +Calendar._DN = new Array +("Sondag", + "Maandag", + "Dinsdag", + "Woensdag", + "Donderdag", + "Vrydag", + "Saterdag", + "Sondag"); +Calendar._MN = new Array +("Januarie", + "Februarie", + "Maart", + "April", + "Mei", + "Junie", + "Julie", + "Augustus", + "September", + "Oktober", + "November", + "Desember"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["TOGGLE"] = "Verander eerste dag van die week"; +Calendar._TT["PREV_YEAR"] = "Vorige jaar (hou vir keuselys)"; +Calendar._TT["PREV_MONTH"] = "Vorige maand (hou vir keuselys)"; +Calendar._TT["GO_TODAY"] = "Gaan na vandag"; +Calendar._TT["NEXT_MONTH"] = "Volgende maand (hou vir keuselys)"; +Calendar._TT["NEXT_YEAR"] = "Volgende jaar (hou vir keuselys)"; +Calendar._TT["SEL_DATE"] = "Kies datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Sleep om te skuif"; +Calendar._TT["PART_TODAY"] = " (vandag)"; +Calendar._TT["MON_FIRST"] = "Vertoon Maandag eerste"; +Calendar._TT["SUN_FIRST"] = "Display Sunday first"; +Calendar._TT["CLOSE"] = "Close"; +Calendar._TT["TODAY"] = "Today"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-al.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-al.js new file mode 100644 index 0000000..4f701cf --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-al.js @@ -0,0 +1,101 @@ +// Calendar ALBANIAN language +//author Rigels Gordani rige@hotmail.com + +// ditet +Calendar._DN = new Array +("E Diele", +"E Hene", +"E Marte", +"E Merkure", +"E Enjte", +"E Premte", +"E Shtune", +"E Diele"); + +//ditet shkurt +Calendar._SDN = new Array +("Die", +"Hen", +"Mar", +"Mer", +"Enj", +"Pre", +"Sht", +"Die"); + +// muajt +Calendar._MN = new Array +("Janar", +"Shkurt", +"Mars", +"Prill", +"Maj", +"Qeshor", +"Korrik", +"Gusht", +"Shtator", +"Tetor", +"Nentor", +"Dhjetor"); + +// muajte shkurt +Calendar._SMN = new Array +("Jan", +"Shk", +"Mar", +"Pri", +"Maj", +"Qes", +"Kor", +"Gus", +"Sht", +"Tet", +"Nen", +"Dhj"); + +// ndihmesa +Calendar._TT = {}; +Calendar._TT["INFO"] = "Per kalendarin"; + +Calendar._TT["ABOUT"] = +"Zgjedhes i ores/dates ne DHTML \n" + +"\n\n" +"Zgjedhja e Dates:\n" + +"- Perdor butonat \xab, \xbb per te zgjedhur vitin\n" + +"- Perdor butonat" + String.fromCharCode(0x2039) + ", " + +String.fromCharCode(0x203a) + +" per te zgjedhur muajin\n" + +"- Mbani shtypur butonin e mousit per nje zgjedje me te shpejte."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Zgjedhja e kohes:\n" + +"- Kliko tek ndonje nga pjeset e ores per ta rritur ate\n" + +"- ose kliko me Shift per ta zvogeluar ate\n" + +"- ose cliko dhe terhiq per zgjedhje me te shpejte."; + +Calendar._TT["PREV_YEAR"] = "Viti i shkuar (prit per menune)"; +Calendar._TT["PREV_MONTH"] = "Muaji i shkuar (prit per menune)"; +Calendar._TT["GO_TODAY"] = "Sot"; +Calendar._TT["NEXT_MONTH"] = "Muaji i ardhshem (prit per menune)"; +Calendar._TT["NEXT_YEAR"] = "Viti i ardhshem (prit per menune)"; +Calendar._TT["SEL_DATE"] = "Zgjidh daten"; +Calendar._TT["DRAG_TO_MOVE"] = "Terhiqe per te levizur"; +Calendar._TT["PART_TODAY"] = " (sot)"; + +// "%s" eshte dita e pare e javes +// %s do te zevendesohet me emrin e dite +Calendar._TT["DAY_FIRST"] = "Trego te %s te paren"; + + +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Mbyll"; +Calendar._TT["TODAY"] = "Sot"; +Calendar._TT["TIME_PART"] = "Kliko me (Shift-)ose terhiqe per te ndryshuar +vleren"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "Java"; +Calendar._TT["TIME"] = "Koha:"; + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-bg.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-bg.js new file mode 100644 index 0000000..5eb73ec --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-bg.js @@ -0,0 +1,124 @@ +// ** I18N + +// Calendar BG language +// Author: Mihai Bazon, +// Translator: Valentin Sheiretsky, +// Encoding: Windows-1251 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Íåäåëÿ", + "Ïîíåäåëíèê", + "Âòîðíèê", + "Ñðÿäà", + "×åòâúðòúê", + "Ïåòúê", + "Ñúáîòà", + "Íåäåëÿ"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Íåä", + "Ïîí", + "Âòî", + "Ñðÿ", + "×åò", + "Ïåò", + "Ñúá", + "Íåä"); + +// full month names +Calendar._MN = new Array +("ßíóàðè", + "Ôåâðóàðè", + "Ìàðò", + "Àïðèë", + "Ìàé", + "Þíè", + "Þëè", + "Àâãóñò", + "Ñåïòåìâðè", + "Îêòîìâðè", + "Íîåìâðè", + "Äåêåìâðè"); + +// short month names +Calendar._SMN = new Array +("ßíó", + "Ôåâ", + "Ìàð", + "Àïð", + "Ìàé", + "Þíè", + "Þëè", + "Àâã", + "Ñåï", + "Îêò", + "Íîå", + "Äåê"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Èíôîðìàöèÿ çà êàëåíäàðà"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Date selection:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" + +"- Hold mouse button on any of the above buttons for faster selection."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Time selection:\n" + +"- Click on any of the time parts to increase it\n" + +"- or Shift-click to decrease it\n" + +"- or click and drag for faster selection."; + +Calendar._TT["PREV_YEAR"] = "Ïðåäíà ãîäèíà (çàäðúæòå çà ìåíþ)"; +Calendar._TT["PREV_MONTH"] = "Ïðåäåí ìåñåö (çàäðúæòå çà ìåíþ)"; +Calendar._TT["GO_TODAY"] = "Èçáåðåòå äíåñ"; +Calendar._TT["NEXT_MONTH"] = "Ñëåäâàù ìåñåö (çàäðúæòå çà ìåíþ)"; +Calendar._TT["NEXT_YEAR"] = "Ñëåäâàùà ãîäèíà (çàäðúæòå çà ìåíþ)"; +Calendar._TT["SEL_DATE"] = "Èçáåðåòå äàòà"; +Calendar._TT["DRAG_TO_MOVE"] = "Ïðåìåñòâàíå"; +Calendar._TT["PART_TODAY"] = " (äíåñ)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "%s êàòî ïúðâè äåí"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Çàòâîðåòå"; +Calendar._TT["TODAY"] = "Äíåñ"; +Calendar._TT["TIME_PART"] = "(Shift-)Click èëè drag çà äà ïðîìåíèòå ñòîéíîñòòà"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%A - %e %B %Y"; + +Calendar._TT["WK"] = "Ñåäì"; +Calendar._TT["TIME"] = "×àñ:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-big5-utf8.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-big5-utf8.js new file mode 100644 index 0000000..14e0d5d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-big5-utf8.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar big5-utf8 language +// Author: Gary Fu, +// Encoding: utf8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("星期日", + "星期一", + "星期二", + "星期三", + "星期四", + "星期五", + "星期六", + "星期日"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("æ—¥", + "一", + "二", + "三", + "å››", + "五", + "å…­", + "æ—¥"); + +// full month names +Calendar._MN = new Array +("一月", + "二月", + "三月", + "四月", + "五月", + "六月", + "七月", + "八月", + "ä¹æœˆ", + "å月", + "å一月", + "å二月"); + +// short month names +Calendar._SMN = new Array +("一月", + "二月", + "三月", + "四月", + "五月", + "六月", + "七月", + "八月", + "ä¹æœˆ", + "å月", + "å一月", + "å二月"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "關於"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"日期é¸æ“‡æ–¹æ³•:\n" + +"- 使用 \xab, \xbb 按鈕å¯é¸æ“‡å¹´ä»½\n" + +"- 使用 " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " 按鈕å¯é¸æ“‡æœˆä»½\n" + +"- 按ä½ä¸Šé¢çš„按鈕å¯ä»¥åŠ å¿«é¸å–"; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"時間é¸æ“‡æ–¹æ³•:\n" + +"- 點擊任何的時間部份å¯å¢žåŠ å…¶å€¼\n" + +"- åŒæ™‚按Shiftéµå†é»žæ“Šå¯æ¸›å°‘其值\n" + +"- 點擊並拖曳å¯åŠ å¿«æ”¹è®Šçš„值"; + +Calendar._TT["PREV_YEAR"] = "上一年 (按ä½é¸å–®)"; +Calendar._TT["PREV_MONTH"] = "下一年 (按ä½é¸å–®)"; +Calendar._TT["GO_TODAY"] = "到今日"; +Calendar._TT["NEXT_MONTH"] = "上一月 (按ä½é¸å–®)"; +Calendar._TT["NEXT_YEAR"] = "下一月 (按ä½é¸å–®)"; +Calendar._TT["SEL_DATE"] = "é¸æ“‡æ—¥æœŸ"; +Calendar._TT["DRAG_TO_MOVE"] = "拖曳"; +Calendar._TT["PART_TODAY"] = " (今日)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "å°‡ %s 顯示在å‰"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "關閉"; +Calendar._TT["TODAY"] = "今日"; +Calendar._TT["TIME_PART"] = "點擊or拖曳å¯æ”¹è®Šæ™‚é–“(åŒæ™‚按Shift為減)"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "週"; +Calendar._TT["TIME"] = "Time:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-big5.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-big5.js new file mode 100644 index 0000000..a589358 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-big5.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar big5 language +// Author: Gary Fu, +// Encoding: big5 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("¬P´Á¤é", + "¬P´Á¤@", + "¬P´Á¤G", + "¬P´Á¤T", + "¬P´Á¥|", + "¬P´Á¤­", + "¬P´Á¤»", + "¬P´Á¤é"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("¤é", + "¤@", + "¤G", + "¤T", + "¥|", + "¤­", + "¤»", + "¤é"); + +// full month names +Calendar._MN = new Array +("¤@¤ë", + "¤G¤ë", + "¤T¤ë", + "¥|¤ë", + "¤­¤ë", + "¤»¤ë", + "¤C¤ë", + "¤K¤ë", + "¤E¤ë", + "¤Q¤ë", + "¤Q¤@¤ë", + "¤Q¤G¤ë"); + +// short month names +Calendar._SMN = new Array +("¤@¤ë", + "¤G¤ë", + "¤T¤ë", + "¥|¤ë", + "¤­¤ë", + "¤»¤ë", + "¤C¤ë", + "¤K¤ë", + "¤E¤ë", + "¤Q¤ë", + "¤Q¤@¤ë", + "¤Q¤G¤ë"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Ãö©ó"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"¤é´Á¿ï¾Ü¤èªk:\n" + +"- ¨Ï¥Î \xab, \xbb «ö¶s¥i¿ï¾Ü¦~¥÷\n" + +"- ¨Ï¥Î " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " «ö¶s¥i¿ï¾Ü¤ë¥÷\n" + +"- «ö¦í¤W­±ªº«ö¶s¥i¥H¥[§Ö¿ï¨ú"; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"®É¶¡¿ï¾Ü¤èªk:\n" + +"- ÂIÀ»¥ô¦óªº®É¶¡³¡¥÷¥i¼W¥[¨ä­È\n" + +"- ¦P®É«öShiftÁä¦AÂIÀ»¥i´î¤Ö¨ä­È\n" + +"- ÂIÀ»¨Ã©ì¦²¥i¥[§Ö§ïÅܪº­È"; + +Calendar._TT["PREV_YEAR"] = "¤W¤@¦~ («ö¦í¿ï³æ)"; +Calendar._TT["PREV_MONTH"] = "¤U¤@¦~ («ö¦í¿ï³æ)"; +Calendar._TT["GO_TODAY"] = "¨ì¤µ¤é"; +Calendar._TT["NEXT_MONTH"] = "¤W¤@¤ë («ö¦í¿ï³æ)"; +Calendar._TT["NEXT_YEAR"] = "¤U¤@¤ë («ö¦í¿ï³æ)"; +Calendar._TT["SEL_DATE"] = "¿ï¾Ü¤é´Á"; +Calendar._TT["DRAG_TO_MOVE"] = "©ì¦²"; +Calendar._TT["PART_TODAY"] = " (¤µ¤é)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "±N %s Åã¥Ü¦b«e"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Ãö³¬"; +Calendar._TT["TODAY"] = "¤µ¤é"; +Calendar._TT["TIME_PART"] = "ÂIÀ»or©ì¦²¥i§ïÅܮɶ¡(¦P®É«öShift¬°´î)"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "¶g"; +Calendar._TT["TIME"] = "Time:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-br.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-br.js new file mode 100644 index 0000000..bfb0747 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-br.js @@ -0,0 +1,108 @@ +// ** I18N + +// Calendar pt-BR language +// Author: Fernando Dourado, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Domingo", + "Segunda", + "Terça", + "Quarta", + "Quinta", + "Sexta", + "Sabádo", + "Domingo"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +// [No changes using default values] + +// full month names +Calendar._MN = new Array +("Janeiro", + "Fevereiro", + "Março", + "Abril", + "Maio", + "Junho", + "Julho", + "Agosto", + "Setembro", + "Outubro", + "Novembro", + "Dezembro"); + +// short month names +// [No changes using default values] + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Sobre o calendário"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Translate to portuguese Brazil (pt-BR) by Fernando Dourado (fernando.dourado@ig.com.br)\n" + +"Tradução para o português Brasil (pt-BR) por Fernando Dourado (fernando.dourado@ig.com.br)" + +"\n\n" + +"Selecionar data:\n" + +"- Use as teclas \xab, \xbb para selecionar o ano\n" + +"- Use as teclas " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para selecionar o mês\n" + +"- Clique e segure com o mouse em qualquer botão para selecionar rapidamente."; + +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Selecionar hora:\n" + +"- Clique em qualquer uma das partes da hora para aumentar\n" + +"- ou Shift-clique para diminuir\n" + +"- ou clique e arraste para selecionar rapidamente."; + +Calendar._TT["PREV_YEAR"] = "Ano anterior (clique e segure para menu)"; +Calendar._TT["PREV_MONTH"] = "Mês anterior (clique e segure para menu)"; +Calendar._TT["GO_TODAY"] = "Ir para a data atual"; +Calendar._TT["NEXT_MONTH"] = "Próximo mês (clique e segure para menu)"; +Calendar._TT["NEXT_YEAR"] = "Próximo ano (clique e segure para menu)"; +Calendar._TT["SEL_DATE"] = "Selecione uma data"; +Calendar._TT["DRAG_TO_MOVE"] = "Clique e segure para mover"; +Calendar._TT["PART_TODAY"] = " (hoje)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Exibir %s primeiro"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Fechar"; +Calendar._TT["TODAY"] = "Hoje"; +Calendar._TT["TIME_PART"] = "(Shift-)Clique ou arraste para mudar o valor"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%d de %B de %Y"; + +Calendar._TT["WK"] = "sem"; +Calendar._TT["TIME"] = "Hora:"; + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ca.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ca.js new file mode 100644 index 0000000..a2121bc --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ca.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar CA language +// Author: Mihai Bazon, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Diumenge", + "Dilluns", + "Dimarts", + "Dimecres", + "Dijous", + "Divendres", + "Dissabte", + "Diumenge"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Diu", + "Dil", + "Dmt", + "Dmc", + "Dij", + "Div", + "Dis", + "Diu"); + +// full month names +Calendar._MN = new Array +("Gener", + "Febrer", + "Març", + "Abril", + "Maig", + "Juny", + "Juliol", + "Agost", + "Setembre", + "Octubre", + "Novembre", + "Desembre"); + +// short month names +Calendar._SMN = new Array +("Gen", + "Feb", + "Mar", + "Abr", + "Mai", + "Jun", + "Jul", + "Ago", + "Set", + "Oct", + "Nov", + "Des"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Sobre el calendari"; + +Calendar._TT["ABOUT"] = +"DHTML Selector de Data/Hora\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Sel.lecció de Dates:\n" + +"- Fes servir els botons \xab, \xbb per sel.leccionar l'any\n" + +"- Fes servir els botons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per se.lecciconar el mes\n" + +"- Manté el ratolí apretat en qualsevol dels anteriors per sel.lecció ràpida."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Time selection:\n" + +"- claca en qualsevol de les parts de la hora per augmentar-les\n" + +"- o Shift-click per decrementar-la\n" + +"- or click and arrastra per sel.lecció ràpida."; + +Calendar._TT["PREV_YEAR"] = "Any anterior (Mantenir per menu)"; +Calendar._TT["PREV_MONTH"] = "Mes anterior (Mantenir per menu)"; +Calendar._TT["GO_TODAY"] = "Anar a avui"; +Calendar._TT["NEXT_MONTH"] = "Mes següent (Mantenir per menu)"; +Calendar._TT["NEXT_YEAR"] = "Any següent (Mantenir per menu)"; +Calendar._TT["SEL_DATE"] = "Sel.leccionar data"; +Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar per moure"; +Calendar._TT["PART_TODAY"] = " (avui)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Mostra %s primer"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Tanca"; +Calendar._TT["TODAY"] = "Avui"; +Calendar._TT["TIME_PART"] = "(Shift-)Click a arrastra per canviar el valor"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "st"; +Calendar._TT["TIME"] = "Hora:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cn.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cn.js new file mode 100644 index 0000000..a0ef7c6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cn.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: any +// Translator : Niko +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("\u5468\u65e5",//\u5468\u65e5 + "\u5468\u4e00",//\u5468\u4e00 + "\u5468\u4e8c",//\u5468\u4e8c + "\u5468\u4e09",//\u5468\u4e09 + "\u5468\u56db",//\u5468\u56db + "\u5468\u4e94",//\u5468\u4e94 + "\u5468\u516d",//\u5468\u516d + "\u5468\u65e5");//\u5468\u65e5 + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("\u5468\u65e5", + "\u5468\u4e00", + "\u5468\u4e8c", + "\u5468\u4e09", + "\u5468\u56db", + "\u5468\u4e94", + "\u5468\u516d", + "\u5468\u65e5"); + +// full month names +Calendar._MN = new Array +("\u4e00\u6708", + "\u4e8c\u6708", + "\u4e09\u6708", + "\u56db\u6708", + "\u4e94\u6708", + "\u516d\u6708", + "\u4e03\u6708", + "\u516b\u6708", + "\u4e5d\u6708", + "\u5341\u6708", + "\u5341\u4e00\u6708", + "\u5341\u4e8c\u6708"); + +// short month names +Calendar._SMN = new Array +("\u4e00\u6708", + "\u4e8c\u6708", + "\u4e09\u6708", + "\u56db\u6708", + "\u4e94\u6708", + "\u516d\u6708", + "\u4e03\u6708", + "\u516b\u6708", + "\u4e5d\u6708", + "\u5341\u6708", + "\u5341\u4e00\u6708", + "\u5341\u4e8c\u6708"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "\u5173\u4e8e"; + +Calendar._TT["ABOUT"] = +" DHTML \u65e5\u8d77/\u65f6\u95f4\u9009\u62e9\u63a7\u4ef6\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: \u6700\u65b0\u7248\u672c\u8bf7\u767b\u9646http://www.dynarch.com/projects/calendar/\u5bdf\u770b\n" + +"\u9075\u5faaGNU LGPL. \u7ec6\u8282\u53c2\u9605 http://gnu.org/licenses/lgpl.html" + +"\n\n" + +"\u65e5\u671f\u9009\u62e9:\n" + +"- \u70b9\u51fb\xab(\xbb)\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e00\u5e74\u5ea6.\n" + +"- \u70b9\u51fb" + String.fromCharCode(0x2039) + "(" + String.fromCharCode(0x203a) + ")\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e2a\u6708\u4efd.\n" + +"- \u957f\u65f6\u95f4\u6309\u7740\u6309\u94ae\u5c06\u51fa\u73b0\u66f4\u591a\u9009\u62e9\u9879."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"\u65f6\u95f4\u9009\u62e9:\n" + +"-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u589e\u52a0\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\n" + +"-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u6309\u4f4fShift\u952e\u540e\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u51cf\u5c11\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)."; + +Calendar._TT["PREV_YEAR"] = "\u4e0a\u4e00\u5e74"; +Calendar._TT["PREV_MONTH"] = "\u4e0a\u4e2a\u6708"; +Calendar._TT["GO_TODAY"] = "\u5230\u4eca\u5929"; +Calendar._TT["NEXT_MONTH"] = "\u4e0b\u4e2a\u6708"; +Calendar._TT["NEXT_YEAR"] = "\u4e0b\u4e00\u5e74"; +Calendar._TT["SEL_DATE"] = "\u9009\u62e9\u65e5\u671f"; +Calendar._TT["DRAG_TO_MOVE"] = "\u62d6\u52a8"; +Calendar._TT["PART_TODAY"] = " (\u4eca\u5929)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "%s\u4e3a\u8fd9\u5468\u7684\u7b2c\u4e00\u5929"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "\u5173\u95ed"; +Calendar._TT["TODAY"] = "\u4eca\u5929"; +Calendar._TT["TIME_PART"] = "(\u6309\u7740Shift\u952e)\u5355\u51fb\u6216\u62d6\u52a8\u6539\u53d8\u503c"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e\u65e5"; + +Calendar._TT["WK"] = "\u5468"; +Calendar._TT["TIME"] = "\u65f6\u95f4:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs-utf8.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs-utf8.js new file mode 100644 index 0000000..f6bbbeb --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs-utf8.js @@ -0,0 +1,65 @@ +/* + calendar-cs-win.js + language: Czech + encoding: windows-1250 + author: Lubos Jerabek (xnet@seznam.cz) + Jan Uhlir (espinosa@centrum.cz) +*/ + +// ** I18N +Calendar._DN = new Array('NedÄ›le','PondÄ›lí','Úterý','StÅ™eda','ÄŒtvrtek','Pátek','Sobota','NedÄ›le'); +Calendar._SDN = new Array('Ne','Po','Út','St','ÄŒt','Pá','So','Ne'); +Calendar._MN = new Array('Leden','Únor','BÅ™ezen','Duben','KvÄ›ten','ÄŒerven','ÄŒervenec','Srpen','Září','Říjen','Listopad','Prosinec'); +Calendar._SMN = new Array('Led','Úno','BÅ™e','Dub','KvÄ›','ÄŒrv','ÄŒvc','Srp','Zář','Říj','Lis','Pro'); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O komponentÄ› kalendář"; +Calendar._TT["TOGGLE"] = "ZmÄ›na prvního dne v týdnu"; +Calendar._TT["PREV_YEAR"] = "PÅ™edchozí rok (pÅ™idrž pro menu)"; +Calendar._TT["PREV_MONTH"] = "PÅ™edchozí mÄ›síc (pÅ™idrž pro menu)"; +Calendar._TT["GO_TODAY"] = "DneÅ¡ní datum"; +Calendar._TT["NEXT_MONTH"] = "Další mÄ›síc (pÅ™idrž pro menu)"; +Calendar._TT["NEXT_YEAR"] = "Další rok (pÅ™idrž pro menu)"; +Calendar._TT["SEL_DATE"] = "Vyber datum"; +Calendar._TT["DRAG_TO_MOVE"] = "ChyÅ¥ a táhni, pro pÅ™esun"; +Calendar._TT["PART_TODAY"] = " (dnes)"; +Calendar._TT["MON_FIRST"] = "Ukaž jako první PondÄ›lí"; +//Calendar._TT["SUN_FIRST"] = "Ukaž jako první NedÄ›li"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"VýbÄ›r datumu:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Použijte tlaÄítka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k výbÄ›ru mÄ›síce\n" + +"- Podržte tlaÄítko myÅ¡i na jakémkoliv z tÄ›ch tlaÄítek pro rychlejší výbÄ›r."; + +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"VýbÄ›r Äasu:\n" + +"- KliknÄ›te na jakoukoliv z Äástí výbÄ›ru Äasu pro zvýšení.\n" + +"- nebo Shift-click pro snížení\n" + +"- nebo kliknÄ›te a táhnÄ›te pro rychlejší výbÄ›r."; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Zobraz %s první"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Zavřít"; +Calendar._TT["TODAY"] = "Dnes"; +Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro zmÄ›nu hodnoty"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "ÄŒas:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs-win.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs-win.js new file mode 100644 index 0000000..140dff3 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs-win.js @@ -0,0 +1,65 @@ +/* + calendar-cs-win.js + language: Czech + encoding: windows-1250 + author: Lubos Jerabek (xnet@seznam.cz) + Jan Uhlir (espinosa@centrum.cz) +*/ + +// ** I18N +Calendar._DN = new Array('Nedìle','Pondìlí','Úterý','Støeda','Ètvrtek','Pátek','Sobota','Nedìle'); +Calendar._SDN = new Array('Ne','Po','Út','St','Èt','Pá','So','Ne'); +Calendar._MN = new Array('Leden','Únor','Bøezen','Duben','Kvìten','Èerven','Èervenec','Srpen','Záøí','Øíjen','Listopad','Prosinec'); +Calendar._SMN = new Array('Led','Úno','Bøe','Dub','Kvì','Èrv','Èvc','Srp','Záø','Øíj','Lis','Pro'); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O komponentì kalendáø"; +Calendar._TT["TOGGLE"] = "Zmìna prvního dne v týdnu"; +Calendar._TT["PREV_YEAR"] = "Pøedchozí rok (pøidrž pro menu)"; +Calendar._TT["PREV_MONTH"] = "Pøedchozí mìsíc (pøidrž pro menu)"; +Calendar._TT["GO_TODAY"] = "Dnešní datum"; +Calendar._TT["NEXT_MONTH"] = "Další mìsíc (pøidrž pro menu)"; +Calendar._TT["NEXT_YEAR"] = "Další rok (pøidrž pro menu)"; +Calendar._TT["SEL_DATE"] = "Vyber datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Chy a táhni, pro pøesun"; +Calendar._TT["PART_TODAY"] = " (dnes)"; +Calendar._TT["MON_FIRST"] = "Ukaž jako první Pondìlí"; +//Calendar._TT["SUN_FIRST"] = "Ukaž jako první Nedìli"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Výbìr datumu:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Použijte tlaèítka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k výbìru mìsíce\n" + +"- Podržte tlaèítko myši na jakémkoliv z tìch tlaèítek pro rychlejší výbìr."; + +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Výbìr èasu:\n" + +"- Kliknìte na jakoukoliv z èástí výbìru èasu pro zvýšení.\n" + +"- nebo Shift-click pro snížení\n" + +"- nebo kliknìte a táhnìte pro rychlejší výbìr."; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Zobraz %s první"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Zavøít"; +Calendar._TT["TODAY"] = "Dnes"; +Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro zmìnu hodnoty"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Èas:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs.js new file mode 100644 index 0000000..f6bbbeb --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-cs.js @@ -0,0 +1,65 @@ +/* + calendar-cs-win.js + language: Czech + encoding: windows-1250 + author: Lubos Jerabek (xnet@seznam.cz) + Jan Uhlir (espinosa@centrum.cz) +*/ + +// ** I18N +Calendar._DN = new Array('NedÄ›le','PondÄ›lí','Úterý','StÅ™eda','ÄŒtvrtek','Pátek','Sobota','NedÄ›le'); +Calendar._SDN = new Array('Ne','Po','Út','St','ÄŒt','Pá','So','Ne'); +Calendar._MN = new Array('Leden','Únor','BÅ™ezen','Duben','KvÄ›ten','ÄŒerven','ÄŒervenec','Srpen','Září','Říjen','Listopad','Prosinec'); +Calendar._SMN = new Array('Led','Úno','BÅ™e','Dub','KvÄ›','ÄŒrv','ÄŒvc','Srp','Zář','Říj','Lis','Pro'); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O komponentÄ› kalendář"; +Calendar._TT["TOGGLE"] = "ZmÄ›na prvního dne v týdnu"; +Calendar._TT["PREV_YEAR"] = "PÅ™edchozí rok (pÅ™idrž pro menu)"; +Calendar._TT["PREV_MONTH"] = "PÅ™edchozí mÄ›síc (pÅ™idrž pro menu)"; +Calendar._TT["GO_TODAY"] = "DneÅ¡ní datum"; +Calendar._TT["NEXT_MONTH"] = "Další mÄ›síc (pÅ™idrž pro menu)"; +Calendar._TT["NEXT_YEAR"] = "Další rok (pÅ™idrž pro menu)"; +Calendar._TT["SEL_DATE"] = "Vyber datum"; +Calendar._TT["DRAG_TO_MOVE"] = "ChyÅ¥ a táhni, pro pÅ™esun"; +Calendar._TT["PART_TODAY"] = " (dnes)"; +Calendar._TT["MON_FIRST"] = "Ukaž jako první PondÄ›lí"; +//Calendar._TT["SUN_FIRST"] = "Ukaž jako první NedÄ›li"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"VýbÄ›r datumu:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Použijte tlaÄítka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k výbÄ›ru mÄ›síce\n" + +"- Podržte tlaÄítko myÅ¡i na jakémkoliv z tÄ›ch tlaÄítek pro rychlejší výbÄ›r."; + +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"VýbÄ›r Äasu:\n" + +"- KliknÄ›te na jakoukoliv z Äástí výbÄ›ru Äasu pro zvýšení.\n" + +"- nebo Shift-click pro snížení\n" + +"- nebo kliknÄ›te a táhnÄ›te pro rychlejší výbÄ›r."; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Zobraz %s první"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Zavřít"; +Calendar._TT["TODAY"] = "Dnes"; +Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro zmÄ›nu hodnoty"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "ÄŒas:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-da.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-da.js new file mode 100644 index 0000000..a99b598 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-da.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar DA language +// Author: Michael Thingmand Henriksen, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Søndag", +"Mandag", +"Tirsdag", +"Onsdag", +"Torsdag", +"Fredag", +"Lørdag", +"Søndag"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Søn", +"Man", +"Tir", +"Ons", +"Tor", +"Fre", +"Lør", +"Søn"); + +// full month names +Calendar._MN = new Array +("Januar", +"Februar", +"Marts", +"April", +"Maj", +"Juni", +"Juli", +"August", +"September", +"Oktober", +"November", +"December"); + +// short month names +Calendar._SMN = new Array +("Jan", +"Feb", +"Mar", +"Apr", +"Maj", +"Jun", +"Jul", +"Aug", +"Sep", +"Okt", +"Nov", +"Dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Om Kalenderen"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For den seneste version besøg: http://www.dynarch.com/projects/calendar/\n"; + +"Distribueret under GNU LGPL. Se http://gnu.org/licenses/lgpl.html for detajler." + +"\n\n" + +"Valg af dato:\n" + +"- Brug \xab, \xbb knapperne for at vælge Ã¥r\n" + +"- Brug " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knapperne for at vælge mÃ¥ned\n" + +"- Hold knappen pÃ¥ musen nede pÃ¥ knapperne ovenfor for hurtigere valg."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Valg af tid:\n" + +"- Klik pÃ¥ en vilkÃ¥rlig del for større værdi\n" + +"- eller Shift-klik for for mindre værdi\n" + +"- eller klik og træk for hurtigere valg."; + +Calendar._TT["PREV_YEAR"] = "Ét Ã¥r tilbage (hold for menu)"; +Calendar._TT["PREV_MONTH"] = "Én mÃ¥ned tilbage (hold for menu)"; +Calendar._TT["GO_TODAY"] = "GÃ¥ til i dag"; +Calendar._TT["NEXT_MONTH"] = "Én mÃ¥ned frem (hold for menu)"; +Calendar._TT["NEXT_YEAR"] = "Ét Ã¥r frem (hold for menu)"; +Calendar._TT["SEL_DATE"] = "Vælg dag"; +Calendar._TT["DRAG_TO_MOVE"] = "Træk vinduet"; +Calendar._TT["PART_TODAY"] = " (i dag)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Vis %s først"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Luk"; +Calendar._TT["TODAY"] = "I dag"; +Calendar._TT["TIME_PART"] = "(Shift-)klik eller træk for at ændre værdi"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "Uge"; +Calendar._TT["TIME"] = "Tid:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-de.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-de.js new file mode 100644 index 0000000..4bc1137 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-de.js @@ -0,0 +1,124 @@ +// ** I18N + +// Calendar DE language +// Author: Jack (tR), +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Sonntag", + "Montag", + "Dienstag", + "Mittwoch", + "Donnerstag", + "Freitag", + "Samstag", + "Sonntag"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("So", + "Mo", + "Di", + "Mi", + "Do", + "Fr", + "Sa", + "So"); + +// full month names +Calendar._MN = new Array +("Januar", + "Februar", + "M\u00e4rz", + "April", + "Mai", + "Juni", + "Juli", + "August", + "September", + "Oktober", + "November", + "Dezember"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Feb", + "M\u00e4r", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Okt", + "Nov", + "Dez"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "\u00DCber dieses Kalendarmodul"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Datum ausw\u00e4hlen:\n" + +"- Benutzen Sie die \xab, \xbb Buttons um das Jahr zu w\u00e4hlen\n" + +"- Benutzen Sie die " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Buttons um den Monat zu w\u00e4hlen\n" + +"- F\u00fcr eine Schnellauswahl halten Sie die Maustaste \u00fcber diesen Buttons fest."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Zeit ausw\u00e4hlen:\n" + +"- Klicken Sie auf die Teile der Uhrzeit, um diese zu erh\u00F6hen\n" + +"- oder klicken Sie mit festgehaltener Shift-Taste um diese zu verringern\n" + +"- oder klicken und festhalten f\u00fcr Schnellauswahl."; + +Calendar._TT["TOGGLE"] = "Ersten Tag der Woche w\u00e4hlen"; +Calendar._TT["PREV_YEAR"] = "Voriges Jahr (Festhalten f\u00fcr Schnellauswahl)"; +Calendar._TT["PREV_MONTH"] = "Voriger Monat (Festhalten f\u00fcr Schnellauswahl)"; +Calendar._TT["GO_TODAY"] = "Heute ausw\u00e4hlen"; +Calendar._TT["NEXT_MONTH"] = "N\u00e4chst. Monat (Festhalten f\u00fcr Schnellauswahl)"; +Calendar._TT["NEXT_YEAR"] = "N\u00e4chst. Jahr (Festhalten f\u00fcr Schnellauswahl)"; +Calendar._TT["SEL_DATE"] = "Datum ausw\u00e4hlen"; +Calendar._TT["DRAG_TO_MOVE"] = "Zum Bewegen festhalten"; +Calendar._TT["PART_TODAY"] = " (Heute)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Woche beginnt mit %s "; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Schlie\u00dfen"; +Calendar._TT["TODAY"] = "Heute"; +Calendar._TT["TIME_PART"] = "(Shift-)Klick oder Festhalten und Ziehen um den Wert zu \u00e4ndern"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Zeit:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-du.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-du.js new file mode 100644 index 0000000..2200448 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-du.js @@ -0,0 +1,45 @@ +// ** I18N +Calendar._DN = new Array +("Zondag", + "Maandag", + "Dinsdag", + "Woensdag", + "Donderdag", + "Vrijdag", + "Zaterdag", + "Zondag"); +Calendar._MN = new Array +("Januari", + "Februari", + "Maart", + "April", + "Mei", + "Juni", + "Juli", + "Augustus", + "September", + "Oktober", + "November", + "December"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["TOGGLE"] = "Toggle startdag van de week"; +Calendar._TT["PREV_YEAR"] = "Vorig jaar (indrukken voor menu)"; +Calendar._TT["PREV_MONTH"] = "Vorige month (indrukken voor menu)"; +Calendar._TT["GO_TODAY"] = "Naar Vandaag"; +Calendar._TT["NEXT_MONTH"] = "Volgende Maand (indrukken voor menu)"; +Calendar._TT["NEXT_YEAR"] = "Volgend jaar (indrukken voor menu)"; +Calendar._TT["SEL_DATE"] = "Selecteer datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Sleep om te verplaatsen"; +Calendar._TT["PART_TODAY"] = " (vandaag)"; +Calendar._TT["MON_FIRST"] = "Toon Maandag eerst"; +Calendar._TT["SUN_FIRST"] = "Toon Zondag eerst"; +Calendar._TT["CLOSE"] = "Sluiten"; +Calendar._TT["TODAY"] = "Vandaag"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "y-mm-dd"; +Calendar._TT["TT_DATE_FORMAT"] = "D, M d"; + +Calendar._TT["WK"] = "wk"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-el.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-el.js new file mode 100644 index 0000000..43a9b2c --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-el.js @@ -0,0 +1,89 @@ +// ** I18N +Calendar._DN = new Array +("ΚυÏιακή", + "ΔευτέÏα", + "ΤÏίτη", + "ΤετάÏτη", + "Πέμπτη", + "ΠαÏασκευή", + "Σάββατο", + "ΚυÏιακή"); + +Calendar._SDN = new Array +("Κυ", + "Δε", + "TÏ", + "Τε", + "Πε", + "Πα", + "Σα", + "Κυ"); + +Calendar._MN = new Array +("ΙανουάÏιος", + "ΦεβÏουάÏιος", + "ΜάÏτιος", + "ΑπÏίλιος", + "Μάϊος", + "ΙοÏνιος", + "ΙοÏλιος", + "ΑÏγουστος", + "ΣεπτέμβÏιος", + "ΟκτώβÏιος", + "ÎοέμβÏιος", + "ΔεκέμβÏιος"); + +Calendar._SMN = new Array +("Ιαν", + "Φεβ", + "ΜαÏ", + "ΑπÏ", + "Μαι", + "Ιουν", + "Ιουλ", + "Αυγ", + "Σεπ", + "Οκτ", + "Îοε", + "Δεκ"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Για το ημεÏολόγιο"; + +Calendar._TT["ABOUT"] = +"Επιλογέας ημεÏομηνίας/ÏŽÏας σε DHTML\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Για τελευταία έκδοση: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Επιλογή ημεÏομηνίας:\n" + +"- ΧÏησιμοποιείστε τα κουμπιά \xab, \xbb για επιλογή έτους\n" + +"- ΧÏησιμοποιείστε τα κουμπιά " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " για επιλογή μήνα\n" + +"- ΚÏατήστε κουμπί Ï€Î¿Î½Ï„Î¹ÎºÎ¿Ï Ï€Î±Ï„Î·Î¼Î­Î½Î¿ στα παÏαπάνω κουμπιά για πιο γÏήγοÏη επιλογή."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Επιλογή ÏŽÏας:\n" + +"- Κάντε κλικ σε ένα από τα μέÏη της ÏŽÏας για αÏξηση\n" + +"- ή Shift-κλικ για μείωση\n" + +"- ή κλικ και μετακίνηση για πιο γÏήγοÏη επιλογή."; +Calendar._TT["TOGGLE"] = "ΜπάÏα Ï€Ïώτης ημέÏας της εβδομάδας"; +Calendar._TT["PREV_YEAR"] = "ΠÏοηγ. έτος (κÏατήστε για το μενοÏ)"; +Calendar._TT["PREV_MONTH"] = "ΠÏοηγ. μήνας (κÏατήστε για το μενοÏ)"; +Calendar._TT["GO_TODAY"] = "ΣήμεÏα"; +Calendar._TT["NEXT_MONTH"] = "Επόμενος μήνας (κÏατήστε για το μενοÏ)"; +Calendar._TT["NEXT_YEAR"] = "Επόμενο έτος (κÏατήστε για το μενοÏ)"; +Calendar._TT["SEL_DATE"] = "Επιλέξτε ημεÏομηνία"; +Calendar._TT["DRAG_TO_MOVE"] = "ΣÏÏτε για να μετακινήσετε"; +Calendar._TT["PART_TODAY"] = " (σήμεÏα)"; +Calendar._TT["MON_FIRST"] = "Εμφάνιση ΔευτέÏας Ï€Ïώτα"; +Calendar._TT["SUN_FIRST"] = "Εμφάνιση ΚυÏιακής Ï€Ïώτα"; +Calendar._TT["CLOSE"] = "Κλείσιμο"; +Calendar._TT["TODAY"] = "ΣήμεÏα"; +Calendar._TT["TIME_PART"] = "(Shift-)κλικ ή μετακίνηση για αλλαγή"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; +Calendar._TT["TT_DATE_FORMAT"] = "D, d M"; + +Calendar._TT["WK"] = "εβδ"; + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-en.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-en.js new file mode 100644 index 0000000..6aa07a8 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-en.js @@ -0,0 +1,129 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat", + "Sun"); + +// First day of the week. "0" means display Sunday first, "1" means display +// Monday first, etc. +Calendar._FD = 0; + +// full month names +Calendar._MN = new Array +("January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "About the calendar"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Date selection:\n" + +"- Use the \xab, \xbb buttons to select year\n" + +"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" + +"- Hold mouse button on any of the above buttons for faster selection."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Time selection:\n" + +"- Click on any of the time parts to increase it\n" + +"- or Shift-click to decrease it\n" + +"- or click and drag for faster selection."; + +Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)"; +Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)"; +Calendar._TT["GO_TODAY"] = "Go Today"; +Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)"; +Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)"; +Calendar._TT["SEL_DATE"] = "Select date"; +Calendar._TT["DRAG_TO_MOVE"] = "Drag to move"; +Calendar._TT["PART_TODAY"] = " (today)"; +Calendar._TT["GO_NONE"] = "Don't enter in a date"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Display %s first"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Close"; +Calendar._TT["TODAY"] = "Today"; +Calendar._TT["NONE"] = "None"; +Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Time:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-es.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-es.js new file mode 100644 index 0000000..19c1b30 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-es.js @@ -0,0 +1,129 @@ +// ** I18N + +// Calendar ES (spanish) language +// Author: Mihai Bazon, +// Updater: Servilio Afre Puentes +// Updated: 2004-06-03 +// Encoding: utf-8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Domingo", + "Lunes", + "Martes", + "Miércoles", + "Jueves", + "Viernes", + "Sábado", + "Domingo"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Dom", + "Lun", + "Mar", + "Mié", + "Jue", + "Vie", + "Sáb", + "Dom"); + +// First day of the week. "0" means display Sunday first, "1" means display +// Monday first, etc. +Calendar._FD = 1; + +// full month names +Calendar._MN = new Array +("Enero", + "Febrero", + "Marzo", + "Abril", + "Mayo", + "Junio", + "Julio", + "Agosto", + "Septiembre", + "Octubre", + "Noviembre", + "Diciembre"); + +// short month names +Calendar._SMN = new Array +("Ene", + "Feb", + "Mar", + "Abr", + "May", + "Jun", + "Jul", + "Ago", + "Sep", + "Oct", + "Nov", + "Dic"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Acerca del calendario"; + +Calendar._TT["ABOUT"] = +"Selector DHTML de Fecha/Hora\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Para conseguir la última versión visite: http://www.dynarch.com/projects/calendar/\n" + +"Distribuido bajo licencia GNU LGPL. Visite http://gnu.org/licenses/lgpl.html para más detalles." + +"\n\n" + +"Selección de fecha:\n" + +"- Use los botones \xab, \xbb para seleccionar el año\n" + +"- Use los botones " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar el mes\n" + +"- Mantenga pulsado el ratón en cualquiera de estos botones para una selección rápida."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Selección de hora:\n" + +"- Pulse en cualquiera de las partes de la hora para incrementarla\n" + +"- o pulse las mayúsculas mientras hace clic para decrementarla\n" + +"- o haga clic y arrastre el ratón para una selección más rápida."; + +Calendar._TT["PREV_YEAR"] = "Año anterior (mantener para menú)"; +Calendar._TT["PREV_MONTH"] = "Mes anterior (mantener para menú)"; +Calendar._TT["GO_TODAY"] = "Ir a hoy"; +Calendar._TT["NEXT_MONTH"] = "Mes siguiente (mantener para menú)"; +Calendar._TT["NEXT_YEAR"] = "Año siguiente (mantener para menú)"; +Calendar._TT["SEL_DATE"] = "Seleccionar fecha"; +Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar para mover"; +Calendar._TT["PART_TODAY"] = " (hoy)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Hacer %s primer día de la semana"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Cerrar"; +Calendar._TT["TODAY"] = "Hoy"; +Calendar._TT["TIME_PART"] = "(Mayúscula-)Clic o arrastre para cambiar valor"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y"; + +Calendar._TT["WK"] = "sem"; +Calendar._TT["TIME"] = "Hora:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-fi.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-fi.js new file mode 100644 index 0000000..328eabb --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-fi.js @@ -0,0 +1,98 @@ +// ** I18N + +// Calendar FI language (Finnish, Suomi) +// Author: Jarno Käyhkö, +// Encoding: UTF-8 +// Distributed under the same terms as the calendar itself. + +// full day names +Calendar._DN = new Array +("Sunnuntai", + "Maanantai", + "Tiistai", + "Keskiviikko", + "Torstai", + "Perjantai", + "Lauantai", + "Sunnuntai"); + +// short day names +Calendar._SDN = new Array +("Su", + "Ma", + "Ti", + "Ke", + "To", + "Pe", + "La", + "Su"); + +// full month names +Calendar._MN = new Array +("Tammikuu", + "Helmikuu", + "Maaliskuu", + "Huhtikuu", + "Toukokuu", + "Kesäkuu", + "Heinäkuu", + "Elokuu", + "Syyskuu", + "Lokakuu", + "Marraskuu", + "Joulukuu"); + +// short month names +Calendar._SMN = new Array +("Tam", + "Hel", + "Maa", + "Huh", + "Tou", + "Kes", + "Hei", + "Elo", + "Syy", + "Lok", + "Mar", + "Jou"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Tietoja kalenterista"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Uusin versio osoitteessa: http://www.dynarch.com/projects/calendar/\n" + +"Julkaistu GNU LGPL lisenssin alaisuudessa. Lisätietoja osoitteessa http://gnu.org/licenses/lgpl.html" + +"\n\n" + +"Päivämäärä valinta:\n" + +"- Käytä \xab, \xbb painikkeita valitaksesi vuosi\n" + +"- Käytä " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " painikkeita valitaksesi kuukausi\n" + +"- Pitämällä hiiren painiketta minkä tahansa yllä olevan painikkeen kohdalla, saat näkyviin valikon nopeampaan siirtymiseen."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Ajan valinta:\n" + +"- Klikkaa kellonajan numeroita lisätäksesi aikaa\n" + +"- tai pitämällä Shift-näppäintä pohjassa saat aikaa taaksepäin\n" + +"- tai klikkaa ja pidä hiiren painike pohjassa sekä liikuta hiirtä muuttaaksesi aikaa nopeasti eteen- ja taaksepäin."; + +Calendar._TT["PREV_YEAR"] = "Edell. vuosi (paina hetki, näet valikon)"; +Calendar._TT["PREV_MONTH"] = "Edell. kuukausi (paina hetki, näet valikon)"; +Calendar._TT["GO_TODAY"] = "Siirry tähän päivään"; +Calendar._TT["NEXT_MONTH"] = "Seur. kuukausi (paina hetki, näet valikon)"; +Calendar._TT["NEXT_YEAR"] = "Seur. vuosi (paina hetki, näet valikon)"; +Calendar._TT["SEL_DATE"] = "Valitse päivämäärä"; +Calendar._TT["DRAG_TO_MOVE"] = "Siirrä kalenterin paikkaa"; +Calendar._TT["PART_TODAY"] = " (tänään)"; +Calendar._TT["MON_FIRST"] = "Näytä maanantai ensimmäisenä"; +Calendar._TT["SUN_FIRST"] = "Näytä sunnuntai ensimmäisenä"; +Calendar._TT["CLOSE"] = "Sulje"; +Calendar._TT["TODAY"] = "Tänään"; +Calendar._TT["TIME_PART"] = "(Shift-) Klikkaa tai liikuta muuttaaksesi aikaa"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%d.%m.%Y"; + +Calendar._TT["WK"] = "Vko"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-fr.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-fr.js new file mode 100644 index 0000000..b003a65 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-fr.js @@ -0,0 +1,129 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: UTF-8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// Translator: André Liechti, (2006-01-04) from scratch for version 1.x + +// full day names +Calendar._DN = new Array +("Dimanche", + "Lundi", + "Mardi", + "Mercredi", + "Jeudi", + "Vendredi", + "Samedi", + "Dimanche"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Dim", + "Lun", + "Mar", + "Mer", + "Jeu", + "Ven", + "Sam", + "Dim"); + +// First day of the week. "0" means display Sunday first, "1" means display +// Monday first, etc. +Calendar._FD = 1; + +// full month names +Calendar._MN = new Array +("Janvier", + "Février", + "Mars", + "Avril", + "Mai", + "Juin", + "Juillet", + "Août", + "Septembre", + "Octobre", + "Novembre", + "Décembre"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Fév", + "Mar", + "Avr", + "Mai", + "Juin", + "Juil", + "Aou", + "Sep", + "Oct", + "Nov", + "Déc"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "À propos du calendrier"; + +Calendar._TT["ABOUT"] = +"Sélecteur DHTML de date/heure\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Pour la version actuelle, visitez: http://www.dynarch.com/projects/calendar/\n" + +"Distribué sous licence GNU LGPL. Voir http://gnu.org/licenses/lgpl.html pour les détails." + "\n(licence traduite en français: http://www.rodage.org/lgpl.fr.html)" + +"\n\n" + +"Sélection de la date:\n" + +"- Utiliser les boutons \xab, \xbb pour sélectionner l'année\n" + +"- Utiliser les boutons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pour sélectionner le mois\n" + +"- En conservant pressé le bouton de la souris sur l'un de ces boutons, la sélection devient plus rapide."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Sélection de l\'heure:\n" + +"- Cliquer sur l'une des parties du temps pour l'augmenter\n" + +"- ou Maj-clic pour le diminuer\n" + +"- ou faire un cliquer-déplacer horizontal pour une modification plus rapide."; + +Calendar._TT["PREV_YEAR"] = "Année préc. (maintenir pour afficher menu)"; +Calendar._TT["PREV_MONTH"] = "Mois préc. (maintenir pour afficher menu)"; +Calendar._TT["GO_TODAY"] = "Atteindre la date du jour"; +Calendar._TT["NEXT_MONTH"] = "Mois suiv. (maintenir pour afficher menu)"; +Calendar._TT["NEXT_YEAR"] = "Année suiv. (maintenir pour afficher menu)"; +Calendar._TT["SEL_DATE"] = "Sélectionner une date"; +Calendar._TT["DRAG_TO_MOVE"] = "Glisser pour déplacer"; +Calendar._TT["PART_TODAY"] = " (aujourd'hui)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Afficher %s en premier"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Fermer"; +Calendar._TT["TODAY"] = "Aujourd'hui"; +Calendar._TT["TIME_PART"] = "(Maj-)Clic ou glisser pour changer la valeur"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %e %B"; + +Calendar._TT["WK"] = "sem."; +Calendar._TT["TIME"] = "Heure:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-he-utf8.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-he-utf8.js new file mode 100644 index 0000000..7861217 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-he-utf8.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar EN language +// Author: Idan Sofer, +// Encoding: UTF-8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("ר×שון", + "שני", + "שלישי", + "רביעי", + "חמישי", + "שישי", + "שבת", + "ר×שון"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("×", + "ב", + "×’", + "ד", + "×”", + "ו", + "ש", + "×"); + +// full month names +Calendar._MN = new Array +("ינו×ר", + "פברו×ר", + "מרץ", + "×פריל", + "מ××™", + "יוני", + "יולי", + "×וגוסט", + "ספטמבר", + "×וקטובר", + "נובמבר", + "דצמבר"); + +// short month names +Calendar._SMN = new Array +("×™× ×", + "פבר", + "מרץ", + "×פר", + "מ××™", + "יונ", + "יול", + "×וג", + "ספט", + "×וק", + "נוב", + "דצמ"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "×ודות השנתון"; + +Calendar._TT["ABOUT"] = +"בחרן ת×ריך/שעה DHTML\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"×”×’×™×¨×¡× ×”×חרונה זמינה ב: http://www.dynarch.com/projects/calendar/\n" + +"מופץ תחת זיכיון ×” GNU LGPL. עיין ב http://gnu.org/licenses/lgpl.html ×œ×¤×¨×˜×™× × ×•×¡×¤×™×." + +"\n\n" + +בחירת ת×ריך:\n" + +"- השתמש ×‘×›×¤×ª×•×¨×™× \xab, \xbb לבחירת שנה\n" + +"- השתמש ×‘×›×¤×ª×•×¨×™× " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " לבחירת חודש\n" + +"- החזק העכבר לחוץ מעל ×”×›×¤×ª×•×¨×™× ×”×ž×•×–×›×¨×™× ×œ×¢×™×œ לבחירה מהירה יותר."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"בחירת זמן:\n" + +"- לחץ על כל ×חד מחלקי הזמן כדי להוסיף\n" + +"- ×ו shift בשילוב ×¢× ×œ×—×™×¦×” כדי להחסיר\n" + +"- ×ו לחץ וגרור לפעולה מהירה יותר."; + +Calendar._TT["PREV_YEAR"] = "שנה קודמת - החזק לקבלת תפריט"; +Calendar._TT["PREV_MONTH"] = "חודש ×§×•×“× - החזק לקבלת תפריט"; +Calendar._TT["GO_TODAY"] = "עבור להיו×"; +Calendar._TT["NEXT_MONTH"] = "חודש ×”×‘× - החזק לתפריט"; +Calendar._TT["NEXT_YEAR"] = "שנה הב××” - החזק לתפריט"; +Calendar._TT["SEL_DATE"] = "בחר ת×ריך"; +Calendar._TT["DRAG_TO_MOVE"] = "גרור להזזה"; +Calendar._TT["PART_TODAY"] = " )היו×("; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "הצג %s קוד×"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "6"; + +Calendar._TT["CLOSE"] = "סגור"; +Calendar._TT["TODAY"] = "היו×"; +Calendar._TT["TIME_PART"] = "(שיפט-)לחץ וגרור כדי לשנות ערך"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "שעה::"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-he.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-he.js new file mode 100644 index 0000000..7861217 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-he.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar EN language +// Author: Idan Sofer, +// Encoding: UTF-8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("ר×שון", + "שני", + "שלישי", + "רביעי", + "חמישי", + "שישי", + "שבת", + "ר×שון"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("×", + "ב", + "×’", + "ד", + "×”", + "ו", + "ש", + "×"); + +// full month names +Calendar._MN = new Array +("ינו×ר", + "פברו×ר", + "מרץ", + "×פריל", + "מ××™", + "יוני", + "יולי", + "×וגוסט", + "ספטמבר", + "×וקטובר", + "נובמבר", + "דצמבר"); + +// short month names +Calendar._SMN = new Array +("×™× ×", + "פבר", + "מרץ", + "×פר", + "מ××™", + "יונ", + "יול", + "×וג", + "ספט", + "×וק", + "נוב", + "דצמ"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "×ודות השנתון"; + +Calendar._TT["ABOUT"] = +"בחרן ת×ריך/שעה DHTML\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"×”×’×™×¨×¡× ×”×חרונה זמינה ב: http://www.dynarch.com/projects/calendar/\n" + +"מופץ תחת זיכיון ×” GNU LGPL. עיין ב http://gnu.org/licenses/lgpl.html ×œ×¤×¨×˜×™× × ×•×¡×¤×™×." + +"\n\n" + +בחירת ת×ריך:\n" + +"- השתמש ×‘×›×¤×ª×•×¨×™× \xab, \xbb לבחירת שנה\n" + +"- השתמש ×‘×›×¤×ª×•×¨×™× " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " לבחירת חודש\n" + +"- החזק העכבר לחוץ מעל ×”×›×¤×ª×•×¨×™× ×”×ž×•×–×›×¨×™× ×œ×¢×™×œ לבחירה מהירה יותר."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"בחירת זמן:\n" + +"- לחץ על כל ×חד מחלקי הזמן כדי להוסיף\n" + +"- ×ו shift בשילוב ×¢× ×œ×—×™×¦×” כדי להחסיר\n" + +"- ×ו לחץ וגרור לפעולה מהירה יותר."; + +Calendar._TT["PREV_YEAR"] = "שנה קודמת - החזק לקבלת תפריט"; +Calendar._TT["PREV_MONTH"] = "חודש ×§×•×“× - החזק לקבלת תפריט"; +Calendar._TT["GO_TODAY"] = "עבור להיו×"; +Calendar._TT["NEXT_MONTH"] = "חודש ×”×‘× - החזק לתפריט"; +Calendar._TT["NEXT_YEAR"] = "שנה הב××” - החזק לתפריט"; +Calendar._TT["SEL_DATE"] = "בחר ת×ריך"; +Calendar._TT["DRAG_TO_MOVE"] = "גרור להזזה"; +Calendar._TT["PART_TODAY"] = " )היו×("; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "הצג %s קוד×"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "6"; + +Calendar._TT["CLOSE"] = "סגור"; +Calendar._TT["TODAY"] = "היו×"; +Calendar._TT["TIME_PART"] = "(שיפט-)לחץ וגרור כדי לשנות ערך"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "שעה::"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hr-old.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hr-old.js new file mode 100644 index 0000000000000000000000000000000000000000..6c27f60c4f8d416145e316bdb92e455a04a26fc4 GIT binary patch literal 3088 zcmcJRZEq4$5QV3oOpN^xn|@MLX``QvFOd|BwX`K&TD8VBv|!x=g_MG!Mt{2coVhHp zKpTvj4cxc6GiS~{b9aCJT(gH3*@j(O+p2bD3I7+&G`&5u9_^Xcnfc6GbJ%NRA7TB) z#|3+172C0rd#bwCh1J+8t3EcD)@66wJ+E8Np7MLl+OpmC_<7>UTkyM$eGl6lj3p>PheZ0=Ww2=H?b(l|o^zMwpyIsrK|Sp&cKx5sS&@!9bLPe8y!ma|m&W@1t~03i zVNK_Gk(rhME=;!FTP?E|GvDK^rJ*FVQYO0UUUgnYdn=YQt!h}~kw)7*(yTJ*-gpib zZl$2fZ}$C`^OD_1B2{e9iaaHI&FIr`ue2#lE!UXvs;0s%sav4I+Bvf=`W^bqOTsRd z3#r;*y|Ms;vh5T5kb3$+n`bnQL#ow1S#y3O?q>A^Tan$T-(yY~JD^USqb_J0%v{q( z;0&xk!1v7>PB|GP+JT*2IC^s{CPfZR>2^A0^zShhL2~S;Re+-p89ZCghHfF{s#~oA zBX>BH^wbu~dKdQJ6XBS*+Pth|)R*2l^`ZCwo%I;gJZ(%PQuhB_8!;@E{O-@gRkmif zTx}=tA5^GnP#vi5TMH?#fco=PV>sz>5{FY!RGF#9LuCf#>z3-FK8=FvRSn}B)_YO4 zdX0swRHcjPqU<#(UFfcuRiD(Z+ew)YxVaYb85DMGo3=&9F`lPuK0(7(ZvHg4+4rPw zp(=4h)$5DrPt+dsC9+FSiy_EH7n6SzdjkdSk#$x*N3ImTX>`7eusHub3i#1Y&>i_0 zzeR!?rOVGAr{ytkf1BtnQ2^`agzClH9w)bhHnL||LkEvgdyD_U2*JFsr}VZ}t8b}L hPd9rmV52WTMaX%C+(ZQBcw3Zrwhfx``>it4|8LNz+, June 2003. +* Feel free to use this script under the terms of the GNU Lesser General +* Public License, as long as you do not remove or alter this notice. +*/ +Calendar._DN = new Array +("Nedjelja", + "Ponedjeljak", + "Utorak", + "Srijeda", + "ÄŒetvrtak", + "Petak", + "Subota", + "Nedjelja"); +Calendar._MN = new Array +("SijeÄanj", + "VeljaÄa", + "Ožujak", + "Travanj", + "Svibanj", + "Lipanj", + "Srpanj", + "Kolovoz", + "Rujan", + "Listopad", + "Studeni", + "Prosinac"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["TOGGLE"] = "Promjeni dan s kojim poÄinje tjedan"; +Calendar._TT["PREV_YEAR"] = "Prethodna godina (dugi pritisak za meni)"; +Calendar._TT["PREV_MONTH"] = "Prethodni mjesec (dugi pritisak za meni)"; +Calendar._TT["GO_TODAY"] = "Idi na tekući dan"; +Calendar._TT["NEXT_MONTH"] = "Slijedeći mjesec (dugi pritisak za meni)"; +Calendar._TT["NEXT_YEAR"] = "Slijedeća godina (dugi pritisak za meni)"; +Calendar._TT["SEL_DATE"] = "Izaberite datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Pritisni i povuci za promjenu pozicije"; +Calendar._TT["PART_TODAY"] = " (today)"; +Calendar._TT["MON_FIRST"] = "Prikaži ponedjeljak kao prvi dan"; +Calendar._TT["SUN_FIRST"] = "Prikaži nedjelju kao prvi dan"; +Calendar._TT["CLOSE"] = "Zatvori"; +Calendar._TT["TODAY"] = "Danas"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; +Calendar._TT["TT_DATE_FORMAT"] = "DD, dd.mm.y"; + +Calendar._TT["WK"] = "Tje"; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hr.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hr.js new file mode 100644 index 0000000..d569cfd --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hr.js @@ -0,0 +1,49 @@ +/* Croatian language file for the DHTML Calendar version 0.9.2 +* Author Krunoslav Zubrinic , June 2003. +* Feel free to use this script under the terms of the GNU Lesser General +* Public License, as long as you do not remove or alter this notice. +*/ +Calendar._DN = new Array +("Nedjelja", + "Ponedjeljak", + "Utorak", + "Srijeda", + "ÄŒetvrtak", + "Petak", + "Subota", + "Nedjelja"); +Calendar._MN = new Array +("SijeÄanj", + "VeljaÄa", + "Ožujak", + "Travanj", + "Svibanj", + "Lipanj", + "Srpanj", + "Kolovoz", + "Rujan", + "Listopad", + "Studeni", + "Prosinac"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["TOGGLE"] = "Promjeni dan s kojim poÄinje tjedan"; +Calendar._TT["PREV_YEAR"] = "Prethodna godina (dugi pritisak za meni)"; +Calendar._TT["PREV_MONTH"] = "Prethodni mjesec (dugi pritisak za meni)"; +Calendar._TT["GO_TODAY"] = "Idi na tekući dan"; +Calendar._TT["NEXT_MONTH"] = "Slijedeći mjesec (dugi pritisak za meni)"; +Calendar._TT["NEXT_YEAR"] = "Slijedeća godina (dugi pritisak za meni)"; +Calendar._TT["SEL_DATE"] = "Izaberite datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Pritisni i povuci za promjenu pozicije"; +Calendar._TT["PART_TODAY"] = " (today)"; +Calendar._TT["MON_FIRST"] = "Prikaži ponedjeljak kao prvi dan"; +Calendar._TT["SUN_FIRST"] = "Prikaži nedjelju kao prvi dan"; +Calendar._TT["CLOSE"] = "Zatvori"; +Calendar._TT["TODAY"] = "Danas"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; +Calendar._TT["TT_DATE_FORMAT"] = "DD, dd.mm.y"; + +Calendar._TT["WK"] = "Tje"; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hu.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hu.js new file mode 100644 index 0000000..f5bf057 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-hu.js @@ -0,0 +1,124 @@ +// ** I18N + +// Calendar HU language +// Author: ??? +// Modifier: KARASZI Istvan, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Vasárnap", + "Hétfõ", + "Kedd", + "Szerda", + "Csütörtök", + "Péntek", + "Szombat", + "Vasárnap"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("v", + "h", + "k", + "sze", + "cs", + "p", + "szo", + "v"); + +// full month names +Calendar._MN = new Array +("január", + "február", + "március", + "április", + "május", + "június", + "július", + "augusztus", + "szeptember", + "október", + "november", + "december"); + +// short month names +Calendar._SMN = new Array +("jan", + "feb", + "már", + "ápr", + "máj", + "jún", + "júl", + "aug", + "sze", + "okt", + "nov", + "dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "A kalendáriumról"; + +Calendar._TT["ABOUT"] = +"DHTML dátum/idõ kiválasztó\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"a legfrissebb verzió megtalálható: http://www.dynarch.com/projects/calendar/\n" + +"GNU LGPL alatt terjesztve. Lásd a http://gnu.org/licenses/lgpl.html oldalt a részletekhez." + +"\n\n" + +"Dátum választás:\n" + +"- használja a \xab, \xbb gombokat az év kiválasztásához\n" + +"- használja a " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " gombokat a hónap kiválasztásához\n" + +"- tartsa lenyomva az egérgombot a gyors választáshoz."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Idõ választás:\n" + +"- kattintva növelheti az idõt\n" + +"- shift-tel kattintva csökkentheti\n" + +"- lenyomva tartva és húzva gyorsabban kiválaszthatja."; + +Calendar._TT["PREV_YEAR"] = "Elõzõ év (tartsa nyomva a menühöz)"; +Calendar._TT["PREV_MONTH"] = "Elõzõ hónap (tartsa nyomva a menühöz)"; +Calendar._TT["GO_TODAY"] = "Mai napra ugrás"; +Calendar._TT["NEXT_MONTH"] = "Köv. hónap (tartsa nyomva a menühöz)"; +Calendar._TT["NEXT_YEAR"] = "Köv. év (tartsa nyomva a menühöz)"; +Calendar._TT["SEL_DATE"] = "Válasszon dátumot"; +Calendar._TT["DRAG_TO_MOVE"] = "Húzza a mozgatáshoz"; +Calendar._TT["PART_TODAY"] = " (ma)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "%s legyen a hét elsõ napja"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Bezár"; +Calendar._TT["TODAY"] = "Ma"; +Calendar._TT["TIME_PART"] = "(Shift-)Klikk vagy húzás az érték változtatásához"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%b %e, %a"; + +Calendar._TT["WK"] = "hét"; +Calendar._TT["TIME"] = "idõ:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-it.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-it.js new file mode 100644 index 0000000..7f84cde --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-it.js @@ -0,0 +1,124 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Translator: Fabio Di Bernardini, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Domenica", + "Lunedì", + "Martedì", + "Mercoledì", + "Giovedì", + "Venerdì", + "Sabato", + "Domenica"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Dom", + "Lun", + "Mar", + "Mer", + "Gio", + "Ven", + "Sab", + "Dom"); + +// full month names +Calendar._MN = new Array +("Gennaio", + "Febbraio", + "Marzo", + "Aprile", + "Maggio", + "Giugno", + "Luglio", + "Augosto", + "Settembre", + "Ottobre", + "Novembre", + "Dicembre"); + +// short month names +Calendar._SMN = new Array +("Gen", + "Feb", + "Mar", + "Apr", + "Mag", + "Giu", + "Lug", + "Ago", + "Set", + "Ott", + "Nov", + "Dic"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Informazioni sul calendario"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Per gli aggiornamenti: http://www.dynarch.com/projects/calendar/\n" + +"Distribuito sotto licenza GNU LGPL. Vedi http://gnu.org/licenses/lgpl.html per i dettagli." + +"\n\n" + +"Selezione data:\n" + +"- Usa \xab, \xbb per selezionare l'anno\n" + +"- Usa " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per i mesi\n" + +"- Tieni premuto a lungo il mouse per accedere alle funzioni di selezione veloce."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Selezione orario:\n" + +"- Clicca sul numero per incrementarlo\n" + +"- o Shift+click per decrementarlo\n" + +"- o click e sinistra o destra per variarlo."; + +Calendar._TT["PREV_YEAR"] = "Anno prec.(clicca a lungo per il menù)"; +Calendar._TT["PREV_MONTH"] = "Mese prec. (clicca a lungo per il menù)"; +Calendar._TT["GO_TODAY"] = "Oggi"; +Calendar._TT["NEXT_MONTH"] = "Pross. mese (clicca a lungo per il menù)"; +Calendar._TT["NEXT_YEAR"] = "Pross. anno (clicca a lungo per il menù)"; +Calendar._TT["SEL_DATE"] = "Seleziona data"; +Calendar._TT["DRAG_TO_MOVE"] = "Trascina per spostarlo"; +Calendar._TT["PART_TODAY"] = " (oggi)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Mostra prima %s"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Chiudi"; +Calendar._TT["TODAY"] = "Oggi"; +Calendar._TT["TIME_PART"] = "(Shift-)Click o trascina per cambiare il valore"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a:%b:%e"; + +Calendar._TT["WK"] = "set"; +Calendar._TT["TIME"] = "Ora:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-jp.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-jp.js new file mode 100644 index 0000000..3bca7eb --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-jp.js @@ -0,0 +1,45 @@ +// ** I18N +Calendar._DN = new Array +("“ú", + "ŒŽ", + "‰Î", + "…", + "–Ø", + "‹à", + "“y", + "“ú"); +Calendar._MN = new Array +("1ŒŽ", + "2ŒŽ", + "3ŒŽ", + "4ŒŽ", + "5ŒŽ", + "6ŒŽ", + "7ŒŽ", + "8ŒŽ", + "9ŒŽ", + "10ŒŽ", + "11ŒŽ", + "12ŒŽ"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["TOGGLE"] = "T‚Ìʼn‚Ì—j“ú‚ðØ‚è‘Ö‚¦"; +Calendar._TT["PREV_YEAR"] = "‘O”N"; +Calendar._TT["PREV_MONTH"] = "‘OŒŽ"; +Calendar._TT["GO_TODAY"] = "¡“ú"; +Calendar._TT["NEXT_MONTH"] = "—‚ŒŽ"; +Calendar._TT["NEXT_YEAR"] = "—‚”N"; +Calendar._TT["SEL_DATE"] = "“ú•t‘I‘ð"; +Calendar._TT["DRAG_TO_MOVE"] = "ƒEƒBƒ“ƒhƒE‚̈ړ®"; +Calendar._TT["PART_TODAY"] = " (¡“ú)"; +Calendar._TT["MON_FIRST"] = "ŒŽ—j“ú‚ð擪‚É"; +Calendar._TT["SUN_FIRST"] = "“ú—j“ú‚ð擪‚É"; +Calendar._TT["CLOSE"] = "•Â‚¶‚é"; +Calendar._TT["TODAY"] = "¡“ú"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "y-mm-dd"; +Calendar._TT["TT_DATE_FORMAT"] = "%mŒŽ %d“ú (%a)"; + +Calendar._TT["WK"] = "T"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko-utf8.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko-utf8.js new file mode 100644 index 0000000..035dd74 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko-utf8.js @@ -0,0 +1,120 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Translation: Yourim Yi +// Encoding: EUC-KR +// lang : ko +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names + +Calendar._DN = new Array +("ì¼ìš”ì¼", + "월요ì¼", + "화요ì¼", + "수요ì¼", + "목요ì¼", + "금요ì¼", + "토요ì¼", + "ì¼ìš”ì¼"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("ì¼", + "ì›”", + "í™”", + "수", + "목", + "금", + "토", + "ì¼"); + +// full month names +Calendar._MN = new Array +("1ì›”", + "2ì›”", + "3ì›”", + "4ì›”", + "5ì›”", + "6ì›”", + "7ì›”", + "8ì›”", + "9ì›”", + "10ì›”", + "11ì›”", + "12ì›”"); + +// short month names +Calendar._SMN = new Array +("1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "calendar ì— ëŒ€í•´ì„œ"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"\n"+ +"최신 ë²„ì „ì„ ë°›ìœ¼ì‹œë ¤ë©´ http://www.dynarch.com/projects/calendar/ ì— ë°©ë¬¸í•˜ì„¸ìš”\n" + +"\n"+ +"GNU LGPL ë¼ì´ì„¼ìŠ¤ë¡œ ë°°í¬ë©ë‹ˆë‹¤. \n"+ +"ë¼ì´ì„¼ìŠ¤ì— 대한 ìžì„¸í•œ ë‚´ìš©ì€ http://gnu.org/licenses/lgpl.html ì„ ì½ìœ¼ì„¸ìš”." + +"\n\n" + +"날짜 ì„ íƒ:\n" + +"- ì—°ë„를 ì„ íƒí•˜ë ¤ë©´ \xab, \xbb ë²„íŠ¼ì„ ì‚¬ìš©í•©ë‹ˆë‹¤\n" + +"- ë‹¬ì„ ì„ íƒí•˜ë ¤ë©´ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ë²„íŠ¼ì„ ëˆ„ë¥´ì„¸ìš”\n" + +"- ê³„ì† ëˆ„ë¥´ê³  있으면 위 ê°’ë“¤ì„ ë¹ ë¥´ê²Œ ì„ íƒí•˜ì‹¤ 수 있습니다."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"시간 ì„ íƒ:\n" + +"- 마우스로 누르면 ì‹œê°„ì´ ì¦ê°€í•©ë‹ˆë‹¤\n" + +"- Shift 키와 함께 누르면 ê°ì†Œí•©ë‹ˆë‹¤\n" + +"- 누른 ìƒíƒœì—ì„œ 마우스를 움ì§ì´ë©´ 좀 ë” ë¹ ë¥´ê²Œ ê°’ì´ ë³€í•©ë‹ˆë‹¤.\n"; + +Calendar._TT["PREV_YEAR"] = "지난 í•´ (길게 누르면 목ë¡)"; +Calendar._TT["PREV_MONTH"] = "지난 달 (길게 누르면 목ë¡)"; +Calendar._TT["GO_TODAY"] = "오늘 날짜로"; +Calendar._TT["NEXT_MONTH"] = "ë‹¤ìŒ ë‹¬ (길게 누르면 목ë¡)"; +Calendar._TT["NEXT_YEAR"] = "ë‹¤ìŒ í•´ (길게 누르면 목ë¡)"; +Calendar._TT["SEL_DATE"] = "날짜를 ì„ íƒí•˜ì„¸ìš”"; +Calendar._TT["DRAG_TO_MOVE"] = "마우스 드래그로 ì´ë™ 하세요"; +Calendar._TT["PART_TODAY"] = " (오늘)"; +Calendar._TT["MON_FIRST"] = "월요ì¼ì„ í•œ ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ"; +Calendar._TT["SUN_FIRST"] = "ì¼ìš”ì¼ì„ í•œ ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ"; +Calendar._TT["CLOSE"] = "닫기"; +Calendar._TT["TODAY"] = "오늘"; +Calendar._TT["TIME_PART"] = "(Shift-)í´ë¦­ ë˜ëŠ” 드래그 하세요"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%b/%e [%a]"; + +Calendar._TT["WK"] = "주"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko.js new file mode 100644 index 0000000..035dd74 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko.js @@ -0,0 +1,120 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Translation: Yourim Yi +// Encoding: EUC-KR +// lang : ko +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names + +Calendar._DN = new Array +("ì¼ìš”ì¼", + "월요ì¼", + "화요ì¼", + "수요ì¼", + "목요ì¼", + "금요ì¼", + "토요ì¼", + "ì¼ìš”ì¼"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("ì¼", + "ì›”", + "í™”", + "수", + "목", + "금", + "토", + "ì¼"); + +// full month names +Calendar._MN = new Array +("1ì›”", + "2ì›”", + "3ì›”", + "4ì›”", + "5ì›”", + "6ì›”", + "7ì›”", + "8ì›”", + "9ì›”", + "10ì›”", + "11ì›”", + "12ì›”"); + +// short month names +Calendar._SMN = new Array +("1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "calendar ì— ëŒ€í•´ì„œ"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"\n"+ +"최신 ë²„ì „ì„ ë°›ìœ¼ì‹œë ¤ë©´ http://www.dynarch.com/projects/calendar/ ì— ë°©ë¬¸í•˜ì„¸ìš”\n" + +"\n"+ +"GNU LGPL ë¼ì´ì„¼ìŠ¤ë¡œ ë°°í¬ë©ë‹ˆë‹¤. \n"+ +"ë¼ì´ì„¼ìŠ¤ì— 대한 ìžì„¸í•œ ë‚´ìš©ì€ http://gnu.org/licenses/lgpl.html ì„ ì½ìœ¼ì„¸ìš”." + +"\n\n" + +"날짜 ì„ íƒ:\n" + +"- ì—°ë„를 ì„ íƒí•˜ë ¤ë©´ \xab, \xbb ë²„íŠ¼ì„ ì‚¬ìš©í•©ë‹ˆë‹¤\n" + +"- ë‹¬ì„ ì„ íƒí•˜ë ¤ë©´ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ë²„íŠ¼ì„ ëˆ„ë¥´ì„¸ìš”\n" + +"- ê³„ì† ëˆ„ë¥´ê³  있으면 위 ê°’ë“¤ì„ ë¹ ë¥´ê²Œ ì„ íƒí•˜ì‹¤ 수 있습니다."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"시간 ì„ íƒ:\n" + +"- 마우스로 누르면 ì‹œê°„ì´ ì¦ê°€í•©ë‹ˆë‹¤\n" + +"- Shift 키와 함께 누르면 ê°ì†Œí•©ë‹ˆë‹¤\n" + +"- 누른 ìƒíƒœì—ì„œ 마우스를 움ì§ì´ë©´ 좀 ë” ë¹ ë¥´ê²Œ ê°’ì´ ë³€í•©ë‹ˆë‹¤.\n"; + +Calendar._TT["PREV_YEAR"] = "지난 í•´ (길게 누르면 목ë¡)"; +Calendar._TT["PREV_MONTH"] = "지난 달 (길게 누르면 목ë¡)"; +Calendar._TT["GO_TODAY"] = "오늘 날짜로"; +Calendar._TT["NEXT_MONTH"] = "ë‹¤ìŒ ë‹¬ (길게 누르면 목ë¡)"; +Calendar._TT["NEXT_YEAR"] = "ë‹¤ìŒ í•´ (길게 누르면 목ë¡)"; +Calendar._TT["SEL_DATE"] = "날짜를 ì„ íƒí•˜ì„¸ìš”"; +Calendar._TT["DRAG_TO_MOVE"] = "마우스 드래그로 ì´ë™ 하세요"; +Calendar._TT["PART_TODAY"] = " (오늘)"; +Calendar._TT["MON_FIRST"] = "월요ì¼ì„ í•œ ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ"; +Calendar._TT["SUN_FIRST"] = "ì¼ìš”ì¼ì„ í•œ ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ"; +Calendar._TT["CLOSE"] = "닫기"; +Calendar._TT["TODAY"] = "오늘"; +Calendar._TT["TIME_PART"] = "(Shift-)í´ë¦­ ë˜ëŠ” 드래그 하세요"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%b/%e [%a]"; + +Calendar._TT["WK"] = "주"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko.old.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko.old.js new file mode 100644 index 0000000..8cddf58 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ko.old.js @@ -0,0 +1,120 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Translation: Yourim Yi +// Encoding: EUC-KR +// lang : ko +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names + +Calendar._DN = new Array +("ÀÏ¿äÀÏ", + "¿ù¿äÀÏ", + "È­¿äÀÏ", + "¼ö¿äÀÏ", + "¸ñ¿äÀÏ", + "±Ý¿äÀÏ", + "Åä¿äÀÏ", + "ÀÏ¿äÀÏ"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("ÀÏ", + "¿ù", + "È­", + "¼ö", + "¸ñ", + "±Ý", + "Åä", + "ÀÏ"); + +// full month names +Calendar._MN = new Array +("1¿ù", + "2¿ù", + "3¿ù", + "4¿ù", + "5¿ù", + "6¿ù", + "7¿ù", + "8¿ù", + "9¿ù", + "10¿ù", + "11¿ù", + "12¿ù"); + +// short month names +Calendar._SMN = new Array +("1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "calendar ¿¡ ´ëÇؼ­"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"\n"+ +"ÃֽŠ¹öÀüÀ» ¹ÞÀ¸½Ã·Á¸é http://www.dynarch.com/projects/calendar/ ¿¡ ¹æ¹®Çϼ¼¿ä\n" + +"\n"+ +"GNU LGPL ¶óÀ̼¾½º·Î ¹èÆ÷µË´Ï´Ù. \n"+ +"¶óÀ̼¾½º¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº http://gnu.org/licenses/lgpl.html À» ÀÐÀ¸¼¼¿ä." + +"\n\n" + +"³¯Â¥ ¼±ÅÃ:\n" + +"- ¿¬µµ¸¦ ¼±ÅÃÇÏ·Á¸é \xab, \xbb ¹öÆ°À» »ç¿ëÇÕ´Ï´Ù\n" + +"- ´ÞÀ» ¼±ÅÃÇÏ·Á¸é " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ¹öÆ°À» ´©¸£¼¼¿ä\n" + +"- °è¼Ó ´©¸£°í ÀÖÀ¸¸é À§ °ªµéÀ» ºü¸£°Ô ¼±ÅÃÇÏ½Ç ¼ö ÀÖ½À´Ï´Ù."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"½Ã°£ ¼±ÅÃ:\n" + +"- ¸¶¿ì½º·Î ´©¸£¸é ½Ã°£ÀÌ Áõ°¡ÇÕ´Ï´Ù\n" + +"- Shift Å°¿Í ÇÔ²² ´©¸£¸é °¨¼ÒÇÕ´Ï´Ù\n" + +"- ´©¸¥ »óÅ¿¡¼­ ¸¶¿ì½º¸¦ ¿òÁ÷À̸é Á» ´õ ºü¸£°Ô °ªÀÌ º¯ÇÕ´Ï´Ù.\n"; + +Calendar._TT["PREV_YEAR"] = "Áö³­ ÇØ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; +Calendar._TT["PREV_MONTH"] = "Áö³­ ´Þ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; +Calendar._TT["GO_TODAY"] = "¿À´Ã ³¯Â¥·Î"; +Calendar._TT["NEXT_MONTH"] = "´ÙÀ½ ´Þ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; +Calendar._TT["NEXT_YEAR"] = "´ÙÀ½ ÇØ (±æ°Ô ´©¸£¸é ¸ñ·Ï)"; +Calendar._TT["SEL_DATE"] = "³¯Â¥¸¦ ¼±ÅÃÇϼ¼¿ä"; +Calendar._TT["DRAG_TO_MOVE"] = "¸¶¿ì½º µå·¡±×·Î À̵¿ Çϼ¼¿ä"; +Calendar._TT["PART_TODAY"] = " (¿À´Ã)"; +Calendar._TT["MON_FIRST"] = "¿ù¿äÀÏÀ» ÇÑ ÁÖÀÇ ½ÃÀÛ ¿äÀÏ·Î"; +Calendar._TT["SUN_FIRST"] = "ÀÏ¿äÀÏÀ» ÇÑ ÁÖÀÇ ½ÃÀÛ ¿äÀÏ·Î"; +Calendar._TT["CLOSE"] = "´Ý±â"; +Calendar._TT["TODAY"] = "¿À´Ã"; +Calendar._TT["TIME_PART"] = "(Shift-)Ŭ¸¯ ¶Ç´Â µå·¡±× Çϼ¼¿ä"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%b/%e [%a]"; + +Calendar._TT["WK"] = "ÁÖ"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt-utf8.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt-utf8.js new file mode 100644 index 0000000..d39653b --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt-utf8.js @@ -0,0 +1,114 @@ +// ** I18N + +// Calendar LT language +// Author: Martynas Majeris, +// Encoding: UTF-8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Sekmadienis", + "Pirmadienis", + "Antradienis", + "TreÄiadienis", + "Ketvirtadienis", + "Pentadienis", + "Å eÅ¡tadienis", + "Sekmadienis"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Sek", + "Pir", + "Ant", + "Tre", + "Ket", + "Pen", + "Å eÅ¡", + "Sek"); + +// full month names +Calendar._MN = new Array +("Sausis", + "Vasaris", + "Kovas", + "Balandis", + "Gegužė", + "Birželis", + "Liepa", + "RugpjÅ«tis", + "RugsÄ—jis", + "Spalis", + "Lapkritis", + "Gruodis"); + +// short month names +Calendar._SMN = new Array +("Sau", + "Vas", + "Kov", + "Bal", + "Geg", + "Bir", + "Lie", + "Rgp", + "Rgs", + "Spa", + "Lap", + "Gru"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Apie kalendorių"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"NaujausiÄ… versijÄ… rasite: http://www.dynarch.com/projects/calendar/\n" + +"Platinamas pagal GNU LGPL licencijÄ…. Aplankykite http://gnu.org/licenses/lgpl.html" + +"\n\n" + +"Datos pasirinkimas:\n" + +"- Metų pasirinkimas: \xab, \xbb\n" + +"- MÄ—nesio pasirinkimas: " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" + +"- Nuspauskite ir laikykite pelÄ—s klaviÅ¡Ä… greitesniam pasirinkimui."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Laiko pasirinkimas:\n" + +"- Spustelkite ant valandų arba minuÄių - skaiÄius padidÄ—s vienetu.\n" + +"- Jei spausite kartu su Shift, skaiÄius sumažės.\n" + +"- Greitam pasirinkimui spustelkite ir pajudinkite pelÄ™."; + +Calendar._TT["PREV_YEAR"] = "Ankstesni metai (laikykite, jei norite meniu)"; +Calendar._TT["PREV_MONTH"] = "Ankstesnis mÄ—nuo (laikykite, jei norite meniu)"; +Calendar._TT["GO_TODAY"] = "Pasirinkti Å¡iandienÄ…"; +Calendar._TT["NEXT_MONTH"] = "Kitas mÄ—nuo (laikykite, jei norite meniu)"; +Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikykite, jei norite meniu)"; +Calendar._TT["SEL_DATE"] = "Pasirinkite datÄ…"; +Calendar._TT["DRAG_TO_MOVE"] = "Tempkite"; +Calendar._TT["PART_TODAY"] = " (Å¡iandien)"; +Calendar._TT["MON_FIRST"] = "Pirma savaitÄ—s diena - pirmadienis"; +Calendar._TT["SUN_FIRST"] = "Pirma savaitÄ—s diena - sekmadienis"; +Calendar._TT["CLOSE"] = "Uždaryti"; +Calendar._TT["TODAY"] = "Å iandien"; +Calendar._TT["TIME_PART"] = "Spustelkite arba tempkite jei norite pakeisti"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %Y-%m-%d"; + +Calendar._TT["WK"] = "sav"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt.js new file mode 100644 index 0000000..d39653b --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt.js @@ -0,0 +1,114 @@ +// ** I18N + +// Calendar LT language +// Author: Martynas Majeris, +// Encoding: UTF-8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Sekmadienis", + "Pirmadienis", + "Antradienis", + "TreÄiadienis", + "Ketvirtadienis", + "Pentadienis", + "Å eÅ¡tadienis", + "Sekmadienis"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Sek", + "Pir", + "Ant", + "Tre", + "Ket", + "Pen", + "Å eÅ¡", + "Sek"); + +// full month names +Calendar._MN = new Array +("Sausis", + "Vasaris", + "Kovas", + "Balandis", + "Gegužė", + "Birželis", + "Liepa", + "RugpjÅ«tis", + "RugsÄ—jis", + "Spalis", + "Lapkritis", + "Gruodis"); + +// short month names +Calendar._SMN = new Array +("Sau", + "Vas", + "Kov", + "Bal", + "Geg", + "Bir", + "Lie", + "Rgp", + "Rgs", + "Spa", + "Lap", + "Gru"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Apie kalendorių"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"NaujausiÄ… versijÄ… rasite: http://www.dynarch.com/projects/calendar/\n" + +"Platinamas pagal GNU LGPL licencijÄ…. Aplankykite http://gnu.org/licenses/lgpl.html" + +"\n\n" + +"Datos pasirinkimas:\n" + +"- Metų pasirinkimas: \xab, \xbb\n" + +"- MÄ—nesio pasirinkimas: " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" + +"- Nuspauskite ir laikykite pelÄ—s klaviÅ¡Ä… greitesniam pasirinkimui."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Laiko pasirinkimas:\n" + +"- Spustelkite ant valandų arba minuÄių - skaiÄius padidÄ—s vienetu.\n" + +"- Jei spausite kartu su Shift, skaiÄius sumažės.\n" + +"- Greitam pasirinkimui spustelkite ir pajudinkite pelÄ™."; + +Calendar._TT["PREV_YEAR"] = "Ankstesni metai (laikykite, jei norite meniu)"; +Calendar._TT["PREV_MONTH"] = "Ankstesnis mÄ—nuo (laikykite, jei norite meniu)"; +Calendar._TT["GO_TODAY"] = "Pasirinkti Å¡iandienÄ…"; +Calendar._TT["NEXT_MONTH"] = "Kitas mÄ—nuo (laikykite, jei norite meniu)"; +Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikykite, jei norite meniu)"; +Calendar._TT["SEL_DATE"] = "Pasirinkite datÄ…"; +Calendar._TT["DRAG_TO_MOVE"] = "Tempkite"; +Calendar._TT["PART_TODAY"] = " (Å¡iandien)"; +Calendar._TT["MON_FIRST"] = "Pirma savaitÄ—s diena - pirmadienis"; +Calendar._TT["SUN_FIRST"] = "Pirma savaitÄ—s diena - sekmadienis"; +Calendar._TT["CLOSE"] = "Uždaryti"; +Calendar._TT["TODAY"] = "Å iandien"; +Calendar._TT["TIME_PART"] = "Spustelkite arba tempkite jei norite pakeisti"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %Y-%m-%d"; + +Calendar._TT["WK"] = "sav"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt.old.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt.old.js new file mode 100644 index 0000000..43b93d6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lt.old.js @@ -0,0 +1,114 @@ +// ** I18N + +// Calendar LT language +// Author: Martynas Majeris, +// Encoding: Windows-1257 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Sekmadienis", + "Pirmadienis", + "Antradienis", + "Treèiadienis", + "Ketvirtadienis", + "Pentadienis", + "Ðeðtadienis", + "Sekmadienis"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Sek", + "Pir", + "Ant", + "Tre", + "Ket", + "Pen", + "Ðeð", + "Sek"); + +// full month names +Calendar._MN = new Array +("Sausis", + "Vasaris", + "Kovas", + "Balandis", + "Geguþë", + "Birþelis", + "Liepa", + "Rugpjûtis", + "Rugsëjis", + "Spalis", + "Lapkritis", + "Gruodis"); + +// short month names +Calendar._SMN = new Array +("Sau", + "Vas", + "Kov", + "Bal", + "Geg", + "Bir", + "Lie", + "Rgp", + "Rgs", + "Spa", + "Lap", + "Gru"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Apie kalendoriø"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Naujausià versijà rasite: http://www.dynarch.com/projects/calendar/\n" + +"Platinamas pagal GNU LGPL licencijà. Aplankykite http://gnu.org/licenses/lgpl.html" + +"\n\n" + +"Datos pasirinkimas:\n" + +"- Metø pasirinkimas: \xab, \xbb\n" + +"- Mënesio pasirinkimas: " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" + +"- Nuspauskite ir laikykite pelës klaviðà greitesniam pasirinkimui."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Laiko pasirinkimas:\n" + +"- Spustelkite ant valandø arba minuèiø - skaièus padidës vienetu.\n" + +"- Jei spausite kartu su Shift, skaièius sumaþës.\n" + +"- Greitam pasirinkimui spustelkite ir pajudinkite pelæ."; + +Calendar._TT["PREV_YEAR"] = "Ankstesni metai (laikykite, jei norite meniu)"; +Calendar._TT["PREV_MONTH"] = "Ankstesnis mënuo (laikykite, jei norite meniu)"; +Calendar._TT["GO_TODAY"] = "Pasirinkti ðiandienà"; +Calendar._TT["NEXT_MONTH"] = "Kitas mënuo (laikykite, jei norite meniu)"; +Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikykite, jei norite meniu)"; +Calendar._TT["SEL_DATE"] = "Pasirinkite datà"; +Calendar._TT["DRAG_TO_MOVE"] = "Tempkite"; +Calendar._TT["PART_TODAY"] = " (ðiandien)"; +Calendar._TT["MON_FIRST"] = "Pirma savaitës diena - pirmadienis"; +Calendar._TT["SUN_FIRST"] = "Pirma savaitës diena - sekmadienis"; +Calendar._TT["CLOSE"] = "Uþdaryti"; +Calendar._TT["TODAY"] = "Ðiandien"; +Calendar._TT["TIME_PART"] = "Spustelkite arba tempkite jei norite pakeisti"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %Y-%m-%d"; + +Calendar._TT["WK"] = "sav"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lv.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lv.js new file mode 100644 index 0000000..407699d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-lv.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar LV language +// Author: Juris Valdovskis, +// Encoding: cp1257 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Svçtdiena", + "Pirmdiena", + "Otrdiena", + "Treðdiena", + "Ceturdiena", + "Piektdiena", + "Sestdiena", + "Svçtdiena"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Sv", + "Pr", + "Ot", + "Tr", + "Ce", + "Pk", + "Se", + "Sv"); + +// full month names +Calendar._MN = new Array +("Janvâris", + "Februâris", + "Marts", + "Aprîlis", + "Maijs", + "Jûnijs", + "Jûlijs", + "Augusts", + "Septembris", + "Oktobris", + "Novembris", + "Decembris"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Feb", + "Mar", + "Apr", + "Mai", + "Jûn", + "Jûl", + "Aug", + "Sep", + "Okt", + "Nov", + "Dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Par kalendâru"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Datuma izvçle:\n" + +"- Izmanto \xab, \xbb pogas, lai izvçlçtos gadu\n" + +"- Izmanto " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "pogas, lai izvçlçtos mçnesi\n" + +"- Turi nospiestu peles pogu uz jebkuru no augstâk minçtajâm pogâm, lai paâtrinâtu izvçli."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Laika izvçle:\n" + +"- Uzklikðíini uz jebkuru no laika daïâm, lai palielinâtu to\n" + +"- vai Shift-klikðíis, lai samazinâtu to\n" + +"- vai noklikðíini un velc uz attiecîgo virzienu lai mainîtu âtrâk."; + +Calendar._TT["PREV_YEAR"] = "Iepr. gads (turi izvçlnei)"; +Calendar._TT["PREV_MONTH"] = "Iepr. mçnesis (turi izvçlnei)"; +Calendar._TT["GO_TODAY"] = "Ðodien"; +Calendar._TT["NEXT_MONTH"] = "Nâkoðais mçnesis (turi izvçlnei)"; +Calendar._TT["NEXT_YEAR"] = "Nâkoðais gads (turi izvçlnei)"; +Calendar._TT["SEL_DATE"] = "Izvçlies datumu"; +Calendar._TT["DRAG_TO_MOVE"] = "Velc, lai pârvietotu"; +Calendar._TT["PART_TODAY"] = " (ðodien)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Attçlot %s kâ pirmo"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "1,7"; + +Calendar._TT["CLOSE"] = "Aizvçrt"; +Calendar._TT["TODAY"] = "Ðodien"; +Calendar._TT["TIME_PART"] = "(Shift-)Klikðíis vai pârvieto, lai mainîtu"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Laiks:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-nl.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-nl.js new file mode 100644 index 0000000..a1dea94 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-nl.js @@ -0,0 +1,73 @@ +// ** I18N +Calendar._DN = new Array +("Zondag", + "Maandag", + "Dinsdag", + "Woensdag", + "Donderdag", + "Vrijdag", + "Zaterdag", + "Zondag"); + +Calendar._SDN_len = 2; + +Calendar._MN = new Array +("Januari", + "Februari", + "Maart", + "April", + "Mei", + "Juni", + "Juli", + "Augustus", + "September", + "Oktober", + "November", + "December"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Info"; + +Calendar._TT["ABOUT"] = +"DHTML Datum/Tijd Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + +"Ga voor de meest recente versie naar: http://www.dynarch.com/projects/calendar/\n" + +"Verspreid onder de GNU LGPL. Zie http://gnu.org/licenses/lgpl.html voor details." + +"\n\n" + +"Datum selectie:\n" + +"- Gebruik de \xab \xbb knoppen om een jaar te selecteren\n" + +"- Gebruik de " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knoppen om een maand te selecteren\n" + +"- Houd de muis ingedrukt op de genoemde knoppen voor een snellere selectie."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Tijd selectie:\n" + +"- Klik op een willekeurig onderdeel van het tijd gedeelte om het te verhogen\n" + +"- of Shift-klik om het te verlagen\n" + +"- of klik en sleep voor een snellere selectie."; + +//Calendar._TT["TOGGLE"] = "Selecteer de eerste week-dag"; +Calendar._TT["PREV_YEAR"] = "Vorig jaar (ingedrukt voor menu)"; +Calendar._TT["PREV_MONTH"] = "Vorige maand (ingedrukt voor menu)"; +Calendar._TT["GO_TODAY"] = "Ga naar Vandaag"; +Calendar._TT["NEXT_MONTH"] = "Volgende maand (ingedrukt voor menu)"; +Calendar._TT["NEXT_YEAR"] = "Volgend jaar (ingedrukt voor menu)"; +Calendar._TT["SEL_DATE"] = "Selecteer datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Klik en sleep om te verplaatsen"; +Calendar._TT["PART_TODAY"] = " (vandaag)"; +//Calendar._TT["MON_FIRST"] = "Toon Maandag eerst"; +//Calendar._TT["SUN_FIRST"] = "Toon Zondag eerst"; + +Calendar._TT["DAY_FIRST"] = "Toon %s eerst"; + +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Sluiten"; +Calendar._TT["TODAY"] = "(vandaag)"; +Calendar._TT["TIME_PART"] = "(Shift-)Klik of sleep om de waarde te veranderen"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b %Y"; + +Calendar._TT["WK"] = "wk"; +Calendar._TT["TIME"] = "Tijd:"; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-no.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-no.js new file mode 100644 index 0000000..d9297d1 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-no.js @@ -0,0 +1,114 @@ +// ** I18N + +// Calendar NO language +// Author: Daniel Holmen, +// Encoding: UTF-8 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Søndag", + "Mandag", + "Tirsdag", + "Onsdag", + "Torsdag", + "Fredag", + "Lørdag", + "Søndag"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Søn", + "Man", + "Tir", + "Ons", + "Tor", + "Fre", + "Lør", + "Søn"); + +// full month names +Calendar._MN = new Array +("Januar", + "Februar", + "Mars", + "April", + "Mai", + "Juni", + "Juli", + "August", + "September", + "Oktober", + "November", + "Desember"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Feb", + "Mar", + "Apr", + "Mai", + "Jun", + "Jul", + "Aug", + "Sep", + "Okt", + "Nov", + "Des"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Om kalenderen"; + +Calendar._TT["ABOUT"] = +"DHTML Dato-/Tidsvelger\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For nyeste versjon, gÃ¥ til: http://www.dynarch.com/projects/calendar/\n" + +"Distribuert under GNU LGPL. Se http://gnu.org/licenses/lgpl.html for detaljer." + +"\n\n" + +"Datovalg:\n" + +"- Bruk knappene \xab og \xbb for Ã¥ velge Ã¥r\n" + +"- Bruk knappene " + String.fromCharCode(0x2039) + " og " + String.fromCharCode(0x203a) + " for Ã¥ velge mÃ¥ned\n" + +"- Hold inne musknappen eller knappene over for raskere valg."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Tidsvalg:\n" + +"- Klikk pÃ¥ en av tidsdelene for Ã¥ øke den\n" + +"- eller Shift-klikk for Ã¥ senke verdien\n" + +"- eller klikk-og-dra for raskere valg.."; + +Calendar._TT["PREV_YEAR"] = "Forrige. Ã¥r (hold for meny)"; +Calendar._TT["PREV_MONTH"] = "Forrige. mÃ¥ned (hold for meny)"; +Calendar._TT["GO_TODAY"] = "GÃ¥ til idag"; +Calendar._TT["NEXT_MONTH"] = "Neste mÃ¥ned (hold for meny)"; +Calendar._TT["NEXT_YEAR"] = "Neste Ã¥r (hold for meny)"; +Calendar._TT["SEL_DATE"] = "Velg dato"; +Calendar._TT["DRAG_TO_MOVE"] = "Dra for Ã¥ flytte"; +Calendar._TT["PART_TODAY"] = " (idag)"; +Calendar._TT["MON_FIRST"] = "Vis mandag først"; +Calendar._TT["SUN_FIRST"] = "Vis søndag først"; +Calendar._TT["CLOSE"] = "Lukk"; +Calendar._TT["TODAY"] = "Idag"; +Calendar._TT["TIME_PART"] = "(Shift-)Klikk eller dra for Ã¥ endre verdi"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "uke"; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl-utf8.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl-utf8.js new file mode 100644 index 0000000..6b8ca67 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl-utf8.js @@ -0,0 +1,93 @@ +// ** I18N + +// Calendar PL language +// Author: Dariusz Pietrzak, +// Author: Janusz Piwowarski, +// Encoding: utf-8 +// Distributed under the same terms as the calendar itself. + +Calendar._DN = new Array +("Niedziela", + "PoniedziaÅ‚ek", + "Wtorek", + "Åšroda", + "Czwartek", + "PiÄ…tek", + "Sobota", + "Niedziela"); +Calendar._SDN = new Array +("Nie", + "Pn", + "Wt", + "Åšr", + "Cz", + "Pt", + "So", + "Nie"); +Calendar._MN = new Array +("StyczeÅ„", + "Luty", + "Marzec", + "KwiecieÅ„", + "Maj", + "Czerwiec", + "Lipiec", + "SierpieÅ„", + "WrzesieÅ„", + "Październik", + "Listopad", + "GrudzieÅ„"); +Calendar._SMN = new Array +("Sty", + "Lut", + "Mar", + "Kwi", + "Maj", + "Cze", + "Lip", + "Sie", + "Wrz", + "Paź", + "Lis", + "Gru"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O kalendarzu"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Aby pobrać najnowszÄ… wersjÄ™, odwiedź: http://www.dynarch.com/projects/calendar/\n" + +"DostÄ™pny na licencji GNU LGPL. Zobacz szczegóły na http://gnu.org/licenses/lgpl.html." + +"\n\n" + +"Wybór daty:\n" + +"- Użyj przycisków \xab, \xbb by wybrać rok\n" + +"- Użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " by wybrać miesiÄ…c\n" + +"- Przytrzymaj klawisz myszy nad jednym z powyższych przycisków dla szybszego wyboru."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Wybór czasu:\n" + +"- Kliknij na jednym z pól czasu by zwiÄ™kszyć jego wartość\n" + +"- lub kliknij trzymajÄ…c Shift by zmiejszyć jego wartość\n" + +"- lub kliknij i przeciÄ…gnij dla szybszego wyboru."; + +//Calendar._TT["TOGGLE"] = "ZmieÅ„ pierwszy dzieÅ„ tygodnia"; +Calendar._TT["PREV_YEAR"] = "Poprzedni rok (przytrzymaj dla menu)"; +Calendar._TT["PREV_MONTH"] = "Poprzedni miesiÄ…c (przytrzymaj dla menu)"; +Calendar._TT["GO_TODAY"] = "Idź do dzisiaj"; +Calendar._TT["NEXT_MONTH"] = "NastÄ™pny miesiÄ…c (przytrzymaj dla menu)"; +Calendar._TT["NEXT_YEAR"] = "NastÄ™pny rok (przytrzymaj dla menu)"; +Calendar._TT["SEL_DATE"] = "Wybierz datÄ™"; +Calendar._TT["DRAG_TO_MOVE"] = "PrzeciÄ…gnij by przesunąć"; +Calendar._TT["PART_TODAY"] = " (dzisiaj)"; +Calendar._TT["MON_FIRST"] = "WyÅ›wietl poniedziaÅ‚ek jako pierwszy"; +Calendar._TT["SUN_FIRST"] = "WyÅ›wietl niedzielÄ™ jako pierwszÄ…"; +Calendar._TT["CLOSE"] = "Zamknij"; +Calendar._TT["TODAY"] = "Dzisiaj"; +Calendar._TT["TIME_PART"] = "(Shift-)Kliknij lub przeciÄ…gnij by zmienić wartość"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%e %B, %A"; + +Calendar._TT["WK"] = "ty"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl.js new file mode 100644 index 0000000..6b8ca67 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl.js @@ -0,0 +1,93 @@ +// ** I18N + +// Calendar PL language +// Author: Dariusz Pietrzak, +// Author: Janusz Piwowarski, +// Encoding: utf-8 +// Distributed under the same terms as the calendar itself. + +Calendar._DN = new Array +("Niedziela", + "PoniedziaÅ‚ek", + "Wtorek", + "Åšroda", + "Czwartek", + "PiÄ…tek", + "Sobota", + "Niedziela"); +Calendar._SDN = new Array +("Nie", + "Pn", + "Wt", + "Åšr", + "Cz", + "Pt", + "So", + "Nie"); +Calendar._MN = new Array +("StyczeÅ„", + "Luty", + "Marzec", + "KwiecieÅ„", + "Maj", + "Czerwiec", + "Lipiec", + "SierpieÅ„", + "WrzesieÅ„", + "Październik", + "Listopad", + "GrudzieÅ„"); +Calendar._SMN = new Array +("Sty", + "Lut", + "Mar", + "Kwi", + "Maj", + "Cze", + "Lip", + "Sie", + "Wrz", + "Paź", + "Lis", + "Gru"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O kalendarzu"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Aby pobrać najnowszÄ… wersjÄ™, odwiedź: http://www.dynarch.com/projects/calendar/\n" + +"DostÄ™pny na licencji GNU LGPL. Zobacz szczegóły na http://gnu.org/licenses/lgpl.html." + +"\n\n" + +"Wybór daty:\n" + +"- Użyj przycisków \xab, \xbb by wybrać rok\n" + +"- Użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " by wybrać miesiÄ…c\n" + +"- Przytrzymaj klawisz myszy nad jednym z powyższych przycisków dla szybszego wyboru."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Wybór czasu:\n" + +"- Kliknij na jednym z pól czasu by zwiÄ™kszyć jego wartość\n" + +"- lub kliknij trzymajÄ…c Shift by zmiejszyć jego wartość\n" + +"- lub kliknij i przeciÄ…gnij dla szybszego wyboru."; + +//Calendar._TT["TOGGLE"] = "ZmieÅ„ pierwszy dzieÅ„ tygodnia"; +Calendar._TT["PREV_YEAR"] = "Poprzedni rok (przytrzymaj dla menu)"; +Calendar._TT["PREV_MONTH"] = "Poprzedni miesiÄ…c (przytrzymaj dla menu)"; +Calendar._TT["GO_TODAY"] = "Idź do dzisiaj"; +Calendar._TT["NEXT_MONTH"] = "NastÄ™pny miesiÄ…c (przytrzymaj dla menu)"; +Calendar._TT["NEXT_YEAR"] = "NastÄ™pny rok (przytrzymaj dla menu)"; +Calendar._TT["SEL_DATE"] = "Wybierz datÄ™"; +Calendar._TT["DRAG_TO_MOVE"] = "PrzeciÄ…gnij by przesunąć"; +Calendar._TT["PART_TODAY"] = " (dzisiaj)"; +Calendar._TT["MON_FIRST"] = "WyÅ›wietl poniedziaÅ‚ek jako pierwszy"; +Calendar._TT["SUN_FIRST"] = "WyÅ›wietl niedzielÄ™ jako pierwszÄ…"; +Calendar._TT["CLOSE"] = "Zamknij"; +Calendar._TT["TODAY"] = "Dzisiaj"; +Calendar._TT["TIME_PART"] = "(Shift-)Kliknij lub przeciÄ…gnij by zmienić wartość"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%e %B, %A"; + +Calendar._TT["WK"] = "ty"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl.old.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl.old.js new file mode 100644 index 0000000..76e0551 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pl.old.js @@ -0,0 +1,56 @@ +// ** I18N +// Calendar PL language +// Author: Artur Filipiak, +// January, 2004 +// Encoding: UTF-8 +Calendar._DN = new Array +("Niedziela", "PoniedziaÅ‚ek", "Wtorek", "Åšroda", "Czwartek", "PiÄ…tek", "Sobota", "Niedziela"); + +Calendar._SDN = new Array +("N", "Pn", "Wt", "Åšr", "Cz", "Pt", "So", "N"); + +Calendar._MN = new Array +("StyczeÅ„", "Luty", "Marzec", "KwiecieÅ„", "Maj", "Czerwiec", "Lipiec", "SierpieÅ„", "WrzesieÅ„", "Październik", "Listopad", "GrudzieÅ„"); + +Calendar._SMN = new Array +("Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O kalendarzu"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Wybór daty:\n" + +"- aby wybrać rok użyj przycisków \xab, \xbb\n" + +"- aby wybrać miesiÄ…c użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" + +"- aby przyspieszyć wybór przytrzymaj wciÅ›niÄ™ty przycisk myszy nad ww. przyciskami."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Wybór czasu:\n" + +"- aby zwiÄ™kszyć wartość kliknij na dowolnym elemencie selekcji czasu\n" + +"- aby zmniejszyć wartość użyj dodatkowo klawisza Shift\n" + +"- możesz również poruszać myszkÄ™ w lewo i prawo wraz z wciÅ›niÄ™tym lewym klawiszem."; + +Calendar._TT["PREV_YEAR"] = "Poprz. rok (przytrzymaj dla menu)"; +Calendar._TT["PREV_MONTH"] = "Poprz. miesiÄ…c (przytrzymaj dla menu)"; +Calendar._TT["GO_TODAY"] = "Pokaż dziÅ›"; +Calendar._TT["NEXT_MONTH"] = "Nast. miesiÄ…c (przytrzymaj dla menu)"; +Calendar._TT["NEXT_YEAR"] = "Nast. rok (przytrzymaj dla menu)"; +Calendar._TT["SEL_DATE"] = "Wybierz datÄ™"; +Calendar._TT["DRAG_TO_MOVE"] = "PrzesuÅ„ okienko"; +Calendar._TT["PART_TODAY"] = " (dziÅ›)"; +Calendar._TT["MON_FIRST"] = "Pokaż PoniedziaÅ‚ek jako pierwszy"; +Calendar._TT["SUN_FIRST"] = "Pokaż NiedzielÄ™ jako pierwszÄ…"; +Calendar._TT["CLOSE"] = "Zamknij"; +Calendar._TT["TODAY"] = "DziÅ›"; +Calendar._TT["TIME_PART"] = "(Shift-)klik | drag, aby zmienić wartość"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y.%m.%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "wk"; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pt.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pt.js new file mode 100644 index 0000000..deee8a1 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-pt.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar pt_BR language +// Author: Adalberto Machado, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Domingo", + "Segunda", + "Terca", + "Quarta", + "Quinta", + "Sexta", + "Sabado", + "Domingo"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("Dom", + "Seg", + "Ter", + "Qua", + "Qui", + "Sex", + "Sab", + "Dom"); + +// full month names +Calendar._MN = new Array +("Janeiro", + "Fevereiro", + "Marco", + "Abril", + "Maio", + "Junho", + "Julho", + "Agosto", + "Setembro", + "Outubro", + "Novembro", + "Dezembro"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Fev", + "Mar", + "Abr", + "Mai", + "Jun", + "Jul", + "Ago", + "Set", + "Out", + "Nov", + "Dez"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Sobre o calendario"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Ultima versao visite: http://www.dynarch.com/projects/calendar/\n" + +"Distribuido sobre GNU LGPL. Veja http://gnu.org/licenses/lgpl.html para detalhes." + +"\n\n" + +"Selecao de data:\n" + +"- Use os botoes \xab, \xbb para selecionar o ano\n" + +"- Use os botoes " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para selecionar o mes\n" + +"- Segure o botao do mouse em qualquer um desses botoes para selecao rapida."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Selecao de hora:\n" + +"- Clique em qualquer parte da hora para incrementar\n" + +"- ou Shift-click para decrementar\n" + +"- ou clique e segure para selecao rapida."; + +Calendar._TT["PREV_YEAR"] = "Ant. ano (segure para menu)"; +Calendar._TT["PREV_MONTH"] = "Ant. mes (segure para menu)"; +Calendar._TT["GO_TODAY"] = "Hoje"; +Calendar._TT["NEXT_MONTH"] = "Prox. mes (segure para menu)"; +Calendar._TT["NEXT_YEAR"] = "Prox. ano (segure para menu)"; +Calendar._TT["SEL_DATE"] = "Selecione a data"; +Calendar._TT["DRAG_TO_MOVE"] = "Arraste para mover"; +Calendar._TT["PART_TODAY"] = " (hoje)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Mostre %s primeiro"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Fechar"; +Calendar._TT["TODAY"] = "Hoje"; +Calendar._TT["TIME_PART"] = "(Shift-)Click ou arraste para mudar valor"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b"; + +Calendar._TT["WK"] = "sm"; +Calendar._TT["TIME"] = "Hora:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ro.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ro.js new file mode 100644 index 0000000..116e358 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ro.js @@ -0,0 +1,66 @@ +// ** I18N +Calendar._DN = new Array +("Duminică", + "Luni", + "MarÅ£i", + "Miercuri", + "Joi", + "Vineri", + "Sâmbătă", + "Duminică"); +Calendar._SDN_len = 2; +Calendar._MN = new Array +("Ianuarie", + "Februarie", + "Martie", + "Aprilie", + "Mai", + "Iunie", + "Iulie", + "August", + "Septembrie", + "Octombrie", + "Noiembrie", + "Decembrie"); + +// tooltips +Calendar._TT = {}; + +Calendar._TT["INFO"] = "Despre calendar"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Pentru ultima versiune vizitaÅ£i: http://www.dynarch.com/projects/calendar/\n" + +"Distribuit sub GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"SelecÅ£ia datei:\n" + +"- FolosiÅ£i butoanele \xab, \xbb pentru a selecta anul\n" + +"- FolosiÅ£i butoanele " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pentru a selecta luna\n" + +"- TineÅ£i butonul mouse-ului apăsat pentru selecÅ£ie mai rapidă."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"SelecÅ£ia orei:\n" + +"- Click pe ora sau minut pentru a mări valoarea cu 1\n" + +"- Sau Shift-Click pentru a micÅŸora valoarea cu 1\n" + +"- Sau Click ÅŸi drag pentru a selecta mai repede."; + +Calendar._TT["PREV_YEAR"] = "Anul precedent (lung pt menu)"; +Calendar._TT["PREV_MONTH"] = "Luna precedentă (lung pt menu)"; +Calendar._TT["GO_TODAY"] = "Data de azi"; +Calendar._TT["NEXT_MONTH"] = "Luna următoare (lung pt menu)"; +Calendar._TT["NEXT_YEAR"] = "Anul următor (lung pt menu)"; +Calendar._TT["SEL_DATE"] = "Selectează data"; +Calendar._TT["DRAG_TO_MOVE"] = "Trage pentru a miÅŸca"; +Calendar._TT["PART_TODAY"] = " (astăzi)"; +Calendar._TT["DAY_FIRST"] = "AfiÅŸează %s prima zi"; +Calendar._TT["WEEKEND"] = "0,6"; +Calendar._TT["CLOSE"] = "ÃŽnchide"; +Calendar._TT["TODAY"] = "Astăzi"; +Calendar._TT["TIME_PART"] = "(Shift-)Click sau drag pentru a selecta"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %d %B"; + +Calendar._TT["WK"] = "spt"; +Calendar._TT["TIME"] = "Ora:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ru.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ru.js new file mode 100644 index 0000000..9f75a6a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ru.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar RU language +// Translation: Sly Golovanov, http://golovanov.net, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("воÑкреÑенье", + "понедельник", + "вторник", + "Ñреда", + "четверг", + "пÑтница", + "Ñуббота", + "воÑкреÑенье"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("вÑк", + "пон", + "втр", + "Ñрд", + "чет", + "пÑÑ‚", + "Ñуб", + "вÑк"); + +// full month names +Calendar._MN = new Array +("Ñнварь", + "февраль", + "март", + "апрель", + "май", + "июнь", + "июль", + "авгуÑÑ‚", + "ÑентÑбрь", + "октÑбрь", + "ноÑбрь", + "декабрь"); + +// short month names +Calendar._SMN = new Array +("Ñнв", + "фев", + "мар", + "апр", + "май", + "июн", + "июл", + "авг", + "Ñен", + "окт", + "ноÑ", + "дек"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "О календаре..."; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Как выбрать дату:\n" + +"- При помощи кнопок \xab, \xbb можно выбрать год\n" + +"- При помощи кнопок " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " можно выбрать меÑÑц\n" + +"- Подержите Ñти кнопки нажатыми, чтобы поÑвилоÑÑŒ меню быÑтрого выбора."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Как выбрать времÑ:\n" + +"- При клике на чаÑах или минутах они увеличиваютÑÑ\n" + +"- при клике Ñ Ð½Ð°Ð¶Ð°Ñ‚Ð¾Ð¹ клавишей Shift они уменьшаютÑÑ\n" + +"- еÑли нажать и двигать мышкой влево/вправо, они будут менÑÑ‚ÑŒÑÑ Ð±Ñ‹Ñтрее."; + +Calendar._TT["PREV_YEAR"] = "Ðа год назад (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; +Calendar._TT["PREV_MONTH"] = "Ðа меÑÑц назад (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; +Calendar._TT["GO_TODAY"] = "СегоднÑ"; +Calendar._TT["NEXT_MONTH"] = "Ðа меÑÑц вперед (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; +Calendar._TT["NEXT_YEAR"] = "Ðа год вперед (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)"; +Calendar._TT["SEL_DATE"] = "Выберите дату"; +Calendar._TT["DRAG_TO_MOVE"] = "ПеретаÑкивайте мышкой"; +Calendar._TT["PART_TODAY"] = " (ÑегоднÑ)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Первый день недели будет %s"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Закрыть"; +Calendar._TT["TODAY"] = "СегоднÑ"; +Calendar._TT["TIME_PART"] = "(Shift-)клик или нажать и двигать"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%e %b, %a"; + +Calendar._TT["WK"] = "нед"; +Calendar._TT["TIME"] = "ВремÑ:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ru_win_.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ru_win_.js new file mode 100644 index 0000000..de455af --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-ru_win_.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar RU language +// Translation: Sly Golovanov, http://golovanov.net, +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("âîñêðåñåíüå", + "ïîíåäåëüíèê", + "âòîðíèê", + "ñðåäà", + "÷åòâåðã", + "ïÿòíèöà", + "ñóááîòà", + "âîñêðåñåíüå"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("âñê", + "ïîí", + "âòð", + "ñðä", + "÷åò", + "ïÿò", + "ñóá", + "âñê"); + +// full month names +Calendar._MN = new Array +("ÿíâàðü", + "ôåâðàëü", + "ìàðò", + "àïðåëü", + "ìàé", + "èþíü", + "èþëü", + "àâãóñò", + "ñåíòÿáðü", + "îêòÿáðü", + "íîÿáðü", + "äåêàáðü"); + +// short month names +Calendar._SMN = new Array +("ÿíâ", + "ôåâ", + "ìàð", + "àïð", + "ìàé", + "èþí", + "èþë", + "àâã", + "ñåí", + "îêò", + "íîÿ", + "äåê"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Î êàëåíäàðå..."; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Êàê âûáðàòü äàòó:\n" + +"- Ïðè ïîìîùè êíîïîê \xab, \xbb ìîæíî âûáðàòü ãîä\n" + +"- Ïðè ïîìîùè êíîïîê " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ìîæíî âûáðàòü ìåñÿö\n" + +"- Ïîäåðæèòå ýòè êíîïêè íàæàòûìè, ÷òîáû ïîÿâèëîñü ìåíþ áûñòðîãî âûáîðà."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Êàê âûáðàòü âðåìÿ:\n" + +"- Ïðè êëèêå íà ÷àñàõ èëè ìèíóòàõ îíè óâåëè÷èâàþòñÿ\n" + +"- ïðè êëèêå ñ íàæàòîé êëàâèøåé Shift îíè óìåíüøàþòñÿ\n" + +"- åñëè íàæàòü è äâèãàòü ìûøêîé âëåâî/âïðàâî, îíè áóäóò ìåíÿòüñÿ áûñòðåå."; + +Calendar._TT["PREV_YEAR"] = "Íà ãîä íàçàä (óäåðæèâàòü äëÿ ìåíþ)"; +Calendar._TT["PREV_MONTH"] = "Íà ìåñÿö íàçàä (óäåðæèâàòü äëÿ ìåíþ)"; +Calendar._TT["GO_TODAY"] = "Ñåãîäíÿ"; +Calendar._TT["NEXT_MONTH"] = "Íà ìåñÿö âïåðåä (óäåðæèâàòü äëÿ ìåíþ)"; +Calendar._TT["NEXT_YEAR"] = "Íà ãîä âïåðåä (óäåðæèâàòü äëÿ ìåíþ)"; +Calendar._TT["SEL_DATE"] = "Âûáåðèòå äàòó"; +Calendar._TT["DRAG_TO_MOVE"] = "Ïåðåòàñêèâàéòå ìûøêîé"; +Calendar._TT["PART_TODAY"] = " (ñåãîäíÿ)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Ïåðâûé äåíü íåäåëè áóäåò %s"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Çàêðûòü"; +Calendar._TT["TODAY"] = "Ñåãîäíÿ"; +Calendar._TT["TIME_PART"] = "(Shift-)êëèê èëè íàæàòü è äâèãàòü"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%e %b, %a"; + +Calendar._TT["WK"] = "íåä"; +Calendar._TT["TIME"] = "Âðåìÿ:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-si.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-si.js new file mode 100644 index 0000000..cb3dfb9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-si.js @@ -0,0 +1,94 @@ +/* Slovenian language file for the DHTML Calendar version 0.9.2 +* Author David Milost , January 2004. +* Feel free to use this script under the terms of the GNU Lesser General +* Public License, as long as you do not remove or alter this notice. +*/ + // full day names +Calendar._DN = new Array +("Nedelja", + "Ponedeljek", + "Torek", + "Sreda", + "ÄŒetrtek", + "Petek", + "Sobota", + "Nedelja"); + // short day names + Calendar._SDN = new Array +("Ned", + "Pon", + "Tor", + "Sre", + "ÄŒet", + "Pet", + "Sob", + "Ned"); +// short month names +Calendar._SMN = new Array +("Jan", + "Feb", + "Mar", + "Apr", + "Maj", + "Jun", + "Jul", + "Avg", + "Sep", + "Okt", + "Nov", + "Dec"); + // full month names +Calendar._MN = new Array +("Januar", + "Februar", + "Marec", + "April", + "Maj", + "Junij", + "Julij", + "Avgust", + "September", + "Oktober", + "November", + "December"); + +// tooltips +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O koledarju"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Za zadnjo verzijo pojdine na naslov: http://www.dynarch.com/projects/calendar/\n" + +"Distribuirano pod GNU LGPL. Poglejte http://gnu.org/licenses/lgpl.html za podrobnosti." + +"\n\n" + +"Izbor datuma:\n" + +"- Uporabite \xab, \xbb gumbe za izbor leta\n" + +"- Uporabite " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " gumbe za izbor meseca\n" + +"- Zadržite klik na kateremkoli od zgornjih gumbov za hiter izbor."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Izbor ćasa:\n" + +"- Kliknite na katerikoli del ćasa za poveć. le-tega\n" + +"- ali Shift-click za zmanj. le-tega\n" + +"- ali kliknite in povlecite za hiter izbor."; + +Calendar._TT["TOGGLE"] = "Spremeni dan s katerim se prićne teden"; +Calendar._TT["PREV_YEAR"] = "Predhodnje leto (dolg klik za meni)"; +Calendar._TT["PREV_MONTH"] = "Predhodnji mesec (dolg klik za meni)"; +Calendar._TT["GO_TODAY"] = "Pojdi na tekoći dan"; +Calendar._TT["NEXT_MONTH"] = "Naslednji mesec (dolg klik za meni)"; +Calendar._TT["NEXT_YEAR"] = "Naslednje leto (dolg klik za meni)"; +Calendar._TT["SEL_DATE"] = "Izberite datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Pritisni in povleci za spremembo pozicije"; +Calendar._TT["PART_TODAY"] = " (danes)"; +Calendar._TT["MON_FIRST"] = "Prikaži ponedeljek kot prvi dan"; +Calendar._TT["SUN_FIRST"] = "Prikaži nedeljo kot prvi dan"; +Calendar._TT["CLOSE"] = "Zapri"; +Calendar._TT["TODAY"] = "Danes"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e"; + +Calendar._TT["WK"] = "Ted"; \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sk.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sk.js new file mode 100644 index 0000000..4fe6a3c --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sk.js @@ -0,0 +1,99 @@ +// ** I18N + +// Calendar SK language +// Author: Peter Valach (pvalach@gmx.net) +// Encoding: utf-8 +// Last update: 2003/10/29 +// Distributed under the same terms as the calendar itself. + +// full day names +Calendar._DN = new Array +("NedeÄľa", + "Pondelok", + "Utorok", + "Streda", + "Ĺ tvrtok", + "Piatok", + "Sobota", + "NedeÄľa"); + +// short day names +Calendar._SDN = new Array +("Ned", + "Pon", + "Uto", + "Str", + "Ĺ tv", + "Pia", + "Sob", + "Ned"); + +// full month names +Calendar._MN = new Array +("Január", + "Február", + "Marec", + "AprĂ­l", + "Máj", + "JÄ‚ÅŸn", + "JÄ‚ÅŸl", + "August", + "September", + "OktÄ‚Å‚ber", + "November", + "December"); + +// short month names +Calendar._SMN = new Array +("Jan", + "Feb", + "Mar", + "Apr", + "Máj", + "JÄ‚ÅŸn", + "JÄ‚ÅŸl", + "Aug", + "Sep", + "Okt", + "Nov", + "Dec"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "O kalendári"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + +"PoslednÄ‚ÅŸ verziu nájdete na: http://www.dynarch.com/projects/calendar/\n" + +"DistribuovanĂ© pod GNU LGPL. ViÄŹ http://gnu.org/licenses/lgpl.html pre detaily." + +"\n\n" + +"VÄ‚Ëber dátumu:\n" + +"- PouĹľite tlaÄŤidlá \xab, \xbb pre vÄ‚Ëber roku\n" + +"- PouĹľite tlaÄŤidlá " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pre vÄ‚Ëber mesiaca\n" + +"- Ak ktorĂ©koÄľvek z tÄ‚Ëchto tlaÄŤidiel podržíte dlhšie, zobrazĂ­ sa rÄ‚Ëchly vÄ‚Ëber."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"VÄ‚Ëber ÄŤasu:\n" + +"- Kliknutie na niektorÄ‚ÅŸ poloĹľku ÄŤasu ju zvÄ‚Ëši\n" + +"- Shift-klik ju znĂ­Ĺľi\n" + +"- Ak podržíte tlaÄŤĂ­tko stlaÄŤenĂ©, posÄ‚ÅŸvanĂ­m menĂ­te hodnotu."; + +Calendar._TT["PREV_YEAR"] = "PredošlÄ‚Ë rok (podrĹľte pre menu)"; +Calendar._TT["PREV_MONTH"] = "PredošlÄ‚Ë mesiac (podrĹľte pre menu)"; +Calendar._TT["GO_TODAY"] = "PrejsĹĄ na dnešok"; +Calendar._TT["NEXT_MONTH"] = "Nasl. mesiac (podrĹľte pre menu)"; +Calendar._TT["NEXT_YEAR"] = "Nasl. rok (podrĹľte pre menu)"; +Calendar._TT["SEL_DATE"] = "ZvoÄľte dátum"; +Calendar._TT["DRAG_TO_MOVE"] = "PodrĹľanĂ­m tlaÄŤĂ­tka zmenĂ­te polohu"; +Calendar._TT["PART_TODAY"] = " (dnes)"; +Calendar._TT["MON_FIRST"] = "ZobraziĹĄ pondelok ako prvÄ‚Ë"; +Calendar._TT["SUN_FIRST"] = "ZobraziĹĄ nedeÄľu ako prvÄ‚ÅŸ"; +Calendar._TT["CLOSE"] = "ZavrieĹĄ"; +Calendar._TT["TODAY"] = "Dnes"; +Calendar._TT["TIME_PART"] = "(Shift-)klik/ĹĄahanie zmenĂ­ hodnotu"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "$d. %m. %Y"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %e. %b"; + +Calendar._TT["WK"] = "tÄ‚ËĹľ"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sp.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sp.js new file mode 100644 index 0000000..239d1b3 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sp.js @@ -0,0 +1,110 @@ +// ** I18N + +// Calendar SP language +// Author: Rafael Velasco +// Encoding: any +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("Domingo", + "Lunes", + "Martes", + "Miercoles", + "Jueves", + "Viernes", + "Sabado", + "Domingo"); + +Calendar._SDN = new Array +("Dom", + "Lun", + "Mar", + "Mie", + "Jue", + "Vie", + "Sab", + "Dom"); + +// full month names +Calendar._MN = new Array +("Enero", + "Febrero", + "Marzo", + "Abril", + "Mayo", + "Junio", + "Julio", + "Agosto", + "Septiembre", + "Octubre", + "Noviembre", + "Diciembre"); + +// short month names +Calendar._SMN = new Array +("Ene", + "Feb", + "Mar", + "Abr", + "May", + "Jun", + "Jul", + "Ago", + "Sep", + "Oct", + "Nov", + "Dic"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Información del Calendario"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"Nuevas versiones en: http://www.dynarch.com/projects/calendar/\n" + +"Distribuida bajo licencia GNU LGPL. Para detalles vea http://gnu.org/licenses/lgpl.html ." + +"\n\n" + +"Selección de Fechas:\n" + +"- Use \xab, \xbb para seleccionar el año\n" + +"- Use " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar el mes\n" + +"- Mantenga presionado el botón del ratón en cualquiera de las opciones superiores para un acceso rapido ."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Selección del Reloj:\n" + +"- Seleccione la hora para cambiar el reloj\n" + +"- o presione Shift-click para disminuirlo\n" + +"- o presione click y arrastre del ratón para una selección rapida."; + +Calendar._TT["PREV_YEAR"] = "Año anterior (Presione para menu)"; +Calendar._TT["PREV_MONTH"] = "Mes Anterior (Presione para menu)"; +Calendar._TT["GO_TODAY"] = "Ir a Hoy"; +Calendar._TT["NEXT_MONTH"] = "Mes Siguiente (Presione para menu)"; +Calendar._TT["NEXT_YEAR"] = "Año Siguiente (Presione para menu)"; +Calendar._TT["SEL_DATE"] = "Seleccione fecha"; +Calendar._TT["DRAG_TO_MOVE"] = "Arrastre y mueva"; +Calendar._TT["PART_TODAY"] = " (Hoy)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "Mostrar %s primero"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "Cerrar"; +Calendar._TT["TODAY"] = "Hoy"; +Calendar._TT["TIME_PART"] = "(Shift-)Click o arrastra para cambar el valor"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%dd-%mm-%yy"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y"; + +Calendar._TT["WK"] = "Sm"; +Calendar._TT["TIME"] = "Hora:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sv.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sv.js new file mode 100644 index 0000000..db1f4b8 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-sv.js @@ -0,0 +1,93 @@ +// ** I18N + +// Calendar SV language (Swedish, svenska) +// Author: Mihai Bazon, +// Translation team: +// Translator: Leonard Norrgård +// Last translator: Leonard Norrgård +// Encoding: iso-latin-1 +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("söndag", + "måndag", + "tisdag", + "onsdag", + "torsdag", + "fredag", + "lördag", + "söndag"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. +Calendar._SDN_len = 2; +Calendar._SMN_len = 3; + +// full month names +Calendar._MN = new Array +("januari", + "februari", + "mars", + "april", + "maj", + "juni", + "juli", + "augusti", + "september", + "oktober", + "november", + "december"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "Om kalendern"; + +Calendar._TT["ABOUT"] = +"DHTML Datum/tid-väljare\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"För senaste version gå till: http://www.dynarch.com/projects/calendar/\n" + +"Distribueras under GNU LGPL. Se http://gnu.org/licenses/lgpl.html för detaljer." + +"\n\n" + +"Val av datum:\n" + +"- Använd knapparna \xab, \xbb för att välja år\n" + +"- Använd knapparna " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " för att välja månad\n" + +"- Håll musknappen nedtryckt på någon av ovanstående knappar för snabbare val."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Val av tid:\n" + +"- Klicka på en del av tiden för att öka den delen\n" + +"- eller skift-klicka för att minska den\n" + +"- eller klicka och drag för snabbare val."; + +Calendar._TT["PREV_YEAR"] = "Föregående år (håll för menu)"; +Calendar._TT["PREV_MONTH"] = "Föregående månad (håll för menu)"; +Calendar._TT["GO_TODAY"] = "Gå till dagens datum"; +Calendar._TT["NEXT_MONTH"] = "Följande månad (håll för menu)"; +Calendar._TT["NEXT_YEAR"] = "Följande år (håll för menu)"; +Calendar._TT["SEL_DATE"] = "Välj datum"; +Calendar._TT["DRAG_TO_MOVE"] = "Drag för att flytta"; +Calendar._TT["PART_TODAY"] = " (idag)"; +Calendar._TT["MON_FIRST"] = "Visa måndag först"; +Calendar._TT["SUN_FIRST"] = "Visa söndag först"; +Calendar._TT["CLOSE"] = "Stäng"; +Calendar._TT["TODAY"] = "Idag"; +Calendar._TT["TIME_PART"] = "(Skift-)klicka eller drag för att ändra tid"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%A %d %b %Y"; + +Calendar._TT["WK"] = "vecka"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-tr.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-tr.js new file mode 100644 index 0000000..2164687 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-tr.js @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////////////////////////// +// Turkish Translation by Nuri AKMAN +// Location: Ankara/TURKEY +// e-mail : nuriakman@hotmail.com +// Date : April, 9 2003 +// +// Note: if Turkish Characters does not shown on you screen +// please include falowing line your html code: +// +// +// +////////////////////////////////////////////////////////////////////////////////////////////// + +// ** I18N +Calendar._DN = new Array +("Pazar", + "Pazartesi", + "Salý", + "Çarþamba", + "Perþembe", + "Cuma", + "Cumartesi", + "Pazar"); +Calendar._MN = new Array +("Ocak", + "Þubat", + "Mart", + "Nisan", + "Mayýs", + "Haziran", + "Temmuz", + "Aðustos", + "Eylül", + "Ekim", + "Kasým", + "Aralýk"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["TOGGLE"] = "Haftanýn ilk gününü kaydýr"; +Calendar._TT["PREV_YEAR"] = "Önceki Yýl (Menü için basýlý tutunuz)"; +Calendar._TT["PREV_MONTH"] = "Önceki Ay (Menü için basýlý tutunuz)"; +Calendar._TT["GO_TODAY"] = "Bugün'e git"; +Calendar._TT["NEXT_MONTH"] = "Sonraki Ay (Menü için basýlý tutunuz)"; +Calendar._TT["NEXT_YEAR"] = "Sonraki Yýl (Menü için basýlý tutunuz)"; +Calendar._TT["SEL_DATE"] = "Tarih seçiniz"; +Calendar._TT["DRAG_TO_MOVE"] = "Taþýmak için sürükleyiniz"; +Calendar._TT["PART_TODAY"] = " (bugün)"; +Calendar._TT["MON_FIRST"] = "Takvim Pazartesi gününden baþlasýn"; +Calendar._TT["SUN_FIRST"] = "Takvim Pazar gününden baþlasýn"; +Calendar._TT["CLOSE"] = "Kapat"; +Calendar._TT["TODAY"] = "Bugün"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y"; +Calendar._TT["TT_DATE_FORMAT"] = "d MM y, DD"; + +Calendar._TT["WK"] = "Hafta"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-zh.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-zh.js new file mode 100644 index 0000000..4a0feb6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/calendar-zh.js @@ -0,0 +1,119 @@ +// ** I18N + +// Calendar ZH language +// Author: muziq, +// Encoding: GB2312 or GBK +// Distributed under the same terms as the calendar itself. + +// full day names +Calendar._DN = new Array +("ÐÇÆÚÈÕ", + "ÐÇÆÚÒ»", + "ÐÇÆÚ¶þ", + "ÐÇÆÚÈý", + "ÐÇÆÚËÄ", + "ÐÇÆÚÎå", + "ÐÇÆÚÁù", + "ÐÇÆÚÈÕ"); + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("ÈÕ", + "Ò»", + "¶þ", + "Èý", + "ËÄ", + "Îå", + "Áù", + "ÈÕ"); + +// full month names +Calendar._MN = new Array +("Ò»ÔÂ", + "¶þÔÂ", + "ÈýÔÂ", + "ËÄÔÂ", + "ÎåÔÂ", + "ÁùÔÂ", + "ÆßÔÂ", + "°ËÔÂ", + "¾ÅÔÂ", + "Ê®ÔÂ", + "ʮһÔÂ", + "Ê®¶þÔÂ"); + +// short month names +Calendar._SMN = new Array +("Ò»ÔÂ", + "¶þÔÂ", + "ÈýÔÂ", + "ËÄÔÂ", + "ÎåÔÂ", + "ÁùÔÂ", + "ÆßÔÂ", + "°ËÔÂ", + "¾ÅÔÂ", + "Ê®ÔÂ", + "ʮһÔÂ", + "Ê®¶þÔÂ"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "°ïÖú"; + +Calendar._TT["ABOUT"] = +"DHTML Date/Time Selector\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: http://www.dynarch.com/projects/calendar/\n" + +"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." + +"\n\n" + +"Ñ¡ÔñÈÕÆÚ:\n" + +"- µã»÷ \xab, \xbb °´Å¥Ñ¡ÔñÄê·Ý\n" + +"- µã»÷ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " °´Å¥Ñ¡ÔñÔ·Ý\n" + +"- ³¤°´ÒÔÉÏ°´Å¥¿É´Ó²Ëµ¥ÖпìËÙÑ¡ÔñÄê·Ý»òÔ·Ý"; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"Ñ¡Ôñʱ¼ä:\n" + +"- µã»÷Сʱ»ò·ÖÖÓ¿Éʹ¸ÄÊýÖµ¼ÓÒ»\n" + +"- °´×¡Shift¼üµã»÷Сʱ»ò·ÖÖÓ¿Éʹ¸ÄÊýÖµ¼õÒ»\n" + +"- µã»÷Í϶¯Êó±ê¿É½øÐпìËÙÑ¡Ôñ"; + +Calendar._TT["PREV_YEAR"] = "ÉÏÒ»Äê (°´×¡³ö²Ëµ¥)"; +Calendar._TT["PREV_MONTH"] = "ÉÏÒ»Ô (°´×¡³ö²Ëµ¥)"; +Calendar._TT["GO_TODAY"] = "תµ½½ñÈÕ"; +Calendar._TT["NEXT_MONTH"] = "ÏÂÒ»Ô (°´×¡³ö²Ëµ¥)"; +Calendar._TT["NEXT_YEAR"] = "ÏÂÒ»Äê (°´×¡³ö²Ëµ¥)"; +Calendar._TT["SEL_DATE"] = "Ñ¡ÔñÈÕÆÚ"; +Calendar._TT["DRAG_TO_MOVE"] = "Í϶¯"; +Calendar._TT["PART_TODAY"] = " (½ñÈÕ)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "×î×ó±ßÏÔʾ%s"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "¹Ø±Õ"; +Calendar._TT["TODAY"] = "½ñÈÕ"; +Calendar._TT["TIME_PART"] = "(Shift-)µã»÷Êó±ê»òÍ϶¯¸Ä±äÖµ"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%A, %b %eÈÕ"; + +Calendar._TT["WK"] = "ÖÜ"; +Calendar._TT["TIME"] = "ʱ¼ä:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/cn_utf8.js b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/cn_utf8.js new file mode 100644 index 0000000..a0ef7c6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/lang/cn_utf8.js @@ -0,0 +1,123 @@ +// ** I18N + +// Calendar EN language +// Author: Mihai Bazon, +// Encoding: any +// Translator : Niko +// Distributed under the same terms as the calendar itself. + +// For translators: please use UTF-8 if possible. We strongly believe that +// Unicode is the answer to a real internationalized world. Also please +// include your contact information in the header, as can be seen above. + +// full day names +Calendar._DN = new Array +("\u5468\u65e5",//\u5468\u65e5 + "\u5468\u4e00",//\u5468\u4e00 + "\u5468\u4e8c",//\u5468\u4e8c + "\u5468\u4e09",//\u5468\u4e09 + "\u5468\u56db",//\u5468\u56db + "\u5468\u4e94",//\u5468\u4e94 + "\u5468\u516d",//\u5468\u516d + "\u5468\u65e5");//\u5468\u65e5 + +// Please note that the following array of short day names (and the same goes +// for short month names, _SMN) isn't absolutely necessary. We give it here +// for exemplification on how one can customize the short day names, but if +// they are simply the first N letters of the full name you can simply say: +// +// Calendar._SDN_len = N; // short day name length +// Calendar._SMN_len = N; // short month name length +// +// If N = 3 then this is not needed either since we assume a value of 3 if not +// present, to be compatible with translation files that were written before +// this feature. + +// short day names +Calendar._SDN = new Array +("\u5468\u65e5", + "\u5468\u4e00", + "\u5468\u4e8c", + "\u5468\u4e09", + "\u5468\u56db", + "\u5468\u4e94", + "\u5468\u516d", + "\u5468\u65e5"); + +// full month names +Calendar._MN = new Array +("\u4e00\u6708", + "\u4e8c\u6708", + "\u4e09\u6708", + "\u56db\u6708", + "\u4e94\u6708", + "\u516d\u6708", + "\u4e03\u6708", + "\u516b\u6708", + "\u4e5d\u6708", + "\u5341\u6708", + "\u5341\u4e00\u6708", + "\u5341\u4e8c\u6708"); + +// short month names +Calendar._SMN = new Array +("\u4e00\u6708", + "\u4e8c\u6708", + "\u4e09\u6708", + "\u56db\u6708", + "\u4e94\u6708", + "\u516d\u6708", + "\u4e03\u6708", + "\u516b\u6708", + "\u4e5d\u6708", + "\u5341\u6708", + "\u5341\u4e00\u6708", + "\u5341\u4e8c\u6708"); + +// tooltips +Calendar._TT = {}; +Calendar._TT["INFO"] = "\u5173\u4e8e"; + +Calendar._TT["ABOUT"] = +" DHTML \u65e5\u8d77/\u65f6\u95f4\u9009\u62e9\u63a7\u4ef6\n" + +"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-) +"For latest version visit: \u6700\u65b0\u7248\u672c\u8bf7\u767b\u9646http://www.dynarch.com/projects/calendar/\u5bdf\u770b\n" + +"\u9075\u5faaGNU LGPL. \u7ec6\u8282\u53c2\u9605 http://gnu.org/licenses/lgpl.html" + +"\n\n" + +"\u65e5\u671f\u9009\u62e9:\n" + +"- \u70b9\u51fb\xab(\xbb)\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e00\u5e74\u5ea6.\n" + +"- \u70b9\u51fb" + String.fromCharCode(0x2039) + "(" + String.fromCharCode(0x203a) + ")\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e2a\u6708\u4efd.\n" + +"- \u957f\u65f6\u95f4\u6309\u7740\u6309\u94ae\u5c06\u51fa\u73b0\u66f4\u591a\u9009\u62e9\u9879."; +Calendar._TT["ABOUT_TIME"] = "\n\n" + +"\u65f6\u95f4\u9009\u62e9:\n" + +"-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u589e\u52a0\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\n" + +"-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u6309\u4f4fShift\u952e\u540e\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u51cf\u5c11\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)."; + +Calendar._TT["PREV_YEAR"] = "\u4e0a\u4e00\u5e74"; +Calendar._TT["PREV_MONTH"] = "\u4e0a\u4e2a\u6708"; +Calendar._TT["GO_TODAY"] = "\u5230\u4eca\u5929"; +Calendar._TT["NEXT_MONTH"] = "\u4e0b\u4e2a\u6708"; +Calendar._TT["NEXT_YEAR"] = "\u4e0b\u4e00\u5e74"; +Calendar._TT["SEL_DATE"] = "\u9009\u62e9\u65e5\u671f"; +Calendar._TT["DRAG_TO_MOVE"] = "\u62d6\u52a8"; +Calendar._TT["PART_TODAY"] = " (\u4eca\u5929)"; + +// the following is to inform that "%s" is to be the first day of week +// %s will be replaced with the day name. +Calendar._TT["DAY_FIRST"] = "%s\u4e3a\u8fd9\u5468\u7684\u7b2c\u4e00\u5929"; + +// This may be locale-dependent. It specifies the week-end days, as an array +// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1 +// means Monday, etc. +Calendar._TT["WEEKEND"] = "0,6"; + +Calendar._TT["CLOSE"] = "\u5173\u95ed"; +Calendar._TT["TODAY"] = "\u4eca\u5929"; +Calendar._TT["TIME_PART"] = "(\u6309\u7740Shift\u952e)\u5355\u51fb\u6216\u62d6\u52a8\u6539\u53d8\u503c"; + +// date formats +Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d"; +Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e\u65e5"; + +Calendar._TT["WK"] = "\u5468"; +Calendar._TT["TIME"] = "\u65f6\u95f4:"; diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/menuarrow.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/menuarrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed2dee0e6368d201bf5d32833884c7c1da6c7424 GIT binary patch literal 68 zcmZ?wbhEHbWM^Py_{hZ2(9rPi-LwDy|1&T!DE?$&WME)o&;ha;K=KSsqAVN&i(DE6 VRJ~d>0vEY-3aNTcS;53$4FHxP5xxKb literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/menuarrow2.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/menuarrow2.gif new file mode 100644 index 0000000000000000000000000000000000000000..40c0aadfc6e62e7cdf4a0dc4a3a3d735c6995b76 GIT binary patch literal 49 zcmZ?wbhEHbWM^PyXkcV;a&r3r|G(l-7DfgJMg|=QAOOiQFmbfVR-Qb-pUlW$4FDM} B3akJC literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/multiple-dates.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/multiple-dates.html new file mode 100644 index 0000000..9f1e1f9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/multiple-dates.html @@ -0,0 +1,82 @@ + + + Sample for the multiple dates feature + + + + + + + + + + + + + + +

    Sample for the multiple dates feature

    + +

    + Starting version 0.9.7, + the calendar is able to handle multiple dates selection, in either + flat or popup form. For this to happen one needs to pass the + "multiple: true" parameter to + Calendar.setup and to install an onUpdate + handler that watches for modifications. +

    + + [open calendar...] + +
    + + + +
    +
    mishoo
    + Last modified: Thu Mar 3 20:17:42 EET 2005 + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/release-notes.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/release-notes.html new file mode 100644 index 0000000..b6adeb2 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/release-notes.html @@ -0,0 +1,435 @@ + + + + jscalendar release notes + + + + + +
    + The Coolest DHTML Calendar
    + © Dynarch.com 2002 and later. +
    +

    jscalendar release notes

    + +

    This release compiled at Tuesday, 13 Jan 2009 (13:30).

    + +

    1.0

    + +
      + +
    • + Added support for multiple dates selection. In this mode the + calendar will allow the user to select more than one date, and + will maintain an array of selected dates that can be + investigated from your custom handlers. Sample in multiple-dates.html. +
    • + +
    • + Support for “day infoâ€. Using this feature you can display + custom information for certain dates. Sample in dayinfo.html. Note that if the text + is really big the calendar layout might appear somehow broken; + this is something that should be easy to fix in the CSS file. +
    • + +
    • + Clicking on “Today†will now close the calendar if the current + date is already selected. +
    • + +
    • + The “first day of week†setting can now be defined in the + language file--after all, it is locale-specific. The new + parameter is “Calendar._FDâ€. Language files should be + updated, but the calendar will not complain nor fail to + function if the parameter is not present. +
    • + +
    • + Some fixes to make the thing work in Safari. It now seems to + be properly supported, please let me know if you encounter any + problems. +
    • + +
    • + New skin: Aqua theme, appropriate for MacOSX fan sites :-) + This theme is located in “skins/aqua/theme.css†(in the + future, all themes will go to this directory). +
    • + +
    • + Bug fixes. +
        +
      • + Keyboard operation now functions normally when the + calendar is displaying days from adjacent months; it might + even work correctly for months containing disabled dates + :). This fix was originally developed under contract for + The + Zapatec Calendar. Zapatec kindly allowed us to + include the bugfixes back in the open source calendar. +
      • +
      • + Fixed the time selection bug: the previous version would + reset the time to current time when a new date was + clicked. +
      • +
      • + Parsing hours like "12:XX pm" would wrongfully replace + "pm" with "am"--fixed. +
      • +
      • + Fixed critical bugs in parseDate function that would + initialize the calendar with 'NaN' values in all cells if + the string to be parsed is not a valid date. +
      • +
      • + The golbal variable that we are using was renamed to + “_dynarch_popupCalendar†to minimize the risk of name + clashes. It's still difficult to get rid of it. +
      • +
      • + Added z-index property to drop-down menus style. +
      • +
      • + The calendar will update an input field even in flat mode, + if an input field was passed. Also, the “showOthers†+ parameter will be effective in both popup and flat mode. +
      • +
      • + Others, probably. +
      • +
      +
    • + +
    • + Documentation & sample files updated. +
    • + +
    + +

    0.9.6

    + +
      + +
    • + "Smart" (TM :-) positioning algorithm. The new algorithm will + try to keep the calendar in the browser view, which is helpful + in situations when the input field is near the bottom or the + right edge. This code is only tested with IE and Mozilla, but + it should work with other browsers too. Many thanks to Sunny Chowdhury for sponsoring + this feature! +
    • + +
    • + Support for IE5/Win is back. I also want to thank Janusz + Piwowarski for keeping his eye on the CVS ;-) He reviewed my + IE5-related changes and sent me a much cleaner patch. +
    • + +
    • + The calendar will now allow any day of week to be "the first + day of week". This was requested long time ago, by someone + whose name I forgot (sorry). The reason was that in certain + countries weeks start on Saturday. So I thought that instead + of having a "mondayFirst" and a "saturdayFirst" parameter, + :-), it's better to have a "firstDayOfWeek" parameter; now + it's present and its meaning is: "0 for Sunday", "1 for + Monday", "2 for Tuesday", etc. The equivalent parameter for + Calendar.setup is "firstDay". The end user can also change + it very easy: click on the day name in the calendar display. +
    • + +
    • + The above feature triggered one important change: the + notion of "weekend" is now defined in the language file. + Added parameters: + +
      +          Calendar._TT["WEEKEND"] = "0,6";
      +          Calendar._TT["DAY_FIRST"] = "Display %s first";
      + + "WEEKEND" specifies a string with comma-separated numbers from + 0 to 7; they define what days are marked as "weekend". 5 and + 6 mean, of course, "Sunday" and "Saturday". Day first is the + tooltip displayed when a day name is hovered; "%s" will get + replaced with the day name. Updated languages are "en" and + "ro", which I maintain. Please note that languages wich are + not updated will not work. If yours is one of them, + please consider fixing it and sending me the fix so that I can + include it in the distro. +
    • + +
    • + The calendar can now display days from the months adjacent to + the currently displayed one. This is optional, of course, and + the parameter name is "showsOtherMonths" (or "showOthers" in + Calendar.setup). All theme files were updated. +
    • + +
    • + Displays "Time:" near the time selector, only if defined in + the language file. +
    • + +
    • + Some bugs fixed in the date parsing code (which has also been + rewritten a little bit cleaner). +
    • + +
    • + Calendar.setup will now configure the calendar to trigger the + input fields' "onchange" event, if specified, when a date is + selected. +
    • + +
    • + New parameter in Calendar.setup: "cache" (defaults to + false). If set to true then the popup calendar object + will be "cached", meaning, it will be created only once, no + matter how many input fields are there in the page. Sometimes + this is not desirable, which is why I've added this + parameter. Please note that it defaults to "false" (thus the + default behavior has changed). +
    • + +
    • + Added a simple PHP wrapper. It provides code which loads all + the required scripts and theme file, and one function which + creates and configures an input field for date input. It + takes care of creating and assigning unique ID-s for the + calendar fields and it also creates the "Calendar.setup" code. + Functions to create more specialized fields can be added very + easily. This feature was requested by the FreeMED.org project + (thanks for donating!). +
    • + +
    + +

    Wow, there were quite some changes :-D Enjoy it!

    + +

    0.9.5

    + +

    + This release's primary goal is to fix a wrong license statement which + can be found in some files from 0.9.4. For instance in README or + calendar.js, the statement was that the code is distributed under the + GNU GPL; that's because I had plans to change the license, then + changed my mind but unfortunately I committed files so. I am sorry + for this inconvenience, please use the latest (0.9.5) release which is + fully covered by LGPL. +

    + +

    Other changes:

    + +
      + +
    • + Fixed an annoying bug that prevented the calendar to display + correctly when it was configured for an input field inside a + scrolling area. Many thanks to Ian Barrack (Simban.com) who pointed it up and + donated quite some money for the Calendar project! +
    • + +
    • + All examples use UTF-8 now; the translations may not be all + up-to-date, but I strongly suggest everyone to use + UTF-8; other encodings are a plain mess. So far I know for sure + that Romanian translation will work with UTF-8 and not + anymore with ISO-8859-2. Other translations are probably + usable under UTF-8, but if your preferred language isn't... ;-) + please make it and send it to me for inclusion. +
    • + +
    • + Fixed small bug in the documentation (one footnote didn't appear + where it should have). +
    • + +
    • + Updated translations: DE, ES, HU, IT, RO. Thanks to everyone who + sent translations! +
    • + +
    + +

    0.9.4

    + +

    New stuff

    + +
      + +
    • Supports time selection. Yes. ;-) This work has been largely + sponsored by Himanshukumar Shah (thank you!). See + the docs and example files for details on how to setup.
    • + +
    • Easy to link 2 or more fields by using the new + onUpdate parameter of Calendar.setup. This + is useful, say, to automatically set a value in a second field based + on the value selected in the first field. See the documentation and + first sample in simple-1.html.
    • + +
    • Other Calendar.setup low-level parameters, for those + wanting to have the complete control: onSelect and + onClose. The handlers are called when something is + selected in the calendar or when the calendar is closed.
    • + +
    • The translation files can optionally include the short day names + and the short month names. That's because in some languages, like + German, the short form is not the first 3 letters of the entire name + but only the first 2. Also in other languages short names can't be + as easily derived from the full name by just calling substr, so this + patch solves the problem.
    • + +
    • Implemented a nice way to make some dates "special" (look + different). Specifically, the setDisabledHandler method + was replaced with the more general setDateStatusHandler + method (the old one is still available for backwards compatibility but + will be removed). More details about this in the + documentation. Also see simple-3.html + for a live sample.
    • + +
    • Date parsing and formatting engine is now rewritten and supports a + subset of strftime format specifiers from ANSI C. This + makes it possible to use dates like "YYYYMMDD" (the corresponding + format for this would be "%Y%m%d"). Details in the documentation. + Please note that the new engine is not compatibile with older + calendar releases!
    • + +
    • Along with the new date parser I workarounded an unpleasant crash + that occurred in IE when certain accented characters appeared in the + texts. I think German was one of the language with such problems, and + the workaround was to use the letter without an accent. Well, now you + can translate to whatever you want.
    • + +
    • "Fixes" (I mean, "horrible workarounds") for Konqueror (and + hopefully Safari). Unfortunately, this otherwise excellent browser + still has some bugs that keep the calendar from working + exactly as it should.. But they're going to be fixed, + right? ;-)
    • + +
    • CSS themes got pretty much modified too so if you wrote your theme + you need to update it. Aside for the time selector support, the CSS + themes contain a simple hack that makes the navigation buttons show + a little arrow in the lower-right corner which indicates that if one + holds the mouse a menu will appear.
    • + +
    + +

    Translation files

    + +

    The translation files need to be updated in order for the calendar to + work properly. Currently the only updated files are calendar-en.js + (main file) and calendar-ro.js (well, yes, I am a Romanian ;-).

    + +

    Specifically, they need the following:

    + +
      + +
    • Correct date format, according with the new format specifiers + introduced in 0.9.4. Details about the available format specifiers + in the documentation
    • + +
    • Short day or month names, if required. If they can be + derived by taking the first N letters of the full name then a simple + Calendar._SDN_len = N or Calendar._SMN_len = N will suffice. If N + is 3 then nothing needs to be done as we take it for granted if no + other option is offered ;-)
    • + +
    • We have some new texts that shows short usage information as well + as copyright information.
    • + +
    + +

    If your favorite language is not there yet, or it is but not updated + according to the main calendar-en.js file, then please consider + translating calendar-en.js and send the translation back to me so that + I include it in the official distribution.

    + +

    Bug status

    + +

    Check SourceForge, + I didn't keep track. However, there were a lot of bugfixes.

    + +

    0.9.3

    + +

    New stuff

    + +
      + +
    • Opera 7 compatibility — keyboard navigation is + still not available; text selection can't be disabled, leading to an + ugly effect when walking through the month/year menus.
    • + +
    • Ability to align the calendar relative to the input field (or any + other element). Vertical: top, center, bottom. Horizontal: left, + center, right. This is established as a new parameter for + showAtElement.
    • + +
    • Added dateClicked property (boolean). This can be + inspected in the "onSelect" handler to determine if a date was + really clicked or the user only changed month/year using the menus. + You need to check this for "single-click" calendars and + only close/hide the calendar if it's true.
    • + +
    • Full documentation in HTML + and PDF format is now available in the + distribution archive.
    • + +
    • New language definition files: HU, HR, PT, ZH. Thanks those who + submitted!
    • + +
    + +

    Bug status

    + +

    This covers only those bugs that have been reported at SourceForge.

    + +
      + +
    1. #703,238 — fixed
    2. +
    3. #703,814 — fixed
    4. +
    5. #716,777 — closed (was fixed already in 0.9.2-1)
    6. +
    7. #723,335 — fixed
    8. +
    9. #715,122 — feature request; implemented.
    10. +
    11. #721,206 — fixed (added "refresh()" function)
    12. +
    13. #721,833 — fixed (bug concerning the "yy" format + parsing)
    14. +
    15. #721,833 — won't fix (we won't set the time to + midnight; time might actually be useful when we implement support + for time selection). + +
    + +
    +
    Mihai Bazon
    + + +Last modified on Wed Oct 29 02:37:07 2003 + + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-1.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-1.html new file mode 100644 index 0000000..285bff6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-1.html @@ -0,0 +1,244 @@ + + + + + +Simple calendar setups [popup calendar] + + + + + + + + + + + + + + + + + +

    DHTML Calendar — for the impatient

    + +
    +

    + This page lists some common setups for the popup calendar. In + order to see how to do any of them please see the source of this + page. For each example it's structured like this: there's the + <form> that contains the input field, and following there is + the JavaScript snippet that setups that form. An example of + flat calendar is available in another page. +

    +

    + The code in this page uses a helper function defined in + "calendar-setup.js". With it you can setup the calendar in + minutes. If you're not that impatient, ;-) complete documenation is + available. +

    +
    + + + +
    + +

    Basic setup: one input per calendar. Clicking in the input field +activates the calendar. The date format is "%m/%d/%Y %I:%M %p". The +calendar defaults to "single-click mode".

    + +

    The example below has been updated to show you how to create "linked" +fields. Basically, when some field is filled with a date, the other +is updated so that the difference between them remains one week. The +property useful here is "onUpdate".

    + +
    + + +
    + + + + + +
    + +

    Input field with a trigger button. Clicking the button activates +the calendar. Note that this one needs double-click (singleClick parameter +is explicitely set to false). Also demonstrates the "step" parameter +introduced in 0.9.6 (show all years in drop-down boxes, instead of every +other year as default).

    + +
    + +
    + + + + + +
    + +

    Input field with a trigger image. Note that the Calendar.setup +function doesn't care if the trigger is a button, image, or anything else. +Also in this example we setup a different alignment, just to show how it's +done. The input field is read-only (that is set from HTML).

    + +
    + + + +
    +
    + + + + + +
    + +

    Hidden field, display area. The calendar now puts the date into 2 +elements: one is an input field of type "hidden"—so that the user +can't directly see or modify it— and one is a <span> element in +which the date is displayed. Note that if the trigger is not specified the +calendar will use the displayArea (or inputField as in the first example). +The display area can have it's own format. This is useful if, for instance, +we need to store one format in the database (thus pass it in the input +field) but we wanna show a friendlier format to the end-user.

    + +
    + +
    + +

    Your birthday: + Click to open date selector.

    + + + + + +
    + +

    Hidden field, display area, trigger image. Very similar to the +previous example. The difference is that we also have a trigger image.

    + +
    + +
    + +

    Your birthday: -- not entered -- .

    + + + + + +
    + +

    Hidden field, display area. Very much like the previous examples, +but we now disable some dates (all weekends, that is, Saturdays and +Sundays).

    + +
    + +
    + +

    Your birthday: + Click to open date selector.

    + + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-2.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-2.html new file mode 100644 index 0000000..1cbe522 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-2.html @@ -0,0 +1,108 @@ + + + + + +Simple calendar setup [flat calendar] + + + + + + + + + + + + + + + + + +

    DHTML Calendar — for the impatient

    + +
    +

    + This page demonstrates how to setup a flat calendar. Examples of + popup calendars are available in another page. +

    +

    + The code in this page uses a helper function defined in + "calendar-setup.js". With it you can setup the calendar in + minutes. If you're not that impatient, ;-) complete documentation is + available. +

    +
    + + + +
    + +
    + + + +

    The positioning of the DIV that contains the calendar is entirely your +job. For instance, the "calendar-container" DIV from this page has the +following style: "float: right; margin-left: 1em; margin-bottom: 1em".

    + +

    Following there is the code that has been used to create this calendar. +You can find the full description of the Calendar.setup() function +in the calendar documentation.

    + +
    <div style="float: right; margin-left: 1em; margin-bottom: 1em;"
    +id="calendar-container"></div>
    +
    +<script type="text/javascript">
    +  function dateChanged(calendar) {
    +    // Beware that this function is called even if the end-user only
    +    // changed the month/year.  In order to determine if a date was
    +    // clicked you can use the dateClicked property of the calendar:
    +    if (calendar.dateClicked) {
    +      // OK, a date was clicked, redirect to /yyyy/mm/dd/index.php
    +      var y = calendar.date.getFullYear();
    +      var m = calendar.date.getMonth();     // integer, 0..11
    +      var d = calendar.date.getDate();      // integer, 1..31
    +      // redirect...
    +      window.location = "/" + y + "/" + m + "/" + d + "/index.php";
    +    }
    +  };
    +
    +  Calendar.setup(
    +    {
    +      flat         : "calendar-container", // ID of the parent element
    +      flatCallback : dateChanged           // our callback function
    +    }
    +  );
    +</script>
    + + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-3.html b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-3.html new file mode 100644 index 0000000..753ca43 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/simple-3.html @@ -0,0 +1,130 @@ + + + + + +Simple calendar setup [flat calendar] + + + + + + + + + + + + + + + + + + + +

    DHTML Calendar — for the impatient

    + +
    +

    + This page demonstrates how to setup a flat calendar. Examples of + popup calendars are available in another page. +

    +

    + The code in this page uses a helper function defined in + "calendar-setup.js". With it you can setup the calendar in + minutes. If you're not that impatient, ;-) complete documenation is + available. +

    +
    + + + +
    + +
    + + + +

    The positioning of the DIV that contains the calendar is entirely your +job. For instance, the "calendar-container" DIV from this page has the +following style: "float: right; margin-left: 1em; margin-bottom: 1em".

    + +

    Following there is the code that has been used to create this calendar. +You can find the full description of the Calendar.setup() function +in the calendar documenation.

    + +
    <div style="float: right; margin-left: 1em; margin-bottom: 1em;"
    +id="calendar-container"></div>
    +
    +<script type="text/javascript">
    +  function dateChanged(calendar) {
    +    // Beware that this function is called even if the end-user only
    +    // changed the month/year.  In order to determine if a date was
    +    // clicked you can use the dateClicked property of the calendar:
    +    if (calendar.dateClicked) {
    +      // OK, a date was clicked, redirect to /yyyy/mm/dd/index.php
    +      var y = calendar.date.getFullYear();
    +      var m = calendar.date.getMonth();     // integer, 0..11
    +      var d = calendar.date.getDate();      // integer, 1..31
    +      // redirect...
    +      window.location = "/" + y + "/" + m + "/" + d + "/index.php";
    +    }
    +  };
    +
    +  Calendar.setup(
    +    {
    +      flat         : "calendar-container", // ID of the parent element
    +      flatCallback : dateChanged           // our callback function
    +    }
    +  );
    +</script>
    + + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/aqua/active-bg.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/aqua/active-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..d608c54698e081a3deae0f1b9b827484deaeacce GIT binary patch literal 89 zcmZ?wbhEHb3xI7cXAAbm`*d3l}e6x_tTajT<-q|NpP}lZBCift^8z p0SG{98JMLwcHQ}C;N`q}uj=cwv(saC#4b@4SZ=W5%`PM literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/aqua/hover-bg.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/aqua/hover-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..fbf94fc2c1891ff891f2d3c3208cf431c35a4628 GIT binary patch literal 89 zcmZ?wbhEHb-E$->CMz|NrfPt>_6 zHL)Z$MWH;iBts!2BUQoO(>H)Y2dIbvWC#PZ6vwVR9}T>mSMODQeRg(w%#PS4t~~0B LE8grwc6hbmm72G|20~mA|fB", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ + background: url("title-bg.gif") repeat-x 0 100%; color: #000; + font-weight: bold; +} + +.calendar .nav { + font-family: verdana,tahoma,sans-serif; +} + +.calendar .nav div { + background: transparent url("menuarrow.gif") no-repeat 100% 100%; +} + +.calendar thead tr { background: url("title-bg.gif") repeat-x 0 100%; color: #000; } + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + padding: 2px; + background: url("title-bg.gif") repeat-x 0 100%; color: #000; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #797979; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #c44; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background: url("hover-bg.gif"); + border-bottom: 1px solid #797979; + padding: 2px 2px 1px 2px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background: url("active-bg.gif"); color: #fff; + padding: 3px 1px 0px 3px; + border-bottom: 1px solid #797979; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: url("dark-bg.gif"); +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + font-family: verdana,tahoma,sans-serif; + width: 2em; + color: #000; + text-align: right; + padding: 2px 4px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #999; +} +.calendar tbody .day.othermonth.oweekend { + color: #f99; +} + +.calendar table .wn { + padding: 2px 3px 2px 2px; + border-right: 1px solid #797979; + background: url("dark-bg.gif"); +} + +.calendar tbody .rowhilite td, +.calendar tbody .rowhilite td.wn { + background: url("rowhover-bg.gif"); +} + +.calendar tbody td.today { font-weight: bold; /* background: url("today-bg.gif") no-repeat 70% 50%; */ } + +.calendar tbody td.hilite { /* Hovered cells */ + background: url("hover-bg.gif"); + padding: 1px 3px 1px 1px; + border: 1px solid #bbb; +} + +.calendar tbody td.active { /* Active (pressed) cells */ + padding: 2px 2px 0px 2px; +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #c44; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + border: 1px solid #797979; + padding: 1px 3px 1px 1px; + background: url("active-bg.gif"); color: #fff; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #565; + color: #fff; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + padding: 2px; + background: url("status-bg.gif") repeat-x 0 0; color: #000; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #afa; + border: 1px solid #084; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #7c7; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border-width: 0 1px 1px 1px; + border-style: solid; + border-color: #797979; + background: url("normal-bg.gif"); color: #000; + z-index: 100; + font-size: 90%; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: url("hover-bg.gif"); color: #000; +} + +.calendar .combo .active { + background: url("active-bg.gif"); color: #fff; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #797979; + padding: 1px 0px; + text-align: center; + background: url("dark-bg.gif"); +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 5px 0px 6px; + font-weight: bold; + background: url("normal-bg.gif"); color: #000; +} + +.calendar td.time .hour, +.calendar td.time .minute { + font-family: monospace; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + background: url("hover-bg.gif"); color: #000; +} + +.calendar td.time span.active { + background: url("active-bg.gif"); color: #fff; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/aqua/title-bg.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/aqua/title-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..6a541b3bc1e4bbee3268e8a5b431e2c7e067b3b9 GIT binary patch literal 116 zcmZ?wbhEHbWMmLyc+AI8Sy_4e_U#7`9z1*Y?D_NOFJ8QO`}Xa-ckkZ6fB*UO=PzHr zeEwc6hbmm72G|20~mA|fBtHB8VX&K*sP!FEoV37-@-w z0R<@%0vdJ3g^a|I?Pj7#(uKh`L|Finie4=6J7+yFJ!?;2&hK|#eqYx=!aJTkdGdK~ zpXAvT*|;uzpq}wF^XC|f7Hy%(3T3cCne7xg0NE&VQse^UpvX;;2at=R3KMyuTq^;2 zC|Y8oD$05(`vPTsz*a#S0tVY?u&+|C9=JNny<&2Wlxxu0Hl1B<&bOHJt%U0!T(_BC zgSodcw-fkw;8z2`7Wg+!zQf>qKnNTBb`ZKuVKa!`hOo;JcIVTBAiY~i59ZSeL+aC| z!@BeVWcDfiw+cT5^1&QG406AoIcj8%=$U~We@)9obve2q{HDt%A^V9eOz8`!W#PUo z{Glyegxu${_yBUTjF`%Z|48DTBtDfyM6y>wiIePzB&H=%lq8Adt`lWUQ^v6JD^_ko zVMxpW0>xpRzl-zJT46#fEanU@Jl2Z$aN#etkRrv0xcG#WQfd*YMOH0xfG5?`f?CQG zRZvSM70ars5}YAe!5FKgv{(qnpg$pmfIbJN473Ck12uqBc&`6pfd*o?R4~A_FpDaG zf^k#kwtL0q(ctCQJ>$_C|68Xo9Y5B%<>HN|rPXUc)#iLZ4#(@;I^sWF!BdIIrn4`- z_ReJJ%ebfY&*2}GiP+Mnwl{8s9^RRq>F%t|b=gjA`^L{W-2=&FGRjoj?dL}ulChUN ztGti>UrgEp&DJF~TgO`%XJ0rw;D5cjZkdINhI+^4JxpY(BDmw(Y^2$Dw;%8S`6J8C z+7+J0mD495S)75uciVQyzK?~28yvw)3bIF5-kaz;!0dbQmF@mI-kmt>7+F`d+N zt#PY&(k@T!8mH}j>(;M_TI-IV)AU=8{=a)`lc$<@jm#z)SE${(>{g=Z!tz!BW;gbH Q9Q54|91Yd!^&U{0QZjy A#Q*>R literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/menuarrow.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/menuarrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..40c0aadfc6e62e7cdf4a0dc4a3a3d735c6995b76 GIT binary patch literal 49 zcmZ?wbhEHbWM^PyXkcV;a&r3r|G(l-7DfgJMg|=QAOOiQFmbfVR-Qb-pUlW$4FDM} B3akJC literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/normal-bg.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/normal-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f413e95d15ef1d094657564f76b6c56e3605116c GIT binary patch literal 50 zcmZ?wbhEHbi_@% literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/rowhover-bg.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/rowhover-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..55d38251c549991821f2c99f8cb5a95c557295cd GIT binary patch literal 50 zcmZ?wbhEHb_ AUH||9 literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/status-bg.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/status-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a0bb57b1df8bf3bfc42a0c2ecc7ab6b3b7cc25a GIT binary patch literal 149 zcmZ?wbhEHbWMmLyIKsg2?Af!24 + Copyright 2005 Marcus Bointon + Subject to the same license as The Coolest DHTML Calendar +*/ + +/* The main calendar widget. DIV containing a table. */ + +div.calendar { position: relative; } + +.calendar, .calendar table { + border: 1px solid #bdb2bf; + font-size: 12px; + color: #000; + cursor: default; + background: url("normal-bg.gif"); + font-family: Myriad, "trebuchet ms",verdana,tahoma,sans-serif; +} + +.calendar { + border-color: #797979; +} + +/* Header part -- contains navigation buttons and day names. */ + +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */ + text-align: center; /* They are the navigation buttons */ + padding: 2px; /* Make the buttons seem like they're pressing */ + background: url("title-bg.gif") repeat-x 0 100%; color: #000; + font-weight: bold; +} + +.calendar .nav { + font-family: Myriad, verdana,tahoma,sans-serif; +} + +.calendar .nav div { + background: transparent url("menuarrow.gif") no-repeat 100% 100%; +} + +.calendar thead tr { background: url("title-bg.gif") repeat-x 0 100%; color: #000; } + +.calendar thead .title { /* This holds the current "month, year" */ + font-weight: bold; /* Pressing it will take you to the current date */ + text-align: center; + padding: 4px; + background: url("title-bg.gif") repeat-x 0 100%; color: #000; +} + +.calendar thead .headrow { /* Row containing navigation buttons */ +} + +.calendar thead .name { /* Cells containing the day names */ + border-bottom: 1px solid #797979; + padding: 2px; + text-align: center; + color: #000; +} + +.calendar thead .weekend { /* How a weekend day name shows in header */ + color: #e22; +} + +.calendar thead .hilite { /* How do the buttons in header appear when hover */ + background: url("hover-bg.gif"); + border-bottom: 1px solid #797979; + padding: 2px 2px 1px 2px; +} + +.calendar thead .active { /* Active (pressed) buttons in header */ + background: url("active-bg.gif"); color: #fff; + padding: 2px 2px 1px 2px; + border-bottom: 1px solid #797979; +} + +.calendar thead .daynames { /* Row containing the day names */ + background: url("dark-bg.gif"); +} + +/* The body part -- contains all the days in month. */ + +.calendar tbody .day { /* Cells containing month days dates */ + font-family: Myriad,verdana,tahoma,sans-serif; + width: 2em; + color: #000; + text-align: right; + padding: 3px 3px 2px 2px; +} +.calendar tbody .day.othermonth { + font-size: 80%; + color: #999; +} +.calendar tbody .day.othermonth.oweekend { + color: #f99; +} + +.calendar table .wn { + padding: 2px 1px 1px 1px; + border-right: 1px solid #797979; + background: url("dark-bg.gif"); +} + +.calendar tbody .rowhilite td, +.calendar tbody .rowhilite td.wn { + background: url("rowhover-bg.gif"); +} + +.calendar tbody td.today { font-weight: bold; } + +.calendar tbody td.hilite { /* Hovered cells */ + background: url("hover-bg.gif"); + padding: 2px 2px 1px 1px; + border: 1px solid #bbb; +} + +.calendar tbody td.active { /* Active (pressed) cells */ +} + +.calendar tbody td.weekend { /* Cells showing weekend days */ + color: #e22; +} + +.calendar tbody td.selected { /* Cell showing selected date */ + font-weight: bold; + border: 1px solid #797979; + padding: 2px 2px 1px 1px; + background: url("active-bg.gif"); color: #fff; +} + +.calendar tbody .disabled { color: #999; } + +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */ + visibility: hidden; +} + +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */ + display: none; +} + +/* The footer part -- status bar and "Close" button */ + +.calendar tfoot .footrow { /* The in footer (only one right now) */ + text-align: center; + background: #565; + color: #fff; +} + +.calendar tfoot .footrow td { /* The in footer (only one right now) */ + padding-top: 4px; +} + +.calendar tfoot .ttip { /* Tooltip (status bar) cell */ + padding: 2px; + background: url("status-bg.gif") repeat-x 0 0; color: #000; +} + +.calendar tfoot .hilite { /* Hover style for buttons in footer */ + background: #afa; + border: 1px solid #084; + color: #000; + padding: 1px; +} + +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */ + background: #7c7; + padding: 2px 0px 0px 2px; +} + +/* Combo boxes (menus that display months/years for direct selection) */ + +.calendar .combo { + position: absolute; + display: none; + top: 0px; + left: 0px; + width: 4em; + cursor: default; + border-width: 0 1px 1px 1px; + border-style: solid; + border-color: #797979; + background: url("normal-bg.gif"); color: #000; + z-index: 100; + font-size: 90%; +} + +.calendar .combo .label, +.calendar .combo .label-IEfix { + text-align: center; + padding: 1px; +} + +.calendar .combo .label-IEfix { + width: 4em; +} + +.calendar .combo .hilite { + background: url("hover-bg.gif"); color: #000; +} + +.calendar .combo .active { + background: url("active-bg.gif"); color: #fff; + font-weight: bold; +} + +.calendar td.time { + border-top: 1px solid #797979; + padding: 1px 0px; + text-align: center; + background: url("dark-bg.gif"); +} + +.calendar td.time .hour, +.calendar td.time .minute, +.calendar td.time .ampm { + padding: 0px 5px 0px 6px; + font-weight: bold; + background: url("normal-bg.gif"); color: #000; +} + +.calendar td.time .hour, +.calendar td.time .minute { + font-family: monospace; +} + +.calendar td.time .ampm { + text-align: center; +} + +.calendar td.time .colon { + padding: 0px 2px 0px 3px; + font-weight: bold; +} + +.calendar td.time span.hilite { + background: url("hover-bg.gif"); color: #000; +} + +.calendar td.time span.active { + background: url("active-bg.gif"); color: #fff; +} diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/title-bg.gif b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/skins/tiger/title-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..75bf48c0952b4307145d43f2cad4f2ea96263d7e GIT binary patch literal 149 zcmZ?wbhEHbWMmLyIKsg2?Af!24 + + + + JS Calendar (positioning test) + + + + + + + + + + + + +
    + + + + + + + +
    + + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/test.php b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/test.php new file mode 100644 index 0000000..4ae18c9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscalendar-1.0/test.php @@ -0,0 +1,116 @@ + + + + + +Test for calendar.php + + + section; it will "echo" code that loads the calendar +// scripts and theme file. +$calendar->load_files(); + +?> + + + + + + + +

    Form submitted

    + + $val) { + echo htmlspecialchars($key) . ' = ' . htmlspecialchars($val) . '
    '; +} ?> + + + +

    Calendar.php test

    + +
    + Select language: +
    + NOTE: as of this release, 0.9.6, only "EN" and "RO", which I + maintain, function correctly. Other language files do not work + because they need to be updated. If you update some language file, + please consider sending it back to me so that I can include it in the + calendar distribution. +
    +
    + +
    + + + + + + + +
    + Date 1: + + make_input_field( + // calendar options go here; see the documentation and/or calendar-setup.js + array('firstDay' => 1, // show Monday first + 'showsTime' => true, + 'showOthers' => true, + 'ifFormat' => '%Y-%m-%d %I:%M %P', + 'timeFormat' => '12'), + // field attributes go here + array('style' => 'width: 15em; color: #840; background-color: #ff8; border: 1px solid #000; text-align: center', + 'name' => 'date1', + 'value' => strftime('%Y-%m-%d %I:%M %P', strtotime('now')))); ?> +
    + +
    + + +
    + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscolor/arrow.gif b/itf/static/js/html5Forms.js/shared/js/jscolor/arrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..246478a864f812d93d4cd0e0d0ad1c8e2d09c825 GIT binary patch literal 66 zcmZ?wbhEHbWM|-JSjfZx1poj4Utv=LM2bII7`Ygj7<53QAbAERVV@R>f}L*~a`L;Z PKCZl?^}@uHk--`OML81Y literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscolor/cross.gif b/itf/static/js/html5Forms.js/shared/js/jscolor/cross.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ee9c7ac517bee40b78aea03afa809631f0b69fa GIT binary patch literal 83 zcmZ?wbhEHb + + jscolor demo + + + + + + Click here: + + + diff --git a/itf/static/js/html5Forms.js/shared/js/jscolor/hs.png b/itf/static/js/html5Forms.js/shared/js/jscolor/hs.png new file mode 100644 index 0000000000000000000000000000000000000000..3d94486cedaf7111d010fdaf2cefad45fd1f878b GIT binary patch literal 2684 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 YzFqsNg>|5V=vOIWZ|#VBZRvIQe;Bk#LI3~& literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscolor/hv.png b/itf/static/js/html5Forms.js/shared/js/jscolor/hv.png new file mode 100644 index 0000000000000000000000000000000000000000..1c5e01f8bcecc4cf835e8eeeaa43ef2c06789022 GIT binary patch literal 2865 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 E0LKozl>h($ literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/jscolor/jscolor.js b/itf/static/js/html5Forms.js/shared/js/jscolor/jscolor.js new file mode 100644 index 0000000..1d7713b --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/jscolor/jscolor.js @@ -0,0 +1,840 @@ +/** + * jscolor, JavaScript Color Picker + * + * @version 1.3.1 + * @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html + * @author Jan Odvarko, http://odvarko.cz + * @created 2008-06-15 + * @updated 2010-01-23 + * @link http://jscolor.com + */ + + +var jscolor = { + + + dir : '', // location of jscolor directory (leave empty to autodetect) + bindClass : 'color', // class name + binding : true, // automatic binding via + preloading : true, // use image preloading? + + + install : function() { + jscolor.addEvent(window, 'load', jscolor.init); + }, + + + init : function() { + if(jscolor.binding) { + jscolor.bind(); + } + if(jscolor.preloading) { + jscolor.preload(); + } + }, + + + getDir : function() { + if(!jscolor.dir) { + var detected = jscolor.detectDir(); + jscolor.dir = detected!==false ? detected : 'jscolor/'; + } + return jscolor.dir; + }, + + + detectDir : function() { + var base = location.href; + + var e = document.getElementsByTagName('base'); + for(var i=0; i vs[a] ? + (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) : + tp[a], + -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ? + (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) : + (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c) + ]; + drawPicker(pp[a], pp[b]); + } + }; + + + this.importColor = function() { + if(!valueElement) { + this.exportColor(); + } else { + if(!this.adjust) { + if(!this.fromString(valueElement.value, leaveValue)) { + styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; + styleElement.style.color = styleElement.jscStyle.color; + this.exportColor(leaveValue | leaveStyle); + } + } else if(!this.required && /^\s*$/.test(valueElement.value)) { + valueElement.value = ''; + styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; + styleElement.style.color = styleElement.jscStyle.color; + this.exportColor(leaveValue | leaveStyle); + + } else if(this.fromString(valueElement.value)) { + // OK + } else { + this.exportColor(); + } + } + }; + + + this.exportColor = function(flags) { + if(!(flags & leaveValue) && valueElement) { + var value = this.toString(); + if(this.caps) { value = value.toUpperCase(); } + if(this.hash) { value = '#'+value; } + valueElement.value = value; + } + if(!(flags & leaveStyle) && styleElement) { + styleElement.style.backgroundColor = + '#'+this.toString(); + styleElement.style.color = + 0.213 * this.rgb[0] + + 0.715 * this.rgb[1] + + 0.072 * this.rgb[2] + < 0.5 ? '#FFF' : '#000'; + } + if(!(flags & leavePad) && isPickerOwner()) { + redrawPad(); + } + if(!(flags & leaveSld) && isPickerOwner()) { + redrawSld(); + } + }; + + + this.fromHSV = function(h, s, v, flags) { // null = don't change + h<0 && (h=0) || h>6 && (h=6); + s<0 && (s=0) || s>1 && (s=1); + v<0 && (v=0) || v>1 && (v=1); + this.rgb = HSV_RGB( + h===null ? this.hsv[0] : (this.hsv[0]=h), + s===null ? this.hsv[1] : (this.hsv[1]=s), + v===null ? this.hsv[2] : (this.hsv[2]=v) + ); + this.exportColor(flags); + }; + + + this.fromRGB = function(r, g, b, flags) { // null = don't change + r<0 && (r=0) || r>1 && (r=1); + g<0 && (g=0) || g>1 && (g=1); + b<0 && (b=0) || b>1 && (b=1); + var hsv = RGB_HSV( + r===null ? this.rgb[0] : (this.rgb[0]=r), + g===null ? this.rgb[1] : (this.rgb[1]=g), + b===null ? this.rgb[2] : (this.rgb[2]=b) + ); + if(hsv[0] !== null) { + this.hsv[0] = hsv[0]; + } + if(hsv[2] !== 0) { + this.hsv[1] = hsv[1]; + } + this.hsv[2] = hsv[2]; + this.exportColor(flags); + }; + + + this.fromString = function(hex, flags) { + var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i); + if(!m) { + return false; + } else { + if(m[1].length === 6) { // 6-char notation + this.fromRGB( + parseInt(m[1].substr(0,2),16) / 255, + parseInt(m[1].substr(2,2),16) / 255, + parseInt(m[1].substr(4,2),16) / 255, + flags + ); + } else { // 3-char notation + this.fromRGB( + parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255, + parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255, + parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255, + flags + ); + } + return true; + } + }; + + + this.toString = function() { + return ( + (0x100 | Math.round(255*this.rgb[0])).toString(16).substr(1) + + (0x100 | Math.round(255*this.rgb[1])).toString(16).substr(1) + + (0x100 | Math.round(255*this.rgb[2])).toString(16).substr(1) + ); + }; + + + function RGB_HSV(r, g, b) { + var n = Math.min(Math.min(r,g),b); + var v = Math.max(Math.max(r,g),b); + var m = v - n; + if(m === 0) { return [ null, 0, v ]; } + var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m); + return [ h===6?0:h, m/v, v ]; + } + + + function HSV_RGB(h, s, v) { + if(h === null) { return [ v, v, v ]; } + var i = Math.floor(h); + var f = i%2 ? h-i : 1-(h-i); + var m = v * (1 - s); + var n = v * (1 - s*f); + switch(i) { + case 6: + case 0: return [v,n,m]; + case 1: return [n,v,m]; + case 2: return [m,v,n]; + case 3: return [m,n,v]; + case 4: return [n,m,v]; + case 5: return [v,m,n]; + } + } + + + function removePicker() { + delete jscolor.picker.owner; + document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB); + } + + + function drawPicker(x, y) { + if(!jscolor.picker) { + jscolor.picker = { + box : document.createElement('div'), + boxB : document.createElement('div'), + pad : document.createElement('div'), + padB : document.createElement('div'), + padM : document.createElement('div'), + sld : document.createElement('div'), + sldB : document.createElement('div'), + sldM : document.createElement('div') + }; + for(var i=0,segSize=4; i",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return o.call(a)=="[object Function]"}function e(a){return typeof a=="string"}function f(){}function g(a){return!a||a=="loaded"||a=="complete"||a=="uninitialized"}function h(){var a=p.shift();q=1,a?a.t?m(function(){(a.t=="c"?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){a!="img"&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l={},o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};y[c]===1&&(r=1,y[c]=[],l=b.createElement(a)),a=="object"?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),a!="img"&&(r||y[c]===2?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i(b=="c"?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),p.length==1&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&o.call(a.opera)=="[object Opera]",l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return o.call(a)=="[object Array]"},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f7)};d.historymanagement=function(){return!!(i.history&&history.pushState)};d.draganddrop=function(){return u("drag")&&u("dragstart")&&u("dragenter")&&u("dragover")&&u("dragleave")&&u("dragend")&&u("drop")};d.websockets=function(){return"WebSocket"in i};d.rgba=function(){m.cssText="background-color:rgba(150,255,150,.5)";return(""+m.backgroundColor).indexOf("rgba")!==-1};d.hsla=function(){m.cssText="background-color:hsla(120,40%,100%,.5)";return(""+ + m.backgroundColor).indexOf("rgba")!==-1};d.multiplebgs=function(){m.cssText="background:url(//:),url(//:),red url(//:)";return/(url\s*\(.*?){3}/.test(m.background)};d.backgroundsize=function(){return r("backgroundSize")};d.borderimage=function(){return r("borderImage")};d.borderradius=function(){return r("borderRadius","",function(a){return(""+a).indexOf("orderRadius")!==-1})};d.boxshadow=function(){return r("boxShadow")};d.opacity=function(){var a=y.join("opacity:.5;")+"";m.cssText=a;return(""+m.opacity).indexOf("0.5")!== + -1};d.cssanimations=function(){return r("animationName")};d.csscolumns=function(){return r("columnCount")};d.cssgradients=function(){var a=("background-image:"+y.join("gradient(linear,left top,right bottom,from(#9f9),to(white));background-image:")+y.join("linear-gradient(left top,#9f9, white);background-image:")).slice(0,-17);m.cssText=a;return(""+m.backgroundImage).indexOf("gradient")!==-1};d.cssreflections=function(){return r("boxReflect")};d.csstransforms=function(){return!!C(["transformProperty", + "WebkitTransform","MozTransform","OTransform","msTransform"])};d.csstransforms3d=function(){var a=!!C(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);if(a){var b=document.createElement("style"),c=e.createElement("div");b.textContent="@media ("+y.join("transform-3d),(")+"modernizr){#modernizr{height:3px}}";e.getElementsByTagName("head")[0].appendChild(b);c.id="modernizr";s.appendChild(c);a=c.offsetHeight===3;b.parentNode.removeChild(b);c.parentNode.removeChild(c)}return a}; + d.csstransitions=function(){return r("transitionProperty")};d.fontface=function(){var a;if(/*@cc_on@if(@_jscript_version>=5)!@end@*/0)a=true;else{var b=e.createElement("style"),c=e.createElement("span"),h,t=false,g=e.body,o,w;b.textContent="@font-face{font-family:testfont;src:url('data:font/ttf;base64,AAEAAAAMAIAAAwBAT1MvMliohmwAAADMAAAAVmNtYXCp5qrBAAABJAAAANhjdnQgACICiAAAAfwAAAAEZ2FzcP//AAMAAAIAAAAACGdseWYv5OZoAAACCAAAANxoZWFk69bnvwAAAuQAAAA2aGhlYQUJAt8AAAMcAAAAJGhtdHgGDgC4AAADQAAAABRsb2NhAIQAwgAAA1QAAAAMbWF4cABVANgAAANgAAAAIG5hbWUgXduAAAADgAAABPVwb3N03NkzmgAACHgAAAA4AAECBAEsAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAACAAMDAAAAAAAAgAACbwAAAAoAAAAAAAAAAFBmRWQAAAAgqS8DM/8zAFwDMwDNAAAABQAAAAAAAAAAAAMAAAADAAAAHAABAAAAAABGAAMAAQAAAK4ABAAqAAAABgAEAAEAAgAuqQD//wAAAC6pAP///9ZXAwAAAAAAAAACAAAABgBoAAAAAAAvAAEAAAAAAAAAAAAAAAAAAAABAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEACoAAAAGAAQAAQACAC6pAP//AAAALqkA////1lcDAAAAAAAAAAIAAAAiAogAAAAB//8AAgACACIAAAEyAqoAAwAHAC6xAQAvPLIHBADtMrEGBdw8sgMCAO0yALEDAC88sgUEAO0ysgcGAfw8sgECAO0yMxEhESczESMiARDuzMwCqv1WIgJmAAACAFUAAAIRAc0ADwAfAAATFRQWOwEyNj0BNCYrASIGARQGKwEiJj0BNDY7ATIWFX8aIvAiGhoi8CIaAZIoN/43KCg3/jcoAWD0JB4eJPQkHh7++EY2NkbVRjY2RgAAAAABAEH/+QCdAEEACQAANjQ2MzIWFAYjIkEeEA8fHw8QDxwWFhwWAAAAAQAAAAIAAIuYbWpfDzz1AAsEAAAAAADFn9IuAAAAAMWf0i797/8zA4gDMwAAAAgAAgAAAAAAAAABAAADM/8zAFwDx/3v/98DiAABAAAAAAAAAAAAAAAAAAAABQF2ACIAAAAAAVUAAAJmAFUA3QBBAAAAKgAqACoAWgBuAAEAAAAFAFAABwBUAAQAAgAAAAEAAQAAAEAALgADAAMAAAAQAMYAAQAAAAAAAACLAAAAAQAAAAAAAQAhAIsAAQAAAAAAAgAFAKwAAQAAAAAAAwBDALEAAQAAAAAABAAnAPQAAQAAAAAABQAKARsAAQAAAAAABgAmASUAAQAAAAAADgAaAUsAAwABBAkAAAEWAWUAAwABBAkAAQBCAnsAAwABBAkAAgAKAr0AAwABBAkAAwCGAscAAwABBAkABABOA00AAwABBAkABQAUA5sAAwABBAkABgBMA68AAwABBAkADgA0A/tDb3B5cmlnaHQgMjAwOSBieSBEYW5pZWwgSm9obnNvbi4gIFJlbGVhc2VkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgT3BlbiBGb250IExpY2Vuc2UuIEtheWFoIExpIGdseXBocyBhcmUgcmVsZWFzZWQgdW5kZXIgdGhlIEdQTCB2ZXJzaW9uIDMuYmFlYzJhOTJiZmZlNTAzMiAtIHN1YnNldCBvZiBKdXJhTGlnaHRiYWVjMmE5MmJmZmU1MDMyIC0gc3Vic2V0IG9mIEZvbnRGb3JnZSAyLjAgOiBKdXJhIExpZ2h0IDogMjMtMS0yMDA5YmFlYzJhOTJiZmZlNTAzMiAtIHN1YnNldCBvZiBKdXJhIExpZ2h0VmVyc2lvbiAyIGJhZWMyYTkyYmZmZTUwMzIgLSBzdWJzZXQgb2YgSnVyYUxpZ2h0aHR0cDovL3NjcmlwdHMuc2lsLm9yZy9PRkwAQwBvAHAAeQByAGkAZwBoAHQAIAAyADAAMAA5ACAAYgB5ACAARABhAG4AaQBlAGwAIABKAG8AaABuAHMAbwBuAC4AIAAgAFIAZQBsAGUAYQBzAGUAZAAgAHUAbgBkAGUAcgAgAHQAaABlACAAdABlAHIAbQBzACAAbwBmACAAdABoAGUAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUALgAgAEsAYQB5AGEAaAAgAEwAaQAgAGcAbAB5AHAAaABzACAAYQByAGUAIAByAGUAbABlAGEAcwBlAGQAIAB1AG4AZABlAHIAIAB0AGgAZQAgAEcAUABMACAAdgBlAHIAcwBpAG8AbgAgADMALgBiAGEAZQBjADIAYQA5ADIAYgBmAGYAZQA1ADAAMwAyACAALQAgAHMAdQBiAHMAZQB0ACAAbwBmACAASgB1AHIAYQBMAGkAZwBoAHQAYgBhAGUAYwAyAGEAOQAyAGIAZgBmAGUANQAwADMAMgAgAC0AIABzAHUAYgBzAGUAdAAgAG8AZgAgAEYAbwBuAHQARgBvAHIAZwBlACAAMgAuADAAIAA6ACAASgB1AHIAYQAgAEwAaQBnAGgAdAAgADoAIAAyADMALQAxAC0AMgAwADAAOQBiAGEAZQBjADIAYQA5ADIAYgBmAGYAZQA1ADAAMwAyACAALQAgAHMAdQBiAHMAZQB0ACAAbwBmACAASgB1AHIAYQAgAEwAaQBnAGgAdABWAGUAcgBzAGkAbwBuACAAMgAgAGIAYQBlAGMAMgBhADkAMgBiAGYAZgBlADUAMAAzADIAIAAtACAAcwB1AGIAcwBlAHQAIABvAGYAIABKAHUAcgBhAEwAaQBnAGgAdABoAHQAdABwADoALwAvAHMAYwByAGkAcAB0AHMALgBzAGkAbAAuAG8AcgBnAC8ATwBGAEwAAAAAAgAAAAAAAP+BADMAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAQACAQIAEQt6ZXJva2F5YWhsaQ==')}"; + e.getElementsByTagName("head")[0].appendChild(b);c.setAttribute("style","font:99px _,arial,helvetica;position:absolute;visibility:hidden");if(!g){g=s.appendChild(e.createElement("fontface"));t=true}c.innerHTML="........";c.id="fonttest";g.appendChild(c);h=c.offsetWidth*c.offsetHeight;c.style.font="99px testfont,_,arial,helvetica";a=h!==c.offsetWidth*c.offsetHeight;var v=function(){if(g.parentNode){a=j.fontface=h!==c.offsetWidth*c.offsetHeight;s.className=s.className.replace(/(no-)?fontface\b/,"")+ + (a?" ":" no-")+"fontface"}};setTimeout(v,75);setTimeout(v,150);addEventListener("load",function(){v();(w=true)&&o&&o(a);setTimeout(function(){t||(g=c);g.parentNode.removeChild(g);b.parentNode.removeChild(b)},50)},false)}j._fontfaceready=function(p){w||a?p(a):(o=p)};return a||h!==c.offsetWidth};d.video=function(){var a=e.createElement("video"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('video/ogg; codecs="theora"');b.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"');b.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}return b}; + d.audio=function(){var a=e.createElement("audio"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('audio/ogg; codecs="vorbis"');b.mp3=a.canPlayType("audio/mpeg;");b.wav=a.canPlayType('audio/wav; codecs="1"');b.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")}return b};d.localStorage=function(){return"localStorage"in i&&i.localStorage!==null};d.sessionStorage=function(){try{return"sessionStorage"in i&&i.sessionStorage!==null}catch(a){return false}};d.webworkers=function(){return!!i.Worker}; + d.applicationCache=function(){var a=i.applicationCache;return!!(a&&typeof a.status!="undefined"&&typeof a.update=="function"&&typeof a.swapCache=="function")};d.svg=function(){return!!e.createElementNS&&!!e.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect};d.smil=function(){return!!e.createElementNS&&/SVG/.test(M.call(e.createElementNS("http://www.w3.org/2000/svg","animate")))};d.svgclippaths=function(){return!!e.createElementNS&&/SVG/.test(M.call(e.createElementNS("http://www.w3.org/2000/svg", + "clipPath")))};for(var z in d)if(O(d,z))N.push(((j[z.toLowerCase()]=d[z]())?"":"no-")+z.toLowerCase());j[E]||P();j.addTest=function(a,b){a=a.toLowerCase();if(!j[a]){b=!!b();s.className+=" "+(b?"":"no-")+a;j[a]=b;return j}};m.cssText="";D=n=null;(function(){var a=e.createElement("div");a.innerHTML="";return a.childNodes.length!==1})()&&function(a,b){function c(f,k){if(o[f])o[f].styleSheet.cssText+=k;else{var l=t[G],q=b[A]("style");q.media=f;l.insertBefore(q,l[G]);o[f]=q;c(f,k)}}function h(f, + k){for(var l=new RegExp("\\b("+w+")\\b(?!.*[;}])","gi"),q=function(B){return".iepp_"+B},x=-1;++x\\s*$","i");g.innerHTML=f.outerHTML.replace(/\r|\n/g," ").replace(l,f.currentStyle.display=="block"?"":"");l=g.childNodes[0];l.className+=" iepp_"+q;l=p[p.length]=[f,l];f.parentNode.replaceChild(l[1],l[0])}h(b.styleSheets,"all")});a.attachEvent("onafterprint", + function(){for(var f=-1,k;++f={0,1}|<={0,1})\s*/g; + var leftBkRe = /\(/g; + var rightBkRe = /\)/g; + var reRe = /~ \"([^\"]*)\"/g; + var equalsRe = / == /g; + var quotedStringRe = /"[^"]*"/g; + var quotedStringOneOnlyRe = /"[^"]*"/; + var placeHolderString = '_pLaCeHoLdEr_'; + var placeHolderRe = new RegExp(placeHolderString); + + var nodesWithEventsAttached = new Array(); + + var inputsToClear; + + var req = null; + + var nameCounter = 0; + var CSSHelpers, StringHelpers, XMLHelpers, DOMHelpers; + /* + * Things to look into: + * + * I don't think you need the options.isPageLoad checks inside + * setFormElementsInside() since we are setting doClear accordingly. + */ + me.init = function(reset){ + if (EventHelpers.hasPageLoadHappened(arguments) && !reset) { + return; + } + + visibleIfNodes = CSSHelpers.getElementsByClassName(document, 'visibleIf'); + mandatoryNodes = CSSHelpers.getElementsByClassName(document, 'mandatoryIf'); + + removeDisabledNodes(); + me.refreshPage({ + isPageLoad: true + }); + setMandatoryStates(); + setEvents(); + //strutsHelpers.populateDynamicFormElements(); + } + + function removeDisabledNodes(){ + + for (var i = 0; i < visibleIfNodes.length; i++) { + var node = visibleIfNodes[i]; + + var els = getAllFormElementsIn(node) + + for (var j = 0; j < els.length; j++) { + var el = els[j]; + el.disabled = false; + + } + } + } + + function refreshPageEvent(e){ + me.refreshPage(); + } + + me.refreshPage = function(options){ + + changedInput = this; + + inputsToClear = new Array(); + qsSb = new StringBuffer(); + for (var i = 0; i < visibleIfNodes.length; i++) { + setVisibility(visibleIfNodes[i], options); + + } + + + if (!(options && !options.isPageLoaded)) { + for (i in inputsToClear) { + var el = inputsToClear[i]; + if (i != 0) { + qsSb.append('&'); + } + qsSb.append(i).append('='); + } + + var qs = qsSb.toString(); + + + if (qsSb.getLength() > 0) { + + var url = DOMHelpers.getDatasetItem(document.body, 'visibleif-deletedataurl'); + + if (url) { + req = XMLHelpers.getXMLHttpRequest(url, deleteRequestHandler, 'GET', qs); + } + + } + + + + for (var i = 0; i < mandatoryNodes.length; i++) { + setMandatoryStates(mandatoryNodes[i], options); + + } + } + + var formNodes = document.getElementsByTagName('form'); + + for (var i=0; i 0) { + + var fieldNode = parentForm[inputVars[j]]; + //var fieldNode = document.getElementById(inputVars[j]); + + if (fieldNode != null) { + if (fieldNode.nodeName != "SELECT" && fieldNode.length) { + for (var k = 0; k < fieldNode.length; k++) { + + EventHelpers.addEvent(fieldNode[k], 'click', refreshPageEvent); + + } + } else { + + EventHelpers.addEvent(fieldNode, 'change', refreshPageEvent); + } + + if (fieldNode.type == 'text') { + + EventHelpers.addEvent(fieldNode, 'change', refreshPageEvent); + } + + if (fieldNode.type == 'checkbox') { + EventHelpers.addEvent(fieldNode, 'click', refreshPageEvent); + } + } + + } + } + } + } + } + } + + } + + function updateVisibilityProperties(formNode){ + var fields = formNode.elements; + + for (var i = 0; i < fields.length; i++) { + var field = fields[i] + if (!isVisible(field) && !CSSHelpers.isMemberOfClass(field, 'visibleIf-submitIfInvisible')) { + CSSHelpers.addClass(field, 'visibleIf-notSubmitted'); + field.disabled = true; + } else { + CSSHelpers.removeClass(field, 'visibleIf-notSubmitted'); + field.disabled = false; + } + } + } + + function formSubmitEvent(e){ + + if (CSSHelpers.isMemberOfClass(this, 'visibleIf-submitInvisibleData')) { + return; + } + + updateVisibilityProperties(this); + } + + function isVisible(node){ + return node.offsetWidth != 0; + } + + + + function setVisibility(node, options){ + var rule = getRule(node, 'visibleIf-rule') + + if (rule == null) { + throw "There is no rule for with the node with the following HTML:" + XMLHelpers.getOuterXML(node); + } + + var isRuleTrue = evaluateRule(DOMHelpers.getAncestorByTagName(node, 'form'), rule); + + + if (isRuleTrue) { + CSSHelpers.addClass(node, 'visibleIf-visible'); + setFormElementsInside(node, false, options); + } else { + CSSHelpers.removeClass(node, 'visibleIf-visible'); + + if (options && options.isPageLoad) { + setFormElementsInside(node, false, options); + } else { + setFormElementsInside(node, true, options); + } + } + } + + function setMandatoryState(node){ + var rule = getRule(node, 'mandatoryIf-rule') + + if (rule == null) { + throw "There is no rule for with the node with the following HTML:" + XMLHelpers.getOuterXML(node); + } + + + var isRuleTrue = evaluateRule(DOMHelpers.getAncestorByTagName(node, 'form'), getRule(node, rule)); + + + if (isRuleTrue) { + CSSHelpers.addClass(node, 'mandatoryIf-mandatory'); + //setFormElementsInside(node, false); + } else { + CSSHelpers.removeClass(node, 'mandatoryIf-mandatory'); + //setFormElementsInside(node, true); + } + + } + + + function evaluateRule(parentForm, rule){ //node, ruleNode) { + //var rule = getRuleString(ruleNode); + + if (rule == "") { + return true; + } else { + + + if (rule != null) { + + //var parentForm = DOMHelpers.getAncestorByTagName(node, 'form'); + if (!parentForm) { + throw "Error: the rule " + rule + " is not attached to a form." + } + + var stringToEval; + + var formElem = parentForm[rule.name]; + + // first, replace all quoted strings with placeholders: + var diddledRule = rule.replace(quotedStringRe, placeHolderString); + + // next, grab all those quoted strings + var quotedVals = rule.match(quotedStringRe); + + + var formId = parentForm.id; + + if (!formId) { + formId = 'visibleIf-form' + nameCounter; + parentForm.id = formId; + + nameCounter++; + } + + + // now replace all variables with javascript form element values + stringToEval = diddledRule.replace(leftBkRe, '( ').replace(rightBkRe, ' )').replace(varRe, 'getFieldValue(document.getElementById("' + + formId + + '")["$1"]) ').replace(reRe, '.match(/$1/)'); + + // now, replace placeholders back to the original strings. + if (quotedVals) { + for (var i = 0; i < quotedVals.length; i++) { + stringToEval = stringToEval.replace(placeHolderRe, quotedVals[i]); + } + } + + + try { + if (eval(stringToEval)) { + return true; + } else { + return false; + } + } + catch (ex) { + //alert('Bad equation: ' + stringToEval) + return false; + } + } + } + } + + + function setFormElementsInside(node, doClear, options){ + + + + if (!options) { + options = {}; + } + + var formElements = getAllFormElementsIn(node); + + for (var i = 0; i < formElements.length; i++) { + + + var el = formElements[i]; + + + /* Let's disable them so they aren't submitted + if (!CSSHelpers.isMemberOfClass(node, 'visibleIf-ignoreDisableAttr')) { + + el.disabled = doClear ? "disabled" : ""; + + if (CSSHelpers.isMemberOfClass(el, 'streetName')) { + jslog.debug(el.disabled); + } + }*/ + if (el != changedInput) { + + switch (el.nodeName) { + case "INPUT": + switch (el.type) { + + case "checkbox": + if (el.checked) { + if (doClear) { + + if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) { + // cache the value + formCache.setValue(el.name, el.value); + el.checked = false; + addToInputToClear(el); + } + + } else if (formCache.getValue(el.name) == el.value) { + //el.checked = true; + + } + } + break; + case "radio": + + if (doClear) { + + if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) { + + // cache the value + if (el.checked) { + formCache.setValue(el.name, el.value); + el.checked = false; + } + addToInputToClear(el); + + } + + } else if (formCache.getValue(el.name) == el.value) { + //el.checked = true; + + } + + break; + + case "file": + + // do nothing to avoid a security error. + break; + case "hidden": + // don't do anything + break; + default: + if (doClear) { + + /* + * The following code is for use with a seperate + * JavaScript library, fileChanger.js. If + * it's a fileChanger widget, we need to do an Ajax call + */ + if (CSSHelpers.isMemberOfClass(el, 'fileList_fileDisplay')) { + CSSHelpers.removeClass(el, 'fileList_fileDisplay'); + el.disabled = false; + el.name = el.name.replace("_ignore", "") + var html = XMLHelpers.getOuterXML(el).replace(/text/, 'file'); + el.parentNode.innerHTML = html; + + // insert ajax call to delete file here. + url = config.getScriptedValue('visibleIf.urls.deleteFiles', { + files: StringHelpers.urlencode(el.value), + formProperty: el.name + }) + req = XMLHelpers.getXMLHttpRequest(url, deleteRequestHandler); + } + + + // cache the value + formCache.setValue(el.name, el.value); + if (options.isPageLoad) { + el.value = DOMHelpers.getAttributeValue(el, 'value'); + if (el.value == "null") { + el.value = ""; + } + } else if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) { + el.value = ""; + addToInputToClear(el); + } + + } else { + //el.value = formCache.getValue(el.name); + } + break; + } + break; + case "TEXTAREA": + if (doClear) { + // cache the value + formCache.setValue(el.name, el.value); + if (options.isPageLoad) { + //el.value = DOMHelpers.getAttributeValue(el, 'value'); + } else if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) { + el.value = ""; + addToInputToClear(el); + } + } else { + //el.value = formCache.getValue(el.name); + } + + break; + case "SELECT": + if (doClear) { + + if (!CSSHelpers.isMemberOfClass(el, 'visibleIf-doNotReset')) { + // cache the value + formCache.setValue(el.name, el.selectedIndex); + + // TODO: should this be 0 or -1? + el.selectedIndex = 0; + addToInputToClear(el); + } + + el.disabled = true; + + } else { + //el.selectedValue = formCache.getValue(el.name); + el.disabled = false; + } + break; + + + } + } + + } + + + + + + + + } + + function addToInputToClear(el){ + if (!inputsToClear[el.name]) { + inputsToClear[el.name] = el; + } + } + + function deleteRequestHandler(){ + + if (!req) { + return; + } + + // only if req shows "complete" + if (req.readyState == ReadyState.COMPLETED) { + // only if "OK" + //DebugHelpers.log(req.getAllResponseHeaders()); + + if (req.status == HttpCode.OK || req.status == HttpCode.LOCAL_OK) { + // whatever + //jslog.debug('Deleted Successfully') + } else { + throw "Something bad happened. HTTP Status: " + req.status; + + } + } + } + + + function getInputVars(rule){ + rule = rule.replace(leftBkRe, '( ').replace(rightBkRe, ' )'); + var vars = rule.match(varRe); + + if (vars == null) { + return new Array(); + } + + for (var i = 0; i < vars.length; i++) { + vars[i] = vars[i].trim(); + } + + + return vars; + + } + + + function getFieldValue(formElementNode){ + var r = ""; + var type; + + type = formElementNode.type + + if (!type) { + if (formElementNode.length) + type = formElementNode[0].type; + } + + + switch (type) { + + case 'text': + case 'hidden': + case 'password': + case 'textarea': + case 'select-one': + r = formElementNode.value; + case 'checkbox': + if (formElementNode.checked) { + r = formElementNode.value; + } + break; + case 'radio': + for (var i = 0; i < formElementNode.length; i++) { + if (formElementNode[i].checked) { + r = formElementNode[i].value; + break; + } + } + + + } + + if (formElementNode.length) { + for (var i = 0; i < formElementNode.length; i++) { + if (formElementNode[i].checked) { + r = formElementNode[i].value; + } + } + + } + + return r.replace('\n', '').replace(' ', ''); + } + + function getAllFormElementsIn(node){ + if (!node) { + node = document; + } + + var r = new Array(); + + var elems = { + inputs: node.getElementsByTagName('input'), + selects: node.getElementsByTagName('select'), + textareas: node.getElementsByTagName('textarea') + }; + + for (var i in elems) { + var elem = elems[i]; + for (j = 0; j < elem.length; j++) { + r.push(elem[j]); + } + } + + return r; + } + + + /* Helper routines */ + if (window.CSSHelpers) { + CSSHelpers = window.CSSHelpers; + } else { + CSSHelpers = new function(){ + var me = this; + var blankRe = new RegExp('\\s'); + + /** + * Generates a regular expression string that can be used to detect a class name + * in a tag's class attribute. It is used by a few methods, so I + * centralized it. + * + * @param {String} className - a name of a CSS class. + */ + function getClassReString(className){ + return '\\s' + className + '\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className + '$'; + } + + function getClassPrefixReString(className){ + return '\\s' + className + '-[0-9a-zA-Z_]+\\s|^' + className + '[0-9a-zA-Z_]+\\s|\\s' + className + '[0-9a-zA-Z_]+$|' + '^' + className + '[0-9a-zA-Z_]+$'; + } + + + + /** + * Make an HTML object be a member of a certain class. + * + * @param {Object} obj - an HTML object + * @param {String} className - a CSS class name. + */ + me.addClass = function(obj, className){ + if (blankRe.test(className)) { + return; + } + + // only add class if the object is not a member of it yet. + if (!me.isMemberOfClass(obj, className)) { + obj.className += " " + className; + } + } + + /** + * Make an HTML object *not* be a member of a certain class. + * + * @param {Object} obj - an HTML object + * @param {Object} className - a CSS class name. + */ + me.removeClass = function(obj, className){ + + if (blankRe.test(className)) { + return; + } + + + var re = new RegExp(getClassReString(className), "g"); + + var oldClassName = obj.className; + + + if (obj.className) { + obj.className = oldClassName.replace(re, ''); + } + + + } + + /** + * Given an HTML element, find all child nodes of a specific class. + * + * With ideas from Jonathan Snook + * (http://snook.ca/archives/javascript/your_favourite_1/) + * Since this was presented within a post on this site, it is for the + * public domain according to the site's copyright statement. + * + * @param {Object} obj - an HTML element. If you want to search a whole document, set + * this to the document object. + * @param {String} className - the class name of the objects to return + * @return {Array} - the list of objects of class cls. + */ + me.getElementsByClassName = function(obj, className){ + if (obj.getElementsByClassName) { + return DOMHelpers.nodeListToArray(obj.getElementsByClassName(className)) + } else { + var a = []; + var re = new RegExp(getClassReString(className)); + var els = DOMHelpers.getAllDescendants(obj); + + for (var i = 0, j = els.length; i < j; i++) { + if (re.test(els[i].className)) { + a.push(els[i]); + + } + } + return a; + } + } + + /** + * Determines if an HTML object is a member of a specific class. + * @param {Object} obj - an HTML object. + * @param {Object} className - the CSS class name. + */ + me.isMemberOfClass = function(obj, className){ + + if (blankRe.test(className)) + return false; + + var re = new RegExp(getClassReString(className), "g"); + + return (re.test(obj.className)); + } + } + } + + if (window.DOMHelpers) { + DOMHelpers = window.DOMHelpers; + } else { + DOMHelpers = new function(){ + + var me = this; + /** + * Given an tag, find the first ancestor tag of a given tag name. + * + * @param {Object} obj - a HTML or XML tag. + * @param {String} tagName - the name of the ancestor tag to find. + * @return {Object} - the ancestor tag, or null if not found. + */ + /** + * Returns all children of an element. Needed if it is necessary to do + * the equivalent of getElementsByTagName('*') for IE5 for Windows. + * + * @param {Object} e - an HTML object. + */ + me.getAllDescendants = function(obj){ + return obj.all ? obj.all : obj.getElementsByTagName('*'); + } + + me.getAncestorByTagName = function(obj, tagName){ + + for (var node = obj.parentNode; node.nodeName.toLowerCase() != 'body'; node = node.parentNode) { + + if (tagName.toLowerCase() == node.nodeName.toLowerCase()) { + return node; + } + + } + return null; + } + + /** + * Given an HTML or XML object, find the an attribute by name. + * + * @param {Object} obj - a DOM object. + * @param {String} attrName - the name of an attribute inside the DOM object. + * @return {Object} - the attribute object or null if there isn't one. + */ + me.getAttributeByName = function(obj, attrName){ + var i; + + var attributes = obj.attributes; + for (i = 0; i < attributes.length; i++) { + var attr = attributes[i] + if (attr.nodeName == attrName && attr.specified) { + return attr; + } + } + return null; + } + + /** + * Given an HTML or XML object, find the value of an attribute. + * + * @param {Object} obj - a DOM object. + * @param {String} attrName - the name of an attribute inside the DOM object. + * @return {String} - the value of the attribute. + */ + me.getAttributeValue = function(obj, attrName){ + var attr = me.getAttributeByName(obj, attrName); + + if (attr != null) { + return attr.nodeValue; + } else { + return null; + } + } + + me.getDatasetItem = function(obj, name){ + var r = DOMHelpers.getAttributeValue(obj, 'data-' + name); + + if (!r) { + r = DOMHelpers.getAttributeValue(obj, 'data-' + name.toLowerCase()) + } + return r; + } + + /****** + * Converts a DOM live node list to a static/dead array. Good when you don't + * want the thing you are iterating in a for loop changing as the DOM changes. + * + * @param {Object} nodeList - a node list (like one returned by document.getElementsByTagName) + * @return {Array} - an array of nodes. + * + *******/ + me.nodeListToArray = function(nodeList){ + var ary = []; + for (var i = 0, len = nodeList.length; i < len; i++) { + ary.push(nodeList[i]); + } + return ary; + } + + } + } + + if (window.StringHelpers) { + StringHelpers = window.StringHelpers; + } else { + StringHelpers = new function(){ + var me = this; + me.initWhitespaceRe = /^\s\s*/; + me.endWhitespaceRe = /\s\s*$/; + me.whitespaceRe = /\s/; + + me.unentify = function(s){ + + return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); + } + + me.urlencode = function(str){ + return escape(str).replace('+', '%2B').replace('%20', '+').replace('*', '%2A').replace('/', '%2F').replace('@', '%40'); + } + + } + } + + if (window.XMLHelpers) { + XMLHelpers = window.XMLHelpers; + } else { + XMLHelpers = new function(){ + var me = this; + + /** + * Given an XML node, return the XML inside as a string and the XML string of the node itself. + * Similar to Internet Explorer's outerHTML property, except it is for XML, not HTML. + * Created with information from http://www.codingforums.com/showthread.php?t=31489 + * and http://www.mercurytide.co.uk/whitepapers/issues-working-with-ajax/ + * + * @param {Object} node - a DOM object. + * @param {Object} options - a JS object containing options. To date, + * the only one supported is "insertClosingTags", when set to + * true, converts self closing tags, like , to . + * @return {String} - the XML String inside the object. + */ + me.getOuterXML = function(node, options){ + var r; + // Internet Explorer + if (node.xml) { + r = node.xml; + + // Everyone else + } else if (node.outerHTML) { + r = node.outerHTML; + } else if (window.XMLSerializer) { + + var serializer = new XMLSerializer(); + var text = serializer.serializeToString(node); + r = text; + } else { + return null; + } + + /* + * If the XML is actually HTML and you are inserting it into an HTML + * document, you must use the "insertClosingTags" option, otherwise + * Opera will not like you, especially if you have empty tags. + */ + if (options) { + if (options.insertClosingTags) { + r = r.replace(selfClosingTagRe, "<$1>"); + } + } + return r; + } + + /** + * Wrapper for XMLHttpRequest Object. Grabbing data (XML and/or text) from a URL. + * Grabbing data from a URL. Input is one parameter, url. It returns a request + * object. Based on code from + * http://www.xml.com/pub/a/2005/02/09/xml-http-request.html. IE caching problem + * fix from Wikipedia article http://en.wikipedia.org/wiki/XMLHttpRequest + * + * @param {String} url - the URL to retrieve + * @param {Function} processReqChange - the function/method to call at key events of the URL retrieval. + * @param {String} method - (optional) "GET" or "POST" (default "GET") + * @param {String} data - (optional) the CGI data to pass. Default null. + * @param {boolean} isAsync - (optional) is this call asyncronous. Default true. + * + * @return {Object} a XML request object. + */ + me.getXMLHttpRequest = function(url, processReqChange) //, method, data, isAsync) + { + var argv = me.getXMLHttpRequest.arguments; + var argc = me.getXMLHttpRequest.arguments.length; + var httpMethod = (argc > 2) ? argv[2] : 'GET'; + var data = (argc > 3) ? argv[3] : ""; + var isAsync = (argc > 4) ? argv[4] : true; + + var req; + // branch for native XMLHttpRequest object + if (window.XMLHttpRequest) { + req = new XMLHttpRequest(); + // branch for IE/Windows ActiveX version + } else if (window.ActiveXObject) { + try { + req = new ActiveXObject('Msxml2.XMLHTTP'); + } + catch (ex) { + req = new ActiveXObject("Microsoft.XMLHTTP"); + } + // the browser doesn't support XML HttpRequest. Return null; + } else { + return null; + } + + if (isAsync) { + req.onreadystatechange = processReqChange; + } + + if (httpMethod == "GET" && data != "") { + url += "?" + data; + } + + req.open(httpMethod, url, isAsync); + + //Fixes IE Caching problem + req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); + req.send(data); + + return req; + } + + } + } + + /* + * stringBuffer - ideas from + * http://www.multitask.com.au/people/dion/archives/000354.html + */ + function StringBuffer(){ + var me = this; + + var buffer = []; + + + me.append = function(string){ + buffer.push(string); + return me; + } + + me.appendBuffer = function(bufferToAppend){ + buffer = buffer.concat(bufferToAppend); + } + + me.toString = function(){ + return buffer.join(""); + } + + me.getLength = function(){ + return buffer.length; + } + + me.flush = function(){ + buffer.length = 0; + } + + } + + /* + * Adding trim method to String Object. Ideas from + * http://www.faqts.com/knowledge_base/view.phtml/aid/1678/fid/1 and + * http://blog.stevenlevithan.com/archives/faster-trim-javascript + */ + String.prototype.trim = function(){ + var str = this; + + // The first method is faster on long strings than the second and + // vice-versa. + if (this.length > 6000) { + str = this.replace(StringHelpers.initWhitespaceRe, ''); + var i = str.length; + while (StringHelpers.whitespaceRe.test(str.charAt(--i))) + ; + return str.slice(0, i + 1); + } else { + return this.replace(StringHelpers.initWhitespaceRe, '').replace(StringHelpers.endWhitespaceRe, ''); + } + }; + +} + +var formCache = new function(){ + var me = this; + var values = new Array(); + + me.setValue = function(name, value){ + values[name] = value; + } + + me.getValue = function(name){ + if (values[name] == undefined) { + return ""; + } else { + return values[name]; + } + } +} + +EventHelpers.addPageLoadEvent('visibleIf.init'); + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/.DS_Store b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..72a32cf10859c540b3e8b4eda3787deaca8cdf5e GIT binary patch literal 6148 zcmeHKPiz!b82`TQ0yB&wuP9Le5Ep7hV?(w`sqs(PZd-x^w$LqGq_)iNJnY2Tna#Y} zU9=PyuSBC44@3hu;>E-W;!&ef;>ko~f+youFP^-3@OyvO*c6W#HS;C!{l53UfAfCx z=gk8EEVuk&00saSHHrC+)ZIp;UA8rnGcyuV<%l7H1_;#Xt4CNc&x2L5df$amL< z4sfW!Y52?gE1I=1u95YFS~CnpS}cB#xxW0m^&2dbyXLDwI3#`Ecvk~IU0P(@mY4U8?j0(OjI0b5miG;lI=Xjs zWyL08pITdX?tbQA#alkRa_+n)5b1lP#5LH13#8m;J)vlu_2jPh*7HMeJ@!V&aqoWq z(BZ8|#ugcC34V-+UK+IdgqL!$$TkUD-*fdinof8-;GIR*U-!a#i=6ma7|sN*aZ#D@Ub16TQN*|eMm1*up5hv-m3Y-flzxLWJYfLp|usF^WL1^37 ztxc?d^F8-&*}83D$0LsyN1ob0IaiMx4IZUp-lr=$68pjFfcq!qU_9Z}`xQZTXG5>X z!^$gk$Et0euM&9;z91bBdm^1`@`(H2-FN>34{moJa%ahrpE==)I*`Z?^3lL zh@cj7w!!YlAxnAhbRTvYTI{;5hP&LyT$ZDuwhpX zicp5*umDYX6)wU%a2c+_b@&)=z}N6C{0P6mukaiEj(N0k0C(Un9L7=Hk7HQINj!j4 zcodIe1!r*qPoal(^s#|4HZehgXYm}K#|!v6Uc@)>O?(UA#!L7vzK56b3cimY;zxK5 zZ{R2R8Gepm;FtIneuKC0Cw+yv-h=!?@8UJ$&#T9GVq{8N&Yeh}<;)n!82C>!Aioa< zY7$EZyBgJ}gF5;9AnkdHQb?C)35f-RC4*g!WFbKvN~lB895GOb(|p1Bl?-+@>Tp0+ znev#*Xig}os?&TyxdWCoW_`v$#=vR@`t*>={eSZB&;P4~vQfrB#=!rI0nAU#Oq6L! zW^Y}yIJwsrsGXuFMf!C$su1eTcB~Y+6%SBTLbifb2ulXL8fk_k`w>tyWL?I + + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/.mymetadata b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/.mymetadata new file mode 100644 index 0000000..0e2fe5e --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/.mymetadata @@ -0,0 +1,13 @@ + + + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/.project b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/.project new file mode 100644 index 0000000..1878e08 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/.project @@ -0,0 +1,38 @@ + + + webforms2 + + + + + + com.genuitec.eclipse.j2eedt.core.WebClasspathBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.genuitec.eclipse.j2eedt.core.J2EEProjectValidator + + + + + com.genuitec.eclipse.j2eedt.core.DeploymentDescriptorValidator + + + + + org.eclipse.wst.validation.validationbuilder + + + + + + com.genuitec.eclipse.j2eedt.core.webnature + org.eclipse.jdt.core.javanature + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/DTD/xhtml1-strict-wf2.dtd b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/DTD/xhtml1-strict-wf2.dtd new file mode 100644 index 0000000..153c8d8 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/DTD/xhtml1-strict-wf2.dtd @@ -0,0 +1,1075 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/DTD/xhtml1-transitional-wf2.dtd b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/DTD/xhtml1-transitional-wf2.dtd new file mode 100644 index 0000000..5ae33c2 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/DTD/xhtml1-transitional-wf2.dtd @@ -0,0 +1,1294 @@ + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/META-INF/MANIFEST.MF b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/META-INF/MANIFEST.MF new file mode 100644 index 0000000..5e94951 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/WEB-INF/web.xml b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/WEB-INF/web.xml new file mode 100644 index 0000000..cb0657f --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/WEB-INF/web.xml @@ -0,0 +1,10 @@ + + + + index.jsp + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/index.jsp b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/index.jsp new file mode 100644 index 0000000..d871e53 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/WebRoot/index.jsp @@ -0,0 +1,26 @@ +<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> +<% +String path = request.getContextPath(); +String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; +%> + + + + + + + My JSP 'index.jsp' starting page + + + + + + + + + + This is my JSP page.
    + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/pack.pl b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/pack.pl new file mode 100644 index 0000000..8df6483 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/pack.pl @@ -0,0 +1,269 @@ + +use File::Copy; + +@commonVarNames = qw( +xhr +processAttr +parent +attrName +attr +distance +evt +btnType +attrValue +addEvt +moveEvt +isValid +refNode +removeEvt +attrs +sibling +minAttrNode +maxAttrNode +rtNestedDepth +repetitionTemplates +eventSet +isTimeRelated +IDAttrValue +formElements +handleRepetitionEvent +funcBody +deprecatedAttrs +indexAttr +attrVal +reTemplateName +results +invalidIndicator +doCheckPrecision +typeArg +IDAttrName +xmlDoc +elementArg + +code +funcMatches +hasChecked +canBubbleArg +valueAttrNode +repeatTemplateAttr +doMaxLengthCheck +isRequired + +handlerAttr +isDateRelated +matches +onremovedAttr +isNumberRelated +currentBlockCount +count +isRadioOrCheckbox +isNotEqual +isFileInput +isTemplate +elNames +allElements +oninvalidAttr +attrExpr +hasIndex +addBtns +thisAttrValue +cancelableArg +btns +doCheckRange +doRequiredCheck +zeroPoint +invalidIndicators +indicatorTimeoutId +indicatorIntervalId +addInvalidIndicator +createLI +clearInvalidIndicators +cloneNode_customAttrs +cloneNode_skippedAttrs +cloneNode_rtEventHandlerAttrs +getRepetitionBlock +getHtmlTemplate +getFormElements +getElementsByTagNames +getElementsByTagNamesAndAttribute +arrayHasItem +getElementStyle +createMiscFunctions +ISO8601RegExp +parseISO8601 +validateDateTimeType +zeroPad +dateToISO8601 +namespaceURIArg +initAutofocusElement +isInitialized +applyValidityInterface +controlCheckValidity +controlSetCustomValidity +formCheckValidity +createValidityState +loadDataURI +numberRegExp +onsubmitValidityHandler +constructRepetitionBlock +clickRepetitionButton +constructRepetitionButton +constructRepetitionTemplate +sortNodes +updateValidityState +urlRegExp +valueToWF2Type +emailRegExp +hasInvalidState +libpath +DOMException +isInitialized +updateAddButtons +updateMoveButtons +property +visitedParents +rePattern +patternAttr +hasInvalidIndicator +prefillSelectElements +prefillFormElements +hasElementExtensions +hasGettersAndSetters +); +#onDOMContentLoaded + +push @commonVarNames, '(?<=2\.|\s\s)cloneNode'; #\$wf2\.|\s +push @commonVarNames, '(?<=2\.|\s\s)createElement'; +push @commonVarNames, '(?<=2\.|\s\s)addRepetitionBlock(?!:1)'; +push @commonVarNames, '(?<=2\.|\s\s)addRepetitionBlockByIndex(?!:1)'; +push @commonVarNames, '(?<=2\.|\s\s)removeRepetitionBlock(?!:1)'; +push @commonVarNames, '(?<=2\.|\s\s)moveRepetitionBlock(?!:1)'; + +%replacements = ( + 'RepetitionElement.REPETITION_NONE' => 0, + 'RepetitionElement.REPETITION_TEMPLATE' => 1, + 'RepetitionElement.REPETITION_BLOCK' => 2, + 'XPathResult.ORDERED_NODE_SNAPSHOT_TYPE' => 7 +); + +open IN, "webforms2_src.js"; +$source = join "", ; +close IN; + +$source =~ m{^(.+?)(\s+if\(!window\.\$wf2\).+$)}s; +$header = $1; +$code = $2; + + +#strip all comments +open NOCOM, ">webforms2-nocomments.js"; +$nocoms = $code; +$nocoms =~ s{\s*(?webforms2-nocomments-nowhitespace.js"; +$nowhite = $nocoms; +$nowhite =~ s{ +}{ }g; +$nowhite =~ s{ +,}{,}g; +$nowhite =~ s{^\s+}{}gm; #remove all non-newline whitespace +$thisHeader = $header; +$thisHeader =~ s{\bwebforms.+?js\b}{webforms2-nocomments-nowhitespace.js}; +print NOWHITE $thisHeader . "\n" . $nowhite; +close NOWHITE; + +open MAINS, ">webforms2.js"; +$thisHeader = $header; +$thisHeader =~ s{\bwebforms.+?js\b}{webforms2.js}; +print MAINS $thisHeader . "\n\n" . $nowhite; +close MAINS; + +#shorten long variable names +open SHORT, ">webforms2-nocomments-nowhitespace-shortnames.js"; +$short = $nocoms; +$count = 0; +foreach(@commonVarNames){ + $re = /\W/ ? $_ : '(? 1024){ + $lineSize = 0; + $newShort .= $_ . "\n"; + } + else { + $newShort .= $_; + } + +} + +$thisHeader = $header; +$thisHeader =~ s{\bwebforms.+?js\b}{webforms2-nocomments-nowhitespace-shortnames.js}; +print SHORT $thisHeader . "\n\n" . $newShort; +close SHORT; + + +#open MAINS, ">webforms2-p.js"; +#$thisHeader = $header; +#$thisHeader =~ s{\bwebforms.+?js\b}{webforms2-p.js}; +#print MAINS $thisHeader . "\n\n" . $newShort; +#close MAINS; + + + + +#use Dean Edward's packer to condense the code +open PACKED, ">webforms2-p.js"; +$packed = jsPack($short); +$thisHeader = $header; +$thisHeader =~ s{\bwebforms.+?js\b}{webforms2-p.js}; +print PACKED $thisHeader . "\n\n" . $packed; +close PACKED; +sub jsPack { + open TEMP, ">~topack.js"; + print TEMP shift; + close TEMP; + + chdir('./packer.perl/'); + my $packed = `perl jsPacker.pl -q -f -e0 -i ../~topack.js`; #-e62 -f #-e62 + chdir('..'); + + unlink "~topack.js"; + return $packed; +} + + + +exit; + +#$source =~ s{(/\*\@cc_on \@\*/\n/\*\@if \(\@_win32\).+?/\*\@end \@\*/)} +# {MSIE_ONDOMCONTENTLOADED();}s; +#(?=/\*\s+cssQuery) + + +#$source =~ s{var RepetitionElement.+?(?=/\*\@cc_on \@\*/)} +# {SOURCE1}es; +#$source =~ s{var RepetitionElement.+?(?=/\*\@cc_on \@\*/)} +# {SOURCE1}es; +#$source =~ s{(?<=/\*\@cc_on \@\*/\n/\*\@if \(\@_win32\))(.+?)(?=/\*\@end \@\*/)} +# {SOURCE2}es; diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/project.kpf b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/project.kpf new file mode 100644 index 0000000..cc305d0 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/project.kpf @@ -0,0 +1,7 @@ + + + + + 1 + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-msie_init.js b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-msie_init.js new file mode 100644 index 0000000..93af8ca --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-msie_init.js @@ -0,0 +1,4 @@ +//Loaded dynamically in MSIE by script[defer] tag which emulated DOMContentLoaded event. See +if(!window.ValidityState) + throw Error("Validation error: You must include the file 'wf2-validation.js' to enable the functionality. The file you included is loaded dynamically for MSIE."); +window.ValidityState.__initDescendents(); \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/001.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/001.html new file mode 100644 index 0000000..b3785a9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/001.html @@ -0,0 +1,114 @@ + + + + + Test Page + + + + + + + + + + + +
    If you were using Internet Explorer 6 on a Windows machine or Opera 9, this demo would actually work!
    + + + + +

    Validation

    + +

    WF2 introduces built-in validation on the client-side.

    +

    In this example, the input field is declared "required", which means the form cannot be submitted if the field is empty. Instead an error message will be displayed to the user.

    + +
    +
    + + +
    +
    + +

    The code looks like this: +

    +<form>
    +  <input name="textfield" type="text" required>
    +  <button type=submit>Submit me</button>
    +</form>
    +
    + +

    This field requires a number between 18 and 99: + +

    +
    + Age: + +
    +
    + +

    The code looks like this: +

    +<form>
    +  Age:  <input name="age"  type="number" min="18" max="99" required>
    +  <button type=submit>Submit me</button>
    +</form>
    +
    + +

    Here is a sample form using an assortment of the new validation constraints:

    + +
    +
    +

    (must be an email adress)

    +

    (must be an URI)

    +

    (must be between 18 and 90)

    +

    (decimal, will be rounded to two decimals)

    +

    + +
    +
    + +

    (There are also several date and time related controls, but they are described in a seperate section.)

    + + +

    Custom validation

    + +

    Of course, the built-in types and constraints cannot cover every use case. Therefore it is possible to hook custom code into the validation system. + +

    +
    + + Number: + +
    +
    + + +

    The code for the control looks like this: +

    +<input name="num" type="number" onchange="if(isSquareNumber(value)) setCustomValidity('Must be a square number'); else setCustomValidity()">
    +
    + +

    The method setCustomValidity called with an error message, indicates that the control is not valid. +The message will be display, if the user tries to submit the form. If setCustomValidity is called without an argument, the field is considered valid again

    + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/002.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/002.html new file mode 100644 index 0000000..a139f7e --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/002.html @@ -0,0 +1,12 @@ + + + Test 2 + + + +
    + + +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/003.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/003.html new file mode 100644 index 0000000..dcaa98f --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/003.html @@ -0,0 +1,115 @@ + + + Test 3 + + + + + + + + +
    +
    +
    +
    + +
    +
    + + +
    + Event Log + + + + + + + + + + +
    #TypeElementInvalid states
    +
    (Click the add button above to fire events)
    +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/demo.css b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/demo.css new file mode 100644 index 0000000..deb6537 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/demo.css @@ -0,0 +1,44 @@ +body { + font-family: georgia; + font-size: 10pt; + margin: 2em; + margin-left: 4em; + } +h1, h2 { + font-family: trebuchet ms; +} + +form { + margin: 0 + } +.example { + background: #e8e8e8; + font-family: verdana; + width: 400px; + padding: 1em; + margin: 1em; +} +p { + width: 500px; +} + +pre { + margin-left: 2em; +} +pre, code { + color: teal; +} + +pre strong { + background: yellow; +} + + + .sidemenu { float:right; width:200px; border: solid black 2px; padding: 1em;} + .sidemenu div { } + .sidemenu div.current a { background: blue; color: white; } + .sidemenu a { text-decoration: none; font-weight: bold; } + + #platformWarning { + position:absolute;left:0;top:0;width:100%;background:yellow;border:solid 1px;font-family:verdana; font-size: 8pt; + } \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/jsUnitCore.js b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/jsUnitCore.js new file mode 100644 index 0000000..02f0402 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation-testcases/jsUnitCore.js @@ -0,0 +1,422 @@ +/* jsUnit */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Edward Hieatt code. + * + * The Initial Developer of the Original Code is + * Edward Hieatt, edward@jsunit.net. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Edward Hieatt, edward@jsunit.net (original author) + * Bob Clary, bc@bclary.com + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +var JSUNIT_UNDEFINED_VALUE; +var isTestPageLoaded = false; + +//hack for NS62 bug +function jsUnitFixTop() { + var tempTop = top; + if (!tempTop) { + tempTop = window; + while (tempTop.parent) { + tempTop = tempTop.parent; + if (tempTop.top && tempTop.top.jsUnitTestSuite) { + tempTop = tempTop.top; + break; + } + } + } + try { + window.top = tempTop; + } catch (e) {} +} + +jsUnitFixTop(); + +function _displayStringForValue(aVar) { + if (aVar === null) + return 'null'; + + if (aVar === top.JSUNIT_UNDEFINED_VALUE) + return 'undefined'; + + return aVar; +} + +function fail(failureMessage) { + throw new JsUnitException(null, failureMessage); +} + +function error(errorMessage) { + var errorObject = new Object(); + errorObject.description = errorMessage; + errorObject.stackTrace = getStackTrace(); + throw errorObject; +} + +function argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) { + return args.length == expectedNumberOfNonCommentArgs + 1; +} + +function commentArg(expectedNumberOfNonCommentArgs, args) { + if (argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) + return args[0]; + + return null; +} + +function nonCommentArg(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) { + return argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ? + args[desiredNonCommentArgIndex] : + args[desiredNonCommentArgIndex - 1]; +} + +function _validateArguments(expectedNumberOfNonCommentArgs, args) { + if (!( args.length == expectedNumberOfNonCommentArgs || + (args.length == expectedNumberOfNonCommentArgs + 1 && typeof(args[0]) == 'string') )) + error('Incorrect arguments passed to assert function'); +} + +function _assert(comment, booleanValue, failureMessage) { + if (!booleanValue) + throw new JsUnitException(comment, failureMessage); +} + +function assert() { + _validateArguments(1, arguments); + var booleanValue=nonCommentArg(1, 1, arguments); + + if (typeof(booleanValue) != 'boolean') + error('Bad argument to assert(boolean)'); + + _assert(commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false'); +} + +function assertTrue() { + _validateArguments(1, arguments); + var booleanValue=nonCommentArg(1, 1, arguments); + + if (typeof(booleanValue) != 'boolean') + error('Bad argument to assertTrue(boolean)'); + + _assert(commentArg(1, arguments), booleanValue === true, 'Call to assertTrue(boolean) with false'); +} + +function assertFalse() { + _validateArguments(1, arguments); + var booleanValue=nonCommentArg(1, 1, arguments); + + if (typeof(booleanValue) != 'boolean') + error('Bad argument to assertFalse(boolean)'); + + _assert(commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true'); +} + +function assertEquals() { + _validateArguments(2, arguments); + var var1=nonCommentArg(1, 2, arguments); + var var2=nonCommentArg(2, 2, arguments); + _assert(commentArg(2, arguments), var1 === var2, 'Expected ' + var1 + ' (' + typeof(var1) + ') but was ' + _displayStringForValue(var2) + ' (' + typeof(var2) + ')'); +} + +function assertNotEquals() { + _validateArguments(2, arguments); + var var1=nonCommentArg(1, 2, arguments); + var var2=nonCommentArg(2, 2, arguments); + _assert(commentArg(2, arguments), var1 !== var2, 'Expected not to be ' + _displayStringForValue(var2)); +} + +function assertNull() { + _validateArguments(1, arguments); + var aVar=nonCommentArg(1, 1, arguments); + _assert(commentArg(1, arguments), aVar === null, 'Expected null but was ' + _displayStringForValue(aVar)); +} + +function assertNotNull() { + _validateArguments(1, arguments); + var aVar=nonCommentArg(1, 1, arguments); + _assert(commentArg(1, arguments), aVar !== null, 'Expected not to be null'); +} + +function assertUndefined() { + _validateArguments(1, arguments); + var aVar=nonCommentArg(1, 1, arguments); + _assert(commentArg(1, arguments), aVar === top.JSUNIT_UNDEFINED_VALUE, 'Expected undefined but was ' + _displayStringForValue(aVar)); +} + +function assertNotUndefined() { + _validateArguments(1, arguments); + var aVar=nonCommentArg(1, 1, arguments); + _assert(commentArg(1, arguments), aVar !== top.JSUNIT_UNDEFINED_VALUE, 'Expected not to be undefined'); +} + +function assertNaN() { + _validateArguments(1, arguments); + var aVar=nonCommentArg(1, 1, arguments); + _assert(commentArg(1, arguments), isNaN(aVar), 'Expected NaN'); +} + +function assertNotNaN() { + _validateArguments(1, arguments); + var aVar=nonCommentArg(1, 1, arguments); + _assert(commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN'); +} + +function isLoaded() { + return isTestPageLoaded; +} + +function setUp() { +} + +function tearDown() { +} + +function getFunctionName(aFunction) { + var name = aFunction.toString().match(/function (\w*)/)[1]; + + if ((name == null) || (name.length == 0)) + name = 'anonymous'; + + return name; +} + +function getStackTrace() { + var result = ''; + + if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA + for (var a = arguments.caller; a != null; a = a.caller) { + result += '> ' + getFunctionName(a.callee) + '\n'; + if (a.caller == a) { + result += '*'; + break; + } + } + } + else { // Mozilla, not ECMA + // fake an exception so we can get Mozilla's error stack + var testExcp; + try + { + foo.bar; + } + catch(testExcp) + { + var stack = parseErrorStack(testExcp); + for (var i = 1; i < stack.length; i++) + { + result += '> ' + stack[i] + '\n'; + // result = stack.join('\n'); + } + } + } + + return result; + +} + +function parseErrorStack(excp) +{ + var stack = []; + var name; + + if (!excp || !excp.stack) + { + return stack; + } + + var stacklist = excp.stack.split('\n'); + + for (var i = 0; i < stacklist.length - 1; i++) + { + var framedata = stacklist[i]; + + name = framedata.match(/^(\w*)/)[1]; + if (!name) { + name = 'anonymous'; + } + + stack[stack.length] = name; + } + // remove top level anonymous functions to match IE + + while (stack.length && stack[stack.length - 1] == 'anonymous') + { + stack.length = stack.length - 1; + } + return stack; +} + +function JsUnitException(comment, message) { + this.isJsUnitException = true; + this.comment = comment; + this.jsUnitMessage = message; + this.stackTrace = getStackTrace(); +} + +function warn() { + if (top.tracer != null) + top.tracer.warn(arguments[0], arguments[1]); +} + +function inform() { + if (top.tracer != null) + top.tracer.inform(arguments[0], arguments[1]); +} + +function info() { + inform(arguments[0], arguments[1]); +} + +function debug() { + if (top.tracer != null) + top.tracer.debug(arguments[0], arguments[1]); +} + +function setjsUnitTracer(ajsUnitTracer) { + top.tracer=ajsUnitTracer; +} + +function trim(str) { + if (str == null) + return null; + + var startingIndex = 0; + var endingIndex = str.length-1; + + while (str.substring(startingIndex, startingIndex+1) == ' ') + startingIndex++; + + while (str.substring(endingIndex, endingIndex+1) == ' ') + endingIndex--; + + if (endingIndex < startingIndex) + return ''; + + return str.substring(startingIndex, endingIndex+1); +} + +function isBlank(str) { + return trim(str) == ''; +} + +// the functions push(anArray, anObject) and pop(anArray) +// exist because the JavaScript Array.push(anObject) and Array.pop() +// functions are not available in IE 5.0 + +function push(anArray, anObject) { + anArray[anArray.length]=anObject; +} +function pop(anArray) { + if (anArray.length>=1) { + delete anArray[anArray.length - 1]; + anArray.length--; + } +} + +// safe, strict access to jsUnitParmHash +function jsUnitGetParm(name) +{ + if (typeof(top.jsUnitParmHash[name]) != 'undefined') + { + return top.jsUnitParmHash[name]; + } + return null; +} + +if (top && typeof(top.xbDEBUG) != 'undefined' && top.xbDEBUG.on && top.testManager) +{ + top.xbDebugTraceObject('top.testManager.containerTestFrame', 'JSUnitException'); + // asserts + top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_displayStringForValue'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'error'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'argumentsIncludeComments'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'commentArg'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'nonCommentArg'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_validateArguments'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', '_assert'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assert'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertTrue'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertEquals'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotEquals'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNull'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNull'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertUndefined'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotUndefined'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNaN'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'assertNotNaN'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isLoaded'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setUp'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'tearDown'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getFunctionName'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'getStackTrace'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'warn'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'inform'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'debug'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'setjsUnitTracer'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'trim'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'isBlank'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'newOnLoadEvent'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'push'); + top.xbDebugTraceFunction('top.testManager.containerTestFrame', 'pop'); +} + +function newOnLoadEvent() { + isTestPageLoaded = true; +} + +function jsUnitSetOnLoad(windowRef, onloadHandler) +{ + var isKonqueror = navigator.userAgent.indexOf('Konqueror/') != -1 || + navigator.userAgent.indexOf('Safari/') != -1; + + if (typeof(windowRef.attachEvent) != 'undefined') { + // Internet Explorer, Opera + windowRef.attachEvent("onload", onloadHandler); + } else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror){ + // Mozilla, Konqueror + // exclude Konqueror due to load issues + windowRef.addEventListener("load", onloadHandler, false); + } else if (typeof(windowRef.document.addEventListener) != 'undefined' && !isKonqueror) { + // DOM 2 Events + // exclude Mozilla, Konqueror due to load issues + windowRef.document.addEventListener("load", onloadHandler, false); + } else if (typeof(windowRef.onload) != 'undefined' && windowRef.onload) { + windowRef.jsunit_original_onload = windowRef.onload; + windowRef.onload = function() { windowRef.jsunit_original_onload(); onloadHandler(); }; + } else { + // browsers that do not support windowRef.attachEvent or + // windowRef.addEventListener will override a page's own onload event + windowRef.onload=onloadHandler; + } +} + +jsUnitSetOnLoad(window, newOnLoadEvent); diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation.css b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation.css new file mode 100644 index 0000000..e3086c4 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation.css @@ -0,0 +1,60 @@ +input.wf2_invalid, textarea.wf2_invalid, select.wf2_invalid { background-color:#FFCCCC; } + +.wf2_errorMsg +{ + position:absolute; display:inline; border:dotted 1px red; background-color:white; padding:.25em; + padding-left:.5em; + /*padding-right:3em;*/ + cursor:default; + background-color:#FFCCCC; + font-size:smaller; + opacity:.5; + filter: alpha(opacity=50); +} +.wf2_firstErrorMsg +{ + opacity:1; + filter: alpha(opacity=100); +} + +.wf2_errorMsg:hover +{ + /*background-color:Black; + color:White; + opacity:.4;*/ + opacity:1 !important; + z-index:1000 !important; +} + +.wf2_errorMsg ol +{ + list-style-position:inside; + margin:0; + padding:0; +} +.wf2_errorMsg ol.single +{ + list-style:none; +} +.wf2_errorMsg ol.single li +{ + margin:0; + padding:0; +} + +.wf2_errorMsg a.closeErrorMsg +{ + display:none; + + position:absolute; + top:.25em; + right:.5em; + text-decoration:none; + color:gray; + font-size:13pt; +} +.wf2_errorMsg a.closeErrorMsg:hover +{ + color:Red; + font-weight:bold; +} \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation.js b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation.js new file mode 100644 index 0000000..cf2af9e --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/proto-validation/wf2-validation.js @@ -0,0 +1,659 @@ + +//How can we emulate the :invalid selector, even with an "invalid" class name? +//We need to be able to remove this + +if(!window.ValidityState && document.implementation && document.implementation.hasFeature && !document.implementation.hasFeature("WebForms", "2.0")){ + var clearErrorIndicators = function(){ + //while(document.body.lastChild.className && document.body.lastChild.className.indexOf("wf2_errorMsg") != -1){ + // document.body.removeChild(document.body.lastChild); + //} + var insts = ValidityState.__invalidInstances; + while(insts.length){ + if(insts[0].errorMsg && insts[0].errorMsg.parentNode) + insts[0].errorMsg.parentNode.removeChild(insts[0].errorMsg); + window.clearInterval(insts[0].intervalId); + insts[0].srcElement.className = insts[0].srcElement.className.replace(/\s?wf2_invalid/, ""); //([^\b]\s)? + insts.shift(); + } + } + if(document.addEventListener){ + document.addEventListener("mousedown", clearErrorIndicators, false); + document.addEventListener("keydown", clearErrorIndicators, false); + } + else if(document.attachEvent){ + document.attachEvent("onmousedown", clearErrorIndicators); + document.attachEvent("onkeydown", clearErrorIndicators); + } + + + var ValidityState = { + __invalidInstances : [], //{srcElement:..., intervalCounter:[1-5], errorMsg:[],intervalId:#} + __initDescendents : function(context){ + context = (context || document); + var i,j, form, forms = context.getElementsByTagName('form'); + for(i = 0; form = forms[i]; i++){ + if(form.checkValidity) + continue; + form.checkValidity = ValidityState._form_checkValidity; + if(form.addEventListener) + form.addEventListener('submit', ValidityState.__onsubmitHandler, false); + else + form.attachEvent('onsubmit', ValidityState.__onsubmitHandler); + } + + var tagNames = ["input","select","textarea","button"]; + var controls = context.getElementsByTagName([i]) + for(i = 0; i < tagNames.length; i++){ + controls = context.getElementsByTagName(tagNames[i]); + for(j = 0; control = controls[j]; j++){ + ValidityState._applyValidityInterface(control); + ValidityState._updateValidityState.apply(control); //control._updateValidityState(); + } + } + }, + + __onsubmitHandler : function(event){ + var form = event.currentTarget || event.srcElement; + if(!form.checkValidity()){ + if(event.preventDefault) + event.preventDefault(); + event.returnValue = false + return false; + } + event.returnValue = true; + return true; + }, + + + _control_setCustomValidity : function(error){ + if(error){ + this.validationMessage = String(error); + this.validity.customError = true; + } + else { + this.validationMessage = ""; + this.validity.customError = false; + } + this.validity.valid = !( + this.validity.typeMismatch + || this.validity.rangeUnderflow + || this.validity.rangeOverflow + || this.validity.tooLong + || this.validity.patternMismatch + || this.validity.valueMissing + || this.validity.customError + ); + }, + + _form_checkValidity : function(){ + var invalidElements = []; + var i,valid = true; + for(i = 0; el = this.elements[i]; i++){ + if(el.checkValidity && el.willValidate == true){ + if(!el.checkValidity()){ + //invalidElements.push(el); + valid = false; + } + } + } + + //if(invalidElements.length) + // invalidElements[0].focus(); + + if(!valid){ + //var base_zIndex = 100; + var insts = ValidityState.__invalidInstances; + //insts[0].errorMsg.style.zIndex = base_zIndex + insts.length; + insts[0].errorMsg.className += " wf2_firstErrorMsg"; + //for(i = 1; i < insts.length; i++){ + // insts[i].errorMsg.style.zIndex = base_zIndex + insts.length - i; + //} + + var el = insts[0].srcElement; + if(el.style.display == 'none' || !el.offsetParent){ + while(el && (el.nodeType != 1 || (el.style.display == 'none' || !el.offsetParent))) + el = el.previousSibling; + var cur = el; + var top = 0; + if(cur && cur.offsetParent) { + top = cur.offsetTop; + while (cur = cur.offsetParent) + top += cur.offsetTop; + } + window.scrollTo(0, top); + } + else el.focus(); + } + + //while(insts.length){ + // insts[0].errorMsg.parentNode.removeChild(insts[0].errorMsg); + // window.clearInterval(insts[0].intervalId); + // insts[0].srcElement.className = insts[0].srcElement.className.replace(/\s?wf2_invalid/, ""); //([^\b]\s)? + // insts.shift(); + //} + + return valid; + }, + + _control_checkValidity : function(){ + //ValidityState._updateValidityState.apply(this, [{currentTarget:this}]); + //ValidityState._updateValidityState({currentTarget:this}); + + this._updateValidityState(); + if(this.validity.valid){ + return true; + } + + + var canceled = false; + + var evt; + try { + if(document.createEvent) + evt = document.createEvent("UIEvents"); //document.createEvent("RepetitionEvent") + else if(document.createEventObject) + evt = document.createEventObject(); + evt.initEvent("invalid", true /*canBubble*/, true /*cancelable*/); + evt.srcElement = this; + if(this.dispatchEvent) + canceled = !this.dispatchEvent(evt); + else if(this.fireEvent){ + //console.warn("fireEvent('oninvalid') for MSIE is not yet working"); + //this.fireEvent('oninvalid', invalidEvt); + } + } + catch(err){ + evt = new Object(); + if(evt.initEvent) + evt.initEvent("invalid", true /*canBubble*/, true /*cancelable*/); + else { + evt.type = "invalid"; + evt.cancelBubble = false; + } + evt.srcElement = this; + } + + //Add support for event handler set with HTML attribute + var oninvalidAttr = this.getAttribute('oninvalid'); + if(oninvalidAttr && (!this.oninvalid || typeof this.oninvalid != 'function')) //in MSIE, attribute == property + this.oninvalid = new Function('event', oninvalidAttr); + + //Dispatch events for the old event model (extension to spec + if(this.oninvalid) + canceled = this.oninvalid(evt) === false || canceled; + + //do default action + if(!canceled){ + + //NOTE: currently an element which has an intrinsit invalid state will persist in that state until + // the new newsletter is loaded and the person blurs or changes the content of a text box + // Furthermore, the following removal of the error messages should be held by the validation + // implementation. The notices could be shown only when focus remains on an element. + // Add focus and blur events to determine when a box is shown or deleted? + + //if(!this.className.match(/\bwf2_invalid\b/)) + // this.className += " wf2_invalid"; //substitute for :invalid pseudo class + + //show contextual help message + var msg = document.createElement('div'); + msg.className = "wf2_errorMsg"; + //msg.title = "Close"; + msg.id = (this.id || this.name) + "_wf2_errorMsg"; //QUESTION: does this work for MSIE? + msg.onmousedown = function(){ + this.parentNode.removeChild(this); + }; + + function createLI(text){ + var li = document.createElement('li'); + li.appendChild(document.createTextNode(text)); + return li; + } + + var ol = document.createElement('ol'); + if(this.validity.valueMissing) + ol.appendChild(createLI('The value must be supplied.')); + if(this.validity.typeMismatch) + ol.appendChild(createLI("The value is invalid for the type '" + this.getAttribute('type') + "'.")); + if(this.validity.rangeUnderflow) + ol.appendChild(createLI('The value must be greater than ' + this.getAttribute('min') + ".")); + if(this.validity.rangeOverflow) + ol.appendChild(createLI('The value must be less than ' + this.getAttribute('min') + ".")); + if(this.validity.stepMismatch) + ol.appendChild(createLI('The value has a step mismatch; it must be a value by adding multiples of ' + this.getAttribute('step') + " to " + this.getAttribute('min') + ".")); + if(this.validity.tooLong) + ol.appendChild(createLI('The value is too long.')); + if(this.validity.patternMismatch) + ol.appendChild(createLI('The value does not match the pattern (regular expression) "' + this.getAttribute('pattern') + '".')); + if(this.validity.customError) + ol.appendChild(createLI(this.validationMessage)); + + if(ol.childNodes.length == 1) + ol.className = "single"; + + msg.appendChild(ol); + //remove existing error message + if(document.getElementById(msg.id)) + document.body.removeChild(document.getElementById(msg.id)); + //this.parentNode.insertBefore(msg, this); //Inserting error message next to element in question causes problems when the element has a positioned containing block + if(ValidityState.__invalidInstances.length) //insert before other error messages so that it appears on top + document.body.insertBefore(msg, ValidityState.__invalidInstances[ValidityState.__invalidInstances.length-1].errorMsg); + else //insert at the end of the document + document.body.insertBefore(msg, null); + //this.wf2_errorMsg = msg; + + //if(this.style.display == 'none' || !this.offsetParent){ + // var prevEl = this.previousSibling; + // var nextEl = this.nextSibling; + // var prevCount = 0, nextCount = 0; + // while(prevEl && (prevEl.nodeType != 1 || (prevEl.style.display == 'none' || !prevEl.offsetParent)) && ++prevCount) + // prevEl = prevEl.previousSibling; + // while(nextEl && (nextEl.nodeType != 1 || (nextEl.style.display == 'none' || !nextEl.offsetParent)) && ++nextCount) + // nextEl = nextEl.nextSibling; + // + // if(prevEl && prevCount > nextCount) + // + //} + var el = this.parentNode; + while(el && (el.nodeType != 1 || (el.style.display == 'none' || el.style.visibility == 'hidden' || !el.offsetParent))) + el = el.parentNode; + + var top = left = 0; + var cur = el; + if(cur && cur.offsetParent) { + left = cur.offsetLeft; + top = cur.offsetTop; + while (cur = cur.offsetParent) { + left += cur.offsetLeft; + top += cur.offsetTop; + } + top += el.offsetHeight; + } + msg.style.top = top + "px"; + msg.style.left = left + "px"; + + //NOTE: delete this element after click or after timeout? + var i = ValidityState.__invalidInstances.length; + var srcElement_id = this.id || this.name; + var errorMsg_id = msg.id; + //var _this = this; + ValidityState.__invalidInstances.push({ + srcElement : this, + errorMsg : msg, + intervalId : window.setInterval(function(){ + var _this = ValidityState.__invalidInstances[i].srcElement; //closure??? + if(++ValidityState.__invalidInstances[i].intervalCounter % 2){ + _this.className = _this.className.replace(/\s?wf2_invalid/, ""); // + if(ValidityState.__invalidInstances[i].intervalCounter > 4){ + window.clearInterval(ValidityState.__invalidInstances[i].intervalId); + window.setTimeout(function(){ + if(!ValidityState.__invalidInstances[i]) + return; + var msg = document.getElementById(errorMsg_id); + if(msg) + msg.parentNode.removeChild(msg); + ValidityState.__invalidInstances[i].errorMsg = null; + }, 4000); + } + } + else { + if(!_this.className.match(/\bwf2_invalid\b/)) + _this.className += " wf2_invalid"; //substitute for :invalid pseudo class + } + //console.info("Flasher " + i + ": " + ValidityState.__invalidInstances[i].intervalCounter); + //console.info(_this) + }, 500), + intervalCounter : 0 + }); + if(!this.className.match(/\bwf2_invalid\b/)) + this.className += " wf2_invalid"; + } + + return false; + }, + + _updateValidityState : function(){ //should be called "live" + + //valueMissing -- The control has the required attribute set but it has not been satisfied. + this.validity.valueMissing = Boolean(this.getAttributeNode('required') && (this.options ? this.selectedIndex == -1 : !this.value)); + if(!this.validity.valueMissing){ + if(!this.value){ + this.validity = { + typeMismatch : false, + rangeUnderflow : false, + rangeOverflow : false, + stepMismatch : false, + tooLong : false, + patternMismatch : false, + valueMissing : false, + customError : false, + valid : true + }; + } + else { + //patternMismatch -- The value of the control with a pattern attribute doesn't match the pattern. + // If the control is empty, this flag must not be set. + var pattern; + if(pattern = this.getAttribute('pattern')){ + if(!/^\^/.test(pattern)) pattern = "^" + pattern; + if(!/\$$/.test(pattern)) pattern += "$"; + var rePattern = new RegExp(pattern); + this.validity.patternMismatch = (rePattern ? !rePattern.test(this.value) : false); + } + + //typeMismatch -- The data entered does not match the type of the control. For example, if the UA + // allows uninterpreted arbitrary text entry for month controls, and the user has entered SEP02, + // then this flag would be set. This code is also used when the selected file in a file upload + // control does not have an appropriate MIME type. If the control is empty, this flag must not be set. + + //NOTE: this will not work for DATE types + var step,min,max; + if(/^-?\d+(.\d+)?(e-?\d+)?$/.test(String(this.getAttribute("step")))) + step = Number(this.getAttribute("step")); + if(/^-?\d+(.\d+)?(e-?\d+)?$/.test(String(this.getAttribute("min")))) + min = Number(this.getAttribute("min")); + if(/^-?\d+(.\d+)?(e-?\d+)?$/.test(String(this.getAttribute("max")))) + max = Number(this.getAttribute("max")); + + + var type = this.getAttribute('type'); + switch(type){ + case 'date': + case 'datetime': + case 'datetime-local': + //code from http://delete.me.uk/2005/03/iso8601.html + var regexp = "(\d\d\d\d)(-(0\d|1[0-2])(-(0\d|[1-2]\d|3[0-1])" + + "(T(0\d|1\d|2[0-4]):([0-5]\d)(:([0-5]\d)(\.(\d+))?)?" + + "(Z)?"; + var d = string.match(new RegExp(regexp)); + if(!d){ + this.validity.typeMismatch = true; + break; + } + + //Verify that the number of days in the month are valid + if(d[5]){ + var date = new Date(d[1], d[3]-1, d[5]); + if(date.getMonth() != d[3]-1){ + this.validity.typeMismatch = true; + break; + } + } + + switch(type){ + case 'date': + if(d[6]) //if time field present + this.validity.typeMismatch = true; + break; + case 'datetime': + if(!d[14]) //if missing Z + this.validity.typeMismatch = true; + break; + case 'datetime-local': + if(d[14]) //if Z provided + this.validity.typeMismatch = true; + break; + } + + if(this.getAttribute("step") != 'any'){ + if(step == undefined) + step = 60; + + //... + } + break; + //this.validity.typeMismatch = !/^\d\d\d\d-(0\d|1[0-2])-(0\d|[1-2]\d|3[0-1])$/.test(this.value); + //break; + case 'month': + this.validity.typeMismatch = !/^\d\d\d\d-(0\d|1[0-2])$/.test(this.value); + break; + case 'week': + this.validity.typeMismatch = !/^\d\d\d\d-W(0[1-9]|[1-4]\d|5[0-2])$/.test(this.value); + break; + case 'time': + this.validity.typeMismatch = !/^(0\d|1\d|2[0-4]):[0-5]\d(:[0-5]\d(.\d+)?)?$/.test(this.value); + break; + case 'number': + case 'range': + this.validity.typeMismatch = !/^-?\d+(.\d+)?(e-?\d+)?$/.test(this.value); + if(!this.validity.typeMismatch && this.getAttribute("step") != 'any'){ + if(step == undefined) + step = 1; + var val = Number(this.value); + this.validity.stepMismatch = (val == parseInt(val) && step != parseInt(step)); + this.validity.rangeUnderflow = (min != undefined && val < min); + this.validity.rangeOverflow = (max != undefined && val > max); + } + break; + case 'email': + this.validity.typeMismatch = !/^.+@.+$/.test(this.value); + break; + case 'url': + this.validity.typeMismatch = !/^(http|ftp):\/\/.+$/i.test(this.value); + break; + } + } + } + + + //rangeUnderflow -- The numeric, date, or time value of a control with a min attribute is lower than + // the minimum, or a file upload control has fewer files selected than the minimum. If the control + // is empty or if the typeMismatch flag is set, this flag must not be set. + + //rangeOverflow -- The numeric, date, or time value of a control with a max attribute is higher than + // the maximum, or a file upload control has more files selected than the maximum. If the control + // is empty or if the typeMismatch flag is set, this flag must not be set. + + //stepMismatch -- The value is not one of the values allowed by the step attribute, and the UA will + // not be rounding the value for submission. Empty values and values that caused the typeMismatch + // flag to be set must not cause this flag to be set. + + //tooLong -- The value of a control with a maxlength attribute is longer than the attribute allows, + // and the value of the control doesn't exactly match the control's default value. + + + //customError -- The control was marked invalid from script. See the definition of the setCustomValiditiy() method. + + //with(this.validity){ + // valid = !(typeMismatch || rangeUnderflow || rangeOverflow || tooLong || patternMismatch || valueMissing || customError); + //} + this.validity.valid = !( + this.validity.typeMismatch + || this.validity.rangeUnderflow + || this.validity.rangeOverflow + || this.validity.tooLong + || this.validity.patternMismatch + || this.validity.valueMissing + || this.validity.customError + ); + + //This is now done onmousedown or onkeydown, just as Opera does + //if(this.validity.valid){ + // this.className = this.className.replace(/\s*\binvalid\b\s*/g, " "); //substitute for :invalid pseudo class + // //if(this.wf2_errorMsg){ + // // this.wf2_errorMsg.parentNode.removeChild(this.wf2_errorMsg); + // // this.wf2_errorMsg = null; + // //} + // var errMsg = document.getElementById((this.id || this.name) + "_wf2_errorMsg"); + // if(errMsg) + // errMsg.parentNode.removeChild(errMsg); + //} + }, + + _applyValidityInterface : function(node){ + if(node.validity && typeof node.validity.typeMismatch != 'undefined') //MSIE needs the second test for some reason + return; + + //if(node.id == "section-CONTENT0") + // alert(/(hidden|button|reset|add|remove|move-up|move-down)/.test(node.getAttribute('type')) || !node.name || node.disabled); + + node.validationMessage = ""; + + //ValidityState interface + node.validity = { + typeMismatch : false, + rangeUnderflow : false, + rangeOverflow : false, + stepMismatch : false, + tooLong : false, + patternMismatch : false, + valueMissing : false, + customError : false, + valid : true + }; + + node.willValidate = true; + + if(node.nodeName.toLowerCase() == 'button'){ + node.setCustomValidity = function(error){ + throw Error("NOT_SUPPORTED_ERR"); + } + node.checkValidity = function(){ + return true; + } + return node; + } + node._updateValidityState = ValidityState._updateValidityState; + node.setCustomValidity = ValidityState._control_setCustomValidity; + node.checkValidity = ValidityState._control_checkValidity; + + if(/(hidden|button|reset|add|remove|move-up|move-down)/.test(node.getAttribute('type')) || !node.name || node.disabled) + node.willValidate = false; + else if(window.RepetitionElement) { + var parent = node; + while(parent = parent.parentNode){ + if(parent.repetitionType == RepetitionElement.REPETITION_TEMPLATE){ + node.willValidate = false; + break; + } + } + } + + //var handler = function(event){ + // return (event.currentTarget || event.srcElement)._updateValidityState(); + //}; + + ////attempt to check validity live + //if(document.addEventListener){ + // node.addEventListener('change', handler, false); + // node.addEventListener('blur', handler, false); + // node.addEventListener('keyup', handler, false); + //} + //else if(window.attachEvent){ + // node.attachEvent('onchange', handler); + // node.attachEvent('onblur', handler); + // node.attachEvent('onkeyup', handler); + //} + //else { + // + //} + + return node; + } +// , +// +// __createElementWithName : function(type, name){ +// throw Error("__createElementWithName not yet created. Browser-specific code defined immediately below."); +// } + } +////createElementWithName code by Anthony Lieuallen +//(function(){ +// try { +// var el = document.createElement('
    '); +// if(el.tagName.toLowerCase() == 'div' || el.name != 'foo'){ +// throw 'create element error'; +// } +// RepetitionElement.__createElementWithName = function(tag, name){ +// return document.createElement('<'+tag+' name="'+name+'">'); +// }; +// } +// catch(err){ +// RepetitionElement.__createElementWithName = function(tag, name){ +// var el = document.createElement(tag); +// el.setAttribute('name', name); +// //el.name = name; +// return el; +// }; +// } +//})(); + + //(function(){ + //add invalid style to document + + var match, dirname = ''; //get path to source directory + var scripts = document.getElementsByTagName('head')[0].getElementsByTagName('script'); + for(var i = 0; i < scripts.length; i++){ + if(match = scripts[i].src.match(/^(.*)wf2-validation[^\/]+$/)) + dirname = match[1]; + } + + var style = document.createElement('link'); + style.setAttribute('type', "text/css"); + style.setAttribute('rel', "stylesheet"); + style.setAttribute('href', dirname + "wf2-validation.css"); + + var head = document.getElementsByTagName('head')[0]; + head.insertBefore(style, head.firstChild) + +if(document.addEventListener){ + //onDOMload for Gecko and Opera + document.addEventListener("DOMContentLoaded", function(){ + ValidityState.__initDescendents(document); + }, false); + + //for other browsers which do not support DOMContentLoaded use the following as a fallback to be called hopefully before all other onload handlers + window.addEventListener("load", function(){ + ValidityState.__initDescendents(document); + }, false); +} +////old event model used as a last-resort fallback +//else if(window.onload){ //if(window.onload != RepetitionElement._init_document) +// var oldonload = window.onload; +// window.onload = function(){ +// ValidityState.__initDescendents(); +// oldonload(); +// }; +//} +//else window.onload = ValidityState.__initDescendents; + +//onDOMload for Safari +if (/WebKit/i.test(navigator.userAgent)) { // sniff + var _timer = setInterval(function() { + if (/loaded|complete/.test(document.readyState)) { + clearInterval(_timer); + delete _timer; + ValidityState.__initDescendents(document); // call the onload handler + } + }, 10); +} +//onDOMload for Internet Explorer (formerly using conditional comments) +else if(/MSIE/i.test(navigator.userAgent) && !document.addEventListener && window.attachEvent){ + //This following attached onload handler will attempt to be the first onload handler to be called and thus + // initiate the repetition model as early as possible if the DOMContentLoaded substitute fails. + window.attachEvent("onload", function(){ + ValidityState.__initDescendents(document); + }); + + //document.getElementsByTagName('*')[0].addBehavior(dirname + 'repetition-model.htc'); //use this if Behaviors are employed in 0.9 + document.write(" + + + + + + + +
    + +

    Web Forms 2.0 Test Case 1: Spec Example: Sample Order Form

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following is the first example from the specification:

    + + + +
    +
    + + +

    Sample Order Form

    +
    + + + + + + + + + + + + + + +
    ProductQuantity
    +

    +

    +
    + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/002.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/002.html new file mode 100644 index 0000000..22abb53 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/002.html @@ -0,0 +1,71 @@ + + + + + Test Case 2: Spec Example: Repeated rows « Web Forms 2.0 Test Suite + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 2: Spec Example: Repeated rows

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following example from the specification "shows how to use repetition templates to dynamically add rows to a form in a table":

    Initially, two rows would be visible, each with two text input controls, the first row having the values "John Smith" and "2", the second row having the values "" (a blank text field) and "1". The second row is the result of the (implied) repeat-start attribute adding a repetition block when the document was loaded.

    If the "Add Row" button is pressed, a new row is added. The first such row would have the index 2 (since there are already two repetition blocks numbered 0 and 1) and so the controls would be named "name_2" and "count_2" respectively.

    If the "Delete Row" button above is pressed, the row is removed.

    + + + +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + +
    NameNumber of Cats
    +

    + + +

    +
    + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/003.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/003.html new file mode 100644 index 0000000..776eb26 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/003.html @@ -0,0 +1,65 @@ + + + + + Test Case 3: Spec Example: Solar system « Web Forms 2.0 Test Suite + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 3: Spec Example: Solar system

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following is the specification's example of nested repetition elements:

    The previous example does not demonstrate nested repeat blocks, reordering repetition blocks, and inserting new repetition blocks in the middle of the existing sequence, all of which are possible using the facilities described above. This example shows nested repeats.

    Note that to uniquely identify each nested repeat (which is required since the add buttons are dependent on IDs to specify which template should have a block added), the IDs of the nested templates are specified in terms of the ancestor template's ID, using the index substitution feature.

    + + + +
    +
    + + +
    +

    Solar system

    +

    +

    Planets

    +
      +
    1. + +

      Moons

      +
        +
      • + + +
      • +
      +

      +

      +
    2. +
    +

    +

    +
    + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/004.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/004.html new file mode 100644 index 0000000..1bc040d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/004.html @@ -0,0 +1,310 @@ + + + + + Test Case 4: Movement Buttons and Canceling Default Action « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 4: Movement Buttons and Canceling Default Action

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following demonstrates the use of all of the repetition model buttons—add, remove, move-up and move-down—as well as the various ways to cancel the default action of these repetition buttons. It also provides examples of customized addition buttons.

    + + + +
    +
    + + + + +

    Note: Buttons with ellipses will confirm the action.

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    No onclick handler » +
    +
    onclick HTML attr. » +
    +
    onclick DOM property » + +
    DOM Event Level 2 click »
    (native implementations only)
    + +
    +
    + +

    Form addition buttons (RepeatMax = 5):

    + + + + + + + + + + + + + + + + + +
    No onclick handler »
    onclick HTML attr. »
    onclick DOM property »
    DOM Event Level 2 click »
    (native implementations only)
    +

    Other addition buttons: + + +

    + + +
    + + + + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/005.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/005.html new file mode 100644 index 0000000..1d0f86a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/005.html @@ -0,0 +1,259 @@ + + + + + Test Case 5: Repetition Index in Attributes « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 5: Repetition Index in Attributes

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    For all attributes in a block, template name is to be replaced with the block's current repetition index. The first section below is a test case taken from: <http://simon.html5.org/test/webforms2/repetition/addition/001.htm>; the second section contains a more thorough test case. It demonstrates Opera bug #230280 and this implementation's issue #7. The specification defines the correct behavior in 3.6.1. Addition:

    ...any occurrences of a string consisting of an opening square bracket (U+005B, "[") or a modifier letter half triangular colon (U+02D1, "ˑ"), the template's name, and a closing square bracket (U+005D, "]") or a middle dot (U+00B7, "·"), are replaced by the new repetition block's index. This is performed regardless of the types, names, or namespaces of attributes, and is done to all descendants, even those inside nested forms, nested repetition templates, and so forth.

    + + + +
    +
    + + +

    Test Case from simon.html5.org

    +
    +
    + + +
    TEST
    +
    + +

    The above should be exactly equivalent to the following:

    + +
    + + +
    TEST
    + + +
    TEST
    +
    +
    + +
    +

    Extensive Attribute Test

    + +

    Whereas every attribute which contains "[j]" should be replaced with the repetition index (0), +it is likely, due to Opera bug #230280 and my issue #7, +the specified behavior will fail in style and non-CDATA attributes (note that a '1' is also included as "1[j]" so the value of "10" should appear in each attribute):

    + + +
    +
    + + + + + + + + + + + + + + + + + + +
    T + + + +
    + + (This field has access key set to 1[j]) + + +
    + + + +
    +
    + Image 1[j] + test +
    rowspancolspan + +
    + q +
    +
    test
    + + + + test + +
      + +
    + +
    +
    +
    + + +

    Test results

    + + + + + + + +
    AttributeValue of attribute (should contain '10')
    +

    Test result: working...

    +
      +
    1. working...
    2. +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/006.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/006.html new file mode 100644 index 0000000..b5f58d5 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/006.html @@ -0,0 +1,228 @@ + + + + + Test Case 6: Repetition Events « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 6: Repetition Events

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following demonstrates the handling of repetition events, using both the DOM Level 2 event model and the traditional event model; the MSIE's proprietary event model is not demonstrated.

    + + + +
    +
    + + + +
    +
    + Event model options +
    + + Unsupported by this browser +
    +
    + (extension provided by implementation)
    +
    + +

    +
      +
    • + + + +
    • +
    +
    +
    + +
    + Event Log + + + + + + + + + + +
    #TypeElementModel
    +
    (Click the add button above to fire events)
    +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/007.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/007.html new file mode 100644 index 0000000..e80ea15 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/007.html @@ -0,0 +1,153 @@ + + + + + Test Case 7: Repetition Event Handler Attributes « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 7: Repetition Event Handler Attributes

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following demonstrates the handling of repetition events handled by onadded, onmoved, and onremoved HTML attributes set on a repetition template which handle their respective events. This is made possible by extension to the specification, found in this implementation.

    + + + +
    +
    + + + +
    +

    +
      +
    • + + + +
    • +
    +
    +
    + +
    + Event Log + + + + + + + + + +
    #TypeElement
    +
    (Click the add button above to fire events)
    +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/008.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/008.html new file mode 100644 index 0000000..ddc9050 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/008.html @@ -0,0 +1,82 @@ + + + + + Test Case 8: Initialization Time « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 8: Initialization Time

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following test verifies whether or not the repetition template is initialized before the user's onload fires.

    + + + +
    +
    + + +

    Test result: loading page...

    + +
    +
    +
    + + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/009.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/009.html new file mode 100644 index 0000000..0db240a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/009.html @@ -0,0 +1,79 @@ + + + + + Test Case 9: Repetition Buttons « Web Forms 2.0 Test Suite + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 9: Repetition Buttons

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following test verifies whether repetition buttons can be created using either button or input elements. + +

    + +
    +
    + + + +
    +
      +
    1. + + + + +
    2. +
    +

    +
    + +

    The preceding DIV should appear exactly as the one below:

    + +
    +
      +
    1. + + + + +
    2. +
    +

    +
    + + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/010.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/010.html new file mode 100644 index 0000000..ef28296 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/010.html @@ -0,0 +1,73 @@ + + + + + Test Case 10: Orphan Repetition Blocks « Web Forms 2.0 Test Suite + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 10: Orphan Repetition Blocks

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following demonstrates prefilled orphaned repetition blocks.

    + + + +
    +
    + + + +

    The following blocks are prefilled and orphaned.

    +
    +
      +
    1. + Orphan 1: + + + +
    2. +
    3. + Orphan 2: + + + +
    4. +
    5. + Orphan 3: + + + +
    6. +
    +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/011.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/011.html new file mode 100644 index 0000000..1dd3f15 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/011.html @@ -0,0 +1,121 @@ + + + + + Test Case 11: Disabled Form Fields in Template « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 11: Disabled Form Fields in Template

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following verifies that form fields within a repetition template are not successful. It also tests whether form fields disabled in the repetition template are also disabled in each instantiated repetition block, but note: for this to work in this implementation, authors must include a class name of "disabled" on all disabled elements in the repetition template element to ensure that they are also disabled in each repetition block. This is due to an issue in Firefox which is detailed in issue #9.

    + + + +
    +
    + + + + + +
    +
      +
    1. + Not disabled element:
      + Disabled element: (this should not be successful in form submission) +
    2. +
    + + +
    + +

    Test results

    +
      +
    1. Form fields in repetition template should not be 'successful' (there should not be any querystring parameters with keys such as submitted[i]; these fields should not be submitted): + + Press 'submit form' to test... + Passed + Failed! + +

    2. + +
    3. Form fields in the repetition template which are originally flagged as disabled should be disabled in each instantiated repetition block: + + Press 'submit form' to test... + Passed + Failed! + +

    4. +
    + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/012.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/012.html new file mode 100644 index 0000000..46513b9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/012.html @@ -0,0 +1,102 @@ + + + + + Test Case 12: repeat-min, repeat-max, and repeat-start attributes « Web Forms 2.0 Test Suite + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 12: repeat-min, repeat-max, and repeat-start attributes

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following verifies that the repeat-min, repeat-max, and repeat-start attributes work correctly. The event log utilizes the onadd and onremove extensions to the repetition model specification.

    + + + +
    +
    + + + +

    For the following repetition template:

    +
      +
    • repeat-min = 1
    • +
    • repeat-max = 5
    • +
    • repeat-start = 3
    • +
    + +
    +
    + # +
    +
    +

    + +
    + Event Log + + + + + + + + + +
    #TyperepetitionBlocks.length
    +
    (Click the add button above to fire events)
    +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013.html new file mode 100644 index 0000000..dff7e02 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013.html @@ -0,0 +1,116 @@ + + + + + Test Case 13: Repeated Photo Albums « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 13: Repeated Photo Albums

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following demonstrates repetition model-driven content in nested repetition templates. Note the use of repetition indexes in img[src], img[alt], and img[repeat-start] attributes, as well as in the background-image CSS property within a style attribute. If your browser supports addEventListener, you will see a dynamic count of the photos in an album, and you will be able to delete a photo by clicking it. There are only images for numbers from 0 to 16. Opera 9.02 does not display the repetition model-driven background image, and furthermore it does not correctly initialize the nested repetition template; this is probably due to the repetition index appearing in the repeat-start which Opera requires to be an integer.

    + + + +
    +
    + + + +
    +
    + Album #[albums] Photo album # +
    +

    There are currently 0 photo(s) in this album. Click on a photo to delete it.

    + (max-repeat = 17; repeat-start = repetitionIndex) +
    + Image in album [albums], with repetition index [album[albums].photos] +
    +
    +
    +
    +

    + +

    Graphics from <http://school.discovery.com/clipart/category/letr0.html>.

    + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/0.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/0.gif new file mode 100644 index 0000000000000000000000000000000000000000..9fda3c1384bf85400e130e2bf664022280347f8a GIT binary patch literal 5123 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 F{eOj?9hU$A literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/1.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..f931d174f660fd3a1b68b7267e806b16f5a957cc GIT binary patch literal 4187 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 M=f5^lH861fA8~}cTL1t6 literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/10.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/10.gif new file mode 100644 index 0000000000000000000000000000000000000000..3bb8bb59c0d124be2be1e2fa2b5db3162ecd7f74 GIT binary patch literal 4295 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 C5m5aA literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/12.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/12.gif new file mode 100644 index 0000000000000000000000000000000000000000..3124e1f3981de62bf35c122c5b25a6d52f3fb652 GIT binary patch literal 5762 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 literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/13.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/13.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2eda86f0197b58e225217da332b17709de9bf25 GIT binary patch literal 7221 zcmWkycUV)))85mPlR|P3kSYXGx*8BHc)^6C5fo!V5nCuWu*43Cc<3FYf(oJ@umK80 zY&7)%f+&{YwcxeQgylo2;%Dt?SA!Y z?UgG&;bDLN{Q3MDdncbxm3s60#=zFQM^p$GQTY?n`^PFGan1^FN2Munes>^}qjGJ33CEzEF_nyS%I{ z@z<{f{sGUQcl!D+`S4ydFz~}+>Qs|}fcV&bL(ex{KInJ+?AhBV=coSs>27cD?(cv4 zRU0n$t>-+cb!^6YhzG<{tpnDu~=-?rr z6~Q0+`c9n&8jXf&&LcN^bzEQZxO~yLy|J2(h>?*IwYqzFctkAnCXeR3hK1R=n)ZC^ z`L5M|{rWXv z_gNMaCDoXO8#u0NQx-R;5jOrslFKD6Ste5>U$=C(v?JHTv*t)zOTpR}+xdk4*+W%=hCPGF|IIovZmYPLu_>Ukqijh-^h+1_sG|p) zM|j`Zamy>h@7@kpN@j%~jPSqx=&JNZCQ-AQv8^q$BsV2}b=#OJgD!}Pfoy7+L4fP5 zdmiJz9R3vO{o#3qf!$`r?$;UZ!H~=QM`Vk$I_qB7t-X87(){@Gu7GNrm4^#Y@3m_9 zY^Xa+3)+5Jg+2GnvW3XozcugMPxEJsb{hJ9dSAMGJk9_81H;$q149$Q_9bjm`6Grt zkXT<>6BrLK+ZYPGc8y^;cc=jd#-N0re)}XS0F1q#=94f3jn3lN6Rs*JXN?Ub#i85Y zYU)(`P`-OW&9W?$12vbkEY@i?X(r>k?Hjo-^lbzNBYz2{uC-cuV(zN@#(K`ra5XDi z7Izsjo_IBMp7ShPe?l%?B1G7?S?SiCDjYp%)kbyxdwMuw5ldjws}dop>WS{>2PLnjQ9rw+&^pXo4_gjpp3$GxHS$8>Cc|vc`m-j=W%olJw z817!gmxIiC&K((cr#72Btd$B8E5q5J!V*NUiW(mueSCkpBXi!JJx!TmHTnUptGATR zR&qBX&B=)6WP&MlV^ZxOqCah7r<)_r57RC|4Mv8N5dIa3wMs9h_tiGis)W9?d+XA_ z!6p7NICWx1E|u)Qye&3m;*O_@E~#Gji&)q7YVOU~pDh_&qkm0i-7ezSj8v0;l;Zf9 zs{8-U_x#C~@ojf--)Wj>@F_XpA0+$6CB>&E^p=7W>5 zLu2A6TyaI(=r>ag+KTK_O{QM5`DmZ7p%*%fktcnZI;SD`Ijij7Ax_uic5|{iEEoai z%fSvmy8y#RZcqP~NZ1Q0`;HWq?C~r^$H?VPT&|h)K7PH%rO8O)KFg>90HTa-LX2vyIZqbMhlpPF&ZUm-HcZ}7-?B3uDV;?m&a_?)Hj&3sM4sAjY zoNUdIX^a9lzitO4%yav?JWP@el>+8W6WPjU^5r4k&GE0FV7KIq#J-BBD2*jDI zM4(+wa-%MiKiOWfxhRyiFS#V{c>;Ix(PF)|+Gb;s3mUO2G5VR1w&DV@OG*{)rx0bq zN_0jxZD|wS#6{;>al(Y=kMPsZAKzQe)Bw{{8%4hzp|n6;1h%LftqMsfz#ih>Z`5;< zsv3>+iw!oLV6%nObXGu+l&_=Lf4$Bs>3;)*`5LjQ3`&dbL=0Cce4Op4CE99aCMP#0 zjyW9RppQ{Wz8aphKVU{Ew|R{bwT=@WuUda^F?=oEtg?GWR`Z>bF{gl!bDZ?P@ha=F zCn@iVsH%N}>TcAC+=u1ik`z2}$V%TN-Dx$u#Z*IaM>>-n(h0w>!Dlv&NOGV;VWM$^ zrpSh3&VIgq>9=I-ZS&=kV_L4b?w0;s=O;*=(5~Tle@bM1EXQV#5_=kL&E0B`@b}0u z$c-LzQro;ITAnpnL|Vycl=Gsak&Tg7yGX)u?VjA3bqQ7nC39Sk3YfA9Q;QeK4bA;! zIpcKBYy;VhzA+Q#rOcMQds(~F#%bF*F*nl+e=Zs?wv@lv0MX3L>c+_y3H1xF7H{m3 zB<_8!LQk-Op$!e3$29XTovp`SPsB*C($(>8p=hWeaeDz|kvG};Dw08O9Nx`|r<<63 zd!{R`BIo88?=5f#&PUY@%Qk524n>l=MMi>k-Zh9J{Jf8%lU?n_r3dW4K8@E*8`Lft zSK?Vzdh6;+gPQmHmq7ADbGd)8J%n64=k1)QW(APN+_zU5_BHN6dMAv5z^VHxtig0j zu*6bL?v1?s_T{_ff(rYj%=dp=zRxWm%Nv_8!|ZbMv>BI7VSvm&N-!)ny*i8pzK9Uw zER>xwe313bNT|B_8>lmtw8%4X*Xuv7xKcB(%n|Rxoj052u~sMcemb*!Nic<}wt$K{ zW5$$R%5WV*d6p`ZX9qW1wj+K9iuB^S%V2{`fOs0AziL9J!_da85gPWp=*sy_Uug2Y6y{x@ zd-Z~(txp@r#)l1>ifjl66|z;jFWIIBLQFM2oo_o*@M!UFXZ(cucy*e?h-i1P@Acw0 zv0_i9S9Yx6Gh1CURCrrJ?u`pG8=(<6S(zCBBk9Wu0qWWG2O;Irsto351c^hSA zCCZ-M-IcXkdQv>1PI-6;`t9EQuC;2%GowA*M#aN>`6^kGAWyiaWr}r5Q_%?1aob>f zyMUwk)L1|N`C!b8cXK|%t(KD)rQZJtptn7_x~{vk;|1YI7j4ho>FKeaoM-}eC@*-x z-BS>gIEwS|@$GxXk8^sqv8m~Dro{x;YYOJ*#k4Q@P68CCI3N7t3CV6Yg?~E>#%@gb zA>u3M?v559-U9U34cJM63@%SRdUy95g7==D;*igb_~<`dFa-jfT}r06G|@=|36)7g zO@b>4qDkhVW4jL-Cm)`EK$H$#mC4@f1aB(IyN!=a5^aN19^QbjD18m2E2yhz^msxm z<=*M$-ypHw8m>^5GV}r)UlV7gNtGW@YPU<=)rsv%Kd`iu|G(*+cmcvHO%1AnB?M$D zW3H-k$kPaPN;{WN{5v`svqH(T0_l0d8Kga8AmSXRHkE!) z03#CaK}zq0BK4$6)=?aZmm~4g9o5GXZy}_km?Ij!v8Bj}JQKFoJE%&(A!EOjXH|D* zlUhg&^i~Lv7)i#2PHY{CSE!Ll3L6mc*Q=2tQrudDcF+(l~M(E|APrCA-D-L ze7_p0kii$y!1N5}bS*T$HtA8?fh~Jua7AiBC*Lal$nU!(=Qv_TZH>OCcU1<9aAdXS z*bLMB|AaAtF(y}JJ3W+8fgD{Z0%a5j9pvAWvqR?rBQ>a#vxg|wmbp25dyXE_CTMDo zUAVh@dQDzk=~l^%7$=gMc8|X;omns7d^btPNp8rEJZU=GqkuUw21^ZlP>7ct1Q7_T zgzAL3aKglsn-24cBb6VKMXVF6rN_n%Lf$%(Tc=6*@u_fWEjcb7i=-G{(gV2s_+|%` zJ09DuMkEyCsDK?5yfkqUM-9wnSb@60MTCT?^>`vMR|G_4feFelDqy2ZegVPlQ}7%C z%u(??NZ_S75>R@oN3F+{G4_)|?H7`}?(tm(thYj3B;&csL62(If>Pv&956|gPx9L+ zC>5X%baA8_-Xvl~2{8u>-Y???$#7O7$d+OYrC2w`cv_o2o;YeG0^!QyWlC&q2)0DV z=%o-zB05O(m;~2Nz;2XcJPJCmW_-v%D=8?6fQ^)lC;~5*;R9-{M8Hl`u!BS(K}SKi z<;Zn4Y(&6olz<~(yD1r2Y?LJ{iz5&hDOOUKzuXLtlryIM=08#4UJ8IpF*hM2%O6ne zlScAUB-{`+5NXf^8E-#{*2zH#$*KK}Wl523>Vm5wV2O~iUjdhh7^o76n*kU#*> z(QqW9inacr(7#}z5+myvopt$_pf}ukMk4^ zOazvJ@+`B;D0zXt4DwRzaWkvu%JI31>NO{-mq%ie3eH&p0jHwwnsaUx)Jvix04|VL z&#LE72&nWluO14))}E+#0m{cKu$2myIl+ySgSP}1Bhg1Be;tK9&Zzdwy1I{Z9aWsW z0Qj&zHbSByQYc8nFjK=UDdHx_KYuPDhc29YbffaHOyxIk#2> zU7$GDipr{4wfTdLNLufSqIQJhoE%2e6s!Ve>EoUPYXzf32?U}`5mbKTtQ%G47(Ea-J0TQ1B1Sm|_z1QbFOO zi$}7mV$B`K5h0N}{nEc8m(ImvfhZJIl+fFcEU* z^R@g&~Z(Mm8RkA}U#dYj7f*qkF_#R4-Edmkr)r-=KjK7%K zG+qkIFDgKt3bq$Ri)l`;lD#bQJWGuQQXDh2o|(L*FSAiXbGl^L*C}qDioyj-4wqn?6iZ+RqO@@Z<~U4 zAz%kV-Fi8A`I^J4L9M2t2Pn=>6_2R^EDAa~i{YW>JfhNL4|9HnR0omlQu<-cm%8Qm z@p$JJwTvBViudb;9Q)^wZHc{+B+72#_sX!?;TCHtSSEtq6l|UXNHom#&x6;}{74Ea z-lr5O*#eqhPqX?x2(AK_-fy5{@z=xGRw}U`iuuW=s)1rm5WziCE~9u#c`w)|FZK|{}(q0A^8`PZZBgjm%oY-Xeq_O4$cg zP>EWvPXVvk#OqOT3<&g{GhwPi%w+Vd_Lp}>tW8^>dJ5V`acZT+OPyR%S%=LUMz#JI z|KgNyIa$}`&j?hp(w;G1WB571F%vQxm5|w+t8dkat0~kl!Z)Cwi~g#8ZdSfFIvF3(yQ zf-RulMTO6t8P3VlH1!P?1P9_CtB7hH_@`S_zAp2s3w`%4iEb@q#BWA*6t_inI8gQG zeF9e?zqtDrqg#qZDD&6s!*yE5O&OSO;FQzlc#gz2X_}@E-wIaYZ7Te?D{)(H!Xt3I zm%L5Vw&Ed1qYNVpU$4vJ-=dH>nkU~vTu|_{rCmlOJBxzrWQ=E-Ex??w6vBq#(|pvd ztS;8ynrD4=rQCYOy%W4(DVM8)nLXnoRm?yVeJjL#UsuIAl|Rez`l>>DXxx$R!M5|y z%efo{V9L4mB9>SUM=0pO%-LCTP)74EQRo6X_?Hlkf8l*o`c_rI*8lQ#*z$t*E4p9C zXy42b=m30n^7CDr+t!~<*NNDk6dWYQ#j+m8cK!xhFL({NLjCxJuydF!pe`fpTmJ5-}pF?}uo;{jz_% z(upbsv{(Ucx_NkwWqG$8h!hO&_`Tz7j{QV=L*To6LR6k2HOW&=2RQ%3U)5q)Tu z`d9Dpr^kc8_Bjpl$LopZAc{a(YDBEYdHrCOGq+dHU9VtS>lA$9;ic;tqEkuGh>ByT zfO!ILgc`f4M)qs!-_)~Hm3Y4lix6Vjpw((~xd)%OI(8Bk7B)~tfud~++&DAA|F>hmzPZG`tAOA4ol z`0DTTuEvK$fn5_yOy7dD%3>s%y81UwNuXm-r9%fxQ6rj={3j_D%@_}(ze!O)@zw%{p>x^lq%p~;J+jeX3|DFRo*(*eFTPK}`xJeq{ z?A_OE4<9=mfigit5I>W;U8db4(XkKaMy3Iu(4}$7#ADI?4?Uur1&`S+0Yl zU*G$a7*V~j75{qfo?yg&yyRByvJmTJMfW_Lc&%Lj2RB-T+Da2R5i(?)R)o)yCK{ZT nVUwc8-1X8V^A9qnr*@2(NR=krObBHyi1s!-FHC_TFzf#S=YIF# literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/14.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/14.gif new file mode 100644 index 0000000000000000000000000000000000000000..9fa9bbfd9e63fe2cf8fe61dc20dec390252f7fea GIT binary patch literal 6733 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 MCfB%46aZ8I56WklYybcN literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/16.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/16.gif new file mode 100644 index 0000000000000000000000000000000000000000..44200c6f3140d016ec58b3e46aeaaa2e4df0315d GIT binary patch literal 3479 zcmWlYc{tRI_s7qS!HjLjAlqOF*|H4DSelQqH!ahUC~0h$ge>JM(b%`aDC;dnB&F^h zDoatuPPz@%H!U=l`q6Epjc(KYy6@NXoacG}^FDu^^Y-%bbfAXpg&6n-U(fX~&Lzg|Au^%84yNC4psNV2~wnfD?T4W~M8w z!CDEF$b&owfn(0F3agLdaRC&3hR+2*e+F1UA|$3bgJ*7TG9(j$2)5e(=5P~k(t#d& z=T0od4!{6py1|FE-v$SbRGiP{ zXYlM6+zRjS4-*LNv;ZVrkmOcu1z5{Uc7igA#06aXpifRk3d zF62^xvII-@P_HTnFn^S;4{D$my$RgG{RupYcYp`*fCa25J3uMO{ALTgVRs0GK&Wl3 zJ#2^V;SjEFVFAH5(Gcwo-qIi~EhmQnqM)H6Ed_YM6ZG`Z7z~)Ndk61&pohcZ(CPF% zHz@P~t|#Qsq1Y3OJRsK%^4+1p9b_?3-~l;qumUS3UXbqwY-=d-gb(l`+Z77kA(swZ z54aB3-@@AiaNs?>2TAD^Oz9E8%Mh;qLc*Jc*>33m2|sz>&H_Spu1GuJdBMmp`1_oal3+Opwwn}7ByTGs^i~iR8_bbVQ6iUjcxY%UJjua=r$jE{q{N$G}ZU$hY3ikH)r+@vx z-7t82{1v=n$}$5WfTjoVE(3J%P~wyQYx}RO{t`&^*D(JXu=sEM*9pK%K#U`K^Xmjz zSQWFN5q^Dt9%22~v)-*228%RoqhE})HVl`N-3m!QZH=R+O?H~c91fO`-ngo>E#L#O%Zg!bHeQ{O zr2*CGfQOxJGoJZfmhI!z!{i#oanI1(MDywU7uM_pm1R*S-BL51;q%7GT`NVFy7Bab z8==#wX}uQnQdV+R6kUz3xfS$BL3dh1`p+=lHl5$UbUM2pWJ%k1xHwBbXs5mZuq+{T za}$kJrhTR1^F7ySBF)DwXo!BdOK#yxc(fs?sYJGqXp!TsA=D)hbrV9K=X9`nN

    +yR*TZc^SRR2=zh)WTZD8oj5 z{woEH?b(Qm>f_|(*f57W6_sQOb`oDPx^*Rr7Aluopjwd_GJVH4z&0mV{7Ap3yJoMw zfU&a|F0Pa0KipYLJ2x`UDBgm_ZF=8RE~VG*PA`zz-;7N-`1;_Rs^gfkq}I$=#9Olda2@UCK!m{O04a&17-+sFY}zAjaft#{ea6^@$A4C z*@KTuEorPil1yU!1l~Mcz6GaC8RKOb8Tk4x=_hmV_{>#^b}bb)cmxHSao-&Dk!}nY z#Tk1WI`O%A-VfoeKNOwEFdX^%Wz~|3y0S5{S=Gwo^{Jg)pMc6{)XaC$ zotXiy?Oxu5+K?S?+lxBA0MQxYm?ti!{2s1~=e_}{Gpjl4CbdZPH?+vj&~x9JT(Qjg zOSG%dI0I#THdSbBmLNky6)Nrw_}`FZEMAG#gOMpCPiGOT^pE+9ZCIinCLTVd_{FkSbeBLfo)T@;)JnHf!T{XHMeGt zF>%AyR}&Ba;5neI@B)dBeet-K{IuX!O|BMPI)_ZmM4HC8Ku}Cb?jP^;<<-GTwD# z!(Wt-u9d8dmkgV2q!W9x<#cWjNMSp#>}Do3F~hjWDf&68O`8%9{N7_4mfV!An-3tmorgFl~mmj8ghwRB74GUxOt+ZEKCacig>y_%re|gZ_`-Z&4o5 z?&G|9uVv%A1nmY)6~gIa>8LWFl=)`(xOyH4h>7aBR~^&Zr*gX1ed>GOuH!5Nj|jMy ztle^^KvO>O0t)qK{IfT~9eO$(?Rt_kS>SI&IO= ze~}27K*ktT&pj45HNC0BPjEO=))oIX1ZTXnXA!TG^18(*Vm(RQHY{d z(nsoYTXqYO)lzH*Yrj_xILR}Jcn2+m-?W$X=Z)4;1<YvSestBO9FPT6ZBM=+8r$8NP2L)H+?f9!ws`%_!L`mfXI1{zF@g zpWWPZQQQFWQIYzA@L8j*M@vRLC=IO$kzSr`Z#-zWp_(vCks@Ss(I9(c@;Z@hQp0#} zqZ={2FjF}@(4-wc`R`EpzFr%LZNSSc+}GWi)^&}MTsK?q518>)cY%pYLeRXSe2zpv zgOM1;3d$E?Hz$p1&(+49erYJ3vy1iRR!qUhti9-ugcRB{FY`0cvv+5sd})6#a~Psf z^|D@!v0Z|<)5lQ0n4E3!UC?{s@a-9^<>XH7jMhHks!AEsr-qHsYQM*+5({Omzb_YK z5!2h7B;VVV<202Nyk)413)`;p72`g;X|{V9f;rSBM}(IAr7s73zmi zev@ULv{~n~ThlR8+LFLA<6&+J@dE^z5TTTqfWl1Soe})+2=-pQf|w`!JW{vC-;l&p z`_557nP7a_N@6zJ1Ho{F_?zTRv9+QHfn(L11AJ6>r0(Vb{dK}auRb1^=P8VIU_I*O z_6hL|LPgpXIy^qr6+um$iajept5dLB*$LdK{E{Q9`6bO5*#f$jC0yzCYD1W6y literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/2.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/2.gif new file mode 100644 index 0000000000000000000000000000000000000000..c6544fec1f34a4e70d3cb4d6ca72aad78a9514b3 GIT binary patch literal 4846 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 literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/4.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/4.gif new file mode 100644 index 0000000000000000000000000000000000000000..215096f5d37467f1cbcb97b763a3e89026c511ac GIT binary patch literal 4882 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 literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/5.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/5.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9f8e4eb31f74df2496411c36a1a46bbfeefd53e GIT binary patch literal 5113 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 E0j!=}E&u=k literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/7.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/7.gif new file mode 100644 index 0000000000000000000000000000000000000000..f595fb65e6a61dfca0aa474dee2a303b4882154a GIT binary patch literal 5219 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 C8Dg>k literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/8.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/8.gif new file mode 100644 index 0000000000000000000000000000000000000000..5fe6259eb4b02a9de746d3d9b3f57209b120f5cd GIT binary patch literal 5759 zcmWkydpy(oAO3v5-+j05X0wrNl(BM4EavX;MTAsy>A2PzQIcvTx1??6E-lHCq(v9W zIjy^t%r#1rE&+GZ~{dzsm^LpN|XH}rTi)&moNC95~0MF89 zfY8;&1*i*w`p_iU6B8W`rt)TIXYbs(1JwK5+uOlELa@u-!^^Y2?id)`y$v|82R6B- z`68hZ3?>8d%FN76@E`?T+CX(-fyVGoka!Wqf;f9!fTaWXyCC@{hzEJz2?+^6pR!|L zh8h$O4GnR?LXhOB1_#xk1RP#d1=fODks6f#aqpg?f#JuGABRB7Gm!T1;X@VJ3)f7( z+uGV*zIsW3Ah16W1ew>CSAvO*ckkYT`TQ#_7XZhozUs*5&!54YOwg6^acmsC%Wk`H z6%1@{X=#B|Tmn~J&t@cZ;gI%}30r9Q2n|)wQAY@(){J~_N)k0HHv#zM1 zu)4b1GSWN9!-r*W9SiJ0_|mI@2d@62OQC;y{q78i1V2QkfDZi4LIc-;O}3yTjsgfY z4Jx>m2$-4?+%SGZ@;YF-fMrx$Sq=FAX;IbI(_x}x2sYY*lM&BAhO?c+!=d5!)*Ctj zc3!~f2Pl-CYzFSML`MM(gv)xXa*5rt`IaufP;Z5AfO}UAD~#r zh6(6IFkA31C;|d+V5>)G83J`FP?rF88BiAq_U!}n#bCZ!$b+JkDgU?46 z2CUe;A>MJ3CHOmU0;E z9AkJ{zE^z&$3un&?_aon1w`2F+mSIeIua4T0nC@pOwRz9g=!%F&-g$sR;$&f{}TSs zfzAKn|Cs=o8mP&}0WxW4KDNL*wqJIlyNJOGstdT#&|7BUko>IwLgVcNOy5%Dz>6mb z4q1jZrx)`QeJmX2lYGY#h4(B|7f*cXLI%7oJSsJv5Yy*kKdYe?wo67A)px1&cJ zi$ba_oi5qRYn6A88}g3H2}TP7MV1@W-eyZqZ)cy4UTL~}q1BNM?76A;&;Pt1{;Oz3 z@|(n~XV`~>iya11duvipbNAGsl%7mGgBvCv{F{%u8lFkW`m)wGq?O;)b0oa{`;fHr z{T5dI?dr#7PRH|jH>tU1jepTG(#bVOw)<;S(f&iL5B>aGkS;Yex8G=};U7#xuRaQE z^eH%}6<5PnKj94;9HrgS86ApjbR00MBFvZ-sm?_fm<~>+#S4V*R zmcp-f1C}0EzPwGZYG#)&*&!P>7g5R;>vYtdp>^o+WvewSVvP?GwymaCiZk+GtNjRx zr|LGXWc@_o%FRB>0m2Zs$Y9f-_{;OkhNwKvv8Sk#8<$n-SPeae1B#d zz$>fRepj)zjol0{C9{O&l_1Dpv6{_VXy8qd`Or`qzw6eInY-)2egjj{dG<4Y!9{!V z=2EIX-$!h9mkkx|d8!w%hBz1LfLP47Sia?0_pjJr6e}O{(QXoS2JW1DE$>`*x#aB&y%$gDB z*zt$~OXhld#T<1LM2w{ltwY?Z6zi<~8EGQIjP>*#n$Rq4R|i`$Ceo^%fC+!jU6glq zhRY5TJXW4G3tDgm11_$?I%BOh2(I0~JY;6LwT4pn;6Brn!KXMhB{0c}y!5;-yC}|7 z5Q~`$hz?T4AYB7}&A?pYld6DQ^YwBVoBOcoHWU-l(Cd8YnO4B^Xca>2y4;woW6CIZ z5ls~qF}DIKfhHh8ONQulzUjv7>o8-&A9JhfB780G)bER<)E?vM7OKcFFQkGl=Ixks zgQ#W-x?$EPhL=R-VSPeJyJrl(&_qJiF$r?*K?E%~iWfF(RhTj~wHHsUGH8_-#fckC zw6f3-&#o5e1S?Ili-ov3w@4Qo(@wU;TtnsOM@?D!#RlC5WmQHCz4-VQLII+yJBn);LZm>k z5BjBlH7izv1h>(!b8PSZ!EwOiN8_TpCdi;Aj*%`9nYcFzG2XZ)s|u$y1{5sr|6Hy& z(hUcN`XM!M)n>`xq$W;=n^({|0)&I3Ufj-wPOAJIn>g}Zq@NyptejS_B-ToBEA{81 z>K};S_>wnxokBZDAVQ-?A@hwBSN#O>NPz&cC76Oml6Z`-^zll^X>YTe&Ebz{G#M1Z zCXYs_$%U|Vk^yBZycbMOdh3-7u!UM;qw&a2R`u9DyMEk2Enj8(GehW)oj}fP@+J^F z!B)0_yap7Z{YoJh=S!D2`0HddgX6zfYQ!55iT}BRE)de>A68MYAz^|?120`Jc25h@ z+&TY>oC$i(6u;)DO>~oqt++?Al+0MkD>RE-x=79|f zrJy@0uiy{35XWh(aBo&JLJ%Z*d6C)0|*C8z_`W3%iGK znXAF##ql_xQ_qf4YT{C{aEGAKSTn9%J3)DkbZ0qkHAD}cxg47$6~RQFFfTv^45Yz& zW-^Lp3!cZ}ucYBJEMX;6e_YzB$IH6qm(J5Ym()X>adftsfHgkP`f2_%M%P<|Xm_gw zEAoI~WA)v%RRM>7+4r3&;tr`E8yzM8xMrCq?fv86DZB)*?GSd;eF}6A4}5t z?wcv1Q(-H4IKTQPB!#F?l4g#Oql$Za&{CVys>D#_I2Ln$lK> z!%?!Q;Ss?P?Ueae^?Ybc9FA@Nqq&E(FJ*fz@Uo$d& z0@b-XVV7y#V!~IBUy3pQ7&+1S^pd$H0(gb+nnw8OWP!%UF_=3e-C{Z+Ah^lkU*5qP zHY)K?axJkN`wGI9;Afv_h;(Ke2~p}7&X+?%%Ju={4&f3dsD)^~u;~jF_ot2aiF6af z3C2u+%?!3prc3-H4{7kmAYsY+a$};Y{I2%QZ&UhG9}Ts{aWM0wfNhyU+O3pRj3E)N z;diY8#cGNOh?rPDLCu$M#I@j@8*B92`^$E&U)-->#nX(smhrIJw2&SE28cIl~z z&et+VltM$RZLBP`5;*5rp^FB0IQX z(lW*fpBLdV(U7Dy|2L#K5HQ#|Zrh}8~;d5L9kW;*k5 z#{=xuV}Lm22*U}365#kCX7IKL`WADSQ7%j1-Cwu-fm5RZ+|DJnGYItnHCDn_4B*0o zyoc#&IIZZP6p}u6RYfnm#A$Q}onN3+TuUFRpVZv@-=f-P~#Yy6nwY!D%zBS9xsLm0ko{u ziqi_^1EMRJVsok>Yr^Rd2AppO{m!8PrZI8U3VfkY%cYfbi$&xg_i5nxZ zOZYOTN`uWPIcr(6wjg=AVEL>+?IK>bSGTn8B{JnBte-AZBss7ZNM<99Or`X>u+$9F z93Q*Wl(<~xI?ez+di&oRj|V}Kr`%#sqbr|dOSuOE6n5~wj^K7xB|gUY6W zJqPu%B!z7tZdk#t-p;C#5()lHJ3ZOKVk^c*S&e%rw@E?o0Y|d4;4%T(`67qHHIWR{ z|9h*WF~m%wAI^_iZeLq^oiJ!YJF2kP pr4SV)Sl&YD#%e%5S<18#Nf1NC&`bH z=GcVw@8}~Sr1J0^Zsa=2GJNl3HIPfhpVCfg$5u z7_bj+xSbP&SMROPd}d`Xw+gnF9I^~F%omaOxgLW6MI##DCa0bPC9ksg__FKPZOTzI zgOdwmFcQ&LKrX|j+q>Z#TS+m_yDr$XjdEBPW~J+V$*^hg-Dxu{f?_3y&QEV^>W4WD zES66@W2m_l5Ywd%%X0SQavSHW3V)U~o_@Ew%8$Bb6sV?}CYUa>f0pO)1CS(`d2PCvYZI zs}>v$CnCoO&~IPj&yry+w_~Uzk>} zQSZ(;`y$yVD)vyU)lyvg)a+fhkr@**#xZv(xv8ze7!Y&W8U-@r0sviPgw$R?e8Vax zbzpn&H@c;QuHX@i{Aqy-dOKh9lQiC)e>Rs$@R4wC^RW~@wMpP~`$@f|)H&JJ{B{xo zYa#ci;iA((JwkU^Q4TO5qx9138aF1lNGj1dpg_(q*x$hb)W>xGR_jF3`O&uXMdr;y z$%#))=oyMcu~YKyz_<)W`N&Pnb57kUNyyQoipmFU!YL^YR$p+*m!Ci5N{e_+Hs)qn z$hUF$Fr=ur(MZfpCYU=n^i0F~5^5s<5>IkznSpdS6RKA&i&A0dx%=8(4pn~B*yV7+ zQ*{~*M+fmTw#yZ_ySuNA*mvN2v@yh#h;%Sd@?ugtl-MF1Lsd|?;_8`_tI0-=;j2A1 z%ZWljL2>K=fO}r1qZ0W0k!zoa%PeGwRDO#1sB&JJH@z4JXfbwZ$q*b=?{zzr z{Hi_*5N^H1w4NMu`y8=NK8n0X1*fK1~|HiPp|6$Oxg;Aobowc>8?T7eKp@q&$uC8bW0^ecvDvGhx^FA9LbOyZB%y4coY)Uox(SD*C0M&0oXacKLc4 ztxyT#aNA*UPW+vImVYSK%KRa2GOVD+G3{CpB2j>HSwMZLPVkrAgvS|#o6mB@vLbI) zeRc>u%Z2k9lsGQb%S9`3l*J?s@rhgbP_ty`zlpA_=ja^&m~{lrKmpeLgvASpLD%%p zsTB1J#G4uSlM-teTuf)A)~J@`t}wLt6=Ero!|y0v5|WM-+lv$H;$64cx3y~(TW9i< zc$BBt^o8;zNes#f9G!xRS>8{MPD3>`;t4h-K(r){zsOLr^bak~j}ZAcM>LK}ImjmD zZ)T1Haubj8w+myx6O|-uxs$>lWoRnADMm7Ks2m;R67DgL5gE~w4gaoq^5G&hr9z7E z{3)TyB`f2HGBe6W=JL1a-Bj>*wG)lRrp_@Bqp8^n8I;0CDKca02D8U|pVyiV{vK`o zfPGYT!T4V-(}6K&f#NTo==qcOoxR@7u3%aLLz9t6k*{W8Y;w1Sh9^#OkrCGeumdOh zNyhG}7I&NOBH=`X3aChcgz~YITr=icVu}E<`2$@q84FV`Huik=x9NX3nVbnl4W;ne ztrWV15x_%p?Q`RNA6KowW+kr!JqdY=*Li^6BBvB9msEXZ|0<(~)Y~*@Ipqo{fg2a{ zHZJt#(*1pw1WE|IFOq^t#5EEcRS5Q}(8yGcYjSL-bb;GJVvdSfq9X1D*f9lhyGrvI zpvt8*hgdC?%tqEq>F)vcJx{|iZb3Odeoa1pL#DC)AaN6$RPRY@mJ%-T^iOVlU#A31 zB%~+G5Zg|zWT5xU3S=Fww{_(G)x62p`pLFilQ&;X-kP73FaFTw`N2|)0o?xwi$@na literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/9.gif b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/013/9.gif new file mode 100644 index 0000000000000000000000000000000000000000..cdf3610c89471daa69283184413155feb80cb05c GIT binary patch literal 4813 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 O`b! literal 0 HcmV?d00001 diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/014.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/014.html new file mode 100644 index 0000000..9ed4ce5 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/014.html @@ -0,0 +1,69 @@ + + + + + Test Case 14: Exceptions in Repetition Events « Web Forms 2.0 Test Suite + + + + + + + + + + + + +

    + +

    Web Forms 2.0 Test Case 14: Exceptions in Repetition Events

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following demonstrates that the repetition model code does not fail when a user-supplied event handler raises an exception.

    + + + +
    +
    + + +

    Note that the there should be errors raised whenever repetition behavior is envoked. An event handler createRuntimeException purposely raises a runtime error.

    +
      +
    1. + + + + +
    2. +
    + + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/015.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/015.html new file mode 100644 index 0000000..1d549c2 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/015.html @@ -0,0 +1,78 @@ + + + + + Test Case 15: Required Elements in Repeated Blocks « Web Forms 2.0 Test Suite + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 15: Required Elements in Repeated Blocks

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following demonstrates using the required attribute on controls within a repetition template. The autofocus attribute is also included an input.

    + + + +
    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    NameNumber of Cats
    +

    + + +

    +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/016.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/016.html new file mode 100644 index 0000000..c6020fe --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/016.html @@ -0,0 +1,57 @@ + + + + + Test Case 16: Autofocus on unfocusable form control « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 16: Autofocus on unfocusable form control

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following tests whether the hidden INPUT element below is incorrectly (attempted to be) focused upon. Attempting to focus on hidden form controls raises an exception in MSIE.

    + + + +
    +
    + + + +

    The following form, containing an input element with an autofocus attribute, is set to not display with CSS.

    +
    + +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/017.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/017.html new file mode 100644 index 0000000..e504c2c --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/017.html @@ -0,0 +1,324 @@ + + + + + Test Case 17: Form validation « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 17: Form validation

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The following tests all of the form validation controls.

    + + + +
    +
    + + + +
    + invalid Event model options +
    + + Unsupported by this browser +
    +
    +
    +
    + + + + + + +
    +
    +
    + +
    + Calendar controls +
      +
    • type=datetime
    • +
    • type=datetime-local
    • +
    • type=date (no step)
    • +
    • type=month step=2
    • +
    • type=week step=2
    • +
    • type=time step=any
    • +
    +
    +
    + Text input +
      +
    • type=text (required)
    • +
    • type=text (pattern="\d\d\d-\d\d-\d\d\d\d")
    • +
    • type=text (required pattern="\(\d\d\d\) \d\d\d-\d\d\d\d")
    • +
    • type=email (required, overriding oninvalid)
    • +
    • type=text (required)
    • +
    • type=text (pattern="")
    • +
    • type=url (required pattern)
    • +
    • (length should be 7) maxlength=10 (QUESTION: what about when maxlength < len(defaultValue))
    • +
    • type=range default step = 1
    • +
    • type=number min=-127, max=128, step=0.5
    • +
    +
    + +
    + Non-input required +

    Favorite color: + + +

    +

    Favorite food: + + +

    + +

    Movies:

    +
    +
    +
    +
    +
    + Event Log +
    + +
    +
    + Form is valid! +
    + + + + + + + + + + + +
    #TypeElementModel
    +
    (Click the "check validity" button above to fire events)
    +
    +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/018.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/018.html new file mode 100644 index 0000000..20a6be6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/018.html @@ -0,0 +1,115 @@ + + + + + Test Case 18: Input Controls in Nested Repetition Blocks « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 18: Input Controls in Nested Repetition Blocks

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    Testing various types of input controls in nested repetition blocks.

    + + + +
    +
    + + +
    +

    Solar system

    +

    +

    Planets

    +
      +
    1. + + + +
      + Class: + +
      + +
      +
      +
      + +
      + Moons +
        +
      • + + Class: + + + + +
      • +
      +

      +
      +

      +
    2. +
    +

    +

    +
    + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-colors.xml b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-colors.xml new file mode 100644 index 0000000..8c33384 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-colors.xml @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-formdata.xml b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-formdata.xml new file mode 100644 index 0000000..1f2b0f8 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-formdata.xml @@ -0,0 +1,16 @@ + + + + + + index (pre-filled) + index 101 + test + test + + green + blue + evening + Fridays are awesome! + 2007-W01 + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-statesAndProvinces.xml b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-statesAndProvinces.xml new file mode 100644 index 0000000..99adcca --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019-statesAndProvinces.xml @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019.html new file mode 100644 index 0000000..c7d9315 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/019.html @@ -0,0 +1,405 @@ + + + + + Test Case 19: Prefilling form data « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 19: Prefilling form data

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    Regarding fetching data from external resources, the specification states:

    There are two scenarios where authors may wish data to be fetched from an external file to fill forms. In the first, a select's options are replaced by options from an external file. In the second, a form's values are prefilled from an external data source.

    In both cases, the prefilling may either be full, in which case the previous contents are removed first, or incremental, in which case the fetched data is in addition to the data already in the form.

    + + + +
    +
    + + +

    Filling select elements

    +
    + +

    States and provinces: (3 states, 2 provinces)

    + +

    Colors: (there should be 8 colors, 5 provided incrementally)

    + + +

    +
    + +

    Seeding a form with initial values

    +

    The formdata XML file associated with the following form first + clears all of the existing repetition blocks. Then it adds two repetition blocks + with indexes 100 and 101. Then it prefills the values of these two repetition blocks.

    +
    +
      +
    1. + + + + +
    2. +
    3. + + + + +
    4. +
    5. + + + + +
    6. +
    7. + + + + +
    8. +
    9. + + + + +
    10. +
    + + +

    +

    + +

    Last two checkboxes below should be checked (prefilling failed if only "Red" is checked): + + + +

    + +

    The "Evening" button should be selected (prefilling failed if "Afternoon" is checked): + + + + +

    + +

    +

    +
    + + +

    Setting data DOM property dynamically on select elements

    + +

    The following tests are adapted from an example in the Filling select elements section. + The eight following select elements should have exactly the same contents. Note that only the first four will work in Internet Explorer 7.

    + +
      +
    1. + Loading... + Before onload, data DOM attribute set on statically created element: + +
    2. + + +
    3. + Loading... + Before onload, data content attribute set on statically created element: + +
    4. + + +
    5. + Loading... + Before onload, select element dynamically created; data DOM attribute set: +
    6. + + +
    7. + Loading... + Before onload, select element dynamically created; data content attribute set with setAttribute(...): +
    8. + + +
    9. + Loading... + After onload, data DOM attribute set on statically created element: +
    10. + + +
    11. + Loading... + After onload, data content attribute set on statically created element: +
    12. + + +
    13. + Loading... + After onload, select element dynamically created; data DOM attribute set: +
    14. + + +
    15. + Loading... + After onload, select element dynamically created; data content attribute set with setAttribute(...): +
    16. + + +
    + + + + + + + + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/020.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/020.html new file mode 100644 index 0000000..71ad29a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/020.html @@ -0,0 +1,84 @@ + + + + + Test Case 20: Creating Repetition Templates Dynamically « Web Forms 2.0 Test Suite + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 20: Creating Repetition Templates Dynamically

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +
    + + + +
    +
    + + + + + +

    The following statement, "We are quintuplits", should be repeated five times:

    +
    + +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/021.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/021.html new file mode 100644 index 0000000..5e9cc17 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/021.html @@ -0,0 +1,79 @@ + + + + + Test Case 21: "required" attribute on checkboxes and radio buttons « Web Forms 2.0 Test Suite + + + + + + + + + + + + + +
    + +

    Web Forms 2.0 Test Case 21: "required" attribute on checkboxes and radio buttons

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + +

    The specification states:

    For checkboxes, the required attribute shall only be satisfied when one or more of the checkboxes with that name in that form are checked.

    For radio buttons, the required attribute shall only be satisfied when exactly one of the radio buttons in that radio group is checked.

    Specifying a required attribute on a checkbox only makes sense when there are multiple checkboxes defined to be in a group by providing each with the same name attribute (as the quote from the specification makes reference to). In Opera 9.23 when a required attribute is specified on either one or all radio buttons in a group, the form validates if one of the buttons is checked. With regard to a group of checkboxes, however, when the required attribute is defined on one checkbox, that one specific checkbox must be checked in order for the form to validate in Opera. If the required attribute is defined on all checkboxes in the group, then the form only validates if every checkbox is checked. Opera's implementation, then, is faulty, since it does not make sense to present the user with a single checkbox that must always be checked, and since the specification states that UAs must apply the required attribute onto the entire group of checkboxes, not every single one individually.

    + +

    + +
    +
    + + + +
    +
    + required attribute set all controls in a group +

    Favorite color: + + +

    +

    Favorite food: + + +

    +
    + +
    + required attribute set on last control of a group +

    Favorite color: + + +

    +

    Favorite food: + + +

    +
    +

    +
    + + + +
    + Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/index.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/index.html new file mode 100644 index 0000000..2cf379b --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/index.html @@ -0,0 +1,45 @@ + + + + + + Web Forms 2.0 Test Suite + + +

    Web Forms 2.0 Test Suite

    +

    The following test suite is compiled in order to give examples of what the Web Forms 2.0 specification + is designed to do. Its purpose is also to test the implementations as found in Opera and also the + cross-browser Web Forms 2.0 implementation.

    + +
      +
    1. Spec Example: Sample Order Form
    2. +
    3. Spec Example: Repeated rows: Dynamically adding table rows
    4. +
    5. Spec Example: Solar system: Nesting repetition elements two levels deep
    6. +
    7. Movement Buttons and Canceling Default Action
    8. +
    9. Repetition Index in Attributes: Replacing template name block's current repetition index in all attributes
    10. +
    11. Repetition Events: Demonstrating the handling of added, removed, and moved events
    12. +
    13. Repetition Event Handler Attributes: Demonstrating the use of the onadd, onremove, and onmove attribute handler extensions
    14. +
    15. Initialization Time: Verifies whether or not the repetition template is initialized before onload.
    16. +
    17. Repetition Buttons: Demonstrates repetition buttons created with BUTTON and INPUT elements.
    18. +
    19. Orphan Repetition Blocks
    20. +
    21. Disabled Form Fields in Template
    22. +
    23. repeat-min, repeat-max, and repeat-start attributes
    24. +
    25. Repeated Photo Albums: Demonstrates repetition model-driven content in nested repetition templates.
    26. +
    27. Exceptions in Repetition Events
    28. +
    29. Required Elements in Repeated Blocks
    30. +
    31. Autofocus on unfocusable form control
    32. +
    33. Form validation
    34. +
    35. Input Controls in Nested Repetition Blocks
    36. +
    37. Prefilling form data
    38. +
    39. Creating Repetition Templates Dynamically
    40. +
    41. "required" attribute on checkboxes and radio buttons
    42. + +
    +
    + Test suite powered by cross-browser Web Forms 2.0 implementation
    + Version: 0.5.2 (2007-11-29) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/testcase.css b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/testcase.css new file mode 100644 index 0000000..58db76f --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/testcase.css @@ -0,0 +1,38 @@ +#testSuiteNote { + border:dotted 1px gray; + padding:1em; + background-color:#EEE; + margin-bottom:1em; +} +#testSuiteNote h1 { + margin:0; + margin-bottom:1pt; + font-size:medium; +} +#testSuiteNote p.purpose +{ + margin-top:0; + font-style:italic; +} + +.testSuiteNavigation { + text-align:center; +} +.testSuiteNavigation a +{ + +} +.testSuiteNavigation a.prev, +.testSuiteNavigation a.index +{ + margin-right:1ex; +} +.testSuiteNavigation a.next, +.testSuiteNavigation a.index +{ + margin-left:1ex; +} + +#testSuiteNote hr { + display:none; +} \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/001.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/001.html new file mode 100644 index 0000000..a5e1364 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/001.html @@ -0,0 +1,38 @@ + + + + Spec Example: Sample Order Form + + + + + +
    +

    The following is the first example from the specification:

    +
    + + +

    Sample Order Form

    +
    + + + + + + + + + + + + + + +
    ProductQuantity
    +

    +

    +
    + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/002.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/002.html new file mode 100644 index 0000000..955b191 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/002.html @@ -0,0 +1,53 @@ + + + + Spec Example: Repeated rows + + + + + + + +
    +

    The following example from the specification "shows how to use repetition templates to dynamically add rows to a form in a table": + +

    +

    Initially, two rows would be visible, each with two text input controls, the first row having the values "John Smith" and "2", the second row having the values "" (a blank text field) and "1". The second row is the result of the (implied) repeat-start attribute adding a repetition block when the document was loaded.

    +

    If the "Add Row" button is pressed, a new row is added. The first such row would have the index 2 (since there are already two repetition blocks numbered 0 and 1) and so the controls would be named "name_2" and "count_2" respectively.

    +

    If the "Delete Row" button above is pressed, the row is removed.

    +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + +
    NameNumber of Cats
    +

    + + +

    +
    + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/003.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/003.html new file mode 100644 index 0000000..2417c09 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/003.html @@ -0,0 +1,46 @@ + + + + Spec Example: Solar system + + + + + + +
    +

    The following is the specification's example of nested + repetition elements:

    + +
    +

    The previous example does not demonstrate nested repeat blocks, reordering repetition blocks, and inserting new repetition blocks in the middle of the existing sequence, all of which are possible using the facilities described above. This example shows nested repeats.

    +

    Note that to uniquely identify each nested repeat (which is required since the add buttons are dependent on IDs to specify which template should have a block added), the IDs of the nested templates are specified in terms of the ancestor template's ID, using the index substitution feature.

    +
    +
    + + +
    +

    Solar system

    +

    +

    Planets

    +
      +
    1. + +

      Moons

      +
        +
      • + + +
      • +
      +

      +

      +
    2. +
    +

    +

    +
    + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/004.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/004.html new file mode 100644 index 0000000..92e88f8 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/004.html @@ -0,0 +1,285 @@ + + + Movement Buttons and Canceling Default Action + + + + + + + + + + +
    +

    The following demonstrates the use of all of the repetition model buttons—add, remove, move-up and move-down—as well as the various ways to cancel the default action of these repetition buttons. + It also provides examples of customized addition buttons.

    +
    + + + + +

    Note: Buttons with ellipses will confirm the action.

    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    No onclick handler » +
    +
    onclick HTML attr. » +
    +
    onclick DOM property » + +
    DOM Event Level 2 click »
    (native implementations only)
    + +
    +
    + +

    Form addition buttons (RepeatMax = 5):

    + + + + + + + + + + + + + + + + + +
    No onclick handler »
    onclick HTML attr. »
    onclick DOM property »
    DOM Event Level 2 click »
    (native implementations only)
    +

    Other addition buttons: + + +

    + + +
    + + + + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/005.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/005.html new file mode 100644 index 0000000..875741d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/005.html @@ -0,0 +1,245 @@ + + + + Repetition Index in Attributes + + + + + + + + + + + +
    +

    For all attributes in a block, template name is to be replaced with the block's current repetition index. The first section below is a test case taken from: <http://simon.html5.org/test/webforms2/repetition/addition/001.htm>; the second section contains a more thorough test case. + It demonstrates Opera bug #230280 and this implementation's issue #7. The specification defines the correct behavior in 3.6.1. Addition:

    + +
    +

    ...any occurrences of a string consisting of an opening square bracket (U+005B, "[") or a modifier + letter half triangular colon (U+02D1, "ˑ"), the template's name, and a closing square bracket (U+005D, "]") + or a middle dot (U+00B7, "·"), are replaced by the new repetition block's index. This is performed regardless + of the types, names, or namespaces of attributes, and is done to all descendants, even those inside nested forms, + nested repetition templates, and so forth.

    +
    +
    + + +

    Test Case from simon.html5.org

    +
    +
    + + +
    TEST
    +
    + +

    The above should be exactly equivalent to the following:

    + +
    + + +
    TEST
    + + +
    TEST
    +
    +
    + +
    +

    Extensive Attribute Test

    + +

    Whereas every attribute which contains "[j]" should be replaced with the repetition index (0), +it is likely, due to Opera bug #230280 and my issue #7, +the specified behavior will fail in style and non-CDATA attributes (note that a '1' is also included as "1[j]" so the value of "10" should appear in each attribute):

    + + +
    +
    + + + + + + + + + + + + + + + + + + +
    T + + + +
    + + (This field has access key set to 1[j]) + + +
    + + + +
    +
    + Image 1[j] + test +
    rowspancolspan + +
    + q +
    +
    test
    + + + + test + +
      + +
    + +
    +
    +
    + + +

    Test results

    + + + + + + + +
    AttributeValue of attribute (should contain '10')
    +

    Test result: working...

    +
      +
    1. working...
    2. +
    + + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/006.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/006.html new file mode 100644 index 0000000..98d398a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/006.html @@ -0,0 +1,203 @@ + + + Repetition Events + + + + + + + + + + + +
    +

    The following demonstrates the handling of repetition events, using both the DOM Level 2 event model and the traditional event model; the MSIE's proprietary event model is not demonstrated.

    +
    + + + +
    +
    + Event model options +
    + + Unsupported by this browser +
    +
    + (extension provided by implementation)
    +
    + +

    +
      +
    • + + + +
    • +
    +
    +
    + +
    + Event Log + + + + + + + + + + +
    #TypeElementModel
    +
    (Click the add button above to fire events)
    +
    + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/007.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/007.html new file mode 100644 index 0000000..b7bb0b9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/007.html @@ -0,0 +1,129 @@ + + + Repetition Event Handler Attributes + + + + + + + + + + + +
    +

    The following demonstrates the handling of repetition events handled by onadded, onmoved, and onremoved + HTML attributes set on a repetition template which handle their respective events. This is made possible by extension to the specification, found in this implementation.

    +
    + + + +
    +

    +
      +
    • + + + +
    • +
    +
    +
    + +
    + Event Log + + + + + + + + + +
    #TypeElement
    +
    (Click the add button above to fire events)
    +
    + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/008.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/008.html new file mode 100644 index 0000000..6763b33 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/008.html @@ -0,0 +1,56 @@ + + + Initialization Time + + + + + + + + + + +
    +

    The following test verifies whether or not the repetition template is initialized before the user's onload fires.

    +
    + + +

    Test result: loading page...

    + +
    +
    +
    + + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/009.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/009.html new file mode 100644 index 0000000..3336be9 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/009.html @@ -0,0 +1,64 @@ + + + Repetition Buttons + + + + + + + + + + +
    +

    The following test verifies whether repetition buttons can be created using either button or input elements. + +

    + + + +
    +
      +
    1. + + + + +
    2. +
    +

    +
    + +

    The preceding DIV should appear exactly as the one below:

    + +
    +
      +
    1. + + + + +
    2. +
    +

    +
    + + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/010.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/010.html new file mode 100644 index 0000000..ed60b6a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/010.html @@ -0,0 +1,50 @@ + + + Orphan Repetition Blocks + + + + + + + + + + +
    +

    The following demonstrates prefilled orphaned repetition blocks.

    + +
    + + + +

    The following blocks are prefilled and orphaned.

    +
    +
      +
    1. + Orphan 1: + + + +
    2. +
    3. + Orphan 2: + + + +
    4. +
    5. + Orphan 3: + + + +
    6. +
    +
    + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/011.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/011.html new file mode 100644 index 0000000..e0b87e1 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/011.html @@ -0,0 +1,99 @@ + + + Disabled Form Fields in Template + + + + + + + + + + + +
    +

    The following verifies that form fields within a repetition template are not successful. It also tests whether form fields disabled + in the repetition template are also disabled in each instantiated repetition block, but note: for this to work in this implementation, authors must + include a class name of "disabled" on all disabled elements in the repetition template element to ensure that they are also disabled in each repetition block. This is due to an issue in Firefox which is detailed in issue #9.

    +
    + + + + + +
    +
      +
    1. + Not disabled element:
      + Disabled element: (this should not be successful in form submission) +
    2. +
    + + +
    + +

    Test results

    +
      +
    1. Form fields in repetition template should not be 'successful' (there should not be any querystring parameters with keys such as submitted[i]; these fields should not be submitted): + + Press 'submit form' to test... + Passed + Failed! + +

    2. + +
    3. Form fields in the repetition template which are originally flagged as disabled should be disabled in each instantiated repetition block: + + Press 'submit form' to test... + Passed + Failed! + +

    4. +
    + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/012.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/012.html new file mode 100644 index 0000000..c6a8e82 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/012.html @@ -0,0 +1,79 @@ + + + repeat-min, repeat-max, and repeat-start attributes + + + + + + + + + + +
    +

    The following verifies that the repeat-min, repeat-max, and repeat-start attributes work correctly. + The event log utilizes the onadd and onremove extensions to the repetition model specification.

    +
    + + + +

    For the following repetition template:

    +
      +
    • repeat-min = 1
    • +
    • repeat-max = 5
    • +
    • repeat-start = 3
    • +
    + +
    +
    + # +
    +
    +

    + +
    + Event Log + + + + + + + + + +
    #TyperepetitionBlocks.length
    +
    (Click the add button above to fire events)
    +
    + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/013.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/013.html new file mode 100644 index 0000000..3a97f4d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/013.html @@ -0,0 +1,92 @@ + + + Repeated Photo Albums + + + + + + + + + + + +
    +

    The following demonstrates repetition model-driven content in nested repetition templates. Note the use of repetition indexes in img[src], img[alt], and img[repeat-start] attributes, as well as in the background-image CSS property within a style attribute. If your browser supports addEventListener, you will see a dynamic count of the photos in an album, and you will be able to delete a photo by clicking it. There are only images for numbers from 0 to 16. Opera 9.02 does not display the repetition model-driven background image, and furthermore it does not correctly initialize the nested repetition template; this is probably due to the repetition index appearing in the repeat-start which Opera requires to be an integer.

    +
    + + + +
    +
    + Album #[albums] Photo album # +
    +

    There are currently 0 photo(s) in this album. Click on a photo to delete it.

    + (max-repeat = 17; repeat-start = repetitionIndex) +
    + Image in album [albums], with repetition index [album[albums].photos] +
    +
    +
    +
    +

    + +

    Graphics from <http://school.discovery.com/clipart/category/letr0.html>.

    + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/014.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/014.html new file mode 100644 index 0000000..6499854 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/014.html @@ -0,0 +1,44 @@ + + + Exceptions in Repetition Events + + + + + + + + + +
    +

    The following demonstrates that the repetition model code does not fail when a user-supplied event handler raises an exception.

    +
    + + +

    Note that the there should be errors raised whenever repetition behavior is envoked. An event handler createRuntimeException purposely raises a runtime error.

    +
      +
    1. + + + + +
    2. +
    + + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/015.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/015.html new file mode 100644 index 0000000..70fccd6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/015.html @@ -0,0 +1,54 @@ + + + Required Elements in Repeated Blocks + + + + + + + + + +
    +

    The following demonstrates using the required attribute on controls within a repetition template. + The autofocus attribute is also included an input.

    +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    NameNumber of Cats
    +

    + + +

    +
    + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/016.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/016.html new file mode 100644 index 0000000..815b8f3 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/016.html @@ -0,0 +1,33 @@ + + + Autofocus on unfocusable form control + + + + + + + + + + + +
    +

    The following tests whether the hidden INPUT element below is incorrectly (attempted to be) focused upon. Attempting to focus on hidden form controls raises an exception in MSIE.

    +
    + + + +

    The following form, containing an input element with an autofocus attribute, is set to not display with CSS.

    +
    + +
    + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/017.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/017.html new file mode 100644 index 0000000..622741c --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/017.html @@ -0,0 +1,301 @@ + + + + Form validation + + + + + + + + + + + +
    +

    The following tests all of the form validation controls.

    +
    + + + +
    + invalid Event model options +
    + + Unsupported by this browser +
    +
    +
    +
    + + + + + + +
    +
    +
    + +
    + Calendar controls +
      +
    • type=datetime
    • +
    • type=datetime-local
    • +
    • type=date (no step)
    • +
    • type=month step=2
    • +
    • type=week step=2
    • +
    • type=time step=any
    • +
    +
    +
    + Text input +
      +
    • type=text (required)
    • +
    • type=text (pattern="\d\d\d-\d\d-\d\d\d\d")
    • +
    • type=text (required pattern="\(\d\d\d\) \d\d\d-\d\d\d\d")
    • +
    • type=email (required, overriding oninvalid)
    • +
    • type=text (required)
    • +
    • type=text (pattern="")
    • +
    • type=url (required pattern)
    • +
    • (length should be 7) maxlength=10 (QUESTION: what about when maxlength < len(defaultValue))
    • +
    • type=range default step = 1
    • +
    • type=number min=-127, max=128, step=0.5
    • +
    +
    + +
    + Non-input required +

    Favorite color: + + +

    +

    Favorite food: + + +

    + +

    Movies:

    +
    +
    +
    +
    +
    + Event Log +
    + +
    +
    + Form is valid! +
    + + + + + + + + + + + +
    #TypeElementModel
    +
    (Click the "check validity" button above to fire events)
    +
    +
    + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/018.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/018.html new file mode 100644 index 0000000..96ab524 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/018.html @@ -0,0 +1,92 @@ + + + + Input Controls in Nested Repetition Blocks + + + + + + + + + + + +
    +

    Testing various types of input controls in nested repetition blocks.

    +
    + + +
    +

    Solar system

    +

    +

    Planets

    +
      +
    1. + + + +
      + Class: + +
      + +
      +
      +
      + +
      + Moons +
        +
      • + + Class: + + + + +
      • +
      +

      +
      +

      +
    2. +
    +

    +

    +
    + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-colors.xml b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-colors.xml new file mode 100644 index 0000000..8c33384 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-colors.xml @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-formdata.xml b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-formdata.xml new file mode 100644 index 0000000..1f2b0f8 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-formdata.xml @@ -0,0 +1,16 @@ + + + + + + index (pre-filled) + index 101 + test + test + + green + blue + evening + Fridays are awesome! + 2007-W01 + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-statesAndProvinces.xml b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-statesAndProvinces.xml new file mode 100644 index 0000000..99adcca --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019-statesAndProvinces.xml @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019.html new file mode 100644 index 0000000..c9a0f2a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/019.html @@ -0,0 +1,388 @@ + + + + Prefilling form data + + + + + + + + + + + +
    +

    Regarding fetching data from external resources, the specification states:

    + +
    +

    There are two scenarios where authors may wish data to be fetched from an external file to fill forms. In the first, a select's options are replaced by options from an external file. In the second, a form's values are prefilled from an external data source.

    + +

    In both cases, the prefilling may either be full, in which case the previous contents are removed first, or incremental, in which case the fetched data is in addition to the data already in the form.

    +
    +
    + + +

    Filling select elements

    +
    + +

    States and provinces: (3 states, 2 provinces)

    + +

    Colors: (there should be 8 colors, 5 provided incrementally)

    + + +

    +
    + +

    Seeding a form with initial values

    +

    The formdata XML file associated with the following form first + clears all of the existing repetition blocks. Then it adds two repetition blocks + with indexes 100 and 101. Then it prefills the values of these two repetition blocks.

    +
    +
      +
    1. + + + + +
    2. +
    3. + + + + +
    4. +
    5. + + + + +
    6. +
    7. + + + + +
    8. +
    9. + + + + +
    10. +
    + + +

    +

    + +

    Last two checkboxes below should be checked (prefilling failed if only "Red" is checked): + + + +

    + +

    The "Evening" button should be selected (prefilling failed if "Afternoon" is checked): + + + + +

    + +

    +

    +
    + + +

    Setting data DOM property dynamically on select elements

    + +

    The following tests are adapted from an example in the Filling select elements section. + The eight following select elements should have exactly the same contents. Note that only the first four will work in Internet Explorer 7.

    + +
      +
    1. + Loading... + Before onload, data DOM attribute set on statically created element: + +
    2. + + +
    3. + Loading... + Before onload, data content attribute set on statically created element: + +
    4. + + +
    5. + Loading... + Before onload, select element dynamically created; data DOM attribute set: +
    6. + + +
    7. + Loading... + Before onload, select element dynamically created; data content attribute set with setAttribute(...): +
    8. + + +
    9. + Loading... + After onload, data DOM attribute set on statically created element: +
    10. + + +
    11. + Loading... + After onload, data content attribute set on statically created element: +
    12. + + +
    13. + Loading... + After onload, select element dynamically created; data DOM attribute set: +
    14. + + +
    15. + Loading... + After onload, select element dynamically created; data content attribute set with setAttribute(...): +
    16. + + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/020.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/020.html new file mode 100644 index 0000000..0e30d79 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/020.html @@ -0,0 +1,69 @@ + + + + Creating Repetition Templates Dynamically + + + + + + + +
    + + +
    + +
    +
    + + + + + +

    The following statement, "We are quintuplits", should be repeated five times:

    +
    + +
    + + + + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/021.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/021.html new file mode 100644 index 0000000..ffaf751 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/021.html @@ -0,0 +1,82 @@ + + + + "required" attribute on checkboxes and radio buttons + + + + + + + + + + + +
    +

    The specification states:

    +
    +

    For checkboxes, the required + attribute shall only be satisfied when one or more of the checkboxes with + that name in that form are checked.

    +

    For radio buttons, the required + attribute shall only be satisfied when exactly one of the radio buttons in + that radio group is checked.

    +
    + +

    + Specifying a required attribute on a checkbox only makes sense when there + are multiple checkboxes defined to be in a group by providing each with the same name attribute + (as the quote from the specification makes reference to). + In Opera 9.23 when a required attribute is specified on either one or all radio buttons in a group, + the form validates if one of the buttons is checked. With regard to a group of checkboxes, however, when the + required attribute is defined on one checkbox, that one specific checkbox must be + checked in order for the form to validate in Opera. If the required attribute is defined on all checkboxes + in the group, then the form only validates if every checkbox is checked. Opera's implementation, then, + is faulty, since it does not make sense to present the user with a single checkbox that must always be checked, + and since the specification states that UAs must apply the required attribute onto the entire group + of checkboxes, not every single one individually. +

    + + + +

    + + + +
    +
    + required attribute set all controls in a group +

    Favorite color: + + +

    +

    Favorite food: + + +

    +
    + +
    + required attribute set on last control of a group +

    Favorite color: + + +

    +

    Favorite food: + + +

    +
    +

    +
    + + + + + diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/compile.pl b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/compile.pl new file mode 100644 index 0000000..bf946ce --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/compile.pl @@ -0,0 +1,141 @@ + + +use Win32::File qw/GetAttributes SetAttributes ARCHIVE NORMAL/; + + +while(1){ + @files = grep /^\d/, sort <*.html>; + $doupdate = 0; + foreach(@files){ + GetAttributes($_, $attrib); + if($attrib & ARCHIVE){ + $doupdate++; + } + } + GetAttributes("index.template.html", $attrib); + $doupdate++ if($attrib & ARCHIVE); + GetAttributes("testcase.template.html", $attrib); + $doupdate++ if($attrib & ARCHIVE); + + + if(!$doupdate){ + sleep 1; + next; + } + + + open S, "testcase.template.html"; + $testcaseTemplate = join "", ; + close S; + $counter = 1; + + open S, "../../webforms2.js"; + $s = join '', ; + $s =~ /Version:\s+(.+?)\s+\((.+?)\)/; + $implementationVersion = $1; + $implementationDate = $2; + close S; + + %testcases = (); + + for($i = 0; $i < @files; $i++){ + #next if not $files[$i] =~ /011/; #REMOVE + + print "$files[$i]\n"; + $testcaseNumber = sprintf("%03d", $counter); + + $testcasePage = $testcaseTemplate; + + open FILE, $files[$i]; + $_ = join '', ; + close FILE; + + m{(.+?)}s; + $testcaseTitle = $1; + $testcasePage =~ s{__testcaseTitle__}{$testcaseTitle}g; + + + m{
    (.+?)
    }s; + $testcaseDesc = $1; + $testcaseDesc =~ s{\s+}{ }g; + $testcasePage =~ s{__testcaseDesc__}{$testcaseDesc}; + + #__testcaseShortDesc__ + m{}s; + $testcaseShortDesc = $1; + $testcasePage =~ s{__testcaseShortDesc__}{$testcaseShortDesc}g; + + $testcases{$testcaseNumber} = { + title => $testcaseTitle, + shortDesc => $testcaseShortDesc + }; + + m{(.+?)}s; + $testcaseCode = $1; + $testcasePage =~ s{__testcaseCode__}{$testcaseCode}; + + m{(.+?)}s; + $testcaseHeadCode = $1; + $testcasePage =~ s{__testcaseHeadCode__}{$testcaseHeadCode}; + + $testcasePage =~ s{__testcaseNumber__}{$counter}eg; + + $testcasePage =~ s{__implementationVersion__}{$implementationVersion}g; + $testcasePage =~ s{__implementationDate__}{$implementationDate}g; + + if($i == 0){ + $testcasePage =~ s{(.+?)}{}g; + } + $testcasePage =~ s{__previousNumber__}{sprintf("%03d", $counter-1)}ge; + $testcasePage =~ s{__previousTitle__}{getPageTitle(sprintf("%03d.html", $counter-1))}ge; + if($i == @files-1){ + $testcasePage =~ s{(.+?)}{}g; + } + $testcasePage =~ s{__nextNumber__}{sprintf("%03d", $counter+1)}ge; + $testcasePage =~ s{__nextTitle__}{getPageTitle(sprintf("%03d.html", $counter+1))}ge; + + open OUT, ">../$testcaseNumber.html"; + print OUT $testcasePage; + close OUT; + SetAttributes($files[$i], NORMAL); + + $counter++; + } + + SetAttributes("index.template.html", NORMAL); + SetAttributes("testcase.template.html", NORMAL); + + + #TEST SUITE INDEX + + open S, "index.template.html"; + $indexTemplate = join "", ; + close S; + + $list = ""; + foreach(sort keys %testcases){ + $list .= "
  • " . $testcases{$_}{title} . ""; + + $list .= ": " . $testcases{$_}{shortDesc} if $testcases{$_}{shortDesc}; + + $list .= "
  • \n"; + } + + $indexTemplate =~ s{__testcaseList__}{$list}; + $indexTemplate =~ s{__implementationVersion__}{$implementationVersion}g; + $indexTemplate =~ s{__implementationDate__}{$implementationDate}g; + + open OUT, ">../index.html"; + print OUT $indexTemplate; + close OUT; + + #exit; #REMOVE +} + + +sub getPageTitle { + open FILE, shift; + $_ = join('', ); + m{(.+?)}s; + return $1; +} diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/index.template.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/index.template.html new file mode 100644 index 0000000..f0fea2a --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/index.template.html @@ -0,0 +1,24 @@ + + + + + + Web Forms 2.0 Test Suite + + +

    Web Forms 2.0 Test Suite

    +

    The following test suite is compiled in order to give examples of what the Web Forms 2.0 specification + is designed to do. Its purpose is also to test the implementations as found in Opera and also the + cross-browser Web Forms 2.0 implementation.

    + +
      + __testcaseList__ +
    +
    + Test suite powered by cross-browser Web Forms 2.0 implementation
    + Version: __implementationVersion__ (__implementationDate__) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/testcase.template.html b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/testcase.template.html new file mode 100644 index 0000000..2dd64b6 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/testsuite/~testcases/testcase.template.html @@ -0,0 +1,43 @@ + + + + + Test Case __testcaseNumber__: __testcaseTitle__ « Web Forms 2.0 Test Suite + + + + + + + + __testcaseHeadCode__ + + +
    + +

    Web Forms 2.0 Test Case __testcaseNumber__: __testcaseTitle__

    +

    + This test case demonstrates functionality of the Web Forms 2.0 specification and tests the compliance of + this cross-browser Web Forms 2.0 implementation.

    + + __testcaseDesc__ + + + +
    +
    + +__testcaseCode__ + +
    + Web Forms 2.0 implementation
    + Version: __implementationVersion__ (__implementationDate__) changelog +
    + Weston Ruter +
    + + \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/validationPointer.png b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/validationPointer.png new file mode 100644 index 0000000000000000000000000000000000000000..d293f7a837cf67d3c0284163644045e76537fea3 GIT binary patch literal 688 zcmV;h0#E&kP)&fA00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyY! z6($w%Z^HWk001I%MObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakAa8CUVIWOmV~41B zLjV8*0!c(cR5;7ElgnxvQ5?qqXD%ScB#uz4sg@?aJxB{(4|I{mKp()h4sECbH?9pObxadRp0A1Nhn@(H1DX3$du`-O#oLd)Onnt3jm;)bwIOlxlcfNB0*swL5&BvR1 zg-wm^cKc(!UO(Ezi#9PChB5FwFCL9XDMCogX0weOO==j%z;T?o@B84ouE-dBSE*Ev zZY*i7R_hFh!z9LdYDNfTS%z3FMuQ;Ga=Bb%tI%q-%3armIdHK6LLf;JD2hVEFx2w- zd}Axna=FYM#{ojfm2+fShIl+qF~*v%>np+HI$)_(n%K521wjCm(km5)A^5&8L?RJ2 zl}cHyR?FN7S}Yd1-S10b7y@H#r6^;7F^2JYEM(FdRfycOet!RE{ui`xa>D!P=YTN= z#`#+DnFt{;nM{Ny4m}gC89psC&tM%Q`j9 zmC)D6$Gp?&B8&-e&VX|cjPXUisA)R3G|o8(j0yO@FC1jjY9e#r`ts@T9WP$*3+?6Z z;oanK+qQvH3fpKL03=a_L?S`kzdG87_ir2jBz^wu>7?83PVaE-kzQYf5b!)t*uQgI zO{VWzXP-|^r0aTYG#a^s!Qj#lMgW}8>U`g5RxgbMT$sz3U#loWOi=&;8oN6?ul@kT W&B3loM5s;x0000 + * Copyright: 2007, Weston Ruter + * License: GNU General Public License, Free Software Foundation + * + * + * The comments contained in this code are largely quotations from the + * WebForms 2.0 specification: + * + * Usage: + */ + + +if(document.implementation && document.implementation.hasFeature && + !document.implementation.hasFeature('WebForms', '2.0')) +{ + //get path to source directory + var scripts = document.getElementsByTagName('head')[0].getElementsByTagName('script'), match, dirname = ''; + for(var i = 0; i < scripts.length; i++){ + if(match = scripts[i].src.match(/^(.*)webforms2-loader\.js$/)) + dirname = match[1]; + } + + //load script + if(document.write) + document.write(""); + else { + var script = document.createElement('script'); + script.setAttribute('type', 'text/javascript'); + script.setAttribute('src', dirname + 'webforms2-p.js'); + document.getElementsByTagName('head')[0].appendChild(script); + } +} diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/webforms2-msie.js b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/webforms2-msie.js new file mode 100644 index 0000000..fd4c88d --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/webforms2-msie.js @@ -0,0 +1 @@ +$wf2.onDOMContentLoaded(); \ No newline at end of file diff --git a/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/webforms2-p.js b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/webforms2-p.js new file mode 100644 index 0000000..ed28247 --- /dev/null +++ b/itf/static/js/html5Forms.js/shared/js/weston.ruter.net/webforms2/webforms2-p.js @@ -0,0 +1,56 @@ +if(!window.$wf2){var $wf2={};document.implementation&&document.implementation.hasFeature&&!document.implementation.hasFeature("WebForms","2.0")&&($wf2={version:"0.5.4",isInitialized:!1,libpath:"",globalEvent:null,hasElementExtensions:window.HTMLElement&&HTMLElement.prototype,hasGettersAndSetters:$wf2.__defineGetter__&&$wf2.__defineSetter__,hasBadImplementation:0=k.value)break}else if(c.name==n){if(k){if(++p-1a.max;a.validity.stepMismatch=!$wf2.isValidNumber(a)}else if("file"==e)a.min=b&&/^\d+$/.test(b.value)?Number(b.value):0,a.max=d&&/^\d+$/.test(d.value)?Number(d.value):1;else if(b&&(a.min=$wf2.parseISO8601(b.value,e),a.validity.rangeUnderflow=a.min&&a.wf2Valuea.max;if(!g&&!f&&o&&!a.validity.rangeUnderflow&&!a.validity.rangeOverflow){var l=$wf2.getOriginalAttrNode(a,"step");a.step=l?"any"== +l.value?"any":$wf2.numberRegExp.test(l.value)&&0a.maxLength}}else if(b&&$wf2.numberRegExp.test(b.value)&&(a.min=Number(b.value)),d&&$wf2.numberRegExp.test(d.value)&&(a.max=Number(d.value)),l&&$wf2.numberRegExp.test(l.value))a.step=Number(l.value);a.validity.valid=!$wf2.hasInvalidState(a.validity);a.validity.valid? +($wf2.css.removeClass(a,"wf2_invalid"),$wf2.css.addClass(a,"wf2_valid")):($wf2.css.removeClass(a,"wf2_valid"),$wf2.css.addClass(a,"wf2_invalid"))}},isValidNumber:function(a){a=(parseFloat(a.wf2Value)-parseFloat(a.min))/parseFloat(a.step);return a==parseInt(a)},applyValidityInterface:function(a){if($wf2.hasBadImplementation){if("submit"==a.type||"button"==a.type)a.formNoValidate=!0}else if(a.validity&&void 0!==a.validity.typeMismatch)return a;a.validationMessage="";a.validity=$wf2.createValidityState(); +a.willValidate=!0;var b=a.nodeName.toLowerCase();if("button"==b||"fieldset"==b)return a.setCustomValidity=function(){throw $wf2.DOMException(9);},a.checkValidity=function(){return!0},a;a.setCustomValidity||(a.setCustomValidity=$wf2.controlSetCustomValidity);a.checkValidity=$wf2.controlCheckValidity;if(/(hidden|button|reset|add|remove|move-up|move-down)/.test(a.getAttribute("type")?a.getAttribute("type").toLowerCase():a.type)||!a.name||a.disabled)a.willValidate=!1;else if(window.RepetitionElement)for(b= +a;b=b.parentNode;)if(b.repetitionType==RepetitionElement.REPETITION_TEMPLATE){a.willValidate=!1;break}b=function(a){return $wf2.updateValidityState(a.currentTarget||a.srcElement)};document.addEventListener?(a.addEventListener("change",b,!1),a.addEventListener("blur",b,!1),a.addEventListener("keyup",b,!1)):window.attachEvent&&(a.attachEvent("onchange",b),a.attachEvent("onblur",b),a.attachEvent("onkeyup",b));return a},onsubmitValidityHandler:function(a){for(var b=a.currentTarget||a.srcElement,d=0;d< +$wf2.callBeforeValidation.length;d++)$wf2.callBeforeValidation[d](a);b.checkValidity()?b=a.returnValue=!0:(a.preventDefault&&a.preventDefault(),b=a.returnValue=!1);for(d=0;d<$wf2.callAfterValidation.length;d++)$wf2.callAfterValidation[d](a,b);return b},controlSetCustomValidity:function(a){a?(this.validationMessage=""+a,this.validity.customError=!0):(this.validationMessage="",this.validity.customError=!1);this.validity.valid=!$wf2.hasInvalidState(this.validity)},hasInvalidState:function(a){return a.typeMismatch|| +a.rangeUnderflow||a.rangeOverflow||a.stepMismatch||a.tooLong||a.patternMismatch||a.valueMissing||a.customError},createValidityState:function(){return{typeMismatch:!1,rangeUnderflow:!1,rangeOverflow:!1,stepMismatch:!1,tooLong:!1,patternMismatch:!1,valueMissing:!1,customError:!1,valid:!0}},invalidIndicators:[],indicatorTimeoutId:null,indicatorIntervalId:null,stepUnits:{datetime:"second","datetime-local":"second",time:"second",date:"day",week:"week",month:"month"},invalidMessages:{valueMissing:"Please fill out this field.", +typeMismatch:"Please enter a valid %s.",rangeUnderflow:"The value must be equal to or greater than %s.",rangeOverflow:"The value must be equal to or less than %s.",stepMismatch:"The value has a step mismatch; it must be a certain number multiples of %s from %s.",tooLong:"The value is too long. The field may have a maximum of %s characters but you supplied %s. Note that each line-break counts as two characters.",patternMismatch:"Please match the requested format."},valueToWF2Type:function(a,b){switch((""+ +b).toLowerCase()){case "datetime":case "datetime-local":case "date":case "month":case "week":case "time":return $wf2.dateToISO8601(a,b);default:return a}},addInvalidIndicator:function(a){console.log("addInvalidIndicator");var b=document.createElement("div");b.className="wf2_errorMsg";var d=document.createElement("div");d.className="wf2_errorMsgContainer";b.appendChild(d);b.id=(a.id||a.name)+"_wf2_errorMsg";b.onmousedown=function(){this.parentNode.removeChild(this)};var c=a.getAttribute("type")?a.getAttribute("type").toLowerCase(): +a.type,e=document.createElement("ol");a.validity.customError?e.appendChild($wf2.createLI(a.validationMessage)):(a.validity.valueMissing&&e.appendChild($wf2.createLI($wf2.invalidMessages.valueMissing)),a.validity.typeMismatch&&e.appendChild($wf2.createLI($wf2.invalidMessages.typeMismatch.replace(/%s/,c))),a.validity.rangeUnderflow&&e.appendChild($wf2.createLI($wf2.invalidMessages.rangeUnderflow.replace(/%s/,$wf2.valueToWF2Type(a.min,c)))),a.validity.rangeOverflow&&e.appendChild($wf2.createLI($wf2.invalidMessages.rangeOverflow.replace(/%s/, +$wf2.valueToWF2Type(a.max,c)))),a.validity.stepMismatch&&e.appendChild($wf2.createLI($wf2.invalidMessages.stepMismatch.replace(/%s/,a.step+($wf2.stepUnits[c]?" "+$wf2.stepUnits[c]+"(s)":"")).replace(/%s/,$wf2.valueToWF2Type(a.wf2StepDatum,c)))),a.validity.tooLong&&e.appendChild($wf2.createLI($wf2.invalidMessages.tooLong.replace(/%s/,a.maxLength).replace(/%s/,a.wf2ValueLength?a.wf2ValueLength:a.value.length))),a.validity.patternMismatch&&e.appendChild($wf2.createLI($wf2.invalidMessages.patternMismatch.replace(/%s/, +a.title?a.title:' "'+a.getAttribute("pattern")+'"'))));1==e.childNodes.length&&(e.className="single");d.appendChild(e);d=document.body?document.body:document.documentElement;$wf2.invalidIndicators.length?d.insertBefore(b,$wf2.invalidIndicators[$wf2.invalidIndicators.length-1].errorMsg):d.insertBefore(b,null);for(d=a;d&&(1!=d.nodeType||"none"==d.style.display||"hidden"==d.style.visibility||!d.offsetParent);)d=d.parentNode;c=left=0;if((e=d)&&e.offsetParent){left=e.offsetLeft;for(c=e.offsetTop;e=e.offsetParent;)left+= +e.offsetLeft,c+=e.offsetTop;c+=d.offsetHeight}b.style.top=c+"px";b.style.left=left+"px";$wf2.invalidIndicators.push({target:a,errorMsg:b});$wf2.css.addClass(a,"wf2_invalid");null==$wf2.indicatorIntervalId&&($wf2.indicatorIntervalId=setInterval(function(){for(var a,b=0;a=$wf2.invalidIndicators[b];b++)$wf2.css.isMemberOfClass(a.target,"wf2_invalid")?$wf2.css.removeClass(a.target,"wf2_invalid"):$wf2.css.addClass(a.target,"wf2_invalid")},500))},clearInvalidIndicators:function(){clearTimeout($wf2.indicatorTimeoutId); +$wf2.indicatorTimeoutId=null;clearInterval($wf2.indicatorIntervalId);$wf2.indicatorIntervalId=null;for(var a;a=$wf2.invalidIndicators[0];)a.errorMsg&&a.errorMsg.parentNode&&a.errorMsg.parentNode.removeChild(a.errorMsg),$wf2.invalidIndicators.shift()},cloneNode_customAttrs:{type:1,template:1,repeat:1,"repeat-template":1,"repeat-min":1,"repeat-max":1,"repeat-start":1,value:1,"class":1,required:1,pattern:1,form:1,autocomplete:1,autofocus:1,inputmode:1,max:1,min:1,step:1,onmoved:1,onadded:1,onremoved:1, +onadd:1,onremove:1,onmove:1},cloneNode_skippedAttrs:{name:1,"class":1,"for":1,style:1,checked:1,addRepetitionBlock:1,addRepetitionBlockByIndex:1,moveRepetitionBlock:1,removeRepetitionBlock:1,repetitionBlocks:1,setCustomValidity:1,checkValidity:1,validity:1,validationMessage:1,willValidate:1,wf2StepDatum:1,wf2Value:1,wf2Initialized:1,wf2ValueLength:1},cloneNode_rtEventHandlerAttrs:{onmoved:1,onadded:1,onremoved:1,onadd:1,onremove:1,onmove:1},cloneNode:function(a,b,d){d||(d=0);var c,e,f;switch(a.nodeType){case 1:var g= +"template"==a.getAttribute("repeat");g&&d++;c=[];a.name&&(c.name=b?b(a.name):a.name);"radio"==a.type&&(c.type=a.type);a.checked&&(c.checked="checked");c=$wf2.createElement(a.nodeName,c);for(e=0;f=a.attributes[e];e++)if((f.specified||$wf2.cloneNode_customAttrs[f.name])&&!$wf2.cloneNode_skippedAttrs[f.name]&&(!g||1d&&0===f.name.indexOf("on")&&"function"==typeof a[f.name]){var m=b(a[f.name].toString().match(/{((?:.|\n)+)}/)[1]),m=b(m);c[f.name]=new Function("event", +m)}else m=a.getAttribute(f.name),m=b?b(m):m,c.setAttribute(f.name,m);if(a.className)if(g=b?b(a.className):a.className,c.getAttributeNode("class"))for(e=0;e');if("div"!=a.tagName.toLowerCase()|| +"foo"!=a.name)throw"create element error";return function(a,b){var e="<"+a,f;for(f in b)e+=" "+f+'="'+b[f]+'"';e+=">";"input"!=a.toLowerCase()&&(e+="");return document.createElement(e)}}catch(b){return function(a,b){var e=document.createElement(a),f;for(f in b)e.setAttribute(f,b[f]);return e}}}(),sortNodes:function(){var a=document.documentElement.firstChild;if(a.sourceIndex)return function(a,d){return a.sourceIndex-d.sourceIndex};if(a.compareDocumentPosition)return function(a,d){return 3- +(a.compareDocumentPosition(d)&6)}}(),createLI:function(a){var b=document.createElement("li");b.appendChild(document.createTextNode(a));return b},ISO8601RegExp:/^(?:(\d\d\d\d)-(W(0[1-9]|[1-4]\d|5[0-2])|(0\d|1[0-2])(-(0\d|[1-2]\d|3[0-1])(T(0\d|1\d|2[0-4]):([0-5]\d)(:([0-5]\d)(\.(\d+))?)?(Z)?)?)?)|(0\d|1\d|2[0-4]):([0-5]\d)(:([0-5]\d)(\.(\d+))?)?)$/,parseISO8601:function(a,b){var d=$wf2.validateDateTimeType(a,b);if(!d)return null;var c=new Date(0),e=8;if(d[15]){if(b&&"time"!=b)return null;e=15}else{c.setUTCFullYear(d[1]); +if(d[3]){if(b&&"week"!=b)return null;c.setUTCDate(c.getUTCDate()+(8-c.getUTCDay())%7+7*(d[3]-1));return c}c.setUTCMonth(d[4]-1);d[6]&&c.setUTCDate(d[6])}d[e+0]&&c.setUTCHours(d[e+0]);d[e+1]&&c.setUTCMinutes(d[e+1]);d[e+2]&&c.setUTCSeconds(d[e+3]);d[e+4]&&c.setUTCMilliseconds(Math.round(1E3*Number(d[e+4])));d[4]&&d[e+0]&&!d[e+6]&&c.setUTCMinutes(c.getUTCMinutes()+c.getTimezoneOffset());return c},validateDateTimeType:function(a,b){var d=!1,c=$wf2.ISO8601RegExp.exec(a);if(!c||!b)return c;b=b.toLowerCase(); +if("week"==b)d=0===c[2].toString().indexOf("W");else if("time"==b)d=!!c[15];else if("month"==b)d=!c[5];else if(c[6])if((new Date(c[1],c[4]-1,c[6])).getMonth()!=c[4]-1)d=!1;else switch(b){case "date":d=c[4]&&!c[7];break;case "datetime":d=!!c[14];break;case "datetime-local":d=c[7]&&!c[14]}return d?c:null},zeroPad:function(a,b){b||(b=2);for(var d=a.toString();d.length<\/script>");document.write(" + * + * Changelog: + * version 0.5.4 - initial release by Weston Ruter + * version 0.6 - refactored for use with HTML5Widgets by Zoltan Hawryluk (July 27th, 2010) + * version 0.6.1 - updated to deal with WebKit's half-implemented WebForms 2 Implementation (Sept 10, 2010) + * version 0.7 - abug fixes with nested repetition models by Zoltan Hawryluk. + * version 0.7.1 - updated to dual MIT/GPL 2.0 license. + * version 1.0 - Updated to mimic CSS validation pseudo-classes, support for newer browsers + * native support (IE10, Firefox 4, Webkit, Opera 11.11). This version does rely on + * the WebForms.js framework. + */ + +if(!window.$wf2){ +var $wf2 = {}; + +if(document.implementation && document.implementation.hasFeature && + !document.implementation.hasFeature('WebForms', '2.0')){ + +$wf2 = { + version : '0.5.4', + isInitialized : false, + libpath : '', + globalEvent: null, + + hasElementExtensions : (window.HTMLElement && HTMLElement.prototype), + hasGettersAndSetters : ($wf2.__defineGetter__ && $wf2.__defineSetter__), + + hasBadImplementation: navigator.userAgent.indexOf('WebKit') > 0, + + // WebKit less than 534 doesn't show validation UI - we need to check for this (from http://stackoverflow.com/questions/6030522/html5-form-validation-modernizr-safari) + hasNativeBubbles: navigator.userAgent.indexOf('WebKit') < 0 || parseInt(navigator.userAgent.match(/AppleWebKit\/([^ ]*)/)[1].split('.')[0]) > 534, + + callBeforeValidation : new Array(), + callAfterValidation : new Array(), + callAfterDOMContentLoaded: new Array(), + + + onDOMContentLoaded : function(){ + + if($wf2.isInitialized) + return; + + $wf2.isInitialized = true; //Safari needs this here for some reason + + var i,j,k,node; + + //set global event for fireEvent method + if (document.createEventObject){ + // dispatch for IE + $wf2.globalEvent = document.createEventObject(); + } else if (document.createEvent) { + $wf2.globalEvent = document.createEvent("HTMLEvents"); + } + + //Include stylesheet + var style = document.createElement('link'); + style.setAttribute('type', 'text/css'); + style.setAttribute('rel', 'stylesheet'); + style.setAttribute('href', $wf2.libpath + 'webforms2.css'); + var parent = document.getElementsByTagName('head')[0]; + if(!parent) + parent = document.getElementsByTagName('*')[0]; + parent.insertBefore(style, parent.firstChild); + + //The zero point for datetime controls is 1970-01-01T00:00:00.0Z, for datetime-local is + // 1970-01-01T00:00:00.0, for date controls is 1970-01-01, for month controls is 1970-01, for week + // controls is 1970-W01 (the week starting 1969-12-29 and containing 1970-01-01), and for time controls + // is 00:00. + $wf2.zeroPoint = {}; + $wf2.zeroPoint.datetime = $wf2.parseISO8601("1970-01-01T00:00:00.0Z"); + $wf2.zeroPoint['datetime-local'] = $wf2.parseISO8601("1970-01-01T00:00:00.0"); + $wf2.zeroPoint.date = $wf2.zeroPoint.datetime; //parseISO8601("1970-01-01"); //.zeroPointDatetime; //1970-01-01 (UTC) + $wf2.zeroPoint.month = $wf2.zeroPoint.datetime; //parseISO8601("1970-01"); //1970-01 (UTC) + $wf2.zeroPoint.week = $wf2.parseISO8601("1970-W01"); //(UTC) + $wf2.zeroPoint.time = $wf2.zeroPoint.datetime; //parseISO8601("00:00"); //00:00 (UTC) + + //## Fetching data from external resources ################################## + $wf2.xhr = null; + if(window.XMLHttpRequest) + $wf2.xhr = new XMLHttpRequest(); + else if(window.ActiveXObject){ + try { + $wf2.xhr = new ActiveXObject("Msxml2.XMLHTTP"); + } catch(e){ + try { + $wf2.xhr = new ActiveXObject("Microsoft.XMLHTTP"); + } catch(e){} + } + } + if($wf2.xhr){ + $wf2.prefillSelectElements(); + $wf2.prefillFormElements(); + } + + //Initialize Repetition Behaviors **************************************** + //Before load events are fired, but after the entire document has been parsed and after forms with data + // attributes are prefilled (if necessary), UAs must iterate through every node in the document, depth + // first, looking for templates so that their initial repetition blocks can be created. ... UAs should not + // specifically wait for images and style sheets to be loaded before creating initial repetition blocks + // as described above. + if (window.$wf2Rep) { + $wf2.initRepetitionBlocks(); + $wf2.initRepetitionTemplates(); + $wf2.initRepetitionButtons('add'); + $wf2.initRepetitionButtons('remove'); + $wf2.initRepetitionButtons('move-up'); + $wf2.initRepetitionButtons('move-down'); + $wf2.updateAddButtons(); + $wf2.updateMoveButtons(); + } + // Initialize Non-Repetition Behaviors **************************************** + if(document.addEventListener){ + document.addEventListener('mousedown', $wf2.clearInvalidIndicators, false); + document.addEventListener('keydown', $wf2.clearInvalidIndicators, false); + } + else if(document.attachEvent){ + document.attachEvent('onmousedown', $wf2.clearInvalidIndicators); + document.attachEvent('onkeydown', $wf2.clearInvalidIndicators); + } + + $wf2.initNonRepetitionFunctionality(); + + for (var i=0; i<$wf2.callAfterDOMContentLoaded.length; i++) { + $wf2.callAfterDOMContentLoaded[i](); + } + + + }, + + + + + + + /*############################################################################################## + # Section: Fetching data from external resources + ##############################################################################################*/ + + prefillSelectElements : function(){ + //If a select element or a datalist element being parsed has a data attribute, then as soon + // as the element and all its children have been parsed and added to the document, the + // prefilling process described here should start. + var select, selects = $wf2.getElementsByTagNames.apply(document.documentElement, ['select', 'datalist']); //$wf2.getElementsByTagNamesAndAttribute.apply(document.documentElement, [['select', 'datalist']]); //, 'data' + for(var i = 0; select = selects[i]; i++){ + //If a select element or a datalist element has a data attribute, it must be a URI or + // IRI that points to a well-formed XML file whose root element is a select element + // in the http://www.w3.org/1999/xhtml namespace. The MIME type must be an XML MIME + // type [RFC3023], preferably application/xml. It should not be application/xhtml+xml + // since the root element is not html. + //UAs must process this file if it has an XML MIME type [RFC3023], if it is a well-formed + // XML file, and if the root element is the right root element in the right namespace. + // If any of these conditions are not met, UAs must act as if the attribute was not + // specified, although they may report the error to the user. UAs are expected to + // correctly handle namespaces, so the file may use prefixes, etc. + var xmlDoc = $wf2.loadDataURI(select); + if(///\bxml\b/.test(xhr.getResponseHeader('Content-Type') && + xmlDoc && + xmlDoc.documentElement && + /:?\bselect$/i.test(xmlDoc.documentElement.nodeName) && + xmlDoc.documentElement.namespaceURI == 'http://www.w3.org/1999/xhtml' + ) + { + var root = xmlDoc.documentElement; + //1. Unless the root element of the file has a type attribute with the exact literal + // string incremental, the children of the select or datalist element in the original + // document must all be removed from the document. + if(root.getAttribute('type') != 'incremental'){ + while(select.lastChild) + select.removeChild(select.lastChild); + } + + //2. The entire contents of the select element in the referenced document are imported + // into the original document and appended as children of the select or datalist + // element. (Even if importing into a text/html document, the newly imported nodes + // will still be namespaced.) + //3. All nodes outside the select (such as style sheet processing instructions, whitespace + // text nodes, and DOCTYPEs) are ignored, as are attributes (other than type) on the + // select element. + node = root.firstChild; + while(node){ + //select.appendChild(node.cloneNode(true)); //MSIE BUG: Throws "No such interface supported" exception + select.appendChild($wf2.cloneNode(node)); + node = node.nextSibling; + } + } + } + }, + + prefillFormElements : function(){ + //-- Seeding a form with initial values ------------------------------- + //Before load events are fired, but after the entire document has been parsed and after select + // elements have been filled from external data sources (if necessary), forms with data attributes + // are prefilled. + var frm, frms = document.getElementsByTagName('form'); //$wf2.getElementsByTagNamesAndAttribute.apply(document.documentElement, [['form'], 'data']); + for(var i = 0; frm = frms[i]; i++){ + //If a form has a data attribute, it must be a URI or IRI that points to a well-formed XML file + // whose root element is a formdata element in the http://n.whatwg.org/formdata namespace. The + // MIME type must be an XML MIME type [RFC3023], preferably application/xml. + //UAs must process this file if these conditions are met. If any of these conditions are not met, + // UAs must act as if the attribute was not specified, although they may report the error to + // the user. UAs are expected to correctly handle namespaces, so the file may use prefixes, etc. + var xmlDoc = $wf2.loadDataURI(frm); + if(///\bxml\b/.test(xhr.getResponseHeader('Content-Type') && + xmlDoc && + xmlDoc.documentElement && + /:?\bformdata$/.test(xmlDoc.documentElement.nodeName) && + xmlDoc.documentElement.namespaceURI == 'http://n.whatwg.org/formdata' + ) + { + var rt; + var root = xmlDoc.documentElement; + //1. Unless the root element has a type attribute with the exact literal string incremental, + // the form must be reset to its initial values as specified in the markup. + if(root.getAttribute('type') != 'incremental') + frm.reset(); + + //The algorithm must be processed in the order given above, meaning any clear elements are + // handled before any repeat elements which are handled before the field elements, regardless + // of the order in which the elements are given. (Note that this implies that this process + // cannot be performed incrementally.) + + //clear elements in the http://n.whatwg.org/formdata namespace that are children of + // the root element, have a non-empty template attribute, have no other non-namespaced + // attributes (ignoring xmlns attributes), and have no content, must be processed...: + //The template attribute should contain the ID of an element in the document. If the + // template attribute specifies an element that is not a repetition template, then + // the clear element is ignored. + var clr, clrs = root.getElementsByTagName('clear'); //getElementsByTagNameNS('http://n.whatwg.org/formdata', 'clr') + for(j = 0; clr = clrs[j]; j++){ + if(clr.namespaceURI == 'http://n.whatwg.org/formdata' && + clr.parentNode == root && + !clr.firstChild && + (rt = document.getElementById(clr.getAttribute('template'))) && + rt.getAttribute('repeat') == 'template' + /*Examining of non-namespaced attributes skipped*/ + ) + { + //The user must make a note of the list of repetition blocks associated with that + // template that are siblings of the template, and must then go through this list, + // removing each repetition block in turn. + //Note that we cannot use rt.repetitionBlocks since the repetition behavior has + // not yet been initialized. + var attr,node,next; + node = rt.parentNode.firstChild; + while(node){ + if(node.nodeType == 1 && (attr = node.getAttributeNode('repeat')) && attr.value != 'template'){ + next = node.nextSibling; + node.parentNode.removeChild(node); + node = next; + } + else node = node.nextSibling; + } + } + } + + //repeat elements in the http://n.whatwg.org/formdata namespace that are children of + // the root element, have a non-empty template attribute and an index attribute that + // contains only one or more digits in the range 0-9 with an optional leading minus + // sign (U+002D, "-"), have no other non-namespaced attributes (ignoring xmlns + // attributes), and have no content, must be processed as follows: + //The template attribute should contain the ID of an element in the document. If the + // template attribute specifies an element that is not a repetition template, then + // the repeat element is ignored. + var index, rpt, rpts = root.getElementsByTagName('repeat'); + for(j = 0; rpt = rpts[j]; j++){ + if(rpt.namespaceURI == 'http://n.whatwg.org/formdata' && + rpt.parentNode == root && + !rpt.firstChild && + (rt = document.getElementById(rpt.getAttribute('template'))) && + rt.getAttribute('repeat') == 'template' && + /^-?\d+$/.test(index = rpt.getAttribute('index')) + /*Examining of non-namespaced attributes skipped*/ + ) + { + //If the template attribute specifies a repetition template and that template + // already has a repetition block with the index specified by the index attribute, + // then the element is ignored. + //for(j = 0; j < rt.repetitionBlocks.length; j++){ + // if(rt.repetitionBlocks[j].repetititionIndex == index){ + // hasIndex = true; + // break; + // } + //} + var hasIndex,attr,node,next; + node = rt.parentNode.firstChild; + while(node){ + if(node.nodeType == 1 && (attr = node.getAttributeNode('repeat')) && attr.value == index){ + hasIndex = true; + break; + } + node = node.nextSibling; + } + + if(!hasIndex){ + //Otherwise, the specified template's addRepetitionBlockByIndex() method is + // called, with a null first argument and the index specified by the repeat + // element's index attribute as the second. + $wf2.addRepetitionBlockByIndex.apply(rt, [null, index]); + } + } + } + + //field elements in the http://n.whatwg.org/formdata namespace that are children of + // the root element, have a non-empty name attribute, either an index attribute + // that contains only one or more digits in the range 0-9 or no index attribute at + // all, have no other non-namespaced attributes (ignoring xmlns attributes), and + // have either nothing or only text and CDATA nodes as children, must be used to + // initialize controls... + var fld, flds = root.getElementsByTagName('field'); + var formElements = $wf2.getFormElements.apply(frm); + for(j = 0; fld = flds[j]; j++){ + var indexAttr = fld.getAttributeNode('index'); + var name = fld.getAttribute('name'); + if(!name || (indexAttr && !/^\d+$/.test(indexAttr.value))) + /*Examining of non-namespaced attributes skipped*/ + /*Verification of the presence of text and CDATA nodes below*/ + continue; + //First, the form control that the field references must be identified. + var value = ''; + for(k = 0; node = fld.childNodes[k]; k++){ + if(node.nodeType == 3 /*text*/ || node.nodeType == 4 /*CDATA*/) + value += node.data; + else break; //only text and CDATA nodes allowed + } + var ctrl, count = 0; + for(k = 0; ctrl = formElements[k]; k++){ + //console.info(ctrl.name + ' == ' + name) + if(ctrl.type == 'image'){ + //For image controls, instead of using the name given by the name attribute, + // the field's name is checked against two names, the first being the value + // of the name attribute with the string .x appended to it, and the second + // being the same but with .y appended instead. If an image control's name + // is the empty string (e.g. if its name attribute is omitted) then the + // names x and y must be used instead. Thus image controls are handled as + // if they were two controls. + if(ctrl.name ? + (ctrl.name + '.x' == name || ctrl.name + '.y' == name) + : (name == 'x' || name == 'y') ){ + + if(!indexAttr || ++count-1 >= indexAttr.value) + break; + } + } + //This is done by walking the list of form controls associated with the form until + // one is found that has a name exactly equal to the name given in the field + // element's name attribute, skipping as many such matches as is specified in + // the index attribute, or, if the index attribute was omitted, skipping over + // any type="radio" and type="checkbox" controls that have the exact name given + // but have a value that is not exactly the same as the contents of the field element. + // SPECIFICATION DEFICIENCY: Note that this is not completely true. If the value of + // a field element is empty, then it should not be skipped if it associated with + // a radio button or checkbox. For example, the specification states four paragraphs + // later, "The only values that would have an effect in this example are "", which + // would uncheck the checkbox, and "green", which would check the checkbox." + else if(ctrl.name == name){ + if(indexAttr){ + if(++count-1 < indexAttr.value) + continue; + } + else if((ctrl.type == 'radio' || ctrl.type == 'checkbox') && + (value && ctrl.value != value)) + continue; + break; + } + } + + //If the identified form control is a file upload control, a push button control, or + // an image control, then the field element is now skipped. + if(ctrl.type == 'file' || ctrl.type == 'button' || ctrl.type == 'image') + continue; + + //Next, if the identified form control is not a multiple-valued control (a multiple- + // valued control is one that can generate more than one value on submission, such + // as a ), or if it is a multiple-valued control but it + // is the first time the control has been identified by a field element in this + // data file that was not ignored, then it is set to the given value (the contents + // of the field element), removing any previous values (even if these values were + // the result of processing previous field elements in the same data file). + if(!ctrl.getAttributeNode('multiple') || !ctrl.wf2Prefilled){ + //If the element cannot be given the value specified, the field element is + // ignored and the control's value is left unchanged. For example, if a + // checkbox has its value attribute set to green and the field element + // specifies that its value should be set to blue, it won't be changed from + // its current value. (The only values that would have an effect in this + // example are "", which would uncheck the checkbox, and "green", which would + // check the checkbox.) + if(ctrl.type == 'checkbox' || ctrl.type == 'radio'){ + if(!value) + ctrl.checked = false; + else if(ctrl.value == value) + ctrl.checked = true; + else break; + } + else if(ctrl.nodeName.toLowerCase() == 'select'){ + ctrl.selectedIndex = -1; + for(var opt,k = 0; opt = ctrl.options[k]; k++){ + if(opt.value ? opt.value == value : opt.text == value){ + opt.selected = true; + break; + } + } + } + //Another example would be a datetime control where the specified value is + // outside the range allowed by the min and max attributes. The format + // must match the allowed formats for that type for the value to be set. + else { + ctrl.value = value; + $wf2.updateValidityState(ctrl); + if(!ctrl.validity.valid){ + ctrl.value = ctrl.defaultValue; + $wf2.updateValidityState(ctrl); + } + } + ctrl.wf2Prefilled = true; //TRACE + } + //Otherwise, this is a subsequent value for a multiple-valued control, and the + // given value (the contents of the field element) should be added to the list of + // values that the element has selected. + //If the element is a multiple-valued control and the control already has the given + // value selected, but it can be given the value again, then that occurs. + else if(ctrl.getAttributeNode('multiple')){ + for(var opt,k = 0; opt = ctrl.options[k]; k++){ + if(!opt.selected && (opt.value ? opt.value == value : opt.text == value)){ + opt.selected = true; + break; + } + } + } + + //if(ctrl){ + // + //} + } + + //A formchange event is then fired on all the form controls of the form. + var formElements = $wf2.getFormElements.apply(frm); + for(j = 0; j < formElements.length; j++){ + //onformchange(); + //fireEvent() + } + } + } + }, + + /*############################################################################################## + # Section: Repetition Model + ##############################################################################################*/ + + //## REPETITION TEMPLATE ############################################################# + repetitionTemplates:[], + constructRepetitionTemplate : function(){ + if(this.wf2Initialized) + return; + this.wf2Initialized = true; //SAFARI needs this to be here for some reason... + + this.style.display = 'none'; //This is also specified via a stylesheet + this.repetitionType = RepetitionElement.REPETITION_TEMPLATE; + if(!this.repetitionIndex) + this.repetitionIndex = 0; + this.repetitionTemplate = null; //IMPLEMENT GETTER + if(!this.repetitionBlocks) + this.repetitionBlocks = []; //IMPLEMENT GETTER + var _attr; + this.repeatStart = /^\d+$/.test(_attr = this.getAttribute('repeat-start')) ? parseInt(_attr) : 1; + this.repeatMin = /^\d+$/.test(_attr = this.getAttribute('repeat-min')) ? parseInt(_attr) : 0; + this.repeatMax = /^\d+$/.test(_attr = this.getAttribute('repeat-max')) ? parseInt(_attr) : Number.MAX_VALUE; //Infinity; + + if(!this.addRepetitionBlock) this.addRepetitionBlock = function(refNode, index){ + return $wf2.addRepetitionBlock.apply(this, [refNode, index]); //wrapper to save memory? + }; + if(!this.addRepetitionBlockByIndex) + this.addRepetitionBlockByIndex = this.addRepetitionBlock/*ByIndex*/; //one method implements both algorithms + + //Any form controls inside a repetition template are associated with their forms' templateElements + // DOM attributes, and are not present in the forms' elements DOM attributes. + + //On the HTMLFormElement, the templateElements attribute contains the list of form controls associated + // with this form that form part of repetition templates. It is defined in more detail in the section + // on the repetition model. (Image controls are part of this array, when appropriate.) The controls + // in the elements and templateElements lists must be in document order. + var frm = this; + while(frm = frm.parentNode){ + if(frm.nodeName.toLowerCase() == 'form') + break; + } + + var _templateElements; + //IMAGE???, fieldset not included + if(frm && (_templateElements = $wf2.getElementsByTagNames.apply(this, ['button','input','select','textarea','isindex'])).length){ + //INCORRECT IMPLEMENTATION: this should append the new elements onto the frm.templateElements array and then sort them in document order? + //each time that a nesting repetition block is instantiated, the form's templateElemenents property becomes invalid + + //frm.templateElements = _templateElements; + + //Controls in the templateElements attribute cannot be successful; controls inside repetition templates can never be submitted. + // Therefore disable all elements in the template; however, due to the issue below, the original disabled state must be stored in the field's class attribute as "disabled" + // this storing of the original disabled state will enable the elements in cloned blocks to be disabled as originally coded in the template + //ISSUE: inputs retain disabled (but not defaultDisabled) attribue after returning to page from back button or reload + // see http://weblogs.mozillazine.org/gerv/archives/2006/10/firefox_reload_behaviour.html + // As a workaround... this implementation requires that authors, in addition to supplying a DISABLED attribute (for Opera), to include a class name "disabled" + for(var el, i = 0; el = _templateElements[i]; i++) + el.disabled = true; + + //IMPLEMENTATION DEFICIENCY: unable to remove frm.templateElements from frm.elements + } + + //Repetition blocks without a repeat-template attribute are associated with their first following sibling + // that is a repetition template, if there is one. + var attr,sibling = this.parentNode.firstChild; + while(sibling && sibling != this){ + if(sibling.nodeType == 1 && (attr = sibling.getAttributeNode('repeat')) && /^-?\d+$/.test(attr.value) && !sibling.getAttribute('repeat-template')){ + //if(sibling.repetitionType == RepetitionElement.REPETITION_BLOCK && !sibling.getAttribute('repeat-template')){ + //console.info(sibling) + sibling.repetitionTemplate = this; + sibling.setAttribute('repeat-template', this.id); + this.repetitionBlocks.push(sibling); + } + sibling = sibling.nextSibling; + } + //while(sibling = sibling.previousSibling){ + // if(sibling.repetitionType == RepetitionElement.REPETITION_BLOCK && !sibling.getAttribute('repeat-template')){ + // sibling.repetitionTemplate = this; + // sibling.setAttribute('repeat-template', this.id); + // this.repetitionBlocks.unshift(sibling); + // } + //} + + //the UA must invoke the template's replication behaviour as many times as the repeat-start attribute + // on the same element specifies (just once, if the attribute is missing or has an invalid value). + // Then, while the number of repetition blocks associated with the repetition template is less than + // the template's repeat-min attribute, the template's replication behaviour must be further invoked. + // (Invoking the template's replication behaviour means calling its addRepetitionBlock() method). + //for(var i = 0; i < Math.max(this.repeatStart, this.repeatMin); i++) + for(var i = 0; (i < this.repeatStart || this.repetitionBlocks.length < this.repeatMin); i++) + if (!this.addRepetitionBlock()) { + break; + } + + $wf2.repetitionTemplates.push(this); + this.wf2Initialized = true; + }, + + initRepetitionTemplates : function(parentNode){ + //UAs must iterate through every node in the document, depth first, looking for templates so that their + // initial repetition blocks can be created. + //var repetitionTemplates = cssQuery("*[repeat=template]", parentNode); + var repetitionTemplates = $wf2.getElementsByTagNamesAndAttribute.apply((parentNode || document.documentElement), [['*'], 'repeat', 'template']); + for(var i = 0, rt; i < repetitionTemplates.length; i++) + $wf2.constructRepetitionTemplate.apply(repetitionTemplates[i]); + }, + + + //## REPETITION BLOCK ############################################################# + constructRepetitionBlock : function(){ + if(this.wf2Initialized) + return; + + this.style.display = ''; //This should preferrably be specified via a stylesheet + this.repetitionType = RepetitionElement.REPETITION_BLOCK; + var _attr; + this.repetitionIndex = /^\d+$/.test(_attr = this.getAttribute('repeat')) ? parseInt(_attr) : 0; + this.repetitionBlocks = null; + + //find this block's repetition template + this.repetitionTemplate = null; //IMPLEMENT GETTER + var node; + + if((node = document.getElementById(this.getAttribute('repeat-template'))) && + node.getAttribute('repeat') == 'template') + { + this.repetitionTemplate = node; + } + else { + node = this; + while(node = node.nextSibling){ + if(node.nodeType == 1 && node.getAttribute('repeat') == 'template'){ + this.repetitionTemplate = node; + break; + } + } + } + + if(!this.removeRepetitionBlock) this.removeRepetitionBlock = function(){ + return $wf2.removeRepetitionBlock.apply(this); //wrapper to save memory + }; + if(!this.moveRepetitionBlock) this.moveRepetitionBlock = function(distance){ + return $wf2.moveRepetitionBlock.apply(this, [distance]); //wrapper to save memory + }; + this.wf2Initialized = true; + }, + + initRepetitionBlocks : function(parentNode){ + //var repetitionBlocks = cssQuery('*[repeat]:not([repeat="template"])', parentNode); //:not([repeat="template"]) + var repetitionBlocks = $wf2.getElementsByTagNamesAndAttribute.apply((parentNode || document.documentElement), [['*'], 'repeat', 'template', true]); + for(var i = 0; i < repetitionBlocks.length; i++) + $wf2.constructRepetitionBlock.apply(repetitionBlocks[i]); + }, + + + //## Repetition buttons ############################################################# + repetitionButtonDefaultLabels : { + 'add' : 'Add', + 'remove' : 'Remove', + 'move-up' : 'Move-up', + 'move-down' : 'Move-down' + }, + + constructRepetitionButton : function(btnType){ + if(this.wf2Initialized) + return; + this.htmlTemplate = $wf2.getHtmlTemplate(this); //IMPLEMENT GETTER + if(!this.firstChild) + this.appendChild(document.createTextNode($wf2.repetitionButtonDefaultLabels[btnType])); + + //user agents must automatically disable remove, move-up, and move-down buttons when they are not in a repetition + // block. [NOT IMPLEMENTED:] This automatic disabling does not affect the DOM disabled attribute. It is an intrinsic property of these buttons. + if(btnType != 'add') + this.disabled = !$wf2.getRepetitionBlock(this); + //user agents must automatically disable add buttons (irrespective of the value of the disabled + // DOM attribute [NOT IMPLEMENTED]) when the buttons are not in a repetition block that has an + // associated template and their template attribute is either not specified or does not have + // an ID that points to a repetition template... + else { + var rb; + this.disabled = !(((rb = $wf2.getRepetitionBlock(this)) && rb.repetitionTemplate) + || + this.htmlTemplate + ); + } + + if(this.addEventListener) + this.addEventListener('click', $wf2.clickRepetitionButton, false); + else if(this.attachEvent) + this.attachEvent('onclick', $wf2.clickRepetitionButton); + else this.onclick = $wf2.clickRepetitionButton; + + this.wf2Initialized = true; + }, + + initRepetitionButtons : function(btnType, parent){ + var i; + if(!parent) + parent = document.documentElement; + + //change INPUTs to BUTTONs + var inpts = $wf2.getElementsByTagNamesAndAttribute.apply(parent, [['input'], 'type', btnType]); + for(i = 0; i < inpts.length; i++){ + var btn = document.createElement('button'); + for(var j = 0, attr; attr = inpts[i].attributes[j]; j++) + btn.setAttribute(attr.nodeName, inpts[i].getAttribute(attr.nodeName)); //MSIE returns correct value with getAttribute but not nodeValue + inpts[i].parentNode.replaceChild(btn, inpts[i]); + btn = null; + } + + //construct all buttons + var btns = $wf2.getElementsByTagNamesAndAttribute.apply(parent, [['button'], 'type', btnType]); + for(var i = 0; i < btns.length; i++) + $wf2.constructRepetitionButton.apply(btns[i], [btnType]); + }, + + clickRepetitionButton : function(e){ + if(e && e.preventDefault) + e.preventDefault(); //Keep default submission behavior from executing + + //If the event is canceled (btn.returnValue === false, set within onclick handler), then the default action will not occur. + var btn; + if(e && e.target) + btn = e.target; + else if(window.event) + btn = event.srcElement; + else if(this.nodeName.toLowerCase() == 'button') + btn = this; + var btnType = String(btn.getAttribute('type')).toLowerCase(); + + //Prevent the onclick handler from firing afterwards (would fire after movement action) + // ISSUE: This only works in Firefox + if(btn.onclick){ + btn._onclick = btn.onclick; + btn.removeAttribute('onclick'); + btn.onclick = null; + } + + //Terminate if an onclick handler was called beforehand and returned a false value + // passed via the button's returnValue property. Handlers defined by HTML attributes + // are called before those assigned by onclick DOM properties. + if(btn.returnValue !== undefined && !btn.returnValue){ + btn.returnValue = undefined; + return false; + } + + //Ensure that a user-supplied onclick handler is fired before the repetition behavior is executed + // and terminate if this onclick handler returns a false value + // Note that handlers defined in onclick HTML attributes are executed before clickRepetitionButton + if(btn._onclick && btn.returnValue === undefined){ // && !btn.getAttributeNode("onclick") //&& btn.hasAttribute && !btn.hasAttribute("onclick") //NOTE: MSIE fires this afterwards??? btn.returnValue = btn._onclick(e); + btn.returnValue = btn._onclick(e); + if(btn.returnValue !== undefined && !btn.returnValue){ + btn.returnValue = undefined; + return false; + } + } + btn.returnValue = undefined; + + //ISSUE: How do we ensure that the MSIE and DOM Level 2 Event handlers are executed beforehand? + + var block; + if(btnType != 'add'){ + block = $wf2.getRepetitionBlock(btn); + + //user agents must automatically disable remove, move-up, and move-down buttons when they are not in a repetition + // block. [NOT IMPLEMENTED:] This automatic disabling does not affect the DOM disabled attribute. It is an intrinsic property of these buttons. + this.disabled = !block; + + if(block){ + if(btnType.indexOf('move') === 0){ + block._clickedMoveBtn = btn; + block.moveRepetitionBlock(btnType == 'move-up' ? -1 : 1); + } + else if(btnType == 'remove'){ + block.removeRepetitionBlock(); + } + } + } + else { + var rt; + //If an add button with a template attribute is activated, and its template attribute gives the ID + // of an element in the document that is a repetition template as defined above, then that + // template's replication behaviour is invoked. (Specifically, in scripting-aware environments, + // the template's addRepetitionBlock() method is called with a null argument.) In the case of + // duplicate IDs, the behaviour should be the same as with getElementById(). + if(btn.htmlTemplate) + rt = btn.htmlTemplate; + else { + //If an add button without a template attribute is activated, and it has an ancestor that is a + // repetition block that is not an orphan repetition block, then the repetition template associated + // with that repetition block has its template replication behaviour invoked with the respective + // repetition block as its argument. (Specifically, in scripting-aware environments, the template's + // addRepetitionBlock() method is called with a reference to the DOM Element node that represents + // the repetition block.) + block = $wf2.getRepetitionBlock(btn); + if(block && block.repetitionTemplate) + rt = block.repetitionTemplate; + } + if(rt) + rt.addRepetitionBlock(); + else + btn.disabled = true; //NOTE: THIS IS NOT A VALID IMPLEMENTATION + } + return false; + }, + + //## AddRepetitionBlock algorithm ############################################################# + + //Element addRepetitionBlock(in Node refNode); + addRepetitionBlock : function(refNode, index){ //addRepetitionBlockByIndex functionalty enabled if @index defined + //if(refNode && !refNode.nodeType) + // throw Error("Exception: WRONG_ARGUMENTS_ERR"); + + //if(this.repetitionType == RepetitionElement.REPETITION_TEMPLATE) + if(this.getAttribute('repeat') != 'template') + throw $wf2.DOMException(9); //NOT_SUPPORTED_ERR + + //if addRepetitionBlock called before repetition constructors called (by pre-filling forms) + if(!this.repetitionBlocks) + this.repetitionBlocks = []; + if(!this.repetitionIndex) + this.repetitionIndex = 0; + if(!this.repeatMin) + this.repeatMin = 0; + if(!this.repeatMax) + this.repeatMax = Number.MAX_VALUE; + if(!this.repeatStart) + this.repeatStart = 1; + + //1. If the template has no parent node or its parent node is not an element, then the method must abort + // the steps and do nothing. + if(this.parentNode == null) + return null; + + //[furthermore, if this template is the child of another template (not the child of an instance, a block) return false] + var node = this; + while(node = node.parentNode){ + //if(node.repetitionType == RepetitionElement.REPETITION_TEMPLATE) + if(node.nodeType == 1 && node.getAttribute('repeat') == 'template') + return false; + } + + //2. The template examines its preceding siblings, up to the start of the parent element. For each sibling + // that is a repetition block whose associated template is this template, if the repetition block's index + // is greater than or equal to the template's index, then the template's index is increased to the repetition + // block's index plus one. The total number of repetition blocks associated with this template that were + // found is used in the next step. + //QUESTION: Why not just use this.repetitionBlocks.length???????????? + var sibling = this.previousSibling; + var currentBlockCount = 0; + while(sibling != null){ + if(sibling.nodeType == 1){ + var repeatAttr,repeatTemplateAttr; + repeat = parseInt(sibling.getAttribute('repeat')); + repeatTemplateAttr = sibling.getAttributeNode('repeat-template'); + + //if(sibling.repetitionType == RepetitionElement.REPETITION_BLOCK && sibling.repetitionTemplate == this) + if(!isNaN(repeat) && (!repeatTemplateAttr || repeatTemplateAttr.value == this.id)) + { + //Old Note: sibling.getAttribute('repeat') is used instead of sibling.repetitionIndex because appearantly + // the sibling is not yet bound to the document and so the getters are not available + //this.repetitionIndex = Math.max(this.repetitionIndex, parseInt(sibling.getAttribute('repeat'))+1); + this.repetitionIndex = Math.max(this.repetitionIndex, repeat+1); + currentBlockCount++; + } + } + sibling = sibling.previousSibling; + } + + //3. If the repetition template has a repeat-max attribute and that attribute's value is less than or equal + // to the number of repetition blocks associated with this template that were found in the previous step, + // the UA must stop at this step, returning a null value. + if(this.repeatMax <= currentBlockCount) + return null; + + //4. If this algorithm was invoked via the addRepetitionBlockByIndex() method, and the value of the method's + // index argument is greater than the template's index, then the template's index is set to the value of the + // method's index argument. + if(index !== undefined && index > this.repetitionIndex) + this.repetitionIndex = index; + + //(the following steps are out of order to facilitate a custom cloneNode to cope for MSIE and Gecko issues) + + //9. If the new repetition block has an ID attribute (that is, an attribute specifying an ID, regardless + // of the attribute's namespace or name), then that attribute's value is used as the template name in + // the following steps. Otherwise, the template has no name. (If there is more than one ID attribute, + // the "first" one in terms of node order is used. [DOM3CORE]) + // [Since this step was moved here, it uses 'this' and not 'block', which hasn't been created yet] + //var IDAttr = block.getAttributeNode('id') ? block.getAttributeNode('id') : block.getAttributeNode('name'); //DETECT ID TYPE For others? + var IDAttrName = this.getAttribute('id') ? 'id' : this.getAttribute('name') ? 'name' : ''; //NOTE: hasAttribute not implemented in MSIE + var IDAttrValue = this.getAttribute(IDAttrName); + + //5. A clone of the template is made. The resulting element is the new repetition block element. + // [Note that the DOM cloneNode method is not invoked in this implementation due to MSIE + // errors, such as not being able to modify the name attribute of an existing node and strange Gecko behavior + // regarding the inconsistant correspondence of an input node's value attribute and value property. + // Instead of invoking the native cloneNode method, each element is copied manually when it is iterated over.] + // [Note: step 11 of the the specification's algorithm has been merged into step 5. See note at step 11 below] + //(11). If the template has a name and it is not being ignored (see the previous two steps), then, for every + // attribute on the new element, and for every attribute in every descendant of the new element: if the + // attribute starts with a zero-width non-breaking space character (U+FEFF) then that character is + // removed from the attribute; otherwise, any occurrences of a string consisting of an opening square + // bracket (U+005B, "[") or a modifier letter half triangular colon (U+02D1), the template's name, + // and a closing square bracket (U+005D, "]") or a middle dot (U+00B7), are replaced by the new + // repetition block's index. This is performed regardless of the types, names, or namespaces of attributes, + // and is done to all descendants, even those inside nested forms, nested repetition templates, and so forth. + var block; + + //(10). If the template has a name (see the previous step), and that name contains either an opening square + // bracket (U+005B, "[") a modifier letter half triangular colon (U+02D1), a closing square bracket + // (U+005D, "]") or a middle dot (U+00B7), then the template's name is ignored for the purposes of + // [this] step. + var replaceValue = this.repetitionIndex; + var reTemplateName, processAttr; + if(IDAttrValue && !/\u005B|\u02D1|\u005D|\u00B7/.test(IDAttrValue)){ //VALID LOGIC? + reTemplateName = new RegExp("(\\[|\u02D1)" + IDAttrValue + "(\\]|\u00B7)", 'g'); //new RegExp('(\\u005B|\\u02D1)' + IDAttrValue + '(\\u005D|\\u00B7)', 'g'); + processAttr = function(attrVal){ //Function that processes an attribute value as defined in step 11 + if(!attrVal) + return attrVal; + attrVal = attrVal.toString(); + if(attrVal.indexOf("\uFEFF") === 0) + return attrVal.replace(/^\uFEFF/, ''); + return attrVal.replace(reTemplateName, replaceValue); + }; + } + block = $wf2.cloneNode(this, processAttr); + block.wf2Initialized = false; + reTemplateName = null; + + //6. If this algorithm was invoked via the addRepetitionBlockByIndex() method, the new repetition block + // element's index is set to the method's index argument. Otherwise, the new repetition block element's + // index is set to the template's index. [Note: if called by addRepetitionBlockByIndex() then the + // template's repetitionIndex has already been set to the index argument. Redundant algorithm step.] + //block.repetitionIndex = this.repetitionIndex; //this is set in the constructor for the repetitionBlock + //7. If the new repetition block element is in the http://www.w3.org/1999/xhtml namespace, then the + // repeat attribute in no namespace on the cloned element has its value changed to the new block's + // index. Otherwise, the repeat attribute in the http://www.w3.org/1999/xhtml namespace has its value + // changed to the new block's index. + //if(block.namespaceURI == 'http://www.w3.org/1999/xhtml') + block.setAttribute('repeat', this.repetitionIndex); //when inserted into DOM, constructor sets block.repetitionIndex + //else + // block.setAttributeNS('http://www.w3.org/1999/xhtml', 'repeat', this.repetitionIndex); + + //8. If the new repetition block element is in the http://www.w3.org/1999/xhtml namespace, then any + // repeat-min, repeat-max, or repeat-start attributes in no namespace are removed from the element. + // Otherwise, any repeat-min, repeat-max, or repeat-start attributes in the http://www.w3.org/1999/xhtml + // namespace are removed instead. + + //if(block.namespaceURI == 'http://www.w3.org/1999/xhtml'){ + block.removeAttribute('repeat-min'); + block.removeAttribute('repeat-max'); + block.removeAttribute('repeat-start'); + //} + //else { + // block.removeAttributeNS('http://www.w3.org/1999/xhtml', 'repeat-min'); + // block.removeAttributeNS('http://www.w3.org/1999/xhtml', 'repeat-max'); + // block.removeAttributeNS('http://www.w3.org/1999/xhtml', 'repeat-start'); + //} + + //(steps 9 and 10 moved to before step 5 (operates on this repetition template, and not on cloned block)) + + + //11. (Note: the algorithm below which most closely follows the algorithm as described in the specification, + // this has been merged into the cloning of the template in step 5. This has been done because of MSIE + // errors, such as not being able to modify the name attribute of an existing node and strange Gecko behavior + // regarding the inconsistant correspondence of an input node's value attribute and value property.) + //if(IDAttrValue && !ignoreName){ + // var reTemplateName = new RegExp('(?:\\u005B|\\u02D1)' + IDAttrValue + '(?:\\u005D|\\u00B7)', 'g'); + // function processAttrs(node){ + // var i,attr; + // for(i = 0; node.attributes && i < node.attributes.length; i++){ + // if(!(attr = node.attributes[i]).nodeValue) + // continue; + // + // if(String(attr.nodeValue).indexOf("\uFEFF") === 0) + // attr.nodeValue = attr.nodeValue.replace(/^\uFEFF/, ''); + // + // else if(reTemplateName.test(attr.nodeValue)) + // attr.nodeValue = attr.nodeValue.replace(reTemplateName, block.getAttribute('repeat')); + // } + // for(i = 0; i < node.childNodes.length; i++) + // processAttrs(node.childNodes[i]); + // } + // processAttrs(block); + //} + + + //12. If the template has a name (see the earlier steps): If the new repetition block element is in the + // http://www.w3.org/1999/xhtml namespace, then the repeat-template attribute in no namespace on the + // cloned element has its value set to the template's name. Otherwise, the repeat-template attribute + // in the http://www.w3.org/1999/xhtml namespace has its value set to the template's name. (This + // happens even if the name was ignored for the purposes of the previous step.) + if(IDAttrName){ + //if(block.namespaceURI == "http://www.w3.org/1999/xhtml") + block.setAttribute('repeat-template', IDAttrValue); //block.setAttributeNS(null, 'repeat-template', IDAttr.nodeValue); + //else + // block.setAttributeNS('http://www.w3.org/1999/xhtml', 'repeat-template', IDAttr.nodeValue); + + + //13. The attribute from which the template's name was derived, if any, and even if it was ignored, is + // removed from the new repetition block element. (See the previous four steps.) + block.removeAttribute(IDAttrName); + } + + //14. If the first argument to the method was null, then the template once again crawls through its + // previous siblings, this time stopping at the first node (possibly the template itself) whose + // previous sibling is a repetition block (regardless of what that block's template is) or the first + // node that has no previous sibling, whichever comes first. The new element is the inserted into the + // parent of the template, immediately before that node. Mutation events are fired if appropriate. + if(!refNode){ + refNode = this; + while(refNode.previousSibling && refNode.previousSibling.repetitionType != RepetitionElement.REPETITION_BLOCK) + refNode = refNode.previousSibling; + this.parentNode.insertBefore(block, refNode); + this.repetitionBlocks.push(block); + } + //15. Otherwise, the new element is inserted into the parent of the node that was passed to the method + // as the first argument, immediately after that node (before the node's following sibling, if any). + // Mutation events are fired if appropriate. + else { + refNode.parentNode.insertBefore(block, refNode.nextSibling); + this.repetitionBlocks.push(block); + if($wf2.sortNodes) + this.repetitionBlocks.sort($wf2.sortNodes); + } + + //16. The template's index is increased by one. + this.repetitionIndex++; + + //[apply constructors to the new repetition block, and to the new remove buttons, add buttons, etc] + $wf2.constructRepetitionBlock.apply(block); + $wf2.initRepetitionTemplates(block); + + $wf2.initRepetitionButtons('add', block); + $wf2.initRepetitionButtons('remove', block); + $wf2.initRepetitionButtons('move-up', block); + $wf2.initRepetitionButtons('move-down', block); + + //In addition, user agents must automatically disable add buttons (irrespective of the value of the + // disabled DOM attribute) when the buttons are not in a repetition block that has an associated + // template and their template attribute is either not specified or does not have an ID that points + // to a repetition template, and, when the repetition template's repeat-max attribute is less than + // or equal to the number of repetition blocks that are associated with that template and that have + // the same parent. This automatic disabling does not affect the DOM disabled attribute. It is an + // intrinsic property of these buttons. + if($wf2.isInitialized){ //if buttons not yet initialized, will initially be called by _init_document + $wf2.updateAddButtons(this); + $wf2.updateMoveButtons(this.parentNode); + } + + //Setup block with the other WF2 behavior + $wf2.initNonRepetitionFunctionality(block); + //var els = $wf2.getElementsByTagNamesAndAttribute.apply(block, [['*'], "autofocus"]); //ISSUE: Any form control (except hidden and output controls) can have an autofocus attribute specified. //var elName = els[i].nodeName.toLowerCase(); if(elName == 'output' || (elName == 'input' && els[i].type == 'hidden')) + //for(var i = 0; i < els.length; i++) + // $wf2.initAutofocusElement(els[i]); + + //17. An added event with no namespace, which bubbles but is not cancelable and has no default action, + // must be fired on the repetition template using the RepetitionEvent interface, with the repetition + // block's DOM node as the context information in the element attribute. + var addEvt; + try { + if(document.createEvent) + addEvt = document.createEvent('UIEvents'); //document.createEvent("RepetitionEvent") + else if(document.createEventObject) + addEvt = document.createEventObject(); + RepetitionEvent._upgradeEvent.apply(addEvt); + addEvt.initRepetitionEvent('added', true /*canBubble*/, false /*cancelable*/, block); + if(this.dispatchEvent) + this.dispatchEvent(addEvt); + else if(this.fireEvent){ + //console.warn("fireEvent('onadd') for MSIE is not yet working"); + //this.fireEvent('onadded', addEvt); + } + } + catch(err){ + addEvt = new Object(); + RepetitionEvent._upgradeEvent.apply(addEvt); + addEvt.initRepetitionEvent('added', true /*canBubble*/, false /*cancelable*/, block); + } + + //Add support for event handler set with HTML attribute + var handlerAttr; + if((handlerAttr = this.getAttribute('onadded')) && (!this.onadded || typeof this.onadded != 'function')){ //in MSIE, attribute == property + this.onadded = new Function('event', handlerAttr); + } + //Deprecated + else if((handlerAttr = this.getAttribute('onadd')) && (!this.onadd || typeof this.onadd != 'function')){ + this.onadd = new Function('event', handlerAttr); + } + + try { + //Dispatch events for the old event model (extension to spec) + if(this.onadded){ + //this.onadded(addEvt); + this.onadded.apply(this, [addEvt]); //for some reason, exceptions cannot be caught if using the method above in MSIE + } + else if(this.onadd){ //deprecated + //this.onadd(addEvt); + this.onadd.apply(this, [addEvt]); + } + } + catch(err){ + //throw exception within setTimeout so that the current execution will not be aborted + setTimeout(function(){ + throw err; + }, 0); //using 0 milliseconds done at + } + + //18. The return value is the newly cloned element. + return block; + }, + //Element addRepetitionBlockByIndex(in Node refNode, in long index); + addRepetitionBlockByIndex : function(refNode, index){ + $wf2.addRepetitionBlock.apply(this, [refNode, index]) + }, + + //## RemoveRepetitionBlock algorithm ############################################################# + + //void removeRepetitionBlock(); + removeRepetitionBlock : function(){ + if(this.repetitionType != RepetitionElement.REPETITION_BLOCK) + throw $wf2.DOMException(9); //NOT_SUPPORTED_ERR + + //1. The node is removed from its parent, if it has one. Mutation events are fired if appropriate. + // (This occurs even if the repetition block is an orphan repetition block.) + var parentNode = this.parentNode; //save for updateMoveButtons + var block = parentNode.removeChild(this); + $wf2.updateMoveButtons(parentNode); + + //The following loop used to appear within step #3 below; + // this caused problems because the program state was incorrect when onremoved was called (repetitionBlocks was not modified) + if(this.repetitionTemplate != null){ + for(var i = 0; i < this.repetitionTemplate.repetitionBlocks.length; i++){ + if(this.repetitionTemplate.repetitionBlocks[i] == this){ + this.repetitionTemplate.repetitionBlocks.splice(i,1); + break; + } + } + } + + //2. If the repetition block is not an orphan, a removed event with no namespace, which bubbles but + // is not cancelable and has no default action, must be fired on the element's repetition template, + // using the RepetitionEvent interface, with the repetition block's DOM node as the context information + // in the element attribute. + if(this.repetitionTemplate != null){ + var removeEvt; + try { + if(document.createEvent) + removeEvt = document.createEvent('UIEvents'); //document.createEvent("RepetitionEvent") + else if(document.createEventObject) + removeEvt = document.createEventObject(); + RepetitionEvent._upgradeEvent.apply(removeEvt); + removeEvt.initRepetitionEvent('removed', true /*canBubble*/, false /*cancelable*/, this); + if(this.repetitionTemplate.dispatchEvent) + this.repetitionTemplate.dispatchEvent(removeEvt); + else if(this.repetitionTemplate.fireEvent){ + //console.warn("fireEvent('onremoved') for MSIE is not yet working"); + //this.repetitionTemplate.fireEvent('onremoved', removeEvt); + } + } + catch(err){ + removeEvt = new Object(); + RepetitionEvent._upgradeEvent.apply(removeEvt); + removeEvt.initRepetitionEvent('removed', true /*canBubble*/, false /*cancelable*/, this); + } + + //Add support for event handler set with HTML attribute + var handlerAttr; + if((handlerAttr = this.repetitionTemplate.getAttribute('onremoved')) && + (!this.repetitionTemplate.onremoved || typeof this.repetitionTemplate.onremoved != 'function')) //in MSIE, attribute == property + { + this.repetitionTemplate.onremoved = new Function('event', handlerAttr); + } + //Deprecated + else if((handlerAttr = this.repetitionTemplate.getAttribute('onremove')) && + (!this.repetitionTemplate.onremove || typeof this.repetitionTemplate.onremove != 'function')) + { + this.repetitionTemplate.onremove = new Function('event', handlerAttr); + } + + try { + //Dispatch events for the old event model (extension to spec) + if(this.repetitionTemplate.onremoved){ + //this.repetitionTemplate.onremoved(removeEvt); + this.repetitionTemplate.onremoved.apply(this, [removeEvt]); //for some reason, exceptions cannot be caught if using the method above in MSIE + } + else if(this.repetitionTemplate.onremove){ //deprecated + //this.repetitionTemplate.onremove(removeEvt); + this.repetitionTemplate.onremove.apply(this, [removeEvt]); + } + } + catch(err){ + //throw exception within setTimeout so that the current execution will not be aborted + setTimeout(function(){ + throw err; + }, 0); + } + } + + //3. If the repetition block is not an orphan, then while the remaining number of repetition blocks + // associated with the original element's repetition template and with the same parent as the template + // is less than the template's repeat-min attribute and less than its repeat-max attribute, the + // template's replication behaviour is invoked (specifically, its addRepetitionBlock() method is called). + if(this.repetitionTemplate != null){ +// //BUG: The following needs to be moved before the call to onremoved +// var t = this.repetitionTemplate; +// for(var i = 0; i < t.repetitionBlocks.length; i++){ +// if(t.repetitionBlocks[i] == this){ +// t.repetitionBlocks.splice(i,1); +// break; +// } +// } + if(this.repetitionTemplate.repetitionBlocks.length < this.repetitionTemplate.repeatMin + && this.repetitionTemplate.repetitionBlocks.length < this.repetitionTemplate.repeatMax) + { + this.repetitionTemplate.addRepetitionBlock(); + } + + //enable add buttons + if(this.repetitionTemplate.repetitionBlocks.length < this.repetitionTemplate.repeatMax){ + //var addBtns = cssQuery("button[type=add]"); + var addBtns = $wf2.getElementsByTagNamesAndAttribute.apply(document.documentElement, [['button'], 'type', 'add']); + for(i = 0; i < addBtns.length; i++){ + if(addBtns[i].htmlTemplate == this.repetitionTemplate) + addBtns[i].disabled = false; + } + } + } + }, + + //## MoveRepetitionBlock algorithm ############################################################# + + //void moveRepetitionBlock(in long distance); + moveRepetitionBlock : function(distance){ + if(this.repetitionType != RepetitionElement.REPETITION_BLOCK) + throw $wf2.DOMException(9); //NOT_SUPPORTED_ERR + + //1. If distance is 0, or if the repetition block has no parent, nothing happens and the algorithm ends here. + if(distance == 0 || this.parentNode == null) + return; + + //2. Set target, a reference to a DOM Node, to the repetition block being moved. + // [Furthermore, move the reference to this block in the template's repetitionBlocks HTMLCollection to + // reflect the new position that it is being moved to.] + var target = this; + if(this.repetitionTemplate){ + var pos = 0; + var rp = this.repetitionTemplate.repetitionBlocks; + while(pos < rp.length && rp[pos] != this) + pos++; + rp.splice(pos, 1); + rp.splice(distance < 0 ? Math.max(pos+distance, 0) : Math.min(pos+distance, rp.length), 0, this); + } + + //3. If distance is negative: while distance is not zero and target's previousSibling is defined and is + // not a repetition template, set target to this previousSibling and, if it is a repetition block, + // increase distance by one (make it less negative by one). + if(distance < 0){ + while(distance != 0 && target.previousSibling && + target.previousSibling.repetitionType != RepetitionElement.REPETITION_TEMPLATE) + { + target = target.previousSibling; + if(target.repetitionType == RepetitionElement.REPETITION_BLOCK) + distance++; + } + } + //4. Otherwise, distance is positive: while distance is not zero and target's nextSibling is defined + // and is not a repetition template, set target to this nextSibling and, if it is a repetition block, + // decrease distance by one. After the loop, set target to target's nextSibling (which may be null). + else { + while(distance != 0 && target.nextSibling && target.nextSibling.repetitionType != RepetitionElement.REPETITION_TEMPLATE){ + target = target.nextSibling; + if(target.repetitionType == RepetitionElement.REPETITION_BLOCK) + distance--; + } + target = target.nextSibling; + } + + //5. Call the repetition block's parent node's insertBefore() method with the newChild argument + // being the repetition block and the refChild argument being target (which may be null by this + // point). Mutation events are fired if appropriate. + this.parentNode.insertBefore(this, target); + + //Keep focus on the move button which was clicked + if(this._clickedMoveBtn){ + this._clickedMoveBtn.focus(); + this._clickedMoveBtn = null; + } + + //In addition, user agents must automatically disable move-up buttons (irrespective of the + // value of the disabled DOM attribute) when their repetition block could not be moved any + // higher according to the algorithm above, and when the buttons are not in a repetition + // block. Similarly, user agents must automatically disable move-down buttons when their + // repetition block could not be moved any lower according to the algorithm above, and + // when the buttons are not in a repetition block. This automatic disabling does not affect + // the DOM disabled attribute. It is an intrinsic property of these buttons. + $wf2.updateMoveButtons(this.parentNode); + + //6. A moved event with no namespace, which bubbles but is not cancelable and has no default action, + // must be fired on the element's repetition template (if it has one), using the RepetitionEvent + // interface, with the repetition block's DOM node as the context information in the element attribute. + if(this.repetitionTemplate != null){ + var moveEvt; + try { + if(document.createEvent) + moveEvt = document.createEvent('UIEvents'); //document.createEvent("RepetitionEvent") + else if(document.createEventObject) + moveEvt = document.createEventObject(); + RepetitionEvent._upgradeEvent.apply(moveEvt); + moveEvt.initRepetitionEvent('moved', true /*canBubble*/, false /*cancelable*/, this); + if(this.repetitionTemplate.dispatchEvent) + this.repetitionTemplate.dispatchEvent(moveEvt); + else if(this.repetitionTemplate.fireEvent){ + //console.warn("fireEvent('onmoved') for MSIE is not yet working"); + //this.fireEvent('onmoved', moveEvt); + } + } + catch(err){ + moveEvt = new Object(); + RepetitionEvent._upgradeEvent.apply(moveEvt); + moveEvt.initRepetitionEvent('moved', true /*canBubble*/, false /*cancelable*/, this); + } + + //Add support for event handler set with HTML attribute--------------------- + var handlerAttr; + if((handlerAttr = this.repetitionTemplate.getAttribute('onmoved')) && + (!this.repetitionTemplate.onmoved || typeof this.repetitionTemplate.onmoved != 'function')) //in MSIE, attribute == property + { + this.repetitionTemplate.onmoved = new Function('event', handlerAttr); + } + //Deprecated + else if(handlerAttr = this.repetitionTemplate.getAttribute('onmove')) + { + if(!this.repetitionTemplate.onmove || typeof this.repetitionTemplate.onmove != 'function'){ + this.repetitionTemplate.onmove = new Function('event', handlerAttr); + } + + //For MSIE, onmove is already an event, and attributes are equal to properties, so attribute value can be function. + // The 'event' argument must be added to the function argument list. + var funcMatches; + if(typeof handlerAttr == 'function' && (funcMatches = handlerAttr.toString().match(/^\s*function\s+anonymous\(\s*\)\s*\{((?:.|\n)+)\}\s*$/))){ + this.repetitionTemplate.onmove = new Function('event', funcMatches[1]); + } + } + + +// var onmovedAttr = this.repetitionTemplate.getAttribute('onmoved') +// || /* deprecated */ this.repetitionTemplate.getAttribute('onmove'); + + //For MSIE, onmove is already an event, and attributes are equal to properties, so attribute value can be function. + // The 'event' argument must be added to the function argument list. +// var funcMatches; +// if(typeof onmovedAttr == 'function' && (funcMatches = onmovedAttr.toString().match(/^\s*function\s+anonymous\(\s*\)\s*\{((?:.|\n)+)\}\s*$/))){ +// this.repetitionTemplate.onmoved = new Function('event', funcMatches[1]); +// } + + //If the onmove attribute has been set but the property (method) has not +// if(onmovedAttr && !this.repetitionTemplate.onmoved) +// this.repetitionTemplate.onmoved = new Function('event', onmovedAttr); + + //This need not be done in MSIE since onmove is already an event, and attributes == properties + //if(onmoveAttr && typeof onmoveAttr != 'function' /* for MSIE */ && + // (!this.repetitionTemplate.onmove || typeof this.repetitionTemplate.onmove != 'function') + // ){ + // this.repetitionTemplate.onmove = new Function('event', onmoveAttr); + //} + + try { + //Dispatch events for the old event model (extension to spec) + if(this.repetitionTemplate.onmoved){ + //this.repetitionTemplate.onmoved(moveEvt); + this.repetitionTemplate.onmoved.apply(this, [moveEvt]); + } + else if(this.repetitionTemplate.onmove){ //deprecated + //this.repetitionTemplate.onmove(moveEvt); + this.repetitionTemplate.onmove.apply(this, [moveEvt]); + } + } + catch(err){ + //throw exception within setTimeout so that the current execution will not be aborted + setTimeout(function(){ + throw err; + }, 0); //using 0 milliseconds done at + } + } + }, + + //## Other helper functions for the repetition model behaviors ############################## + getRepetitionBlock : function(node){ + while(node = node.parentNode){ + if(node.repetitionType == RepetitionElement.REPETITION_BLOCK){ + return node; + } + } + return null; + }, + + getHtmlTemplate : function(button){ + var attr = button.getAttribute('template'); + var node; + if(attr && (node = document.getElementById(attr)) && node.getAttribute('repeat') == 'template' /*node.repetitionType == RepetitionElement.REPETITION_TEMPLATE*/) + return node; + return null; + }, + + updateAddButtons : function(rt){ + //In addition, user agents must automatically disable add buttons (irrespective of the value of the + // disabled DOM attribute) when the buttons are not in a repetition block that has an associated + // template and their template attribute is either not specified or does not have an ID that points + // to a repetition template, and, when the repetition template's repeat-max attribute is less than + // or equal to the number of repetition blocks that are associated with that template and that have + // the same parent. This automatic disabling does not affect the DOM disabled attribute. It is an + // intrinsic property of these buttons. + + var repetitionTemplates = rt ? [rt] : $wf2.repetitionTemplates; + + //var btns = cssQuery("button[type=add]"); + var btns = $wf2.getElementsByTagNamesAndAttribute.apply(document.documentElement, [['button'], 'type', 'add']); + for(var i = 0; i < btns.length; i++){ + for(var t, j = 0; t = repetitionTemplates[j]; j++){ + if(btns[i].htmlTemplate == t && t.repetitionBlocks.length >= t.repeatMax){ + btns[i].disabled = true; + } + } + } + }, + + updateMoveButtons : function(parent){ + //In addition, user agents must automatically disable move-up buttons (irrespective of the value of + // the disabled DOM attribute) when their repetition block could not be moved any higher according + // to the algorithm above, and when the buttons are not in a repetition block. Similarly, user agents + // must automatically disable move-down buttons when their repetition block could not be moved any + // lower according to the algorithm above, and when the buttons are not in a repetition block. This + // automatic disabling does not affect the DOM disabled attribute. It is an intrinsic property of + // these buttons. + + var i; + var rbs = []; + + //update all move buttons if a repetition block's parent was not given + if(!parent){ + var visitedParents = []; + //var rbs = cssQuery('*[repeat]:not([repeat="template"])'); + //var rbs = $wf2.getElementsByProperty('repetitionType', RepetitionElement.REPETITION_BLOCK); + rbs = $wf2.getElementsByTagNamesAndAttribute.apply(document.documentElement, [['*'], 'repeat', 'template', true]); + for(i = 0; block = rbs[i]; i++){ + //if(!visitedParents.some(function(i){return i == block.parentNode})){ + if(!$wf2.arrayHasItem(visitedParents, block.parentNode)){ + $wf2.updateMoveButtons(block.parentNode); + visitedParents.push(block.parentNode); + } + } + return; + } + + //get all of the repetition block siblings + var j,btn,block; + var child = parent.firstChild; + while(child){ + if(child.repetitionType == RepetitionElement.REPETITION_BLOCK) + rbs.push(child); + child = child.nextSibling; + } + + //disable or enable movement buttons within each block + for(i = 0; block = rbs[i]; i++){ + //var moveUpBtns = cssQuery("button[type=move-up]", block); + var moveUpBtns = $wf2.getElementsByTagNamesAndAttribute.apply(block, [['button'], 'type', 'move-up']); + for(j = 0; btn = moveUpBtns[j]; j++){ + btn.disabled = + //if the button is not in a repetition block + !(rb = $wf2.getRepetitionBlock(btn)) + || + //when their repetition block could not be moved any lower + (i == 0); + } + //var moveDownBtns = cssQuery("button[type=move-down]", block); + var moveDownBtns = $wf2.getElementsByTagNamesAndAttribute.apply(block, [['button'], 'type', 'move-down']); + for(j = 0; btn = moveDownBtns[j]; j++){ + btn.disabled = + //if the button is not in a repetition block + !(rb = $wf2.getRepetitionBlock(btn)) + || + //when their repetition block could not be moved any higher + (i == rbs.length-1); + } + } + }, + + /*############################################################################################# + # Section: Extensions to the input element + ##############################################################################################*/ + + initNonRepetitionFunctionality : function(parent){ + parent = (parent || document.documentElement); + var i,j, frm, frms = parent.getElementsByTagName('form'); + for(i = 0; frm = frms[i]; i++){ + if(frm.checkValidity && !$wf2.hasBadImplementation) + continue; + frm.checkValidity = $wf2.formCheckValidity; + + if(frm.addEventListener) + frm.addEventListener('submit', $wf2.onsubmitValidityHandler, false); + else + frm.attachEvent('onsubmit', $wf2.onsubmitValidityHandler); + } + + var ctrl, ctrls = $wf2.getElementsByTagNames.apply(parent, ['input','select','textarea', 'button']);//parent.getElementsByTagName([i]); + for(i = 0; ctrl = ctrls[i]; i++){ + $wf2.applyValidityInterface(ctrl); + $wf2.updateValidityState(ctrl); //ctrl._updateValidityState(); + } + + //Autofocus ********************************************************** + //Authors must not set the autofocus attribute on multiple enabled elements in a document. + // If multiple elements with the autofocus attribute set are inserted into a document, each one + // will be processed as described above, as they are inserted. This means that during document + // load, for example, the last focusable form control in document order with the attribute set + // will end up with the focus. + var els = $wf2.getElementsByTagNamesAndAttribute.apply(document.documentElement, [['*'], 'autofocus']); //ISSUE: Any form control (except hidden and output controls) can have an autofocus attribute specified. //var elName = els[i].nodeName.toLowerCase(); if(elName == 'output' || (elName == 'input' && els[i].type == 'hidden')) + if(parent.getAttribute('autofocus')) + els.unshift(parent); + for(i = 0; i < els.length; i++) + $wf2.initAutofocusElement(els[i]); + + // Maxlength for textareas ****************************************************** + var textareas = $wf2.getElementsByTagNamesAndAttribute.apply(parent, [['textarea'], 'maxlength']); + if(parent.nodeName.toLowerCase() == 'textarea') + textareas.unshift(parent); + for(i = 0; i < textareas.length; i++) + textareas[i].maxLength = parseInt(textareas[i].getAttribute('maxlength')); + //TODO: we must dynamically apply this behavior for new textareas (via repetition model or eventlistener) + }, + + initAutofocusElement : function(el){ + //skip if already initialized + if(el.autofocus === false || el.autofocus === true) //(el.autofocus !== undefined) does not work due to MSIE's handling of attributes + return; + el.autofocus = true; + + //[autofocus if] the control is not disabled + if(el.disabled) + return; + + //[control] is of a type normally focusable in the user's operating environment + //Don't focus on the control if it is not visible or nor displayed + var node = el; + while(node && node.nodeType == 1){ + if($wf2.getElementStyle(node, 'visibility') == 'hidden' || $wf2.getElementStyle(node, 'display') == 'none') + return; + node = node.parentNode; + } + + //Then the UA should focus the control, as if the control's focus() method was invoked. + // UAs with a viewport should also scroll the document enough to make the control visible, + // [[even if it is not of a type normally focusable.]] //WHAT DOES THIS MEAN? + el.focus(); //BUG: in Gecko this does not work within DOMNodeInserted event handler, but the following does; setTimeout(function(){el.focus();}, 0); + + + }, + + /*############################################################################################# + # Section: Form Validation model + ##############################################################################################*/ + + formCheckValidity : function(){ + var i, el, valid = true; + + //When a form is submitted, user agents must act as if they used the following algorithm. + // First, each element in that form's elements list is added to a temporary list (note that + // the elements list is defined to be in document order). + + //An invalid event must be fired on each element that, when checked, is found to fail to + // comply with its constraints (i.e. each element whose validity.valid DOM attribute is + // false) and is still a member of the form after the event has been handled. + //var _elements = []; + var formElements = $wf2.getFormElements.apply(this); + //for(i = 0; i < formElements.length; i++) + // _elements.push(formElements[i]); + for(i = 0; el = formElements[i]; i++){ + var type = (el.getAttribute('type') ? el.getAttribute('type').toLowerCase() : el.type); + el.willValidate = !(/(hidden|button|reset|add|remove|move-up|move-down)/.test(type) || !el.name || el.disabled) + //Then, each element in this list whose willValidate DOM attribute is true is checked for validity + if(el.checkValidity && el.willValidate){ + if(!el.checkValidity() && el.checkValidity() != undefined) { + valid = false; + + + /* we change this to only show the first error. + if (!$wf2.showAllErrors) { + break; + } + */ + } + } + } + + if (!valid) { + $wf2.hiliteFirstError(); + } + return valid; + }, + + hiliteFirstError: function () { + + if($wf2.invalidIndicators.length){ //second condition needed because modal in oninvalid handler may cause indicators to disappear before this is reached + //$wf2.invalidIndicators[0].errorMsg.className += " wf2_firstErrorMsg"; + $wf2.css.addClass($wf2.invalidIndicators[0].errorMsg, "wf2_firstErrorMsg"); + //scroll to near the location where invalid control is + el = $wf2.invalidIndicators[0].target; + + var doScroll = (el.form.getAttribute('data-wf2-no-scroll-on-error') != 'true') + + if(el.style.display == 'none' || !el.offsetParent){ + while(el && (el.nodeType != 1 || (el.style.display == 'none' || !el.offsetParent))) + el = el.previousSibling; + var cur = el; + var top = 0; + if(cur && cur.offsetParent) { + top = cur.offsetTop; + while (cur = cur.offsetParent) + top += cur.offsetTop; + } + if (doScroll) { + scrollTo(0, top); + } + } + //focus on the first invalid control and make sure error message is visible + else { + + setTimeout( + function() { + el.focus(); + $wf2.fireEvent(el, 'focus'); + } + , 10) + + //NOTE: We should only do this if the control's style.bottom == 0 + if (doScroll) { + scrollBy(0, $wf2.invalidIndicators[0].errorMsg.offsetHeight); + } + } + } + + }, + + controlCheckValidity : function(){ + return $wf2.controlCheckValidityOfElement(this); + + }, + + controlCheckValidityOfElement: function (el) { + + + + $wf2.updateValidityState(el); + + if (el.validity.valid) { + + return true; + } + + var canceled = false; + + var evt; + try { + if(document.createEvent) + evt = document.createEvent('Events'); //document.createEvent("RepetitionEvent") + else if(document.createEventObject) + evt = document.createEventObject(); + evt.initEvent('invalid', true /*canBubble*/, true /*cancelable*/); + evt.srcElement = el; + if(el.dispatchEvent) + canceled = !el.dispatchEvent(evt); + else if(el.fireEvent){ + //console.warn("fireEvent('oninvalid') for MSIE is not yet working"); + //el.fireEvent('oninvalid', invalidEvt); + } + } + catch(err){ + evt = new Object(); + if(evt.initEvent) + evt.initEvent('invalid', true /*canBubble*/, true /*cancelable*/); + else { + evt.type = 'invalid'; + evt.cancelBubble = false; + } + evt.target = evt.srcElement = el; + } + + var oninvalidAttr = el.getAttribute('oninvalid'); + if(oninvalidAttr && (!el.oninvalid || typeof el.oninvalid != 'function')) //in MSIE, attribute == property + el.oninvalid = new Function('event', oninvalidAttr); + + try { + //Dispatch events for the old event model + if(el.oninvalid){ + //canceled = el.oninvalid(evt) === false || canceled; + canceled = el.oninvalid.apply(el, [evt]) === false || canceled; //for some reason, exceptions cannot be caught if using the method above in MSIE + } + } + catch(err){ + //throw exception within setTimeout so that the current execution will not be aborted + setTimeout(function(){ + throw err; + }, 0); + } + + //Determine if this radio/checkbox already has an invalid indicator + var hasInvalidIndicator = false; + if(el.type == 'radio' || el.type == 'checkbox'){ + for(var i = 0; i < $wf2.invalidIndicators.length; i++){ + if(el.form[el.name][0] == $wf2.invalidIndicators[i].target){ + hasInvalidIndicator = true; + break; + } + } + } + + //Do default action + if(!canceled && !hasInvalidIndicator) //(!(el.form && el.form[el.name]) || !el.form[el.name].wf2HasInvalidIndicator) + $wf2.addInvalidIndicator(el); + return false; + }, + + //Frequently used regular expressions //W(?:0[1-9]|[1-4]\d|5[0-2])| + //monthRegExp : /^\d\d\d\d-(0\d|1[0-2])$/, + //weekRegExp : /^(\d\d\d\d)-W(0[1-9]|[1-4]\d|5[0-2])$/, + //timeRegExp : /^(0\d|1\d|2[0-4]):([0-5]\d)(:[0-5]\d(.\d+)?)?$/, + numberRegExp : /^-?\d+(.\d+)?(e-?\d+)?$/, + //numberOrAnyRegExp : /^(any|-?\d+(.\d+)?(e-?\d+)?)$/i, + urlRegExp : /^(\w+):(\/\/)?.+$/i, + emailRegExp : /^\S+@\S+$/i, + + //Zero points for datetime-related types (set in onDOMContentLoaded function) +// zeroPointDatetime : null, +// zeroPointDatetimeLocal : null, +// zeroPointDate : null, +// zeroPointMonth : null, +// zeroPointWeek : null, +// zeroPointTime : null, + + copyOf: function(obj) { + if (obj !== null && obj !== undefined) { + var r = new Object(); + for (i in obj) { + + try { + r[i] = obj[i]; + } + catch (ex) { + // do nothing; + } + } + + } else { + r = null; + } + + return r; + }, + + getOriginalAttrNode: function (node, attrName) { + var r; + + /* var dataSetItemName = attrName + 'AttrNode'; + + if ($wf2.getDatasetItem(node, dataSetItemName) == null) { + r = $wf2.copyOf(node.getAttributeNode(attrName)); + $wf2.setDatasetItem(node, dataSetItemName, r.value); + } else { + r = $wf2.getDatasetItem(node, dataSetItemName); + if (r == 'null') { + r = null; + } + } */ + + r = $wf2.copyOf(node.getAttributeNode(attrName)); + + return r; + }, + + //This function is called "live" + updateValidityState : function(node){ + //if(node.form && node.form[node.name] && node.form[node.name].wf2HasInvalidIndicator) + // return; + + var minAttrNode, maxAttrNode, valueAttrNode; + + minAttrNode = $wf2.getOriginalAttrNode(node, 'min'); + maxAttrNode = $wf2.getOriginalAttrNode(node, 'max'); + stepAttrNode = $wf2.getOriginalAttrNode(node, 'step'); + valueAttrNode = $wf2.getOriginalAttrNode(node, 'value'); + + node.min = undefined; //wf2Min + node.max = undefined; //wf2Max + node.step = undefined; //wf2Step + + + + node.validity = $wf2.createValidityState(); + node.validity.customError = !!node.validationMessage; + + //var type = node.type ? node.type.toLowerCase() : 'text'; + //var type = (node.type ? node.getAttribute('type').toLowerCase() : + // (node.nodeName.toLowerCase() == 'input' ? 'text' : '')); + var type = (node.getAttribute('type') ? node.getAttribute('type').toLowerCase() : node.type); + var isTimeRelated = (type == 'datetime' || type == 'datetime-local' || type == 'time'); //datetime, datetime-local, time + var isDateRelated = (type == 'date' || type == 'month' || type == 'week'); //date, month, week + var isNumberRelated = (type == 'number' || type == 'range'); //number, range + var isFileInput = (type == 'file'); + var doCheckPrecision = (isTimeRelated || isDateRelated || isNumberRelated); //datetime, datetime-local, time, date, month, week, number, range + var doMaxLengthCheck = doCheckPrecision || node.nodeName.toLowerCase() == 'textarea'; //datetime, datetime-local, time, date, month, week, number, range, textarea + var doCheckRange = (doCheckPrecision || isFileInput); //datetime, datetime-local, time, date, month, week, number, range, file + var isRadioOrCheckbox = (type == 'radio' || type == 'checkbox'); + var doRequiredCheck = (doMaxLengthCheck || //datetime, datetime-local, time, date, month, week, number, range, textarea + isFileInput || + type == 'email' || + type == 'url' || + type == 'text' || + type == 'password'|| + type == 'tel' || + isRadioOrCheckbox); + + //If a control has its type attribute changed to another type, then the user agent must reinterpret the min and + // max attributes. If an attribute has an invalid value according to the new type, then the appropriate + // default must be used (and not, e.g., the default appropriate for the previous type). Control values that + // no longer match the range allowed for the control must be handled as described in the error handling section. + //if(!node.wf2PreviousType) + // node.wf2PreviousType == type; + //else if(type != node.wf2PreviousType){ + // throw Error("Currently unable to change the type of a control."); //TODO + //} + + if(type == 'range'){ + //For this type...min defaults to 0...and value defaults to the min value. + node.min = (minAttrNode && $wf2.numberRegExp.test(minAttrNode.value)) ? Number(minAttrNode.value) : 0; + if((!valueAttrNode || !valueAttrNode.specified) && node.value === '' && !node.wf2ValueProvided){ //(!valueAttrNode || !valueAttrNode.specified) && + node.setAttribute('value', node.min); + node.value = node.min; + node.wf2ValueProvided = true; + } + return; + } + + if ($wf2.css.isMemberOfClass(node, 'html5-hasPlaceholderText')) { + node.wf2Value = ''; + } else { + node.wf2Value = node.value; + } + //console.log("changing:", node.value, ", " , node.wf2Value) + + //valueMissing -- The control has the required attribute set but it has not been satisfied. + //The required attribute applies to all form controls except controls with the type hidden, + // image inputs, buttons (submit, move-up, etc), and select and output elements. For + // disabled or readonly controls, the attribute has no effect. + var type = (node.getAttribute('type') ? node.getAttribute('type').toLowerCase() : node.type); + node.willValidate = !(/(hidden|button|reset|add|remove|move-up|move-down)/.test(type) || !node.name || node.disabled); + if(doRequiredCheck && node.willValidate){ + //For checkboxes, the required attribute shall only be satisfied when one or more of + // the checkboxes with that name in that form are checked. + //For radio buttons, the required attribute shall only be satisfied when exactly one of + // the radio buttons in that radio group is checked. + if(isRadioOrCheckbox){ + if(node.form && node.form[node.name]){ + var isRequired = false; + var hasChecked = false; + + var inputs = node.form[node.name]; + + /* + * remember: the above expression may return an array + * or a single value. Must check for this. + */ + if (inputs.length == undefined) { + if (inputs.getAttributeNode('required')) + isRequired = true; + if (inputs.checked) + hasChecked = true; + } else { + for (var i = 0; i < inputs.length; i++) { + if (inputs[i].getAttributeNode('required')) + isRequired = true; + if (inputs[i].checked) + hasChecked = true; + } + } + node.validity.valueMissing = (isRequired && !hasChecked); + } + } + //The required attribute applies to all form controls except controls with the type hidden, + // image inputs, buttons (submit, move-up, etc), and select and output elements. For + // disabled or readonly controls, the attribute has no effect. + else if(node.getAttributeNode('required')){ + //if(node.options) + // node.validity.valueMissing = (node.selectedIndex == -1); + //For other controls, any non-empty value shall satisfy the required condition, + // including a simple whitespace character. + //else + node.validity.valueMissing = (node.wf2Value == ''); + } + //if(node.options ? node.selectedIndex == -1 : node.value === '') + // node.validity.valueMissing = true; + // + } + if(!node.validity.valueMissing && node.wf2Value){ + //patternMismatch -- The value of the control with a pattern attribute doesn't match the pattern. + // If the control is empty, this flag must not be set. + //If the pattern attribute is present but empty, it doesn't match any value, and thus the + // patternMismatch flag shall be set whenever the control's value isn't empty. + var patternAttr = node.getAttributeNode('pattern'); + if(patternAttr){ + //the pattern attribute must match the entire value, not just any subset (somewhat as if + // it implied a ^(?: at the start of the pattern and a )$ at the end). + var rePattern = new RegExp("^(?:" + patternAttr.value + ")$"); + //The pattern must be compiled with the global, ignoreCase, and multiline flags disabled + rePattern.global = false; + rePattern.ignoreCase = false; + rePattern.multiline = false; + //When the pattern is not a valid regular expression, it is ignored for the purposes of + // validation, as if it wasn't specified. + if(rePattern) + node.validity.patternMismatch = !rePattern.test(node.wf2Value); + } + + //typeMismatch -- The data entered does not match the type of the control. For example, if the UA + // allows uninterpreted arbitrary text entry for month controls, and the user has entered SEP02, + // then this flag would be set. This code is also used when the selected file in a file upload + // control does not have an appropriate MIME type. If the control is empty, this flag must not be set. + if(isDateRelated || isTimeRelated) { + //node.validity.typeMismatch = ((node.value = $wf2.parseISO8601(node.wf2Value, type)) == null); + //node.wf2Value = node.value; + } else { + switch(type){ + case 'number': + case 'range': + node.validity.typeMismatch = !$wf2.numberRegExp.test(node.wf2Value); + // if(!node.validity.typeMismatch && node.getAttribute("step") != 'any'){ + // if(node.step == undefined) + // node.step = 1; + // var val = Number(node.value); + // node.validity.stepMismatch = (val == parseInt(val) && node.step != parseInt(node.step)); + // } + break; + case 'email': + //An e-mail address, following the format of the addr-spec token defined in RFC 2822 section + // 3.4.1 [RFC2822], but excluding the CFWS subtoken everywhere, and excluding the FWS + // subtoken everywhere except in the quoted-string subtoken. UAs could, for example, offer + // e-mail addresses from the user's address book. (See below for notes on IDN.) + //http://www.ietf.org/rfc/rfc2822 + node.validity.typeMismatch = !$wf2.emailRegExp.test(node.wf2Value); + break; + case 'url': + //An IRI, as defined by [RFC3987] (the IRI token, defined in RFC 3987 section 2.2). UAs could, + // for example, offer the user URIs from his bookmarks. (See below for notes on IDN.) The value + // is called url (as opposed to iri or uri) for consistency with CSS syntax and because it is + // generally felt authors are more familiar with the term "URL" than the other, more technically + // correct terms. + //http://www.ietf.org/rfc/rfc3987 + node.validity.typeMismatch = !$wf2.urlRegExp.test(node.wf2Value); + break; + } + } + + if(!node.validity.patternMismatch && !node.validity.typeMismatch){ + //To limit the range of values allowed by some of the above types, two new attributes are introduced, which + // apply to the date-related, time-related, numeric, and file upload types: min and max + + //rangeUnderflow -- The numeric, date, or time value of a control with a min attribute is lower than + // the minimum, or a file upload control has fewer files selected than the minimum. If the control + // is empty or if the typeMismatch flag is set, this flag must not be set. + //rangeOverflow -- The numeric, date, or time value of a control with a max attribute is higher than + // the maximum, or a file upload control has more files selected than the maximum. If the control + // is empty or if the typeMismatch flag is set, this flag must not be set. + if(doCheckRange){ + if(isNumberRelated){ + //For numeric types (number and range) the value must exactly match the number type (numberRegExp) + if(type == 'range'){ + //For this type...max defaults to 100 + node.max = (maxAttrNode && $wf2.numberRegExp.test(maxAttrNode.value)) ? Number(maxAttrNode.value) : 100; + //node.min is set at the beginning of this function so that the min value can be set as the default value + } + else { + if(minAttrNode && $wf2.numberRegExp.test(minAttrNode.value)) + node.min = Number(minAttrNode.value); + if(maxAttrNode && $wf2.numberRegExp.test(maxAttrNode.value)) + node.max = Number(maxAttrNode.value); + if(stepAttrNode && $wf2.numberRegExp.test(stepAttrNode.value)) + node.step = Number(stepAttrNode.value); + } + node.validity.rangeUnderflow = (node.min != undefined && Number(node.wf2Value) < node.min); + node.validity.rangeOverflow = (node.max != undefined && Number(node.wf2Value) > node.max); + node.validity.stepMismatch = !$wf2.isValidNumber(node); + //console.log('first: ', node.validity.stepMismatch, ',', node.getAttribute('type')) + } + //For file types it must be a sequence of digits 0-9, treated as a base ten integer. + else if(type == 'file'){ + if(minAttrNode && /^\d+$/.test(minAttrNode.value)) + node.min = Number(minAttrNode.value); + //If absent, or if the minimum value is not in exactly the expected format, there + // is no minimum restriction, except for the ... file types, where the default is zero. + else node.min = 0; + if(maxAttrNode && /^\d+$/.test(maxAttrNode.value)) + node.max = Number(maxAttrNode.value); + //If absent, or if the maximum value is not in exactly the expected format, there is no + // maximum restriction (beyond those intrinsic to the type), except for ... the file + // type, where the default is 1. + else node.max = 1; + + //node.validity.rangeUnderflow = (node.min != undefined && Number(node.value) < node.min); + //node.validity.rangeOverflow = (node.max != undefined && Number(node.value) > node.max); + } + //Date related + else { + //For date and time types it must match the relevant format mentioned for that type, all fields + // having the right number of digits, with the right separating punctuation. + if(minAttrNode){ + node.min = $wf2.parseISO8601(minAttrNode.value, type); + node.validity.rangeUnderflow = (node.min && node.wf2Value < node.min); + } + if(maxAttrNode){ + node.max = $wf2.parseISO8601(maxAttrNode.value, type); + node.validity.rangeOverflow = (node.max && node.wf2Value > node.max); + } + } + } + //The step attribute controls the precision allowed for the date-related, time-related, and numeric types. + + //Note: webforms2 as of March 6, 2012 does not support step for time related inputs. Will revisit later. + if(!(isDateRelated || isTimeRelated) && doCheckPrecision && !node.validity.rangeUnderflow && !node.validity.rangeOverflow){ + //stepMismatch -- The value is not one of the values allowed by the step attribute, and the UA will + // not be rounding the value for submission. Empty values and values that caused the typeMismatch + // flag to be set must not cause this flag to be set. + + var stepAttrNode = $wf2.getOriginalAttrNode(node, 'step'); //node.getAttributeNode('step'); + + if(!stepAttrNode){ + //The step attribute [for types datetime, datetime-local, and time] ... defaulting to 60 (one minute). + //For time controls, the value of the step attribute is in seconds, although it may be a fractional + // number as well to allow fractional times. The default value of the step + // attribute for datetime, datetime-local and time controls is 60 (one minute). + //The step [for type date] attribute specifies the precision in days, defaulting to 1. + //The step [for type month] attribute specifies the precision in months, defaulting to 1. + //The step [for type week] attribute specifies the precision in weeks, defaulting to 1. + //For date controls, the value of the step attribute is in days, weeks, or months, for the date, + // week, and month types respectively. The format is a non-negative integer; one or more digits + // 0-9 interpreted as base ten. If the step is zero, it is interpreted as the default. The default + // for the step attribute for these control types is 1. + //The step [for types number and range] attribute specifies the precision, defaulting to 1. + node.step = isTimeRelated ? 60 : 1; + } + //The literal value 'any' may be used as the value of the step attribute. This keyword indicates that + // any value may be used (within the bounds of other restrictions placed on the control). + else if(stepAttrNode.value == 'any') + node.step = 'any'; //isStepAny = true; + //The format of the step attribute is the number format described above, except that + // the value must be greater than zero. + else if($wf2.numberRegExp.test(stepAttrNode.value) && stepAttrNode.value > 0) + node.step = Number(stepAttrNode.value); + else + node.step = isTimeRelated ? 60 : 1; + + if(node.step != 'any'){ + node.wf2StepDatum = null; + if(minAttrNode) + node.wf2StepDatum = node.min; + else if(maxAttrNode) + node.wf2StepDatum = node.max; + else + node.wf2StepDatum = $wf2.zeroPoint[type] ? $wf2.zeroPoint[type] : 0; + + //The zero point for datetime controls is 1970-01-01T00:00:00.0Z, for datetime-local is + // 1970-01-01T00:00:00.0, for date controls is 1970-01-01, for month controls is 1970-01, + // for week controls is 1970-W01 (the week starting 1969-12-29 and containing 1970-01-01), + // and for time controls is 00:00. + var _step = node.step; + if(type == 'month' && node.wf2StepDatum && node.wf2StepDatum.getUTCFullYear){ + //var month1 = node.wf2StepDatum.getUTCFullYear()*12 + node.wf2StepDatum.getUTCMonth(); + //var month2 = node.wf2Value.getUTCFullYear()*12 + node.wf2Value.getUTCMonth(); + //node.validity.stepMismatch = (month2 - month1)%_step != 0; + } + else { + switch(type){ + case 'datetime': + case 'datetime-local': + case 'time': + _step = parseInt(_step * 1000); //for millisecond comparisons + break; + case 'date': + _step = parseInt(_step * 24*60*60*1000); + break; + case 'week': + _step = parseInt(_step * 7*24*60*60*1000); + break; + } + + //For the control to be valid, the control's value must be an integral number of steps from the min value, + // or, if there is no min attribute, the max value, or if there is neither attribute, from the zero point. + //allow decimal places to the 1,000th place + node.validity.stepMismatch = (Math.round((node.wf2Value - node.wf2StepDatum)*1000) % Math.round(_step*1000)) != 0; + } + } + } + } + + //[TEXTAREA] tooLong -- The value of a control with a maxlength attribute is longer than the attribute allows, + // and the value of the control doesn't exactly match the control's default value. + //[The maxlength] attribute must not affect the initial value (the DOM defaultValue attribute). It must only + // affect what the user may enter and whether a validity error is flagged during validation. + if(doMaxLengthCheck && node.maxLength >= 0 && node.wf2Value != node.defaultValue){ + //A newline in a textarea's value must count as two code points for maxlength processing (because + // newlines in textareas are submitted as U+000D U+000A). [[NOT IMPLEMENTED: This includes the + // implied newlines that are added for submission when the wrap attribute has the value hard.]] + //var matches = node.value.match(/((? node.maxLength; + } + } else { + if(minAttrNode && $wf2.numberRegExp.test(minAttrNode.value)) + node.min = Number(minAttrNode.value); + if(maxAttrNode && $wf2.numberRegExp.test(maxAttrNode.value)) + node.max = Number(maxAttrNode.value); + if(stepAttrNode && $wf2.numberRegExp.test(stepAttrNode.value)) + node.step = Number(stepAttrNode.value); + } + + //customError -- The control was marked invalid from script. See the definition of the setCustomValiditiy() method. + //console.log('second: ', node.validity.stepMismatch) + node.validity.valid = !$wf2.hasInvalidState(node.validity); + if (node.validity.valid) { + $wf2.css.removeClass(node, 'wf2_invalid'); + $wf2.css.addClass(node, 'wf2_valid'); + //node.className = node.className.replace(/\s?wf2_invalid/g, "") + ' wf2_valid'; + //console.log('valid: ', node.className) + } else { + $wf2.css.removeClass(node, 'wf2_valid'); + $wf2.css.addClass(node, 'wf2_invalid'); + //node.className = node.className.replace(/\s?wf2_valid/g, "") + ' wf2_invalid'; + //console.log('not valid: ', node.className, 'value:', node.value, 'wtfValue:', node.wf2Value) + } + //This is now done onmousedown or onkeydown, just as Opera does + //if(node.validity.valid){ + // node.className = node.className.replace(/\s*\binvalid\b\s*/g, " "); //substitute for :invalid pseudo class + // //if(node.wf2_errorMsg){ + // // node.wf2_errorMsg.parentNode.removeChild(node.wf2_errorMsg); + // // node.wf2_errorMsg = null; + // //} + // var errMsg = document.getElementById((node.id || node.name) + '_wf2_errorMsg'); + // if(errMsg) + // errMsg.parentNode.removeChild(errMsg); + //} + }, + + // checks to see if a number node has a value that is valid. + isValidNumber: function (node) { + //console.log(node.wf2Value + ", " + node.min + ", " + node.max + ", " + node.step); + var n = (parseFloat(node.wf2Value) - parseFloat(node.min))/parseFloat(node.step); + //console.log('!' , n == parseInt(n)) + return (n == parseInt(n)); + }, + + applyValidityInterface : function(node){ + + /* Webkit browsers need this */ + if ($wf2.hasBadImplementation) { + + if (node.type == 'submit' || node.type == 'button') { + + node.formNoValidate=true; + + } + } + + /* ZOLTAN made a change here to ensure Google's unfinished native implementation is not used. */ + else if((node.validity && node.validity.typeMismatch !== undefined)) {//MSIE needs the second test for some reason + // console.log('bad implementation!! ' + node.id); + + return node; + } + node.validationMessage = ""; + + //ValidityState interface + node.validity = $wf2.createValidityState(); + node.willValidate = true; + + var nodeName = node.nodeName.toLowerCase(); + if(nodeName == 'button' || nodeName == 'fieldset'){ + node.setCustomValidity = function(error){ + throw $wf2.DOMException(9); //NOT_SUPPORTED_ERR + }; + node.checkValidity = function(){ + return true; + }; + return node; + } + //node._updateValidityState = $wf2._updateValidityState; + + if (!node.setCustomValidity) { + node.setCustomValidity = $wf2.controlSetCustomValidity; + } + + + node.checkValidity = $wf2.controlCheckValidity; + + + //var type = (node.type ? node.type.toLowerCase() : (nodeName == 'input' ? 'text' : '')); + var type = (node.getAttribute('type') ? node.getAttribute('type').toLowerCase() : node.type); + + if(/(hidden|button|reset|add|remove|move-up|move-down)/.test(type) || !node.name || node.disabled) + node.willValidate = false; + else if(window.RepetitionElement) { + var parent = node; + while(parent = parent.parentNode){ + if(parent.repetitionType == RepetitionElement.REPETITION_TEMPLATE){ + node.willValidate = false; + break; + } + } + } + + + /* ZOLTAN: validity */ + var handler = function(event){ + return $wf2.updateValidityState(event.currentTarget || event.srcElement); + }; + + //attempt to check validity live + if(document.addEventListener){ + node.addEventListener('change', handler, false); + node.addEventListener('blur', handler, false); + node.addEventListener('keyup', handler, false); + } + else if(window.attachEvent){ + node.attachEvent('onchange', handler); + node.attachEvent('onblur', handler); + node.attachEvent('onkeyup', handler); + } + else { + + } + + return node; + }, + + /* updateValidityState: function (node) { + if (node.checkValidity()){ + node.className = node.className.replace(/\s?wf2_invalid/, ""); + } else { + node.className += ' wf2_invalid'; + } + }, */ + + onsubmitValidityHandler : function(event){ + var frm = event.currentTarget || event.srcElement; + var r; + + // call routines other libraries have set to be run before + // validation. + for (var i=0; i<$wf2.callBeforeValidation.length; i++) { + $wf2.callBeforeValidation[i](event); + } + + /* ZOLTAN */ + if(!frm.checkValidity()){ + if(event.preventDefault) + event.preventDefault(); + event.returnValue = false; + r = false; + } else { + event.returnValue = true; + r = true; + } + + // call routines other libraries have set to be run before + // validation. + for (var i=0; i<$wf2.callAfterValidation.length; i++) { + $wf2.callAfterValidation[i](event, r); + } + + + + return r; + }, + + controlSetCustomValidity : function(error){ + if(error){ + this.validationMessage = String(error); + this.validity.customError = true; + } + else { + this.validationMessage = ""; + this.validity.customError = false; + } + this.validity.valid = !$wf2.hasInvalidState(this.validity); + }, + hasInvalidState : function(validity){ + return validity.typeMismatch + || validity.rangeUnderflow + || validity.rangeOverflow + || validity.stepMismatch + || validity.tooLong + || validity.patternMismatch + || validity.valueMissing + || validity.customError; + }, + createValidityState : function(){ + return { + typeMismatch : false, + rangeUnderflow : false, + rangeOverflow : false, + stepMismatch : false, + tooLong : false, + patternMismatch : false, + valueMissing : false, + customError : false, + valid : true + }; + }, + + //## Default action functions for invalid events ################################################## + + invalidIndicators : [], + indicatorTimeoutId : null, + indicatorIntervalId : null, + + stepUnits : { + 'datetime' : 'second', + 'datetime-local': 'second', + 'time': 'second', + 'date': 'day', + 'week': 'week', + 'month': 'month' + }, + + invalidMessages : { + valueMissing : 'Please fill out this field.', + typeMismatch : 'Please enter a valid %s.', + rangeUnderflow : 'The value must be equal to or greater than %s.', + rangeOverflow : 'The value must be equal to or less than %s.', + stepMismatch : 'The value has a step mismatch; it must be a certain number multiples of %s from %s.', + tooLong : 'The value is too long. The field may have a maximum of %s characters but you supplied %s. Note that each line-break counts as two characters.', + patternMismatch: 'Please match the requested format.' + }, + + valueToWF2Type : function(value, type){ + switch(String(type).toLowerCase()){ + case 'datetime': + case 'datetime-local': + case 'date': + case 'month': + case 'week': + case 'time': + return $wf2.dateToISO8601(value, type); + default: + return value; + } + }, + + addInvalidIndicator : function(target){ + //show contextual help message + var msg = document.createElement('div'); + msg.className = 'wf2_errorMsg'; + + /* Let's put in a container in here so IE9- can put a gradient filter in here. */ + var msgContainer = document.createElement('div'); + msgContainer.className = 'wf2_errorMsgContainer'; + msg.appendChild(msgContainer); + + + //msg.title = "Close"; + msg.id = (target.id || target.name) + '_wf2_errorMsg'; //QUESTION: does this work for MSIE? + msg.onmousedown = function(){ + this.parentNode.removeChild(this); + }; + //var type = String(target.getAttribute('type')).toLowerCase(); + //var type = (target.type ? target.type.toLowerCase() : (target.nodeName.toLowerCase() == 'input' ? 'text' : '')); + var type = (target.getAttribute('type') ? target.getAttribute('type').toLowerCase() : target.type); + var isDateTimeRelated = (type == 'datetime' || type == 'datetime-local' || type == 'time' || type == 'date' || type == 'month' || type == 'week'); + + var ol = document.createElement('ol'); + if(target.validity.customError) { + ol.appendChild($wf2.createLI(target.validationMessage)); + } else { + if(target.validity.valueMissing) + ol.appendChild($wf2.createLI($wf2.invalidMessages.valueMissing)); + if(target.validity.typeMismatch) + ol.appendChild($wf2.createLI($wf2.invalidMessages.typeMismatch.replace(/%s/, type))); + if(target.validity.rangeUnderflow) + ol.appendChild($wf2.createLI($wf2.invalidMessages.rangeUnderflow.replace(/%s/, $wf2.valueToWF2Type(target.min, type)))); + if(target.validity.rangeOverflow) + ol.appendChild($wf2.createLI($wf2.invalidMessages.rangeOverflow.replace(/%s/, $wf2.valueToWF2Type(target.max, type)))); + if(target.validity.stepMismatch) + ol.appendChild($wf2.createLI($wf2.invalidMessages.stepMismatch.replace(/%s/, target.step + ($wf2.stepUnits[type] ? ' ' + $wf2.stepUnits[type] + '(s)' : '')).replace(/%s/, $wf2.valueToWF2Type(target.wf2StepDatum, type)))); + if(target.validity.tooLong) + ol.appendChild($wf2.createLI($wf2.invalidMessages.tooLong.replace(/%s/, target.maxLength).replace(/%s/, target.wf2ValueLength ? target.wf2ValueLength : target.value.length))); + if(target.validity.patternMismatch) + ol.appendChild($wf2.createLI($wf2.invalidMessages.patternMismatch.replace(/%s/, target.title ? target.title : ' "' + target.getAttribute('pattern') + '"'))); + } + + if(ol.childNodes.length == 1) + ol.className = 'single'; + + msgContainer.appendChild(ol); + ////remove existing error message + //if(document.getElementById(msg.id)) + // document.documentElement.removeChild(document.getElementById(msg.id)); + //target.parentNode.insertBefore(msg, target); //Inserting error message next to element in question causes problems when the element has a positioned containing block + var parent = document.body ? document.body : document.documentElement; + if($wf2.invalidIndicators.length) //insert before other error messages so that it appears on top + parent.insertBefore(msg, $wf2.invalidIndicators[$wf2.invalidIndicators.length-1].errorMsg); + else //insert at the end of the document + parent.insertBefore(msg, null); + //target.wf2_errorMsg = msg; + //if(target.style.display == 'none' || !target.offsetParent){ + // var prevEl = target.previousSibling; + // var nextEl = target.nextSibling; + // var prevCount = 0, nextCount = 0; + // while(prevEl && (prevEl.nodeType != 1 || (prevEl.style.display == 'none' || !prevEl.offsetParent)) && ++prevCount) + // prevEl = prevEl.previousSibling; + // while(nextEl && (nextEl.nodeType != 1 || (nextEl.style.display == 'none' || !nextEl.offsetParent)) && ++nextCount) + // nextEl = nextEl.nextSibling; + // + // if(prevEl && prevCount > nextCount) + // + //} + var el = target; + while(el && (el.nodeType != 1 || (el.style.display == 'none' || el.style.visibility == 'hidden' || !el.offsetParent))) + el = el.parentNode; + + var top = left = 0; + var cur = el; + if(cur && cur.offsetParent){ + left = cur.offsetLeft; + top = cur.offsetTop; + while(cur = cur.offsetParent){ + left += cur.offsetLeft; + top += cur.offsetTop; + } + top += el.offsetHeight; + } + msg.style.top = top + 'px'; + msg.style.left = left + 'px'; + + $wf2.invalidIndicators.push({ + target : target, + errorMsg : msg + }); + //if(target.form && target.form[target.name]){ + // target.form[target.name].wf2HasInvalidIndicator = true; + // console.info('set') + //} + /* if(!target.className.match(/\bwf2_invalid\b/)) + target.className += " wf2_invalid"; */ + $wf2.css.addClass(target, 'wf2_invalid'); + + if($wf2.indicatorIntervalId == null){ + //var i = $wf2.invalidIndicators.length - 1; + $wf2.indicatorIntervalId = setInterval(function(){ + var invalidIndicator; + for(var i = 0; invalidIndicator = $wf2.invalidIndicators[i]; i++){ + + if (!$wf2.css.isMemberOfClass(invalidIndicator.target, 'wf2_invalid')) { + $wf2.css.addClass(invalidIndicator.target, 'wf2_invalid') + } else { + $wf2.css.removeClass(invalidIndicator.target, 'wf2_invalid'); + } + + + /* + if(!invalidIndicator.target.className.match(/\bwf2_invalid\b/)){ + invalidIndicator.target.className += " wf2_invalid"; + } + else { + invalidIndicator.target.className = invalidIndicator.target.className.replace(/\s?wf2_invalid/, ""); + } */ + } + + }, 500); + return; + // call routines other libraries have set to be run before + // validation. + setTimeout(function() { + for (var i=0; i<$wf2.callAfterValidation.length; i++) { + $wf2.callAfterValidation[i](null, false); + } + }, 1); + $wf2.indicatorTimeoutId = setTimeout($wf2.clearInvalidIndicators, 4000); + } + + }, + + clearInvalidIndicators : function(){ + clearTimeout($wf2.indicatorTimeoutId); + $wf2.indicatorTimeoutId = null; + clearInterval($wf2.indicatorIntervalId); + $wf2.indicatorIntervalId = null; + + var invalidIndicator; + while(invalidIndicator = $wf2.invalidIndicators[0]){ + if(invalidIndicator.errorMsg && invalidIndicator.errorMsg.parentNode) + invalidIndicator.errorMsg.parentNode.removeChild(invalidIndicator.errorMsg); + //clearInterval(insts[0].intervalId); + var target = invalidIndicator.target; + + // Removed by ZOLTAN. + // target.className = target.className.replace(/\s?wf2_invalid/, ""); //([^\b]\s)? + $wf2.invalidIndicators.shift(); + } + + }, + + /*############################################################################################## + # Other helper functions (not made into methods) + ##############################################################################################*/ + + cloneNode_customAttrs : { //FOR MSIE BUG: it cannot perceive the attributes that were actually specified + 'type':1,'template':1,'repeat':1,'repeat-template':1,'repeat-min':1, + 'repeat-max':1,'repeat-start':1,'value':1,'class':1,'required':1, + 'pattern':1,'form':1,'autocomplete':1,'autofocus':1,'inputmode':1, + 'max':1,'min':1,'step':1, + onmoved:1,onadded:1,onremoved:1, + onadd:1,onremove:1,onmove:1 //deprecated + }, + cloneNode_skippedAttrs : { + 'name':1, //due to MSIE bug, set via $wf2.createElement + 'class':1, //due to MSIE bug, set below (see http://www.alistapart.com/articles/jslogging) + 'for':1, //due to preceived MSIE bug, set below + 'style':1, //inline styles require special handling + 'checked':1, //set by $wf2.createElement due to MSIE bug creating INPUT@type=radio + + //for MSIE, properties (or methods) == attributes + addRepetitionBlock:1,addRepetitionBlockByIndex:1,moveRepetitionBlock:1, + removeRepetitionBlock:1, repetitionBlocks:1, + setCustomValidity:1,checkValidity:1,validity:1,validationMessage:1,willValidate:1, + wf2StepDatum:1,wf2Value:1,wf2Initialized:1,wf2ValueLength:1 + }, + cloneNode_rtEventHandlerAttrs : { + onmoved:1,onadded:1,onremoved:1, //don't copy Repetition old model event attributes not methods + onadd:1,onremove:1,onmove:1 //deprecated + //QUESTION: is this right??? + }, + + //The following cloneNode algorithm was designed to handle the attribute processing that the repetition + // model specifies. Gecko starts to have irratic behavior with a cloned input's value attribute and value + // property when using DOM cloneNode; furthermore, various MSIE bugs prevent its use of DOM cloneNode + cloneNode : function (node, processAttr, rtNestedDepth){ + if(!rtNestedDepth) + rtNestedDepth = 0; + var clone, i, attr; + switch(node.nodeType){ + case 1: /*Node.ELEMENT_NODE*/ + //if(node.nodeType == 1 /*Node.ELEMENT_NODE*/){ + var isTemplate = node.getAttribute('repeat') == 'template'; + if(isTemplate) + rtNestedDepth++; + //BROWSER BUGS: MSIE does not allow the setting of the node.name, except when creating the new node + // MSIE neither permits the standard DOM creation of radio buttons + var attrs = []; + if(node.name) + attrs.name = processAttr ? processAttr(node.name) : node.name; + if(node.type == 'radio') + attrs.type = node.type; + if(node.checked) + attrs.checked = 'checked'; + clone = $wf2.createElement(node.nodeName, attrs); + //clone = node.name ? + // $wf2.createElement(node.nodeName, attrs) + // : document.createElement(node.nodeName); + + for(i = 0; attr = node.attributes[i]; i++){ + + //MSIE ISSUE: Custom attributes specified do not have .specified property set to true? + //ISSUE: VALUE IS REPEATED IN MSIE WHEN VALUE ATTRIBUTE SET? + //if(attr.specified || node.getAttribute(attr.nodeName)) //$wf2.cloneNode_customAttrs[attr.nodeName] || + // if(window.console && console.info) console.info(node.nodeName + "@" + attr.nodeName + " -- " + attr.specified + " " + node.getAttribute(attr.nodeName) + "(" + typeof node.getAttribute(attr.nodeName) + ")
    "); + + //MSIE needs $wf2.cloneNode_customAttrs[attr.name] test since attr.specified does not work with custom attributes + //If the node is a template, the repetition event handlers should only be copied + // if the template is nested and is being cloned by a parent repetition template. + if((attr.specified || $wf2.cloneNode_customAttrs[attr.name]) + && !$wf2.cloneNode_skippedAttrs[attr.name] && ( + (!isTemplate || (rtNestedDepth > 1 || !$wf2.cloneNode_rtEventHandlerAttrs[attr.name])) // && + )) + { + + //MSIE BUG: when button[type=add|remove|move-up|move-down], then (attr.nodeValue and attr.value == 'button') but node.getAttribute(attr.nodeName) == 'add|remove|move-up|move-down' (as desired) + + //clone and process an event handler property (attribute); + // keep event handler attributes as plain text if nested repetition template + if(rtNestedDepth < 2 && (attr.name.indexOf('on') === 0) && (typeof node[attr.name] == 'function')){ + var funcBody = processAttr(node[attr.name].toString().match(/{((?:.|\n)+)}/)[1]); + funcBody = processAttr(funcBody); + clone[attr.name] = new Function('event', funcBody); + } + //clone and process other attributes + else { + var attrValue = node.getAttribute(attr.name); + attrValue = (processAttr ? processAttr(attrValue) : attrValue); + clone.setAttribute(attr.name, attrValue); + } + //console.log(StringHelpers.sprintf("AFTER attr: %s val: %s (%s)", attr.name, attr.value, processAttr(attrValue))) + } + } + //MSIE BUG: setAttribute('class') creates duplicate value attribute in MSIE; + //QUESTION: will setting className on this clonedNode still cause this error later on for users? will addClassName croak? Should it be improved? + //see: http://www.alistapart.com/articles/jslogging + if(node.className){ + var _className = (processAttr ? processAttr(node.className) : node.className); + if(clone.getAttributeNode('class')){ + for(i = 0; i < clone.attributes.length; i++) { + if(clone.attributes[i].name == 'class') + clone.attributes[i].value = _className; + } + } + else clone.setAttribute('class', _className); + } + + //Restore the template's elements to the originally coded disabled state (indicated by 'disabled' class name) + // All elements within the repetition template are disabled to prevent them from being successful. + if(!/\bdisabled\b/.test(node.className)) + clone.disabled = false; + + //Process the inline style + if(node.style && node.style.cssText){ + //clone.setAttribute('style', processAttr(node.style.cssText)); + clone.style.cssText = (processAttr ? processAttr(node.style.cssText) : node.style.cssText); + } + + //label's 'for' attribute, set here due to MSIE bug + if(node.nodeName && node.nodeName.toLowerCase() == 'label' && node.htmlFor) + clone.htmlFor = (processAttr ? processAttr(node.htmlFor) : node.htmlFor); + + + if(clone.nodeName.toLowerCase() == 'option'){ //MSIE clone element bug requires this + clone.selected = node.selected; + clone.defaultSelected = node.defaultSelected; + } + + for(i = 0; i < node.childNodes.length; i++){ + clone.appendChild($wf2.cloneNode(node.childNodes[i], processAttr, rtNestedDepth)); + } + break; + //MSIE BUG: The following three cases are for MSIE because when cloning nodes from XML + // files loaded via SELECT@data attribute, MSIE fails when performing appendChild. + case 3: /*Node.TEXT_NODE*/ + case 4: /*Node.CDATA_SECTION_NODE*/ + clone = document.createTextNode(node.data); + break; + case 8: /*Node.COMMENT_NODE*/ + clone = document.createComment(node.data); + break; + default: + clone = node.cloneNode(true) + } + //else clone = node.cloneNode(true); + return clone; + }, + + getFormElements : function(){ + var elements = []; + var allElements = $wf2.getElementsByTagNames.apply(this, ['input','output','select','textarea','button']); //fieldset + for(var i = 0; i < allElements.length; i++){ + var node = allElements[i].parentNode; + while(node && node.nodeType == 1 && node.getAttribute('repeat') != 'template') + node = node.parentNode; + if(!node || node.nodeType != 1) + elements.push(allElements[i]); + } + return elements; + }, + + loadDataURI : function(el){ + var uri = el.data || el.getAttribute('data'); + if(!uri) + return null; + var doc = null, matches; + try { + if(matches = uri.match(/^data:[^,]*xml[^,]*,((?:.|\n)+)/)){ + var xml = decodeURI(matches[1].replace(/%3D/ig, '=').replace(/%3A/ig, ':').replace(/%2F/ig, '/')); + if(window.DOMParser){ + var parser = new DOMParser(); + doc = parser.parseFromString(xml, 'text/xml'); + } + else if(window.ActiveXObject){ + doc = new ActiveXObject("Microsoft.XMLDOM"); + doc.async = 'false'; + doc.loadXML(xml); + } + } + else { + $wf2.xhr.open('GET', uri, false); + $wf2.xhr.send(null); //Note: if in Firefox and null not provided, and if Firebug is disabled, an error occurs + doc = $wf2.xhr.responseXML; + } + } + catch(e){ + return null; + } + return doc; + }, + + getAttributeByName: function (obj, attrName) { + var i; + + var attributes = obj.attributes; + for (i=0; i + if(el.currentStyle) + return el.currentStyle[property]; + else if(window.getComputedStyle) + return getComputedStyle(el, '').getPropertyValue(property); + else if(el.style) + return el.style[property]; + else return ''; + }, + + //createElement code based on Anthony Lieuallen's work + // The following function enables MSIE to create elements with the name attribute set, per MSDN: + // The NAME attribute cannot be set at run time on elements dynamically created with the + // createElement method. To create an element with a name attribute, include the attribute + // and value when using the createElement method. + // The same goes for creating radio buttons and creating defaultly checked checkboxes, + // per + createElement : (function(){ + try { + var el = document.createElement('
    '); //MSIE memory leak according to Drip + if(el.tagName.toLowerCase() != 'div' || el.name != 'foo') + throw 'create element error'; + + return function(tag, attrs){ + var html = '<' + tag; + for(var name in attrs) + html += ' ' + name + '="' + attrs[name] + '"'; + html += '>'; + if(tag.toLowerCase() != 'input') + html += ''; + return document.createElement(html); //'<'+tag+' name="'+name+'">' + }; + } + catch(err){ + return function(tag, attrs){ + var el = document.createElement(tag); + for(var name in attrs) + el.setAttribute(name, attrs[name]); + return el; + }; + } + })(), + + //Sort elements in document order (from ppk) + sortNodes : (function(){ + var n = document.documentElement.firstChild; + if(n.sourceIndex){ + return function (a,b){ + return a.sourceIndex - b.sourceIndex; + }; + } + else if(n.compareDocumentPosition){ + return function (a,b){ + return 3 - (a.compareDocumentPosition(b) & 6); + }; + } + })(), + + //Shortcut to create new list items; used by default invalid event handler in listing the errors + createLI : function(text){ + var li = document.createElement('li'); + li.appendChild(document.createTextNode(text)); + return li; + }, + + //Initially inspired by Paul Sowden + ISO8601RegExp : /^(?:(\d\d\d\d)-(W(0[1-9]|[1-4]\d|5[0-2])|(0\d|1[0-2])(-(0\d|[1-2]\d|3[0-1])(T(0\d|1\d|2[0-4]):([0-5]\d)(:([0-5]\d)(\.(\d+))?)?(Z)?)?)?)|(0\d|1\d|2[0-4]):([0-5]\d)(:([0-5]\d)(\.(\d+))?)?)$/, + parseISO8601 : function (str, type) { + var d = $wf2.validateDateTimeType(str, type); + if(!d) + return null; + + var date = new Date(0); + var _timePos = 8; + + if(d[15]){ //Time + if(type && type != 'time') // a time date + return null; + _timePos = 15; + } + else { + date.setUTCFullYear(d[1]); + + //ISO8601 Week + if(d[3]){ + if(type && type != 'week') + return null; + date.setUTCDate(date.getUTCDate() + ((8 - date.getUTCDay()) % 7) + (d[3]-1)*7); //set week day and week + return date; + } + //Other date-related types + else { + date.setUTCMonth(d[4] - 1); //Month must be supplied for WF2 + if(d[6]) + date.setUTCDate(d[6]); + } + } + + //Set time-related fields + if(d[_timePos+0]) date.setUTCHours(d[_timePos+0]); + if(d[_timePos+1]) date.setUTCMinutes(d[_timePos+1]); + if(d[_timePos+2]) date.setUTCSeconds(d[_timePos+3]); + if(d[_timePos+4]) date.setUTCMilliseconds(Math.round(Number(d[_timePos+4]) * 1000)); + + //Set to local time if date given, hours present and no 'Z' provided + if(d[4] && d[_timePos+0] && !d[_timePos+6]) + date.setUTCMinutes(date.getUTCMinutes()+date.getTimezoneOffset()); + + return date; + }, + + validateDateTimeType : function(value, type){ //returns RegExp matches + var isValid = false; + var d = $wf2.ISO8601RegExp.exec(value); //var d = string.match(new RegExp(regexp)); + if(!d || !type) + return d; + type = type.toLowerCase(); + + if(type == 'week') // a week date + isValid = (d[2].toString().indexOf('W') === 0); //valid if W present + else if(type == 'time') // a time date + isValid = !!d[15]; + else if(type == 'month') + isValid = !d[5]; + else { //a date related value + //Verify that the number of days in the month are valid + if(d[6]){ + var date = new Date(d[1], d[4]-1, d[6]); + if(date.getMonth() != d[4]-1) + isValid = false; + else switch(type){ + case 'date': + isValid = (d[4] && !d[7]); //valid if day of month supplied and time field not present + break; + case 'datetime': + isValid = !!d[14]; //valid if Z present + break; + case 'datetime-local': + isValid = (d[7] && !d[14]); //valid if time present and Z not provided + break; + } + } + } + return isValid ? d : null; + }, + + zeroPad : function(num, pad){ + if(!pad) + pad = 2; + var str = num.toString(); + while(str.length < pad) + str = '0' + str; + return str; + }, + + dateToISO8601 : function(date, type){ + type = String(type).toLowerCase(); + var ms = ''; + if(date.getUTCMilliseconds()) + ms = '.' + $wf2.zeroPad(date.getUTCMilliseconds(), 3).replace(/0+$/,''); + switch(type){ + case 'date': + return date.getUTCFullYear() + '-' + $wf2.zeroPad(date.getUTCMonth()+1) + '-' + $wf2.zeroPad(date.getUTCDate()); + case 'datetime-local': + return date.getFullYear() + '-' + $wf2.zeroPad(date.getMonth()+1) + '-' + $wf2.zeroPad(date.getDate()) + + 'T' + $wf2.zeroPad(date.getHours()) + ':' + $wf2.zeroPad(date.getMinutes()) + ':' + $wf2.zeroPad(date.getMinutes()) + ms + 'Z'; + case 'month': + return date.getUTCFullYear() + '-' + $wf2.zeroPad(date.getUTCMonth()+1); + case 'week': + var week1 = $wf2.parseISO8601(date.getUTCFullYear() + '-W01'); + return date.getUTCFullYear() + '-W' + $wf2.zeroPad(((date.valueOf() - week1.valueOf()) / (7*24*60*60*1000)) + 1); + case 'time': + return $wf2.zeroPad(date.getUTCHours()) + ':' + $wf2.zeroPad(date.getUTCMinutes()) + ':' + $wf2.zeroPad(date.getUTCMinutes()) + ms; + case 'datetime': + default: + return date.getUTCFullYear() + '-' + $wf2.zeroPad(date.getUTCMonth()+1) + '-' + $wf2.zeroPad(date.getUTCDate()) + + 'T' + $wf2.zeroPad(date.getUTCHours()) + ':' + $wf2.zeroPad(date.getUTCMinutes()) + ':' + $wf2.zeroPad(date.getUTCMinutes()) + ms + 'Z'; + } + }, + + /* + * Fires an event manually. + * @author Scott Andrew - http://www.scottandrew.com/weblog/articles/cbs-events + * @author John Resig - http://ejohn.org/projects/flexible-javascript-events/ + * @param {Object} obj - a javascript object. + * @param {String} evType - an event attached to the object. + * @param {Function} fn - the function that is called when the event fires. + * + */ + fireEvent: function (element, event, options){ + + if(!element) { + return; + } + + if (document.createEventObject){ + return element.fireEvent('on' + event, $wf2.globalEvent); + } else{ + // dispatch for firefox + others + $wf2.globalEvent.initEvent(event, true, true); // event type,bubbling,cancelable + return !element.dispatchEvent($wf2.globalEvent); + } + }, + + //Emulation of DOMException + DOMException : function(code){ + var message = 'DOMException: '; + switch(code){ + case 1: message += 'INDEX_SIZE_ERR'; break; + case 9: message += 'NOT_SUPPORTED_ERR'; break; + case 11: message += 'INVALID_STATE_ERR'; break; + case 12: message += 'SYNTAX_ERR'; break; + case 13: message += 'INVALID_MODIFICATION_ERR'; break; + } + + var err = new Error(message); + err.code = code; + err.name = 'DOMException'; + + //Provide error codes and messages for the exception types that are raised by WF2 + err.INDEX_SIZE_ERR = 1; + err.NOT_SUPPORTED_ERR = 9; + err.INVALID_STATE_ERR = 11; + err.SYNTAX_ERR = 12; + err.INVALID_MODIFICATION_ERR = 13; + + //with($wf2.DOMException.prototype){ + // INDEX_SIZE_ERR = 1; + // DOMSTRING_SIZE_ERR = 2; + // HIERARCHY_REQUEST_ERR = 3; + // WRONG_DOCUMENT_ERR = 4; + // INVALID_CHARACTER_ERR = 5; + // NO_DATA_ALLOWED_ERR = 6; + // NO_MODIFICATION_ALLOWED_ERR = 7; + // NOT_FOUND_ERR = 8; + // NOT_SUPPORTED_ERR = 9; + // INUSE_ATTRIBUTE_ERR = 10; + // INVALID_STATE_ERR = 11; + // SYNTAX_ERR = 12; + // INVALID_MODIFICATION_ERR = 13; + // NAMESPACE_ERR = 14; + // INVALID_ACCESS_ERR = 15; + //}; + + return err; + }, + + css: new function () { + var me = this; + + var blankRe = new RegExp('\\s'); + + /** + * Generates a regular expression string that can be used to detect a class name + * in a tag's class attribute. It is used by a few methods, so I + * centralized it. + * + * @param {String} className - a name of a CSS class. + */ + + function getClassReString(className) { + return '\\s'+className+'\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className +'$'; + } + + function getClassPrefixReString(className) { + return '\\s'+className+'-[0-9a-zA-Z_]+\\s|^' + className + '[0-9a-zA-Z_]+\\s|\\s' + className + '[0-9a-zA-Z_]+$|' + '^' + className +'[0-9a-zA-Z_]+$'; + } + + + /** + * Make an HTML object be a member of a certain class. + * + * @param {Object} obj - an HTML object + * @param {String} className - a CSS class name. + */ + me.addClass = function (obj, className) { + + if (blankRe.test(className)) { + return; + } + + // only add class if the object is not a member of it yet. + if (!me.isMemberOfClass(obj, className)) { + obj.className += " " + className; + } + + } + + /** + * Make an HTML object *not* be a member of a certain class. + * + * @param {Object} obj - an HTML object + * @param {Object} className - a CSS class name. + */ + me.removeClass = function (obj, className) { + + if (blankRe.test(className)) { + return; + } + + + var re = new RegExp(getClassReString(className) , "g"); + + var oldClassName = obj.className; + + + if (obj.className) { + obj.className = oldClassName.replace(re, ' '); + } + + + } + + /** + * Determines if an HTML object is a member of a specific class. + * @param {Object} obj - an HTML object. + * @param {Object} className - the CSS class name. + */ + me.isMemberOfClass = function (obj, className) { + + if (blankRe.test(className)) + return false; + + var re = new RegExp(getClassReString(className) , "g"); + + return (re.test(obj.className)); + + + } + } +}; //End $wf2 = { + + +/*############################################################################################## + # Section: Repetition Model Definitions + ##############################################################################################*/ + +var RepetitionElement = { + REPETITION_NONE:0, + REPETITION_TEMPLATE:1, + REPETITION_BLOCK:2 +}; + +var RepetitionEvent = { + //the following takes a UIEvent and adds the required properties for a RepetitionEvent + _upgradeEvent : function(){ + this.initRepetitionEvent = RepetitionEvent.initRepetitionEvent; + this.initRepetitionEventNS = RepetitionEvent.initRepetitionEventNS; + }, + initRepetitionEvent : function(typeArg, canBubbleArg, cancelableArg, elementArg){ + if(this.initEvent) + this.initEvent(typeArg, canBubbleArg, cancelableArg); + else { //manually initialize event (i.e., for MSIE) + this.type = typeArg; + // switch(typeArg.toLowerCase()){ + // case 'added': + // this.type = 'add'; + // break; + // case 'removed': + // this.type = 'remove'; + // break; + // case 'moved': + // this.type = 'move'; + // break; + // } + //this.srcElement = elementArg.repetitionTemplate; + //this.cancelBubble = false; + //this.cancelable = cancelableArg; + //this.returnValue = false; + + if(!this.preventDefault) + this.preventDefault = function(){ + this.returnValue = false; + }; + if(!this.stopPropagation) + this.stopPropagation = function(){ + this.cancelBubble = true; + }; + } + this.element = elementArg; + this.relatedNode = elementArg; //for Opera (deprecated?) + }, + initRepetitionEventNS : function(namespaceURIArg, typeArg, canBubbleArg, cancelableArg, elementArg){ + throw Error("NOT IMPLEMENTED: RepetitionEvent.initRepetitionEventNS"); + //this.initEvent(namespaceURIArg, typeArg, canBubbleArg, cancelableArg); + //this.element = elementArg; + //this.relatedNode = elementArg; //for Opera (deprecated?) + } +}; + +/*############################################################################################## + # Change the prototypes of HTML elements + ##############################################################################################*/ + +//RepetitionElement interface must be implemented by all elements. +if(window.Element && Element.prototype){ + Element.prototype.REPETITION_NONE = RepetitionElement.REPETITION_NONE; + Element.prototype.REPETITION_TEMPLATE = RepetitionElement.REPETITION_TEMPLATE; + Element.prototype.REPETITION_BLOCK = RepetitionElement.REPETITION_BLOCK; + + Element.prototype.repetitionType = RepetitionElement.REPETITION_NONE; + Element.prototype.repetitionIndex = 0; + Element.prototype.repetitionTemplate = null; /*readonly*/ + Element.prototype.repetitionBlocks = null; /*readonly*/ + + Element.prototype.repeatStart = 1; + Element.prototype.repeatMin = 0; + Element.prototype.repeatMax = Number.MAX_VALUE; //Infinity; + + Element.prototype.addRepetitionBlock = $wf2.addRepetitionBlock; + Element.prototype.addRepetitionBlockByIndex = $wf2.addRepetitionBlockByIndex; + Element.prototype.moveRepetitionBlock = $wf2.moveRepetitionBlock; + Element.prototype.removeRepetitionBlock = $wf2.removeRepetitionBlock; +} + +/*############################################################################################## + # Set mutation event handlers to automatically add WF2 behaviors + ##############################################################################################*/ + +//When a form control is inserted into a document, the UA must check to see if it has [the autofocus] +// attribute set. If it does, and the control is not disabled, and it is of a type normally +// focusable in the user's operating environment, then the UA should focus the control, as if +// the control's focus() method was invoked. UAs with a viewport should also scroll the document +// enough to make the control visible, even if it is not of a type normally focusable. +//REVISE: there should be one handler for all attr events on the page. +if(document.addEventListener){ + document.addEventListener('DOMNodeInsertedIntoDocument', function(evt){ //DOMNodeInserted? DOMNodeInsertedIntoDocument + if(evt.target.nodeType == 1 && evt.target.hasAttribute('autofocus')){ + $wf2.initAutofocusElement(evt.target); + } + //[[UAs may ignore this attribute if the user has indicated (for example, by starting to type in a + // form control) that he does not wish focus to be changed.]] + }, false); + + //NOT CURRENTLY IMPLEMENTABLE: + // Setting the DOM attribute to true must set the content attribute to the value autofocus. + // Setting the DOM attribute to false must remove the content attribute. + + document.addEventListener('DOMAttrModified', function(evt){ + //The autofocus DOM attribute must return true when the content attribute is present (regardless + // of its value, even if it is the empty string), and false when it is absent. + if(evt.attrName == 'autofocus'){ + if(evt.attrChange == evt.ADDITION) + //evt.relatedNode.autofocus = true; + $wf2.initAutofocusElement(evt.target); + else if(evt.attrChange == evt.REMOVAL) + evt.target.autofocus = false; + } + }, false); +} + +/*################################################################################## + # Execute WF2 code onDOMContentLoaded + # Some of the following code was borrowed from Dean Edwards, John Resig, et al + ##################################################################################*/ + +(function(){ +//Get the path to the library base directory +var match; +//For some reason, if not using documentElement, scriptaculous fails to load if reference to +// webforms2 script placed beforehand in Firefox +var scripts = document.documentElement.getElementsByTagName('script'); +for(var i = 0; i < scripts.length; i++){ + if(match = scripts[i].src.match(/^(.*)webforms2[^\/]+$/)) + $wf2.libpath = match[1]; +} + +//The script has been included after the DOM has loaded (perhaps via Greasemonkey), so fire immediately +//NOTE: This does not work with XHTML documents in Gecko +if(document.body){ + $wf2.onDOMContentLoaded(); + return; +} + +var eventSet = 0; +if(document.addEventListener){ + //for Gecko and Opera + document.addEventListener('DOMContentLoaded', function(){ + $wf2.onDOMContentLoaded(); + }, false); + + //for other browsers which do not support DOMContentLoaded use the following as a fallback to be called hopefully before all other onload handlers + window.addEventListener('load', function(){ + $wf2.onDOMContentLoaded(); + }, false); + + eventSet = 1; +} + +//for Safari +if (/WebKit/i.test(navigator.userAgent)) { //sniff + var _timer = setInterval(function() { + if (/loaded|complete/.test(document.readyState)) { + clearInterval(_timer); + delete _timer; + $wf2.onDOMContentLoaded(); + } + }, 10); + eventSet = 1; +} +//for Internet Explorer (formerly using conditional comments) //sniff +else if(/MSIE/i.test(navigator.userAgent) && !document.addEventListener && window.attachEvent){ + //This following attached onload handler will attempt to be the first onload handler to be called and thus + // initiate the repetition model as early as possible if the DOMContentLoaded substitute fails. + window.attachEvent('onload', function(){ + $wf2.onDOMContentLoaded(); + }); + + //Dean Edward's first solution: http://dean.edwards.name/weblog/2005/09/busted/ + //document.getElementsByTagName('*')[0].addBehavior(dirname + 'repetition-model.htc'); //use this if Behaviors are employed in 0.9 + document.write(" + + + +//$.webshims.polyfill('forms-ext'); + {% endblock %} From 1360d84d86f73bec32e38373e20a43cbac8ef7e9 Mon Sep 17 00:00:00 2001 From: Sanjay B Date: Mon, 23 Sep 2013 00:34:05 +0530 Subject: [PATCH 4/4] add modernizr --- itf/static/js/modernizr.js | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 itf/static/js/modernizr.js diff --git a/itf/static/js/modernizr.js b/itf/static/js/modernizr.js new file mode 100644 index 0000000..0ba6592 --- /dev/null +++ b/itf/static/js/modernizr.js @@ -0,0 +1,4 @@ +/* Modernizr 2.5.3 (Custom Build) | MIT & BSD + * Build: http://www.modernizr.com/download/#-input-inputtypes-shiv-cssclasses-load + */ +;window.Modernizr=function(a,b,c){function v(a){j.cssText=a}function w(a,b){return v(prefixes.join(a+";")+(b||""))}function x(a,b){return typeof a===b}function y(a,b){return!!~(""+a).indexOf(b)}function z(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:x(f,"function")?f.bind(d||b):f}return!1}function A(){e.input=function(c){for(var d=0,e=c.length;d",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return o.call(a)=="[object Function]"}function e(a){return typeof a=="string"}function f(){}function g(a){return!a||a=="loaded"||a=="complete"||a=="uninitialized"}function h(){var a=p.shift();q=1,a?a.t?m(function(){(a.t=="c"?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){a!="img"&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l={},o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};y[c]===1&&(r=1,y[c]=[],l=b.createElement(a)),a=="object"?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),a!="img"&&(r||y[c]===2?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i(b=="c"?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),p.length==1&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&o.call(a.opera)=="[object Opera]",l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return o.call(a)=="[object Array]"},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f

    jscalendar-1.0 +"It is happening again"