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,1078 +1,1026 @@
1
- jQuery.webshims.register('form-extend', function($, webshims, window, doc, undefined, options){
2
- "use strict";
3
- var Modernizr = window.Modernizr;
4
- var modernizrInputTypes = Modernizr.inputtypes;
5
- if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){return;}
6
- var typeModels = webshims.inputTypes;
7
- var validityRules = {};
8
-
9
- webshims.addInputType = function(type, obj){
10
- typeModels[type] = obj;
11
- };
12
-
13
- webshims.addValidityRule = function(type, fn){
14
- validityRules[type] = fn;
15
- };
16
-
17
- webshims.addValidityRule('typeMismatch',function (input, val, cache, validityState){
18
- if(val === ''){return false;}
19
- var ret = validityState.typeMismatch;
20
- if(!('type' in cache)){
21
- cache.type = (input[0].getAttribute('type') || '').toLowerCase();
22
- }
23
-
24
- if(typeModels[cache.type] && typeModels[cache.type].mismatch){
25
- ret = typeModels[cache.type].mismatch(val, input);
26
- }
27
- return ret;
28
- });
29
-
30
- var overrideNativeMessages = options.overrideMessages;
31
-
32
- var overrideValidity = (!modernizrInputTypes.number || !modernizrInputTypes.time || !modernizrInputTypes.range || overrideNativeMessages);
33
- var validityProps = ['customError','typeMismatch','rangeUnderflow','rangeOverflow','stepMismatch','tooLong','patternMismatch','valueMissing','valid'];
34
-
35
- var validityChanger = (overrideNativeMessages)? ['value', 'checked'] : ['value'];
36
- var validityElements = [];
37
- var testValidity = function(elem, init){
38
- if(!elem){return;}
39
- var type = (elem.getAttribute && elem.getAttribute('type') || elem.type || '').toLowerCase();
40
-
41
- if(!overrideNativeMessages && !typeModels[type]){
42
- return;
43
- }
44
-
45
- if(overrideNativeMessages && !init && type == 'radio' && elem.name){
46
- $(doc.getElementsByName( elem.name )).each(function(){
47
- $.prop(this, 'validity');
48
- });
49
- } else {
50
- $.prop(elem, 'validity');
51
- }
52
- };
53
-
54
- var oldSetCustomValidity = {};
55
- ['input', 'textarea', 'select'].forEach(function(name){
56
- var desc = webshims.defineNodeNameProperty(name, 'setCustomValidity', {
57
- prop: {
58
- value: function(error){
59
- error = error+'';
60
- var elem = (name == 'input') ? $(this).getNativeElement()[0] : this;
61
- desc.prop._supvalue.call(elem, error);
62
-
63
- if(webshims.bugs.validationMessage){
64
- webshims.data(elem, 'customvalidationMessage', error);
65
- }
66
- if(overrideValidity){
67
- webshims.data(elem, 'hasCustomError', !!(error));
68
- testValidity(elem);
69
- }
70
- }
71
- }
72
- });
73
- oldSetCustomValidity[name] = desc.prop._supvalue;
74
- });
75
-
76
-
77
- if(overrideValidity || overrideNativeMessages){
78
- validityChanger.push('min');
79
- validityChanger.push('max');
80
- validityChanger.push('step');
81
- validityElements.push('input');
82
- }
83
- if(overrideNativeMessages){
84
- validityChanger.push('required');
85
- validityChanger.push('pattern');
86
- validityElements.push('select');
87
- validityElements.push('textarea');
88
- }
89
-
90
- if(overrideValidity){
91
- var stopValidity;
92
- validityElements.forEach(function(nodeName){
93
-
94
- var oldDesc = webshims.defineNodeNameProperty(nodeName, 'validity', {
95
- prop: {
96
- get: function(){
97
- if(stopValidity){return;}
98
- var elem = (nodeName == 'input') ? $(this).getNativeElement()[0] : this;
99
-
100
- var validity = oldDesc.prop._supget.call(elem);
101
-
102
- if(!validity){
103
- return validity;
104
- }
105
- var validityState = {};
106
- validityProps.forEach(function(prop){
107
- validityState[prop] = validity[prop];
108
- });
109
-
110
- if( !$.prop(elem, 'willValidate') ){
111
- return validityState;
112
- }
113
- stopValidity = true;
114
- var jElm = $(elem),
115
- cache = {type: (elem.getAttribute && elem.getAttribute('type') || '').toLowerCase(), nodeName: (elem.nodeName || '').toLowerCase()},
116
- val = jElm.val(),
117
- customError = !!(webshims.data(elem, 'hasCustomError')),
118
- setCustomMessage
119
- ;
120
- stopValidity = false;
121
- validityState.customError = customError;
122
-
123
- if( validityState.valid && validityState.customError ){
124
- validityState.valid = false;
125
- } else if(!validityState.valid) {
126
- var allFalse = true;
127
- $.each(validityState, function(name, prop){
128
- if(prop){
129
- allFalse = false;
130
- return false;
131
- }
132
- });
133
-
134
- if(allFalse){
135
- validityState.valid = true;
136
- }
137
-
138
- }
139
-
140
- $.each(validityRules, function(rule, fn){
141
- validityState[rule] = fn(jElm, val, cache, validityState);
142
- if( validityState[rule] && (validityState.valid || !setCustomMessage) && (overrideNativeMessages || (typeModels[cache.type] && typeModels[cache.type].mismatch)) ) {
143
- oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, rule));
144
- validityState.valid = false;
145
- setCustomMessage = true;
146
- }
147
- });
148
- if(validityState.valid){
149
- oldSetCustomValidity[nodeName].call(elem, '');
150
- webshims.data(elem, 'hasCustomError', false);
151
- } else if(overrideNativeMessages && !setCustomMessage && !customError){
152
- $.each(validityState, function(name, prop){
153
- if(name !== 'valid' && prop){
154
- oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, name));
155
- return false;
156
- }
157
- });
158
- }
159
- return validityState;
160
- },
161
- writeable: false
162
-
163
- }
164
- });
165
- });
166
-
167
- validityChanger.forEach(function(prop){
168
- webshims.onNodeNamesPropertyModify(validityElements, prop, function(s){
169
- testValidity(this);
170
- });
171
- });
172
-
173
- if(doc.addEventListener){
174
- var inputThrottle;
175
- var testPassValidity = function(e){
176
- if(!('form' in e.target)){return;}
177
- var form = e.target.form;
178
- clearTimeout(inputThrottle);
179
- testValidity(e.target);
180
- if(form && overrideNativeMessages){
181
- $('input', form).each(function(){
182
- if(this.type == 'password'){
183
- testValidity(this);
184
- }
185
- });
186
- }
187
- };
188
-
189
- doc.addEventListener('change', testPassValidity, true);
190
-
191
- if(overrideNativeMessages){
192
- doc.addEventListener('blur', testPassValidity, true);
193
- doc.addEventListener('keydown', function(e){
194
- if(e.keyCode != 13){return;}
195
- testPassValidity(e);
196
- }, true);
197
- }
198
-
199
- doc.addEventListener('input', function(e){
200
- clearTimeout(inputThrottle);
201
- inputThrottle = setTimeout(function(){
202
- testValidity(e.target);
203
- }, 290);
204
- }, true);
205
- }
206
-
207
- var validityElementsSel = validityElements.join(',');
208
-
209
- webshims.addReady(function(context, elem){
210
- $(validityElementsSel, context).add(elem.filter(validityElementsSel)).each(function(){
211
- $.prop(this, 'validity');
212
- });
213
- });
214
-
215
-
216
- if(overrideNativeMessages){
217
- webshims.ready('DOM form-message', function(){
218
- webshims.activeLang({
219
- register: 'form-core',
220
- callback: function(){
221
- $('input, select, textarea')
222
- .getNativeElement()
223
- .each(function(){
224
- if(webshims.data(this, 'hasCustomError')){return;}
225
- var elem = this;
226
- var validity = $.prop(elem, 'validity') || {valid: true};
227
- var nodeName;
228
- if(validity.valid){return;}
229
- nodeName = (elem.nodeName || '').toLowerCase();
230
- $.each(validity, function(name, prop){
231
- if(name !== 'valid' && prop){
232
- oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, name));
233
- return false;
234
- }
235
- });
236
- })
237
- ;
238
- }
239
- });
240
- });
241
- }
242
-
243
- } //end: overrideValidity
244
-
245
- webshims.defineNodeNameProperty('input', 'type', {
246
- prop: {
247
- get: function(){
248
- var elem = this;
249
- var type = (elem.getAttribute('type') || '').toLowerCase();
250
- return (webshims.inputTypes[type]) ? type : elem.type;
251
- }
252
- }
253
- });
254
-
255
-
256
- });//additional tests for partial implementation of forms features
257
- (function($){
258
- var Modernizr = window.Modernizr;
259
- var webshims = $.webshims;
260
- var bugs = webshims.bugs;
261
- 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>');
262
- var testRequiredFind = function(){
263
- if(form[0].querySelector){
264
- try {
265
- bugs.findRequired = !(form[0].querySelector('select:required'));
266
- } catch(er){
267
- bugs.findRequired = false;
268
- }
269
- }
270
- };
271
- bugs.findRequired = false;
272
- bugs.validationMessage = false;
273
- bugs.valueAsNumberSet = false;
274
-
275
- webshims.capturingEventPrevented = function(e){
276
- if(!e._isPolyfilled){
277
- var isDefaultPrevented = e.isDefaultPrevented;
278
- var preventDefault = e.preventDefault;
279
- e.preventDefault = function(){
280
- clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
281
- $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
282
- $.removeData(e.target, e.type + 'DefaultPrevented');
283
- }, 30));
284
- return preventDefault.apply(this, arguments);
285
- };
286
- e.isDefaultPrevented = function(){
287
- return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
288
- };
289
- e._isPolyfilled = true;
290
- }
291
- };
292
-
293
- if(!Modernizr.formvalidation || bugs.bustedValidity){
294
- testRequiredFind();
295
- return;
296
- }
297
-
298
- //create delegatable events
299
- webshims.capturingEvents(['input']);
300
- webshims.capturingEvents(['invalid'], true);
301
-
302
- Modernizr.bugfreeformvalidation = true;
303
- if(window.opera || $.browser.webkit || window.testGoodWithFix){
304
- var dateElem = $('input', form).eq(0);
305
- var timer;
306
- var onDomextend = function(fn){
307
- webshims.loader.loadList(['dom-extend']);
308
- webshims.ready('dom-extend', fn);
309
- };
310
- var loadFormFixes = function(e){
311
- var reTest = ['form-extend', 'form-message', 'form-native-fix'];
312
- if(e){
313
- e.preventDefault();
314
- e.stopImmediatePropagation();
315
- }
316
- clearTimeout(timer);
317
- setTimeout(function(){
318
- if(!form){return;}
319
- form.remove();
320
- form = dateElem = null;
321
- }, 9);
322
- if(!Modernizr.bugfreeformvalidation){
323
- webshims.addPolyfill('form-native-fix', {
324
- f: 'forms',
325
- d: ['form-extend']
326
- });
327
- //remove form-extend readyness
328
- webshims.modules['form-extend'].test = $.noop;
329
- }
330
-
331
- if(webshims.isReady('form-number-date-api')){
332
- reTest.push('form-number-date-api');
333
- }
334
-
335
- webshims.reTest(reTest);
336
-
337
- if(dateElem){
338
- try {
339
- if(dateElem.prop({disabled: true, value: ''}).prop('disabled', false).is(':valid')){
340
- onDomextend(function(){
341
- webshims.onNodeNamesPropertyModify(['input', 'textarea'], ['disabled', 'readonly'], {
342
- set: function(val){
343
- var elem = this;
344
- if(!val && elem){
345
- $.prop(elem, 'value', $.prop(elem, 'value'));
346
- }
347
- }
348
- });
349
- webshims.onNodeNamesPropertyModify(['select'], ['disabled', 'readonly'], {
350
- set: function(val){
351
- var elem = this;
352
- if(!val && elem){
353
- val = $(elem).val();
354
- ($('option:last-child', elem)[0] || {}).selected = true;
355
- $(elem).val( val );
356
- }
357
- }
358
- });
359
- });
360
- }
361
- } catch(er){}
362
- }
363
-
364
- if ($.browser.opera || window.testGoodWithFix) {
365
- onDomextend(function(){
366
-
367
- //Opera shows native validation bubbles in case of input.checkValidity()
368
- // Opera 11.6/12 hasn't fixed this issue right, it's buggy
369
- var preventDefault = function(e){
370
- e.preventDefault();
371
- };
372
-
373
- ['form', 'input', 'textarea', 'select'].forEach(function(name){
374
- var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
375
- prop: {
376
- value: function(){
377
- if (!webshims.fromSubmit) {
378
- $(this).bind('invalid.checkvalidity', preventDefault);
379
- }
380
-
381
- webshims.fromCheckValidity = true;
382
- var ret = desc.prop._supvalue.apply(this, arguments);
383
- if (!webshims.fromSubmit) {
384
- $(this).unbind('invalid.checkvalidity', preventDefault);
385
- }
386
- webshims.fromCheckValidity = false;
387
- return ret;
388
- }
389
- }
390
- });
391
- });
392
-
393
- });
394
- }
395
- };
396
-
397
- form.appendTo('head');
398
- if(window.opera || window.testGoodWithFix) {
399
- testRequiredFind();
400
- bugs.validationMessage = !(dateElem.prop('validationMessage'));
401
- if((Modernizr.inputtypes || {}).date){
402
- try {
403
- dateElem.prop('valueAsNumber', 0);
404
- } catch(er){}
405
- bugs.valueAsNumberSet = (dateElem.prop('value') != '1970-01-01');
406
- }
407
- dateElem.prop('value', '');
408
- }
409
-
410
- form.bind('submit', function(e){
411
- Modernizr.bugfreeformvalidation = false;
412
- loadFormFixes(e);
413
- });
414
-
415
- timer = setTimeout(function(){
416
- if (form) {
417
- form.triggerHandler('submit');
418
- }
419
- }, 9);
420
-
421
- $('input, select', form).bind('invalid', loadFormFixes)
422
- .filter('[type="submit"]')
423
- .bind('click', function(e){
424
- e.stopImmediatePropagation();
425
- })
426
- .trigger('click')
427
- ;
428
-
429
- if($.browser.webkit && Modernizr.bugfreeformvalidation && !webshims.bugs.bustedValidity){
430
- (function(){
431
- var elems = /^(?:textarea|input)$/i;
432
- var form = false;
433
-
434
- document.addEventListener('contextmenu', function(e){
435
- if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
436
- setTimeout(function(){
437
- form = false;
438
- }, 1);
439
- }
440
- }, false);
441
-
442
- $(window).bind('invalid', function(e){
443
- if(e.originalEvent && form && form == e.target.form){
444
- e.wrongWebkitInvalid = true;
445
- e.stopImmediatePropagation();
446
- }
447
- });
448
- })();
449
- }
450
- }
451
-
452
- })(jQuery);
453
-
454
- jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
455
- "use strict";
456
-
457
- var groupTypes = {radio: 1};
458
- var checkTypes = {checkbox: 1, radio: 1};
459
- var emptyJ = $([]);
460
- var bugs = webshims.bugs;
461
- var getGroupElements = function(elem){
462
- elem = $(elem);
463
- var name;
464
- var form;
465
- var ret = emptyJ;
466
- if(groupTypes[elem[0].type]){
467
- form = elem.prop('form');
468
- name = elem[0].name;
469
- if(!name){
470
- ret = elem;
471
- } else if(form){
472
- ret = $(form[name]);
473
- } else {
474
- ret = $(document.getElementsByName(name)).filter(function(){
475
- return !$.prop(this, 'form');
476
- });
477
- }
478
- ret = ret.filter('[type="radio"]');
479
- }
480
- return ret;
481
- };
482
-
483
- var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
484
- var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
485
- if(key && message[key]){
486
- message = message[key];
487
- }
488
- if(typeof message == 'object'){
489
- validity = validity || $.prop(elem, 'validity') || {valid: 1};
490
- if(!validity.valid){
491
- $.each(validity, function(name, prop){
492
- if(prop && name != 'valid' && message[name]){
493
- message = message[name];
494
- return false;
495
- }
496
- });
497
- }
498
- }
499
-
500
- if(typeof message == 'object'){
501
- message = message.defaultMessage;
502
- }
503
- return message || '';
504
- };
505
-
506
- /*
507
- * Selectors for all browsers
508
- */
509
- var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
510
- $.extend($.expr[":"], {
511
- "valid-element": function(elem){
512
- return !!($.prop(elem, 'willValidate') && ($.prop(elem, 'validity') || {valid: 1}).valid);
513
- },
514
- "invalid-element": function(elem){
515
- return !!($.prop(elem, 'willValidate') && !isValid(elem));
516
- },
517
- "required-element": function(elem){
518
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
519
- },
520
- "optional-element": function(elem){
521
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
522
- },
523
- "in-range": function(elem){
524
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
525
- return false;
526
- }
527
- var val = $.prop(elem, 'validity');
528
- return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
529
- },
530
- "out-of-range": function(elem){
531
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
532
- return false;
533
- }
534
- var val = $.prop(elem, 'validity');
535
- return !!(val && (val.rangeOverflow || val.rangeUnderflow));
536
- }
537
-
538
- });
539
-
540
- ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
541
- $.expr[":"][name] = $.expr.filters[name+"-element"];
542
- });
543
-
544
-
545
- $.expr[":"].focus = function( elem ) {
546
- try {
547
- var doc = elem.ownerDocument;
548
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
549
- } catch(e){}
550
- return false;
551
- };
552
-
553
- var customEvents = $.event.customEvent || {};
554
- var isValid = function(elem){
555
- return ($.prop(elem, 'validity') || {valid: 1}).valid;
556
- };
557
-
558
- if (bugs.bustedValidity || bugs.findRequired || !Modernizr.bugfreeformvalidation) {
559
- (function(){
560
- var find = $.find;
561
- var matchesSelector = $.find.matchesSelector;
562
-
563
- var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
564
- var regFn = function(sel){
565
- return sel + '-element';
566
- };
567
-
568
- $.find = (function(){
569
- var slice = Array.prototype.slice;
570
- var fn = function(sel){
571
- var ar = arguments;
572
- ar = slice.call(ar, 1, ar.length);
573
- ar.unshift(sel.replace(regExp, regFn));
574
- return find.apply(this, ar);
575
- };
576
- for (var i in find) {
577
- if(find.hasOwnProperty(i)){
578
- fn[i] = find[i];
579
- }
580
- }
581
- return fn;
582
- })();
583
- if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
584
- $.find.matchesSelector = function(node, expr){
585
- expr = expr.replace(regExp, regFn);
586
- return matchesSelector.call(this, node, expr);
587
- };
588
- }
589
-
590
- })();
591
- }
592
-
593
- //ToDo needs testing
594
- var oldAttr = $.prop;
595
- var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
596
- $.prop = function(elem, name, val){
597
- var ret = oldAttr.apply(this, arguments);
598
- if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass('form-ui-invalid')){
599
- if(isValid(elem)){
600
- $(elem).getShadowElement().removeClass('form-ui-invalid');
601
- if(name == 'checked' && val) {
602
- getGroupElements(elem).not(elem).removeClass('form-ui-invalid').removeAttr('aria-invalid');
603
- }
604
- }
605
- }
606
- return ret;
607
- };
608
-
609
- var returnValidityCause = function(validity, elem){
610
- var ret;
611
- $.each(validity, function(name, value){
612
- if(value){
613
- ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
614
- return false;
615
- }
616
- });
617
- return ret;
618
- };
619
-
620
- var switchValidityClass = function(e){
621
- var elem, timer;
622
- if(!e.target){return;}
623
- elem = $(e.target).getNativeElement()[0];
624
- if(elem.type == 'submit' || !$.prop(elem, 'willValidate') || (e.type == 'focusout' && e.type == 'radio')){return;}
625
- timer = $.data(elem, 'webshimsswitchvalidityclass');
626
- var switchClass = function(){
627
- var validity = $.prop(elem, 'validity');
628
- var shadowElem = $(elem).getShadowElement();
629
- var addClass, removeClass, trigger, generaltrigger, validityCause;
630
-
631
- $(elem).trigger('refreshCustomValidityRules');
632
- if(validity.valid){
633
- if(!shadowElem.hasClass('form-ui-valid')){
634
- addClass = 'form-ui-valid';
635
- removeClass = 'form-ui-invalid';
636
- generaltrigger = 'changedvaliditystate';
637
- trigger = 'changedvalid';
638
- if(checkTypes[elem.type] && elem.checked){
639
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
640
- }
641
- $.removeData(elem, 'webshimsinvalidcause');
642
- }
643
- } else {
644
- validityCause = returnValidityCause(validity, elem);
645
- if($.data(elem, 'webshimsinvalidcause') != validityCause){
646
- $.data(elem, 'webshimsinvalidcause', validityCause);
647
- generaltrigger = 'changedvaliditystate';
648
- }
649
- if(!shadowElem.hasClass('form-ui-invalid')){
650
- addClass = 'form-ui-invalid';
651
- removeClass = 'form-ui-valid';
652
- if (checkTypes[elem.type] && !elem.checked) {
653
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
654
- }
655
- trigger = 'changedinvalid';
656
- }
657
- }
658
- if(addClass){
659
- shadowElem.addClass(addClass).removeClass(removeClass);
660
- //jQuery 1.6.1 IE9 bug (doubble trigger bug)
661
- setTimeout(function(){
662
- $(elem).trigger(trigger);
663
- }, 0);
664
- }
665
- if(generaltrigger){
666
- setTimeout(function(){
667
- $(elem).trigger(generaltrigger);
668
- }, 0);
669
- }
670
- $.removeData(e.target, 'webshimsswitchvalidityclass');
671
-
672
- };
673
- if(timer){
674
- clearTimeout(timer);
675
- }
676
- if(e.type == 'refreshvalidityui'){
677
- switchClass();
678
- } else {
679
- $.data(e.target, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
680
- }
681
- };
682
-
683
- $(document).bind(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
684
- customEvents.changedvaliditystate = true;
685
- customEvents.refreshCustomValidityRules = true;
686
- customEvents.changedvalid = true;
687
- customEvents.changedinvalid = true;
688
- customEvents.refreshvalidityui = true;
689
-
690
-
691
- webshims.triggerInlineForm = function(elem, event){
692
- $(elem).trigger(event);
693
- };
694
-
695
- webshims.modules["form-core"].getGroupElements = getGroupElements;
696
-
697
-
698
- var setRoot = function(){
699
- webshims.scrollRoot = ($.browser.webkit || document.compatMode == 'BackCompat') ?
700
- $(document.body) :
701
- $(document.documentElement)
702
- ;
703
- };
704
- setRoot();
705
- webshims.ready('DOM', setRoot);
706
-
707
- webshims.getRelOffset = function(posElem, relElem){
708
- posElem = $(posElem);
709
- var offset = $(relElem).offset();
710
- var bodyOffset;
711
- $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
712
- bodyOffset = posElem.offset();
713
- });
714
- offset.top -= bodyOffset.top;
715
- offset.left -= bodyOffset.left;
716
- return offset;
717
- };
718
-
719
- /* some extra validation UI */
720
- webshims.validityAlert = (function(){
721
- var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label';
722
- var errorBubble;
723
- var hideTimer = false;
724
- var focusTimer = false;
725
- var resizeTimer = false;
726
- var boundHide;
727
-
728
- var api = {
729
- hideDelay: 5000,
730
-
731
- showFor: function(elem, message, noFocusElem, noBubble){
732
- api._create();
733
- elem = $(elem);
734
- var visual = $(elem).getShadowElement();
735
- var offset = api.getOffsetFromBody(visual);
736
- api.clear();
737
- if(noBubble){
738
- this.hide();
739
- } else {
740
- this.getMessage(elem, message);
741
- this.position(visual, offset);
742
-
743
- this.show();
744
- if(this.hideDelay){
745
- hideTimer = setTimeout(boundHide, this.hideDelay);
746
- }
747
- $(window)
748
- .bind('resize.validityalert', function(){
749
- clearTimeout(resizeTimer);
750
- resizeTimer = setTimeout(function(){
751
- api.position(visual);
752
- }, 9);
753
- })
754
- ;
755
- }
756
-
757
- if(!noFocusElem){
758
- this.setFocus(visual, offset);
759
- }
760
- },
761
- getOffsetFromBody: function(elem){
762
- return webshims.getRelOffset(errorBubble, elem);
763
- },
764
- setFocus: function(visual, offset){
765
- var focusElem = $(visual).getShadowFocusElement();
766
- var scrollTop = webshims.scrollRoot.scrollTop();
767
- var elemTop = ((offset || focusElem.offset()).top) - 30;
768
- var smooth;
769
-
770
- if(webshims.getID && alertElem == 'label'){
771
- errorBubble.attr('for', webshims.getID(focusElem));
772
- }
773
-
774
- if(scrollTop > elemTop){
775
- webshims.scrollRoot.animate(
776
- {scrollTop: elemTop - 5},
777
- {
778
- queue: false,
779
- duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
780
- }
781
- );
782
- smooth = true;
783
- }
784
- try {
785
- focusElem[0].focus();
786
- } catch(e){}
787
- if(smooth){
788
- webshims.scrollRoot.scrollTop(scrollTop);
789
- setTimeout(function(){
790
- webshims.scrollRoot.scrollTop(scrollTop);
791
- }, 0);
792
- }
793
- setTimeout(function(){
794
- $(document).bind('focusout.validityalert', boundHide);
795
- }, 10);
796
- },
797
- getMessage: function(elem, message){
798
- if (!message) {
799
- message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage');
800
- }
801
- if (message) {
802
- $('span.va-box', errorBubble).text(message);
803
- }
804
- else {
805
- this.hide();
806
- }
807
- },
808
- position: function(elem, offset){
809
- offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
810
- offset.top += elem.outerHeight();
811
- errorBubble.css(offset);
812
- },
813
- show: function(){
814
- if(errorBubble.css('display') === 'none'){
815
- errorBubble.css({opacity: 0}).show();
816
- }
817
- errorBubble.addClass('va-visible').fadeTo(400, 1);
818
- },
819
- hide: function(){
820
- errorBubble.removeClass('va-visible').fadeOut();
821
- },
822
- clear: function(){
823
- clearTimeout(focusTimer);
824
- clearTimeout(hideTimer);
825
- $(document).unbind('.validityalert');
826
- $(window).unbind('.validityalert');
827
- errorBubble.stop().removeAttr('for');
828
- },
829
- _create: function(){
830
- if(errorBubble){return;}
831
- 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'});
832
- webshims.ready('DOM', function(){
833
- errorBubble.appendTo('body');
834
- if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){
835
- errorBubble.bgIframe();
836
- }
837
- });
838
- }
839
- };
840
-
841
-
842
- boundHide = $.proxy(api, 'hide');
843
-
844
- return api;
845
- })();
846
-
847
-
848
- /* extension, but also used to fix native implementation workaround/bugfixes */
849
- (function(){
850
- var firstEvent,
851
- invalids = [],
852
- stopSubmitTimer,
853
- form
854
- ;
855
-
856
- $(document).bind('invalid', function(e){
857
- if(e.wrongWebkitInvalid){return;}
858
- var jElm = $(e.target);
859
- var shadowElem = jElm.getShadowElement();
860
- if(!shadowElem.hasClass('form-ui-invalid')){
861
- shadowElem.addClass('form-ui-invalid').removeClass('form-ui-valid');
862
- setTimeout(function(){
863
- $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
864
- }, 0);
865
- }
866
-
867
- if(!firstEvent){
868
- //trigger firstinvalid
869
- firstEvent = $.Event('firstinvalid');
870
- firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
871
- var firstSystemInvalid = $.Event('firstinvalidsystem');
872
- $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
873
- jElm.trigger(firstEvent);
874
- }
875
-
876
- //if firstinvalid was prevented all invalids will be also prevented
877
- if( firstEvent && firstEvent.isDefaultPrevented() ){
878
- e.preventDefault();
879
- }
880
- invalids.push(e.target);
881
- e.extraData = 'fix';
882
- clearTimeout(stopSubmitTimer);
883
- stopSubmitTimer = setTimeout(function(){
884
- var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
885
- //reset firstinvalid
886
- firstEvent = false;
887
- invalids = [];
888
- $(e.target).trigger(lastEvent, lastEvent);
889
- }, 9);
890
- jElm = null;
891
- shadowElem = null;
892
- });
893
- })();
894
-
895
- $.fn.getErrorMessage = function(){
896
- var message = '';
897
- var elem = this[0];
898
- if(elem){
899
- message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
900
- }
901
- return message;
902
- };
903
-
904
- if(options.replaceValidationUI){
905
- webshims.ready('DOM forms', function(){
906
- $(document).bind('firstinvalid', function(e){
907
- if(!e.isInvalidUIPrevented()){
908
- e.preventDefault();
909
- $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') );
910
- }
911
- });
912
- });
913
- }
914
-
915
- });jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
916
- var validityMessages = webshims.validityMessages;
917
-
918
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
919
-
920
- validityMessages['en'] = $.extend(true, {
921
- typeMismatch: {
922
- email: 'Please enter an email address.',
923
- url: 'Please enter a URL.',
924
- number: 'Please enter a number.',
925
- date: 'Please enter a date.',
926
- time: 'Please enter a time.',
927
- range: 'Invalid input.',
928
- "datetime-local": 'Please enter a datetime.'
929
- },
930
- rangeUnderflow: {
931
- defaultMessage: 'Value must be greater than or equal to {%min}.'
932
- },
933
- rangeOverflow: {
934
- defaultMessage: 'Value must be less than or equal to {%max}.'
935
- },
936
- stepMismatch: 'Invalid input.',
937
- tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
938
-
939
- patternMismatch: 'Invalid input. {%title}',
940
- valueMissing: {
941
- defaultMessage: 'Please fill out this field.',
942
- checkbox: 'Please check this box if you want to proceed.'
943
- }
944
- }, (validityMessages['en'] || validityMessages['en-US'] || {}));
945
-
946
-
947
- ['select', 'radio'].forEach(function(type){
948
- validityMessages['en'].valueMissing[type] = 'Please select an option.';
949
- });
950
-
951
- ['date', 'time', 'datetime-local'].forEach(function(type){
952
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
953
- });
954
- ['date', 'time', 'datetime-local'].forEach(function(type){
955
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
956
- });
957
-
958
- validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
959
- validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
960
-
961
- validityMessages['de'] = $.extend(true, {
962
- typeMismatch: {
963
- email: '{%value} ist keine zulässige E-Mail-Adresse',
964
- url: '{%value} ist keine zulässige Webadresse',
965
- number: '{%value} ist keine Nummer!',
966
- date: '{%value} ist kein Datum',
967
- time: '{%value} ist keine Uhrzeit',
968
- range: '{%value} ist keine Nummer!',
969
- "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
970
- },
971
- rangeUnderflow: {
972
- defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
973
- },
974
- rangeOverflow: {
975
- defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
976
- },
977
- stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
978
- tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
979
- patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
980
- valueMissing: {
981
- defaultMessage: 'Bitte geben Sie einen Wert ein',
982
- checkbox: 'Bitte aktivieren Sie das Kästchen'
983
- }
984
- }, (validityMessages['de'] || {}));
985
-
986
- ['select', 'radio'].forEach(function(type){
987
- validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
988
- });
989
-
990
- ['date', 'time', 'datetime-local'].forEach(function(type){
991
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
992
- });
993
- ['date', 'time', 'datetime-local'].forEach(function(type){
994
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
995
- });
996
-
997
- var currentValidationMessage = validityMessages[''];
998
-
999
-
1000
- webshims.createValidationMessage = function(elem, name){
1001
- var message = currentValidationMessage[name];
1002
- if(message && typeof message !== 'string'){
1003
- message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
1004
- }
1005
- if(message){
1006
- ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
1007
- if(message.indexOf('{%'+attr) === -1){return;}
1008
- var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
1009
- if(name == 'patternMismatch' && attr == 'title' && !val){
1010
- webshims.error('no title for patternMismatch provided. Always add a title attribute.');
1011
- }
1012
- message = message.replace('{%'+ attr +'}', val);
1013
- if('value' == attr){
1014
- message = message.replace('{%valueLen}', val.length);
1015
- }
1016
- });
1017
- }
1018
- return message || '';
1019
- };
1020
-
1021
-
1022
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
1023
- implementProperties.push('validationMessage');
1024
- }
1025
-
1026
- webshims.activeLang({
1027
- langObj: validityMessages,
1028
- module: 'form-core',
1029
- callback: function(langObj){
1030
- currentValidationMessage = langObj;
1031
- }
1032
- });
1033
-
1034
- implementProperties.forEach(function(messageProp){
1035
- webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
1036
- prop: {
1037
- value: '',
1038
- writeable: false
1039
- }
1040
- });
1041
- ['input', 'select', 'textarea'].forEach(function(nodeName){
1042
- var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
1043
- prop: {
1044
- get: function(){
1045
- var elem = this;
1046
- var message = '';
1047
- if(!$.prop(elem, 'willValidate')){
1048
- return message;
1049
- }
1050
-
1051
- var validity = $.prop(elem, 'validity') || {valid: 1};
1052
-
1053
- if(validity.valid){return message;}
1054
- message = webshims.getContentValidationMessage(elem, validity);
1055
-
1056
- if(message){return message;}
1057
-
1058
- if(validity.customError && elem.nodeName){
1059
- message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
1060
- if(message){return message;}
1061
- }
1062
- $.each(validity, function(name, prop){
1063
- if(name == 'valid' || !prop){return;}
1064
-
1065
- message = webshims.createValidationMessage(elem, name);
1066
- if(message){
1067
- return false;
1068
- }
1069
- });
1070
- return message || '';
1071
- },
1072
- writeable: false
1073
- }
1074
- });
1075
- });
1076
-
1077
- });
1
+ jQuery.webshims.register('form-extend', function($, webshims, window, doc, undefined, options){
2
+ "use strict";
3
+ var Modernizr = window.Modernizr;
4
+ var modernizrInputTypes = Modernizr.inputtypes;
5
+ if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){return;}
6
+ var typeModels = webshims.inputTypes;
7
+ var validityRules = {};
8
+
9
+ webshims.addInputType = function(type, obj){
10
+ typeModels[type] = obj;
11
+ };
12
+
13
+ webshims.addValidityRule = function(type, fn){
14
+ validityRules[type] = fn;
15
+ };
16
+
17
+ webshims.addValidityRule('typeMismatch',function (input, val, cache, validityState){
18
+ if(val === ''){return false;}
19
+ var ret = validityState.typeMismatch;
20
+ if(!('type' in cache)){
21
+ cache.type = (input[0].getAttribute('type') || '').toLowerCase();
22
+ }
23
+
24
+ if(typeModels[cache.type] && typeModels[cache.type].mismatch){
25
+ ret = typeModels[cache.type].mismatch(val, input);
26
+ }
27
+ return ret;
28
+ });
29
+
30
+ var overrideNativeMessages = options.overrideMessages;
31
+
32
+ var overrideValidity = (!modernizrInputTypes.number || !modernizrInputTypes.time || !modernizrInputTypes.range || overrideNativeMessages);
33
+ var validityProps = ['customError','typeMismatch','rangeUnderflow','rangeOverflow','stepMismatch','tooLong','patternMismatch','valueMissing','valid'];
34
+
35
+ var validityChanger = (overrideNativeMessages)? ['value', 'checked'] : ['value'];
36
+ var validityElements = [];
37
+ var testValidity = function(elem, init){
38
+ if(!elem){return;}
39
+ var type = (elem.getAttribute && elem.getAttribute('type') || elem.type || '').toLowerCase();
40
+
41
+ if(!overrideNativeMessages && !typeModels[type]){
42
+ return;
43
+ }
44
+
45
+ if(overrideNativeMessages && !init && type == 'radio' && elem.name){
46
+ $(doc.getElementsByName( elem.name )).each(function(){
47
+ $.prop(this, 'validity');
48
+ });
49
+ } else {
50
+ $.prop(elem, 'validity');
51
+ }
52
+ };
53
+
54
+ var oldSetCustomValidity = {};
55
+ ['input', 'textarea', 'select'].forEach(function(name){
56
+ var desc = webshims.defineNodeNameProperty(name, 'setCustomValidity', {
57
+ prop: {
58
+ value: function(error){
59
+ error = error+'';
60
+ var elem = (name == 'input') ? $(this).getNativeElement()[0] : this;
61
+ desc.prop._supvalue.call(elem, error);
62
+
63
+ if(webshims.bugs.validationMessage){
64
+ webshims.data(elem, 'customvalidationMessage', error);
65
+ }
66
+ if(overrideValidity){
67
+ webshims.data(elem, 'hasCustomError', !!(error));
68
+ testValidity(elem);
69
+ }
70
+ }
71
+ }
72
+ });
73
+ oldSetCustomValidity[name] = desc.prop._supvalue;
74
+ });
75
+
76
+
77
+ if(overrideValidity || overrideNativeMessages){
78
+ validityChanger.push('min');
79
+ validityChanger.push('max');
80
+ validityChanger.push('step');
81
+ validityElements.push('input');
82
+ }
83
+ if(overrideNativeMessages){
84
+ validityChanger.push('required');
85
+ validityChanger.push('pattern');
86
+ validityElements.push('select');
87
+ validityElements.push('textarea');
88
+ }
89
+
90
+ if(overrideValidity){
91
+ var stopValidity;
92
+ validityElements.forEach(function(nodeName){
93
+
94
+ var oldDesc = webshims.defineNodeNameProperty(nodeName, 'validity', {
95
+ prop: {
96
+ get: function(){
97
+ if(stopValidity){return;}
98
+ var elem = (nodeName == 'input') ? $(this).getNativeElement()[0] : this;
99
+
100
+ var validity = oldDesc.prop._supget.call(elem);
101
+
102
+ if(!validity){
103
+ return validity;
104
+ }
105
+ var validityState = {};
106
+ validityProps.forEach(function(prop){
107
+ validityState[prop] = validity[prop];
108
+ });
109
+
110
+ if( !$.prop(elem, 'willValidate') ){
111
+ return validityState;
112
+ }
113
+ stopValidity = true;
114
+ var jElm = $(elem),
115
+ cache = {type: (elem.getAttribute && elem.getAttribute('type') || '').toLowerCase(), nodeName: (elem.nodeName || '').toLowerCase()},
116
+ val = jElm.val(),
117
+ customError = !!(webshims.data(elem, 'hasCustomError')),
118
+ setCustomMessage
119
+ ;
120
+ stopValidity = false;
121
+ validityState.customError = customError;
122
+
123
+ if( validityState.valid && validityState.customError ){
124
+ validityState.valid = false;
125
+ } else if(!validityState.valid) {
126
+ var allFalse = true;
127
+ $.each(validityState, function(name, prop){
128
+ if(prop){
129
+ allFalse = false;
130
+ return false;
131
+ }
132
+ });
133
+
134
+ if(allFalse){
135
+ validityState.valid = true;
136
+ }
137
+
138
+ }
139
+
140
+ $.each(validityRules, function(rule, fn){
141
+ validityState[rule] = fn(jElm, val, cache, validityState);
142
+ if( validityState[rule] && (validityState.valid || !setCustomMessage) && (overrideNativeMessages || (typeModels[cache.type] && typeModels[cache.type].mismatch)) ) {
143
+ oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, rule));
144
+ validityState.valid = false;
145
+ setCustomMessage = true;
146
+ }
147
+ });
148
+ if(validityState.valid){
149
+ oldSetCustomValidity[nodeName].call(elem, '');
150
+ webshims.data(elem, 'hasCustomError', false);
151
+ } else if(overrideNativeMessages && !setCustomMessage && !customError){
152
+ $.each(validityState, function(name, prop){
153
+ if(name !== 'valid' && prop){
154
+ oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, name));
155
+ return false;
156
+ }
157
+ });
158
+ }
159
+ return validityState;
160
+ },
161
+ writeable: false
162
+
163
+ }
164
+ });
165
+ });
166
+
167
+ validityChanger.forEach(function(prop){
168
+ webshims.onNodeNamesPropertyModify(validityElements, prop, function(s){
169
+ testValidity(this);
170
+ });
171
+ });
172
+
173
+ if(doc.addEventListener){
174
+ var inputThrottle;
175
+ var testPassValidity = function(e){
176
+ if(!('form' in e.target)){return;}
177
+ var form = e.target.form;
178
+ clearTimeout(inputThrottle);
179
+ testValidity(e.target);
180
+ if(form && overrideNativeMessages){
181
+ $('input', form).each(function(){
182
+ if(this.type == 'password'){
183
+ testValidity(this);
184
+ }
185
+ });
186
+ }
187
+ };
188
+
189
+ doc.addEventListener('change', testPassValidity, true);
190
+
191
+ if(overrideNativeMessages){
192
+ doc.addEventListener('blur', testPassValidity, true);
193
+ doc.addEventListener('keydown', function(e){
194
+ if(e.keyCode != 13){return;}
195
+ testPassValidity(e);
196
+ }, true);
197
+ }
198
+
199
+ doc.addEventListener('input', function(e){
200
+ clearTimeout(inputThrottle);
201
+ inputThrottle = setTimeout(function(){
202
+ testValidity(e.target);
203
+ }, 290);
204
+ }, true);
205
+ }
206
+
207
+ var validityElementsSel = validityElements.join(',');
208
+
209
+ webshims.addReady(function(context, elem){
210
+ $(validityElementsSel, context).add(elem.filter(validityElementsSel)).each(function(){
211
+ $.prop(this, 'validity');
212
+ });
213
+ });
214
+
215
+
216
+ if(overrideNativeMessages){
217
+ webshims.ready('DOM form-message', function(){
218
+ webshims.activeLang({
219
+ register: 'form-core',
220
+ callback: function(){
221
+ $('input, select, textarea')
222
+ .getNativeElement()
223
+ .each(function(){
224
+ if(webshims.data(this, 'hasCustomError')){return;}
225
+ var elem = this;
226
+ var validity = $.prop(elem, 'validity') || {valid: true};
227
+ var nodeName;
228
+ if(validity.valid){return;}
229
+ nodeName = (elem.nodeName || '').toLowerCase();
230
+ $.each(validity, function(name, prop){
231
+ if(name !== 'valid' && prop){
232
+ oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, name));
233
+ return false;
234
+ }
235
+ });
236
+ })
237
+ ;
238
+ }
239
+ });
240
+ });
241
+ }
242
+
243
+ } //end: overrideValidity
244
+
245
+ webshims.defineNodeNameProperty('input', 'type', {
246
+ prop: {
247
+ get: function(){
248
+ var elem = this;
249
+ var type = (elem.getAttribute('type') || '').toLowerCase();
250
+ return (webshims.inputTypes[type]) ? type : elem.type;
251
+ }
252
+ }
253
+ });
254
+
255
+
256
+ });//additional tests for partial implementation of forms features
257
+ (function($){
258
+ "use strict";
259
+ var Modernizr = window.Modernizr;
260
+ var webshims = $.webshims;
261
+ var bugs = webshims.bugs;
262
+ var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input required="" name="a" /></form>');
263
+ var testRequiredFind = function(){
264
+ if(form[0].querySelector){
265
+ try {
266
+ bugs.findRequired = !(form[0].querySelector('select:required'));
267
+ } catch(er){
268
+ bugs.findRequired = false;
269
+ }
270
+ }
271
+ };
272
+ var inputElem = $('input', form).eq(0);
273
+ var onDomextend = function(fn){
274
+ webshims.loader.loadList(['dom-extend']);
275
+ webshims.ready('dom-extend', fn);
276
+ };
277
+
278
+ bugs.findRequired = false;
279
+ bugs.validationMessage = false;
280
+
281
+ webshims.capturingEventPrevented = function(e){
282
+ if(!e._isPolyfilled){
283
+ var isDefaultPrevented = e.isDefaultPrevented;
284
+ var preventDefault = e.preventDefault;
285
+ e.preventDefault = function(){
286
+ clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
287
+ $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
288
+ $.removeData(e.target, e.type + 'DefaultPrevented');
289
+ }, 30));
290
+ return preventDefault.apply(this, arguments);
291
+ };
292
+ e.isDefaultPrevented = function(){
293
+ return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
294
+ };
295
+ e._isPolyfilled = true;
296
+ }
297
+ };
298
+
299
+ if(!Modernizr.formvalidation || bugs.bustedValidity){
300
+ testRequiredFind();
301
+ return;
302
+ }
303
+
304
+ //create delegatable events
305
+ webshims.capturingEvents(['input']);
306
+ webshims.capturingEvents(['invalid'], true);
307
+
308
+ if(window.opera || window.testGoodWithFix){
309
+
310
+ form.appendTo('head');
311
+
312
+ testRequiredFind();
313
+ bugs.validationMessage = !(inputElem.prop('validationMessage'));
314
+
315
+ webshims.reTest(['form-extend', 'form-message']);
316
+
317
+ form.remove();
318
+
319
+ $(function(){
320
+ onDomextend(function(){
321
+
322
+ //Opera shows native validation bubbles in case of input.checkValidity()
323
+ // Opera 11.6/12 hasn't fixed this issue right, it's buggy
324
+ var preventDefault = function(e){
325
+ e.preventDefault();
326
+ };
327
+
328
+ ['form', 'input', 'textarea', 'select'].forEach(function(name){
329
+ var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
330
+ prop: {
331
+ value: function(){
332
+ if (!webshims.fromSubmit) {
333
+ $(this).on('invalid.checkvalidity', preventDefault);
334
+ }
335
+
336
+ webshims.fromCheckValidity = true;
337
+ var ret = desc.prop._supvalue.apply(this, arguments);
338
+ if (!webshims.fromSubmit) {
339
+ $(this).unbind('invalid.checkvalidity', preventDefault);
340
+ }
341
+ webshims.fromCheckValidity = false;
342
+ return ret;
343
+ }
344
+ }
345
+ });
346
+ });
347
+
348
+ });
349
+ });
350
+ }
351
+
352
+ if($.browser.webkit && !webshims.bugs.bustedValidity){
353
+ (function(){
354
+ var elems = /^(?:textarea|input)$/i;
355
+ var form = false;
356
+
357
+ document.addEventListener('contextmenu', function(e){
358
+ if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
359
+ setTimeout(function(){
360
+ form = false;
361
+ }, 1);
362
+ }
363
+ }, false);
364
+
365
+ $(window).on('invalid', function(e){
366
+ if(e.originalEvent && form && form == e.target.form){
367
+ e.wrongWebkitInvalid = true;
368
+ e.stopImmediatePropagation();
369
+ }
370
+ });
371
+ })();
372
+ }
373
+ })(jQuery);
374
+
375
+ jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
376
+ "use strict";
377
+
378
+ var groupTypes = {radio: 1};
379
+ var checkTypes = {checkbox: 1, radio: 1};
380
+ var emptyJ = $([]);
381
+ var bugs = webshims.bugs;
382
+ var getGroupElements = function(elem){
383
+ elem = $(elem);
384
+ var name;
385
+ var form;
386
+ var ret = emptyJ;
387
+ if(groupTypes[elem[0].type]){
388
+ form = elem.prop('form');
389
+ name = elem[0].name;
390
+ if(!name){
391
+ ret = elem;
392
+ } else if(form){
393
+ ret = $(form[name]);
394
+ } else {
395
+ ret = $(document.getElementsByName(name)).filter(function(){
396
+ return !$.prop(this, 'form');
397
+ });
398
+ }
399
+ ret = ret.filter('[type="radio"]');
400
+ }
401
+ return ret;
402
+ };
403
+
404
+ var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
405
+ var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
406
+ if(key && message[key]){
407
+ message = message[key];
408
+ }
409
+ if(typeof message == 'object'){
410
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
411
+ if(!validity.valid){
412
+ $.each(validity, function(name, prop){
413
+ if(prop && name != 'valid' && message[name]){
414
+ message = message[name];
415
+ return false;
416
+ }
417
+ });
418
+ }
419
+ }
420
+
421
+ if(typeof message == 'object'){
422
+ message = message.defaultMessage;
423
+ }
424
+ return message || '';
425
+ };
426
+
427
+ /*
428
+ * Selectors for all browsers
429
+ */
430
+ var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
431
+ var hasInvalid = function(elem){
432
+ var ret = false;
433
+ $($.prop(elem, 'elements')).each(function(){
434
+ ret = $(this).is(':invalid');
435
+ if(ret){
436
+ return false;
437
+ }
438
+ });
439
+ return ret;
440
+ };
441
+ $.extend($.expr[":"], {
442
+ "valid-element": function(elem){
443
+ return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
444
+ },
445
+ "invalid-element": function(elem){
446
+ return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
447
+ },
448
+ "required-element": function(elem){
449
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
450
+ },
451
+ "user-error": function(elem){
452
+ return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
453
+ },
454
+ "optional-element": function(elem){
455
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
456
+ },
457
+ "in-range": function(elem){
458
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
459
+ return false;
460
+ }
461
+ var val = $.prop(elem, 'validity');
462
+ return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
463
+ },
464
+ "out-of-range": function(elem){
465
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
466
+ return false;
467
+ }
468
+ var val = $.prop(elem, 'validity');
469
+ return !!(val && (val.rangeOverflow || val.rangeUnderflow));
470
+ }
471
+
472
+ });
473
+
474
+ ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
475
+ $.expr[":"][name] = $.expr.filters[name+"-element"];
476
+ });
477
+
478
+
479
+ $.expr[":"].focus = function( elem ) {
480
+ try {
481
+ var doc = elem.ownerDocument;
482
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
483
+ } catch(e){}
484
+ return false;
485
+ };
486
+
487
+ var customEvents = $.event.customEvent || {};
488
+ var isValid = function(elem){
489
+ return ($.prop(elem, 'validity') || {valid: 1}).valid;
490
+ };
491
+
492
+ if (bugs.bustedValidity || bugs.findRequired) {
493
+ (function(){
494
+ var find = $.find;
495
+ var matchesSelector = $.find.matchesSelector;
496
+
497
+ var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
498
+ var regFn = function(sel){
499
+ return sel + '-element';
500
+ };
501
+
502
+ $.find = (function(){
503
+ var slice = Array.prototype.slice;
504
+ var fn = function(sel){
505
+ var ar = arguments;
506
+ ar = slice.call(ar, 1, ar.length);
507
+ ar.unshift(sel.replace(regExp, regFn));
508
+ return find.apply(this, ar);
509
+ };
510
+ for (var i in find) {
511
+ if(find.hasOwnProperty(i)){
512
+ fn[i] = find[i];
513
+ }
514
+ }
515
+ return fn;
516
+ })();
517
+ if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
518
+ $.find.matchesSelector = function(node, expr){
519
+ expr = expr.replace(regExp, regFn);
520
+ return matchesSelector.call(this, node, expr);
521
+ };
522
+ }
523
+
524
+ })();
525
+ }
526
+
527
+ //ToDo needs testing
528
+ var oldAttr = $.prop;
529
+ var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
530
+ $.prop = function(elem, name, val){
531
+ var ret = oldAttr.apply(this, arguments);
532
+ if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
533
+ if(isValid(elem)){
534
+ $(elem).getShadowElement().removeClass(invalidClasses);
535
+ if(name == 'checked' && val) {
536
+ getGroupElements(elem).not(elem).removeClass(invalidClasses).removeAttr('aria-invalid');
537
+ }
538
+ }
539
+ }
540
+ return ret;
541
+ };
542
+
543
+ var returnValidityCause = function(validity, elem){
544
+ var ret;
545
+ $.each(validity, function(name, value){
546
+ if(value){
547
+ ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
548
+ return false;
549
+ }
550
+ });
551
+ return ret;
552
+ };
553
+
554
+ var isInGroup = function(name){
555
+ var ret;
556
+ try {
557
+ ret = document.activeElement.name === name;
558
+ } catch(e){}
559
+ return ret;
560
+ };
561
+ /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-succes instead */
562
+ var invalidClass = 'user-error';
563
+ var invalidClasses = 'user-error form-ui-invalid';
564
+ var validClass = 'user-success';
565
+ var validClasses = 'user-success form-ui-valid';
566
+ var switchValidityClass = function(e){
567
+ var elem, timer;
568
+ if(!e.target){return;}
569
+ elem = $(e.target).getNativeElement()[0];
570
+ if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
571
+ timer = $.data(elem, 'webshimsswitchvalidityclass');
572
+ var switchClass = function(){
573
+ if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
574
+ var validity = $.prop(elem, 'validity');
575
+ var shadowElem = $(elem).getShadowElement();
576
+ var addClass, removeClass, trigger, generaltrigger, validityCause;
577
+
578
+ $(elem).trigger('refreshCustomValidityRules');
579
+ if(validity.valid){
580
+ if(!shadowElem.hasClass(validClass)){
581
+ addClass = validClasses;
582
+ removeClass = invalidClasses;
583
+ generaltrigger = 'changedvaliditystate';
584
+ trigger = 'changedvalid';
585
+ if(checkTypes[elem.type] && elem.checked){
586
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
587
+ }
588
+ $.removeData(elem, 'webshimsinvalidcause');
589
+ }
590
+ } else {
591
+ validityCause = returnValidityCause(validity, elem);
592
+ if($.data(elem, 'webshimsinvalidcause') != validityCause){
593
+ $.data(elem, 'webshimsinvalidcause', validityCause);
594
+ generaltrigger = 'changedvaliditystate';
595
+ }
596
+ if(!shadowElem.hasClass(invalidClass)){
597
+ addClass = invalidClasses;
598
+ removeClass = validClasses;
599
+ if (checkTypes[elem.type] && !elem.checked) {
600
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
601
+ }
602
+ trigger = 'changedinvalid';
603
+ }
604
+ }
605
+ if(addClass){
606
+ shadowElem.addClass(addClass).removeClass(removeClass);
607
+ //jQuery 1.6.1 IE9 bug (doubble trigger bug)
608
+ setTimeout(function(){
609
+ $(elem).trigger(trigger);
610
+ }, 0);
611
+ }
612
+ if(generaltrigger){
613
+ setTimeout(function(){
614
+ $(elem).trigger(generaltrigger);
615
+ }, 0);
616
+ }
617
+ $.removeData(e.target, 'webshimsswitchvalidityclass');
618
+ };
619
+
620
+ if(timer){
621
+ clearTimeout(timer);
622
+ }
623
+ if(e.type == 'refreshvalidityui'){
624
+ switchClass();
625
+ } else {
626
+ $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
627
+ }
628
+ };
629
+
630
+ $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
631
+ customEvents.changedvaliditystate = true;
632
+ customEvents.refreshCustomValidityRules = true;
633
+ customEvents.changedvalid = true;
634
+ customEvents.changedinvalid = true;
635
+ customEvents.refreshvalidityui = true;
636
+
637
+
638
+ webshims.triggerInlineForm = function(elem, event){
639
+ $(elem).trigger(event);
640
+ };
641
+
642
+ webshims.modules["form-core"].getGroupElements = getGroupElements;
643
+
644
+
645
+ var setRoot = function(){
646
+ webshims.scrollRoot = ($.browser.webkit || document.compatMode == 'BackCompat') ?
647
+ $(document.body) :
648
+ $(document.documentElement)
649
+ ;
650
+ };
651
+ setRoot();
652
+ webshims.ready('DOM', setRoot);
653
+
654
+ webshims.getRelOffset = function(posElem, relElem){
655
+ posElem = $(posElem);
656
+ var offset = $(relElem).offset();
657
+ var bodyOffset;
658
+ $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
659
+ bodyOffset = posElem.offset();
660
+ });
661
+ offset.top -= bodyOffset.top;
662
+ offset.left -= bodyOffset.left;
663
+ return offset;
664
+ };
665
+
666
+ /* some extra validation UI */
667
+ webshims.validityAlert = (function(){
668
+ var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label';
669
+ var errorBubble;
670
+ var hideTimer = false;
671
+ var focusTimer = false;
672
+ var resizeTimer = false;
673
+ var boundHide;
674
+
675
+ var api = {
676
+ hideDelay: 5000,
677
+
678
+ showFor: function(elem, message, noFocusElem, noBubble){
679
+ api._create();
680
+ elem = $(elem);
681
+ var visual = $(elem).getShadowElement();
682
+ var offset = api.getOffsetFromBody(visual);
683
+ api.clear();
684
+ if(noBubble){
685
+ this.hide();
686
+ } else {
687
+ this.getMessage(elem, message);
688
+ this.position(visual, offset);
689
+
690
+ this.show();
691
+ if(this.hideDelay){
692
+ hideTimer = setTimeout(boundHide, this.hideDelay);
693
+ }
694
+ $(window)
695
+ .on('resize.validityalert', function(){
696
+ clearTimeout(resizeTimer);
697
+ resizeTimer = setTimeout(function(){
698
+ api.position(visual);
699
+ }, 9);
700
+ })
701
+ ;
702
+ }
703
+
704
+ if(!noFocusElem){
705
+ this.setFocus(visual, offset);
706
+ }
707
+ },
708
+ getOffsetFromBody: function(elem){
709
+ return webshims.getRelOffset(errorBubble, elem);
710
+ },
711
+ setFocus: function(visual, offset){
712
+ var focusElem = $(visual).getShadowFocusElement();
713
+ var scrollTop = webshims.scrollRoot.scrollTop();
714
+ var elemTop = ((offset || focusElem.offset()).top) - 30;
715
+ var smooth;
716
+
717
+ if(webshims.getID && alertElem == 'label'){
718
+ errorBubble.attr('for', webshims.getID(focusElem));
719
+ }
720
+
721
+ if(scrollTop > elemTop){
722
+ webshims.scrollRoot.animate(
723
+ {scrollTop: elemTop - 5},
724
+ {
725
+ queue: false,
726
+ duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
727
+ }
728
+ );
729
+ smooth = true;
730
+ }
731
+ try {
732
+ focusElem[0].focus();
733
+ } catch(e){}
734
+ if(smooth){
735
+ webshims.scrollRoot.scrollTop(scrollTop);
736
+ setTimeout(function(){
737
+ webshims.scrollRoot.scrollTop(scrollTop);
738
+ }, 0);
739
+ }
740
+ setTimeout(function(){
741
+ $(document).on('focusout.validityalert', boundHide);
742
+ }, 10);
743
+ },
744
+ getMessage: function(elem, message){
745
+ if (!message) {
746
+ message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage');
747
+ }
748
+ if (message) {
749
+ $('span.va-box', errorBubble).text(message);
750
+ }
751
+ else {
752
+ this.hide();
753
+ }
754
+ },
755
+ position: function(elem, offset){
756
+ offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
757
+ offset.top += elem.outerHeight();
758
+ errorBubble.css(offset);
759
+ },
760
+ show: function(){
761
+ if(errorBubble.css('display') === 'none'){
762
+ errorBubble.css({opacity: 0}).show();
763
+ }
764
+ errorBubble.addClass('va-visible').fadeTo(400, 1);
765
+ },
766
+ hide: function(){
767
+ errorBubble.removeClass('va-visible').fadeOut();
768
+ },
769
+ clear: function(){
770
+ clearTimeout(focusTimer);
771
+ clearTimeout(hideTimer);
772
+ $(document).unbind('.validityalert');
773
+ $(window).unbind('.validityalert');
774
+ errorBubble.stop().removeAttr('for');
775
+ },
776
+ _create: function(){
777
+ if(errorBubble){return;}
778
+ 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'});
779
+ webshims.ready('DOM', function(){
780
+ errorBubble.appendTo('body');
781
+ if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){
782
+ errorBubble.bgIframe();
783
+ }
784
+ });
785
+ }
786
+ };
787
+
788
+
789
+ boundHide = $.proxy(api, 'hide');
790
+
791
+ return api;
792
+ })();
793
+
794
+
795
+ /* extension, but also used to fix native implementation workaround/bugfixes */
796
+ (function(){
797
+ var firstEvent,
798
+ invalids = [],
799
+ stopSubmitTimer,
800
+ form
801
+ ;
802
+
803
+ $(document).on('invalid', function(e){
804
+ if(e.wrongWebkitInvalid){return;}
805
+ var jElm = $(e.target);
806
+ var shadowElem = jElm.getShadowElement();
807
+ if(!shadowElem.hasClass(invalidClass)){
808
+ shadowElem.addClass(invalidClasses).removeClass(validClasses);
809
+ setTimeout(function(){
810
+ $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
811
+ }, 0);
812
+ }
813
+
814
+ if(!firstEvent){
815
+ //trigger firstinvalid
816
+ firstEvent = $.Event('firstinvalid');
817
+ firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
818
+ var firstSystemInvalid = $.Event('firstinvalidsystem');
819
+ $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
820
+ jElm.trigger(firstEvent);
821
+ }
822
+
823
+ //if firstinvalid was prevented all invalids will be also prevented
824
+ if( firstEvent && firstEvent.isDefaultPrevented() ){
825
+ e.preventDefault();
826
+ }
827
+ invalids.push(e.target);
828
+ e.extraData = 'fix';
829
+ clearTimeout(stopSubmitTimer);
830
+ stopSubmitTimer = setTimeout(function(){
831
+ var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
832
+ //reset firstinvalid
833
+ firstEvent = false;
834
+ invalids = [];
835
+ $(e.target).trigger(lastEvent, lastEvent);
836
+ }, 9);
837
+ jElm = null;
838
+ shadowElem = null;
839
+ });
840
+ })();
841
+
842
+ $.fn.getErrorMessage = function(){
843
+ var message = '';
844
+ var elem = this[0];
845
+ if(elem){
846
+ message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
847
+ }
848
+ return message;
849
+ };
850
+
851
+ if(options.replaceValidationUI){
852
+ webshims.ready('DOM forms', function(){
853
+ $(document).on('firstinvalid', function(e){
854
+ if(!e.isInvalidUIPrevented()){
855
+ e.preventDefault();
856
+ $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') );
857
+ }
858
+ });
859
+ });
860
+ }
861
+
862
+ });jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
863
+ "use strict";
864
+ var validityMessages = webshims.validityMessages;
865
+
866
+ var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
867
+
868
+ validityMessages['en'] = $.extend(true, {
869
+ typeMismatch: {
870
+ email: 'Please enter an email address.',
871
+ url: 'Please enter a URL.',
872
+ number: 'Please enter a number.',
873
+ date: 'Please enter a date.',
874
+ time: 'Please enter a time.',
875
+ range: 'Invalid input.',
876
+ "datetime-local": 'Please enter a datetime.'
877
+ },
878
+ rangeUnderflow: {
879
+ defaultMessage: 'Value must be greater than or equal to {%min}.'
880
+ },
881
+ rangeOverflow: {
882
+ defaultMessage: 'Value must be less than or equal to {%max}.'
883
+ },
884
+ stepMismatch: 'Invalid input.',
885
+ tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
886
+
887
+ patternMismatch: 'Invalid input. {%title}',
888
+ valueMissing: {
889
+ defaultMessage: 'Please fill out this field.',
890
+ checkbox: 'Please check this box if you want to proceed.'
891
+ }
892
+ }, (validityMessages['en'] || validityMessages['en-US'] || {}));
893
+
894
+
895
+ ['select', 'radio'].forEach(function(type){
896
+ validityMessages['en'].valueMissing[type] = 'Please select an option.';
897
+ });
898
+
899
+ ['date', 'time', 'datetime-local'].forEach(function(type){
900
+ validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
901
+ });
902
+ ['date', 'time', 'datetime-local'].forEach(function(type){
903
+ validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
904
+ });
905
+
906
+ validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
907
+ validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
908
+
909
+ validityMessages['de'] = $.extend(true, {
910
+ typeMismatch: {
911
+ email: '{%value} ist keine zulässige E-Mail-Adresse',
912
+ url: '{%value} ist keine zulässige Webadresse',
913
+ number: '{%value} ist keine Nummer!',
914
+ date: '{%value} ist kein Datum',
915
+ time: '{%value} ist keine Uhrzeit',
916
+ range: '{%value} ist keine Nummer!',
917
+ "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
918
+ },
919
+ rangeUnderflow: {
920
+ defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
921
+ },
922
+ rangeOverflow: {
923
+ defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
924
+ },
925
+ stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
926
+ tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
927
+ patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
928
+ valueMissing: {
929
+ defaultMessage: 'Bitte geben Sie einen Wert ein',
930
+ checkbox: 'Bitte aktivieren Sie das Kästchen'
931
+ }
932
+ }, (validityMessages['de'] || {}));
933
+
934
+ ['select', 'radio'].forEach(function(type){
935
+ validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
936
+ });
937
+
938
+ ['date', 'time', 'datetime-local'].forEach(function(type){
939
+ validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
940
+ });
941
+ ['date', 'time', 'datetime-local'].forEach(function(type){
942
+ validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
943
+ });
944
+
945
+ var currentValidationMessage = validityMessages[''];
946
+
947
+
948
+ webshims.createValidationMessage = function(elem, name){
949
+ var message = currentValidationMessage[name];
950
+ if(message && typeof message !== 'string'){
951
+ message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
952
+ }
953
+ if(message){
954
+ ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
955
+ if(message.indexOf('{%'+attr) === -1){return;}
956
+ var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
957
+ if(name == 'patternMismatch' && attr == 'title' && !val){
958
+ webshims.error('no title for patternMismatch provided. Always add a title attribute.');
959
+ }
960
+ message = message.replace('{%'+ attr +'}', val);
961
+ if('value' == attr){
962
+ message = message.replace('{%valueLen}', val.length);
963
+ }
964
+ });
965
+ }
966
+ return message || '';
967
+ };
968
+
969
+
970
+ if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
971
+ implementProperties.push('validationMessage');
972
+ }
973
+
974
+ webshims.activeLang({
975
+ langObj: validityMessages,
976
+ module: 'form-core',
977
+ callback: function(langObj){
978
+ currentValidationMessage = langObj;
979
+ }
980
+ });
981
+
982
+ implementProperties.forEach(function(messageProp){
983
+ webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
984
+ prop: {
985
+ value: '',
986
+ writeable: false
987
+ }
988
+ });
989
+ ['input', 'select', 'textarea'].forEach(function(nodeName){
990
+ var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
991
+ prop: {
992
+ get: function(){
993
+ var elem = this;
994
+ var message = '';
995
+ if(!$.prop(elem, 'willValidate')){
996
+ return message;
997
+ }
998
+
999
+ var validity = $.prop(elem, 'validity') || {valid: 1};
1000
+
1001
+ if(validity.valid){return message;}
1002
+ message = webshims.getContentValidationMessage(elem, validity);
1003
+
1004
+ if(message){return message;}
1005
+
1006
+ if(validity.customError && elem.nodeName){
1007
+ message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
1008
+ if(message){return message;}
1009
+ }
1010
+ $.each(validity, function(name, prop){
1011
+ if(name == 'valid' || !prop){return;}
1012
+
1013
+ message = webshims.createValidationMessage(elem, name);
1014
+ if(message){
1015
+ return false;
1016
+ }
1017
+ });
1018
+ return message || '';
1019
+ },
1020
+ writeable: false
1021
+ }
1022
+ });
1023
+ });
1024
+
1025
+ });
1078
1026
  });