webshims-rails 1.10.11 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +8 -8
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/readme.textile +14 -1
  4. data/vendor/assets/javascripts/webshims/polyfiller.js +2 -1
  5. data/vendor/assets/javascripts/webshims/shims/combos/1.js +12 -63
  6. data/vendor/assets/javascripts/webshims/shims/combos/10.js +17 -7
  7. data/vendor/assets/javascripts/webshims/shims/combos/11.js +17 -3
  8. data/vendor/assets/javascripts/webshims/shims/combos/12.js +11 -12
  9. data/vendor/assets/javascripts/webshims/shims/combos/13.js +11 -12
  10. data/vendor/assets/javascripts/webshims/shims/combos/14.js +0 -4
  11. data/vendor/assets/javascripts/webshims/shims/combos/15.js +10 -59
  12. data/vendor/assets/javascripts/webshims/shims/combos/16.js +21 -71
  13. data/vendor/assets/javascripts/webshims/shims/combos/17.js +17 -3
  14. data/vendor/assets/javascripts/webshims/shims/combos/18.js +17 -3
  15. data/vendor/assets/javascripts/webshims/shims/combos/19.js +58 -19
  16. data/vendor/assets/javascripts/webshims/shims/combos/2.js +12 -67
  17. data/vendor/assets/javascripts/webshims/shims/combos/20.js +58 -19
  18. data/vendor/assets/javascripts/webshims/shims/combos/21.js +47 -3
  19. data/vendor/assets/javascripts/webshims/shims/combos/23.js +11 -12
  20. data/vendor/assets/javascripts/webshims/shims/combos/24.js +324 -79
  21. data/vendor/assets/javascripts/webshims/shims/combos/25.js +63 -21
  22. data/vendor/assets/javascripts/webshims/shims/combos/26.js +5 -6
  23. data/vendor/assets/javascripts/webshims/shims/combos/27.js +5 -2
  24. data/vendor/assets/javascripts/webshims/shims/combos/28.js +47 -7
  25. data/vendor/assets/javascripts/webshims/shims/combos/3.js +1 -55
  26. data/vendor/assets/javascripts/webshims/shims/combos/30.js +1 -55
  27. data/vendor/assets/javascripts/webshims/shims/combos/31.js +1 -55
  28. data/vendor/assets/javascripts/webshims/shims/combos/4.js +0 -4
  29. data/vendor/assets/javascripts/webshims/shims/combos/5.js +17 -3
  30. data/vendor/assets/javascripts/webshims/shims/combos/6.js +17 -3
  31. data/vendor/assets/javascripts/webshims/shims/combos/7.js +12 -67
  32. data/vendor/assets/javascripts/webshims/shims/combos/8.js +12 -67
  33. data/vendor/assets/javascripts/webshims/shims/combos/9.js +17 -7
  34. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +0 -4
  35. data/vendor/assets/javascripts/webshims/shims/filereader.js +5 -2
  36. data/vendor/assets/javascripts/webshims/shims/form-core.js +1 -51
  37. data/vendor/assets/javascripts/webshims/shims/form-datalist-lazy.js +24 -15
  38. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +6 -2
  39. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +9 -4
  40. data/vendor/assets/javascripts/webshims/shims/form-validation.js +135 -24
  41. data/vendor/assets/javascripts/webshims/shims/form-validators.js +189 -55
  42. data/vendor/assets/javascripts/webshims/shims/forms-picker.js +4 -1
  43. data/vendor/assets/javascripts/webshims/shims/jpicker/jpicker.css +3 -1
  44. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +11 -12
  45. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +47 -3
  46. data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +28 -8
  47. data/vendor/assets/javascripts/webshims/shims/mediagroup.js +29 -0
  48. data/vendor/assets/javascripts/webshims/shims/range-ui.js +11 -1
  49. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +17 -4
  50. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +17 -6
  51. data/vendor/assets/javascripts/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
  52. metadata +3 -3
  53. data/vendor/assets/javascripts/webshims/shims/swf/jwwebshims.swf +0 -0
@@ -13,10 +13,6 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
13
13
  webshims.error("Webshims needs jQuery 1.8+ to work properly. Please update your jQuery version or downgrade webshims.");
14
14
  }
15
15
 
16
- if(webshims.cfg.extendNative === undefined){
17
- webshims.warn("extendNative configuration was set to false by default with this release. In case you rely on it set it to 'true' otherwise to 'false'. See http://bit.ly/16OOTQO");
18
- }
19
-
20
16
  if (!webshims.cfg.no$Switch) {
21
17
  var switch$ = function(){
22
18
  if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
@@ -1271,7 +1267,17 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1271
1267
  this.value(this.options.value, true);
1272
1268
  },
1273
1269
  step: function(val){
1274
- this.options.step = val == 'any' ? 'any' : retDefault(val, 1);
1270
+ var o = this.options;
1271
+ var step = val == 'any' ? 'any' : retDefault(val, 1);
1272
+
1273
+ if(o.stepping){
1274
+ if(step != 'any' && o.stepping % step){
1275
+ webshims.error('wrong stepping value for type range:'+ (o.stepping % step));
1276
+ } else {
1277
+ step = o.stepping;
1278
+ }
1279
+ }
1280
+ o.step = step;
1275
1281
  this.value(this.options.value);
1276
1282
  },
1277
1283
 
@@ -1992,6 +1998,8 @@ webshims.register('form-number-date-ui', function($, webshims, window, document,
1992
1998
  fVal[0] = tmp;
1993
1999
  }
1994
2000
  val = this.date(fVal[0], o) +'T'+ this.time(fVal[1], o);
2001
+ } else if (fVal.length == 3) {
2002
+ val = this.date(fVal[0], o) +'T'+ this.time(fVal[1]+fVal[2], o);
1995
2003
  }
1996
2004
  return val;
1997
2005
  },
@@ -2848,7 +2856,9 @@ webshims.register('form-number-date-ui', function($, webshims, window, document,
2848
2856
 
2849
2857
  picker._actions = {
2850
2858
  changeInput: function(val, popover, data){
2851
- picker._actions.cancel(val, popover, data);
2859
+ if(!data.options.noChangeDismiss){
2860
+ picker._actions.cancel(val, popover, data);
2861
+ }
2852
2862
  data.setChange(val);
2853
2863
  },
2854
2864
  cancel: function(val, popover, data){
@@ -3395,7 +3405,7 @@ webshims.register('form-number-date-ui', function($, webshims, window, document,
3395
3405
  });
3396
3406
  }
3397
3407
 
3398
- var isStupid = modernizrInputTypes.number && navigator.userAgent.indexOf('Touch') == -1 && (/MSIE 1[0|1]\.\d/.test(navigator.userAgent) || /Trident\/7\.0/.test(navigator.userAgent));
3408
+ var isStupid = modernizrInputTypes.number && navigator.userAgent.indexOf('Touch') == -1 && ((/MSIE 1[0|1]\.\d/.test(navigator.userAgent)) || (/Trident\/7\.0/.test(navigator.userAgent)));
3399
3409
  ['number', 'time', 'month', 'date', 'color', 'datetime-local'].forEach(function(name){
3400
3410
  if(!modernizrInputTypes[name] || options.replaceUI || (name == 'number' && isStupid)){
3401
3411
  extendType(name, {
@@ -13,10 +13,6 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
13
13
  webshims.error("Webshims needs jQuery 1.8+ to work properly. Please update your jQuery version or downgrade webshims.");
14
14
  }
15
15
 
16
- if(webshims.cfg.extendNative === undefined){
17
- webshims.warn("extendNative configuration was set to false by default with this release. In case you rely on it set it to 'true' otherwise to 'false'. See http://bit.ly/16OOTQO");
18
- }
19
-
20
16
  if (!webshims.cfg.no$Switch) {
21
17
  var switch$ = function(){
22
18
  if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
@@ -1,8 +1,11 @@
1
1
  webshims.register('filereader', function( $, webshims ){
2
2
  "use strict";
3
-
3
+ /**
4
+ * Code is based on https://github.com/Jahdrien/FileReader
5
+ *
6
+ */
4
7
  (function(){
5
- var swfobject = swfmini;
8
+ var swfobject = window.swfmini || window.swfobject;
6
9
 
7
10
  var readyCallbacks = $.Callbacks('once unique memory'),
8
11
  inputsCount = 0,
@@ -203,60 +203,10 @@ webshims.register('form-core', function($, webshims, window, document, undefined
203
203
 
204
204
 
205
205
  $(document).on('focusin.lazyloadvalidation', function(e){
206
- if('form' in e.target && $(e.target).is(':invalid')){
206
+ if('form' in e.target && (e.target.list || $(e.target).is(':invalid'))){
207
207
  lazyLoad();
208
208
  }
209
209
  });
210
210
  webshims.ready('WINDOWLOAD', lazyLoad);
211
211
 
212
- if(options.replaceValidationUI){
213
- webshims.ready('DOM forms', function(){
214
- $(document).on('firstinvalid', function(e){
215
- if(!e.isInvalidUIPrevented()){
216
- e.preventDefault();
217
- webshims.validityAlert.showFor( e.target );
218
- }
219
- });
220
- });
221
- }
222
-
223
- /* extension, but also used to fix native implementation workaround/bugfixes */
224
- (function(){
225
- var firstEvent,
226
- invalids = [],
227
- stopSubmitTimer,
228
- form
229
- ;
230
-
231
- $(document).on('invalid', function(e){
232
- if(e.wrongWebkitInvalid){return;}
233
- var jElm = $(e.target);
234
-
235
-
236
- if(!firstEvent){
237
- //trigger firstinvalid
238
- firstEvent = $.Event('firstinvalid');
239
- firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
240
- var firstSystemInvalid = $.Event('firstinvalidsystem');
241
- $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
242
- jElm.trigger(firstEvent);
243
- }
244
-
245
- //if firstinvalid was prevented all invalids will be also prevented
246
- if( firstEvent && firstEvent.isDefaultPrevented() ){
247
- e.preventDefault();
248
- }
249
- invalids.push(e.target);
250
- e.extraData = 'fix';
251
- clearTimeout(stopSubmitTimer);
252
- stopSubmitTimer = setTimeout(function(){
253
- var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
254
- //reset firstinvalid
255
- firstEvent = false;
256
- invalids = [];
257
- $(e.target).trigger(lastEvent, lastEvent);
258
- }, 9);
259
- jElm = null;
260
- });
261
- })();
262
212
  });
@@ -166,13 +166,11 @@ webshims.register('form-datalist-lazy', function($, webshims, window, document,
166
166
  if(window.QUnit || (forceShow = ($(that.input).is(':focus') && ($(that.input).hasClass('list-focus') || $.prop(that.input, 'value'))) )){
167
167
  that.updateListOptions(forceShow);
168
168
  } else {
169
- webshims.ready('WINDOWLOAD', function(){
170
- that.updateTimer = setTimeout(function(){
171
- that.updateListOptions();
172
- that = null;
173
- listidIndex = 1;
174
- }, 200 + (100 * listidIndex));
175
- });
169
+ that.updateTimer = setTimeout(function(){
170
+ that.updateListOptions();
171
+ that = null;
172
+ listidIndex = 1;
173
+ }, 200 + (100 * listidIndex));
176
174
  }
177
175
  }
178
176
  },
@@ -181,8 +179,11 @@ webshims.register('form-datalist-lazy', function($, webshims, window, document,
181
179
  clearTimeout(this.updateTimer);
182
180
  this.updateTimer = false;
183
181
 
184
- this.searchStart = formsCFG.customDatalist && $(this.input).hasClass('search-start');
182
+ if($(this.input).hasClass('ws-nosearch') || $(this.input).hasClass('search-start')){
183
+ webshims.error('please use listFilter/data-list-filer configuration with values: "*", "^" or "!"');
184
+ }
185
185
  this.addMarkElement = options.addMark || $(this.input).hasClass('mark-option-text');
186
+ this.listFilter = $(this.input).data('listFilter') || options.listFilter || '*';
186
187
 
187
188
  var list = [];
188
189
 
@@ -195,7 +196,8 @@ webshims.register('form-datalist-lazy', function($, webshims, window, document,
195
196
  rItem = {
196
197
  value: value.replace(lReg, '<').replace(gReg, '>'),
197
198
  label: $.trim($.attr(rElem, 'label')) || '',
198
- className: rElem.className || ''
199
+ className: rElem.className || '',
200
+ elem: options.getOptionContent ? rElem : null
199
201
  };
200
202
 
201
203
  if(rItem.label){
@@ -224,22 +226,29 @@ webshims.register('form-datalist-lazy', function($, webshims, window, document,
224
226
  this.arrayOptions = allOptions;
225
227
  this.popover.contentElement.html('<div class="datalist-box"><ul role="list">'+ list.join("\n") +'</ul></div>');
226
228
 
229
+ if(options.datalistCreated){
230
+ options.datalistCreated.apply(this);
231
+ }
227
232
 
228
233
  if(_forceShow || this.popover.isVisible){
229
234
  this.showHideOptions();
230
235
  }
231
236
  },
232
237
  getOptionContent: function(item){
233
- var content = '';
238
+ var content;
234
239
  if(options.getOptionContent){
235
- content = options.apply(this, arguments) || '';
236
- } else {
240
+ content = options.getOptionContent.apply(this, arguments);
241
+ if(content != null){
242
+ content += '<span class="option-value" style="display: none;">'+ item.value +'</span>'
243
+ }
244
+ }
245
+ if(content == null){
237
246
  content = '<span class="option-value">'+ item.value +'</span>';
238
247
  if(item.label){
239
248
  content += ' <span class="option-label">'+ item.label +'</span>';
240
249
  }
241
250
  }
242
- return content;
251
+ return content || '';
243
252
  },
244
253
  showHideOptions: function(_fromShowList){
245
254
  var value = $.prop(this.input, 'value').toLowerCase();
@@ -256,10 +265,10 @@ webshims.register('form-datalist-lazy', function($, webshims, window, document,
256
265
 
257
266
  this.lastUpdatedValue = value;
258
267
  var found = false;
259
- var startSearch = this.searchStart;
268
+ var startSearch = this.listFilter == '^';
260
269
  var lis = $('li', this.shadowList);
261
270
  var that = this;
262
- if(value){
271
+ if(value && this.listFilter != '!'){
263
272
 
264
273
  this.arrayOptions.forEach(function(item, i){
265
274
  var search, searchIndex, foundName;
@@ -402,6 +402,8 @@ webshims.register('form-number-date-ui', function($, webshims, window, document,
402
402
  fVal[0] = tmp;
403
403
  }
404
404
  val = this.date(fVal[0], o) +'T'+ this.time(fVal[1], o);
405
+ } else if (fVal.length == 3) {
406
+ val = this.date(fVal[0], o) +'T'+ this.time(fVal[1]+fVal[2], o);
405
407
  }
406
408
  return val;
407
409
  },
@@ -1258,7 +1260,9 @@ webshims.register('form-number-date-ui', function($, webshims, window, document,
1258
1260
 
1259
1261
  picker._actions = {
1260
1262
  changeInput: function(val, popover, data){
1261
- picker._actions.cancel(val, popover, data);
1263
+ if(!data.options.noChangeDismiss){
1264
+ picker._actions.cancel(val, popover, data);
1265
+ }
1262
1266
  data.setChange(val);
1263
1267
  },
1264
1268
  cancel: function(val, popover, data){
@@ -1805,7 +1809,7 @@ webshims.register('form-number-date-ui', function($, webshims, window, document,
1805
1809
  });
1806
1810
  }
1807
1811
 
1808
- var isStupid = modernizrInputTypes.number && navigator.userAgent.indexOf('Touch') == -1 && (/MSIE 1[0|1]\.\d/.test(navigator.userAgent) || /Trident\/7\.0/.test(navigator.userAgent));
1812
+ var isStupid = modernizrInputTypes.number && navigator.userAgent.indexOf('Touch') == -1 && ((/MSIE 1[0|1]\.\d/.test(navigator.userAgent)) || (/Trident\/7\.0/.test(navigator.userAgent)));
1809
1813
  ['number', 'time', 'month', 'date', 'color', 'datetime-local'].forEach(function(name){
1810
1814
  if(!modernizrInputTypes[name] || options.replaceUI || (name == 'number' && isStupid)){
1811
1815
  extendType(name, {
@@ -1331,6 +1331,7 @@ try {
1331
1331
  var isOver = (webshims.cfg.forms.placeholderType == 'over');
1332
1332
  var isResponsive = (webshims.cfg.forms.responsivePlaceholder);
1333
1333
  var polyfillElements = ['textarea'];
1334
+ var debug = webshims.debug !== false;
1334
1335
  if(!Modernizr.input.placeholder || bustedPlaceholder){
1335
1336
  polyfillElements.push('input');
1336
1337
  }
@@ -1421,6 +1422,11 @@ try {
1421
1422
  data = $.data(elem, 'placeHolder');
1422
1423
  if(!data){return;}
1423
1424
  }
1425
+ var isVisible = $(elem).hasClass('placeholder-visible');
1426
+ if(placeholderTxt === false){
1427
+ placeholderTxt = $.attr(elem, 'placeholder') || '';
1428
+ }
1429
+
1424
1430
  $(elem).unbind('.placeholderremove');
1425
1431
 
1426
1432
  if(value === false){
@@ -1428,7 +1434,7 @@ try {
1428
1434
  }
1429
1435
 
1430
1436
  if(!value && (type == 'focus' || (!type && $(elem).is(':focus')))){
1431
- if(elem.type == 'password' || isOver || $(elem).hasClass('placeholder-visible')){
1437
+ if(elem.type == 'password' || isOver || isVisible){
1432
1438
  hidePlaceholder(elem, data, '', true);
1433
1439
  }
1434
1440
  return;
@@ -1438,9 +1444,7 @@ try {
1438
1444
  hidePlaceholder(elem, data, value);
1439
1445
  return;
1440
1446
  }
1441
- if(placeholderTxt === false){
1442
- placeholderTxt = $.attr(elem, 'placeholder') || '';
1443
- }
1447
+
1444
1448
  if(placeholderTxt && !value){
1445
1449
  showPlaceholder(elem, data, placeholderTxt);
1446
1450
  } else {
@@ -1548,6 +1552,7 @@ try {
1548
1552
  var reset = function(e){
1549
1553
  if($(elem).hasClass('placeholder-visible')){
1550
1554
  hidePlaceholder(elem, data, '');
1555
+
1551
1556
  setTimeout(function(){
1552
1557
  if(!e || e.type != 'submit' || e.isDefaultPrevented()){
1553
1558
  changePlaceholderVisibility(elem, false, false, data );
@@ -4,6 +4,10 @@ webshims.register('form-validation', function($, webshims, window, document, und
4
4
  var webkitVersion = chromeBugs && parseFloat((navigator.userAgent.match(/Safari\/([\d\.]+)/) || ['', '999999'])[1], 10);
5
5
  var invalidClass = options.iVal.errorClass || 'user-error';
6
6
  var validClass = options.iVal.successClass || 'user-success';
7
+
8
+ var invalidWrapperClass = options.iVal.errorWrapperClass || 'ws-invalid';
9
+ var successWrapperClass = options.iVal.successWrapperClass || 'ws-success';
10
+ var errorBoxClass = options.iVal.errorBoxClass || 'ws-errorbox';
7
11
  var checkTypes = {checkbox: 1, radio: 1};
8
12
 
9
13
  var emptyJ = $([]);
@@ -93,13 +97,18 @@ webshims.register('form-validation', function($, webshims, window, document, und
93
97
  ){
94
98
  return;
95
99
  }
100
+ if(webshims.refreshCustomValidityRules){
101
+ if(webshims.refreshCustomValidityRules(elem) == 'async'){
102
+ $(elem).one('refreshvalidityui', switchValidityClass);
103
+ return;
104
+ }
105
+ }
106
+
96
107
  var validity = $.prop(elem, 'validity');
97
108
 
98
109
  var addClass, removeClass, trigger, generaltrigger, validityCause;
99
110
 
100
- if(webshims.refreshCustomValidityRules){
101
- webshims.refreshCustomValidityRules(elem);
102
- }
111
+
103
112
 
104
113
  if(validity.valid){
105
114
  if(!shadowElem.hasClass(validClass)){
@@ -457,10 +466,10 @@ webshims.register('form-validation', function($, webshims, window, document, und
457
466
  if(!fieldWrapper){
458
467
  fieldWrapper = this.getFieldWrapper(elem);
459
468
  }
460
- var errorBox = $('div.ws-errorbox', fieldWrapper);
469
+ var errorBox = $('div.'+errorBoxClass, fieldWrapper);
461
470
 
462
471
  if(!errorBox.length){
463
- errorBox = $('<div class="ws-errorbox" hidden="hidden">');
472
+ errorBox = $('<div class="'+ errorBoxClass +'" hidden="hidden">');
464
473
  fieldWrapper.append(errorBox);
465
474
  }
466
475
 
@@ -481,6 +490,48 @@ webshims.register('form-validation', function($, webshims, window, document, und
481
490
  }
482
491
  return fieldWrapper;
483
492
  },
493
+ _createContentMessage: (function(){
494
+ var fields = {};
495
+ var getErrorName = function(elem){
496
+ var ret = $(elem).data('errortype');
497
+ if(!ret){
498
+ $.each(fields, function(errorName, cNames){
499
+ if($(elem).is(cNames)){
500
+ ret = errorName;
501
+ return false;
502
+ }
503
+ });
504
+ }
505
+ return ret || 'defaultMessage';
506
+ };
507
+ $(function(){
508
+ $.each($('<input />').prop('validity'), function(name){
509
+ if(name != 'valid'){
510
+ var cName = name.replace(/[A-Z]/, function(c){
511
+ return '-'+(c).toLowerCase();
512
+ });
513
+ fields[name] = '.'+cName+', .'+name+', .'+(name).toLowerCase()+', [data-errortype="'+ name +'"]';
514
+ }
515
+ });
516
+ });
517
+ return function(elem, errorBox){
518
+ var extended = false;
519
+ var errorMessages = $(elem).data('errormessage') || {};
520
+ if(typeof errorMessages == 'string'){
521
+ errorMessages = {defaultMessage: errorMessages};
522
+ }
523
+ $('> *', errorBox).each(function(){
524
+ var name = getErrorName(this);
525
+ if(!errorMessages[name]){
526
+ extended = true;
527
+ errorMessages[name] = $(this).html();
528
+ }
529
+ });
530
+ if(extended){
531
+ $(elem).data('errormessage', errorMessages);
532
+ }
533
+ };
534
+ })(),
484
535
  get: function(elem, fieldWrapper){
485
536
  if(!fieldWrapper){
486
537
  fieldWrapper = this.getFieldWrapper(elem);
@@ -488,9 +539,11 @@ webshims.register('form-validation', function($, webshims, window, document, und
488
539
  var errorBox = fieldWrapper.data('errorbox');
489
540
  if(!errorBox){
490
541
  errorBox = this.create(elem, fieldWrapper);
542
+ this._createContentMessage(elem, errorBox);
491
543
  } else if(typeof errorBox == 'string'){
492
544
  errorBox = $('#'+errorBox);
493
545
  fieldWrapper.data('errorbox', errorBox);
546
+ this._createContentMessage(elem, errorBox);
494
547
  }
495
548
  return errorBox;
496
549
  },
@@ -498,7 +551,7 @@ webshims.register('form-validation', function($, webshims, window, document, und
498
551
  var type = $.prop(elem, 'type');
499
552
  var check = function(){
500
553
  var hasVal = checkTypes[type] ? $.prop(elem, 'checked') : $(elem).val();
501
- fieldWrapper[hasVal ? 'addClass' : 'removeClass']('ws-success');
554
+ fieldWrapper[hasVal ? 'addClass' : 'removeClass'](successWrapperClass);
502
555
  };
503
556
  var evt = changeTypes[type] ? 'change' : 'blur';
504
557
 
@@ -507,13 +560,13 @@ webshims.register('form-validation', function($, webshims, window, document, und
507
560
  },
508
561
  hideError: function(elem, reset){
509
562
  var fieldWrapper = this.getFieldWrapper(elem);
510
- var errorBox = fieldWrapper.data('errorbox');
563
+ var errorBox = fieldWrapper.hasClass(invalidWrapperClass) ? this.get(elem, fieldWrapper) : fieldWrapper.data('errorbox');
511
564
 
512
565
  if(errorBox && errorBox.jquery){
513
- fieldWrapper.removeClass('ws-invalid');
566
+ fieldWrapper.removeClass(invalidWrapperClass);
514
567
  errorBox.message = '';
515
568
  $(elem).filter('input').off('.recheckinvalid');
516
- errorBox.slideUp(function(){
569
+ errorBox[fx[options.iVal.fx].hide](function(){
517
570
  $(this).attr({hidden: 'hidden'});
518
571
  });
519
572
  }
@@ -528,21 +581,28 @@ webshims.register('form-validation', function($, webshims, window, document, und
528
581
  var throttle = function(){
529
582
  switchValidityClass({type: 'input', target: input});
530
583
  };
531
- $(input).filter('input:not([type="checkbox"], [type="radio"])').off('.recheckinvalid').on('input.recheckinvalid', function(){
532
- clearTimeout(timer);
533
- timer = setTimeout(throttle, options.iVal.recheckDelay);
534
- });
584
+ $(input)
585
+ .filter('input:not([type="checkbox"], [type="radio"])')
586
+ .off('.recheckinvalid')
587
+ .on('input.recheckinvalid', function(){
588
+ clearTimeout(timer);
589
+ timer = setTimeout(throttle, options.iVal.recheckDelay);
590
+ })
591
+ .on('focusout.recheckinvalid', function(){
592
+ clearTimeout(timer);
593
+ })
594
+ ;
535
595
  }
536
596
  },
537
- showError: function(elem, message){
597
+ showError: function(elem){
538
598
  var fieldWrapper = this.getFieldWrapper(elem);
539
599
  var box = this.get(elem, fieldWrapper);
540
-
600
+ var message = $(elem).getErrorMessage();
541
601
  if(box.message != message){
542
602
  box.stop(true, true).html('<p>'+ message +'</p>');
543
603
  box.message = message;
544
- fieldWrapper.addClass('ws-invalid').removeClass('ws-success');
545
- if(box.is('[hidden]')){
604
+ fieldWrapper.addClass(invalidWrapperClass).removeClass(successWrapperClass);
605
+ if(box.is('[hidden]') || box.css('display') == 'none'){
546
606
  this.recheckInvalidInput(elem);
547
607
  box
548
608
  .css({display: 'none'})
@@ -551,20 +611,19 @@ webshims.register('form-validation', function($, webshims, window, document, und
551
611
  ;
552
612
  }
553
613
  }
554
- fieldWrapper.removeClass('ws-success');
614
+ fieldWrapper.removeClass(successWrapperClass);
555
615
  $(elem).off('.recheckvalid');
556
616
 
557
617
  return fieldWrapper;
558
618
  },
559
619
  reset: function(elem){
560
- this.hideError(elem, true).removeClass('ws-success');
620
+ this.hideError(elem, true).removeClass(successWrapperClass);
561
621
  },
562
622
  toggle: function(elem){
563
- var message = $(elem).getErrorMessage();
564
- if(message){
565
- this.showError(elem, message);
623
+ if($(elem).is(':invalid')){
624
+ this.showError(elem);
566
625
  } else {
567
- this.hideError(elem, message);
626
+ this.hideError(elem);
568
627
  }
569
628
  }
570
629
  };
@@ -599,7 +658,7 @@ webshims.register('form-validation', function($, webshims, window, document, und
599
658
  }
600
659
  },
601
660
  submit: function(e){
602
- if(options.iVal.sel && $(e.target).is(options.iVal.sel) && $.prop(e.target, 'noValidate') && !$(e.target).checkValidity()){
661
+ if(options.iVal.sel && !options.iVal.noSubmitCheck &&$(e.target).is(options.iVal.sel) && $.prop(e.target, 'noValidate') && !$(e.target).checkValidity()){
603
662
  e.stopImmediatePropagation();
604
663
  return false;
605
664
  }
@@ -609,6 +668,58 @@ webshims.register('form-validation', function($, webshims, window, document, und
609
668
 
610
669
  webshims.modules["form-core"].getGroupElements = getGroupElements;
611
670
 
671
+
672
+ if(options.replaceValidationUI){
673
+ webshims.ready('DOM forms', function(){
674
+ $(document).on('firstinvalid', function(e){
675
+ if(!e.isInvalidUIPrevented()){
676
+ e.preventDefault();
677
+ webshims.validityAlert.showFor( e.target );
678
+ }
679
+ });
680
+ });
681
+ }
682
+
683
+ /* extension, but also used to fix native implementation workaround/bugfixes */
684
+ (function(){
685
+ var firstEvent,
686
+ invalids = [],
687
+ stopSubmitTimer,
688
+ form
689
+ ;
690
+
691
+ $(document).on('invalid', function(e){
692
+ if(e.wrongWebkitInvalid){return;}
693
+ var jElm = $(e.target);
694
+
695
+
696
+ if(!firstEvent){
697
+ //trigger firstinvalid
698
+ firstEvent = $.Event('firstinvalid');
699
+ firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
700
+ var firstSystemInvalid = $.Event('firstinvalidsystem');
701
+ $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
702
+ jElm.trigger(firstEvent);
703
+ }
704
+
705
+ //if firstinvalid was prevented all invalids will be also prevented
706
+ if( firstEvent && firstEvent.isDefaultPrevented() ){
707
+ e.preventDefault();
708
+ }
709
+ invalids.push(e.target);
710
+ e.extraData = 'fix';
711
+ clearTimeout(stopSubmitTimer);
712
+ stopSubmitTimer = setTimeout(function(){
713
+ var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
714
+ //reset firstinvalid
715
+ firstEvent = false;
716
+ invalids = [];
717
+ $(e.target).trigger(lastEvent, [lastEvent]);
718
+ }, 9);
719
+ jElm = null;
720
+ });
721
+ })();
722
+
612
723
  //see: https://bugs.webkit.org/show_bug.cgi?id=113377
613
724
  if (chromeBugs && webkitVersion < 540) {
614
725
  (function(){