webshims-rails 1.10.11 → 1.11.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -476,6 +476,7 @@ var swfmini = function() {
476
476
  if(hasNative){
477
477
  var videoElem = document.createElement('video');
478
478
  Modernizr.videoBuffered = ('buffered' in videoElem);
479
+ Modernizr.mediaDefaultMuted = ('defaultMuted' in videoElem);
479
480
  supportsLoop = ('loop' in videoElem);
480
481
 
481
482
  webshims.capturingEvents(['play', 'playing', 'waiting', 'paused', 'ended', 'durationchange', 'loadedmetadata', 'canplay', 'volumechange']);
@@ -489,20 +490,15 @@ var swfmini = function() {
489
490
 
490
491
  if(!options.preferFlash){
491
492
  var noSwitch = {
492
- 1: 1,
493
- 2: 1
493
+ 1: 1
494
494
  };
495
495
  var switchOptions = function(e){
496
496
  var media, error, parent;
497
497
  if(!options.preferFlash &&
498
498
  ($(e.target).is('audio, video') || ((parent = e.target.parentNode) && $('source:last', parent)[0] == e.target)) &&
499
- (media = $(e.target).closest('audio, video')) && !noSwitch[(error = media.prop('error'))]
499
+ (media = $(e.target).closest('audio, video')) && (error = media.prop('error')) && !noSwitch[error.code]
500
500
  ){
501
- if(error == null){
502
- webshims.warn("There was an unspecified error on a mediaelement");
503
- return;
504
-
505
- }
501
+
506
502
  $(function(){
507
503
  if(hasSwf && !options.preferFlash){
508
504
  loadSwf();
@@ -514,7 +510,7 @@ var swfmini = function() {
514
510
  $('audio, video').each(function(){
515
511
  webshims.mediaelement.selectSource(this);
516
512
  });
517
- webshims.error("switching mediaelements option to 'preferFlash', due to an error with native player: "+e.target.src+" Mediaerror: "+ media.prop('error'));
513
+ webshims.error("switching mediaelements option to 'preferFlash', due to an error with native player: "+e.target.src+" Mediaerror: "+ media.prop('error')+ 'first error: '+ error);
518
514
  }
519
515
  }, 9);
520
516
  });
@@ -720,7 +716,7 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u
720
716
  if(src.indexOf('rtmp') === 0){
721
717
  return nodeName+'/rtmp';
722
718
  }
723
- src = src.split('?')[0].split('.');
719
+ src = src.split('?')[0].split('#')[0].split('.');
724
720
  src = src[src.length - 1];
725
721
  var mt;
726
722
 
@@ -839,7 +835,7 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u
839
835
  webshims.error('mediaelementError: '+ message);
840
836
  setTimeout(function(){
841
837
  if($(elem).data('mediaerror')){
842
- $(elem).trigger('mediaerror');
838
+ $(elem).addClass('media-error').trigger('mediaerror');
843
839
  }
844
840
  }, 1);
845
841
  }
@@ -903,6 +899,7 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u
903
899
  var parent = elem.parentNode;
904
900
 
905
901
  clearTimeout(baseData.loadTimer);
902
+ $(elem).removeClass('media-error');
906
903
  $.data(elem, 'mediaerror', false);
907
904
 
908
905
  if(!_srces.length || !parent || parent.nodeType != 1 || stopParent.test(parent.nodeName || '')){return;}
@@ -930,7 +927,9 @@ webshims.register('mediaelement-core', function($, webshims, window, document, u
930
927
  var testFixMedia = function(){
931
928
  if(webshims.implement(this, 'mediaelement')){
932
929
  selectSource(this);
933
-
930
+ if(!Modernizr.mediaDefaultMuted && $.attr(this, 'muted') != null){
931
+ $.prop(this, 'muted', true);
932
+ }
934
933
  //fixes for FF 12 and IE9/10 || does not hurt, if run in other browsers
935
934
  if(hasNative && (!supportsLoop || ('ActiveXObject' in window))){
936
935
  var bufferTimer;
@@ -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(){
@@ -649,7 +760,16 @@ webshims.register('form-validators', function($, webshims, window, document, und
649
760
  var onEventTest = function(e){
650
761
  webshims.refreshCustomValidityRules(e.target);
651
762
  };
652
-
763
+ var noValidate = function(){
764
+ return !noValidate.types[this.type];
765
+ };
766
+ noValidate.types = {
767
+ hidden: 1,
768
+ image: 1,
769
+ button: 1,
770
+ reset: 1,
771
+ submit: 1
772
+ };
653
773
 
654
774
  webshims.customErrorMessages = {};
655
775
  webshims.addCustomValidityRule = function(name, test, defaultMessage){
@@ -658,68 +778,78 @@ webshims.register('form-validators', function($, webshims, window, document, und
658
778
  webshims.customErrorMessages[name] = [];
659
779
  webshims.customErrorMessages[name][''] = defaultMessage || name;
660
780
  }
661
- if($.isReady && formReady){
662
- $('input, select, textarea').each(function(){
663
- testValidityRules(this);
664
- });
781
+ if(formReady){
782
+ $('input, select, textarea')
783
+ .filter(noValidate)
784
+ .each(function(){
785
+ testValidityRules(this);
786
+ })
787
+ ;
665
788
  }
666
789
  };
667
790
  webshims.refreshCustomValidityRules = function(elem){
668
- if(!elem.form || (!initTest && !$.prop(elem, 'willValidate')) ){return;}
669
- blockCustom = true;
670
- var customMismatchedRule = $.data(elem, 'customMismatchedRule');
791
+ if(!initTest){return;}
792
+
793
+ var data = $(elem).data() || $.data(elem, {});
794
+ var customMismatchedRule = data.customMismatchedRule;
671
795
  var validity = $.prop(elem, 'validity') || {};
672
796
  var message = '';
673
- if(customMismatchedRule || !validity.customError){
797
+ var setMessage = function(message, errorType){
798
+ blockCustom = true;
799
+ data.customMismatchedRule = message ? errorType : '';
800
+
801
+ if(typeof message != 'string'){
802
+ message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || webshims.customErrorMessages[errorType][webshims.activeLang()] || webshims.customErrorMessages[errorType][''];
803
+ }
804
+
805
+ if(typeof message == 'object'){
806
+ message = message[errorType] || message.customError || message.defaultMessage;
807
+ }
808
+ $(elem).setCustomValidity(message);
809
+ blockCustom = false;
810
+ };
811
+ if(customMismatchedRule || validity.valid || (data.dependentValidation && !data.dependentValidation._init)){
674
812
  var val = $(elem).val();
675
813
  $.each(customValidityRules, function(name, test){
676
- message = test(elem, val) || '';
814
+ message = test(elem, val, data, setMessage) || '';
677
815
  customMismatchedRule = name;
678
816
  if(message){
679
-
680
- if(typeof message != 'string'){
681
- message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || webshims.customErrorMessages[name][webshims.activeLang()] || webshims.customErrorMessages[name][''];
682
- }
683
-
684
- if(typeof message == 'object'){
685
- message = message[name] || message.customError || message.defaultMessage;
686
- }
687
817
  return false;
688
818
  }
689
819
  });
690
-
691
- if(message){
692
- $.data(elem, 'customMismatchedRule', customMismatchedRule);
820
+ if(message != 'async'){
821
+ setMessage(message, customMismatchedRule);
693
822
  }
694
- $(elem).setCustomValidity(message);
695
823
  }
696
- blockCustom = false;
824
+ return message;
697
825
  };
698
826
  var testValidityRules = webshims.refreshCustomValidityRules;
699
827
 
700
828
  webshims.ready('forms form-validation', function(){
701
829
 
702
-
703
- var oldCustomValidity = $.fn.setCustomValidity;
704
-
705
-
706
- $.fn.setCustomValidity = function(message){
707
- if(!blockCustom){
708
- this.data('customMismatchedRule', '');
830
+ $.propHooks.setCustomValidity = {
831
+ get: function(elem){
832
+ if(!blockCustom){
833
+ $.data(elem, 'customMismatchedRule', '');
834
+ }
835
+ return null;
709
836
  }
710
- return oldCustomValidity.apply(this, arguments);
711
837
  };
712
838
 
839
+
713
840
  setTimeout(function(){
714
841
  webshims.addReady(function(context, selfElement){
715
842
  initTest = true;
716
- $('input, select, textarea', context).add(selfElement.filter('input, select, textarea')).each(function(){
717
- testValidityRules(this);
718
- });
719
- initTest = false;
843
+ $('input, select, textarea', context).add(selfElement.filter('input, select, textarea'))
844
+ .filter(noValidate)
845
+ .each(function(){
846
+ testValidityRules(this);
847
+ })
848
+ ;
849
+
720
850
  formReady = true;
721
851
  });
722
- $(document).on('refreshCustomValidityRules change', onEventTest);
852
+ $(document).on('refreshCustomValidityRules', onEventTest);
723
853
  }, 9);
724
854
 
725
855
  });
@@ -737,17 +867,20 @@ webshims.register('form-validators', function($, webshims, window, document, und
737
867
  */
738
868
  (function(){
739
869
 
740
- var addCustomValidityRule = $.webshims.addCustomValidityRule;
741
- addCustomValidityRule('partialPattern', function(elem, val){
742
- if(!val || !elem.getAttribute('data-partial-pattern')){return;}
743
- var pattern = $(elem).data('partial-pattern');
744
- if(!pattern){return;}
870
+ var addCustomValidityRule = webshims.addCustomValidityRule;
871
+ var getId = function(name){
872
+ return document.getElementById(name);
873
+ };
874
+ addCustomValidityRule('partialPattern', function(elem, val, pattern){
875
+ pattern = pattern.partialPattern;
876
+ if(!val || !pattern){return;}
745
877
  return !(new RegExp('(' + pattern + ')', 'i').test(val));
746
878
  }, 'This format is not allowed here.');
747
879
 
748
- addCustomValidityRule('tooShort', function(elem, val){
749
- if(!val || !elem.getAttribute('data-minlength')){return;}
750
- return $(elem).data('minlength') > val.length;
880
+
881
+ addCustomValidityRule('tooShort', function(elem, val, data){
882
+ if(!val || !data.minlength){return;}
883
+ return data.minlength > val.length;
751
884
  }, 'Entered value is too short.');
752
885
 
753
886
  var groupTimer = {};
@@ -765,7 +898,7 @@ webshims.register('form-validators', function($, webshims, window, document, und
765
898
  .unbind('click.groupRequired')
766
899
  .bind('click.groupRequired', function(){
767
900
  checkboxes.filter('.group-required').each(function(){
768
- $.webshims.refreshCustomValidityRules(this);
901
+ webshims.refreshCustomValidityRules(this);
769
902
  });
770
903
  })
771
904
  ;
@@ -804,19 +937,16 @@ webshims.register('form-validators', function($, webshims, window, document, und
804
937
  var getGroupElements = function(elem) {
805
938
  return $(elem.form[elem.name]).filter('[type="radio"]');
806
939
  };
807
- $.webshims.ready('form-validation', function(){
808
- if($.webshims.modules){
809
- getGroupElements = $.webshims.modules["form-core"].getGroupElements || getGroupElements;
940
+ webshims.ready('form-validation', function(){
941
+ if(webshims.modules){
942
+ getGroupElements = webshims.modules["form-core"].getGroupElements || getGroupElements;
810
943
  }
811
944
  });
812
945
 
813
- addCustomValidityRule('dependent', function(elem, val){
814
-
815
- if( !elem.getAttribute('data-dependent-validation') ){return;}
816
-
817
- var data = $(elem).data('dependentValidation');
946
+ addCustomValidityRule('dependent', function(elem, val, data){
947
+ data = data.dependentValidation;
948
+ if( !data ){return;}
818
949
  var specialVal;
819
- if(!data){return;}
820
950
  var depFn = function(e){
821
951
  var val = $.prop(data.masterElement, data["from-prop"]);
822
952
  if(specialVal){
@@ -865,7 +995,7 @@ webshims.register('form-validators', function($, webshims, window, document, und
865
995
  $(data.masterElement.type === 'radio' && getGroupElements(data.masterElement) || data.masterElement).bind('change', depFn);
866
996
  } else {
867
997
  $(data.masterElement).bind('change', function(){
868
- $.webshims.refreshCustomValidityRules(elem);
998
+ webshims.refreshCustomValidityRules(elem);
869
999
  $(elem).getShadowElement().filter('.user-error, .user-success').trigger('refreshvalidityui');
870
1000
  });
871
1001
  }
@@ -879,6 +1009,121 @@ webshims.register('form-validators', function($, webshims, window, document, und
879
1009
  }
880
1010
 
881
1011
  }, 'The value of this field does not repeat the value of the other field');
1012
+
1013
+
1014
+ if(window.JSON){
1015
+ addCustomValidityRule('ajaxvalidate', function(elem, val, data){
1016
+ if(!val || !data.ajaxvalidate){return;}
1017
+ var opts;
1018
+ if(!data.remoteValidate){
1019
+ if(typeof data.ajaxvalidate == 'string'){
1020
+ data.ajaxvalidate = {url: data.ajaxvalidate, depends: $([])};
1021
+ } else {
1022
+ data.ajaxvalidate.depends = data.ajaxvalidate.depends ? $(data.ajaxvalidate.depends).map(getId) : $([]);
1023
+ }
1024
+
1025
+ data.ajaxvalidate.depends.on('refreshCustomValidityRules', function(){
1026
+ webshims.refreshCustomValidityRules(elem);
1027
+ });
1028
+
1029
+ opts = data.ajaxvalidate;
1030
+
1031
+ var remoteValidate = {
1032
+ ajaxLoading: false,
1033
+ restartAjax: false,
1034
+ message: 'async',
1035
+ cache: {},
1036
+ update: function(remoteData){
1037
+ if(this.ajaxLoading){
1038
+ this.restartAjax = remoteData;
1039
+ } else {
1040
+ this.restartAjax = false;
1041
+ this.ajaxLoading = true;
1042
+ $.ajax(
1043
+ $.extend({}, opts, {
1044
+ url: opts.url,
1045
+ dataType: 'json',
1046
+ depData: remoteData,
1047
+ data: opts.fullForm ?
1048
+ $(elem).jProp('form').serializeArray() :
1049
+ remoteData,
1050
+ success: this.getResponse,
1051
+ complete: this._complete
1052
+ })
1053
+ );
1054
+ }
1055
+ },
1056
+ _complete: function(){
1057
+ remoteValidate.ajaxLoading = false;
1058
+ if(remoteValidate.restartAjax){
1059
+ this.update(remoteValidate.restartAjax);
1060
+ }
1061
+ remoteValidate.restartAjax = false;
1062
+ },
1063
+ getResponse: function(data){
1064
+ var old = webshims.refreshCustomValidityRules;
1065
+ if(!data){
1066
+ data = {message: '', valid: true};
1067
+ } else if(typeof data == 'string'){
1068
+ data = JSON.parse(data);
1069
+ }
1070
+
1071
+ remoteValidate.message = ('message' in data) ? data.message : !data.valid;
1072
+ remoteValidate.lastMessage = remoteValidate.message;
1073
+ remoteValidate.blockUpdate = true;
1074
+ $(elem).triggerHandler('refreshvalidityui');
1075
+ remoteValidate.message = 'async';
1076
+ remoteValidate.blockUpdate = false;
1077
+ },
1078
+ getData: function(){
1079
+ var data;
1080
+ data = {};
1081
+ data[$.prop(elem, 'name') || $.prop(elem, 'id')] = $(elem).val();
1082
+ opts.depends.each(function(){
1083
+ if($(this).is(':invalid')){
1084
+ data = false;
1085
+ return false;
1086
+ }
1087
+ data[$.prop(this, 'name') || $.prop(this, 'id')] = $(this).val();
1088
+ });
1089
+ return data;
1090
+ },
1091
+ getTempMessage: function(){
1092
+ var message = 'async';
1093
+ var remoteData, dataStr;
1094
+ if(!data.remoteValidate.blockUpdate){
1095
+ remoteData = this.getData();
1096
+ if(!remoteData){
1097
+ message = '';
1098
+ } else {
1099
+ try {
1100
+ dataStr = JSON.stringify(remoteData);
1101
+ } catch(er){}
1102
+
1103
+ if(dataStr === this.lastString){
1104
+ message = this.ajaxLoading ? 'async' : this.lastMessage;
1105
+ } else {
1106
+ this.lastString = dataStr;
1107
+ this.lastMessage = 'async';
1108
+ clearTimeout(data.remoteValidate.timer);
1109
+ data.remoteValidate.timer = setTimeout(function(){
1110
+ data.remoteValidate.update(remoteData);
1111
+ }, 9);
1112
+ }
1113
+
1114
+ }
1115
+ } else {
1116
+ message = remoteValidate.message;
1117
+ }
1118
+ return message;
1119
+ }
1120
+ };
1121
+ data.remoteValidate = remoteValidate;
1122
+ }
1123
+
1124
+ return data.remoteValidate.getTempMessage();
1125
+ }, 'remote error');
1126
+ }
882
1127
  })();
883
1128
 
884
1129
  });