webshims-rails 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. data/lib/webshims-rails/version.rb +2 -2
  2. data/vendor/assets/javascripts/webshims/extras/custom-validity.js +261 -261
  3. data/vendor/assets/javascripts/webshims/extras/modernizr-custom.js +534 -534
  4. data/vendor/assets/javascripts/webshims/extras/mousepress.js +60 -60
  5. data/vendor/assets/javascripts/webshims/minified/extras/custom-validity.js +1 -1
  6. data/vendor/assets/javascripts/webshims/minified/polyfiller.js +24 -24
  7. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/README +82 -82
  8. data/vendor/assets/javascripts/webshims/minified/shims/combos/1.js +35 -34
  9. data/vendor/assets/javascripts/webshims/minified/shims/combos/10.js +79 -82
  10. data/vendor/assets/javascripts/webshims/minified/shims/combos/11.js +45 -44
  11. data/vendor/assets/javascripts/webshims/minified/shims/combos/12.js +43 -42
  12. data/vendor/assets/javascripts/webshims/minified/shims/combos/13.js +28 -27
  13. data/vendor/assets/javascripts/webshims/minified/shims/combos/15.js +4 -4
  14. data/vendor/assets/javascripts/webshims/minified/shims/combos/16.js +57 -59
  15. data/vendor/assets/javascripts/webshims/minified/shims/combos/17.js +64 -66
  16. data/vendor/assets/javascripts/webshims/minified/shims/combos/18.js +53 -54
  17. data/vendor/assets/javascripts/webshims/minified/shims/combos/19.js +64 -66
  18. data/vendor/assets/javascripts/webshims/minified/shims/combos/2.js +72 -73
  19. data/vendor/assets/javascripts/webshims/minified/shims/combos/20.js +42 -46
  20. data/vendor/assets/javascripts/webshims/minified/shims/combos/21.js +52 -50
  21. data/vendor/assets/javascripts/webshims/minified/shims/combos/22.js +55 -59
  22. data/vendor/assets/javascripts/webshims/minified/shims/combos/23.js +66 -64
  23. data/vendor/assets/javascripts/webshims/minified/shims/combos/24.js +80 -82
  24. data/vendor/assets/javascripts/webshims/minified/shims/combos/25.js +60 -59
  25. data/vendor/assets/javascripts/webshims/minified/shims/combos/26.js +79 -81
  26. data/vendor/assets/javascripts/webshims/minified/shims/combos/27.js +101 -104
  27. data/vendor/assets/javascripts/webshims/minified/shims/combos/3.js +94 -95
  28. data/vendor/assets/javascripts/webshims/minified/shims/combos/4.js +26 -29
  29. data/vendor/assets/javascripts/webshims/minified/shims/combos/5.js +33 -36
  30. data/vendor/assets/javascripts/webshims/minified/shims/combos/59.js +51 -54
  31. data/vendor/assets/javascripts/webshims/minified/shims/combos/6.js +27 -28
  32. data/vendor/assets/javascripts/webshims/minified/shims/combos/7.js +27 -28
  33. data/vendor/assets/javascripts/webshims/minified/shims/combos/8.js +39 -38
  34. data/vendor/assets/javascripts/webshims/minified/shims/combos/9.js +65 -68
  35. data/vendor/assets/javascripts/webshims/minified/shims/details.js +4 -4
  36. data/vendor/assets/javascripts/webshims/minified/shims/dom-extend.js +23 -22
  37. data/vendor/assets/javascripts/webshims/minified/shims/form-core.js +19 -22
  38. data/vendor/assets/javascripts/webshims/minified/shims/form-datalist.js +14 -14
  39. data/vendor/assets/javascripts/webshims/minified/shims/form-number-date-api.js +9 -9
  40. data/vendor/assets/javascripts/webshims/minified/shims/form-number-date-ui.js +18 -19
  41. data/vendor/assets/javascripts/webshims/minified/shims/form-shim-extend.js +45 -43
  42. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-de.txt +33 -33
  43. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-en.txt +34 -34
  44. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-core.js +12 -12
  45. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-jaris.js +23 -0
  46. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-native-fix.js +1 -1
  47. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-swf.js +26 -30
  48. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-yt.js +3 -3
  49. data/vendor/assets/javascripts/webshims/minified/shims/styles/shim.css +689 -686
  50. data/vendor/assets/javascripts/webshims/minified/shims/swf/JarisFLVPlayer.swf +0 -0
  51. data/vendor/assets/javascripts/webshims/minified/shims/track-ui.js +9 -9
  52. data/vendor/assets/javascripts/webshims/minified/shims/track.js +21 -21
  53. data/vendor/assets/javascripts/webshims/polyfiller.js +1191 -1175
  54. data/vendor/assets/javascripts/webshims/shims/combos/1.js +1754 -1714
  55. data/vendor/assets/javascripts/webshims/shims/combos/10.js +3247 -3320
  56. data/vendor/assets/javascripts/webshims/shims/combos/11.js +1633 -1588
  57. data/vendor/assets/javascripts/webshims/shims/combos/12.js +1636 -1591
  58. data/vendor/assets/javascripts/webshims/shims/combos/13.js +1100 -1058
  59. data/vendor/assets/javascripts/webshims/shims/combos/14.js +476 -476
  60. data/vendor/assets/javascripts/webshims/shims/combos/15.js +316 -314
  61. data/vendor/assets/javascripts/webshims/shims/combos/16.js +2094 -2104
  62. data/vendor/assets/javascripts/webshims/shims/combos/17.js +2258 -2267
  63. data/vendor/assets/javascripts/webshims/shims/combos/18.js +1380 -1364
  64. data/vendor/assets/javascripts/webshims/shims/combos/19.js +2239 -2247
  65. data/vendor/assets/javascripts/webshims/shims/combos/2.js +2339 -2294
  66. data/vendor/assets/javascripts/webshims/shims/combos/20.js +1493 -1606
  67. data/vendor/assets/javascripts/webshims/shims/combos/21.js +1733 -1635
  68. data/vendor/assets/javascripts/webshims/shims/combos/22.js +2295 -2408
  69. data/vendor/assets/javascripts/webshims/shims/combos/23.js +2269 -2168
  70. data/vendor/assets/javascripts/webshims/shims/combos/24.js +2775 -2780
  71. data/vendor/assets/javascripts/webshims/shims/combos/25.js +1505 -1456
  72. data/vendor/assets/javascripts/webshims/shims/combos/26.js +2111 -2115
  73. data/vendor/assets/javascripts/webshims/shims/combos/27.js +3264 -3331
  74. data/vendor/assets/javascripts/webshims/shims/combos/3.js +3020 -2970
  75. data/vendor/assets/javascripts/webshims/shims/combos/4.js +770 -822
  76. data/vendor/assets/javascripts/webshims/shims/combos/5.js +1025 -1077
  77. data/vendor/assets/javascripts/webshims/shims/combos/59.js +1706 -1753
  78. data/vendor/assets/javascripts/webshims/shims/combos/6.js +444 -433
  79. data/vendor/assets/javascripts/webshims/shims/combos/7.js +699 -688
  80. data/vendor/assets/javascripts/webshims/shims/combos/8.js +1488 -1445
  81. data/vendor/assets/javascripts/webshims/shims/combos/9.js +2445 -2518
  82. data/vendor/assets/javascripts/webshims/shims/details.js +148 -146
  83. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +952 -912
  84. data/vendor/assets/javascripts/webshims/shims/es5.js +802 -802
  85. data/vendor/assets/javascripts/webshims/shims/excanvas.js +924 -924
  86. data/vendor/assets/javascripts/webshims/shims/form-core.js +606 -659
  87. data/vendor/assets/javascripts/webshims/shims/form-datalist.js +681 -676
  88. data/vendor/assets/javascripts/webshims/shims/form-message.js +164 -163
  89. data/vendor/assets/javascripts/webshims/shims/form-native-extend.js +255 -255
  90. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +383 -383
  91. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +61 -50
  92. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +1569 -1472
  93. data/vendor/assets/javascripts/webshims/shims/geolocation.js +168 -168
  94. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ar.js +32 -32
  95. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ch-ZN.js +32 -32
  96. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-de.txt +33 -33
  97. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-el.js +32 -32
  98. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-en.txt +34 -34
  99. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-es.js +31 -31
  100. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-fr.js +32 -32
  101. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-he.js +32 -32
  102. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-hi.js +32 -32
  103. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-hu.js +32 -32
  104. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-it.js +32 -32
  105. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ja.js +32 -32
  106. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-nl.js +32 -32
  107. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-pt-PT.js +32 -32
  108. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ru.js +31 -31
  109. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-sv.js +32 -32
  110. data/vendor/assets/javascripts/webshims/shims/json-storage.js +308 -308
  111. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +536 -533
  112. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +861 -0
  113. data/vendor/assets/javascripts/webshims/shims/mediaelement-native-fix.js +98 -98
  114. data/vendor/assets/javascripts/webshims/shims/mediaelement-swf.js +957 -1073
  115. data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +543 -543
  116. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +689 -686
  117. data/vendor/assets/javascripts/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
  118. data/vendor/assets/javascripts/webshims/shims/track-ui.js +9 -8
  119. data/vendor/assets/javascripts/webshims/shims/track.js +17 -11
  120. metadata +6 -6
  121. data/vendor/assets/javascripts/webshims/minified/shims/form-native-fix.js +0 -7
  122. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/README +0 -62
  123. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/README +0 -82
  124. data/vendor/assets/javascripts/webshims/shims/form-native-fix.js +0 -261
@@ -1,2294 +1,2339 @@
1
- //additional tests for partial implementation of forms features
2
- (function($){
3
- var Modernizr = window.Modernizr;
4
- var webshims = $.webshims;
5
- var bugs = webshims.bugs;
6
- var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input type="date" required="" name="a" /><input type="submit" /></form>');
7
- var testRequiredFind = function(){
8
- if(form[0].querySelector){
9
- try {
10
- bugs.findRequired = !(form[0].querySelector('select:required'));
11
- } catch(er){
12
- bugs.findRequired = false;
13
- }
14
- }
15
- };
16
- bugs.findRequired = false;
17
- bugs.validationMessage = false;
18
- bugs.valueAsNumberSet = false;
19
-
20
- webshims.capturingEventPrevented = function(e){
21
- if(!e._isPolyfilled){
22
- var isDefaultPrevented = e.isDefaultPrevented;
23
- var preventDefault = e.preventDefault;
24
- e.preventDefault = function(){
25
- clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
26
- $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
27
- $.removeData(e.target, e.type + 'DefaultPrevented');
28
- }, 30));
29
- return preventDefault.apply(this, arguments);
30
- };
31
- e.isDefaultPrevented = function(){
32
- return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
33
- };
34
- e._isPolyfilled = true;
35
- }
36
- };
37
-
38
- if(!Modernizr.formvalidation || bugs.bustedValidity){
39
- testRequiredFind();
40
- return;
41
- }
42
-
43
- //create delegatable events
44
- webshims.capturingEvents(['input']);
45
- webshims.capturingEvents(['invalid'], true);
46
-
47
- Modernizr.bugfreeformvalidation = true;
48
- if(window.opera || $.browser.webkit || window.testGoodWithFix){
49
- var dateElem = $('input', form).eq(0);
50
- var timer;
51
- var onDomextend = function(fn){
52
- webshims.loader.loadList(['dom-extend']);
53
- webshims.ready('dom-extend', fn);
54
- };
55
- var loadFormFixes = function(e){
56
- var reTest = ['form-extend', 'form-message', 'form-native-fix'];
57
- if(e){
58
- e.preventDefault();
59
- e.stopImmediatePropagation();
60
- }
61
- clearTimeout(timer);
62
- setTimeout(function(){
63
- if(!form){return;}
64
- form.remove();
65
- form = dateElem = null;
66
- }, 9);
67
- if(!Modernizr.bugfreeformvalidation){
68
- webshims.addPolyfill('form-native-fix', {
69
- f: 'forms',
70
- d: ['form-extend']
71
- });
72
- //remove form-extend readyness
73
- webshims.modules['form-extend'].test = $.noop;
74
- }
75
-
76
- if(webshims.isReady('form-number-date-api')){
77
- reTest.push('form-number-date-api');
78
- }
79
-
80
- webshims.reTest(reTest);
81
-
82
- if(dateElem){
83
- try {
84
- if(dateElem.prop({disabled: true, value: ''}).prop('disabled', false).is(':valid')){
85
- onDomextend(function(){
86
- webshims.onNodeNamesPropertyModify(['input', 'textarea'], ['disabled', 'readonly'], {
87
- set: function(val){
88
- var elem = this;
89
- if(!val && elem){
90
- $.prop(elem, 'value', $.prop(elem, 'value'));
91
- }
92
- }
93
- });
94
- webshims.onNodeNamesPropertyModify(['select'], ['disabled', 'readonly'], {
95
- set: function(val){
96
- var elem = this;
97
- if(!val && elem){
98
- val = $(elem).val();
99
- ($('option:last-child', elem)[0] || {}).selected = true;
100
- $(elem).val( val );
101
- }
102
- }
103
- });
104
- });
105
- }
106
- } catch(er){}
107
- }
108
-
109
- if ($.browser.opera || window.testGoodWithFix) {
110
- onDomextend(function(){
111
-
112
- //Opera shows native validation bubbles in case of input.checkValidity()
113
- // Opera 11.6/12 hasn't fixed this issue right, it's buggy
114
- var preventDefault = function(e){
115
- e.preventDefault();
116
- };
117
-
118
- ['form', 'input', 'textarea', 'select'].forEach(function(name){
119
- var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
120
- prop: {
121
- value: function(){
122
- if (!webshims.fromSubmit) {
123
- $(this).bind('invalid.checkvalidity', preventDefault);
124
- }
125
-
126
- webshims.fromCheckValidity = true;
127
- var ret = desc.prop._supvalue.apply(this, arguments);
128
- if (!webshims.fromSubmit) {
129
- $(this).unbind('invalid.checkvalidity', preventDefault);
130
- }
131
- webshims.fromCheckValidity = false;
132
- return ret;
133
- }
134
- }
135
- });
136
- });
137
-
138
- });
139
- }
140
- };
141
-
142
- form.appendTo('head');
143
- if(window.opera || window.testGoodWithFix) {
144
- testRequiredFind();
145
- bugs.validationMessage = !(dateElem.prop('validationMessage'));
146
- if((Modernizr.inputtypes || {}).date){
147
- try {
148
- dateElem.prop('valueAsNumber', 0);
149
- } catch(er){}
150
- bugs.valueAsNumberSet = (dateElem.prop('value') != '1970-01-01');
151
- }
152
- dateElem.prop('value', '');
153
- }
154
-
155
- form.bind('submit', function(e){
156
- Modernizr.bugfreeformvalidation = false;
157
- loadFormFixes(e);
158
- });
159
-
160
- timer = setTimeout(function(){
161
- if (form) {
162
- form.triggerHandler('submit');
163
- }
164
- }, 9);
165
-
166
- $('input, select', form).bind('invalid', loadFormFixes)
167
- .filter('[type="submit"]')
168
- .bind('click', function(e){
169
- e.stopImmediatePropagation();
170
- })
171
- .trigger('click')
172
- ;
173
-
174
- if($.browser.webkit && Modernizr.bugfreeformvalidation && !webshims.bugs.bustedValidity){
175
- (function(){
176
- var elems = /^(?:textarea|input)$/i;
177
- var form = false;
178
-
179
- document.addEventListener('contextmenu', function(e){
180
- if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
181
- setTimeout(function(){
182
- form = false;
183
- }, 1);
184
- }
185
- }, false);
186
-
187
- $(window).bind('invalid', function(e){
188
- if(e.originalEvent && form && form == e.target.form){
189
- e.wrongWebkitInvalid = true;
190
- e.stopImmediatePropagation();
191
- }
192
- });
193
- })();
194
- }
195
- }
196
-
197
- })(jQuery);
198
-
199
- jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
200
- "use strict";
201
-
202
- var groupTypes = {radio: 1};
203
- var checkTypes = {checkbox: 1, radio: 1};
204
- var emptyJ = $([]);
205
- var bugs = webshims.bugs;
206
- var getGroupElements = function(elem){
207
- elem = $(elem);
208
- var name;
209
- var form;
210
- var ret = emptyJ;
211
- if(groupTypes[elem[0].type]){
212
- form = elem.prop('form');
213
- name = elem[0].name;
214
- if(!name){
215
- ret = elem;
216
- } else if(form){
217
- ret = $(form[name]);
218
- } else {
219
- ret = $(document.getElementsByName(name)).filter(function(){
220
- return !$.prop(this, 'form');
221
- });
222
- }
223
- ret = ret.filter('[type="radio"]');
224
- }
225
- return ret;
226
- };
227
-
228
- var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
229
- var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
230
- if(key && message[key]){
231
- message = message[key];
232
- }
233
- if(typeof message == 'object'){
234
- validity = validity || $.prop(elem, 'validity') || {valid: 1};
235
- if(!validity.valid){
236
- $.each(validity, function(name, prop){
237
- if(prop && name != 'valid' && message[name]){
238
- message = message[name];
239
- return false;
240
- }
241
- });
242
- }
243
- }
244
-
245
- if(typeof message == 'object'){
246
- message = message.defaultMessage;
247
- }
248
- return message || '';
249
- };
250
-
251
- /*
252
- * Selectors for all browsers
253
- */
254
- var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
255
- $.extend($.expr[":"], {
256
- "valid-element": function(elem){
257
- return !!($.prop(elem, 'willValidate') && ($.prop(elem, 'validity') || {valid: 1}).valid);
258
- },
259
- "invalid-element": function(elem){
260
- return !!($.prop(elem, 'willValidate') && !isValid(elem));
261
- },
262
- "required-element": function(elem){
263
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
264
- },
265
- "optional-element": function(elem){
266
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
267
- },
268
- "in-range": function(elem){
269
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
270
- return false;
271
- }
272
- var val = $.prop(elem, 'validity');
273
- return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
274
- },
275
- "out-of-range": function(elem){
276
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
277
- return false;
278
- }
279
- var val = $.prop(elem, 'validity');
280
- return !!(val && (val.rangeOverflow || val.rangeUnderflow));
281
- }
282
-
283
- });
284
-
285
- ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
286
- $.expr[":"][name] = $.expr.filters[name+"-element"];
287
- });
288
-
289
-
290
- $.expr[":"].focus = function( elem ) {
291
- try {
292
- var doc = elem.ownerDocument;
293
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
294
- } catch(e){}
295
- return false;
296
- };
297
-
298
- var customEvents = $.event.customEvent || {};
299
- var isValid = function(elem){
300
- return ($.prop(elem, 'validity') || {valid: 1}).valid;
301
- };
302
-
303
- if (bugs.bustedValidity || bugs.findRequired || !Modernizr.bugfreeformvalidation) {
304
- (function(){
305
- var find = $.find;
306
- var matchesSelector = $.find.matchesSelector;
307
-
308
- var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
309
- var regFn = function(sel){
310
- return sel + '-element';
311
- };
312
-
313
- $.find = (function(){
314
- var slice = Array.prototype.slice;
315
- var fn = function(sel){
316
- var ar = arguments;
317
- ar = slice.call(ar, 1, ar.length);
318
- ar.unshift(sel.replace(regExp, regFn));
319
- return find.apply(this, ar);
320
- };
321
- for (var i in find) {
322
- if(find.hasOwnProperty(i)){
323
- fn[i] = find[i];
324
- }
325
- }
326
- return fn;
327
- })();
328
- if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
329
- $.find.matchesSelector = function(node, expr){
330
- expr = expr.replace(regExp, regFn);
331
- return matchesSelector.call(this, node, expr);
332
- };
333
- }
334
-
335
- })();
336
- }
337
-
338
- //ToDo needs testing
339
- var oldAttr = $.prop;
340
- var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
341
- $.prop = function(elem, name, val){
342
- var ret = oldAttr.apply(this, arguments);
343
- if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass('form-ui-invalid')){
344
- if(isValid(elem)){
345
- $(elem).getShadowElement().removeClass('form-ui-invalid');
346
- if(name == 'checked' && val) {
347
- getGroupElements(elem).not(elem).removeClass('form-ui-invalid').removeAttr('aria-invalid');
348
- }
349
- }
350
- }
351
- return ret;
352
- };
353
-
354
- var returnValidityCause = function(validity, elem){
355
- var ret;
356
- $.each(validity, function(name, value){
357
- if(value){
358
- ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
359
- return false;
360
- }
361
- });
362
- return ret;
363
- };
364
-
365
- var switchValidityClass = function(e){
366
- var elem, timer;
367
- if(!e.target){return;}
368
- elem = $(e.target).getNativeElement()[0];
369
- if(elem.type == 'submit' || !$.prop(elem, 'willValidate') || (e.type == 'focusout' && e.type == 'radio')){return;}
370
- timer = $.data(elem, 'webshimsswitchvalidityclass');
371
- var switchClass = function(){
372
- var validity = $.prop(elem, 'validity');
373
- var shadowElem = $(elem).getShadowElement();
374
- var addClass, removeClass, trigger, generaltrigger, validityCause;
375
-
376
- $(elem).trigger('refreshCustomValidityRules');
377
- if(validity.valid){
378
- if(!shadowElem.hasClass('form-ui-valid')){
379
- addClass = 'form-ui-valid';
380
- removeClass = 'form-ui-invalid';
381
- generaltrigger = 'changedvaliditystate';
382
- trigger = 'changedvalid';
383
- if(checkTypes[elem.type] && elem.checked){
384
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
385
- }
386
- $.removeData(elem, 'webshimsinvalidcause');
387
- }
388
- } else {
389
- validityCause = returnValidityCause(validity, elem);
390
- if($.data(elem, 'webshimsinvalidcause') != validityCause){
391
- $.data(elem, 'webshimsinvalidcause', validityCause);
392
- generaltrigger = 'changedvaliditystate';
393
- }
394
- if(!shadowElem.hasClass('form-ui-invalid')){
395
- addClass = 'form-ui-invalid';
396
- removeClass = 'form-ui-valid';
397
- if (checkTypes[elem.type] && !elem.checked) {
398
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
399
- }
400
- trigger = 'changedinvalid';
401
- }
402
- }
403
- if(addClass){
404
- shadowElem.addClass(addClass).removeClass(removeClass);
405
- //jQuery 1.6.1 IE9 bug (doubble trigger bug)
406
- setTimeout(function(){
407
- $(elem).trigger(trigger);
408
- }, 0);
409
- }
410
- if(generaltrigger){
411
- setTimeout(function(){
412
- $(elem).trigger(generaltrigger);
413
- }, 0);
414
- }
415
- $.removeData(e.target, 'webshimsswitchvalidityclass');
416
-
417
- };
418
- if(timer){
419
- clearTimeout(timer);
420
- }
421
- if(e.type == 'refreshvalidityui'){
422
- switchClass();
423
- } else {
424
- $.data(e.target, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
425
- }
426
- };
427
-
428
- $(document).bind(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
429
- customEvents.changedvaliditystate = true;
430
- customEvents.refreshCustomValidityRules = true;
431
- customEvents.changedvalid = true;
432
- customEvents.changedinvalid = true;
433
- customEvents.refreshvalidityui = true;
434
-
435
-
436
- webshims.triggerInlineForm = function(elem, event){
437
- $(elem).trigger(event);
438
- };
439
-
440
- webshims.modules["form-core"].getGroupElements = getGroupElements;
441
-
442
-
443
- var setRoot = function(){
444
- webshims.scrollRoot = ($.browser.webkit || document.compatMode == 'BackCompat') ?
445
- $(document.body) :
446
- $(document.documentElement)
447
- ;
448
- };
449
- setRoot();
450
- webshims.ready('DOM', setRoot);
451
-
452
- webshims.getRelOffset = function(posElem, relElem){
453
- posElem = $(posElem);
454
- var offset = $(relElem).offset();
455
- var bodyOffset;
456
- $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
457
- bodyOffset = posElem.offset();
458
- });
459
- offset.top -= bodyOffset.top;
460
- offset.left -= bodyOffset.left;
461
- return offset;
462
- };
463
-
464
- /* some extra validation UI */
465
- webshims.validityAlert = (function(){
466
- var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label';
467
- var errorBubble;
468
- var hideTimer = false;
469
- var focusTimer = false;
470
- var resizeTimer = false;
471
- var boundHide;
472
-
473
- var api = {
474
- hideDelay: 5000,
475
-
476
- showFor: function(elem, message, noFocusElem, noBubble){
477
- api._create();
478
- elem = $(elem);
479
- var visual = $(elem).getShadowElement();
480
- var offset = api.getOffsetFromBody(visual);
481
- api.clear();
482
- if(noBubble){
483
- this.hide();
484
- } else {
485
- this.getMessage(elem, message);
486
- this.position(visual, offset);
487
-
488
- this.show();
489
- if(this.hideDelay){
490
- hideTimer = setTimeout(boundHide, this.hideDelay);
491
- }
492
- $(window)
493
- .bind('resize.validityalert', function(){
494
- clearTimeout(resizeTimer);
495
- resizeTimer = setTimeout(function(){
496
- api.position(visual);
497
- }, 9);
498
- })
499
- ;
500
- }
501
-
502
- if(!noFocusElem){
503
- this.setFocus(visual, offset);
504
- }
505
- },
506
- getOffsetFromBody: function(elem){
507
- return webshims.getRelOffset(errorBubble, elem);
508
- },
509
- setFocus: function(visual, offset){
510
- var focusElem = $(visual).getShadowFocusElement();
511
- var scrollTop = webshims.scrollRoot.scrollTop();
512
- var elemTop = ((offset || focusElem.offset()).top) - 30;
513
- var smooth;
514
-
515
- if(webshims.getID && alertElem == 'label'){
516
- errorBubble.attr('for', webshims.getID(focusElem));
517
- }
518
-
519
- if(scrollTop > elemTop){
520
- webshims.scrollRoot.animate(
521
- {scrollTop: elemTop - 5},
522
- {
523
- queue: false,
524
- duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
525
- }
526
- );
527
- smooth = true;
528
- }
529
- try {
530
- focusElem[0].focus();
531
- } catch(e){}
532
- if(smooth){
533
- webshims.scrollRoot.scrollTop(scrollTop);
534
- setTimeout(function(){
535
- webshims.scrollRoot.scrollTop(scrollTop);
536
- }, 0);
537
- }
538
- setTimeout(function(){
539
- $(document).bind('focusout.validityalert', boundHide);
540
- }, 10);
541
- },
542
- getMessage: function(elem, message){
543
- if (!message) {
544
- message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage');
545
- }
546
- if (message) {
547
- $('span.va-box', errorBubble).text(message);
548
- }
549
- else {
550
- this.hide();
551
- }
552
- },
553
- position: function(elem, offset){
554
- offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
555
- offset.top += elem.outerHeight();
556
- errorBubble.css(offset);
557
- },
558
- show: function(){
559
- if(errorBubble.css('display') === 'none'){
560
- errorBubble.css({opacity: 0}).show();
561
- }
562
- errorBubble.addClass('va-visible').fadeTo(400, 1);
563
- },
564
- hide: function(){
565
- errorBubble.removeClass('va-visible').fadeOut();
566
- },
567
- clear: function(){
568
- clearTimeout(focusTimer);
569
- clearTimeout(hideTimer);
570
- $(document).unbind('.validityalert');
571
- $(window).unbind('.validityalert');
572
- errorBubble.stop().removeAttr('for');
573
- },
574
- _create: function(){
575
- if(errorBubble){return;}
576
- errorBubble = api.errorBubble = $('<'+alertElem+' class="validity-alert-wrapper" role="alert"><span class="validity-alert"><span class="va-arrow"><span class="va-arrow-box"></span></span><span class="va-box"></span></span></'+alertElem+'>').css({position: 'absolute', display: 'none'});
577
- webshims.ready('DOM', function(){
578
- errorBubble.appendTo('body');
579
- if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){
580
- errorBubble.bgIframe();
581
- }
582
- });
583
- }
584
- };
585
-
586
-
587
- boundHide = $.proxy(api, 'hide');
588
-
589
- return api;
590
- })();
591
-
592
-
593
- /* extension, but also used to fix native implementation workaround/bugfixes */
594
- (function(){
595
- var firstEvent,
596
- invalids = [],
597
- stopSubmitTimer,
598
- form
599
- ;
600
-
601
- $(document).bind('invalid', function(e){
602
- if(e.wrongWebkitInvalid){return;}
603
- var jElm = $(e.target);
604
- var shadowElem = jElm.getShadowElement();
605
- if(!shadowElem.hasClass('form-ui-invalid')){
606
- shadowElem.addClass('form-ui-invalid').removeClass('form-ui-valid');
607
- setTimeout(function(){
608
- $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
609
- }, 0);
610
- }
611
-
612
- if(!firstEvent){
613
- //trigger firstinvalid
614
- firstEvent = $.Event('firstinvalid');
615
- firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
616
- var firstSystemInvalid = $.Event('firstinvalidsystem');
617
- $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
618
- jElm.trigger(firstEvent);
619
- }
620
-
621
- //if firstinvalid was prevented all invalids will be also prevented
622
- if( firstEvent && firstEvent.isDefaultPrevented() ){
623
- e.preventDefault();
624
- }
625
- invalids.push(e.target);
626
- e.extraData = 'fix';
627
- clearTimeout(stopSubmitTimer);
628
- stopSubmitTimer = setTimeout(function(){
629
- var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
630
- //reset firstinvalid
631
- firstEvent = false;
632
- invalids = [];
633
- $(e.target).trigger(lastEvent, lastEvent);
634
- }, 9);
635
- jElm = null;
636
- shadowElem = null;
637
- });
638
- })();
639
-
640
- $.fn.getErrorMessage = function(){
641
- var message = '';
642
- var elem = this[0];
643
- if(elem){
644
- message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
645
- }
646
- return message;
647
- };
648
-
649
- if(options.replaceValidationUI){
650
- webshims.ready('DOM forms', function(){
651
- $(document).bind('firstinvalid', function(e){
652
- if(!e.isInvalidUIPrevented()){
653
- e.preventDefault();
654
- $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') );
655
- }
656
- });
657
- });
658
- }
659
-
660
- });jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
661
- var validityMessages = webshims.validityMessages;
662
-
663
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
664
-
665
- validityMessages['en'] = $.extend(true, {
666
- typeMismatch: {
667
- email: 'Please enter an email address.',
668
- url: 'Please enter a URL.',
669
- number: 'Please enter a number.',
670
- date: 'Please enter a date.',
671
- time: 'Please enter a time.',
672
- range: 'Invalid input.',
673
- "datetime-local": 'Please enter a datetime.'
674
- },
675
- rangeUnderflow: {
676
- defaultMessage: 'Value must be greater than or equal to {%min}.'
677
- },
678
- rangeOverflow: {
679
- defaultMessage: 'Value must be less than or equal to {%max}.'
680
- },
681
- stepMismatch: 'Invalid input.',
682
- tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
683
-
684
- patternMismatch: 'Invalid input. {%title}',
685
- valueMissing: {
686
- defaultMessage: 'Please fill out this field.',
687
- checkbox: 'Please check this box if you want to proceed.'
688
- }
689
- }, (validityMessages['en'] || validityMessages['en-US'] || {}));
690
-
691
-
692
- ['select', 'radio'].forEach(function(type){
693
- validityMessages['en'].valueMissing[type] = 'Please select an option.';
694
- });
695
-
696
- ['date', 'time', 'datetime-local'].forEach(function(type){
697
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
698
- });
699
- ['date', 'time', 'datetime-local'].forEach(function(type){
700
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
701
- });
702
-
703
- validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
704
- validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
705
-
706
- validityMessages['de'] = $.extend(true, {
707
- typeMismatch: {
708
- email: '{%value} ist keine zulässige E-Mail-Adresse',
709
- url: '{%value} ist keine zulässige Webadresse',
710
- number: '{%value} ist keine Nummer!',
711
- date: '{%value} ist kein Datum',
712
- time: '{%value} ist keine Uhrzeit',
713
- range: '{%value} ist keine Nummer!',
714
- "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
715
- },
716
- rangeUnderflow: {
717
- defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
718
- },
719
- rangeOverflow: {
720
- defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
721
- },
722
- stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
723
- tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
724
- patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
725
- valueMissing: {
726
- defaultMessage: 'Bitte geben Sie einen Wert ein',
727
- checkbox: 'Bitte aktivieren Sie das Kästchen'
728
- }
729
- }, (validityMessages['de'] || {}));
730
-
731
- ['select', 'radio'].forEach(function(type){
732
- validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
733
- });
734
-
735
- ['date', 'time', 'datetime-local'].forEach(function(type){
736
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
737
- });
738
- ['date', 'time', 'datetime-local'].forEach(function(type){
739
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
740
- });
741
-
742
- var currentValidationMessage = validityMessages[''];
743
-
744
-
745
- webshims.createValidationMessage = function(elem, name){
746
- var message = currentValidationMessage[name];
747
- if(message && typeof message !== 'string'){
748
- message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
749
- }
750
- if(message){
751
- ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
752
- if(message.indexOf('{%'+attr) === -1){return;}
753
- var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
754
- if(name == 'patternMismatch' && attr == 'title' && !val){
755
- webshims.error('no title for patternMismatch provided. Always add a title attribute.');
756
- }
757
- message = message.replace('{%'+ attr +'}', val);
758
- if('value' == attr){
759
- message = message.replace('{%valueLen}', val.length);
760
- }
761
- });
762
- }
763
- return message || '';
764
- };
765
-
766
-
767
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
768
- implementProperties.push('validationMessage');
769
- }
770
-
771
- webshims.activeLang({
772
- langObj: validityMessages,
773
- module: 'form-core',
774
- callback: function(langObj){
775
- currentValidationMessage = langObj;
776
- }
777
- });
778
-
779
- implementProperties.forEach(function(messageProp){
780
- webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
781
- prop: {
782
- value: '',
783
- writeable: false
784
- }
785
- });
786
- ['input', 'select', 'textarea'].forEach(function(nodeName){
787
- var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
788
- prop: {
789
- get: function(){
790
- var elem = this;
791
- var message = '';
792
- if(!$.prop(elem, 'willValidate')){
793
- return message;
794
- }
795
-
796
- var validity = $.prop(elem, 'validity') || {valid: 1};
797
-
798
- if(validity.valid){return message;}
799
- message = webshims.getContentValidationMessage(elem, validity);
800
-
801
- if(message){return message;}
802
-
803
- if(validity.customError && elem.nodeName){
804
- message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
805
- if(message){return message;}
806
- }
807
- $.each(validity, function(name, prop){
808
- if(name == 'valid' || !prop){return;}
809
-
810
- message = webshims.createValidationMessage(elem, name);
811
- if(message){
812
- return false;
813
- }
814
- });
815
- return message || '';
816
- },
817
- writeable: false
818
- }
819
- });
820
- });
821
-
822
- });
823
- });if(!Modernizr.formvalidation || jQuery.webshims.bugs.bustedValidity){
824
- jQuery.webshims.register('form-extend', function($, webshims, window, document){
825
- webshims.inputTypes = webshims.inputTypes || {};
826
- //some helper-functions
827
- var cfg = webshims.cfg.forms;
828
- var isSubmit;
829
-
830
- var isNumber = function(string){
831
- return (typeof string == 'number' || (string && string == string * 1));
832
- },
833
- typeModels = webshims.inputTypes,
834
- checkTypes = {
835
- radio: 1,
836
- checkbox: 1
837
- },
838
- getType = function(elem){
839
- return (elem.getAttribute('type') || elem.type || '').toLowerCase();
840
- }
841
- ;
842
-
843
- //API to add new input types
844
- webshims.addInputType = function(type, obj){
845
- typeModels[type] = obj;
846
- };
847
-
848
- //contsrain-validation-api
849
- var validityPrototype = {
850
- customError: false,
851
-
852
- typeMismatch: false,
853
- rangeUnderflow: false,
854
- rangeOverflow: false,
855
- stepMismatch: false,
856
- tooLong: false,
857
- patternMismatch: false,
858
- valueMissing: false,
859
-
860
- valid: true
861
- };
862
-
863
- var isPlaceholderOptionSelected = function(select){
864
- if(select.type == 'select-one' && select.size < 2){
865
- var option = $('> option:first-child', select);
866
- return !!option.prop('selected');
867
- }
868
- return false;
869
- };
870
-
871
- var validityRules = {
872
- valueMissing: function(input, val, cache){
873
- if(!input.prop('required')){return false;}
874
- var ret = false;
875
- if(!('type' in cache)){
876
- cache.type = getType(input[0]);
877
- }
878
- if(cache.nodeName == 'select'){
879
- ret = (!val && (input[0].selectedIndex < 0 || isPlaceholderOptionSelected(input[0]) ));
880
- } else if(checkTypes[cache.type]){
881
- ret = (cache.type == 'checkbox') ? !input.is(':checked') : !webshims.modules["form-core"].getGroupElements(input).filter(':checked')[0];
882
- } else {
883
- ret = !(val);
884
- }
885
- return ret;
886
- },
887
- tooLong: function(input, val, cache){
888
- return false;
889
- },
890
- typeMismatch: function (input, val, cache){
891
- if(val === '' || cache.nodeName == 'select'){return false;}
892
- var ret = false;
893
- if(!('type' in cache)){
894
- cache.type = getType(input[0]);
895
- }
896
-
897
- if(typeModels[cache.type] && typeModels[cache.type].mismatch){
898
- ret = typeModels[cache.type].mismatch(val, input);
899
- } else if('validity' in input[0]){
900
- ret = input[0].validity.typeMismatch;
901
- }
902
- return ret;
903
- },
904
- patternMismatch: function(input, val, cache) {
905
- if(val === '' || cache.nodeName == 'select'){return false;}
906
- var pattern = input.attr('pattern');
907
- if(!pattern){return false;}
908
- try {
909
- pattern = new RegExp('^(?:' + pattern + ')$');
910
- } catch(er){
911
- webshims.error('invalid pattern value: "'+ pattern +'" | '+ er);
912
- pattern = false;
913
- }
914
- if(!pattern){return false;}
915
- return !(pattern.test(val));
916
- }
917
- }
918
- ;
919
-
920
- webshims.addValidityRule = function(type, fn){
921
- validityRules[type] = fn;
922
- };
923
-
924
- $.event.special.invalid = {
925
- add: function(){
926
- $.event.special.invalid.setup.call(this.form || this);
927
- },
928
- setup: function(){
929
- var form = this.form || this;
930
- if( $.data(form, 'invalidEventShim') ){
931
- form = null;
932
- return;
933
- }
934
- $(form)
935
- .data('invalidEventShim', true)
936
- .bind('submit', $.event.special.invalid.handler)
937
- ;
938
- webshims.moveToFirstEvent(form, 'submit');
939
- if(webshims.bugs.bustedValidity && $.nodeName(form, 'form')){
940
- (function(){
941
- var noValidate = form.getAttribute('novalidate');
942
- form.setAttribute('novalidate', 'novalidate');
943
- webshims.data(form, 'bustedNoValidate', (noValidate == null) ? null : noValidate);
944
- })();
945
- }
946
- form = null;
947
- },
948
- teardown: $.noop,
949
- handler: function(e, d){
950
-
951
- if( e.type != 'submit' || e.testedValidity || !e.originalEvent || !$.nodeName(e.target, 'form') || $.prop(e.target, 'noValidate') ){return;}
952
-
953
- isSubmit = true;
954
- e.testedValidity = true;
955
- var notValid = !($(e.target).checkValidity());
956
- if(notValid){
957
- e.stopImmediatePropagation();
958
- isSubmit = false;
959
- return false;
960
- }
961
- isSubmit = false;
962
- }
963
- };
964
-
965
- var addSubmitBubbles = function(form){
966
- if (!$.support.submitBubbles && form && typeof form == 'object' && !form._submit_attached ) {
967
-
968
- $.event.add( form, 'submit._submit', function( event ) {
969
- event._submit_bubble = true;
970
- });
971
-
972
- form._submit_attached = true;
973
- }
974
- };
975
- if(!$.support.submitBubbles && $.event.special.submit){
976
- $.event.special.submit.setup = function() {
977
- // Only need this for delegated form submit events
978
- if ( $.nodeName( this, "form" ) ) {
979
- return false;
980
- }
981
-
982
- // Lazy-add a submit handler when a descendant form may potentially be submitted
983
- $.event.add( this, "click._submit keypress._submit", function( e ) {
984
- // Node name check avoids a VML-related crash in IE (#9807)
985
- var elem = e.target,
986
- form = $.nodeName( elem, 'input' ) || $.nodeName( elem, 'button' ) ? $.prop(elem, 'form') : undefined;
987
- addSubmitBubbles(form);
988
-
989
- });
990
- // return undefined since we don't need an event listener
991
- };
992
- }
993
-
994
- $.event.special.submit = $.event.special.submit || {setup: function(){return false;}};
995
- var submitSetup = $.event.special.submit.setup;
996
- $.extend($.event.special.submit, {
997
- setup: function(){
998
- if($.nodeName(this, 'form')){
999
- $(this).bind('invalid', $.noop);
1000
- } else {
1001
- $('form', this).bind('invalid', $.noop);
1002
- }
1003
- return submitSetup.apply(this, arguments);
1004
- }
1005
- });
1006
-
1007
- $(window).bind('invalid', $.noop);
1008
-
1009
-
1010
- webshims.addInputType('email', {
1011
- mismatch: (function(){
1012
- //taken from http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
1013
- var test = cfg.emailReg || /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
1014
- return function(val){
1015
- return !test.test(val);
1016
- };
1017
- })()
1018
- });
1019
-
1020
- webshims.addInputType('url', {
1021
- mismatch: (function(){
1022
- //taken from scott gonzales
1023
- 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;
1024
- return function(val){
1025
- return !test.test(val);
1026
- };
1027
- })()
1028
- });
1029
-
1030
- webshims.defineNodeNameProperty('input', 'type', {
1031
- prop: {
1032
- get: function(){
1033
- var elem = this;
1034
- var type = (elem.getAttribute('type') || '').toLowerCase();
1035
- return (webshims.inputTypes[type]) ? type : elem.type;
1036
- }
1037
- }
1038
- });
1039
-
1040
- // IDLs for constrain validation API
1041
- //ToDo: add object to this list
1042
- webshims.defineNodeNamesProperties(['button', 'fieldset', 'output'], {
1043
- checkValidity: {
1044
- value: function(){return true;}
1045
- },
1046
- willValidate: {
1047
- value: false
1048
- },
1049
- setCustomValidity: {
1050
- value: $.noop
1051
- },
1052
- validity: {
1053
- writeable: false,
1054
- get: function(){
1055
- return $.extend({}, validityPrototype);
1056
- }
1057
- }
1058
- }, 'prop');
1059
-
1060
- var baseCheckValidity = function(elem){
1061
- var e,
1062
- v = $.prop(elem, 'validity')
1063
- ;
1064
- if(v){
1065
- $.data(elem, 'cachedValidity', v);
1066
- } else {
1067
- return true;
1068
- }
1069
- if( !v.valid ){
1070
- e = $.Event('invalid');
1071
- var jElm = $(elem).trigger(e);
1072
- if(isSubmit && !baseCheckValidity.unhandledInvalids && !e.isDefaultPrevented()){
1073
- webshims.validityAlert.showFor(jElm);
1074
- baseCheckValidity.unhandledInvalids = true;
1075
- }
1076
- }
1077
- $.removeData(elem, 'cachedValidity');
1078
- return v.valid;
1079
- };
1080
- var rsubmittable = /^(?:select|textarea|input)/i;
1081
- webshims.defineNodeNameProperty('form', 'checkValidity', {
1082
- prop: {
1083
- value: function(){
1084
-
1085
- var ret = true,
1086
- elems = $($.prop(this, 'elements')).filter(function(){
1087
- if(!rsubmittable.test(this.nodeName)){return false;}
1088
- var shadowData = webshims.data(this, 'shadowData');
1089
- return !shadowData || !shadowData.nativeElement || shadowData.nativeElement === this;
1090
- })
1091
- ;
1092
-
1093
- baseCheckValidity.unhandledInvalids = false;
1094
- for(var i = 0, len = elems.length; i < len; i++){
1095
- if( !baseCheckValidity(elems[i]) ){
1096
- ret = false;
1097
- }
1098
- }
1099
- return ret;
1100
- }
1101
- }
1102
- });
1103
-
1104
- webshims.defineNodeNamesProperties(['input', 'textarea', 'select'], {
1105
- checkValidity: {
1106
- value: function(){
1107
- baseCheckValidity.unhandledInvalids = false;
1108
- return baseCheckValidity($(this).getNativeElement()[0]);
1109
- }
1110
- },
1111
- setCustomValidity: {
1112
- value: function(error){
1113
- $.removeData(this, 'cachedValidity');
1114
- webshims.data(this, 'customvalidationMessage', ''+error);
1115
- }
1116
- },
1117
- willValidate: {
1118
- writeable: false,
1119
- get: (function(){
1120
- var types = {
1121
- button: 1,
1122
- reset: 1,
1123
- hidden: 1,
1124
- image: 1
1125
- }
1126
- ;
1127
- return function(){
1128
- var elem = $(this).getNativeElement()[0];
1129
- //elem.name && <- we don't use to make it easier for developers
1130
- return !!(!elem.disabled && !elem.readOnly && !types[elem.type] );
1131
- };
1132
- })()
1133
- },
1134
- validity: {
1135
- writeable: false,
1136
- get: function(){
1137
- var jElm = $(this).getNativeElement();
1138
- var elem = jElm[0];
1139
- var validityState = $.data(elem, 'cachedValidity');
1140
- if(validityState){
1141
- return validityState;
1142
- }
1143
- validityState = $.extend({}, validityPrototype);
1144
-
1145
- if( !$.prop(elem, 'willValidate') || elem.type == 'submit' ){
1146
- return validityState;
1147
- }
1148
- var val = jElm.val(),
1149
- cache = {nodeName: elem.nodeName.toLowerCase()}
1150
- ;
1151
-
1152
- validityState.customError = !!(webshims.data(elem, 'customvalidationMessage'));
1153
- if( validityState.customError ){
1154
- validityState.valid = false;
1155
- }
1156
-
1157
- $.each(validityRules, function(rule, fn){
1158
- if (fn(jElm, val, cache)) {
1159
- validityState[rule] = true;
1160
- validityState.valid = false;
1161
- }
1162
- });
1163
- $(this).getShadowFocusElement().attr('aria-invalid', validityState.valid ? 'false' : 'true');
1164
- jElm = null;
1165
- elem = null;
1166
- return validityState;
1167
- }
1168
- }
1169
- }, 'prop');
1170
-
1171
- webshims.defineNodeNamesBooleanProperty(['input', 'textarea', 'select'], 'required', {
1172
- set: function(value){
1173
- $(this).getShadowFocusElement().attr('aria-required', !!(value)+'');
1174
- },
1175
- initAttr: (!$.browser.msie || webshims.browserVersion > 7)//only if we have aria-support
1176
- });
1177
-
1178
- webshims.reflectProperties(['input'], ['pattern']);
1179
-
1180
-
1181
- if( !('maxLength' in document.createElement('textarea')) ){
1182
- var constrainMaxLength = (function(){
1183
- var timer;
1184
- var curLength = 0;
1185
- var lastElement = $([]);
1186
- var max = 1e9;
1187
- var constrainLength = function(){
1188
- var nowValue = lastElement.prop('value');
1189
- var nowLen = nowValue.length;
1190
- if(nowLen > curLength && nowLen > max){
1191
- nowLen = Math.max(curLength, max);
1192
- lastElement.prop('value', nowValue.substr(0, nowLen ));
1193
- }
1194
- curLength = nowLen;
1195
- };
1196
- var remove = function(){
1197
- clearTimeout(timer);
1198
- lastElement.unbind('.maxlengthconstraint');
1199
- };
1200
- return function(element, maxLength){
1201
- remove();
1202
- if(maxLength > -1){
1203
- max = maxLength;
1204
- curLength = $.prop(element, 'value').length;
1205
- lastElement = $(element);
1206
- lastElement.bind('keydown.maxlengthconstraint keypress.maxlengthconstraint paste.maxlengthconstraint cut.maxlengthconstraint', function(e){
1207
- setTimeout(constrainLength, 0);
1208
- });
1209
- lastElement.bind('keyup.maxlengthconstraint', constrainLength);
1210
- lastElement.bind('blur.maxlengthconstraint', remove);
1211
- timer = setInterval(constrainLength, 200);
1212
- }
1213
- };
1214
- })();
1215
-
1216
- constrainMaxLength.update = function(element, maxLength){
1217
- if($(element).is(':focus')){
1218
- if(maxLength == null){
1219
- maxLength = $.prop(element, 'maxlength');
1220
- }
1221
- constrainMaxLength(e.target, maxLength);
1222
- }
1223
- };
1224
-
1225
- $(document).bind('focusin', function(e){
1226
- var maxLength;
1227
- if(e.target.nodeName == "TEXTAREA" && (maxLength = $.prop(e.target, 'maxlength')) > -1){
1228
- constrainMaxLength(e.target, maxLength);
1229
- }
1230
- });
1231
-
1232
- webshims.defineNodeNameProperty('textarea', 'maxlength', {
1233
- attr: {
1234
- set: function(val){
1235
- this.setAttribute('maxlength', ''+val);
1236
- constrainMaxLength.update(this);
1237
- },
1238
- get: function(){
1239
- var ret = this.getAttribute('maxlength');
1240
- return ret == null ? undefined : ret;
1241
- }
1242
- },
1243
- prop: {
1244
- set: function(val){
1245
- if(isNumber(val)){
1246
- if(val < 0){
1247
- throw('INDEX_SIZE_ERR');
1248
- }
1249
- val = parseInt(val, 10);
1250
- this.setAttribute('maxlength', val);
1251
- constrainMaxLength.update(this, val);
1252
- return;
1253
- }
1254
- this.setAttribute('maxlength', ''+ 0);
1255
- constrainMaxLength.update(this, 0);
1256
- },
1257
- get: function(){
1258
- var val = this.getAttribute('maxlength');
1259
- return (isNumber(val) && val >= 0) ? parseInt(val, 10) : -1;
1260
-
1261
- }
1262
- }
1263
- });
1264
- webshims.defineNodeNameProperty('textarea', 'maxLength', {
1265
- prop: {
1266
- set: function(val){
1267
- $.prop(this, 'maxlength', val);
1268
- },
1269
- get: function(){
1270
- return $.prop(this, 'maxlength');
1271
- }
1272
- }
1273
- });
1274
- }
1275
-
1276
-
1277
-
1278
- var submitterTypes = {submit: 1, button: 1, image: 1};
1279
- var formSubmitterDescriptors = {};
1280
- [
1281
- {
1282
- name: "enctype",
1283
- limitedTo: {
1284
- "application/x-www-form-urlencoded": 1,
1285
- "multipart/form-data": 1,
1286
- "text/plain": 1
1287
- },
1288
- defaultProp: "application/x-www-form-urlencoded",
1289
- proptype: "enum"
1290
- },
1291
- {
1292
- name: "method",
1293
- limitedTo: {
1294
- "get": 1,
1295
- "post": 1
1296
- },
1297
- defaultProp: "get",
1298
- proptype: "enum"
1299
- },
1300
- {
1301
- name: "action",
1302
- proptype: "url"
1303
- },
1304
- {
1305
- name: "target"
1306
- },
1307
- {
1308
- name: "novalidate",
1309
- propName: "noValidate",
1310
- proptype: "boolean"
1311
- }
1312
- ].forEach(function(desc){
1313
- var propName = 'form'+ (desc.propName || desc.name).replace(/^[a-z]/, function(f){
1314
- return f.toUpperCase();
1315
- });
1316
- var attrName = 'form'+ desc.name;
1317
- var formName = desc.name;
1318
- var eventName = 'click.webshimssubmittermutate'+formName;
1319
-
1320
- var changeSubmitter = function(){
1321
- var elem = this;
1322
- if( !('form' in elem) || !submitterTypes[elem.type] ){return;}
1323
- var form = $.prop(elem, 'form');
1324
- if(!form){return;}
1325
- var attr = $.attr(elem, attrName);
1326
- if(attr != null && ( !desc.limitedTo || attr.toLowerCase() === $.prop(elem, propName))){
1327
-
1328
- var oldAttr = $.attr(form, formName);
1329
-
1330
- $.attr(form, formName, attr);
1331
- setTimeout(function(){
1332
- if(oldAttr != null){
1333
- $.attr(form, formName, oldAttr);
1334
- } else {
1335
- try {
1336
- $(form).removeAttr(formName);
1337
- } catch(er){
1338
- form.removeAttribute(formName);
1339
- }
1340
- }
1341
- }, 9);
1342
- }
1343
- };
1344
-
1345
-
1346
-
1347
- switch(desc.proptype) {
1348
- case "url":
1349
- var urlForm = document.createElement('form');
1350
- formSubmitterDescriptors[propName] = {
1351
- prop: {
1352
- set: function(value){
1353
- $.attr(this, attrName, value);
1354
- },
1355
- get: function(){
1356
- var value = $.attr(this, attrName);
1357
- if(value == null){return '';}
1358
- urlForm.setAttribute('action', value);
1359
- return urlForm.action;
1360
- }
1361
- }
1362
- };
1363
- break;
1364
- case "boolean":
1365
- formSubmitterDescriptors[propName] = {
1366
- prop: {
1367
- set: function(val){
1368
- val = !!val;
1369
- if(val){
1370
- $.attr(this, 'formnovalidate', 'formnovalidate');
1371
- } else {
1372
- $(this).removeAttr('formnovalidate');
1373
- }
1374
- },
1375
- get: function(){
1376
- return $.attr(this, 'formnovalidate') != null;
1377
- }
1378
- }
1379
- };
1380
- break;
1381
- case "enum":
1382
- formSubmitterDescriptors[propName] = {
1383
- prop: {
1384
- set: function(value){
1385
- $.attr(this, attrName, value);
1386
- },
1387
- get: function(){
1388
- var value = $.attr(this, attrName);
1389
- return (!value || ( (value = value.toLowerCase()) && !desc.limitedTo[value] )) ? desc.defaultProp : value;
1390
- }
1391
- }
1392
- };
1393
- break;
1394
- default:
1395
- formSubmitterDescriptors[propName] = {
1396
- prop: {
1397
- set: function(value){
1398
- $.attr(this, attrName, value);
1399
- },
1400
- get: function(){
1401
- var value = $.attr(this, attrName);
1402
- return (value != null) ? value : "";
1403
- }
1404
- }
1405
- };
1406
- }
1407
-
1408
-
1409
- if(!formSubmitterDescriptors[attrName]){
1410
- formSubmitterDescriptors[attrName] = {};
1411
- }
1412
- formSubmitterDescriptors[attrName].attr = {
1413
- set: function(value){
1414
- formSubmitterDescriptors[attrName].attr._supset.call(this, value);
1415
- $(this).unbind(eventName).bind(eventName, changeSubmitter);
1416
- },
1417
- get: function(){
1418
- return formSubmitterDescriptors[attrName].attr._supget.call(this);
1419
- }
1420
- };
1421
- formSubmitterDescriptors[attrName].initAttr = true;
1422
- formSubmitterDescriptors[attrName].removeAttr = {
1423
- value: function(){
1424
- $(this).unbind(eventName);
1425
- formSubmitterDescriptors[attrName].removeAttr._supvalue.call(this);
1426
- }
1427
- };
1428
- });
1429
-
1430
- webshims.defineNodeNamesProperties(['input', 'button'], formSubmitterDescriptors);
1431
-
1432
-
1433
- if(!$.support.getSetAttribute && $('<form novalidate></form>').attr('novalidate') == null){
1434
- webshims.defineNodeNameProperty('form', 'novalidate', {
1435
- attr: {
1436
- set: function(val){
1437
- this.setAttribute('novalidate', ''+val);
1438
- },
1439
- get: function(){
1440
- var ret = this.getAttribute('novalidate');
1441
- return ret == null ? undefined : ret;
1442
- }
1443
- }
1444
- });
1445
- } else if(webshims.bugs.bustedValidity){
1446
-
1447
- webshims.defineNodeNameProperty('form', 'novalidate', {
1448
- attr: {
1449
- set: function(val){
1450
- webshims.data(this, 'bustedNoValidate', ''+val);
1451
- },
1452
- get: function(){
1453
- var ret = webshims.data(this, 'bustedNoValidate');
1454
- return ret == null ? undefined : ret;
1455
- }
1456
- },
1457
- removeAttr: {
1458
- value: function(){
1459
- webshims.data(this, 'bustedNoValidate', null);
1460
- }
1461
- }
1462
- });
1463
-
1464
- $.each(['rangeUnderflow', 'rangeOverflow', 'stepMismatch'], function(i, name){
1465
- validityRules[name] = function(elem){
1466
- return (elem[0].validity || {})[name] || false;
1467
- };
1468
- });
1469
-
1470
- }
1471
-
1472
- webshims.defineNodeNameProperty('form', 'noValidate', {
1473
- prop: {
1474
- set: function(val){
1475
- val = !!val;
1476
- if(val){
1477
- $.attr(this, 'novalidate', 'novalidate');
1478
- } else {
1479
- $(this).removeAttr('novalidate');
1480
- }
1481
- },
1482
- get: function(){
1483
- return $.attr(this, 'novalidate') != null;
1484
- }
1485
- }
1486
- });
1487
-
1488
- if($.browser.webkit && Modernizr.inputtypes.date){
1489
- (function(){
1490
-
1491
- var noInputTriggerEvts = {updateInput: 1, input: 1},
1492
- fixInputTypes = {
1493
- date: 1,
1494
- time: 1,
1495
- "datetime-local": 1
1496
- },
1497
- noFocusEvents = {
1498
- focusout: 1,
1499
- blur: 1
1500
- },
1501
- changeEvts = {
1502
- updateInput: 1,
1503
- change: 1
1504
- },
1505
- observe = function(input){
1506
- var timer,
1507
- focusedin = true,
1508
- lastInputVal = input.prop('value'),
1509
- lastChangeVal = lastInputVal,
1510
- trigger = function(e){
1511
- //input === null
1512
- if(!input){return;}
1513
- var newVal = input.prop('value');
1514
-
1515
- if(newVal !== lastInputVal){
1516
- lastInputVal = newVal;
1517
- if(!e || !noInputTriggerEvts[e.type]){
1518
- input.trigger('input');
1519
- }
1520
- }
1521
- if(e && changeEvts[e.type]){
1522
- lastChangeVal = newVal;
1523
- }
1524
- if(!focusedin && newVal !== lastChangeVal){
1525
- input.trigger('change');
1526
- }
1527
- },
1528
- extraTimer,
1529
- extraTest = function(){
1530
- clearTimeout(extraTimer);
1531
- extraTimer = setTimeout(trigger, 9);
1532
- },
1533
- unbind = function(e){
1534
- clearInterval(timer);
1535
- setTimeout(function(){
1536
- if(e && noFocusEvents[e.type]){
1537
- focusedin = false;
1538
- }
1539
- if(input){
1540
- input.unbind('focusout blur', unbind).unbind('input change updateInput', trigger);
1541
- trigger();
1542
- }
1543
- input = null;
1544
- }, 1);
1545
-
1546
- }
1547
- ;
1548
-
1549
- clearInterval(timer);
1550
- timer = setInterval(trigger, 160);
1551
- extraTest();
1552
- input.unbind('focusout blur', unbind).unbind('input change updateInput', trigger);
1553
- input.bind('focusout blur', unbind).bind('input updateInput change', trigger);
1554
- }
1555
- ;
1556
- if($.event.customEvent){
1557
- $.event.customEvent.updateInput = true;
1558
- }
1559
-
1560
- (function(){
1561
-
1562
- var correctValue = function(elem){
1563
- var i = 1;
1564
- var len = 3;
1565
- var abort, val;
1566
- if(elem.type == 'date' && (isSubmit || !$(elem).is(':focus'))){
1567
- val = elem.value;
1568
- if(val && val.length < 10 && (val = val.split('-')) && val.length == len){
1569
- for(; i < len; i++){
1570
- if(val[i].length == 1){
1571
- val[i] = '0'+val[i];
1572
- } else if(val[i].length != 2){
1573
- abort = true;
1574
- break;
1575
- }
1576
- }
1577
- if(!abort){
1578
- val = val.join('-');
1579
- $.prop(elem, 'value', val);
1580
- return val;
1581
- }
1582
- }
1583
- }
1584
- };
1585
- var inputCheckValidityDesc, formCheckValidityDesc, inputValueDesc, inputValidityDesc;
1586
-
1587
- inputCheckValidityDesc = webshims.defineNodeNameProperty('input', 'checkValidity', {
1588
- prop: {
1589
- value: function(){
1590
- correctValue(this);
1591
- return inputCheckValidityDesc.prop._supvalue.apply(this, arguments);
1592
- }
1593
- }
1594
- });
1595
-
1596
- formCheckValidityDesc = webshims.defineNodeNameProperty('form', 'checkValidity', {
1597
- prop: {
1598
- value: function(){
1599
- $('input', this).each(function(){
1600
- correctValue(this);
1601
- });
1602
- return formCheckValidityDesc.prop._supvalue.apply(this, arguments);
1603
- }
1604
- }
1605
- });
1606
-
1607
- inputValueDesc = webshims.defineNodeNameProperty('input', 'value', {
1608
- prop: {
1609
- set: function(){
1610
- return inputValueDesc.prop._supset.apply(this, arguments);
1611
- },
1612
- get: function(){
1613
- return correctValue(this) || inputValueDesc.prop._supget.apply(this, arguments);
1614
- }
1615
- }
1616
- });
1617
-
1618
- inputValidityDesc = webshims.defineNodeNameProperty('input', 'validity', {
1619
- prop: {
1620
- writeable: false,
1621
- get: function(){
1622
- correctValue(this);
1623
- return inputValidityDesc.prop._supget.apply(this, arguments);
1624
- }
1625
- }
1626
- });
1627
-
1628
- $(document).bind('change', function(e){
1629
- isChangeSubmit = true;
1630
- correctValue(e.target);
1631
- isChangeSubmit = false;
1632
- });
1633
-
1634
- })();
1635
-
1636
- $(document)
1637
- .bind('focusin', function(e){
1638
- if( e.target && fixInputTypes[e.target.type] && !e.target.readOnly && !e.target.disabled ){
1639
- observe($(e.target));
1640
- }
1641
- })
1642
- ;
1643
-
1644
-
1645
- })();
1646
- }
1647
-
1648
- webshims.addReady(function(context, contextElem){
1649
- //start constrain-validation
1650
- var focusElem;
1651
- $('form', context)
1652
- .add(contextElem.filter('form'))
1653
- .bind('invalid', $.noop)
1654
- ;
1655
-
1656
- try {
1657
- if(context == document && !('form' in (document.activeElement || {}))) {
1658
- focusElem = $('input[autofocus], select[autofocus], textarea[autofocus]', context).eq(0).getShadowFocusElement()[0];
1659
- if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) {
1660
- focusElem.focus();
1661
- }
1662
- }
1663
- }
1664
- catch (er) {}
1665
-
1666
- });
1667
-
1668
- if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled){
1669
- (function(){
1670
- (function(prop, undefined){
1671
- $.prop = function(elem, name, value){
1672
- var ret;
1673
- if(elem && elem.nodeType == 1 && value === undefined && $.nodeName(elem, 'form') && elem.id){
1674
- ret = document.getElementsByName(name);
1675
- if(!ret || !ret.length){
1676
- ret = document.getElementById(name);
1677
- }
1678
- if(ret){
1679
- ret = $(ret).filter(function(){
1680
- return $.prop(this, 'form') == elem;
1681
- }).get();
1682
- if(ret.length){
1683
- return ret.length == 1 ? ret[0] : ret;
1684
- }
1685
- }
1686
- }
1687
- return prop.apply(this, arguments);
1688
- };
1689
- })($.prop, undefined);
1690
- var removeAddedElements = function(form){
1691
- var elements = $.data(form, 'webshimsAddedElements');
1692
- if(elements){
1693
- elements.remove();
1694
- $.removeData(form, 'webshimsAddedElements');
1695
- }
1696
- };
1697
- var rCRLF = /\r?\n/g,
1698
- rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
1699
- rselectTextarea = /^(?:select|textarea)/i;
1700
-
1701
- if(!Modernizr.formattribute){
1702
- webshims.defineNodeNamesProperty(['input', 'textarea', 'select', 'button', 'fieldset'], 'form', {
1703
- prop: {
1704
- get: function(){
1705
- var form = webshims.contentAttr(this, 'form');
1706
- if(form){
1707
- form = document.getElementById(form);
1708
- if(form && !$.nodeName(form, 'form')){
1709
- form = null;
1710
- }
1711
- }
1712
- return form || this.form;
1713
- },
1714
- writeable: false
1715
- }
1716
- });
1717
-
1718
-
1719
- webshims.defineNodeNamesProperty(['form'], 'elements', {
1720
- prop: {
1721
- get: function(){
1722
- var id = this.id;
1723
- var elements = $.makeArray(this.elements);
1724
- if(id){
1725
- elements = $(elements).add('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"], button[form="'+ id +'"], fieldset[form="'+ id +'"]').not('.webshims-visual-hide > *').get();
1726
- }
1727
- return elements;
1728
- },
1729
- writeable: false
1730
- }
1731
- });
1732
-
1733
-
1734
-
1735
- $(function(){
1736
- var stopPropagation = function(e){
1737
- e.stopPropagation();
1738
- };
1739
- $(document).bind('submit', function(e){
1740
-
1741
- if(!e.isDefaultPrevented()){
1742
- var form = e.target;
1743
- var id = form.id;
1744
- var elements;
1745
-
1746
-
1747
- if(id){
1748
- removeAddedElements(form);
1749
-
1750
- elements = $('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"]')
1751
- .filter(function(){
1752
- return !this.disabled && this.name && this.form != form;
1753
- })
1754
- .clone()
1755
- ;
1756
- if(elements.length){
1757
- $.data(form, 'webshimsAddedElements', $('<div class="webshims-visual-hide" />').append(elements).appendTo(form));
1758
- setTimeout(function(){
1759
- removeAddedElements(form);
1760
- }, 9);
1761
- }
1762
- elements = null;
1763
- }
1764
- }
1765
- });
1766
-
1767
- $(document).bind('click', function(e){
1768
- if(!e.isDefaultPrevented() && $(e.target).is('input[type="submit"][form], button[form], input[type="button"][form], input[type="image"][form], input[type="reset"][form]')){
1769
- var trueForm = $.prop(e.target, 'form');
1770
- var formIn = e.target.form;
1771
- var clone;
1772
- if(trueForm && trueForm != formIn){
1773
- clone = $(e.target)
1774
- .clone()
1775
- .removeAttr('form')
1776
- .addClass('webshims-visual-hide')
1777
- .bind('click', stopPropagation)
1778
- .appendTo(trueForm)
1779
- ;
1780
- if(formIn){
1781
- e.preventDefault();
1782
- }
1783
- addSubmitBubbles(trueForm);
1784
- clone.trigger('click');
1785
- setTimeout(function(){
1786
- clone.remove();
1787
- clone = null;
1788
- }, 9);
1789
- }
1790
- }
1791
- });
1792
- });
1793
- }
1794
-
1795
- if(!Modernizr.fieldsetdisabled){
1796
- webshims.defineNodeNamesProperty(['fieldset'], 'elements', {
1797
- prop: {
1798
- get: function(){
1799
- //add listed elements without keygen, object, output
1800
- return $('input, select, textarea, button, fieldset', this).get() || [];
1801
- },
1802
- writeable: false
1803
- }
1804
- });
1805
- }
1806
-
1807
- $.fn.serializeArray = function() {
1808
- return this.map(function(){
1809
- var elements = $.prop(this, 'elements');
1810
- return elements ? $.makeArray( elements ) : this;
1811
- })
1812
- .filter(function(){
1813
- return this.name && !this.disabled &&
1814
- ( this.checked || rselectTextarea.test( this.nodeName ) ||
1815
- rinput.test( this.type ) );
1816
- })
1817
- .map(function( i, elem ){
1818
- var val = $( this ).val();
1819
-
1820
- return val == null ?
1821
- null :
1822
- $.isArray( val ) ?
1823
- $.map( val, function( val, i ){
1824
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1825
- }) :
1826
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1827
- }).get();
1828
- };
1829
-
1830
- })();
1831
- }
1832
-
1833
- (function(){
1834
- Modernizr.textareaPlaceholder = !!('placeholder' in $('<textarea />')[0]);
1835
- var bustedTextarea = $.browser.webkit && Modernizr.textareaPlaceholder && webshims.browserVersion < 535;
1836
- if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder && !bustedTextarea){return;}
1837
-
1838
- var isOver = (webshims.cfg.forms.placeholderType == 'over');
1839
- var isResponsive = (webshims.cfg.forms.responsivePlaceholder);
1840
- var polyfillElements = ['textarea'];
1841
- if(!Modernizr.input.placeholder){
1842
- polyfillElements.push('input');
1843
- }
1844
-
1845
- var setSelection = function(elem){
1846
- try {
1847
- if(elem.setSelectionRange){
1848
- elem.setSelectionRange(0, 0);
1849
- return true;
1850
- } else if(elem.createTextRange){
1851
- var range = elem.createTextRange();
1852
- range.collapse(true);
1853
- range.moveEnd('character', 0);
1854
- range.moveStart('character', 0);
1855
- range.select();
1856
- return true;
1857
- }
1858
- } catch(er){}
1859
- };
1860
-
1861
- var hidePlaceholder = function(elem, data, value, _onFocus){
1862
- if(value === false){
1863
- value = $.prop(elem, 'value');
1864
- }
1865
- if(!isOver && elem.type != 'password'){
1866
- if(!value && _onFocus && setSelection(elem)){
1867
- var selectTimer = setTimeout(function(){
1868
- setSelection(elem);
1869
- }, 9);
1870
- $(elem)
1871
- .unbind('.placeholderremove')
1872
- .bind('keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove', function(e){
1873
- if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1874
- elem.value = $.prop(elem, 'value');
1875
- data.box.removeClass('placeholder-visible');
1876
- clearTimeout(selectTimer);
1877
- $(elem).unbind('.placeholderremove');
1878
- })
1879
- .bind('mousedown.placeholderremove drag.placeholderremove select.placeholderremove', function(e){
1880
- setSelection(elem);
1881
- clearTimeout(selectTimer);
1882
- selectTimer = setTimeout(function(){
1883
- setSelection(elem);
1884
- }, 9);
1885
- })
1886
- .bind('blur.placeholderremove', function(){
1887
- clearTimeout(selectTimer);
1888
- $(elem).unbind('.placeholderremove');
1889
- })
1890
- ;
1891
- return;
1892
- }
1893
- elem.value = value;
1894
- } else if(!value && _onFocus){
1895
- $(elem)
1896
- .unbind('.placeholderremove')
1897
- .bind('keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove', function(e){
1898
- if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1899
- data.box.removeClass('placeholder-visible');
1900
- $(elem).unbind('.placeholderremove');
1901
- })
1902
- .bind('blur.placeholderremove', function(){
1903
- $(elem).unbind('.placeholderremove');
1904
- })
1905
- ;
1906
- return;
1907
- }
1908
- data.box.removeClass('placeholder-visible');
1909
- },
1910
- showPlaceholder = function(elem, data, placeholderTxt){
1911
- if(placeholderTxt === false){
1912
- placeholderTxt = $.prop(elem, 'placeholder');
1913
- }
1914
-
1915
- if(!isOver && elem.type != 'password'){
1916
- elem.value = placeholderTxt;
1917
- }
1918
- data.box.addClass('placeholder-visible');
1919
- },
1920
- changePlaceholderVisibility = function(elem, value, placeholderTxt, data, type){
1921
- if(!data){
1922
- data = $.data(elem, 'placeHolder');
1923
- if(!data){return;}
1924
- }
1925
- $(elem).unbind('.placeholderremove');
1926
- if(type == 'focus' || (!type && $(elem).is(':focus'))){
1927
- if(elem.type == 'password' || isOver || $(elem).hasClass('placeholder-visible')){
1928
- hidePlaceholder(elem, data, '', true);
1929
- }
1930
- return;
1931
- }
1932
- if(value === false){
1933
- value = $.prop(elem, 'value');
1934
- }
1935
- if(value){
1936
- hidePlaceholder(elem, data, value);
1937
- return;
1938
- }
1939
- if(placeholderTxt === false){
1940
- placeholderTxt = $.attr(elem, 'placeholder') || '';
1941
- }
1942
- if(placeholderTxt && !value){
1943
- showPlaceholder(elem, data, placeholderTxt);
1944
- } else {
1945
- hidePlaceholder(elem, data, value);
1946
- }
1947
- },
1948
- createPlaceholder = function(elem){
1949
- elem = $(elem);
1950
- var id = elem.prop('id'),
1951
- hasLabel = !!(elem.prop('title') || elem.attr('aria-labelledby'))
1952
- ;
1953
- if(!hasLabel && id){
1954
- hasLabel = !!( $('label[for="'+ id +'"]', elem[0].form)[0] );
1955
- }
1956
- if(!hasLabel){
1957
- if(!id){
1958
- id = $.webshims.getID(elem);
1959
- }
1960
- hasLabel = !!($('label #'+ id)[0]);
1961
- }
1962
- return $( hasLabel ? '<span class="placeholder-text"></span>' : '<label for="'+ id +'" class="placeholder-text"></label>');
1963
- },
1964
- pHolder = (function(){
1965
- var delReg = /\n|\r|\f|\t/g,
1966
- allowedPlaceholder = {
1967
- text: 1,
1968
- search: 1,
1969
- url: 1,
1970
- email: 1,
1971
- password: 1,
1972
- tel: 1
1973
- }
1974
- ;
1975
-
1976
- return {
1977
- create: function(elem){
1978
- var data = $.data(elem, 'placeHolder');
1979
- var form;
1980
- var responsiveElem;
1981
- if(data){return data;}
1982
- data = $.data(elem, 'placeHolder', {});
1983
-
1984
- $(elem).bind('focus.placeholder blur.placeholder', function(e){
1985
- changePlaceholderVisibility(this, false, false, data, e.type );
1986
- data.box[e.type == 'focus' ? 'addClass' : 'removeClass']('placeholder-focused');
1987
- });
1988
-
1989
- if((form = $.prop(elem, 'form'))){
1990
- $(form).bind('reset.placeholder', function(e){
1991
- setTimeout(function(){
1992
- changePlaceholderVisibility(elem, false, false, data, e.type );
1993
- }, 0);
1994
- });
1995
- }
1996
-
1997
- if(elem.type == 'password' || isOver){
1998
- data.text = createPlaceholder(elem);
1999
- if(isResponsive || $(elem).is('.responsive-width') || (elem.currentStyle || {width: ''}).width.indexOf('%') != -1){
2000
- responsiveElem = true;
2001
- data.box = data.text;
2002
- } else {
2003
- data.box = $(elem)
2004
- .wrap('<span class="placeholder-box placeholder-box-'+ (elem.nodeName || '').toLowerCase() +' placeholder-box-'+$.css(elem, 'float')+'" />')
2005
- .parent()
2006
- ;
2007
- }
2008
- data.text
2009
- .insertAfter(elem)
2010
- .bind('mousedown.placeholder', function(){
2011
- changePlaceholderVisibility(this, false, false, data, 'focus');
2012
- try {
2013
- setTimeout(function(){
2014
- elem.focus();
2015
- }, 0);
2016
- } catch(e){}
2017
- return false;
2018
- })
2019
- ;
2020
-
2021
-
2022
- $.each(['lineHeight', 'fontSize', 'fontFamily', 'fontWeight'], function(i, style){
2023
- var prop = $.css(elem, style);
2024
- if(data.text.css(style) != prop){
2025
- data.text.css(style, prop);
2026
- }
2027
- });
2028
- $.each(['Left', 'Top'], function(i, side){
2029
- var size = (parseInt($.css(elem, 'padding'+ side), 10) || 0) + Math.max((parseInt($.css(elem, 'margin'+ side), 10) || 0), 0) + (parseInt($.css(elem, 'border'+ side +'Width'), 10) || 0);
2030
- data.text.css('padding'+ side, size);
2031
- });
2032
-
2033
- $(elem)
2034
- .bind('updateshadowdom', function(){
2035
- var height, width;
2036
- if((width = elem.offsetWidth) || (height = elem.offsetHeight)){
2037
- data.text
2038
- .css({
2039
- width: width,
2040
- height: height
2041
- })
2042
- .css($(elem).position())
2043
- ;
2044
- }
2045
- })
2046
- .triggerHandler('updateshadowdom')
2047
- ;
2048
-
2049
- } else {
2050
- var reset = function(e){
2051
- if($(elem).hasClass('placeholder-visible')){
2052
- hidePlaceholder(elem, data, '');
2053
- if(e && e.type == 'submit'){
2054
- setTimeout(function(){
2055
- if(e.isDefaultPrevented()){
2056
- changePlaceholderVisibility(elem, false, false, data );
2057
- }
2058
- }, 9);
2059
- }
2060
- }
2061
- };
2062
-
2063
- $(window).bind('beforeunload', reset);
2064
- data.box = $(elem);
2065
- if(form){
2066
- $(form).submit(reset);
2067
- }
2068
- }
2069
-
2070
- return data;
2071
- },
2072
- update: function(elem, val){
2073
- var type = ($.attr(elem, 'type') || $.prop(elem, 'type') || '').toLowerCase();
2074
- if(!allowedPlaceholder[type] && !$.nodeName(elem, 'textarea')){
2075
- webshims.error('placeholder not allowed on input[type="'+type+'"]');
2076
- if(type == 'date'){
2077
- webshims.error('but you can use data-placeholder for input[type="date"]');
2078
- }
2079
- return;
2080
- }
2081
-
2082
-
2083
- var data = pHolder.create(elem);
2084
- if(data.text){
2085
- data.text.text(val);
2086
- }
2087
-
2088
- changePlaceholderVisibility(elem, false, val, data);
2089
- }
2090
- };
2091
- })()
2092
- ;
2093
-
2094
- $.webshims.publicMethods = {
2095
- pHolder: pHolder
2096
- };
2097
- polyfillElements.forEach(function(nodeName){
2098
- var desc = webshims.defineNodeNameProperty(nodeName, 'placeholder', {
2099
- attr: {
2100
- set: function(val){
2101
- var elem = this;
2102
- if(bustedTextarea){
2103
- webshims.data(elem, 'textareaPlaceholder', val);
2104
- elem.placeholder = '';
2105
- } else {
2106
- webshims.contentAttr(elem, 'placeholder', val);
2107
- }
2108
- pHolder.update(elem, val);
2109
- },
2110
- get: function(){
2111
- var ret = (bustedTextarea) ? webshims.data(this, 'textareaPlaceholder') : '';
2112
- return ret || webshims.contentAttr(this, 'placeholder');
2113
- }
2114
- },
2115
- reflect: true,
2116
- initAttr: true
2117
- });
2118
- });
2119
-
2120
-
2121
- polyfillElements.forEach(function(name){
2122
- var placeholderValueDesc = {};
2123
- var desc;
2124
- ['attr', 'prop'].forEach(function(propType){
2125
- placeholderValueDesc[propType] = {
2126
- set: function(val){
2127
- var elem = this;
2128
- var placeholder;
2129
- if(bustedTextarea){
2130
- placeholder = webshims.data(elem, 'textareaPlaceholder');
2131
- }
2132
- if(!placeholder){
2133
- placeholder = webshims.contentAttr(elem, 'placeholder');
2134
- }
2135
- $.removeData(elem, 'cachedValidity');
2136
- var ret = desc[propType]._supset.call(elem, val);
2137
- if(placeholder && 'value' in elem){
2138
- changePlaceholderVisibility(elem, val, placeholder);
2139
- }
2140
- return ret;
2141
- },
2142
- get: function(){
2143
- var elem = this;
2144
- return $(elem).hasClass('placeholder-visible') ? '' : desc[propType]._supget.call(elem);
2145
- }
2146
- };
2147
- });
2148
- desc = webshims.defineNodeNameProperty(name, 'value', placeholderValueDesc);
2149
- });
2150
-
2151
- })();
2152
-
2153
- (function(){
2154
- var doc = document;
2155
- if( 'value' in document.createElement('output') ){return;}
2156
-
2157
- webshims.defineNodeNameProperty('output', 'value', {
2158
- prop: {
2159
- set: function(value){
2160
- var setVal = $.data(this, 'outputShim');
2161
- if(!setVal){
2162
- setVal = outputCreate(this);
2163
- }
2164
- setVal(value);
2165
- },
2166
- get: function(){
2167
- return webshims.contentAttr(this, 'value') || $(this).text() || '';
2168
- }
2169
- }
2170
- });
2171
-
2172
-
2173
- webshims.onNodeNamesPropertyModify('input', 'value', function(value, boolVal, type){
2174
- if(type == 'removeAttr'){return;}
2175
- var setVal = $.data(this, 'outputShim');
2176
- if(setVal){
2177
- setVal(value);
2178
- }
2179
- });
2180
-
2181
- var outputCreate = function(elem){
2182
- if(elem.getAttribute('aria-live')){return;}
2183
- elem = $(elem);
2184
- var value = (elem.text() || '').trim();
2185
- var id = elem.attr('id');
2186
- var htmlFor = elem.attr('for');
2187
- var shim = $('<input class="output-shim" type="text" disabled name="'+ (elem.attr('name') || '')+'" value="'+value+'" style="display: none !important;" />').insertAfter(elem);
2188
- var form = shim[0].form || doc;
2189
- var setValue = function(val){
2190
- shim[0].value = val;
2191
- val = shim[0].value;
2192
- elem.text(val);
2193
- webshims.contentAttr(elem[0], 'value', val);
2194
- };
2195
-
2196
- elem[0].defaultValue = value;
2197
- webshims.contentAttr(elem[0], 'value', value);
2198
-
2199
- elem.attr({'aria-live': 'polite'});
2200
- if(id){
2201
- shim.attr('id', id);
2202
- elem.attr('aria-labelledby', webshims.getID($('label[for="'+id+'"]', form)));
2203
- }
2204
- if(htmlFor){
2205
- id = webshims.getID(elem);
2206
- htmlFor.split(' ').forEach(function(control){
2207
- control = document.getElementById(control);
2208
- if(control){
2209
- control.setAttribute('aria-controls', id);
2210
- }
2211
- });
2212
- }
2213
- elem.data('outputShim', setValue );
2214
- shim.data('outputShim', setValue );
2215
- return setValue;
2216
- };
2217
-
2218
- webshims.addReady(function(context, contextElem){
2219
- $('output', context).add(contextElem.filter('output')).each(function(){
2220
- outputCreate(this);
2221
- });
2222
- });
2223
-
2224
- /*
2225
- * Implements input event in all browsers
2226
- */
2227
- (function(){
2228
- var noInputTriggerEvts = {updateInput: 1, input: 1},
2229
- noInputTypes = {
2230
- radio: 1,
2231
- checkbox: 1,
2232
- submit: 1,
2233
- button: 1,
2234
- image: 1,
2235
- reset: 1,
2236
- file: 1
2237
-
2238
- //pro forma
2239
- ,color: 1
2240
- //,range: 1
2241
- },
2242
- observe = function(input){
2243
- var timer,
2244
- lastVal = input.prop('value'),
2245
- trigger = function(e){
2246
- //input === null
2247
- if(!input){return;}
2248
- var newVal = input.prop('value');
2249
-
2250
- if(newVal !== lastVal){
2251
- lastVal = newVal;
2252
- if(!e || !noInputTriggerEvts[e.type]){
2253
- webshims.triggerInlineForm && webshims.triggerInlineForm(input[0], 'input');
2254
- }
2255
- }
2256
- },
2257
- extraTimer,
2258
- extraTest = function(){
2259
- clearTimeout(extraTimer);
2260
- extraTimer = setTimeout(trigger, 9);
2261
- },
2262
- unbind = function(){
2263
- input.unbind('focusout', unbind).unbind('keyup keypress keydown paste cut', extraTest).unbind('input change updateInput', trigger);
2264
- clearInterval(timer);
2265
- setTimeout(function(){
2266
- trigger();
2267
- input = null;
2268
- }, 1);
2269
-
2270
- }
2271
- ;
2272
-
2273
- clearInterval(timer);
2274
- timer = setInterval(trigger, 99);
2275
- extraTest();
2276
- input.bind('keyup keypress keydown paste cut', extraTest).bind('focusout', unbind).bind('input updateInput change', trigger);
2277
- }
2278
- ;
2279
- if($.event.customEvent){
2280
- $.event.customEvent.updateInput = true;
2281
- }
2282
-
2283
- $(doc)
2284
- .bind('focusin', function(e){
2285
- if( e.target && e.target.type && !e.target.readOnly && !e.target.disabled && (e.target.nodeName || '').toLowerCase() == 'input' && !noInputTypes[e.target.type] ){
2286
- observe($(e.target));
2287
- }
2288
- })
2289
- ;
2290
- })();
2291
- })();
2292
-
2293
- }); //webshims.ready end
2294
- }//end formvalidation
1
+ //additional tests for partial implementation of forms features
2
+ (function($){
3
+ "use strict";
4
+ var Modernizr = window.Modernizr;
5
+ var webshims = $.webshims;
6
+ var bugs = webshims.bugs;
7
+ var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input required="" name="a" /></form>');
8
+ var testRequiredFind = function(){
9
+ if(form[0].querySelector){
10
+ try {
11
+ bugs.findRequired = !(form[0].querySelector('select:required'));
12
+ } catch(er){
13
+ bugs.findRequired = false;
14
+ }
15
+ }
16
+ };
17
+ var inputElem = $('input', form).eq(0);
18
+ var onDomextend = function(fn){
19
+ webshims.loader.loadList(['dom-extend']);
20
+ webshims.ready('dom-extend', fn);
21
+ };
22
+
23
+ bugs.findRequired = false;
24
+ bugs.validationMessage = false;
25
+
26
+ webshims.capturingEventPrevented = function(e){
27
+ if(!e._isPolyfilled){
28
+ var isDefaultPrevented = e.isDefaultPrevented;
29
+ var preventDefault = e.preventDefault;
30
+ e.preventDefault = function(){
31
+ clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
32
+ $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
33
+ $.removeData(e.target, e.type + 'DefaultPrevented');
34
+ }, 30));
35
+ return preventDefault.apply(this, arguments);
36
+ };
37
+ e.isDefaultPrevented = function(){
38
+ return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
39
+ };
40
+ e._isPolyfilled = true;
41
+ }
42
+ };
43
+
44
+ if(!Modernizr.formvalidation || bugs.bustedValidity){
45
+ testRequiredFind();
46
+ return;
47
+ }
48
+
49
+ //create delegatable events
50
+ webshims.capturingEvents(['input']);
51
+ webshims.capturingEvents(['invalid'], true);
52
+
53
+ if(window.opera || window.testGoodWithFix){
54
+
55
+ form.appendTo('head');
56
+
57
+ testRequiredFind();
58
+ bugs.validationMessage = !(inputElem.prop('validationMessage'));
59
+
60
+ webshims.reTest(['form-extend', 'form-message']);
61
+
62
+ form.remove();
63
+
64
+ $(function(){
65
+ onDomextend(function(){
66
+
67
+ //Opera shows native validation bubbles in case of input.checkValidity()
68
+ // Opera 11.6/12 hasn't fixed this issue right, it's buggy
69
+ var preventDefault = function(e){
70
+ e.preventDefault();
71
+ };
72
+
73
+ ['form', 'input', 'textarea', 'select'].forEach(function(name){
74
+ var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
75
+ prop: {
76
+ value: function(){
77
+ if (!webshims.fromSubmit) {
78
+ $(this).on('invalid.checkvalidity', preventDefault);
79
+ }
80
+
81
+ webshims.fromCheckValidity = true;
82
+ var ret = desc.prop._supvalue.apply(this, arguments);
83
+ if (!webshims.fromSubmit) {
84
+ $(this).unbind('invalid.checkvalidity', preventDefault);
85
+ }
86
+ webshims.fromCheckValidity = false;
87
+ return ret;
88
+ }
89
+ }
90
+ });
91
+ });
92
+
93
+ });
94
+ });
95
+ }
96
+
97
+ if($.browser.webkit && !webshims.bugs.bustedValidity){
98
+ (function(){
99
+ var elems = /^(?:textarea|input)$/i;
100
+ var form = false;
101
+
102
+ document.addEventListener('contextmenu', function(e){
103
+ if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
104
+ setTimeout(function(){
105
+ form = false;
106
+ }, 1);
107
+ }
108
+ }, false);
109
+
110
+ $(window).on('invalid', function(e){
111
+ if(e.originalEvent && form && form == e.target.form){
112
+ e.wrongWebkitInvalid = true;
113
+ e.stopImmediatePropagation();
114
+ }
115
+ });
116
+ })();
117
+ }
118
+ })(jQuery);
119
+
120
+ jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
121
+ "use strict";
122
+
123
+ var groupTypes = {radio: 1};
124
+ var checkTypes = {checkbox: 1, radio: 1};
125
+ var emptyJ = $([]);
126
+ var bugs = webshims.bugs;
127
+ var getGroupElements = function(elem){
128
+ elem = $(elem);
129
+ var name;
130
+ var form;
131
+ var ret = emptyJ;
132
+ if(groupTypes[elem[0].type]){
133
+ form = elem.prop('form');
134
+ name = elem[0].name;
135
+ if(!name){
136
+ ret = elem;
137
+ } else if(form){
138
+ ret = $(form[name]);
139
+ } else {
140
+ ret = $(document.getElementsByName(name)).filter(function(){
141
+ return !$.prop(this, 'form');
142
+ });
143
+ }
144
+ ret = ret.filter('[type="radio"]');
145
+ }
146
+ return ret;
147
+ };
148
+
149
+ var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
150
+ var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
151
+ if(key && message[key]){
152
+ message = message[key];
153
+ }
154
+ if(typeof message == 'object'){
155
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
156
+ if(!validity.valid){
157
+ $.each(validity, function(name, prop){
158
+ if(prop && name != 'valid' && message[name]){
159
+ message = message[name];
160
+ return false;
161
+ }
162
+ });
163
+ }
164
+ }
165
+
166
+ if(typeof message == 'object'){
167
+ message = message.defaultMessage;
168
+ }
169
+ return message || '';
170
+ };
171
+
172
+ /*
173
+ * Selectors for all browsers
174
+ */
175
+ var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
176
+ var hasInvalid = function(elem){
177
+ var ret = false;
178
+ $($.prop(elem, 'elements')).each(function(){
179
+ ret = $(this).is(':invalid');
180
+ if(ret){
181
+ return false;
182
+ }
183
+ });
184
+ return ret;
185
+ };
186
+ $.extend($.expr[":"], {
187
+ "valid-element": function(elem){
188
+ return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
189
+ },
190
+ "invalid-element": function(elem){
191
+ return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
192
+ },
193
+ "required-element": function(elem){
194
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
195
+ },
196
+ "user-error": function(elem){
197
+ return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
198
+ },
199
+ "optional-element": function(elem){
200
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
201
+ },
202
+ "in-range": function(elem){
203
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
204
+ return false;
205
+ }
206
+ var val = $.prop(elem, 'validity');
207
+ return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
208
+ },
209
+ "out-of-range": function(elem){
210
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
211
+ return false;
212
+ }
213
+ var val = $.prop(elem, 'validity');
214
+ return !!(val && (val.rangeOverflow || val.rangeUnderflow));
215
+ }
216
+
217
+ });
218
+
219
+ ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
220
+ $.expr[":"][name] = $.expr.filters[name+"-element"];
221
+ });
222
+
223
+
224
+ $.expr[":"].focus = function( elem ) {
225
+ try {
226
+ var doc = elem.ownerDocument;
227
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
228
+ } catch(e){}
229
+ return false;
230
+ };
231
+
232
+ var customEvents = $.event.customEvent || {};
233
+ var isValid = function(elem){
234
+ return ($.prop(elem, 'validity') || {valid: 1}).valid;
235
+ };
236
+
237
+ if (bugs.bustedValidity || bugs.findRequired) {
238
+ (function(){
239
+ var find = $.find;
240
+ var matchesSelector = $.find.matchesSelector;
241
+
242
+ var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
243
+ var regFn = function(sel){
244
+ return sel + '-element';
245
+ };
246
+
247
+ $.find = (function(){
248
+ var slice = Array.prototype.slice;
249
+ var fn = function(sel){
250
+ var ar = arguments;
251
+ ar = slice.call(ar, 1, ar.length);
252
+ ar.unshift(sel.replace(regExp, regFn));
253
+ return find.apply(this, ar);
254
+ };
255
+ for (var i in find) {
256
+ if(find.hasOwnProperty(i)){
257
+ fn[i] = find[i];
258
+ }
259
+ }
260
+ return fn;
261
+ })();
262
+ if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
263
+ $.find.matchesSelector = function(node, expr){
264
+ expr = expr.replace(regExp, regFn);
265
+ return matchesSelector.call(this, node, expr);
266
+ };
267
+ }
268
+
269
+ })();
270
+ }
271
+
272
+ //ToDo needs testing
273
+ var oldAttr = $.prop;
274
+ var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
275
+ $.prop = function(elem, name, val){
276
+ var ret = oldAttr.apply(this, arguments);
277
+ if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
278
+ if(isValid(elem)){
279
+ $(elem).getShadowElement().removeClass(invalidClasses);
280
+ if(name == 'checked' && val) {
281
+ getGroupElements(elem).not(elem).removeClass(invalidClasses).removeAttr('aria-invalid');
282
+ }
283
+ }
284
+ }
285
+ return ret;
286
+ };
287
+
288
+ var returnValidityCause = function(validity, elem){
289
+ var ret;
290
+ $.each(validity, function(name, value){
291
+ if(value){
292
+ ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
293
+ return false;
294
+ }
295
+ });
296
+ return ret;
297
+ };
298
+
299
+ var isInGroup = function(name){
300
+ var ret;
301
+ try {
302
+ ret = document.activeElement.name === name;
303
+ } catch(e){}
304
+ return ret;
305
+ };
306
+ /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-succes instead */
307
+ var invalidClass = 'user-error';
308
+ var invalidClasses = 'user-error form-ui-invalid';
309
+ var validClass = 'user-success';
310
+ var validClasses = 'user-success form-ui-valid';
311
+ var switchValidityClass = function(e){
312
+ var elem, timer;
313
+ if(!e.target){return;}
314
+ elem = $(e.target).getNativeElement()[0];
315
+ if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
316
+ timer = $.data(elem, 'webshimsswitchvalidityclass');
317
+ var switchClass = function(){
318
+ if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
319
+ var validity = $.prop(elem, 'validity');
320
+ var shadowElem = $(elem).getShadowElement();
321
+ var addClass, removeClass, trigger, generaltrigger, validityCause;
322
+
323
+ $(elem).trigger('refreshCustomValidityRules');
324
+ if(validity.valid){
325
+ if(!shadowElem.hasClass(validClass)){
326
+ addClass = validClasses;
327
+ removeClass = invalidClasses;
328
+ generaltrigger = 'changedvaliditystate';
329
+ trigger = 'changedvalid';
330
+ if(checkTypes[elem.type] && elem.checked){
331
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
332
+ }
333
+ $.removeData(elem, 'webshimsinvalidcause');
334
+ }
335
+ } else {
336
+ validityCause = returnValidityCause(validity, elem);
337
+ if($.data(elem, 'webshimsinvalidcause') != validityCause){
338
+ $.data(elem, 'webshimsinvalidcause', validityCause);
339
+ generaltrigger = 'changedvaliditystate';
340
+ }
341
+ if(!shadowElem.hasClass(invalidClass)){
342
+ addClass = invalidClasses;
343
+ removeClass = validClasses;
344
+ if (checkTypes[elem.type] && !elem.checked) {
345
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
346
+ }
347
+ trigger = 'changedinvalid';
348
+ }
349
+ }
350
+ if(addClass){
351
+ shadowElem.addClass(addClass).removeClass(removeClass);
352
+ //jQuery 1.6.1 IE9 bug (doubble trigger bug)
353
+ setTimeout(function(){
354
+ $(elem).trigger(trigger);
355
+ }, 0);
356
+ }
357
+ if(generaltrigger){
358
+ setTimeout(function(){
359
+ $(elem).trigger(generaltrigger);
360
+ }, 0);
361
+ }
362
+ $.removeData(e.target, 'webshimsswitchvalidityclass');
363
+ };
364
+
365
+ if(timer){
366
+ clearTimeout(timer);
367
+ }
368
+ if(e.type == 'refreshvalidityui'){
369
+ switchClass();
370
+ } else {
371
+ $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
372
+ }
373
+ };
374
+
375
+ $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
376
+ customEvents.changedvaliditystate = true;
377
+ customEvents.refreshCustomValidityRules = true;
378
+ customEvents.changedvalid = true;
379
+ customEvents.changedinvalid = true;
380
+ customEvents.refreshvalidityui = true;
381
+
382
+
383
+ webshims.triggerInlineForm = function(elem, event){
384
+ $(elem).trigger(event);
385
+ };
386
+
387
+ webshims.modules["form-core"].getGroupElements = getGroupElements;
388
+
389
+
390
+ var setRoot = function(){
391
+ webshims.scrollRoot = ($.browser.webkit || document.compatMode == 'BackCompat') ?
392
+ $(document.body) :
393
+ $(document.documentElement)
394
+ ;
395
+ };
396
+ setRoot();
397
+ webshims.ready('DOM', setRoot);
398
+
399
+ webshims.getRelOffset = function(posElem, relElem){
400
+ posElem = $(posElem);
401
+ var offset = $(relElem).offset();
402
+ var bodyOffset;
403
+ $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
404
+ bodyOffset = posElem.offset();
405
+ });
406
+ offset.top -= bodyOffset.top;
407
+ offset.left -= bodyOffset.left;
408
+ return offset;
409
+ };
410
+
411
+ /* some extra validation UI */
412
+ webshims.validityAlert = (function(){
413
+ var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label';
414
+ var errorBubble;
415
+ var hideTimer = false;
416
+ var focusTimer = false;
417
+ var resizeTimer = false;
418
+ var boundHide;
419
+
420
+ var api = {
421
+ hideDelay: 5000,
422
+
423
+ showFor: function(elem, message, noFocusElem, noBubble){
424
+ api._create();
425
+ elem = $(elem);
426
+ var visual = $(elem).getShadowElement();
427
+ var offset = api.getOffsetFromBody(visual);
428
+ api.clear();
429
+ if(noBubble){
430
+ this.hide();
431
+ } else {
432
+ this.getMessage(elem, message);
433
+ this.position(visual, offset);
434
+
435
+ this.show();
436
+ if(this.hideDelay){
437
+ hideTimer = setTimeout(boundHide, this.hideDelay);
438
+ }
439
+ $(window)
440
+ .on('resize.validityalert', function(){
441
+ clearTimeout(resizeTimer);
442
+ resizeTimer = setTimeout(function(){
443
+ api.position(visual);
444
+ }, 9);
445
+ })
446
+ ;
447
+ }
448
+
449
+ if(!noFocusElem){
450
+ this.setFocus(visual, offset);
451
+ }
452
+ },
453
+ getOffsetFromBody: function(elem){
454
+ return webshims.getRelOffset(errorBubble, elem);
455
+ },
456
+ setFocus: function(visual, offset){
457
+ var focusElem = $(visual).getShadowFocusElement();
458
+ var scrollTop = webshims.scrollRoot.scrollTop();
459
+ var elemTop = ((offset || focusElem.offset()).top) - 30;
460
+ var smooth;
461
+
462
+ if(webshims.getID && alertElem == 'label'){
463
+ errorBubble.attr('for', webshims.getID(focusElem));
464
+ }
465
+
466
+ if(scrollTop > elemTop){
467
+ webshims.scrollRoot.animate(
468
+ {scrollTop: elemTop - 5},
469
+ {
470
+ queue: false,
471
+ duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
472
+ }
473
+ );
474
+ smooth = true;
475
+ }
476
+ try {
477
+ focusElem[0].focus();
478
+ } catch(e){}
479
+ if(smooth){
480
+ webshims.scrollRoot.scrollTop(scrollTop);
481
+ setTimeout(function(){
482
+ webshims.scrollRoot.scrollTop(scrollTop);
483
+ }, 0);
484
+ }
485
+ setTimeout(function(){
486
+ $(document).on('focusout.validityalert', boundHide);
487
+ }, 10);
488
+ },
489
+ getMessage: function(elem, message){
490
+ if (!message) {
491
+ message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage');
492
+ }
493
+ if (message) {
494
+ $('span.va-box', errorBubble).text(message);
495
+ }
496
+ else {
497
+ this.hide();
498
+ }
499
+ },
500
+ position: function(elem, offset){
501
+ offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
502
+ offset.top += elem.outerHeight();
503
+ errorBubble.css(offset);
504
+ },
505
+ show: function(){
506
+ if(errorBubble.css('display') === 'none'){
507
+ errorBubble.css({opacity: 0}).show();
508
+ }
509
+ errorBubble.addClass('va-visible').fadeTo(400, 1);
510
+ },
511
+ hide: function(){
512
+ errorBubble.removeClass('va-visible').fadeOut();
513
+ },
514
+ clear: function(){
515
+ clearTimeout(focusTimer);
516
+ clearTimeout(hideTimer);
517
+ $(document).unbind('.validityalert');
518
+ $(window).unbind('.validityalert');
519
+ errorBubble.stop().removeAttr('for');
520
+ },
521
+ _create: function(){
522
+ if(errorBubble){return;}
523
+ errorBubble = api.errorBubble = $('<'+alertElem+' class="validity-alert-wrapper" role="alert"><span class="validity-alert"><span class="va-arrow"><span class="va-arrow-box"></span></span><span class="va-box"></span></span></'+alertElem+'>').css({position: 'absolute', display: 'none'});
524
+ webshims.ready('DOM', function(){
525
+ errorBubble.appendTo('body');
526
+ if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){
527
+ errorBubble.bgIframe();
528
+ }
529
+ });
530
+ }
531
+ };
532
+
533
+
534
+ boundHide = $.proxy(api, 'hide');
535
+
536
+ return api;
537
+ })();
538
+
539
+
540
+ /* extension, but also used to fix native implementation workaround/bugfixes */
541
+ (function(){
542
+ var firstEvent,
543
+ invalids = [],
544
+ stopSubmitTimer,
545
+ form
546
+ ;
547
+
548
+ $(document).on('invalid', function(e){
549
+ if(e.wrongWebkitInvalid){return;}
550
+ var jElm = $(e.target);
551
+ var shadowElem = jElm.getShadowElement();
552
+ if(!shadowElem.hasClass(invalidClass)){
553
+ shadowElem.addClass(invalidClasses).removeClass(validClasses);
554
+ setTimeout(function(){
555
+ $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
556
+ }, 0);
557
+ }
558
+
559
+ if(!firstEvent){
560
+ //trigger firstinvalid
561
+ firstEvent = $.Event('firstinvalid');
562
+ firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
563
+ var firstSystemInvalid = $.Event('firstinvalidsystem');
564
+ $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
565
+ jElm.trigger(firstEvent);
566
+ }
567
+
568
+ //if firstinvalid was prevented all invalids will be also prevented
569
+ if( firstEvent && firstEvent.isDefaultPrevented() ){
570
+ e.preventDefault();
571
+ }
572
+ invalids.push(e.target);
573
+ e.extraData = 'fix';
574
+ clearTimeout(stopSubmitTimer);
575
+ stopSubmitTimer = setTimeout(function(){
576
+ var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
577
+ //reset firstinvalid
578
+ firstEvent = false;
579
+ invalids = [];
580
+ $(e.target).trigger(lastEvent, lastEvent);
581
+ }, 9);
582
+ jElm = null;
583
+ shadowElem = null;
584
+ });
585
+ })();
586
+
587
+ $.fn.getErrorMessage = function(){
588
+ var message = '';
589
+ var elem = this[0];
590
+ if(elem){
591
+ message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
592
+ }
593
+ return message;
594
+ };
595
+
596
+ if(options.replaceValidationUI){
597
+ webshims.ready('DOM forms', function(){
598
+ $(document).on('firstinvalid', function(e){
599
+ if(!e.isInvalidUIPrevented()){
600
+ e.preventDefault();
601
+ $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') );
602
+ }
603
+ });
604
+ });
605
+ }
606
+
607
+ });jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
608
+ "use strict";
609
+ var validityMessages = webshims.validityMessages;
610
+
611
+ var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
612
+
613
+ validityMessages['en'] = $.extend(true, {
614
+ typeMismatch: {
615
+ email: 'Please enter an email address.',
616
+ url: 'Please enter a URL.',
617
+ number: 'Please enter a number.',
618
+ date: 'Please enter a date.',
619
+ time: 'Please enter a time.',
620
+ range: 'Invalid input.',
621
+ "datetime-local": 'Please enter a datetime.'
622
+ },
623
+ rangeUnderflow: {
624
+ defaultMessage: 'Value must be greater than or equal to {%min}.'
625
+ },
626
+ rangeOverflow: {
627
+ defaultMessage: 'Value must be less than or equal to {%max}.'
628
+ },
629
+ stepMismatch: 'Invalid input.',
630
+ tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
631
+
632
+ patternMismatch: 'Invalid input. {%title}',
633
+ valueMissing: {
634
+ defaultMessage: 'Please fill out this field.',
635
+ checkbox: 'Please check this box if you want to proceed.'
636
+ }
637
+ }, (validityMessages['en'] || validityMessages['en-US'] || {}));
638
+
639
+
640
+ ['select', 'radio'].forEach(function(type){
641
+ validityMessages['en'].valueMissing[type] = 'Please select an option.';
642
+ });
643
+
644
+ ['date', 'time', 'datetime-local'].forEach(function(type){
645
+ validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
646
+ });
647
+ ['date', 'time', 'datetime-local'].forEach(function(type){
648
+ validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
649
+ });
650
+
651
+ validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
652
+ validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
653
+
654
+ validityMessages['de'] = $.extend(true, {
655
+ typeMismatch: {
656
+ email: '{%value} ist keine zulässige E-Mail-Adresse',
657
+ url: '{%value} ist keine zulässige Webadresse',
658
+ number: '{%value} ist keine Nummer!',
659
+ date: '{%value} ist kein Datum',
660
+ time: '{%value} ist keine Uhrzeit',
661
+ range: '{%value} ist keine Nummer!',
662
+ "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
663
+ },
664
+ rangeUnderflow: {
665
+ defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
666
+ },
667
+ rangeOverflow: {
668
+ defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
669
+ },
670
+ stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
671
+ tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
672
+ patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
673
+ valueMissing: {
674
+ defaultMessage: 'Bitte geben Sie einen Wert ein',
675
+ checkbox: 'Bitte aktivieren Sie das Kästchen'
676
+ }
677
+ }, (validityMessages['de'] || {}));
678
+
679
+ ['select', 'radio'].forEach(function(type){
680
+ validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
681
+ });
682
+
683
+ ['date', 'time', 'datetime-local'].forEach(function(type){
684
+ validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
685
+ });
686
+ ['date', 'time', 'datetime-local'].forEach(function(type){
687
+ validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
688
+ });
689
+
690
+ var currentValidationMessage = validityMessages[''];
691
+
692
+
693
+ webshims.createValidationMessage = function(elem, name){
694
+ var message = currentValidationMessage[name];
695
+ if(message && typeof message !== 'string'){
696
+ message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
697
+ }
698
+ if(message){
699
+ ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
700
+ if(message.indexOf('{%'+attr) === -1){return;}
701
+ var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
702
+ if(name == 'patternMismatch' && attr == 'title' && !val){
703
+ webshims.error('no title for patternMismatch provided. Always add a title attribute.');
704
+ }
705
+ message = message.replace('{%'+ attr +'}', val);
706
+ if('value' == attr){
707
+ message = message.replace('{%valueLen}', val.length);
708
+ }
709
+ });
710
+ }
711
+ return message || '';
712
+ };
713
+
714
+
715
+ if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
716
+ implementProperties.push('validationMessage');
717
+ }
718
+
719
+ webshims.activeLang({
720
+ langObj: validityMessages,
721
+ module: 'form-core',
722
+ callback: function(langObj){
723
+ currentValidationMessage = langObj;
724
+ }
725
+ });
726
+
727
+ implementProperties.forEach(function(messageProp){
728
+ webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
729
+ prop: {
730
+ value: '',
731
+ writeable: false
732
+ }
733
+ });
734
+ ['input', 'select', 'textarea'].forEach(function(nodeName){
735
+ var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
736
+ prop: {
737
+ get: function(){
738
+ var elem = this;
739
+ var message = '';
740
+ if(!$.prop(elem, 'willValidate')){
741
+ return message;
742
+ }
743
+
744
+ var validity = $.prop(elem, 'validity') || {valid: 1};
745
+
746
+ if(validity.valid){return message;}
747
+ message = webshims.getContentValidationMessage(elem, validity);
748
+
749
+ if(message){return message;}
750
+
751
+ if(validity.customError && elem.nodeName){
752
+ message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
753
+ if(message){return message;}
754
+ }
755
+ $.each(validity, function(name, prop){
756
+ if(name == 'valid' || !prop){return;}
757
+
758
+ message = webshims.createValidationMessage(elem, name);
759
+ if(message){
760
+ return false;
761
+ }
762
+ });
763
+ return message || '';
764
+ },
765
+ writeable: false
766
+ }
767
+ });
768
+ });
769
+
770
+ });
771
+ });if(!Modernizr.formvalidation || jQuery.webshims.bugs.bustedValidity){
772
+ jQuery.webshims.register('form-extend', function($, webshims, window, document){
773
+ "use strict";
774
+ webshims.inputTypes = webshims.inputTypes || {};
775
+ //some helper-functions
776
+ var cfg = webshims.cfg.forms;
777
+ var isSubmit;
778
+
779
+ var isNumber = function(string){
780
+ return (typeof string == 'number' || (string && string == string * 1));
781
+ },
782
+ typeModels = webshims.inputTypes,
783
+ checkTypes = {
784
+ radio: 1,
785
+ checkbox: 1
786
+ },
787
+ getType = function(elem){
788
+ return (elem.getAttribute('type') || elem.type || '').toLowerCase();
789
+ }
790
+ ;
791
+
792
+ //API to add new input types
793
+ webshims.addInputType = function(type, obj){
794
+ typeModels[type] = obj;
795
+ };
796
+
797
+ //contsrain-validation-api
798
+ var validityPrototype = {
799
+ customError: false,
800
+
801
+ typeMismatch: false,
802
+ rangeUnderflow: false,
803
+ rangeOverflow: false,
804
+ stepMismatch: false,
805
+ tooLong: false,
806
+ patternMismatch: false,
807
+ valueMissing: false,
808
+
809
+ valid: true
810
+ };
811
+
812
+ var isPlaceholderOptionSelected = function(select){
813
+ if(select.type == 'select-one' && select.size < 2){
814
+ var option = $('> option:first-child', select);
815
+ return !!option.prop('selected');
816
+ }
817
+ return false;
818
+ };
819
+
820
+ var validityRules = {
821
+ valueMissing: function(input, val, cache){
822
+ if(!input.prop('required')){return false;}
823
+ var ret = false;
824
+ if(!('type' in cache)){
825
+ cache.type = getType(input[0]);
826
+ }
827
+ if(cache.nodeName == 'select'){
828
+ ret = (!val && (input[0].selectedIndex < 0 || isPlaceholderOptionSelected(input[0]) ));
829
+ } else if(checkTypes[cache.type]){
830
+ ret = (cache.type == 'checkbox') ? !input.is(':checked') : !webshims.modules["form-core"].getGroupElements(input).filter(':checked')[0];
831
+ } else {
832
+ ret = !(val);
833
+ }
834
+ return ret;
835
+ },
836
+ tooLong: function(){
837
+ return false;
838
+ },
839
+ typeMismatch: function (input, val, cache){
840
+ if(val === '' || cache.nodeName == 'select'){return false;}
841
+ var ret = false;
842
+ if(!('type' in cache)){
843
+ cache.type = getType(input[0]);
844
+ }
845
+
846
+ if(typeModels[cache.type] && typeModels[cache.type].mismatch){
847
+ ret = typeModels[cache.type].mismatch(val, input);
848
+ } else if('validity' in input[0]){
849
+ ret = input[0].validity.typeMismatch;
850
+ }
851
+ return ret;
852
+ },
853
+ patternMismatch: function(input, val, cache) {
854
+ if(val === '' || cache.nodeName == 'select'){return false;}
855
+ var pattern = input.attr('pattern');
856
+ if(!pattern){return false;}
857
+ try {
858
+ pattern = new RegExp('^(?:' + pattern + ')$');
859
+ } catch(er){
860
+ webshims.error('invalid pattern value: "'+ pattern +'" | '+ er);
861
+ pattern = false;
862
+ }
863
+ if(!pattern){return false;}
864
+ return !(pattern.test(val));
865
+ }
866
+ }
867
+ ;
868
+
869
+ webshims.addValidityRule = function(type, fn){
870
+ validityRules[type] = fn;
871
+ };
872
+
873
+ $.event.special.invalid = {
874
+ add: function(){
875
+ $.event.special.invalid.setup.call(this.form || this);
876
+ },
877
+ setup: function(){
878
+ var form = this.form || this;
879
+ if( $.data(form, 'invalidEventShim') ){
880
+ form = null;
881
+ return;
882
+ }
883
+ $(form)
884
+ .data('invalidEventShim', true)
885
+ .on('submit', $.event.special.invalid.handler)
886
+ ;
887
+ webshims.moveToFirstEvent(form, 'submit');
888
+ if(webshims.bugs.bustedValidity && $.nodeName(form, 'form')){
889
+ (function(){
890
+ var noValidate = form.getAttribute('novalidate');
891
+ form.setAttribute('novalidate', 'novalidate');
892
+ webshims.data(form, 'bustedNoValidate', (noValidate == null) ? null : noValidate);
893
+ })();
894
+ }
895
+ form = null;
896
+ },
897
+ teardown: $.noop,
898
+ handler: function(e, d){
899
+
900
+ if( e.type != 'submit' || e.testedValidity || !e.originalEvent || !$.nodeName(e.target, 'form') || $.prop(e.target, 'noValidate') ){return;}
901
+
902
+ isSubmit = true;
903
+ e.testedValidity = true;
904
+ var notValid = !($(e.target).checkValidity());
905
+ if(notValid){
906
+ e.stopImmediatePropagation();
907
+ isSubmit = false;
908
+ return false;
909
+ }
910
+ isSubmit = false;
911
+ }
912
+ };
913
+
914
+ var addSubmitBubbles = function(form){
915
+ if (!$.support.submitBubbles && form && typeof form == 'object' && !form._submit_attached ) {
916
+
917
+ $.event.add( form, 'submit._submit', function( event ) {
918
+ event._submit_bubble = true;
919
+ });
920
+
921
+ form._submit_attached = true;
922
+ }
923
+ };
924
+ if(!$.support.submitBubbles && $.event.special.submit){
925
+ $.event.special.submit.setup = function() {
926
+ // Only need this for delegated form submit events
927
+ if ( $.nodeName( this, "form" ) ) {
928
+ return false;
929
+ }
930
+
931
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
932
+ $.event.add( this, "click._submit keypress._submit", function( e ) {
933
+ // Node name check avoids a VML-related crash in IE (#9807)
934
+ var elem = e.target,
935
+ form = $.nodeName( elem, 'input' ) || $.nodeName( elem, 'button' ) ? $.prop(elem, 'form') : undefined;
936
+ addSubmitBubbles(form);
937
+
938
+ });
939
+ // return undefined since we don't need an event listener
940
+ };
941
+ }
942
+
943
+ $.event.special.submit = $.event.special.submit || {setup: function(){return false;}};
944
+ var submitSetup = $.event.special.submit.setup;
945
+ $.extend($.event.special.submit, {
946
+ setup: function(){
947
+ if($.nodeName(this, 'form')){
948
+ $(this).on('invalid', $.noop);
949
+ } else {
950
+ $('form', this).on('invalid', $.noop);
951
+ }
952
+ return submitSetup.apply(this, arguments);
953
+ }
954
+ });
955
+
956
+ $(window).on('invalid', $.noop);
957
+
958
+
959
+ webshims.addInputType('email', {
960
+ mismatch: (function(){
961
+ //taken from http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
962
+ var test = cfg.emailReg || /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
963
+ return function(val){
964
+ return !test.test(val);
965
+ };
966
+ })()
967
+ });
968
+
969
+ webshims.addInputType('url', {
970
+ mismatch: (function(){
971
+ //taken from scott gonzales
972
+ 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;
973
+ return function(val){
974
+ return !test.test(val);
975
+ };
976
+ })()
977
+ });
978
+
979
+ webshims.defineNodeNameProperty('input', 'type', {
980
+ prop: {
981
+ get: function(){
982
+ var elem = this;
983
+ var type = (elem.getAttribute('type') || '').toLowerCase();
984
+ return (webshims.inputTypes[type]) ? type : elem.type;
985
+ }
986
+ }
987
+ });
988
+
989
+ // IDLs for constrain validation API
990
+ //ToDo: add object to this list
991
+ webshims.defineNodeNamesProperties(['button', 'fieldset', 'output'], {
992
+ checkValidity: {
993
+ value: function(){return true;}
994
+ },
995
+ willValidate: {
996
+ value: false
997
+ },
998
+ setCustomValidity: {
999
+ value: $.noop
1000
+ },
1001
+ validity: {
1002
+ writeable: false,
1003
+ get: function(){
1004
+ return $.extend({}, validityPrototype);
1005
+ }
1006
+ }
1007
+ }, 'prop');
1008
+
1009
+ var baseCheckValidity = function(elem){
1010
+ var e,
1011
+ v = $.prop(elem, 'validity')
1012
+ ;
1013
+ if(v){
1014
+ $.data(elem, 'cachedValidity', v);
1015
+ } else {
1016
+ return true;
1017
+ }
1018
+ if( !v.valid ){
1019
+ e = $.Event('invalid');
1020
+ var jElm = $(elem).trigger(e);
1021
+ if(isSubmit && !baseCheckValidity.unhandledInvalids && !e.isDefaultPrevented()){
1022
+ webshims.validityAlert.showFor(jElm);
1023
+ baseCheckValidity.unhandledInvalids = true;
1024
+ }
1025
+ }
1026
+ $.removeData(elem, 'cachedValidity');
1027
+ return v.valid;
1028
+ };
1029
+ var rsubmittable = /^(?:select|textarea|input)/i;
1030
+ webshims.defineNodeNameProperty('form', 'checkValidity', {
1031
+ prop: {
1032
+ value: function(){
1033
+
1034
+ var ret = true,
1035
+ elems = $($.prop(this, 'elements')).filter(function(){
1036
+ if(!rsubmittable.test(this.nodeName)){return false;}
1037
+ var shadowData = webshims.data(this, 'shadowData');
1038
+ return !shadowData || !shadowData.nativeElement || shadowData.nativeElement === this;
1039
+ })
1040
+ ;
1041
+
1042
+ baseCheckValidity.unhandledInvalids = false;
1043
+ for(var i = 0, len = elems.length; i < len; i++){
1044
+ if( !baseCheckValidity(elems[i]) ){
1045
+ ret = false;
1046
+ }
1047
+ }
1048
+ return ret;
1049
+ }
1050
+ }
1051
+ });
1052
+
1053
+ webshims.defineNodeNamesProperties(['input', 'textarea', 'select'], {
1054
+ checkValidity: {
1055
+ value: function(){
1056
+ baseCheckValidity.unhandledInvalids = false;
1057
+ return baseCheckValidity($(this).getNativeElement()[0]);
1058
+ }
1059
+ },
1060
+ setCustomValidity: {
1061
+ value: function(error){
1062
+ $.removeData(this, 'cachedValidity');
1063
+ webshims.data(this, 'customvalidationMessage', ''+error);
1064
+ }
1065
+ },
1066
+ willValidate: {
1067
+ writeable: false,
1068
+ get: (function(){
1069
+ var types = {
1070
+ button: 1,
1071
+ reset: 1,
1072
+ hidden: 1,
1073
+ image: 1
1074
+ }
1075
+ ;
1076
+ return function(){
1077
+ var elem = $(this).getNativeElement()[0];
1078
+ //elem.name && <- we don't use to make it easier for developers
1079
+ return !!(!elem.disabled && !elem.readOnly && !types[elem.type] );
1080
+ };
1081
+ })()
1082
+ },
1083
+ validity: {
1084
+ writeable: false,
1085
+ get: function(){
1086
+ var jElm = $(this).getNativeElement();
1087
+ var elem = jElm[0];
1088
+ var validityState = $.data(elem, 'cachedValidity');
1089
+ if(validityState){
1090
+ return validityState;
1091
+ }
1092
+ validityState = $.extend({}, validityPrototype);
1093
+
1094
+ if( !$.prop(elem, 'willValidate') || elem.type == 'submit' ){
1095
+ return validityState;
1096
+ }
1097
+ var val = jElm.val(),
1098
+ cache = {nodeName: elem.nodeName.toLowerCase()}
1099
+ ;
1100
+
1101
+ validityState.customError = !!(webshims.data(elem, 'customvalidationMessage'));
1102
+ if( validityState.customError ){
1103
+ validityState.valid = false;
1104
+ }
1105
+
1106
+ $.each(validityRules, function(rule, fn){
1107
+ if (fn(jElm, val, cache)) {
1108
+ validityState[rule] = true;
1109
+ validityState.valid = false;
1110
+ }
1111
+ });
1112
+ $(this).getShadowFocusElement().attr('aria-invalid', validityState.valid ? 'false' : 'true');
1113
+ jElm = null;
1114
+ elem = null;
1115
+ return validityState;
1116
+ }
1117
+ }
1118
+ }, 'prop');
1119
+
1120
+ webshims.defineNodeNamesBooleanProperty(['input', 'textarea', 'select'], 'required', {
1121
+ set: function(value){
1122
+ $(this).getShadowFocusElement().attr('aria-required', !!(value)+'');
1123
+ },
1124
+ initAttr: (!$.browser.msie || webshims.browserVersion > 7)//only if we have aria-support
1125
+ });
1126
+
1127
+ webshims.reflectProperties(['input'], ['pattern']);
1128
+
1129
+
1130
+ if( !('maxLength' in document.createElement('textarea')) ){
1131
+ var constrainMaxLength = (function(){
1132
+ var timer;
1133
+ var curLength = 0;
1134
+ var lastElement = $([]);
1135
+ var max = 1e9;
1136
+ var constrainLength = function(){
1137
+ var nowValue = lastElement.prop('value');
1138
+ var nowLen = nowValue.length;
1139
+ if(nowLen > curLength && nowLen > max){
1140
+ nowLen = Math.max(curLength, max);
1141
+ lastElement.prop('value', nowValue.substr(0, nowLen ));
1142
+ }
1143
+ curLength = nowLen;
1144
+ };
1145
+ var remove = function(){
1146
+ clearTimeout(timer);
1147
+ lastElement.unbind('.maxlengthconstraint');
1148
+ };
1149
+ return function(element, maxLength){
1150
+ remove();
1151
+ if(maxLength > -1){
1152
+ max = maxLength;
1153
+ curLength = $.prop(element, 'value').length;
1154
+ lastElement = $(element);
1155
+ lastElement.on({
1156
+ 'keydown.maxlengthconstraint keypress.maxlengthconstraint paste.maxlengthconstraint cut.maxlengthconstraint': function(e){
1157
+ setTimeout(constrainLength, 0);
1158
+ },
1159
+ 'keyup.maxlengthconstraint': constrainLength,
1160
+ 'blur.maxlengthconstraint': remove
1161
+ });
1162
+ timer = setInterval(constrainLength, 200);
1163
+ }
1164
+ };
1165
+ })();
1166
+
1167
+ constrainMaxLength.update = function(element, maxLength){
1168
+ if($(element).is(':focus')){
1169
+ if(!maxLength){
1170
+ maxLength = $.prop(element, 'maxlength');
1171
+ }
1172
+ constrainMaxLength(element, maxLength);
1173
+ }
1174
+ };
1175
+
1176
+ $(document).on('focusin', function(e){
1177
+ var maxLength;
1178
+ if(e.target.nodeName == "TEXTAREA" && (maxLength = $.prop(e.target, 'maxlength')) > -1){
1179
+ constrainMaxLength(e.target, maxLength);
1180
+ }
1181
+ });
1182
+
1183
+ webshims.defineNodeNameProperty('textarea', 'maxlength', {
1184
+ attr: {
1185
+ set: function(val){
1186
+ this.setAttribute('maxlength', ''+val);
1187
+ constrainMaxLength.update(this);
1188
+ },
1189
+ get: function(){
1190
+ var ret = this.getAttribute('maxlength');
1191
+ return ret == null ? undefined : ret;
1192
+ }
1193
+ },
1194
+ prop: {
1195
+ set: function(val){
1196
+ if(isNumber(val)){
1197
+ if(val < 0){
1198
+ throw('INDEX_SIZE_ERR');
1199
+ }
1200
+ val = parseInt(val, 10);
1201
+ this.setAttribute('maxlength', val);
1202
+ constrainMaxLength.update(this, val);
1203
+ return;
1204
+ }
1205
+ this.setAttribute('maxlength', '0');
1206
+ constrainMaxLength.update(this, 0);
1207
+ },
1208
+ get: function(){
1209
+ var val = this.getAttribute('maxlength');
1210
+ return (isNumber(val) && val >= 0) ? parseInt(val, 10) : -1;
1211
+
1212
+ }
1213
+ }
1214
+ });
1215
+ webshims.defineNodeNameProperty('textarea', 'maxLength', {
1216
+ prop: {
1217
+ set: function(val){
1218
+ $.prop(this, 'maxlength', val);
1219
+ },
1220
+ get: function(){
1221
+ return $.prop(this, 'maxlength');
1222
+ }
1223
+ }
1224
+ });
1225
+ }
1226
+
1227
+
1228
+
1229
+ var submitterTypes = {submit: 1, button: 1, image: 1};
1230
+ var formSubmitterDescriptors = {};
1231
+ [
1232
+ {
1233
+ name: "enctype",
1234
+ limitedTo: {
1235
+ "application/x-www-form-urlencoded": 1,
1236
+ "multipart/form-data": 1,
1237
+ "text/plain": 1
1238
+ },
1239
+ defaultProp: "application/x-www-form-urlencoded",
1240
+ proptype: "enum"
1241
+ },
1242
+ {
1243
+ name: "method",
1244
+ limitedTo: {
1245
+ "get": 1,
1246
+ "post": 1
1247
+ },
1248
+ defaultProp: "get",
1249
+ proptype: "enum"
1250
+ },
1251
+ {
1252
+ name: "action",
1253
+ proptype: "url"
1254
+ },
1255
+ {
1256
+ name: "target"
1257
+ },
1258
+ {
1259
+ name: "novalidate",
1260
+ propName: "noValidate",
1261
+ proptype: "boolean"
1262
+ }
1263
+ ].forEach(function(desc){
1264
+ var propName = 'form'+ (desc.propName || desc.name).replace(/^[a-z]/, function(f){
1265
+ return f.toUpperCase();
1266
+ });
1267
+ var attrName = 'form'+ desc.name;
1268
+ var formName = desc.name;
1269
+ var eventName = 'click.webshimssubmittermutate'+formName;
1270
+
1271
+ var changeSubmitter = function(){
1272
+ var elem = this;
1273
+ if( !('form' in elem) || !submitterTypes[elem.type] ){return;}
1274
+ var form = $.prop(elem, 'form');
1275
+ if(!form){return;}
1276
+ var attr = $.attr(elem, attrName);
1277
+ if(attr != null && ( !desc.limitedTo || attr.toLowerCase() === $.prop(elem, propName))){
1278
+
1279
+ var oldAttr = $.attr(form, formName);
1280
+
1281
+ $.attr(form, formName, attr);
1282
+ setTimeout(function(){
1283
+ if(oldAttr != null){
1284
+ $.attr(form, formName, oldAttr);
1285
+ } else {
1286
+ try {
1287
+ $(form).removeAttr(formName);
1288
+ } catch(er){
1289
+ form.removeAttribute(formName);
1290
+ }
1291
+ }
1292
+ }, 9);
1293
+ }
1294
+ };
1295
+
1296
+
1297
+
1298
+ switch(desc.proptype) {
1299
+ case "url":
1300
+ var urlForm = document.createElement('form');
1301
+ formSubmitterDescriptors[propName] = {
1302
+ prop: {
1303
+ set: function(value){
1304
+ $.attr(this, attrName, value);
1305
+ },
1306
+ get: function(){
1307
+ var value = $.attr(this, attrName);
1308
+ if(value == null){return '';}
1309
+ urlForm.setAttribute('action', value);
1310
+ return urlForm.action;
1311
+ }
1312
+ }
1313
+ };
1314
+ break;
1315
+ case "boolean":
1316
+ formSubmitterDescriptors[propName] = {
1317
+ prop: {
1318
+ set: function(val){
1319
+ val = !!val;
1320
+ if(val){
1321
+ $.attr(this, 'formnovalidate', 'formnovalidate');
1322
+ } else {
1323
+ $(this).removeAttr('formnovalidate');
1324
+ }
1325
+ },
1326
+ get: function(){
1327
+ return $.attr(this, 'formnovalidate') != null;
1328
+ }
1329
+ }
1330
+ };
1331
+ break;
1332
+ case "enum":
1333
+ formSubmitterDescriptors[propName] = {
1334
+ prop: {
1335
+ set: function(value){
1336
+ $.attr(this, attrName, value);
1337
+ },
1338
+ get: function(){
1339
+ var value = $.attr(this, attrName);
1340
+ return (!value || ( (value = value.toLowerCase()) && !desc.limitedTo[value] )) ? desc.defaultProp : value;
1341
+ }
1342
+ }
1343
+ };
1344
+ break;
1345
+ default:
1346
+ formSubmitterDescriptors[propName] = {
1347
+ prop: {
1348
+ set: function(value){
1349
+ $.attr(this, attrName, value);
1350
+ },
1351
+ get: function(){
1352
+ var value = $.attr(this, attrName);
1353
+ return (value != null) ? value : "";
1354
+ }
1355
+ }
1356
+ };
1357
+ }
1358
+
1359
+
1360
+ if(!formSubmitterDescriptors[attrName]){
1361
+ formSubmitterDescriptors[attrName] = {};
1362
+ }
1363
+ formSubmitterDescriptors[attrName].attr = {
1364
+ set: function(value){
1365
+ formSubmitterDescriptors[attrName].attr._supset.call(this, value);
1366
+ $(this).unbind(eventName).on(eventName, changeSubmitter);
1367
+ },
1368
+ get: function(){
1369
+ return formSubmitterDescriptors[attrName].attr._supget.call(this);
1370
+ }
1371
+ };
1372
+ formSubmitterDescriptors[attrName].initAttr = true;
1373
+ formSubmitterDescriptors[attrName].removeAttr = {
1374
+ value: function(){
1375
+ $(this).unbind(eventName);
1376
+ formSubmitterDescriptors[attrName].removeAttr._supvalue.call(this);
1377
+ }
1378
+ };
1379
+ });
1380
+
1381
+ webshims.defineNodeNamesProperties(['input', 'button'], formSubmitterDescriptors);
1382
+
1383
+
1384
+ if(!$.support.getSetAttribute && $('<form novalidate></form>').attr('novalidate') == null){
1385
+ webshims.defineNodeNameProperty('form', 'novalidate', {
1386
+ attr: {
1387
+ set: function(val){
1388
+ this.setAttribute('novalidate', ''+val);
1389
+ },
1390
+ get: function(){
1391
+ var ret = this.getAttribute('novalidate');
1392
+ return ret == null ? undefined : ret;
1393
+ }
1394
+ }
1395
+ });
1396
+ } else if(webshims.bugs.bustedValidity){
1397
+
1398
+ webshims.defineNodeNameProperty('form', 'novalidate', {
1399
+ attr: {
1400
+ set: function(val){
1401
+ webshims.data(this, 'bustedNoValidate', ''+val);
1402
+ },
1403
+ get: function(){
1404
+ var ret = webshims.data(this, 'bustedNoValidate');
1405
+ return ret == null ? undefined : ret;
1406
+ }
1407
+ },
1408
+ removeAttr: {
1409
+ value: function(){
1410
+ webshims.data(this, 'bustedNoValidate', null);
1411
+ }
1412
+ }
1413
+ });
1414
+
1415
+ $.each(['rangeUnderflow', 'rangeOverflow', 'stepMismatch'], function(i, name){
1416
+ validityRules[name] = function(elem){
1417
+ return (elem[0].validity || {})[name] || false;
1418
+ };
1419
+ });
1420
+
1421
+ }
1422
+
1423
+ webshims.defineNodeNameProperty('form', 'noValidate', {
1424
+ prop: {
1425
+ set: function(val){
1426
+ val = !!val;
1427
+ if(val){
1428
+ $.attr(this, 'novalidate', 'novalidate');
1429
+ } else {
1430
+ $(this).removeAttr('novalidate');
1431
+ }
1432
+ },
1433
+ get: function(){
1434
+ return $.attr(this, 'novalidate') != null;
1435
+ }
1436
+ }
1437
+ });
1438
+
1439
+ if($.browser.webkit && Modernizr.inputtypes.date){
1440
+ (function(){
1441
+
1442
+ var noInputTriggerEvts = {updateInput: 1, input: 1},
1443
+ fixInputTypes = {
1444
+ date: 1,
1445
+ time: 1,
1446
+ "datetime-local": 1
1447
+ },
1448
+ noFocusEvents = {
1449
+ focusout: 1,
1450
+ blur: 1
1451
+ },
1452
+ changeEvts = {
1453
+ updateInput: 1,
1454
+ change: 1
1455
+ },
1456
+ observe = function(input){
1457
+ var timer,
1458
+ focusedin = true,
1459
+ lastInputVal = input.prop('value'),
1460
+ lastChangeVal = lastInputVal,
1461
+ trigger = function(e){
1462
+ //input === null
1463
+ if(!input){return;}
1464
+ var newVal = input.prop('value');
1465
+
1466
+ if(newVal !== lastInputVal){
1467
+ lastInputVal = newVal;
1468
+ if(!e || !noInputTriggerEvts[e.type]){
1469
+ input.trigger('input');
1470
+ }
1471
+ }
1472
+ if(e && changeEvts[e.type]){
1473
+ lastChangeVal = newVal;
1474
+ }
1475
+ if(!focusedin && newVal !== lastChangeVal){
1476
+ input.trigger('change');
1477
+ }
1478
+ },
1479
+ extraTimer,
1480
+ extraTest = function(){
1481
+ clearTimeout(extraTimer);
1482
+ extraTimer = setTimeout(trigger, 9);
1483
+ },
1484
+ unbind = function(e){
1485
+ clearInterval(timer);
1486
+ setTimeout(function(){
1487
+ if(e && noFocusEvents[e.type]){
1488
+ focusedin = false;
1489
+ }
1490
+ if(input){
1491
+ input.unbind('focusout blur', unbind).unbind('input change updateInput', trigger);
1492
+ trigger();
1493
+ }
1494
+ input = null;
1495
+ }, 1);
1496
+
1497
+ }
1498
+ ;
1499
+
1500
+ clearInterval(timer);
1501
+ timer = setInterval(trigger, 160);
1502
+ extraTest();
1503
+ input
1504
+ .off({
1505
+ 'focusout blur': unbind,
1506
+ 'input change updateInput': trigger
1507
+ })
1508
+ .on({
1509
+ 'focusout blur': unbind,
1510
+ 'input updateInput change': trigger
1511
+ })
1512
+ ;
1513
+ }
1514
+ ;
1515
+ if($.event.customEvent){
1516
+ $.event.customEvent.updateInput = true;
1517
+ }
1518
+
1519
+ (function(){
1520
+
1521
+ var correctValue = function(elem){
1522
+ var i = 1;
1523
+ var len = 3;
1524
+ var abort, val;
1525
+ if(elem.type == 'date' && (isSubmit || !$(elem).is(':focus'))){
1526
+ val = elem.value;
1527
+ if(val && val.length < 10 && (val = val.split('-')) && val.length == len){
1528
+ for(; i < len; i++){
1529
+ if(val[i].length == 1){
1530
+ val[i] = '0'+val[i];
1531
+ } else if(val[i].length != 2){
1532
+ abort = true;
1533
+ break;
1534
+ }
1535
+ }
1536
+ if(!abort){
1537
+ val = val.join('-');
1538
+ $.prop(elem, 'value', val);
1539
+ return val;
1540
+ }
1541
+ }
1542
+ }
1543
+ };
1544
+ var inputCheckValidityDesc, formCheckValidityDesc, inputValueDesc, inputValidityDesc;
1545
+
1546
+ inputCheckValidityDesc = webshims.defineNodeNameProperty('input', 'checkValidity', {
1547
+ prop: {
1548
+ value: function(){
1549
+ correctValue(this);
1550
+ return inputCheckValidityDesc.prop._supvalue.apply(this, arguments);
1551
+ }
1552
+ }
1553
+ });
1554
+
1555
+ formCheckValidityDesc = webshims.defineNodeNameProperty('form', 'checkValidity', {
1556
+ prop: {
1557
+ value: function(){
1558
+ $('input', this).each(function(){
1559
+ correctValue(this);
1560
+ });
1561
+ return formCheckValidityDesc.prop._supvalue.apply(this, arguments);
1562
+ }
1563
+ }
1564
+ });
1565
+
1566
+ inputValueDesc = webshims.defineNodeNameProperty('input', 'value', {
1567
+ prop: {
1568
+ set: function(){
1569
+ return inputValueDesc.prop._supset.apply(this, arguments);
1570
+ },
1571
+ get: function(){
1572
+ return correctValue(this) || inputValueDesc.prop._supget.apply(this, arguments);
1573
+ }
1574
+ }
1575
+ });
1576
+
1577
+ inputValidityDesc = webshims.defineNodeNameProperty('input', 'validity', {
1578
+ prop: {
1579
+ writeable: false,
1580
+ get: function(){
1581
+ correctValue(this);
1582
+ return inputValidityDesc.prop._supget.apply(this, arguments);
1583
+ }
1584
+ }
1585
+ });
1586
+
1587
+ $(document).on('change', function(e){
1588
+ isChangeSubmit = true;
1589
+ correctValue(e.target);
1590
+ isChangeSubmit = false;
1591
+ });
1592
+
1593
+ })();
1594
+
1595
+ $(document)
1596
+ .on('focusin', function(e){
1597
+ if( e.target && fixInputTypes[e.target.type] && !e.target.readOnly && !e.target.disabled ){
1598
+ observe($(e.target));
1599
+ }
1600
+ })
1601
+ ;
1602
+
1603
+
1604
+ })();
1605
+ }
1606
+
1607
+ webshims.addReady(function(context, contextElem){
1608
+ //start constrain-validation
1609
+ var focusElem;
1610
+ $('form', context)
1611
+ .add(contextElem.filter('form'))
1612
+ .bind('invalid', $.noop)
1613
+ ;
1614
+
1615
+ try {
1616
+ if(context == document && !('form' in (document.activeElement || {}))) {
1617
+ focusElem = $('input[autofocus], select[autofocus], textarea[autofocus]', context).eq(0).getShadowFocusElement()[0];
1618
+ if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) {
1619
+ focusElem.focus();
1620
+ }
1621
+ }
1622
+ }
1623
+ catch (er) {}
1624
+
1625
+ });
1626
+
1627
+ if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled){
1628
+ (function(){
1629
+ (function(prop, undefined){
1630
+ $.prop = function(elem, name, value){
1631
+ var ret;
1632
+ if(elem && elem.nodeType == 1 && value === undefined && $.nodeName(elem, 'form') && elem.id){
1633
+ ret = document.getElementsByName(name);
1634
+ if(!ret || !ret.length){
1635
+ ret = document.getElementById(name);
1636
+ }
1637
+ if(ret){
1638
+ ret = $(ret).filter(function(){
1639
+ return $.prop(this, 'form') == elem;
1640
+ }).get();
1641
+ if(ret.length){
1642
+ return ret.length == 1 ? ret[0] : ret;
1643
+ }
1644
+ }
1645
+ }
1646
+ return prop.apply(this, arguments);
1647
+ };
1648
+ })($.prop, undefined);
1649
+ var removeAddedElements = function(form){
1650
+ var elements = $.data(form, 'webshimsAddedElements');
1651
+ if(elements){
1652
+ elements.remove();
1653
+ $.removeData(form, 'webshimsAddedElements');
1654
+ }
1655
+ };
1656
+ var rCRLF = /\r?\n/g,
1657
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
1658
+ rselectTextarea = /^(?:select|textarea)/i;
1659
+
1660
+ if(!Modernizr.formattribute){
1661
+ webshims.defineNodeNamesProperty(['input', 'textarea', 'select', 'button', 'fieldset'], 'form', {
1662
+ prop: {
1663
+ get: function(){
1664
+ var form = webshims.contentAttr(this, 'form');
1665
+ if(form){
1666
+ form = document.getElementById(form);
1667
+ if(form && !$.nodeName(form, 'form')){
1668
+ form = null;
1669
+ }
1670
+ }
1671
+ return form || this.form;
1672
+ },
1673
+ writeable: false
1674
+ }
1675
+ });
1676
+
1677
+
1678
+ webshims.defineNodeNamesProperty(['form'], 'elements', {
1679
+ prop: {
1680
+ get: function(){
1681
+ var id = this.id;
1682
+ var elements = $.makeArray(this.elements);
1683
+ if(id){
1684
+ elements = $(elements).add('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"], button[form="'+ id +'"], fieldset[form="'+ id +'"]').not('.webshims-visual-hide > *').get();
1685
+ }
1686
+ return elements;
1687
+ },
1688
+ writeable: false
1689
+ }
1690
+ });
1691
+
1692
+
1693
+
1694
+ $(function(){
1695
+ var stopPropagation = function(e){
1696
+ e.stopPropagation();
1697
+ };
1698
+ $(document).on('submit', function(e){
1699
+
1700
+ if(!e.isDefaultPrevented()){
1701
+ var form = e.target;
1702
+ var id = form.id;
1703
+ var elements;
1704
+
1705
+
1706
+ if(id){
1707
+ removeAddedElements(form);
1708
+
1709
+ elements = $('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"]')
1710
+ .filter(function(){
1711
+ return !this.disabled && this.name && this.form != form;
1712
+ })
1713
+ .clone()
1714
+ ;
1715
+ if(elements.length){
1716
+ $.data(form, 'webshimsAddedElements', $('<div class="webshims-visual-hide" />').append(elements).appendTo(form));
1717
+ setTimeout(function(){
1718
+ removeAddedElements(form);
1719
+ }, 9);
1720
+ }
1721
+ elements = null;
1722
+ }
1723
+ }
1724
+ });
1725
+
1726
+ $(document).on('click', function(e){
1727
+ if(!e.isDefaultPrevented() && $(e.target).is('input[type="submit"][form], button[form], input[type="button"][form], input[type="image"][form], input[type="reset"][form]')){
1728
+ var trueForm = $.prop(e.target, 'form');
1729
+ var formIn = e.target.form;
1730
+ var clone;
1731
+ if(trueForm && trueForm != formIn){
1732
+ clone = $(e.target)
1733
+ .clone()
1734
+ .removeAttr('form')
1735
+ .addClass('webshims-visual-hide')
1736
+ .on('click', stopPropagation)
1737
+ .appendTo(trueForm)
1738
+ ;
1739
+ if(formIn){
1740
+ e.preventDefault();
1741
+ }
1742
+ addSubmitBubbles(trueForm);
1743
+ clone.trigger('click');
1744
+ setTimeout(function(){
1745
+ clone.remove();
1746
+ clone = null;
1747
+ }, 9);
1748
+ }
1749
+ }
1750
+ });
1751
+ });
1752
+ }
1753
+
1754
+ if(!Modernizr.fieldsetdisabled){
1755
+ webshims.defineNodeNamesProperty(['fieldset'], 'elements', {
1756
+ prop: {
1757
+ get: function(){
1758
+ //add listed elements without keygen, object, output
1759
+ return $('input, select, textarea, button, fieldset', this).get() || [];
1760
+ },
1761
+ writeable: false
1762
+ }
1763
+ });
1764
+ }
1765
+
1766
+ $.fn.serializeArray = function() {
1767
+ return this.map(function(){
1768
+ var elements = $.prop(this, 'elements');
1769
+ return elements ? $.makeArray( elements ) : this;
1770
+ })
1771
+ .filter(function(){
1772
+ return this.name && !this.disabled &&
1773
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
1774
+ rinput.test( this.type ) );
1775
+ })
1776
+ .map(function( i, elem ){
1777
+ var val = $( this ).val();
1778
+
1779
+ return val == null ?
1780
+ null :
1781
+ $.isArray( val ) ?
1782
+ $.map( val, function( val, i ){
1783
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1784
+ }) :
1785
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1786
+ }).get();
1787
+ };
1788
+
1789
+ })();
1790
+ }
1791
+
1792
+ try {
1793
+ document.querySelector(':checked');
1794
+ } catch(er){
1795
+ (function(){
1796
+ var checkInputs = {
1797
+ radio: 1,
1798
+ checkbox: 1
1799
+ };
1800
+ var selectChange = function(){
1801
+ var options = this.options || [];
1802
+ var i, len, option;
1803
+ for(i = 0, len = options.length; i < len; i++){
1804
+ option = $(options[i]);
1805
+ option[$.prop(options[i], 'selected') ? 'addClass' : 'removeClass']('prop-checked');
1806
+ }
1807
+ };
1808
+ var checkChange = function(){
1809
+ var fn = $.prop(this, 'checked') ? 'addClass' : 'removeClass';
1810
+ var className = this.className || '';
1811
+ var parent;
1812
+
1813
+ //IE8- has problems to update styles, we help
1814
+ if( (className.indexOf('prop-checked') == -1) == (fn == 'addClass')){
1815
+ $(this)[fn]('prop-checked');
1816
+ if((parent = this.parentNode)){
1817
+ parent.className = parent.className;
1818
+ }
1819
+ }
1820
+ };
1821
+
1822
+
1823
+ webshims.onNodeNamesPropertyModify('select', 'value', selectChange);
1824
+ webshims.onNodeNamesPropertyModify('select', 'selectedIndex', selectChange);
1825
+ webshims.onNodeNamesPropertyModify('option', 'selected', function(){
1826
+ $(this).closest('select').each(selectChange);
1827
+ });
1828
+ webshims.onNodeNamesPropertyModify('input', 'checked', function(value, boolVal){
1829
+ var type = this.type;
1830
+ if(type == 'radio' && boolVal){
1831
+ webshims.modules["form-core"].getGroupElements(this).each(checkChange);
1832
+ } else if(checkInputs[type]) {
1833
+ $(this).each(checkChange);
1834
+ }
1835
+ });
1836
+
1837
+ $(document).on('change', function(e){
1838
+
1839
+ if(checkInputs[e.target.type]){
1840
+ if(e.target.type == 'radio'){
1841
+ webshims.modules["form-core"].getGroupElements(e.target).each(checkChange);
1842
+ } else {
1843
+ $(e.target)[$.prop(e.target, 'checked') ? 'addClass' : 'removeClass']('prop-checked');
1844
+ }
1845
+ } else if(e.target.nodeName.toLowerCase() == 'select'){
1846
+ $(e.target).each(selectChange);
1847
+ }
1848
+ });
1849
+
1850
+ webshims.addReady(function(context, contextElem){
1851
+ $('option, input', context)
1852
+ .add(contextElem.filter('option, input'))
1853
+ .each(function(){
1854
+ var prop;
1855
+ if(checkInputs[this.type]){
1856
+ prop = 'checked';
1857
+ } else if(this.nodeName.toLowerCase() == 'option'){
1858
+ prop = 'selected';
1859
+ }
1860
+ if(prop){
1861
+ $(this)[$.prop(this, prop) ? 'addClass' : 'removeClass']('prop-checked');
1862
+ }
1863
+
1864
+ })
1865
+ ;
1866
+ });
1867
+ })();
1868
+ }
1869
+
1870
+ (function(){
1871
+ Modernizr.textareaPlaceholder = !!('placeholder' in $('<textarea />')[0]);
1872
+ var bustedTextarea = $.browser.webkit && Modernizr.textareaPlaceholder && webshims.browserVersion < 535;
1873
+ if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder && !bustedTextarea){return;}
1874
+
1875
+ var isOver = (webshims.cfg.forms.placeholderType == 'over');
1876
+ var isResponsive = (webshims.cfg.forms.responsivePlaceholder);
1877
+ var polyfillElements = ['textarea'];
1878
+ if(!Modernizr.input.placeholder){
1879
+ polyfillElements.push('input');
1880
+ }
1881
+
1882
+ var setSelection = function(elem){
1883
+ try {
1884
+ if(elem.setSelectionRange){
1885
+ elem.setSelectionRange(0, 0);
1886
+ return true;
1887
+ } else if(elem.createTextRange){
1888
+ var range = elem.createTextRange();
1889
+ range.collapse(true);
1890
+ range.moveEnd('character', 0);
1891
+ range.moveStart('character', 0);
1892
+ range.select();
1893
+ return true;
1894
+ }
1895
+ } catch(er){}
1896
+ };
1897
+
1898
+ var hidePlaceholder = function(elem, data, value, _onFocus){
1899
+ if(value === false){
1900
+ value = $.prop(elem, 'value');
1901
+ }
1902
+ if(!isOver && elem.type != 'password'){
1903
+ if(!value && _onFocus && setSelection(elem)){
1904
+ var selectTimer = setTimeout(function(){
1905
+ setSelection(elem);
1906
+ }, 9);
1907
+ $(elem)
1908
+ .off('.placeholderremove')
1909
+ .on({
1910
+ 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
1911
+ if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1912
+ elem.value = $.prop(elem, 'value');
1913
+ data.box.removeClass('placeholder-visible');
1914
+ clearTimeout(selectTimer);
1915
+ $(elem).unbind('.placeholderremove');
1916
+ },
1917
+ 'mousedown.placeholderremove drag.placeholderremove select.placeholderremove': function(e){
1918
+ setSelection(elem);
1919
+ clearTimeout(selectTimer);
1920
+ selectTimer = setTimeout(function(){
1921
+ setSelection(elem);
1922
+ }, 9);
1923
+ },
1924
+ 'blur.placeholderremove': function(){
1925
+ clearTimeout(selectTimer);
1926
+ $(elem).unbind('.placeholderremove');
1927
+ }
1928
+ })
1929
+ ;
1930
+ return;
1931
+ }
1932
+ elem.value = value;
1933
+ } else if(!value && _onFocus){
1934
+ $(elem)
1935
+ .off('.placeholderremove')
1936
+ .on({
1937
+ 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
1938
+ if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1939
+ data.box.removeClass('placeholder-visible');
1940
+ $(elem).unbind('.placeholderremove');
1941
+ },
1942
+ 'blur.placeholderremove': function(){
1943
+ $(elem).unbind('.placeholderremove');
1944
+ }
1945
+ })
1946
+ ;
1947
+ return;
1948
+ }
1949
+ data.box.removeClass('placeholder-visible');
1950
+ },
1951
+ showPlaceholder = function(elem, data, placeholderTxt){
1952
+ if(placeholderTxt === false){
1953
+ placeholderTxt = $.prop(elem, 'placeholder');
1954
+ }
1955
+
1956
+ if(!isOver && elem.type != 'password'){
1957
+ elem.value = placeholderTxt;
1958
+ }
1959
+ data.box.addClass('placeholder-visible');
1960
+ },
1961
+ changePlaceholderVisibility = function(elem, value, placeholderTxt, data, type){
1962
+ if(!data){
1963
+ data = $.data(elem, 'placeHolder');
1964
+ if(!data){return;}
1965
+ }
1966
+ $(elem).unbind('.placeholderremove');
1967
+ if(type == 'focus' || (!type && $(elem).is(':focus'))){
1968
+ if(elem.type == 'password' || isOver || $(elem).hasClass('placeholder-visible')){
1969
+ hidePlaceholder(elem, data, '', true);
1970
+ }
1971
+ return;
1972
+ }
1973
+ if(value === false){
1974
+ value = $.prop(elem, 'value');
1975
+ }
1976
+ if(value){
1977
+ hidePlaceholder(elem, data, value);
1978
+ return;
1979
+ }
1980
+ if(placeholderTxt === false){
1981
+ placeholderTxt = $.attr(elem, 'placeholder') || '';
1982
+ }
1983
+ if(placeholderTxt && !value){
1984
+ showPlaceholder(elem, data, placeholderTxt);
1985
+ } else {
1986
+ hidePlaceholder(elem, data, value);
1987
+ }
1988
+ },
1989
+ createPlaceholder = function(elem){
1990
+ elem = $(elem);
1991
+ var id = elem.prop('id'),
1992
+ hasLabel = !!(elem.prop('title') || elem.attr('aria-labelledby'))
1993
+ ;
1994
+ if(!hasLabel && id){
1995
+ hasLabel = !!( $('label[for="'+ id +'"]', elem[0].form)[0] );
1996
+ }
1997
+ if(!hasLabel){
1998
+ if(!id){
1999
+ id = $.webshims.getID(elem);
2000
+ }
2001
+ hasLabel = !!($('label #'+ id)[0]);
2002
+ }
2003
+ return $( hasLabel ? '<span class="placeholder-text"></span>' : '<label for="'+ id +'" class="placeholder-text"></label>');
2004
+ },
2005
+ pHolder = (function(){
2006
+ var delReg = /\n|\r|\f|\t/g,
2007
+ allowedPlaceholder = {
2008
+ text: 1,
2009
+ search: 1,
2010
+ url: 1,
2011
+ email: 1,
2012
+ password: 1,
2013
+ tel: 1
2014
+ }
2015
+ ;
2016
+
2017
+ return {
2018
+ create: function(elem){
2019
+ var data = $.data(elem, 'placeHolder');
2020
+ var form;
2021
+ var responsiveElem;
2022
+ if(data){return data;}
2023
+ data = $.data(elem, 'placeHolder', {});
2024
+
2025
+ $(elem).on('focus.placeholder blur.placeholder', function(e){
2026
+ changePlaceholderVisibility(this, false, false, data, e.type );
2027
+ data.box[e.type == 'focus' ? 'addClass' : 'removeClass']('placeholder-focused');
2028
+ });
2029
+
2030
+ if((form = $.prop(elem, 'form'))){
2031
+ $(form).on('reset.placeholder', function(e){
2032
+ setTimeout(function(){
2033
+ changePlaceholderVisibility(elem, false, false, data, e.type );
2034
+ }, 0);
2035
+ });
2036
+ }
2037
+
2038
+ if(elem.type == 'password' || isOver){
2039
+ data.text = createPlaceholder(elem);
2040
+ if(isResponsive || $(elem).is('.responsive-width') || (elem.currentStyle || {width: ''}).width.indexOf('%') != -1){
2041
+ responsiveElem = true;
2042
+ data.box = data.text;
2043
+ } else {
2044
+ data.box = $(elem)
2045
+ .wrap('<span class="placeholder-box placeholder-box-'+ (elem.nodeName || '').toLowerCase() +' placeholder-box-'+$.css(elem, 'float')+'" />')
2046
+ .parent()
2047
+ ;
2048
+ }
2049
+ data.text
2050
+ .insertAfter(elem)
2051
+ .on('mousedown.placeholder', function(){
2052
+ changePlaceholderVisibility(this, false, false, data, 'focus');
2053
+ try {
2054
+ setTimeout(function(){
2055
+ elem.focus();
2056
+ }, 0);
2057
+ } catch(e){}
2058
+ return false;
2059
+ })
2060
+ ;
2061
+
2062
+
2063
+ $.each(['lineHeight', 'fontSize', 'fontFamily', 'fontWeight'], function(i, style){
2064
+ var prop = $.css(elem, style);
2065
+ if(data.text.css(style) != prop){
2066
+ data.text.css(style, prop);
2067
+ }
2068
+ });
2069
+ $.each(['Left', 'Top'], function(i, side){
2070
+ var size = (parseInt($.css(elem, 'padding'+ side), 10) || 0) + Math.max((parseInt($.css(elem, 'margin'+ side), 10) || 0), 0) + (parseInt($.css(elem, 'border'+ side +'Width'), 10) || 0);
2071
+ data.text.css('padding'+ side, size);
2072
+ });
2073
+
2074
+ $(elem)
2075
+ .on('updateshadowdom', function(){
2076
+ var height, width;
2077
+ if((width = elem.offsetWidth) || (height = elem.offsetHeight)){
2078
+ data.text
2079
+ .css({
2080
+ width: width,
2081
+ height: height
2082
+ })
2083
+ .css($(elem).position())
2084
+ ;
2085
+ }
2086
+ })
2087
+ .triggerHandler('updateshadowdom')
2088
+ ;
2089
+
2090
+ } else {
2091
+ var reset = function(e){
2092
+ if($(elem).hasClass('placeholder-visible')){
2093
+ hidePlaceholder(elem, data, '');
2094
+ if(e && e.type == 'submit'){
2095
+ setTimeout(function(){
2096
+ if(e.isDefaultPrevented()){
2097
+ changePlaceholderVisibility(elem, false, false, data );
2098
+ }
2099
+ }, 9);
2100
+ }
2101
+ }
2102
+ };
2103
+
2104
+ $(window).on('beforeunload', reset);
2105
+ data.box = $(elem);
2106
+ if(form){
2107
+ $(form).submit(reset);
2108
+ }
2109
+ }
2110
+
2111
+ return data;
2112
+ },
2113
+ update: function(elem, val){
2114
+ var type = ($.attr(elem, 'type') || $.prop(elem, 'type') || '').toLowerCase();
2115
+ if(!allowedPlaceholder[type] && !$.nodeName(elem, 'textarea')){
2116
+ webshims.error('placeholder not allowed on input[type="'+type+'"]');
2117
+ if(type == 'date'){
2118
+ webshims.error('but you can use data-placeholder for input[type="date"]');
2119
+ }
2120
+ return;
2121
+ }
2122
+
2123
+
2124
+ var data = pHolder.create(elem);
2125
+ if(data.text){
2126
+ data.text.text(val);
2127
+ }
2128
+
2129
+ changePlaceholderVisibility(elem, false, val, data);
2130
+ }
2131
+ };
2132
+ })()
2133
+ ;
2134
+
2135
+ $.webshims.publicMethods = {
2136
+ pHolder: pHolder
2137
+ };
2138
+ polyfillElements.forEach(function(nodeName){
2139
+ var desc = webshims.defineNodeNameProperty(nodeName, 'placeholder', {
2140
+ attr: {
2141
+ set: function(val){
2142
+ var elem = this;
2143
+ if(bustedTextarea){
2144
+ webshims.data(elem, 'textareaPlaceholder', val);
2145
+ elem.placeholder = '';
2146
+ } else {
2147
+ webshims.contentAttr(elem, 'placeholder', val);
2148
+ }
2149
+ pHolder.update(elem, val);
2150
+ },
2151
+ get: function(){
2152
+ var ret = (bustedTextarea) ? webshims.data(this, 'textareaPlaceholder') : '';
2153
+ return ret || webshims.contentAttr(this, 'placeholder');
2154
+ }
2155
+ },
2156
+ reflect: true,
2157
+ initAttr: true
2158
+ });
2159
+ });
2160
+
2161
+
2162
+ polyfillElements.forEach(function(name){
2163
+ var placeholderValueDesc = {};
2164
+ var desc;
2165
+ ['attr', 'prop'].forEach(function(propType){
2166
+ placeholderValueDesc[propType] = {
2167
+ set: function(val){
2168
+ var elem = this;
2169
+ var placeholder;
2170
+ if(bustedTextarea){
2171
+ placeholder = webshims.data(elem, 'textareaPlaceholder');
2172
+ }
2173
+ if(!placeholder){
2174
+ placeholder = webshims.contentAttr(elem, 'placeholder');
2175
+ }
2176
+ $.removeData(elem, 'cachedValidity');
2177
+ var ret = desc[propType]._supset.call(elem, val);
2178
+ if(placeholder && 'value' in elem){
2179
+ changePlaceholderVisibility(elem, val, placeholder);
2180
+ }
2181
+ return ret;
2182
+ },
2183
+ get: function(){
2184
+ var elem = this;
2185
+ return $(elem).hasClass('placeholder-visible') ? '' : desc[propType]._supget.call(elem);
2186
+ }
2187
+ };
2188
+ });
2189
+ desc = webshims.defineNodeNameProperty(name, 'value', placeholderValueDesc);
2190
+ });
2191
+
2192
+ })();
2193
+
2194
+ (function(){
2195
+ var doc = document;
2196
+ if( 'value' in document.createElement('output') ){return;}
2197
+
2198
+ webshims.defineNodeNameProperty('output', 'value', {
2199
+ prop: {
2200
+ set: function(value){
2201
+ var setVal = $.data(this, 'outputShim');
2202
+ if(!setVal){
2203
+ setVal = outputCreate(this);
2204
+ }
2205
+ setVal(value);
2206
+ },
2207
+ get: function(){
2208
+ return webshims.contentAttr(this, 'value') || $(this).text() || '';
2209
+ }
2210
+ }
2211
+ });
2212
+
2213
+
2214
+ webshims.onNodeNamesPropertyModify('input', 'value', function(value, boolVal, type){
2215
+ if(type == 'removeAttr'){return;}
2216
+ var setVal = $.data(this, 'outputShim');
2217
+ if(setVal){
2218
+ setVal(value);
2219
+ }
2220
+ });
2221
+
2222
+ var outputCreate = function(elem){
2223
+ if(elem.getAttribute('aria-live')){return;}
2224
+ elem = $(elem);
2225
+ var value = (elem.text() || '').trim();
2226
+ var id = elem.attr('id');
2227
+ var htmlFor = elem.attr('for');
2228
+ var shim = $('<input class="output-shim" type="text" disabled name="'+ (elem.attr('name') || '')+'" value="'+value+'" style="display: none !important;" />').insertAfter(elem);
2229
+ var form = shim[0].form || doc;
2230
+ var setValue = function(val){
2231
+ shim[0].value = val;
2232
+ val = shim[0].value;
2233
+ elem.text(val);
2234
+ webshims.contentAttr(elem[0], 'value', val);
2235
+ };
2236
+
2237
+ elem[0].defaultValue = value;
2238
+ webshims.contentAttr(elem[0], 'value', value);
2239
+
2240
+ elem.attr({'aria-live': 'polite'});
2241
+ if(id){
2242
+ shim.attr('id', id);
2243
+ elem.attr('aria-labelledby', webshims.getID($('label[for="'+id+'"]', form)));
2244
+ }
2245
+ if(htmlFor){
2246
+ id = webshims.getID(elem);
2247
+ htmlFor.split(' ').forEach(function(control){
2248
+ control = document.getElementById(control);
2249
+ if(control){
2250
+ control.setAttribute('aria-controls', id);
2251
+ }
2252
+ });
2253
+ }
2254
+ elem.data('outputShim', setValue );
2255
+ shim.data('outputShim', setValue );
2256
+ return setValue;
2257
+ };
2258
+
2259
+ webshims.addReady(function(context, contextElem){
2260
+ $('output', context).add(contextElem.filter('output')).each(function(){
2261
+ outputCreate(this);
2262
+ });
2263
+ });
2264
+
2265
+ /*
2266
+ * Implements input event in all browsers
2267
+ */
2268
+ (function(){
2269
+ var noInputTriggerEvts = {updateInput: 1, input: 1},
2270
+ noInputTypes = {
2271
+ radio: 1,
2272
+ checkbox: 1,
2273
+ submit: 1,
2274
+ button: 1,
2275
+ image: 1,
2276
+ reset: 1,
2277
+ file: 1
2278
+
2279
+ //pro forma
2280
+ ,color: 1
2281
+ //,range: 1
2282
+ },
2283
+ observe = function(input){
2284
+ var timer,
2285
+ lastVal = input.prop('value'),
2286
+ trigger = function(e){
2287
+ //input === null
2288
+ if(!input){return;}
2289
+ var newVal = input.prop('value');
2290
+
2291
+ if(newVal !== lastVal){
2292
+ lastVal = newVal;
2293
+ if(!e || !noInputTriggerEvts[e.type]){
2294
+ webshims.triggerInlineForm && webshims.triggerInlineForm(input[0], 'input');
2295
+ }
2296
+ }
2297
+ },
2298
+ extraTimer,
2299
+ extraTest = function(){
2300
+ clearTimeout(extraTimer);
2301
+ extraTimer = setTimeout(trigger, 9);
2302
+ },
2303
+ unbind = function(){
2304
+ input.unbind('focusout', unbind).unbind('keyup keypress keydown paste cut', extraTest).unbind('input change updateInput', trigger);
2305
+ clearInterval(timer);
2306
+ setTimeout(function(){
2307
+ trigger();
2308
+ input = null;
2309
+ }, 1);
2310
+
2311
+ }
2312
+ ;
2313
+
2314
+ clearInterval(timer);
2315
+ timer = setInterval(trigger, 99);
2316
+ extraTest();
2317
+ input.on({
2318
+ 'keyup keypress keydown paste cut': extraTest,
2319
+ focusout: unbind,
2320
+ 'input updateInput change': trigger
2321
+ });
2322
+ }
2323
+ ;
2324
+ if($.event.customEvent){
2325
+ $.event.customEvent.updateInput = true;
2326
+ }
2327
+
2328
+ $(doc)
2329
+ .on('focusin', function(e){
2330
+ if( e.target && e.target.type && !e.target.readOnly && !e.target.disabled && (e.target.nodeName || '').toLowerCase() == 'input' && !noInputTypes[e.target.type] ){
2331
+ observe($(e.target));
2332
+ }
2333
+ })
2334
+ ;
2335
+ })();
2336
+ })();
2337
+
2338
+ }); //webshims.ready end
2339
+ }//end formvalidation