webshims-rails 1.11.6.1 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/webshims/polyfiller.js +126 -72
  4. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/canvas2png.js +9 -4
  5. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.js +32 -26
  6. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.swf +0 -0
  7. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/proxy.php +25 -4
  8. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/save.php +9 -3
  9. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/canvas2png.js +9 -4
  10. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  11. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  12. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flashcanvas.js +36 -30
  13. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/proxy.php +25 -4
  14. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/save.php +9 -3
  15. data/vendor/assets/javascripts/webshims/shims/combos/1.js +13 -6
  16. data/vendor/assets/javascripts/webshims/shims/combos/10.js +156 -143
  17. data/vendor/assets/javascripts/webshims/shims/combos/11.js +97 -84
  18. data/vendor/assets/javascripts/webshims/shims/combos/12.js +2 -4
  19. data/vendor/assets/javascripts/webshims/shims/combos/13.js +1 -2
  20. data/vendor/assets/javascripts/webshims/shims/combos/14.js +956 -2819
  21. data/vendor/assets/javascripts/webshims/shims/combos/15.js +73 -67
  22. data/vendor/assets/javascripts/webshims/shims/combos/16.js +75 -71
  23. data/vendor/assets/javascripts/webshims/shims/combos/17.js +118 -89
  24. data/vendor/assets/javascripts/webshims/shims/combos/18.js +119 -91
  25. data/vendor/assets/javascripts/webshims/shims/combos/19.js +62 -65
  26. data/vendor/assets/javascripts/webshims/shims/combos/2.js +73 -67
  27. data/vendor/assets/javascripts/webshims/shims/combos/20.js +61 -63
  28. data/vendor/assets/javascripts/webshims/shims/combos/21.js +3 -6
  29. data/vendor/assets/javascripts/webshims/shims/combos/22.js +1 -2
  30. data/vendor/assets/javascripts/webshims/shims/combos/23.js +1 -2
  31. data/vendor/assets/javascripts/webshims/shims/combos/24.js +22 -12
  32. data/vendor/assets/javascripts/webshims/shims/combos/25.js +63 -67
  33. data/vendor/assets/javascripts/webshims/shims/combos/26.js +59 -59
  34. data/vendor/assets/javascripts/webshims/shims/combos/27.js +1 -2
  35. data/vendor/assets/javascripts/webshims/shims/combos/28.js +1915 -0
  36. data/vendor/assets/javascripts/webshims/shims/combos/29.js +817 -0
  37. data/vendor/assets/javascripts/webshims/shims/combos/3.js +71 -63
  38. data/vendor/assets/javascripts/webshims/shims/combos/30.js +72 -65
  39. data/vendor/assets/javascripts/webshims/shims/combos/31.js +71 -63
  40. data/vendor/assets/javascripts/webshims/shims/combos/32.js +2343 -0
  41. data/vendor/assets/javascripts/webshims/shims/combos/33.js +897 -0
  42. data/vendor/assets/javascripts/webshims/shims/combos/4.js +59 -59
  43. data/vendor/assets/javascripts/webshims/shims/combos/5.js +119 -91
  44. data/vendor/assets/javascripts/webshims/shims/combos/6.js +120 -93
  45. data/vendor/assets/javascripts/webshims/shims/combos/7.js +74 -69
  46. data/vendor/assets/javascripts/webshims/shims/combos/8.js +73 -67
  47. data/vendor/assets/javascripts/webshims/shims/combos/9.js +157 -145
  48. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +58 -57
  49. data/vendor/assets/javascripts/webshims/shims/form-combat.js +0 -1
  50. data/vendor/assets/javascripts/webshims/shims/form-core.js +12 -3
  51. data/vendor/assets/javascripts/webshims/shims/form-datalist-lazy.js +4 -3
  52. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +20 -3
  53. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +78 -71
  54. data/vendor/assets/javascripts/webshims/shims/form-shim-extend2.js +21 -10
  55. data/vendor/assets/javascripts/webshims/shims/form-validation.js +39 -27
  56. data/vendor/assets/javascripts/webshims/shims/forms-picker.js +173 -128
  57. data/vendor/assets/javascripts/webshims/shims/i18n/{formcfg-ch-ZN.js → formcfg-ch-CN.js} +0 -0
  58. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-en.js +0 -2
  59. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-zh-CN.js +65 -0
  60. data/vendor/assets/javascripts/webshims/shims/plugins/jquery.ui.position.js +1 -1
  61. data/vendor/assets/javascripts/webshims/shims/range-ui.js +18 -11
  62. data/vendor/assets/javascripts/webshims/shims/styles/forms-ext.css +221 -153
  63. data/vendor/assets/javascripts/webshims/shims/styles/progress.gif +0 -0
  64. data/vendor/assets/javascripts/webshims/shims/styles/progress.png +0 -0
  65. data/vendor/assets/javascripts/webshims/shims/styles/scss/_extends.scss +5 -0
  66. data/vendor/assets/javascripts/webshims/shims/styles/scss/forms-ext.scss +273 -177
  67. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +113 -98
  68. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +114 -88
  69. data/vendor/assets/javascripts/webshims/shims/track-ui.js +2 -2
  70. metadata +10 -7
  71. data/vendor/assets/javascripts/webshims/extras/mousepress.js +0 -60
  72. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Thumbs.db +0 -0
  73. data/vendor/assets/javascripts/webshims/shims/json-storage.js +0 -316
  74. data/vendor/assets/javascripts/webshims/shims/mediagroup.js +0 -29
@@ -40,34 +40,6 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
40
40
  webshims.ready('WINDOWLOAD', switch$);
41
41
 
42
42
  }
43
- // (function(){
44
- // var hostNames = {
45
- // 'afarkas.github.io': 1,
46
- // localhost: 1,
47
- // '127.0.0.1': 1
48
- // };
49
- //
50
- // if( webshims.cfg.debug && (hostNames[location.hostname] || location.protocol == 'file:') ){
51
- // var list = $('<ul class="webshims-debug-list" />');
52
- // webshims.errorLog.push = function(message){
53
- // list.appendTo('body');
54
- // $('<li style="display: none;">'+ message +'</li>')
55
- // .appendTo(list)
56
- // .slideDown()
57
- // .delay(3000)
58
- // .slideUp(function(){
59
- // $(this).remove();
60
- // if(!$('li', list).length){
61
- // list.detach();
62
- // }
63
- // })
64
- // ;
65
- // };
66
- // $.each(webshims.errorLog, function(i, message){
67
- // webshims.errorLog.push(message);
68
- // });
69
- // }
70
- // })();
71
43
 
72
44
  //shortcus
73
45
  var modules = webshims.modules;
@@ -509,11 +481,22 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
509
481
  });
510
482
  },
511
483
  getOptions: (function(){
484
+ var normalName = /\-([a-z])/g;
512
485
  var regs = {};
486
+ var nameRegs = {};
513
487
  var regFn = function(f, upper){
514
488
  return upper.toLowerCase();
515
489
  };
516
- return function(elem, name, bases){
490
+ var nameFn = function(f, dashed){
491
+ return dashed.toUpperCase();
492
+ };
493
+ return function(elem, name, bases, stringAllowed){
494
+ if(nameRegs[name]){
495
+ name = nameRegs[name];
496
+ } else {
497
+ nameRegs[name] = name.replace(normalName, nameFn);
498
+ name = nameRegs[name];
499
+ }
517
500
  var data = elementData(elem, 'cfg'+name);
518
501
  var dataName;
519
502
  var cfg = {};
@@ -522,7 +505,12 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
522
505
  return data;
523
506
  }
524
507
  data = $(elem).data();
525
-
508
+ if(data && typeof data[name] == 'string'){
509
+ if(stringAllowed){
510
+ return elementData(elem, 'cfg'+name, data[name]);
511
+ }
512
+ webshims.error('data-'+ name +' attribute has to be a valid JSON, was: '+ data[name]);
513
+ }
526
514
  if(!bases){
527
515
  bases = [true, {}];
528
516
  } else if(!Array.isArray(bases)){
@@ -531,12 +519,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
531
519
  bases.unshift(true, {});
532
520
  }
533
521
 
534
- if(data && data[name]){
535
- if(typeof data[name] == 'object'){
536
- bases.push(data[name]);
537
- } else {
538
- webshims.error('data-'+ name +' attribute has to be a valid JSON, was: '+ data[name]);
539
- }
522
+ if(data && typeof data[name] == 'object'){
523
+ bases.push(data[name]);
540
524
  }
541
525
 
542
526
  if(!regs[name]){
@@ -549,7 +533,6 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
549
533
  }
550
534
  }
551
535
  bases.push(cfg);
552
-
553
536
  return elementData(elem, 'cfg'+name, $.extend.apply($, bases));
554
537
  };
555
538
  })(),
@@ -579,7 +562,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
579
562
  var resizeTimer;
580
563
  var lastHeight;
581
564
  var lastWidth;
582
-
565
+ var $window = $(window);
583
566
  var docObserve = {
584
567
  init: false,
585
568
  runs: 0,
@@ -599,25 +582,36 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
599
582
  docObserve.runs = 0;
600
583
  }
601
584
  },
602
- handler: function(e){
603
- clearTimeout(resizeTimer);
604
- resizeTimer = setTimeout(function(){
605
- if(e.type == 'resize'){
606
- var width = $(window).width();
607
- var height = $(window).width();
608
- if(height == lastHeight && width == lastWidth){
609
- return;
585
+ handler: (function(){
586
+ var trigger = function(){
587
+ $(document).triggerHandler('updateshadowdom');
588
+ };
589
+ return function(e){
590
+ clearTimeout(resizeTimer);
591
+ resizeTimer = setTimeout(function(){
592
+ if(e.type == 'resize'){
593
+ var width = $window.width();
594
+ var height = $window.width();
595
+
596
+ if(height == lastHeight && width == lastWidth){
597
+ return;
598
+ }
599
+ lastHeight = height;
600
+ lastWidth = width;
601
+
602
+ docObserve.height = docObserve.getHeight();
603
+ docObserve.width = docObserve.getWidth();
604
+ }
605
+
606
+ if(window.requestAnimationFrame){
607
+ requestAnimationFrame(trigger);
608
+ } else {
609
+ setTimeout(trigger, 0);
610
610
  }
611
- lastHeight = height;
612
- lastWidth = width;
613
-
614
- docObserve.height = docObserve.getHeight();
615
- docObserve.width = docObserve.getWidth();
616
611
 
617
- }
618
- $(document).triggerHandler('updateshadowdom');
619
- }, (e.type == 'resize') ? 50 : 9);
620
- },
612
+ }, (e.type == 'resize' && !window.requestAnimationFrame) ? 50 : 0);
613
+ };
614
+ })(),
621
615
  _create: function(){
622
616
  $.each({ Height: "getHeight", Width: "getWidth" }, function(name, type){
623
617
  var body = document.body;
@@ -955,13 +949,17 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
955
949
  webshims.defineNodeNamesProperty(elementNames, prop, {
956
950
  attr: {
957
951
  set: function(val){
958
- this.setAttribute(prop, val);
952
+ if(descs.useContentAttribute){
953
+ webshims.contentAttr(this, prop, val);
954
+ } else {
955
+ this.setAttribute(prop, val);
956
+ }
959
957
  if(descs.set){
960
958
  descs.set.call(this, true);
961
959
  }
962
960
  },
963
961
  get: function(){
964
- var ret = this.getAttribute(prop);
962
+ var ret = (descs.useContentAttribute) ? webshims.contentAttr(this, prop) : this.getAttribute(prop);
965
963
  return (ret == null) ? undefined : prop;
966
964
  }
967
965
  },
@@ -1018,6 +1016,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1018
1016
  });
1019
1017
  }
1020
1018
  };
1019
+
1021
1020
  var select = function(obj){
1022
1021
  var oldLang = obj.__active;
1023
1022
  var selectLang = function(i, lang){
@@ -1025,6 +1024,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1025
1024
  if(obj[lang] || obj.availableLangs.indexOf(lang) != -1){
1026
1025
  if(obj[lang]){
1027
1026
  obj.__active = obj[lang];
1027
+ obj.__activeName = lang;
1028
1028
  } else {
1029
1029
  load(obj.langSrc+lang, obj, curLang.join());
1030
1030
  }
@@ -1034,6 +1034,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1034
1034
  $.each(curLang, selectLang);
1035
1035
  if(!obj.__active){
1036
1036
  obj.__active = obj[''];
1037
+ obj.__activeName = '';
1037
1038
  }
1038
1039
  if(oldLang != obj.__active){
1039
1040
  $(obj).trigger('change');
@@ -1138,8 +1139,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1138
1139
  }
1139
1140
  });
1140
1141
 
1141
- })(webshims.$, document);
1142
- webshims.register('filereader', function( $, webshims ){
1142
+ })(webshims.$, document);;webshims.register('filereader', function( $, webshims ){
1143
1143
  "use strict";
1144
1144
  /**
1145
1145
  * Code is based on https://github.com/Jahdrien/FileReader
@@ -449,8 +449,7 @@ var swfmini = function() {
449
449
  }
450
450
  };
451
451
  }();
452
-
453
- webshims.register('filereader', function( $, webshims ){
452
+ ;webshims.register('filereader', function( $, webshims ){
454
453
  "use strict";
455
454
  /**
456
455
  * Code is based on https://github.com/Jahdrien/FileReader
@@ -0,0 +1,1915 @@
1
+ webshims.register('form-shim-extend', function($, webshims, window, document, undefined, options){
2
+ "use strict";
3
+ webshims.inputTypes = webshims.inputTypes || {};
4
+ //some helper-functions
5
+ var cfg = webshims.cfg.forms;
6
+ var bugs = webshims.bugs;
7
+
8
+ var isNumber = function(string){
9
+ return (typeof string == 'number' || (string && string == string * 1));
10
+ },
11
+ typeModels = webshims.inputTypes,
12
+ checkTypes = {
13
+ radio: 1,
14
+ checkbox: 1
15
+ },
16
+ getType = function(elem){
17
+ return (elem.getAttribute('type') || elem.type || '').toLowerCase();
18
+ }
19
+ ;
20
+
21
+ (function(){
22
+ if('querySelector' in document){
23
+ try {
24
+ bugs.findRequired = !($('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /></form>')[0].querySelector('select:required'));
25
+ } catch(er){
26
+ bugs.findRequired = false;
27
+ }
28
+
29
+ if (bugs.bustedValidity || bugs.findRequired) {
30
+ (function(){
31
+ var find = $.find;
32
+ var matchesSelector = $.find.matchesSelector;
33
+
34
+ var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
35
+ var regFn = function(sel){
36
+ return sel + '-element';
37
+ };
38
+
39
+ $.find = (function(){
40
+ var slice = Array.prototype.slice;
41
+ var fn = function(sel){
42
+ var ar = arguments;
43
+ ar = slice.call(ar, 1, ar.length);
44
+ ar.unshift(sel.replace(regExp, regFn));
45
+ return find.apply(this, ar);
46
+ };
47
+ for (var i in find) {
48
+ if(find.hasOwnProperty(i)){
49
+ fn[i] = find[i];
50
+ }
51
+ }
52
+ return fn;
53
+ })();
54
+ if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
55
+ $.find.matchesSelector = function(node, expr){
56
+ expr = expr.replace(regExp, regFn);
57
+ return matchesSelector.call(this, node, expr);
58
+ };
59
+ }
60
+
61
+ })();
62
+ }
63
+ }
64
+ })();
65
+
66
+ //API to add new input types
67
+ webshims.addInputType = function(type, obj){
68
+ typeModels[type] = obj;
69
+ };
70
+
71
+ //contsrain-validation-api
72
+ var validityPrototype = {
73
+ customError: false,
74
+
75
+ typeMismatch: false,
76
+ badInput: false,
77
+ rangeUnderflow: false,
78
+ rangeOverflow: false,
79
+ stepMismatch: false,
80
+ tooLong: false,
81
+ tooShort: false,
82
+ patternMismatch: false,
83
+ valueMissing: false,
84
+
85
+ valid: true
86
+ };
87
+
88
+ var isPlaceholderOptionSelected = function(select){
89
+ if(select.type == 'select-one' && select.size < 2){
90
+ var option = $('> option:first-child', select);
91
+ return !!option.prop('selected');
92
+ }
93
+ return false;
94
+ };
95
+
96
+ var emptyJ = $([]);
97
+ var getGroupElements = function(elem){
98
+ elem = $(elem);
99
+ var name;
100
+ var form;
101
+ var ret = emptyJ;
102
+ if(elem[0].type == 'radio'){
103
+ form = elem.prop('form');
104
+ name = elem[0].name;
105
+ if(!name){
106
+ ret = elem;
107
+ } else if(form){
108
+ ret = $(form[name]);
109
+ } else {
110
+ ret = $(document.getElementsByName(name)).filter(function(){
111
+ return !$.prop(this, 'form');
112
+ });
113
+ }
114
+ ret = ret.filter('[type="radio"]');
115
+ }
116
+ return ret;
117
+ };
118
+ var patternTypes = {url: 1, email: 1, text: 1, search: 1, tel: 1, password: 1};
119
+ var lengthTypes = $.extend({textarea: 1}, patternTypes);
120
+
121
+ var validityRules = {
122
+ valueMissing: function(input, val, cache){
123
+ if(!input.prop('required')){return false;}
124
+ var ret = false;
125
+ if(!('type' in cache)){
126
+ cache.type = getType(input[0]);
127
+ }
128
+ if(cache.nodeName == 'select'){
129
+ ret = (!val && (input[0].selectedIndex < 0 || isPlaceholderOptionSelected(input[0]) ));
130
+ } else if(checkTypes[cache.type]){
131
+ ret = (cache.type == 'checkbox') ? !input.is(':checked') : !getGroupElements(input).filter(':checked')[0];
132
+ } else {
133
+ ret = !(val);
134
+ }
135
+ return ret;
136
+ },
137
+ patternMismatch: function(input, val, cache) {
138
+ if(val === '' || cache.nodeName == 'select'){return false;}
139
+ if(!('type' in cache)){
140
+ cache.type = getType(input[0]);
141
+ }
142
+ if(!patternTypes[cache.type]){return false;}
143
+ var pattern = input.attr('pattern');
144
+ if(!pattern){return false;}
145
+ try {
146
+ pattern = new RegExp('^(?:' + pattern + ')$');
147
+ } catch(er){
148
+ webshims.error('invalid pattern value: "'+ pattern +'" | '+ er);
149
+ pattern = false;
150
+ }
151
+ if(!pattern){return false;}
152
+ return !(pattern.test(val));
153
+ }
154
+ }
155
+ ;
156
+
157
+ $.each({tooShort: ['minLength', -1], tooLong: ['maxLength', 1]}, function(name, props){
158
+ validityRules[name] = function(input, val, cache){
159
+ //defaultValue is not the same as dirty flag, but very similiar
160
+ if(cache.nodeName == 'select' || input.prop('defaultValue') == val){return false;}
161
+ if(!('type' in cache)){
162
+ cache.type = getType(input[0]);
163
+ }
164
+ if(!lengthTypes[cache.type]){return false;}
165
+ var prop = input.prop(props[0]);
166
+
167
+ return ( prop > 0 && prop * props[1] < val.length * props[1] );
168
+ };
169
+ });
170
+
171
+ $.each({typeMismatch: 'mismatch', badInput: 'bad'}, function(name, fn){
172
+ validityRules[name] = function (input, val, cache){
173
+ if(val === '' || cache.nodeName == 'select'){return false;}
174
+ var ret = false;
175
+ if(!('type' in cache)){
176
+ cache.type = getType(input[0]);
177
+ }
178
+
179
+ if(typeModels[cache.type] && typeModels[cache.type][fn]){
180
+ ret = typeModels[cache.type][fn](val, input);
181
+ } else if('validity' in input[0] && ('name' in input[0].validity)){
182
+ ret = input[0].validity[name] || false;
183
+ }
184
+ return ret;
185
+ };
186
+ });
187
+
188
+ webshims.addValidityRule = function(type, fn){
189
+ validityRules[type] = fn;
190
+ };
191
+
192
+ $.event.special.invalid = {
193
+ add: function(){
194
+ $.event.special.invalid.setup.call(this.form || this);
195
+ },
196
+ setup: function(){
197
+ var form = this.form || this;
198
+ if( $.data(form, 'invalidEventShim') ){
199
+ form = null;
200
+ return;
201
+ }
202
+ $(form)
203
+ .data('invalidEventShim', true)
204
+ .on('submit', $.event.special.invalid.handler)
205
+ ;
206
+ webshims.moveToFirstEvent(form, 'submit');
207
+ if(webshims.bugs.bustedValidity && $.nodeName(form, 'form')){
208
+ (function(){
209
+ var noValidate = form.getAttribute('novalidate');
210
+ form.setAttribute('novalidate', 'novalidate');
211
+ webshims.data(form, 'bustedNoValidate', (noValidate == null) ? null : noValidate);
212
+ })();
213
+ }
214
+ form = null;
215
+ },
216
+ teardown: $.noop,
217
+ handler: function(e, d){
218
+
219
+ if( e.type != 'submit' || e.testedValidity || !e.originalEvent || !$.nodeName(e.target, 'form') || $.prop(e.target, 'noValidate') ){return;}
220
+
221
+ e.testedValidity = true;
222
+ var notValid = !($(e.target).callProp('reportValidity'));
223
+ if(notValid){
224
+ e.stopImmediatePropagation();
225
+ return false;
226
+ }
227
+ }
228
+ };
229
+
230
+ $.event.special.submit = $.event.special.submit || {setup: function(){return false;}};
231
+ var submitSetup = $.event.special.submit.setup;
232
+ $.extend($.event.special.submit, {
233
+ setup: function(){
234
+ if($.nodeName(this, 'form')){
235
+ $(this).on('invalid', $.noop);
236
+ } else {
237
+ $('form', this).on('invalid', $.noop);
238
+ }
239
+ return submitSetup.apply(this, arguments);
240
+ }
241
+ });
242
+ webshims.ready('form-shim-extend2 WINDOWLOAD', function(){
243
+ $(window).on('invalid', $.noop);
244
+ });
245
+
246
+
247
+ webshims.addInputType('email', {
248
+ mismatch: (function(){
249
+ //taken from http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
250
+ var test = cfg.emailReg || /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
251
+ var splitReg = /\s*,\s*/g;
252
+ return function(val, input){
253
+ var ret = false;
254
+ val = $(input).prop('multiple') ? val.split(splitReg) : [val];
255
+
256
+ for(var i = 0; i < val.length; i++){
257
+ if(!test.test(val[i])){
258
+ ret = true;
259
+ break;
260
+ }
261
+ }
262
+ return ret;
263
+ };
264
+ })()
265
+ });
266
+
267
+ webshims.addInputType('url', {
268
+ mismatch: (function(){
269
+ //taken from scott gonzales
270
+ var test = cfg.urlReg || /^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
271
+ return function(val){
272
+ return !test.test(val);
273
+ };
274
+ })()
275
+ });
276
+
277
+ webshims.defineNodeNameProperty('input', 'type', {
278
+ prop: {
279
+ get: function(){
280
+ var elem = this;
281
+ var type = (elem.getAttribute('type') || '').toLowerCase();
282
+ return (webshims.inputTypes[type]) ? type : elem.type;
283
+ }
284
+ }
285
+ });
286
+
287
+ // IDLs for constrain validation API
288
+ //ToDo: add object to this list
289
+ webshims.defineNodeNamesProperties(['button', 'fieldset', 'output'], {
290
+ checkValidity: {
291
+ value: function(){return true;}
292
+ },
293
+ reportValidity: {
294
+ value: function(){return true;}
295
+ },
296
+ willValidate: {
297
+ value: false
298
+ },
299
+ setCustomValidity: {
300
+ value: $.noop
301
+ },
302
+ validity: {
303
+ writeable: false,
304
+ get: function(){
305
+ return $.extend({}, validityPrototype);
306
+ }
307
+ }
308
+ }, 'prop');
309
+
310
+ var baseCheckValidity = function(elem, type){
311
+ var e,
312
+ v = $.prop(elem, 'validity')
313
+ ;
314
+ if(v){
315
+ $.data(elem, 'cachedValidity', v);
316
+ } else {
317
+ return true;
318
+ }
319
+ if( !v.valid ){
320
+ e = $.Event('invalid');
321
+ var jElm = $(elem).trigger(e);
322
+ if(type == 'reportValidity' && !baseCheckValidity.unhandledInvalids && !e.isDefaultPrevented()){
323
+ webshims.validityAlert.showFor(jElm);
324
+ baseCheckValidity.unhandledInvalids = true;
325
+ }
326
+ }
327
+ $.removeData(elem, 'cachedValidity');
328
+ return v.valid;
329
+ };
330
+ var rsubmittable = /^(?:select|textarea|input)/i;
331
+
332
+ ['checkValidity', 'reportValidity'].forEach(function(name){
333
+ webshims.defineNodeNameProperty('form', name, {
334
+ prop: {
335
+ value: function(){
336
+
337
+ var ret = true,
338
+ elems = $($.prop(this, 'elements')).filter(function(){
339
+ if(!rsubmittable.test(this.nodeName)){return false;}
340
+ var shadowData = webshims.data(this, 'shadowData');
341
+ return !shadowData || !shadowData.nativeElement || shadowData.nativeElement === this;
342
+ })
343
+ ;
344
+
345
+ baseCheckValidity.unhandledInvalids = false;
346
+ for(var i = 0, len = elems.length; i < len; i++){
347
+ if( !baseCheckValidity(elems[i], name) ){
348
+ ret = false;
349
+ }
350
+ }
351
+ return ret;
352
+ }
353
+ }
354
+ });
355
+ });
356
+
357
+
358
+
359
+
360
+ ['input', 'textarea', 'select'].forEach(function(nodeName){
361
+ var inputValidationAPI = {
362
+ setCustomValidity: {
363
+ value: function(error){
364
+ $.removeData(this, 'cachedValidity');
365
+ webshims.data(this, 'customvalidationMessage', ''+error);
366
+ if(bugs.bustedValidity && inputValidationAPI.setCustomValidity.prop._supvalue){
367
+ inputValidationAPI.setCustomValidity.prop._supvalue.apply(this, arguments);
368
+ }
369
+ }
370
+ },
371
+ willValidate: {
372
+ writeable: false,
373
+ get: (function(){
374
+ var types = {
375
+ button: 1,
376
+ reset: 1,
377
+ hidden: 1,
378
+ image: 1
379
+ }
380
+ ;
381
+ return function(){
382
+ var elem = $(this).getNativeElement()[0];
383
+ return !!(!elem.readOnly && !types[elem.type] && !$(elem).is(':disabled') );
384
+ };
385
+ })()
386
+ },
387
+ validity: {
388
+ writeable: false,
389
+ get: function(){
390
+ var jElm = $(this).getNativeElement();
391
+ var elem = jElm[0];
392
+ var validityState = $.data(elem, 'cachedValidity');
393
+ if(validityState){
394
+ return validityState;
395
+ }
396
+ validityState = $.extend({}, validityPrototype);
397
+
398
+ if( !$.prop(elem, 'willValidate') || elem.type == 'submit' ){
399
+ return validityState;
400
+ }
401
+ var val = jElm.val(),
402
+ cache = {nodeName: elem.nodeName.toLowerCase()}
403
+ ;
404
+
405
+ validityState.customError = !!(webshims.data(elem, 'customvalidationMessage'));
406
+ if( validityState.customError ){
407
+ validityState.valid = false;
408
+ }
409
+
410
+ $.each(validityRules, function(rule, fn){
411
+ if (fn(jElm, val, cache)) {
412
+ validityState[rule] = true;
413
+ validityState.valid = false;
414
+ }
415
+ });
416
+ $(this).getShadowFocusElement().attr('aria-invalid', validityState.valid ? 'false' : 'true');
417
+ jElm = null;
418
+ elem = null;
419
+ return validityState;
420
+ }
421
+ }
422
+ };
423
+
424
+ ['checkValidity', 'reportValidity'].forEach(function(name){
425
+ inputValidationAPI[name] = {
426
+ value: function(){
427
+ baseCheckValidity.unhandledInvalids = false;
428
+ return baseCheckValidity($(this).getNativeElement()[0], name);
429
+ }
430
+ }
431
+ });
432
+
433
+ webshims.defineNodeNameProperties(nodeName, inputValidationAPI, 'prop');
434
+ });
435
+
436
+
437
+ webshims.defineNodeNamesBooleanProperty(['input', 'textarea', 'select'], 'required', {
438
+ set: function(value){
439
+ $(this).getShadowFocusElement().attr('aria-required', !!(value)+'');
440
+ },
441
+ initAttr: Modernizr.localstorage //only if we have aria-support
442
+ });
443
+ webshims.defineNodeNamesBooleanProperty(['input'], 'multiple');
444
+
445
+ if(bugs.bustedValidity){
446
+
447
+ webshims.defineNodeNameProperty('form', 'novalidate', {
448
+ attr: {
449
+ set: function(val){
450
+ webshims.data(this, 'bustedNoValidate', ''+val);
451
+ },
452
+ get: function(){
453
+ var ret = webshims.data(this, 'bustedNoValidate');
454
+ return ret == null ? undefined : ret;
455
+ }
456
+ },
457
+ removeAttr: {
458
+ value: function(){
459
+ webshims.data(this, 'bustedNoValidate', null);
460
+ }
461
+ }
462
+ });
463
+
464
+ $.each(['rangeUnderflow', 'rangeOverflow', 'stepMismatch'], function(i, name){
465
+ validityRules[name] = function(elem){
466
+ return (elem[0].validity || {})[name] || false;
467
+ };
468
+ });
469
+
470
+ }
471
+
472
+ webshims.defineNodeNameProperty('form', 'noValidate', {
473
+ prop: {
474
+ set: function(val){
475
+ val = !!val;
476
+ if(val){
477
+ $.attr(this, 'novalidate', 'novalidate');
478
+ } else {
479
+ $(this).removeAttr('novalidate');
480
+ }
481
+ },
482
+ get: function(){
483
+ return $.attr(this, 'novalidate') != null;
484
+ }
485
+ }
486
+ });
487
+
488
+ webshims.defineNodeNamesProperty(['input', 'textarea'], 'minLength', {
489
+ prop: {
490
+ set: function(val){
491
+ val *= 1;
492
+ if(val < 0){
493
+ throw('INDEX_SIZE_ERR');
494
+ }
495
+ this.setAttribute('minlength', val || 0);
496
+ },
497
+ get: function(){
498
+ var val = this.getAttribute('minlength');
499
+ return val == null ? -1 : (val * 1) || 0;
500
+ }
501
+ }
502
+ })
503
+
504
+ if(Modernizr.inputtypes.date && /webkit/i.test(navigator.userAgent)){
505
+ (function(){
506
+
507
+ var noInputTriggerEvts = {updateInput: 1, input: 1},
508
+ fixInputTypes = {
509
+ date: 1,
510
+ time: 1,
511
+ month: 1,
512
+ week: 1,
513
+ "datetime-local": 1
514
+ },
515
+ noFocusEvents = {
516
+ focusout: 1,
517
+ blur: 1
518
+ },
519
+ changeEvts = {
520
+ updateInput: 1,
521
+ change: 1
522
+ },
523
+ observe = function(input){
524
+ var timer,
525
+ focusedin = true,
526
+ lastInputVal = input.prop('value'),
527
+ lastChangeVal = lastInputVal,
528
+ trigger = function(e){
529
+ //input === null
530
+ if(!input){return;}
531
+ var newVal = input.prop('value');
532
+
533
+ if(newVal !== lastInputVal){
534
+ lastInputVal = newVal;
535
+ if(!e || !noInputTriggerEvts[e.type]){
536
+ input.trigger('input');
537
+ }
538
+ }
539
+ if(e && changeEvts[e.type]){
540
+ lastChangeVal = newVal;
541
+ }
542
+ if(!focusedin && newVal !== lastChangeVal){
543
+ input.trigger('change');
544
+ }
545
+ },
546
+ extraTimer,
547
+ extraTest = function(){
548
+ clearTimeout(extraTimer);
549
+ extraTimer = setTimeout(trigger, 9);
550
+ },
551
+ unbind = function(e){
552
+ clearInterval(timer);
553
+ setTimeout(function(){
554
+ if(e && noFocusEvents[e.type]){
555
+ focusedin = false;
556
+ }
557
+ if(input){
558
+ input.off('focusout blur', unbind).off('input change updateInput', trigger);
559
+ trigger();
560
+ }
561
+ input = null;
562
+ }, 1);
563
+
564
+ }
565
+ ;
566
+
567
+ clearInterval(timer);
568
+ timer = setInterval(trigger, 160);
569
+ extraTest();
570
+ input
571
+ .off({
572
+ 'focusout blur': unbind,
573
+ 'input change updateInput': trigger
574
+ })
575
+ .on({
576
+ 'focusout blur': unbind,
577
+ 'input updateInput change': trigger
578
+ })
579
+ ;
580
+ }
581
+ ;
582
+
583
+
584
+ $(document)
585
+ .on('focusin', function(e){
586
+ if( e.target && fixInputTypes[e.target.type] && !e.target.readOnly && !e.target.disabled ){
587
+ observe($(e.target));
588
+ }
589
+ })
590
+ ;
591
+
592
+
593
+ })();
594
+ }
595
+
596
+ webshims.addReady(function(context, contextElem){
597
+ //start constrain-validation
598
+ var focusElem;
599
+ $('form', context)
600
+ .add(contextElem.filter('form'))
601
+ .on('invalid', $.noop)
602
+ ;
603
+
604
+ try {
605
+ if(context == document && !('form' in (document.activeElement || {}))) {
606
+ focusElem = $('input[autofocus], select[autofocus], textarea[autofocus]', context).eq(0).getShadowFocusElement()[0];
607
+ if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) {
608
+ focusElem.focus();
609
+ }
610
+ }
611
+ }
612
+ catch (er) {}
613
+
614
+ });
615
+
616
+ if(!Modernizr.input.list){
617
+ webshims.defineNodeNameProperty('datalist', 'options', {
618
+ prop: {
619
+ writeable: false,
620
+ get: function(){
621
+ var elem = this;
622
+ var select = $('select', elem);
623
+ var options;
624
+ if(select[0]){
625
+ options = $.makeArray(select[0].options || []);
626
+ } else {
627
+ options = $('option', elem).get();
628
+ if(options.length){
629
+ webshims.warn('you should wrap your option-elements for a datalist in a select element to support IE and other old browsers.');
630
+ }
631
+ }
632
+ return options;
633
+ }
634
+ }
635
+ });
636
+ }
637
+
638
+
639
+
640
+ var submitterTypes = {submit: 1, button: 1, image: 1};
641
+ var formSubmitterDescriptors = {};
642
+ [
643
+ {
644
+ name: "enctype",
645
+ limitedTo: {
646
+ "application/x-www-form-urlencoded": 1,
647
+ "multipart/form-data": 1,
648
+ "text/plain": 1
649
+ },
650
+ defaultProp: "application/x-www-form-urlencoded",
651
+ proptype: "enum"
652
+ },
653
+ {
654
+ name: "method",
655
+ limitedTo: {
656
+ "get": 1,
657
+ "post": 1
658
+ },
659
+ defaultProp: "get",
660
+ proptype: "enum"
661
+ },
662
+ {
663
+ name: "action",
664
+ proptype: "url"
665
+ },
666
+ {
667
+ name: "target"
668
+ },
669
+ {
670
+ name: "novalidate",
671
+ propName: "noValidate",
672
+ proptype: "boolean"
673
+ }
674
+ ].forEach(function(desc){
675
+ var propName = 'form'+ (desc.propName || desc.name).replace(/^[a-z]/, function(f){
676
+ return f.toUpperCase();
677
+ });
678
+ var attrName = 'form'+ desc.name;
679
+ var formName = desc.name;
680
+ var eventName = 'click.webshimssubmittermutate'+formName;
681
+
682
+ var changeSubmitter = function(){
683
+ var elem = this;
684
+ if( !('form' in elem) || !submitterTypes[elem.type] ){return;}
685
+ var form = $.prop(elem, 'form');
686
+ if(!form){return;}
687
+ var attr = $.attr(elem, attrName);
688
+ if(attr != null && ( !desc.limitedTo || attr.toLowerCase() === $.prop(elem, propName))){
689
+
690
+ var oldAttr = $.attr(form, formName);
691
+
692
+ $.attr(form, formName, attr);
693
+ setTimeout(function(){
694
+ if(oldAttr != null){
695
+ $.attr(form, formName, oldAttr);
696
+ } else {
697
+ try {
698
+ $(form).removeAttr(formName);
699
+ } catch(er){
700
+ form.removeAttribute(formName);
701
+ }
702
+ }
703
+ }, 9);
704
+ }
705
+ };
706
+
707
+
708
+
709
+ switch(desc.proptype) {
710
+ case "url":
711
+ var urlForm = document.createElement('form');
712
+ formSubmitterDescriptors[propName] = {
713
+ prop: {
714
+ set: function(value){
715
+ $.attr(this, attrName, value);
716
+ },
717
+ get: function(){
718
+ var value = $.attr(this, attrName);
719
+ if(value == null){return '';}
720
+ urlForm.setAttribute('action', value);
721
+ return urlForm.action;
722
+ }
723
+ }
724
+ };
725
+ break;
726
+ case "boolean":
727
+ formSubmitterDescriptors[propName] = {
728
+ prop: {
729
+ set: function(val){
730
+ val = !!val;
731
+ if(val){
732
+ $.attr(this, 'formnovalidate', 'formnovalidate');
733
+ } else {
734
+ $(this).removeAttr('formnovalidate');
735
+ }
736
+ },
737
+ get: function(){
738
+ return $.attr(this, 'formnovalidate') != null;
739
+ }
740
+ }
741
+ };
742
+ break;
743
+ case "enum":
744
+ formSubmitterDescriptors[propName] = {
745
+ prop: {
746
+ set: function(value){
747
+ $.attr(this, attrName, value);
748
+ },
749
+ get: function(){
750
+ var value = $.attr(this, attrName);
751
+ return (!value || ( (value = value.toLowerCase()) && !desc.limitedTo[value] )) ? desc.defaultProp : value;
752
+ }
753
+ }
754
+ };
755
+ break;
756
+ default:
757
+ formSubmitterDescriptors[propName] = {
758
+ prop: {
759
+ set: function(value){
760
+ $.attr(this, attrName, value);
761
+ },
762
+ get: function(){
763
+ var value = $.attr(this, attrName);
764
+ return (value != null) ? value : "";
765
+ }
766
+ }
767
+ };
768
+ }
769
+
770
+
771
+ if(!formSubmitterDescriptors[attrName]){
772
+ formSubmitterDescriptors[attrName] = {};
773
+ }
774
+ formSubmitterDescriptors[attrName].attr = {
775
+ set: function(value){
776
+ formSubmitterDescriptors[attrName].attr._supset.call(this, value);
777
+ $(this).off(eventName).on(eventName, changeSubmitter);
778
+ },
779
+ get: function(){
780
+ return formSubmitterDescriptors[attrName].attr._supget.call(this);
781
+ }
782
+ };
783
+ formSubmitterDescriptors[attrName].initAttr = true;
784
+ formSubmitterDescriptors[attrName].removeAttr = {
785
+ value: function(){
786
+ $(this).off(eventName);
787
+ formSubmitterDescriptors[attrName].removeAttr._supvalue.call(this);
788
+ }
789
+ };
790
+ });
791
+
792
+ webshims.defineNodeNamesProperties(['input', 'button'], formSubmitterDescriptors);
793
+
794
+ }); //webshims.ready end
795
+ ;webshims.register('form-message', function($, webshims, window, document, undefined, options){
796
+ "use strict";
797
+ if(options.lazyCustomMessages){
798
+ options.customMessages = true;
799
+ }
800
+ var validityMessages = webshims.validityMessages;
801
+
802
+ var implementProperties = options.customMessages ? ['customValidationMessage'] : [];
803
+
804
+ validityMessages.en = $.extend(true, {
805
+ typeMismatch: {
806
+ defaultMessage: 'Please enter a valid value.',
807
+ email: 'Please enter an email address.',
808
+ url: 'Please enter a URL.'
809
+ },
810
+ badInput: {
811
+ defaultMessage: 'Please enter a valid value.',
812
+ number: 'Please enter a number.',
813
+ date: 'Please enter a date.',
814
+ time: 'Please enter a time.',
815
+ range: 'Invalid input.',
816
+ month: 'Please enter a valid value.',
817
+ "datetime-local": 'Please enter a datetime.'
818
+ },
819
+ rangeUnderflow: {
820
+ defaultMessage: 'Value must be greater than or equal to {%min}.'
821
+ },
822
+ rangeOverflow: {
823
+ defaultMessage: 'Value must be less than or equal to {%max}.'
824
+ },
825
+ stepMismatch: 'Invalid input.',
826
+ tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
827
+ tooShort: 'Please enter at least {%minlength} character(s). You entered {%valueLen}.',
828
+ patternMismatch: 'Invalid input. {%title}',
829
+ valueMissing: {
830
+ defaultMessage: 'Please fill out this field.',
831
+ checkbox: 'Please check this box if you want to proceed.'
832
+ }
833
+ }, (validityMessages.en || validityMessages['en-US'] || {}));
834
+
835
+ if(typeof validityMessages['en'].valueMissing == 'object'){
836
+ ['select', 'radio'].forEach(function(type){
837
+ validityMessages.en.valueMissing[type] = validityMessages.en.valueMissing[type] || 'Please select an option.';
838
+ });
839
+ }
840
+ if(typeof validityMessages.en.rangeUnderflow == 'object'){
841
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
842
+ validityMessages.en.rangeUnderflow[type] = validityMessages.en.rangeUnderflow[type] || 'Value must be at or after {%min}.';
843
+ });
844
+ }
845
+ if(typeof validityMessages.en.rangeOverflow == 'object'){
846
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
847
+ validityMessages.en.rangeOverflow[type] = validityMessages.en.rangeOverflow[type] || 'Value must be at or before {%max}.';
848
+ });
849
+ }
850
+ if(!validityMessages['en-US']){
851
+ validityMessages['en-US'] = $.extend(true, {}, validityMessages.en);
852
+ }
853
+ if(!validityMessages['en-GB']){
854
+ validityMessages['en-GB'] = $.extend(true, {}, validityMessages.en);
855
+ }
856
+ if(!validityMessages['en-AU']){
857
+ validityMessages['en-AU'] = $.extend(true, {}, validityMessages.en);
858
+ }
859
+ validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
860
+
861
+ validityMessages.de = $.extend(true, {
862
+ typeMismatch: {
863
+ defaultMessage: '{%value} ist in diesem Feld nicht zulässig.',
864
+ email: '{%value} ist keine gültige E-Mail-Adresse.',
865
+ url: '{%value} ist kein(e) gültige(r) Webadresse/Pfad.'
866
+ },
867
+ badInput: {
868
+ defaultMessage: 'Geben Sie einen zulässigen Wert ein.',
869
+ number: 'Geben Sie eine Nummer ein.',
870
+ date: 'Geben Sie ein Datum ein.',
871
+ time: 'Geben Sie eine Uhrzeit ein.',
872
+ month: 'Geben Sie einen Monat mit Jahr ein.',
873
+ range: 'Geben Sie eine Nummer.',
874
+ "datetime-local": 'Geben Sie ein Datum mit Uhrzeit ein.'
875
+ },
876
+ rangeUnderflow: {
877
+ defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
878
+ },
879
+ rangeOverflow: {
880
+ defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
881
+ },
882
+ stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
883
+ tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
884
+ tooShort: 'Der eingegebene Text ist zu kurz! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%minlength} das Minimum.',
885
+ patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format. {%title}',
886
+ valueMissing: {
887
+ defaultMessage: 'Bitte geben Sie einen Wert ein.',
888
+ checkbox: 'Bitte aktivieren Sie das Kästchen.'
889
+ }
890
+ }, (validityMessages.de || {}));
891
+
892
+ if(typeof validityMessages.de.valueMissing == 'object'){
893
+ ['select', 'radio'].forEach(function(type){
894
+ validityMessages.de.valueMissing[type] = validityMessages.de.valueMissing[type] || 'Bitte wählen Sie eine Option aus.';
895
+ });
896
+ }
897
+ if(typeof validityMessages.de.rangeUnderflow == 'object'){
898
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
899
+ validityMessages.de.rangeUnderflow[type] = validityMessages.de.rangeUnderflow[type] || '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
900
+ });
901
+ }
902
+ if(typeof validityMessages.de.rangeOverflow == 'object'){
903
+ ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
904
+ validityMessages.de.rangeOverflow[type] = validityMessages.de.rangeOverflow[type] || '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
905
+ });
906
+ }
907
+
908
+ var currentValidationMessage = validityMessages[''];
909
+ var getMessageFromObj = function(message, elem){
910
+ if(message && typeof message !== 'string'){
911
+ message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
912
+ }
913
+ return message || '';
914
+ };
915
+ var valueVals = {
916
+ value: 1,
917
+ min: 1,
918
+ max: 1
919
+ };
920
+
921
+ webshims.createValidationMessage = function(elem, name){
922
+ var widget;
923
+ var type = $.prop(elem, 'type');
924
+ var message = getMessageFromObj(currentValidationMessage[name], elem);
925
+ if(!message && name == 'badInput'){
926
+ message = getMessageFromObj(currentValidationMessage.typeMismatch, elem);
927
+ }
928
+ if(!message && name == 'typeMismatch'){
929
+ message = getMessageFromObj(currentValidationMessage.badInput, elem);
930
+ }
931
+ if(!message){
932
+ message = getMessageFromObj(validityMessages[''][name], elem) || $.prop(elem, 'validationMessage');
933
+ webshims.info('could not find errormessage for: '+ name +' / '+ type +'. in language: '+webshims.activeLang());
934
+ }
935
+ if(message){
936
+ ['value', 'min', 'max', 'title', 'maxlength', 'minlength', 'label'].forEach(function(attr){
937
+ if(message.indexOf('{%'+attr) === -1){return;}
938
+ var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.prop(elem, attr)) || '';
939
+ if(name == 'patternMismatch' && attr == 'title' && !val){
940
+ webshims.error('no title for patternMismatch provided. Always add a title attribute.');
941
+ }
942
+ if(valueVals[attr]){
943
+ if(!widget){
944
+ widget = $(elem).getShadowElement().data('wsWidget'+type);
945
+ }
946
+ if(widget && widget.formatValue){
947
+ val = widget.formatValue(val, false);
948
+ }
949
+ }
950
+ message = message.replace('{%'+ attr +'}', val);
951
+ if('value' == attr){
952
+ message = message.replace('{%valueLen}', val.length);
953
+ }
954
+
955
+ });
956
+ }
957
+
958
+ return message || '';
959
+ };
960
+
961
+
962
+ if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){
963
+ implementProperties.push('validationMessage');
964
+ }
965
+
966
+ currentValidationMessage = webshims.activeLang(validityMessages);
967
+
968
+ $(validityMessages).on('change', function(e, data){
969
+ currentValidationMessage = validityMessages.__active;
970
+ });
971
+
972
+ implementProperties.forEach(function(messageProp){
973
+
974
+ webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
975
+ prop: {
976
+ value: '',
977
+ writeable: false
978
+ }
979
+ });
980
+ ['input', 'select', 'textarea'].forEach(function(nodeName){
981
+ var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
982
+ prop: {
983
+ get: function(){
984
+ var elem = this;
985
+ var message = '';
986
+ if(!$.prop(elem, 'willValidate')){
987
+ return message;
988
+ }
989
+
990
+ var validity = $.prop(elem, 'validity') || {valid: 1};
991
+
992
+ if(validity.valid){return message;}
993
+ message = webshims.getContentValidationMessage(elem, validity);
994
+
995
+ if(message){return message;}
996
+
997
+ if(validity.customError && elem.nodeName){
998
+ message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
999
+ if(message){return message;}
1000
+ }
1001
+ $.each(validity, function(name, prop){
1002
+ if(name == 'valid' || !prop){return;}
1003
+
1004
+ message = webshims.createValidationMessage(elem, name);
1005
+ if(message){
1006
+ return false;
1007
+ }
1008
+ });
1009
+
1010
+ return message || '';
1011
+ },
1012
+ writeable: false
1013
+ }
1014
+ });
1015
+ });
1016
+
1017
+ });
1018
+ });
1019
+ ;webshims.register('form-number-date-api', function($, webshims, window, document, undefined, options){
1020
+ "use strict";
1021
+ if(!webshims.addInputType){
1022
+ webshims.error("you can not call forms-ext feature after calling forms feature. call both at once instead: $.webshims.polyfill('forms forms-ext')");
1023
+ }
1024
+
1025
+ if(!webshims.getStep){
1026
+ webshims.getStep = function(elem, type){
1027
+ var step = $.attr(elem, 'step');
1028
+ if(step === 'any'){
1029
+ return step;
1030
+ }
1031
+ type = type || getType(elem);
1032
+ if(!typeModels[type] || !typeModels[type].step){
1033
+ return step;
1034
+ }
1035
+ step = typeProtos.number.asNumber(step);
1036
+ return ((!isNaN(step) && step > 0) ? step : typeModels[type].step) * (typeModels[type].stepScaleFactor || 1);
1037
+ };
1038
+ }
1039
+ if(!webshims.addMinMaxNumberToCache){
1040
+ webshims.addMinMaxNumberToCache = function(attr, elem, cache){
1041
+ if (!(attr+'AsNumber' in cache)) {
1042
+ cache[attr+'AsNumber'] = typeModels[cache.type].asNumber(elem.attr(attr));
1043
+ if(isNaN(cache[attr+'AsNumber']) && (attr+'Default' in typeModels[cache.type])){
1044
+ cache[attr+'AsNumber'] = typeModels[cache.type][attr+'Default'];
1045
+ }
1046
+ }
1047
+ };
1048
+ }
1049
+
1050
+ var nan = parseInt('NaN', 10),
1051
+ doc = document,
1052
+ typeModels = webshims.inputTypes,
1053
+ isNumber = function(string){
1054
+ return (typeof string == 'number' || (string && string == string * 1));
1055
+ },
1056
+ supportsType = function(type){
1057
+ return ($('<input type="'+type+'" />').prop('type') === type);
1058
+ },
1059
+ getType = function(elem){
1060
+ return (elem.getAttribute('type') || '').toLowerCase();
1061
+ },
1062
+ isDateTimePart = function(string){
1063
+ return (string && !(isNaN(string * 1)));
1064
+ },
1065
+ addMinMaxNumberToCache = webshims.addMinMaxNumberToCache,
1066
+ addleadingZero = function(val, len){
1067
+ val = ''+val;
1068
+ len = len - val.length;
1069
+ for(var i = 0; i < len; i++){
1070
+ val = '0'+val;
1071
+ }
1072
+ return val;
1073
+ },
1074
+ EPS = 1e-7,
1075
+ typeBugs = webshims.bugs.bustedValidity
1076
+ ;
1077
+
1078
+ webshims.addValidityRule('stepMismatch', function(input, val, cache, validityState){
1079
+ if(val === ''){return false;}
1080
+ if(!('type' in cache)){
1081
+ cache.type = getType(input[0]);
1082
+ }
1083
+ if(cache.type == 'week'){return false;}
1084
+ var base, attrVal;
1085
+ var ret = (validityState || {}).stepMismatch || false;
1086
+ if(typeModels[cache.type] && typeModels[cache.type].step){
1087
+ if( !('step' in cache) ){
1088
+ cache.step = webshims.getStep(input[0], cache.type);
1089
+ }
1090
+
1091
+ if(cache.step == 'any'){return false;}
1092
+
1093
+ if(!('valueAsNumber' in cache)){
1094
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
1095
+ }
1096
+ if(isNaN(cache.valueAsNumber)){return false;}
1097
+
1098
+ addMinMaxNumberToCache('min', input, cache);
1099
+ base = cache.minAsNumber;
1100
+
1101
+ if(isNaN(base) && (attrVal = input.prop('defaultValue'))){
1102
+ base = typeModels[cache.type].asNumber( attrVal );
1103
+ }
1104
+
1105
+ if(isNaN(base)){
1106
+ base = typeModels[cache.type].stepBase || 0;
1107
+ }
1108
+
1109
+ ret = Math.abs((cache.valueAsNumber - base) % cache.step);
1110
+
1111
+ ret = !( ret <= EPS || Math.abs(ret - cache.step) <= EPS );
1112
+ }
1113
+ return ret;
1114
+ });
1115
+
1116
+
1117
+
1118
+ [{name: 'rangeOverflow', attr: 'max', factor: 1}, {name: 'rangeUnderflow', attr: 'min', factor: -1}].forEach(function(data, i){
1119
+ webshims.addValidityRule(data.name, function(input, val, cache, validityState) {
1120
+ var ret = (validityState || {})[data.name] || false;
1121
+ if(val === ''){return ret;}
1122
+ if (!('type' in cache)) {
1123
+ cache.type = getType(input[0]);
1124
+ }
1125
+ if (typeModels[cache.type] && typeModels[cache.type].asNumber) {
1126
+ if(!('valueAsNumber' in cache)){
1127
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
1128
+ }
1129
+ if(isNaN(cache.valueAsNumber)){
1130
+ return false;
1131
+ }
1132
+
1133
+ addMinMaxNumberToCache(data.attr, input, cache);
1134
+
1135
+ if(isNaN(cache[data.attr+'AsNumber'])){
1136
+ return ret;
1137
+ }
1138
+ ret = ( cache[data.attr+'AsNumber'] * data.factor < cache.valueAsNumber * data.factor - EPS );
1139
+ }
1140
+ return ret;
1141
+ });
1142
+ });
1143
+
1144
+ webshims.reflectProperties(['input'], ['max', 'min', 'step']);
1145
+
1146
+
1147
+ //IDLs and methods, that aren't part of constrain validation, but strongly tight to it
1148
+ var valueAsNumberDescriptor = webshims.defineNodeNameProperty('input', 'valueAsNumber', {
1149
+ prop: {
1150
+ get: function(){
1151
+ var elem = this;
1152
+ var type = getType(elem);
1153
+ var ret = (typeModels[type] && typeModels[type].asNumber) ?
1154
+ typeModels[type].asNumber($.prop(elem, 'value')) :
1155
+ (valueAsNumberDescriptor.prop._supget && valueAsNumberDescriptor.prop._supget.apply(elem, arguments));
1156
+ if(ret == null){
1157
+ ret = nan;
1158
+ }
1159
+ return ret;
1160
+ },
1161
+ set: function(val){
1162
+ var elem = this;
1163
+ var type = getType(elem);
1164
+ if(typeModels[type] && typeModels[type].numberToString){
1165
+ //is NaN a number?
1166
+ if(isNaN(val)){
1167
+ $.prop(elem, 'value', '');
1168
+ return;
1169
+ }
1170
+ var set = typeModels[type].numberToString(val);
1171
+ if(set !== false){
1172
+ $.prop(elem, 'value', set);
1173
+ } else {
1174
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
1175
+ }
1176
+ } else if(valueAsNumberDescriptor.prop._supset) {
1177
+ valueAsNumberDescriptor.prop._supset.apply(elem, arguments);
1178
+ }
1179
+ }
1180
+ }
1181
+ });
1182
+
1183
+ var valueAsDateDescriptor = webshims.defineNodeNameProperty('input', 'valueAsDate', {
1184
+ prop: {
1185
+ get: function(){
1186
+ var elem = this;
1187
+ var type = getType(elem);
1188
+ return (typeModels[type] && typeModels[type].asDate && !typeModels[type].noAsDate) ?
1189
+ typeModels[type].asDate($.prop(elem, 'value')) :
1190
+ valueAsDateDescriptor.prop._supget && valueAsDateDescriptor.prop._supget.call(elem) || null;
1191
+ },
1192
+ set: function(value){
1193
+ var elem = this;
1194
+ var type = getType(elem);
1195
+ if(typeModels[type] && typeModels[type].dateToString && !typeModels[type].noAsDate){
1196
+
1197
+ if(value === null){
1198
+ $.prop(elem, 'value', '');
1199
+ return '';
1200
+ }
1201
+ var set = typeModels[type].dateToString(value);
1202
+ if(set !== false){
1203
+ $.prop(elem, 'value', set);
1204
+ return set;
1205
+ } else {
1206
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
1207
+ }
1208
+ } else {
1209
+ return valueAsDateDescriptor.prop._supset && valueAsDateDescriptor.prop._supset.apply(elem, arguments) || null;
1210
+ }
1211
+ }
1212
+ }
1213
+ });
1214
+
1215
+ $.each({stepUp: 1, stepDown: -1}, function(name, stepFactor){
1216
+ var stepDescriptor = webshims.defineNodeNameProperty('input', name, {
1217
+ prop: {
1218
+ value: function(factor){
1219
+ var step, val, dateVal, valModStep, alignValue, cache, base, attrVal;
1220
+ var type = getType(this);
1221
+ if(typeModels[type] && typeModels[type].asNumber){
1222
+ cache = {type: type};
1223
+ if(!factor){
1224
+ factor = 1;
1225
+ webshims.warn("you should always use a factor for stepUp/stepDown");
1226
+ }
1227
+ factor *= stepFactor;
1228
+
1229
+ val = $.prop(this, 'valueAsNumber');
1230
+
1231
+ if(isNaN(val)){
1232
+ webshims.info("valueAsNumber is NaN can't apply stepUp/stepDown ");
1233
+ throw('invalid state error');
1234
+ }
1235
+
1236
+ step = webshims.getStep(this, type);
1237
+
1238
+ if(step == 'any'){
1239
+ webshims.info("step is 'any' can't apply stepUp/stepDown");
1240
+ throw('invalid state error');
1241
+ }
1242
+
1243
+ webshims.addMinMaxNumberToCache('min', $(this), cache);
1244
+ webshims.addMinMaxNumberToCache('max', $(this), cache);
1245
+
1246
+ base = cache.minAsNumber;
1247
+
1248
+ if(isNaN(base) && (attrVal = $.prop(this, 'defaultValue'))){
1249
+ base = typeModels[type].asNumber( attrVal );
1250
+ }
1251
+
1252
+ if(!base){
1253
+ base = 0;
1254
+ }
1255
+
1256
+ step *= factor;
1257
+
1258
+ val = (val + step).toFixed(5) * 1;
1259
+
1260
+ valModStep = (val - base) % step;
1261
+
1262
+ if ( valModStep && (Math.abs(valModStep) > EPS) ) {
1263
+ alignValue = val - valModStep;
1264
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
1265
+ val = alignValue.toFixed(5) * 1;
1266
+ }
1267
+
1268
+ if( (!isNaN(cache.maxAsNumber) && val > cache.maxAsNumber) || (!isNaN(cache.minAsNumber) && val < cache.minAsNumber) ){
1269
+ webshims.info("max/min overflow can't apply stepUp/stepDown");
1270
+ throw('invalid state error');
1271
+ }
1272
+
1273
+ $.prop(this, 'valueAsNumber', val);
1274
+
1275
+ } else if(stepDescriptor.prop && stepDescriptor.prop._supvalue){
1276
+ return stepDescriptor.prop._supvalue.apply(this, arguments);
1277
+ } else {
1278
+ webshims.info("no step method for type: "+ type);
1279
+ throw('invalid state error');
1280
+ }
1281
+ }
1282
+ }
1283
+ });
1284
+ });
1285
+
1286
+ /*
1287
+ * ToDO: WEEK
1288
+ */
1289
+ // var getWeek = function(date){
1290
+ // var time;
1291
+ // var checkDate = new Date(date.getTime());
1292
+ //
1293
+ // checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
1294
+ //
1295
+ // time = checkDate.getTime();
1296
+ // checkDate.setMonth(0);
1297
+ // checkDate.setDate(1);
1298
+ // return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
1299
+ // };
1300
+ //
1301
+ // var setWeek = function(year, week){
1302
+ // var date = new Date(year, 0, 1);
1303
+ //
1304
+ // week = (week - 1) * 86400000 * 7;
1305
+ // date = new Date(date.getTime() + week);
1306
+ // date.setDate(date.getDate() + 1 - (date.getDay() || 7));
1307
+ // return date;
1308
+ // };
1309
+
1310
+ var typeProtos = {
1311
+
1312
+ number: {
1313
+ bad: function(val){
1314
+ return !(isNumber(val));
1315
+ },
1316
+ step: 1,
1317
+ //stepBase: 0, 0 = default
1318
+ stepScaleFactor: 1,
1319
+ asNumber: function(str){
1320
+ return (isNumber(str)) ? str * 1 : nan;
1321
+ },
1322
+ numberToString: function(num){
1323
+ return (isNumber(num)) ? num : false;
1324
+ }
1325
+ },
1326
+
1327
+ range: {
1328
+ minDefault: 0,
1329
+ maxDefault: 100
1330
+ },
1331
+ color: {
1332
+ bad: (function(){
1333
+ var cReg = /^\u0023[a-f0-9]{6}$/;
1334
+ return function(val){
1335
+ return (!val || val.length != 7 || !(cReg.test(val)));
1336
+ };
1337
+ })()
1338
+ },
1339
+ date: {
1340
+ bad: function(val){
1341
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
1342
+ var i;
1343
+ var valA = val.split(/\u002D/);
1344
+ if(valA.length !== 3){return true;}
1345
+ var ret = false;
1346
+
1347
+
1348
+ if(valA[0].length < 4 || valA[1].length != 2 || valA[1] > 12 || valA[2].length != 2 || valA[2] > 33){
1349
+ ret = true;
1350
+ } else {
1351
+ for(i = 0; i < 3; i++){
1352
+ if(!isDateTimePart(valA[i])){
1353
+ ret = true;
1354
+ break;
1355
+ }
1356
+ }
1357
+ }
1358
+
1359
+ return ret || (val !== this.dateToString( this.asDate(val, true) ) );
1360
+ },
1361
+ step: 1,
1362
+ //stepBase: 0, 0 = default
1363
+ stepScaleFactor: 86400000,
1364
+ asDate: function(val, _noMismatch){
1365
+ if(!_noMismatch && this.bad(val)){
1366
+ return null;
1367
+ }
1368
+ return new Date(this.asNumber(val, true));
1369
+ },
1370
+ asNumber: function(str, _noMismatch){
1371
+ var ret = nan;
1372
+ if(_noMismatch || !this.bad(str)){
1373
+ str = str.split(/\u002D/);
1374
+ ret = Date.UTC(str[0], str[1] - 1, str[2]);
1375
+ }
1376
+ return ret;
1377
+ },
1378
+ numberToString: function(num){
1379
+ return (isNumber(num)) ? this.dateToString(new Date( num * 1)) : false;
1380
+ },
1381
+ dateToString: function(date){
1382
+ return (date && date.getFullYear) ? addleadingZero(date.getUTCFullYear(), 4) +'-'+ addleadingZero(date.getUTCMonth()+1, 2) +'-'+ addleadingZero(date.getUTCDate(), 2) : false;
1383
+ }
1384
+ },
1385
+ /*
1386
+ * ToDO: WEEK
1387
+ */
1388
+ // week: {
1389
+ // bad: function(val){
1390
+ // if(!val || !val.split){return true;}
1391
+ // var valA = val.split('-W');
1392
+ // var ret = true;
1393
+ // if(valA.length == 2 && valA[0].length > 3 && valA.length == 2){
1394
+ // ret = this.dateToString(setWeek(valA[0], valA[1])) != val;
1395
+ // }
1396
+ // return ret;
1397
+ // },
1398
+ // step: 1,
1399
+ // stepScaleFactor: 604800000,
1400
+ // stepBase: -259200000,
1401
+ // asDate: function(str, _noMismatch){
1402
+ // var ret = null;
1403
+ // if(_noMismatch || !this.bad(str)){
1404
+ // ret = str.split('-W');
1405
+ // ret = setWeek(ret[0], ret[1]);
1406
+ // }
1407
+ // return ret;
1408
+ // },
1409
+ // asNumber: function(str, _noMismatch){
1410
+ // var ret = nan;
1411
+ // var date = this.asDate(str, _noMismatch);
1412
+ // if(date && date.getUTCFullYear){
1413
+ // ret = date.getTime();
1414
+ // }
1415
+ // return ret;
1416
+ // },
1417
+ // dateToString: function(date){
1418
+ // var week, checkDate;
1419
+ // var ret = false;
1420
+ // if(date && date.getFullYear){
1421
+ // week = getWeek(date);
1422
+ // if(week == 1){
1423
+ // checkDate = new Date(date.getTime());
1424
+ // checkDate.setDate(checkDate.getDate() + 7);
1425
+ // date.setUTCFullYear(checkDate.getUTCFullYear());
1426
+ // }
1427
+ // ret = addleadingZero(date.getUTCFullYear(), 4) +'-W'+addleadingZero(week, 2);
1428
+ // }
1429
+ // return ret;
1430
+ // },
1431
+ // numberToString: function(num){
1432
+ // return (isNumber(num)) ? this.dateToString(new Date( num * 1)) : false;
1433
+ // }
1434
+ // },
1435
+ time: {
1436
+ bad: function(val, _getParsed){
1437
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
1438
+ val = val.split(/\u003A/);
1439
+ if(val.length < 2 || val.length > 3){return true;}
1440
+ var ret = false,
1441
+ sFraction;
1442
+ if(val[2]){
1443
+ val[2] = val[2].split(/\u002E/);
1444
+ sFraction = parseInt(val[2][1], 10);
1445
+ val[2] = val[2][0];
1446
+ }
1447
+ $.each(val, function(i, part){
1448
+ if(!isDateTimePart(part) || part.length !== 2){
1449
+ ret = true;
1450
+ return false;
1451
+ }
1452
+ });
1453
+ if(ret){return true;}
1454
+ if(val[0] > 23 || val[0] < 0 || val[1] > 59 || val[1] < 0){
1455
+ return true;
1456
+ }
1457
+ if(val[2] && (val[2] > 59 || val[2] < 0 )){
1458
+ return true;
1459
+ }
1460
+ if(sFraction && isNaN(sFraction)){
1461
+ return true;
1462
+ }
1463
+ if(sFraction){
1464
+ if(sFraction < 100){
1465
+ sFraction *= 100;
1466
+ } else if(sFraction < 10){
1467
+ sFraction *= 10;
1468
+ }
1469
+ }
1470
+ return (_getParsed === true) ? [val, sFraction] : false;
1471
+ },
1472
+ step: 60,
1473
+ stepBase: 0,
1474
+ stepScaleFactor: 1000,
1475
+ asDate: function(val){
1476
+ val = new Date(this.asNumber(val));
1477
+ return (isNaN(val)) ? null : val;
1478
+ },
1479
+ asNumber: function(val){
1480
+ var ret = nan;
1481
+ val = this.bad(val, true);
1482
+ if(val !== true){
1483
+ ret = Date.UTC('1970', 0, 1, val[0][0], val[0][1], val[0][2] || 0);
1484
+ if(val[1]){
1485
+ ret += val[1];
1486
+ }
1487
+ }
1488
+ return ret;
1489
+ },
1490
+ dateToString: function(date){
1491
+ if(date && date.getUTCHours){
1492
+ var str = addleadingZero(date.getUTCHours(), 2) +':'+ addleadingZero(date.getUTCMinutes(), 2),
1493
+ tmp = date.getSeconds()
1494
+ ;
1495
+ if(tmp != "0"){
1496
+ str += ':'+ addleadingZero(tmp, 2);
1497
+ }
1498
+ tmp = date.getUTCMilliseconds();
1499
+ if(tmp != "0"){
1500
+ str += '.'+ addleadingZero(tmp, 3);
1501
+ }
1502
+ return str;
1503
+ } else {
1504
+ return false;
1505
+ }
1506
+ }
1507
+ },
1508
+ month: {
1509
+ bad: function(val){
1510
+ return typeProtos.date.bad(val+'-01');
1511
+ },
1512
+ step: 1,
1513
+ stepScaleFactor: false,
1514
+ //stepBase: 0, 0 = default
1515
+ asDate: function(val){
1516
+ return new Date(typeProtos.date.asNumber(val+'-01'));
1517
+ },
1518
+ asNumber: function(val){
1519
+ //1970-01
1520
+ var ret = nan;
1521
+ if(val && !this.bad(val)){
1522
+ val = val.split(/\u002D/);
1523
+ val[0] = (val[0] * 1) - 1970;
1524
+ val[1] = (val[1] * 1) - 1;
1525
+ ret = (val[0] * 12) + val[1];
1526
+ }
1527
+ return ret;
1528
+ },
1529
+ numberToString: function(num){
1530
+ var mod;
1531
+ var ret = false;
1532
+ if(isNumber(num)){
1533
+ mod = (num % 12);
1534
+ num = ((num - mod) / 12) + 1970;
1535
+ mod += 1;
1536
+ if(mod < 1){
1537
+ num -= 1;
1538
+ mod += 12;
1539
+ }
1540
+ ret = addleadingZero(num, 4)+'-'+addleadingZero(mod, 2);
1541
+
1542
+ }
1543
+
1544
+ return ret;
1545
+ },
1546
+ dateToString: function(date){
1547
+ if(date && date.getUTCHours){
1548
+ var str = typeProtos.date.dateToString(date);
1549
+ return (str.split && (str = str.split(/\u002D/))) ? str[0]+'-'+str[1] : false;
1550
+ } else {
1551
+ return false;
1552
+ }
1553
+ }
1554
+ }
1555
+ ,'datetime-local': {
1556
+ bad: function(val, _getParsed){
1557
+ if(!val || !val.split || (val+'special').split(/\u0054/).length !== 2){return true;}
1558
+ val = val.split(/\u0054/);
1559
+ return ( typeProtos.date.bad(val[0]) || typeProtos.time.bad(val[1], _getParsed) );
1560
+ },
1561
+ noAsDate: true,
1562
+ asDate: function(val){
1563
+ val = new Date(this.asNumber(val));
1564
+
1565
+ return (isNaN(val)) ? null : val;
1566
+ },
1567
+ asNumber: function(val){
1568
+ var ret = nan;
1569
+ var time = this.bad(val, true);
1570
+ if(time !== true){
1571
+ val = val.split(/\u0054/)[0].split(/\u002D/);
1572
+
1573
+ ret = Date.UTC(val[0], val[1] - 1, val[2], time[0][0], time[0][1], time[0][2] || 0);
1574
+ if(time[1]){
1575
+ ret += time[1];
1576
+ }
1577
+ }
1578
+ return ret;
1579
+ },
1580
+ dateToString: function(date, _getParsed){
1581
+ return typeProtos.date.dateToString(date) +'T'+ typeProtos.time.dateToString(date, _getParsed);
1582
+ }
1583
+ }
1584
+ };
1585
+
1586
+ if(typeBugs || !supportsType('range') || !supportsType('time') || !supportsType('month') || !supportsType('datetime-local')){
1587
+ typeProtos.range = $.extend({}, typeProtos.number, typeProtos.range);
1588
+ typeProtos.time = $.extend({}, typeProtos.date, typeProtos.time);
1589
+ typeProtos.month = $.extend({}, typeProtos.date, typeProtos.month);
1590
+ typeProtos['datetime-local'] = $.extend({}, typeProtos.date, typeProtos.time, typeProtos['datetime-local']);
1591
+ }
1592
+
1593
+ //
1594
+ ['number', 'month', 'range', 'date', 'time', 'color', 'datetime-local'].forEach(function(type){
1595
+ if(typeBugs || !supportsType(type)){
1596
+ webshims.addInputType(type, typeProtos[type]);
1597
+ }
1598
+ });
1599
+
1600
+ if($('<input />').prop('labels') == null){
1601
+ webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
1602
+ prop: {
1603
+ get: function(){
1604
+ if(this.type == 'hidden'){return null;}
1605
+ var id = this.id;
1606
+ var labels = $(this)
1607
+ .closest('label')
1608
+ .filter(function(){
1609
+ var hFor = (this.attributes['for'] || {});
1610
+ return (!hFor.specified || hFor.value == id);
1611
+ })
1612
+ ;
1613
+
1614
+ if(id) {
1615
+ labels = labels.add('label[for="'+ id +'"]');
1616
+ }
1617
+ return labels.get();
1618
+ },
1619
+ writeable: false
1620
+ }
1621
+ });
1622
+ }
1623
+
1624
+ });;webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
1625
+ "use strict";
1626
+ var doc = document;
1627
+ var lazyLoad = function(name){
1628
+ if(!name || typeof name != 'string'){
1629
+ name = 'DOM';
1630
+ }
1631
+ if(!lazyLoad[name+'Loaded']){
1632
+ lazyLoad[name+'Loaded'] = true;
1633
+ webshims.ready(name, function(){
1634
+ webshims.loader.loadList(['form-datalist-lazy']);
1635
+ });
1636
+ }
1637
+ };
1638
+ var noDatalistSupport = {
1639
+ submit: 1,
1640
+ button: 1,
1641
+ reset: 1,
1642
+ hidden: 1,
1643
+
1644
+ range: 1,
1645
+ date: 1,
1646
+ month: 1
1647
+ };
1648
+ if(webshims.modules["form-number-date-ui"].loaded){
1649
+ $.extend(noDatalistSupport, {
1650
+ number: 1,
1651
+ time: 1
1652
+ });
1653
+ }
1654
+
1655
+
1656
+ /*
1657
+ * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed)
1658
+ */
1659
+ webshims.propTypes.element = function(descs, name){
1660
+ webshims.createPropDefault(descs, 'attr');
1661
+ if(descs.prop){return;}
1662
+ descs.prop = {
1663
+ get: function(){
1664
+ var elem = $.attr(this, name);
1665
+ if(elem){
1666
+ elem = document.getElementById(elem);
1667
+ if(elem && descs.propNodeName && !$.nodeName(elem, descs.propNodeName)){
1668
+ elem = null;
1669
+ }
1670
+ }
1671
+ return elem || null;
1672
+ },
1673
+ writeable: false
1674
+ };
1675
+ };
1676
+
1677
+
1678
+ /*
1679
+ * Implements datalist element and list attribute
1680
+ */
1681
+
1682
+ (function(){
1683
+ var formsCFG = $.webshims.cfg.forms;
1684
+ var listSupport = Modernizr.input.list;
1685
+ if(listSupport && !formsCFG.customDatalist){return;}
1686
+
1687
+ var initializeDatalist = function(){
1688
+
1689
+ var updateDatlistAndOptions = function(){
1690
+ var id;
1691
+ if(!$.data(this, 'datalistWidgetData') && (id = $.prop(this, 'id'))){
1692
+ $('input[list="'+ id +'"], input[data-wslist="'+ id +'"]').eq(0).attr('list', id);
1693
+ } else {
1694
+ $(this).triggerHandler('updateDatalist');
1695
+ }
1696
+ };
1697
+
1698
+ var inputListProto = {
1699
+ //override autocomplete
1700
+ autocomplete: {
1701
+ attr: {
1702
+ get: function(){
1703
+ var elem = this;
1704
+ var data = $.data(elem, 'datalistWidget');
1705
+ if(data){
1706
+ return data._autocomplete;
1707
+ }
1708
+ return ('autocomplete' in elem) ? elem.autocomplete : elem.getAttribute('autocomplete');
1709
+ },
1710
+ set: function(value){
1711
+ var elem = this;
1712
+ var data = $.data(elem, 'datalistWidget');
1713
+ if(data){
1714
+ data._autocomplete = value;
1715
+ if(value == 'off'){
1716
+ data.hideList();
1717
+ }
1718
+ } else {
1719
+ if('autocomplete' in elem){
1720
+ elem.autocomplete = value;
1721
+ } else {
1722
+ elem.setAttribute('autocomplete', value);
1723
+ }
1724
+ }
1725
+ }
1726
+ }
1727
+ }
1728
+ };
1729
+
1730
+ if(listSupport){
1731
+ //options only return options, if option-elements are rooted: but this makes this part of HTML5 less backwards compatible
1732
+ if(!($('<datalist><select><option></option></select></datalist>').prop('options') || []).length ){
1733
+ webshims.defineNodeNameProperty('datalist', 'options', {
1734
+ prop: {
1735
+ writeable: false,
1736
+ get: function(){
1737
+ var options = this.options || [];
1738
+ if(!options.length){
1739
+ var elem = this;
1740
+ var select = $('select', elem);
1741
+ if(select[0] && select[0].options && select[0].options.length){
1742
+ options = select[0].options;
1743
+ }
1744
+ }
1745
+ return options;
1746
+ }
1747
+ }
1748
+ });
1749
+ }
1750
+ inputListProto.list = {
1751
+ attr: {
1752
+ get: function(){
1753
+ var val = webshims.contentAttr(this, 'list');
1754
+ if(val != null){
1755
+ $.data(this, 'datalistListAttr', val);
1756
+ if(!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]){
1757
+ this.removeAttribute('list');
1758
+ }
1759
+ } else {
1760
+ val = $.data(this, 'datalistListAttr');
1761
+ }
1762
+
1763
+ return (val == null) ? undefined : val;
1764
+ },
1765
+ set: function(value){
1766
+ var elem = this;
1767
+ $.data(elem, 'datalistListAttr', value);
1768
+ if (!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]) {
1769
+ webshims.objectCreate(shadowListProto, undefined, {
1770
+ input: elem,
1771
+ id: value,
1772
+ datalist: $.prop(elem, 'list')
1773
+ });
1774
+ elem.setAttribute('data-wslist', value);
1775
+ } else {
1776
+ elem.setAttribute('list', value);
1777
+ }
1778
+ $(elem).triggerHandler('listdatalistchange');
1779
+ }
1780
+ },
1781
+ initAttr: true,
1782
+ reflect: true,
1783
+ propType: 'element',
1784
+ propNodeName: 'datalist'
1785
+ };
1786
+ } else {
1787
+ webshims.defineNodeNameProperties('input', {
1788
+ list: {
1789
+ attr: {
1790
+ get: function(){
1791
+ var val = webshims.contentAttr(this, 'list');
1792
+ return (val == null) ? undefined : val;
1793
+ },
1794
+ set: function(value){
1795
+ var elem = this;
1796
+ webshims.contentAttr(elem, 'list', value);
1797
+ webshims.objectCreate(options.shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
1798
+ $(elem).triggerHandler('listdatalistchange');
1799
+ }
1800
+ },
1801
+ initAttr: true,
1802
+ reflect: true,
1803
+ propType: 'element',
1804
+ propNodeName: 'datalist'
1805
+ }
1806
+ });
1807
+ }
1808
+
1809
+ webshims.defineNodeNameProperties('input', inputListProto);
1810
+
1811
+ webshims.addReady(function(context, contextElem){
1812
+ contextElem
1813
+ .filter('datalist > select, datalist, datalist > option, datalist > select > option')
1814
+ .closest('datalist')
1815
+ .each(updateDatlistAndOptions)
1816
+ ;
1817
+ });
1818
+ };
1819
+
1820
+
1821
+ /*
1822
+ * ShadowList
1823
+ */
1824
+
1825
+ var shadowListProto = {
1826
+ _create: function(opts){
1827
+
1828
+ if(noDatalistSupport[$.prop(opts.input, 'type')] || noDatalistSupport[$.attr(opts.input, 'type')]){return;}
1829
+ var datalist = opts.datalist;
1830
+ var data = $.data(opts.input, 'datalistWidget');
1831
+ var that = this;
1832
+ if(datalist && data && data.datalist !== datalist){
1833
+ data.datalist = datalist;
1834
+ data.id = opts.id;
1835
+
1836
+
1837
+ $(data.datalist)
1838
+ .off('updateDatalist.datalistWidget')
1839
+ .on('updateDatalist.datalistWidget', $.proxy(data, '_resetListCached'))
1840
+ ;
1841
+
1842
+ data._resetListCached();
1843
+ return;
1844
+ } else if(!datalist){
1845
+ if(data){
1846
+ data.destroy();
1847
+ }
1848
+ return;
1849
+ } else if(data && data.datalist === datalist){
1850
+ return;
1851
+ }
1852
+
1853
+
1854
+
1855
+ this.datalist = datalist;
1856
+ this.id = opts.id;
1857
+ this.hasViewableData = true;
1858
+ this._autocomplete = $.attr(opts.input, 'autocomplete');
1859
+ $.data(opts.input, 'datalistWidget', this);
1860
+ $.data(datalist, 'datalistWidgetData', this);
1861
+
1862
+ lazyLoad('WINDOWLOAD');
1863
+
1864
+ if(webshims.isReady('form-datalist-lazy')){
1865
+ this._lazyCreate(opts);
1866
+ } else {
1867
+ $(opts.input).one('focus', lazyLoad);
1868
+ webshims.ready('form-datalist-lazy', function(){
1869
+ if(!that._destroyed){
1870
+ that._lazyCreate(opts);
1871
+ }
1872
+ });
1873
+ }
1874
+ },
1875
+ destroy: function(e){
1876
+ var input;
1877
+ var autocomplete = $.attr(this.input, 'autocomplete');
1878
+ $(this.input)
1879
+ .off('.datalistWidget')
1880
+ .removeData('datalistWidget')
1881
+ ;
1882
+ this.shadowList.remove();
1883
+ $(document).off('.datalist'+this.id);
1884
+ $(window).off('.datalist'+this.id);
1885
+ if(this.input.form && this.input.id){
1886
+ $(this.input.form).off('submit.datalistWidget'+this.input.id);
1887
+ }
1888
+ this.input.removeAttribute('aria-haspopup');
1889
+ if(autocomplete === undefined){
1890
+ this.input.removeAttribute('autocomplete');
1891
+ } else {
1892
+ $(this.input).attr('autocomplete', autocomplete);
1893
+ }
1894
+ if(e && e.type == 'beforeunload'){
1895
+ input = this.input;
1896
+ setTimeout(function(){
1897
+ $.attr(input, 'list', $.attr(input, 'list'));
1898
+ }, 9);
1899
+ }
1900
+ this._destroyed = true;
1901
+ }
1902
+ };
1903
+
1904
+ webshims.loader.addModule('form-datalist-lazy', {
1905
+ noAutoCallback: true,
1906
+ options: $.extend(options, {shadowListProto: shadowListProto})
1907
+ });
1908
+ if(!options.list){
1909
+ options.list = {};
1910
+ }
1911
+ //init datalist update
1912
+ initializeDatalist();
1913
+ })();
1914
+
1915
+ });