webshims-rails 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/lib/webshims-rails/version.rb +2 -2
  2. data/vendor/assets/javascripts/webshims/extras/custom-validity.js +253 -253
  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/polyfiller.js +1 -1
  6. data/vendor/assets/javascripts/webshims/minified/shims/combos/10.js +1 -1
  7. data/vendor/assets/javascripts/webshims/minified/shims/combos/12.js +1 -1
  8. data/vendor/assets/javascripts/webshims/minified/shims/combos/16.js +1 -1
  9. data/vendor/assets/javascripts/webshims/minified/shims/combos/17.js +1 -1
  10. data/vendor/assets/javascripts/webshims/minified/shims/combos/19.js +1 -1
  11. data/vendor/assets/javascripts/webshims/minified/shims/combos/2.js +1 -1
  12. data/vendor/assets/javascripts/webshims/minified/shims/combos/20.js +1 -1
  13. data/vendor/assets/javascripts/webshims/minified/shims/combos/21.js +1 -1
  14. data/vendor/assets/javascripts/webshims/minified/shims/combos/22.js +1 -1
  15. data/vendor/assets/javascripts/webshims/minified/shims/combos/23.js +1 -1
  16. data/vendor/assets/javascripts/webshims/minified/shims/combos/24.js +1 -1
  17. data/vendor/assets/javascripts/webshims/minified/shims/combos/25.js +1 -1
  18. data/vendor/assets/javascripts/webshims/minified/shims/combos/26.js +1 -1
  19. data/vendor/assets/javascripts/webshims/minified/shims/combos/27.js +1 -1
  20. data/vendor/assets/javascripts/webshims/minified/shims/combos/3.js +1 -1
  21. data/vendor/assets/javascripts/webshims/minified/shims/combos/4.js +1 -1
  22. data/vendor/assets/javascripts/webshims/minified/shims/combos/5.js +1 -1
  23. data/vendor/assets/javascripts/webshims/minified/shims/combos/59.js +1 -1
  24. data/vendor/assets/javascripts/webshims/minified/shims/combos/8.js +1 -1
  25. data/vendor/assets/javascripts/webshims/minified/shims/combos/9.js +1 -1
  26. data/vendor/assets/javascripts/webshims/minified/shims/form-core.js +1 -1
  27. data/vendor/assets/javascripts/webshims/minified/shims/form-message.js +1 -1
  28. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-de.txt +33 -33
  29. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-en.txt +34 -34
  30. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-core.js +1 -1
  31. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-jaris.js +1 -1
  32. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-swf.js +1 -1
  33. data/vendor/assets/javascripts/webshims/minified/shims/swf/JarisFLVPlayer.swf +0 -0
  34. data/vendor/assets/javascripts/webshims/polyfiller.js +1188 -1188
  35. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/README +82 -82
  36. data/vendor/assets/javascripts/webshims/shims/combos/1.js +1752 -1752
  37. data/vendor/assets/javascripts/webshims/shims/combos/10.js +3310 -3311
  38. data/vendor/assets/javascripts/webshims/shims/combos/11.js +1631 -1631
  39. data/vendor/assets/javascripts/webshims/shims/combos/12.js +1695 -1696
  40. data/vendor/assets/javascripts/webshims/shims/combos/13.js +1098 -1098
  41. data/vendor/assets/javascripts/webshims/shims/combos/14.js +477 -477
  42. data/vendor/assets/javascripts/webshims/shims/combos/15.js +317 -317
  43. data/vendor/assets/javascripts/webshims/shims/combos/16.js +2177 -2154
  44. data/vendor/assets/javascripts/webshims/shims/combos/17.js +2354 -2319
  45. data/vendor/assets/javascripts/webshims/shims/combos/18.js +1322 -1322
  46. data/vendor/assets/javascripts/webshims/shims/combos/19.js +2262 -2238
  47. data/vendor/assets/javascripts/webshims/shims/combos/2.js +2376 -2340
  48. data/vendor/assets/javascripts/webshims/shims/combos/20.js +1557 -1558
  49. data/vendor/assets/javascripts/webshims/shims/combos/21.js +1745 -1733
  50. data/vendor/assets/javascripts/webshims/shims/combos/22.js +2360 -2361
  51. data/vendor/assets/javascripts/webshims/shims/combos/23.js +2342 -2331
  52. data/vendor/assets/javascripts/webshims/shims/combos/24.js +2859 -2836
  53. data/vendor/assets/javascripts/webshims/shims/combos/25.js +1547 -1548
  54. data/vendor/assets/javascripts/webshims/shims/combos/26.js +2178 -2155
  55. data/vendor/assets/javascripts/webshims/shims/combos/27.js +3311 -3312
  56. data/vendor/assets/javascripts/webshims/shims/combos/3.js +3058 -3022
  57. data/vendor/assets/javascripts/webshims/shims/combos/4.js +807 -771
  58. data/vendor/assets/javascripts/webshims/shims/combos/5.js +1063 -1027
  59. data/vendor/assets/javascripts/webshims/shims/combos/59.js +1745 -1709
  60. data/vendor/assets/javascripts/webshims/shims/combos/6.js +384 -384
  61. data/vendor/assets/javascripts/webshims/shims/combos/7.js +640 -640
  62. data/vendor/assets/javascripts/webshims/shims/combos/8.js +1546 -1547
  63. data/vendor/assets/javascripts/webshims/shims/combos/9.js +2507 -2508
  64. data/vendor/assets/javascripts/webshims/shims/details.js +148 -148
  65. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +949 -949
  66. data/vendor/assets/javascripts/webshims/shims/es5.js +802 -802
  67. data/vendor/assets/javascripts/webshims/shims/excanvas.js +924 -924
  68. data/vendor/assets/javascripts/webshims/shims/form-core.js +630 -606
  69. data/vendor/assets/javascripts/webshims/shims/form-datalist.js +681 -681
  70. data/vendor/assets/javascripts/webshims/shims/form-message.js +176 -164
  71. data/vendor/assets/javascripts/webshims/shims/form-native-extend.js +255 -255
  72. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +383 -383
  73. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +1568 -1568
  74. data/vendor/assets/javascripts/webshims/shims/geolocation.js +168 -168
  75. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ar.js +32 -32
  76. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ch-ZN.js +32 -32
  77. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-de.txt +33 -33
  78. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-el.js +32 -32
  79. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-en.txt +34 -34
  80. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-es.js +31 -31
  81. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-fr.js +32 -32
  82. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-he.js +32 -32
  83. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-hi.js +32 -32
  84. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-hu.js +32 -32
  85. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-it.js +32 -32
  86. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ja.js +32 -32
  87. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-nl.js +32 -32
  88. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-pt-PT.js +32 -32
  89. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ru.js +31 -31
  90. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-sv.js +32 -32
  91. data/vendor/assets/javascripts/webshims/shims/json-storage.js +308 -308
  92. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +596 -597
  93. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +891 -891
  94. data/vendor/assets/javascripts/webshims/shims/mediaelement-native-fix.js +98 -98
  95. data/vendor/assets/javascripts/webshims/shims/mediaelement-swf.js +960 -960
  96. data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +543 -543
  97. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +697 -697
  98. data/vendor/assets/javascripts/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
  99. metadata +2 -4
  100. data/vendor/assets/javascripts/webshims/minified/shims/range-ui.js +0 -1
  101. data/vendor/assets/javascripts/webshims/shims/range-ui.js +0 -66
@@ -1,772 +1,808 @@
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-native-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
- });
608
- jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
609
- "use strict";
610
- var validityMessages = webshims.validityMessages;
611
-
612
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
613
-
614
- validityMessages['en'] = $.extend(true, {
615
- typeMismatch: {
616
- email: 'Please enter an email address.',
617
- url: 'Please enter a URL.',
618
- number: 'Please enter a number.',
619
- date: 'Please enter a date.',
620
- time: 'Please enter a time.',
621
- range: 'Invalid input.',
622
- "datetime-local": 'Please enter a datetime.'
623
- },
624
- rangeUnderflow: {
625
- defaultMessage: 'Value must be greater than or equal to {%min}.'
626
- },
627
- rangeOverflow: {
628
- defaultMessage: 'Value must be less than or equal to {%max}.'
629
- },
630
- stepMismatch: 'Invalid input.',
631
- tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
632
-
633
- patternMismatch: 'Invalid input. {%title}',
634
- valueMissing: {
635
- defaultMessage: 'Please fill out this field.',
636
- checkbox: 'Please check this box if you want to proceed.'
637
- }
638
- }, (validityMessages['en'] || validityMessages['en-US'] || {}));
639
-
640
-
641
- ['select', 'radio'].forEach(function(type){
642
- validityMessages['en'].valueMissing[type] = 'Please select an option.';
643
- });
644
-
645
- ['date', 'time', 'datetime-local'].forEach(function(type){
646
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
647
- });
648
- ['date', 'time', 'datetime-local'].forEach(function(type){
649
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
650
- });
651
-
652
- validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
653
- validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
654
-
655
- validityMessages['de'] = $.extend(true, {
656
- typeMismatch: {
657
- email: '{%value} ist keine zulässige E-Mail-Adresse',
658
- url: '{%value} ist keine zulässige Webadresse',
659
- number: '{%value} ist keine Nummer!',
660
- date: '{%value} ist kein Datum',
661
- time: '{%value} ist keine Uhrzeit',
662
- range: '{%value} ist keine Nummer!',
663
- "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
664
- },
665
- rangeUnderflow: {
666
- defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
667
- },
668
- rangeOverflow: {
669
- defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
670
- },
671
- stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
672
- tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
673
- patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
674
- valueMissing: {
675
- defaultMessage: 'Bitte geben Sie einen Wert ein',
676
- checkbox: 'Bitte aktivieren Sie das Kästchen'
677
- }
678
- }, (validityMessages['de'] || {}));
679
-
680
- ['select', 'radio'].forEach(function(type){
681
- validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
682
- });
683
-
684
- ['date', 'time', 'datetime-local'].forEach(function(type){
685
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
686
- });
687
- ['date', 'time', 'datetime-local'].forEach(function(type){
688
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
689
- });
690
-
691
- var currentValidationMessage = validityMessages[''];
692
-
693
-
694
- webshims.createValidationMessage = function(elem, name){
695
- var message = currentValidationMessage[name];
696
- if(message && typeof message !== 'string'){
697
- message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
698
- }
699
- if(message){
700
- ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
701
- if(message.indexOf('{%'+attr) === -1){return;}
702
- var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
703
- if(name == 'patternMismatch' && attr == 'title' && !val){
704
- webshims.error('no title for patternMismatch provided. Always add a title attribute.');
705
- }
706
- message = message.replace('{%'+ attr +'}', val);
707
- if('value' == attr){
708
- message = message.replace('{%valueLen}', val.length);
709
- }
710
- });
711
- }
712
- return message || '';
713
- };
714
-
715
-
716
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
717
- implementProperties.push('validationMessage');
718
- }
719
-
720
- webshims.activeLang({
721
- langObj: validityMessages,
722
- module: 'form-core',
723
- callback: function(langObj){
724
- currentValidationMessage = langObj;
725
- }
726
- });
727
-
728
- implementProperties.forEach(function(messageProp){
729
- webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
730
- prop: {
731
- value: '',
732
- writeable: false
733
- }
734
- });
735
- ['input', 'select', 'textarea'].forEach(function(nodeName){
736
- var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
737
- prop: {
738
- get: function(){
739
- var elem = this;
740
- var message = '';
741
- if(!$.prop(elem, 'willValidate')){
742
- return message;
743
- }
744
-
745
- var validity = $.prop(elem, 'validity') || {valid: 1};
746
-
747
- if(validity.valid){return message;}
748
- message = webshims.getContentValidationMessage(elem, validity);
749
-
750
- if(message){return message;}
751
-
752
- if(validity.customError && elem.nodeName){
753
- message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
754
- if(message){return message;}
755
- }
756
- $.each(validity, function(name, prop){
757
- if(name == 'valid' || !prop){return;}
758
-
759
- message = webshims.createValidationMessage(elem, name);
760
- if(message){
761
- return false;
762
- }
763
- });
764
- return message || '';
765
- },
766
- writeable: false
767
- }
768
- });
769
- });
770
-
771
- });
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-native-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
+ }
119
+ })(jQuery);
120
+
121
+ jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
122
+ "use strict";
123
+
124
+
125
+ var checkTypes = {checkbox: 1, radio: 1};
126
+ var emptyJ = $([]);
127
+ var bugs = webshims.bugs;
128
+ var groupTypes = {radio: 1};
129
+ var getGroupElements = function(elem){
130
+ elem = $(elem);
131
+ var name;
132
+ var form;
133
+ var ret = emptyJ;
134
+ if(groupTypes[elem[0].type]){
135
+ form = elem.prop('form');
136
+ name = elem[0].name;
137
+ if(!name){
138
+ ret = elem;
139
+ } else if(form){
140
+ ret = $(form[name]);
141
+ } else {
142
+ ret = $(document.getElementsByName(name)).filter(function(){
143
+ return !$.prop(this, 'form');
144
+ });
145
+ }
146
+ ret = ret.filter('[type="radio"]');
147
+ }
148
+ return ret;
149
+ };
150
+
151
+ var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
152
+ var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
153
+ if(key && message[key]){
154
+ message = message[key];
155
+ }
156
+ if(typeof message == 'object'){
157
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
158
+ if(!validity.valid){
159
+ $.each(validity, function(name, prop){
160
+ if(prop && name != 'valid' && message[name]){
161
+ message = message[name];
162
+ return false;
163
+ }
164
+ });
165
+ }
166
+ }
167
+
168
+ if(typeof message == 'object'){
169
+ message = message.defaultMessage;
170
+ }
171
+ return message || '';
172
+ };
173
+
174
+ /*
175
+ * Selectors for all browsers
176
+ */
177
+ var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
178
+ var hasInvalid = function(elem){
179
+ var ret = false;
180
+ $($.prop(elem, 'elements')).each(function(){
181
+ ret = $(this).is(':invalid');
182
+ if(ret){
183
+ return false;
184
+ }
185
+ });
186
+ return ret;
187
+ };
188
+ $.extend($.expr[":"], {
189
+ "valid-element": function(elem){
190
+ return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
191
+ },
192
+ "invalid-element": function(elem){
193
+ return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
194
+ },
195
+ "required-element": function(elem){
196
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
197
+ },
198
+ "user-error": function(elem){
199
+ return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
200
+ },
201
+ "optional-element": function(elem){
202
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
203
+ },
204
+ "in-range": function(elem){
205
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
206
+ return false;
207
+ }
208
+ var val = $.prop(elem, 'validity');
209
+ return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
210
+ },
211
+ "out-of-range": function(elem){
212
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
213
+ return false;
214
+ }
215
+ var val = $.prop(elem, 'validity');
216
+ return !!(val && (val.rangeOverflow || val.rangeUnderflow));
217
+ }
218
+
219
+ });
220
+
221
+ ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
222
+ $.expr[":"][name] = $.expr.filters[name+"-element"];
223
+ });
224
+
225
+
226
+ $.expr[":"].focus = function( elem ) {
227
+ try {
228
+ var doc = elem.ownerDocument;
229
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
230
+ } catch(e){}
231
+ return false;
232
+ };
233
+
234
+ if(Modernizr.formvalidation && $.browser.webkit && !webshims.bugs.bustedValidity && webshims.browserVersion < 27){
235
+ (function(){
236
+ var retriggerRadioValidity = function(){
237
+ var validity;
238
+ if((validity = this.validity) && !validity.customError){
239
+ this.setCustomValidity('');
240
+ }
241
+ };
242
+
243
+ webshims.addReady(function(context, insertedElement){
244
+ if(context !== document){
245
+ $('input[type="radio"]:invalid', context)
246
+ .add(insertedElement.filter('input[type="radio"]:invalid'))
247
+ .each(retriggerRadioValidity)
248
+ ;
249
+ }
250
+ });
251
+ })();
252
+ }
253
+
254
+ var customEvents = $.event.customEvent || {};
255
+ var isValid = function(elem){
256
+ return ($.prop(elem, 'validity') || {valid: 1}).valid;
257
+ };
258
+
259
+ if (bugs.bustedValidity || bugs.findRequired) {
260
+ (function(){
261
+ var find = $.find;
262
+ var matchesSelector = $.find.matchesSelector;
263
+
264
+ var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
265
+ var regFn = function(sel){
266
+ return sel + '-element';
267
+ };
268
+
269
+ $.find = (function(){
270
+ var slice = Array.prototype.slice;
271
+ var fn = function(sel){
272
+ var ar = arguments;
273
+ ar = slice.call(ar, 1, ar.length);
274
+ ar.unshift(sel.replace(regExp, regFn));
275
+ return find.apply(this, ar);
276
+ };
277
+ for (var i in find) {
278
+ if(find.hasOwnProperty(i)){
279
+ fn[i] = find[i];
280
+ }
281
+ }
282
+ return fn;
283
+ })();
284
+ if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
285
+ $.find.matchesSelector = function(node, expr){
286
+ expr = expr.replace(regExp, regFn);
287
+ return matchesSelector.call(this, node, expr);
288
+ };
289
+ }
290
+
291
+ })();
292
+ }
293
+
294
+ //ToDo needs testing
295
+ var oldAttr = $.prop;
296
+ var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
297
+ $.prop = function(elem, name, val){
298
+ var ret = oldAttr.apply(this, arguments);
299
+ if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
300
+ if(isValid(elem)){
301
+ $(elem).getShadowElement().removeClass(invalidClasses);
302
+ if(name == 'checked' && val) {
303
+ getGroupElements(elem).not(elem).removeClass(invalidClasses).removeAttr('aria-invalid');
304
+ }
305
+ }
306
+ }
307
+ return ret;
308
+ };
309
+
310
+ var returnValidityCause = function(validity, elem){
311
+ var ret;
312
+ $.each(validity, function(name, value){
313
+ if(value){
314
+ ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
315
+ return false;
316
+ }
317
+ });
318
+ return ret;
319
+ };
320
+
321
+ var isInGroup = function(name){
322
+ var ret;
323
+ try {
324
+ ret = document.activeElement.name === name;
325
+ } catch(e){}
326
+ return ret;
327
+ };
328
+ /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-success instead */
329
+ var invalidClass = 'user-error';
330
+ var invalidClasses = 'user-error form-ui-invalid';
331
+ var validClass = 'user-success';
332
+ var validClasses = 'user-success form-ui-valid';
333
+ var switchValidityClass = function(e){
334
+ var elem, timer;
335
+ if(!e.target){return;}
336
+ elem = $(e.target).getNativeElement()[0];
337
+ if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
338
+ timer = $.data(elem, 'webshimsswitchvalidityclass');
339
+ var switchClass = function(){
340
+ if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
341
+ var validity = $.prop(elem, 'validity');
342
+ var shadowElem = $(elem).getShadowElement();
343
+ var addClass, removeClass, trigger, generaltrigger, validityCause;
344
+
345
+ $(elem).trigger('refreshCustomValidityRules');
346
+ if(validity.valid){
347
+ if(!shadowElem.hasClass(validClass)){
348
+ addClass = validClasses;
349
+ removeClass = invalidClasses;
350
+ generaltrigger = 'changedvaliditystate';
351
+ trigger = 'changedvalid';
352
+ if(checkTypes[elem.type] && elem.checked){
353
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
354
+ }
355
+ $.removeData(elem, 'webshimsinvalidcause');
356
+ }
357
+ } else {
358
+ validityCause = returnValidityCause(validity, elem);
359
+ if($.data(elem, 'webshimsinvalidcause') != validityCause){
360
+ $.data(elem, 'webshimsinvalidcause', validityCause);
361
+ generaltrigger = 'changedvaliditystate';
362
+ }
363
+ if(!shadowElem.hasClass(invalidClass)){
364
+ addClass = invalidClasses;
365
+ removeClass = validClasses;
366
+ if (checkTypes[elem.type] && !elem.checked) {
367
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
368
+ }
369
+ trigger = 'changedinvalid';
370
+ }
371
+ }
372
+ if(addClass){
373
+ shadowElem.addClass(addClass).removeClass(removeClass);
374
+ //jQuery 1.6.1 IE9 bug (doubble trigger bug)
375
+ setTimeout(function(){
376
+ $(elem).trigger(trigger);
377
+ }, 0);
378
+ }
379
+ if(generaltrigger){
380
+ setTimeout(function(){
381
+ $(elem).trigger(generaltrigger);
382
+ }, 0);
383
+ }
384
+ $.removeData(e.target, 'webshimsswitchvalidityclass');
385
+ };
386
+
387
+ if(timer){
388
+ clearTimeout(timer);
389
+ }
390
+ if(e.type == 'refreshvalidityui'){
391
+ switchClass();
392
+ } else {
393
+ $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
394
+ }
395
+ };
396
+
397
+ $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
398
+ customEvents.changedvaliditystate = true;
399
+ customEvents.refreshCustomValidityRules = true;
400
+ customEvents.changedvalid = true;
401
+ customEvents.changedinvalid = true;
402
+ customEvents.refreshvalidityui = true;
403
+
404
+
405
+ webshims.triggerInlineForm = function(elem, event){
406
+ $(elem).trigger(event);
407
+ };
408
+
409
+ webshims.modules["form-core"].getGroupElements = getGroupElements;
410
+
411
+
412
+ var setRoot = function(){
413
+ webshims.scrollRoot = ($.browser.webkit || document.compatMode == 'BackCompat') ?
414
+ $(document.body) :
415
+ $(document.documentElement)
416
+ ;
417
+ };
418
+ setRoot();
419
+ webshims.ready('DOM', setRoot);
420
+
421
+ webshims.getRelOffset = function(posElem, relElem){
422
+ posElem = $(posElem);
423
+ var offset = $(relElem).offset();
424
+ var bodyOffset;
425
+ $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
426
+ bodyOffset = posElem.offset();
427
+ });
428
+ offset.top -= bodyOffset.top;
429
+ offset.left -= bodyOffset.left;
430
+ return offset;
431
+ };
432
+
433
+ /* some extra validation UI */
434
+ webshims.validityAlert = (function(){
435
+ var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label';
436
+ var errorBubble;
437
+ var hideTimer = false;
438
+ var focusTimer = false;
439
+ var resizeTimer = false;
440
+ var boundHide;
441
+
442
+ var api = {
443
+ hideDelay: 5000,
444
+
445
+ showFor: function(elem, message, noFocusElem, noBubble){
446
+ api._create();
447
+ elem = $(elem);
448
+ var visual = $(elem).getShadowElement();
449
+ var offset = api.getOffsetFromBody(visual);
450
+ api.clear();
451
+ if(noBubble){
452
+ this.hide();
453
+ } else {
454
+
455
+ this.getMessage(elem, message);
456
+ this.position(visual, offset);
457
+
458
+ this.show();
459
+ if(this.hideDelay){
460
+ hideTimer = setTimeout(boundHide, this.hideDelay);
461
+ }
462
+ $(window)
463
+ .on('resize.validityalert reposoverlay.validityalert', function(){
464
+ clearTimeout(resizeTimer);
465
+ resizeTimer = setTimeout(function(){
466
+ api.position(visual);
467
+ }, 9);
468
+ })
469
+ ;
470
+ }
471
+
472
+ if(!noFocusElem){
473
+ this.setFocus(visual, offset);
474
+ }
475
+ },
476
+ getOffsetFromBody: function(elem){
477
+ return webshims.getRelOffset(errorBubble, elem);
478
+ },
479
+ setFocus: function(visual, offset){
480
+ var focusElem = $(visual).getShadowFocusElement();
481
+ var scrollTop = webshims.scrollRoot.scrollTop();
482
+ var elemTop = ((offset || focusElem.offset()).top) - 30;
483
+ var smooth;
484
+
485
+ if(webshims.getID && alertElem == 'label'){
486
+ errorBubble.attr('for', webshims.getID(focusElem));
487
+ }
488
+
489
+ if(scrollTop > elemTop){
490
+ webshims.scrollRoot.animate(
491
+ {scrollTop: elemTop - 5},
492
+ {
493
+ queue: false,
494
+ duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
495
+ }
496
+ );
497
+ smooth = true;
498
+ }
499
+ try {
500
+ focusElem[0].focus();
501
+ } catch(e){}
502
+ if(smooth){
503
+ webshims.scrollRoot.scrollTop(scrollTop);
504
+ setTimeout(function(){
505
+ webshims.scrollRoot.scrollTop(scrollTop);
506
+ }, 0);
507
+ }
508
+ setTimeout(function(){
509
+ $(document).on('focusout.validityalert', boundHide);
510
+ }, 10);
511
+ $(window).triggerHandler('reposoverlay');
512
+ },
513
+ getMessage: function(elem, message){
514
+ if (!message) {
515
+ message = getContentValidationMessage(elem[0]) || elem.prop('customValidationMessage') || elem.prop('validationMessage');
516
+ }
517
+ if (message) {
518
+ $('span.va-box', errorBubble).text(message);
519
+ }
520
+ else {
521
+ this.hide();
522
+ }
523
+ },
524
+ position: function(elem, offset){
525
+ offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
526
+ offset.top += elem.outerHeight();
527
+ errorBubble.css(offset);
528
+ },
529
+ show: function(){
530
+ if(errorBubble.css('display') === 'none'){
531
+ errorBubble.css({opacity: 0}).show();
532
+ }
533
+ errorBubble.addClass('va-visible').fadeTo(400, 1);
534
+ },
535
+ hide: function(){
536
+ errorBubble.removeClass('va-visible').fadeOut();
537
+ },
538
+ clear: function(){
539
+ clearTimeout(focusTimer);
540
+ clearTimeout(hideTimer);
541
+ $(document).unbind('.validityalert');
542
+ $(window).unbind('.validityalert');
543
+ errorBubble.stop().removeAttr('for');
544
+ },
545
+ _create: function(){
546
+ if(errorBubble){return;}
547
+ 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'});
548
+ webshims.ready('DOM', function(){
549
+ errorBubble.appendTo('body');
550
+ if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){
551
+ errorBubble.bgIframe();
552
+ }
553
+ });
554
+ }
555
+ };
556
+
557
+
558
+ boundHide = $.proxy(api, 'hide');
559
+
560
+ return api;
561
+ })();
562
+
563
+
564
+ /* extension, but also used to fix native implementation workaround/bugfixes */
565
+ (function(){
566
+ var firstEvent,
567
+ invalids = [],
568
+ stopSubmitTimer,
569
+ form
570
+ ;
571
+
572
+ $(document).on('invalid', function(e){
573
+ if(e.wrongWebkitInvalid){return;}
574
+ var jElm = $(e.target);
575
+ var shadowElem = jElm.getShadowElement();
576
+ if(!shadowElem.hasClass(invalidClass)){
577
+ shadowElem.addClass(invalidClasses).removeClass(validClasses);
578
+ setTimeout(function(){
579
+ $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
580
+ }, 0);
581
+ }
582
+
583
+ if(!firstEvent){
584
+ //trigger firstinvalid
585
+ firstEvent = $.Event('firstinvalid');
586
+ firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
587
+ var firstSystemInvalid = $.Event('firstinvalidsystem');
588
+ $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
589
+ jElm.trigger(firstEvent);
590
+ }
591
+
592
+ //if firstinvalid was prevented all invalids will be also prevented
593
+ if( firstEvent && firstEvent.isDefaultPrevented() ){
594
+ e.preventDefault();
595
+ }
596
+ invalids.push(e.target);
597
+ e.extraData = 'fix';
598
+ clearTimeout(stopSubmitTimer);
599
+ stopSubmitTimer = setTimeout(function(){
600
+ var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
601
+ //reset firstinvalid
602
+ firstEvent = false;
603
+ invalids = [];
604
+ $(e.target).trigger(lastEvent, lastEvent);
605
+ }, 9);
606
+ jElm = null;
607
+ shadowElem = null;
608
+ });
609
+ })();
610
+
611
+ $.fn.getErrorMessage = function(){
612
+ var message = '';
613
+ var elem = this[0];
614
+ if(elem){
615
+ message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
616
+ }
617
+ return message;
618
+ };
619
+
620
+ if(options.replaceValidationUI){
621
+ webshims.ready('DOM forms', function(){
622
+ $(document).on('firstinvalid', function(e){
623
+ if(!e.isInvalidUIPrevented()){
624
+ e.preventDefault();
625
+ $.webshims.validityAlert.showFor( e.target );
626
+ }
627
+ });
628
+ });
629
+ }
630
+
631
+ });
632
+ jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
633
+ "use strict";
634
+ var validityMessages = webshims.validityMessages;
635
+
636
+ var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
637
+
638
+ validityMessages['en'] = $.extend(true, {
639
+ typeMismatch: {
640
+ email: 'Please enter an email address.',
641
+ url: 'Please enter a URL.',
642
+ number: 'Please enter a number.',
643
+ date: 'Please enter a date.',
644
+ time: 'Please enter a time.',
645
+ range: 'Invalid input.',
646
+ "datetime-local": 'Please enter a datetime.'
647
+ },
648
+ rangeUnderflow: {
649
+ defaultMessage: 'Value must be greater than or equal to {%min}.'
650
+ },
651
+ rangeOverflow: {
652
+ defaultMessage: 'Value must be less than or equal to {%max}.'
653
+ },
654
+ stepMismatch: 'Invalid input.',
655
+ tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
656
+
657
+ patternMismatch: 'Invalid input. {%title}',
658
+ valueMissing: {
659
+ defaultMessage: 'Please fill out this field.',
660
+ checkbox: 'Please check this box if you want to proceed.'
661
+ }
662
+ }, (validityMessages['en'] || validityMessages['en-US'] || {}));
663
+
664
+
665
+ ['select', 'radio'].forEach(function(type){
666
+ if(typeof validityMessages['en'].valueMissing == 'object'){
667
+ validityMessages['en'].valueMissing[type] = 'Please select an option.';
668
+ }
669
+ });
670
+
671
+ ['date', 'time', 'datetime-local'].forEach(function(type){
672
+ if(typeof validityMessages['en'].rangeUnderflow == 'object'){
673
+ validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
674
+ }
675
+ });
676
+ ['date', 'time', 'datetime-local'].forEach(function(type){
677
+ if(typeof validityMessages['en'].rangeOverflow == 'object'){
678
+ validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
679
+ }
680
+ });
681
+
682
+ validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
683
+ validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
684
+
685
+ validityMessages['de'] = $.extend(true, {
686
+ typeMismatch: {
687
+ email: '{%value} ist keine zulässige E-Mail-Adresse',
688
+ url: '{%value} ist keine zulässige Webadresse',
689
+ number: '{%value} ist keine Nummer!',
690
+ date: '{%value} ist kein Datum',
691
+ time: '{%value} ist keine Uhrzeit',
692
+ range: '{%value} ist keine Nummer!',
693
+ "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
694
+ },
695
+ rangeUnderflow: {
696
+ defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
697
+ },
698
+ rangeOverflow: {
699
+ defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
700
+ },
701
+ stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
702
+ tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
703
+ patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
704
+ valueMissing: {
705
+ defaultMessage: 'Bitte geben Sie einen Wert ein',
706
+ checkbox: 'Bitte aktivieren Sie das Kästchen'
707
+ }
708
+ }, (validityMessages['de'] || {}));
709
+
710
+ ['select', 'radio'].forEach(function(type){
711
+ if(typeof validityMessages['de'].valueMissing == 'object'){
712
+ validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
713
+ }
714
+ });
715
+
716
+ ['date', 'time', 'datetime-local'].forEach(function(type){
717
+ if(typeof validityMessages['de'].rangeUnderflow == 'object'){
718
+ validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
719
+ }
720
+ });
721
+ ['date', 'time', 'datetime-local'].forEach(function(type){
722
+ if(typeof validityMessages['de'].rangeOverflow == 'object'){
723
+ validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
724
+ }
725
+ });
726
+
727
+ var currentValidationMessage = validityMessages[''];
728
+
729
+
730
+ webshims.createValidationMessage = function(elem, name){
731
+ var message = currentValidationMessage[name];
732
+ if(message && typeof message !== 'string'){
733
+ message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
734
+ }
735
+ if(message){
736
+ ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
737
+ if(message.indexOf('{%'+attr) === -1){return;}
738
+ var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
739
+ if(name == 'patternMismatch' && attr == 'title' && !val){
740
+ webshims.error('no title for patternMismatch provided. Always add a title attribute.');
741
+ }
742
+ message = message.replace('{%'+ attr +'}', val);
743
+ if('value' == attr){
744
+ message = message.replace('{%valueLen}', val.length);
745
+ }
746
+ });
747
+ }
748
+ return message || '';
749
+ };
750
+
751
+
752
+ if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
753
+ implementProperties.push('validationMessage');
754
+ }
755
+
756
+ webshims.activeLang({
757
+ langObj: validityMessages,
758
+ module: 'form-core',
759
+ callback: function(langObj){
760
+ currentValidationMessage = langObj;
761
+ }
762
+ });
763
+
764
+ implementProperties.forEach(function(messageProp){
765
+ webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
766
+ prop: {
767
+ value: '',
768
+ writeable: false
769
+ }
770
+ });
771
+ ['input', 'select', 'textarea'].forEach(function(nodeName){
772
+ var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
773
+ prop: {
774
+ get: function(){
775
+ var elem = this;
776
+ var message = '';
777
+ if(!$.prop(elem, 'willValidate')){
778
+ return message;
779
+ }
780
+
781
+ var validity = $.prop(elem, 'validity') || {valid: 1};
782
+
783
+ if(validity.valid){return message;}
784
+ message = webshims.getContentValidationMessage(elem, validity);
785
+
786
+ if(message){return message;}
787
+
788
+ if(validity.customError && elem.nodeName){
789
+ message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
790
+ if(message){return message;}
791
+ }
792
+ $.each(validity, function(name, prop){
793
+ if(name == 'valid' || !prop){return;}
794
+
795
+ message = webshims.createValidationMessage(elem, name);
796
+ if(message){
797
+ return false;
798
+ }
799
+ });
800
+ return message || '';
801
+ },
802
+ writeable: false
803
+ }
804
+ });
805
+ });
806
+
807
+ });
772
808
  });