webshims-rails 1.10.3 → 1.10.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +8 -8
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/webshims/polyfiller.js +96 -73
  4. data/vendor/assets/javascripts/webshims/shims/color-picker.js +2415 -0
  5. data/vendor/assets/javascripts/webshims/shims/combos/1.js +248 -745
  6. data/vendor/assets/javascripts/webshims/shims/combos/10.js +771 -1206
  7. data/vendor/assets/javascripts/webshims/shims/combos/11.js +679 -1201
  8. data/vendor/assets/javascripts/webshims/shims/combos/12.js +46 -65
  9. data/vendor/assets/javascripts/webshims/shims/combos/13.js +45 -64
  10. data/vendor/assets/javascripts/webshims/shims/combos/14.js +94 -7
  11. data/vendor/assets/javascripts/webshims/shims/combos/15.js +557 -1189
  12. data/vendor/assets/javascripts/webshims/shims/combos/16.js +598 -1249
  13. data/vendor/assets/javascripts/webshims/shims/combos/17.js +697 -1208
  14. data/vendor/assets/javascripts/webshims/shims/combos/18.js +697 -1208
  15. data/vendor/assets/javascripts/webshims/shims/combos/19.js +145 -78
  16. data/vendor/assets/javascripts/webshims/shims/combos/2.js +472 -1280
  17. data/vendor/assets/javascripts/webshims/shims/combos/20.js +144 -77
  18. data/vendor/assets/javascripts/webshims/shims/combos/21.js +14 -15
  19. data/vendor/assets/javascripts/webshims/shims/combos/22.js +2 -2
  20. data/vendor/assets/javascripts/webshims/shims/combos/23.js +45 -64
  21. data/vendor/assets/javascripts/webshims/shims/combos/24.js +848 -0
  22. data/vendor/assets/javascripts/webshims/shims/combos/25.js +4373 -0
  23. data/vendor/assets/javascripts/webshims/shims/combos/26.js +1516 -0
  24. data/vendor/assets/javascripts/webshims/shims/combos/27.js +884 -0
  25. data/vendor/assets/javascripts/webshims/shims/combos/28.js +2067 -0
  26. data/vendor/assets/javascripts/webshims/shims/combos/29.js +1156 -0
  27. data/vendor/assets/javascripts/webshims/shims/combos/3.js +313 -700
  28. data/vendor/assets/javascripts/webshims/shims/combos/30.js +1868 -0
  29. data/vendor/assets/javascripts/webshims/shims/combos/31.js +1663 -0
  30. data/vendor/assets/javascripts/webshims/shims/combos/4.js +111 -20
  31. data/vendor/assets/javascripts/webshims/shims/combos/5.js +747 -1321
  32. data/vendor/assets/javascripts/webshims/shims/combos/6.js +837 -1809
  33. data/vendor/assets/javascripts/webshims/shims/combos/7.js +435 -1239
  34. data/vendor/assets/javascripts/webshims/shims/combos/8.js +360 -766
  35. data/vendor/assets/javascripts/webshims/shims/combos/9.js +843 -1676
  36. data/vendor/assets/javascripts/webshims/shims/details.js +1 -1
  37. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +90 -3
  38. data/vendor/assets/javascripts/webshims/shims/filereader.js +386 -0
  39. data/vendor/assets/javascripts/webshims/shims/form-core.js +201 -680
  40. data/vendor/assets/javascripts/webshims/shims/form-datalist-lazy.js +418 -0
  41. data/vendor/assets/javascripts/webshims/shims/form-datalist.js +69 -467
  42. data/vendor/assets/javascripts/webshims/shims/form-message.js +21 -17
  43. data/vendor/assets/javascripts/webshims/shims/form-native-extend.js +19 -82
  44. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +17 -6
  45. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +570 -1185
  46. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +181 -28
  47. data/vendor/assets/javascripts/webshims/shims/form-validation.js +599 -0
  48. data/vendor/assets/javascripts/webshims/{extras/custom-validity.js → shims/form-validators.js} +33 -38
  49. data/vendor/assets/javascripts/webshims/shims/forms-picker.js +865 -0
  50. data/vendor/assets/javascripts/webshims/shims/geolocation.js +2 -2
  51. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-de.txt +37 -34
  52. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-en.txt +88 -48
  53. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-lt.js +74 -0
  54. data/vendor/assets/javascripts/webshims/shims/jpicker/ChangeLog.txt +121 -0
  55. data/vendor/assets/javascripts/webshims/shims/jpicker/ReadMe.txt +47 -0
  56. data/vendor/assets/javascripts/webshims/shims/jpicker/images/AlphaBar.png +0 -0
  57. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Bars.png +0 -0
  58. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Maps.png +0 -0
  59. data/vendor/assets/javascripts/webshims/shims/jpicker/images/NoColor.png +0 -0
  60. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Thumbs.db +0 -0
  61. data/vendor/assets/javascripts/webshims/shims/jpicker/images/bar-opacity.png +0 -0
  62. data/vendor/assets/javascripts/webshims/shims/jpicker/images/map-opacity.png +0 -0
  63. data/vendor/assets/javascripts/webshims/shims/jpicker/images/mappoint.gif +0 -0
  64. data/vendor/assets/javascripts/webshims/shims/jpicker/images/picker.gif +0 -0
  65. data/vendor/assets/javascripts/webshims/shims/jpicker/images/preview-opacity.png +0 -0
  66. data/vendor/assets/javascripts/webshims/shims/jpicker/images/rangearrows.gif +0 -0
  67. data/vendor/assets/javascripts/webshims/shims/jpicker/jpicker.css +257 -0
  68. data/vendor/assets/javascripts/webshims/shims/json-storage.js +4 -4
  69. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +44 -63
  70. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +10 -11
  71. data/vendor/assets/javascripts/webshims/shims/mediaelement-native-fix.js +2 -1
  72. data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +5 -3
  73. data/vendor/assets/javascripts/webshims/shims/range-ui.js +110 -17
  74. data/vendor/assets/javascripts/webshims/shims/styles/forms.png +0 -0
  75. data/vendor/assets/javascripts/webshims/shims/styles/range-track.png +0 -0
  76. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +104 -21
  77. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +90 -16
  78. data/vendor/assets/javascripts/webshims/shims/styles/vertical-range.png +0 -0
  79. data/vendor/assets/javascripts/webshims/shims/swf/filereader.swf +0 -0
  80. data/vendor/assets/javascripts/webshims/shims/swfmini.js +1 -1
  81. data/vendor/assets/javascripts/webshims/shims/track-ui.js +35 -3
  82. data/vendor/assets/javascripts/webshims/shims/track.js +1 -1
  83. metadata +33 -3
@@ -1,8 +1,8 @@
1
1
  //DOM-Extension helper
2
- jQuery.webshims.register('dom-extend', function($, webshims, window, document, undefined){
2
+ webshims.register('dom-extend', function($, webshims, window, document, undefined){
3
3
  "use strict";
4
4
 
5
- webshims.assumeARIA = Modernizr.localstorage || Modernizr.video || Modernizr.boxsizing;
5
+ webshims.assumeARIA = $.support.getSetAttribute || Modernizr.canvas || Modernizr.video || Modernizr.boxsizing;
6
6
 
7
7
  if($('<input type="email" />').attr('type') == 'text' || $('<form />').attr('novalidate') === "" || ('required' in $('<input />')[0].attributes)){
8
8
  webshims.error("IE browser modes are busted in IE10. Please test your HTML/CSS/JS with a real IE version or at least IETester or similiar tools");
@@ -11,6 +11,57 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
11
11
  if(!$.parseHTML){
12
12
  webshims.error("Webshims needs jQuery 1.8+ to work properly. Please update your jQuery version or downgrade webshims.");
13
13
  }
14
+ if (!webshims.cfg.no$Switch) {
15
+ var switch$ = function(){
16
+ if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
17
+ webshims.error("jQuery was included more than once. Make sure to include it only once! Webshims and other Plugins might not work properly.");
18
+ if (window.$) {
19
+ window.$ = webshims.$;
20
+ }
21
+ window.jQuery = webshims.$;
22
+ }
23
+ if(webshims.M != Modernizr){
24
+ webshims.error("Modernizr was included more than once. Make sure to include it only once! Webshims and other scripts might not work properly.");
25
+ for(var i in Modernizr){
26
+ if(!(i in webshims.M)){
27
+ webshims.M[i] = Modernizr[i];
28
+ }
29
+ }
30
+ Modernizr = webshims.M;
31
+ }
32
+ };
33
+ switch$();
34
+ setTimeout(switch$, 90);
35
+ $(switch$);
36
+ }
37
+ // (function(){
38
+ // var hostNames = {
39
+ // 'afarkas.github.io': 1,
40
+ // localhost: 1,
41
+ // '127.0.0.1': 1
42
+ // };
43
+ //
44
+ // if( webshims.debug && (hostNames[location.hostname] || location.protocol == 'file:') ){
45
+ // var list = $('<ul class="webshims-debug-list" />');
46
+ // webshims.errorLog.push = function(message){
47
+ // list.appendTo('body');
48
+ // $('<li style="display: none;">'+ message +'</li>')
49
+ // .appendTo(list)
50
+ // .slideDown()
51
+ // .delay(3000)
52
+ // .slideUp(function(){
53
+ // $(this).remove();
54
+ // if(!$('li', list).length){
55
+ // list.detach();
56
+ // }
57
+ // })
58
+ // ;
59
+ // };
60
+ // $.each(webshims.errorLog, function(i, message){
61
+ // webshims.errorLog.push(message);
62
+ // });
63
+ // }
64
+ // })();
14
65
 
15
66
  //shortcus
16
67
  var modules = webshims.modules;
@@ -28,6 +79,24 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
28
79
  return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val);
29
80
  };
30
81
 
82
+ //jquery mobile and jquery ui
83
+ if(!$.widget){
84
+ (function(){
85
+ var _cleanData = $.cleanData;
86
+ $.cleanData = function( elems ) {
87
+ if(!$.widget){
88
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
89
+ try {
90
+ $( elem ).triggerHandler( "remove" );
91
+ // http://bugs.jquery.com/ticket/8235
92
+ } catch( e ) {}
93
+ }
94
+ }
95
+ _cleanData( elems );
96
+ };
97
+ })();
98
+ }
99
+
31
100
 
32
101
  $.fn.val = function(val){
33
102
  var elem = this[0];
@@ -61,6 +130,18 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
61
130
  return this.on(evt, fn).each(fn);
62
131
  };
63
132
 
133
+ $.fn.onWSOff = function(evt, fn, trigger, evtDel){
134
+ if(!evtDel){
135
+ evtDel = document;
136
+ }
137
+ $(evtDel)[trigger ? 'onTrigger' : 'on'](evt, fn);
138
+ this.on('remove', function(e){
139
+ if(!e.originalEvent){
140
+ $(evtDel).off(evt, fn);
141
+ }
142
+ });
143
+ };
144
+
64
145
  var dataID = '_webshimsLib'+ (Math.round(Math.random() * 1000));
65
146
  var elementData = function(elem, key, val){
66
147
  elem = elem.jquery ? elem[0] : elem;
@@ -422,7 +503,7 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
422
503
  implement: function(elem, type){
423
504
  var data = elementData(elem, 'implemented') || elementData(elem, 'implemented', {});
424
505
  if(data[type]){
425
- webshims.info(type +' already implemented for element #'+elem.id);
506
+ webshims.warn(type +' already implemented for element #'+elem.id);
426
507
  return false;
427
508
  }
428
509
  data[type] = true;
@@ -566,6 +647,12 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
566
647
  shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData);
567
648
  }
568
649
 
650
+ $(nativeElem).on('remove', function(e){
651
+ if (!e.originalEvent) {
652
+ $(shadowElem).remove();
653
+ }
654
+ });
655
+
569
656
  nativeData.hasShadow = shadowElem;
570
657
  shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem;
571
658
  shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = {
@@ -1041,32 +1128,9 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1041
1128
 
1042
1129
  })(jQuery, document);
1043
1130
 
1044
- //additional tests for partial implementation of forms features
1045
- (function($){
1131
+ webshims.register('form-core', function($, webshims, window, document, undefined, options){
1046
1132
  "use strict";
1047
- var isWebkit = 'webkitURL' in window;
1048
- var Modernizr = window.Modernizr;
1049
- var webshims = $.webshims;
1050
- var bugs = webshims.bugs;
1051
- var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input required="" name="a" /></form>');
1052
- var testRequiredFind = function(){
1053
- if(form[0].querySelector){
1054
- try {
1055
- bugs.findRequired = !(form[0].querySelector('select:required'));
1056
- } catch(er){
1057
- bugs.findRequired = false;
1058
- }
1059
- }
1060
- };
1061
- var inputElem = $('input', form).eq(0);
1062
- var onDomextend = function(fn){
1063
- webshims.loader.loadList(['dom-extend']);
1064
- webshims.ready('dom-extend', fn);
1065
- };
1066
-
1067
- bugs.findRequired = false;
1068
- bugs.validationMessage = false;
1069
-
1133
+
1070
1134
  webshims.capturingEventPrevented = function(e){
1071
1135
  if(!e._isPolyfilled){
1072
1136
  var isDefaultPrevented = e.isDefaultPrevented;
@@ -1085,195 +1149,258 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1085
1149
  }
1086
1150
  };
1087
1151
 
1088
- if(!Modernizr.formvalidation || bugs.bustedValidity){
1089
- testRequiredFind();
1090
- } else {
1152
+ if(Modernizr.formvalidation && !webshims.bugs.bustedValidity){
1091
1153
  //create delegatable events
1092
1154
  webshims.capturingEvents(['invalid'], true);
1093
-
1094
- if(window.opera || window.testGoodWithFix){
1095
-
1096
- form.appendTo('head');
1097
-
1098
- testRequiredFind();
1099
- bugs.validationMessage = !(inputElem.prop('validationMessage'));
1100
-
1101
- webshims.reTest(['form-native-extend', 'form-message']);
1155
+ }
1156
+
1157
+ var isValid = function(elem){
1158
+ return ($.prop(elem, 'validity') || {valid: 1}).valid;
1159
+ };
1160
+ var lazyLoad = function(){
1161
+ var toLoad = ['form-validation'];
1162
+ if(options.lazyCustomMessages){
1163
+ options.customMessages = true;
1164
+ toLoad.push('form-message');
1165
+ }
1166
+ if(options.addValidators){
1167
+ toLoad.push('form-validators');
1168
+ }
1169
+ webshims.reTest(toLoad);
1170
+ $(document).off('.lazyloadvalidation');
1171
+ };
1172
+ /*
1173
+ * Selectors for all browsers
1174
+ */
1175
+ var hasInvalid = function(elem){
1176
+ var ret = false;
1177
+ $(elem).jProp('elements').each(function(){
1178
+ ret = $(this).is(':invalid');
1179
+ if(ret){
1180
+ return false;
1181
+ }
1182
+ });
1183
+ return ret;
1184
+ };
1185
+ var rElementsGroup = /^(?:form)$/i;///^(?:form|fieldset)$/i
1186
+ $.extend($.expr[":"], {
1187
+ "valid-element": function(elem){
1188
+ return rElementsGroup.test(elem.nodeName || '') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
1189
+ },
1190
+ "invalid-element": function(elem){
1191
+ return rElementsGroup.test(elem.nodeName || '') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
1192
+ },
1193
+ "required-element": function(elem){
1194
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
1195
+ },
1196
+ "user-error": function(elem){
1197
+ return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
1198
+ },
1199
+ "optional-element": function(elem){
1200
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
1201
+ }
1202
+ });
1203
+
1204
+ ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
1205
+ $.expr[":"][name] = $.expr.filters[name+"-element"];
1206
+ });
1207
+
1208
+
1209
+ $.expr[":"].focus = function( elem ) {
1210
+ try {
1211
+ var doc = elem.ownerDocument;
1212
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
1213
+ } catch(e){}
1214
+ return false;
1215
+ };
1216
+
1217
+ webshims.triggerInlineForm = function(elem, event){
1218
+ $(elem).trigger(event);
1219
+ };
1220
+
1221
+ var lazyLoadProxy = function(obj, fn, args){
1222
+ lazyLoad();
1223
+ webshims.ready('form-validation', function(){
1224
+ obj[fn].apply(obj, args);
1225
+ });
1226
+ };
1227
+
1228
+
1229
+ webshims.wsPopover = {
1230
+ id: 0,
1231
+ _create: function(){
1232
+ this.options = $.extend({}, webshims.cfg.wspopover, this.options);
1233
+ this.id = webshims.wsPopover.id++;
1234
+ this.eventns = '.wsoverlay' + this.id;
1235
+ this.timers = {};
1236
+ this.element = $('<div class="ws-popover" tabindex="-1"><div class="ws-po-outerbox"><div class="ws-po-arrow"><div class="ws-po-arrowbox" /></div><div class="ws-po-box" /></div></div>');
1237
+ this.contentElement = $('.ws-po-box', this.element);
1238
+ this.lastElement = $([]);
1239
+ this.bindElement();
1240
+
1241
+ this.element.data('wspopover', this);
1102
1242
 
1103
- form.remove();
1104
-
1105
- $(function(){
1106
- onDomextend(function(){
1107
-
1108
- //Opera shows native validation bubbles in case of input.checkValidity()
1109
- // Opera 11.6/12 hasn't fixed this issue right, it's buggy
1110
- var preventDefault = function(e){
1111
- e.preventDefault();
1112
- };
1113
-
1114
- ['form', 'input', 'textarea', 'select'].forEach(function(name){
1115
- var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
1116
- prop: {
1117
- value: function(){
1118
- if (!webshims.fromSubmit) {
1119
- $(this).on('invalid.checkvalidity', preventDefault);
1120
- }
1121
-
1122
- webshims.fromCheckValidity = true;
1123
- var ret = desc.prop._supvalue.apply(this, arguments);
1124
- if (!webshims.fromSubmit) {
1125
- $(this).unbind('invalid.checkvalidity', preventDefault);
1126
- }
1127
- webshims.fromCheckValidity = false;
1128
- return ret;
1129
- }
1130
- }
1131
- });
1132
- });
1133
-
1134
- });
1243
+ },
1244
+ options: {},
1245
+ content: function(html){
1246
+ this.contentElement.html(html);
1247
+ },
1248
+ bindElement: function(){
1249
+ var that = this;
1250
+ var stopBlur = function(){
1251
+ that.stopBlur = false;
1252
+ };
1253
+ this.preventBlur = function(e){
1254
+ that.stopBlur = true;
1255
+ clearTimeout(that.timers.stopBlur);
1256
+ that.timers.stopBlur = setTimeout(stopBlur, 9);
1257
+ };
1258
+ this.element.on({
1259
+ 'mousedown': this.preventBlur
1135
1260
  });
1261
+ },
1262
+ show: function(){
1263
+ lazyLoadProxy(this, 'show', arguments);
1136
1264
  }
1137
-
1138
- if(isWebkit && !webshims.bugs.bustedValidity){
1139
- (function(){
1140
- var elems = /^(?:textarea|input)$/i;
1141
- var form = false;
1142
-
1143
- document.addEventListener('contextmenu', function(e){
1144
- if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
1145
- setTimeout(function(){
1146
- form = false;
1147
- }, 1);
1148
- }
1149
- }, false);
1150
-
1151
- $(window).on('invalid', function(e){
1152
- if(e.originalEvent && form && form == e.target.form){
1153
- e.wrongWebkitInvalid = true;
1154
- e.stopImmediatePropagation();
1155
- }
1156
- });
1157
-
1158
- })();
1265
+ };
1266
+
1267
+ /* some extra validation UI */
1268
+ webshims.validityAlert = {
1269
+ showFor: function(){
1270
+ lazyLoadProxy(this, 'showFor', arguments);
1159
1271
  }
1160
- }
1161
-
1162
- $.webshims.register('form-core', function($, webshims, window, document, undefined, options){
1272
+ };
1163
1273
 
1164
- var checkTypes = {checkbox: 1, radio: 1};
1165
- var emptyJ = $([]);
1166
- var bugs = webshims.bugs;
1167
- var getGroupElements = function(elem){
1168
- elem = $(elem);
1169
- var name;
1170
- var form;
1171
- var ret = emptyJ;
1172
- if(elem[0].type == 'radio'){
1173
- form = elem.prop('form');
1174
- name = elem[0].name;
1175
- if(!name){
1176
- ret = elem;
1177
- } else if(form){
1178
- ret = $(form[name]);
1179
- } else {
1180
- ret = $(document.getElementsByName(name)).filter(function(){
1181
- return !$.prop(this, 'form');
1182
- });
1183
- }
1184
- ret = ret.filter('[type="radio"]');
1185
- }
1186
- return ret;
1187
- };
1274
+
1275
+ /* extension, but also used to fix native implementation workaround/bugfixes */
1276
+ (function(){
1277
+ var firstEvent,
1278
+ invalids = [],
1279
+ stopSubmitTimer,
1280
+ form
1281
+ ;
1188
1282
 
1189
- var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
1190
- var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
1191
- if(key && message[key]){
1192
- message = message[key];
1193
- }
1194
- if(typeof message == 'object'){
1195
- validity = validity || $.prop(elem, 'validity') || {valid: 1};
1196
- if(!validity.valid){
1197
- $.each(validity, function(name, prop){
1198
- if(prop && name != 'valid' && message[name]){
1199
- message = message[name];
1200
- return false;
1201
- }
1202
- });
1203
- }
1204
- }
1283
+ $(document).on('invalid', function(e){
1284
+ if(e.wrongWebkitInvalid){return;}
1285
+ var jElm = $(e.target);
1286
+
1205
1287
 
1206
- if(typeof message == 'object'){
1207
- message = message.defaultMessage;
1288
+ if(!firstEvent){
1289
+ //trigger firstinvalid
1290
+ firstEvent = $.Event('firstinvalid');
1291
+ firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
1292
+ var firstSystemInvalid = $.Event('firstinvalidsystem');
1293
+ $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
1294
+ jElm.trigger(firstEvent);
1208
1295
  }
1209
- return message || '';
1210
- };
1296
+
1297
+ //if firstinvalid was prevented all invalids will be also prevented
1298
+ if( firstEvent && firstEvent.isDefaultPrevented() ){
1299
+ e.preventDefault();
1300
+ }
1301
+ invalids.push(e.target);
1302
+ e.extraData = 'fix';
1303
+ clearTimeout(stopSubmitTimer);
1304
+ stopSubmitTimer = setTimeout(function(){
1305
+ var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
1306
+ //reset firstinvalid
1307
+ firstEvent = false;
1308
+ invalids = [];
1309
+ $(e.target).trigger(lastEvent, lastEvent);
1310
+ }, 9);
1311
+ jElm = null;
1312
+ });
1313
+ })();
1314
+
1315
+
1316
+ webshims.getContentValidationMessage = function(elem, validity, key){
1317
+ var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
1318
+ if(key && message[key]){
1319
+ message = message[key];
1320
+ }
1321
+ if(typeof message == 'object'){
1322
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
1323
+ if(!validity.valid){
1324
+ $.each(validity, function(name, prop){
1325
+ if(prop && name != 'valid' && message[name]){
1326
+ message = message[name];
1327
+ return false;
1328
+ }
1329
+ });
1330
+ }
1331
+ }
1211
1332
 
1212
- /*
1213
- * Selectors for all browsers
1214
- */
1215
- var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
1216
- var hasInvalid = function(elem){
1217
- var ret = false;
1218
- $($.prop(elem, 'elements')).each(function(){
1219
- ret = $(this).is(':invalid');
1220
- if(ret){
1221
- return false;
1222
- }
1223
- });
1224
- return ret;
1225
- };
1226
- $.extend($.expr[":"], {
1227
- "valid-element": function(elem){
1228
- return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
1229
- },
1230
- "invalid-element": function(elem){
1231
- return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
1232
- },
1233
- "required-element": function(elem){
1234
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
1235
- },
1236
- "user-error": function(elem){
1237
- return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
1238
- },
1239
- "optional-element": function(elem){
1240
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
1241
- },
1242
- "in-range": function(elem){
1243
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
1244
- return false;
1245
- }
1246
- var val = $.prop(elem, 'validity');
1247
- return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
1248
- },
1249
- "out-of-range": function(elem){
1250
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
1251
- return false;
1252
- }
1253
- var val = $.prop(elem, 'validity');
1254
- return !!(val && (val.rangeOverflow || val.rangeUnderflow));
1333
+ if(typeof message == 'object'){
1334
+ message = message.defaultMessage;
1335
+ }
1336
+ return message || '';
1337
+ };
1338
+
1339
+ $.fn.getErrorMessage = function(key){
1340
+ var message = '';
1341
+ var elem = this[0];
1342
+ if(elem){
1343
+ message = webshims.getContentValidationMessage(elem, false, key) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
1344
+ }
1345
+ return message;
1346
+ };
1347
+
1348
+
1349
+ webshims.ready('forms', function(){
1350
+ $(document).on('focusin.lazyloadvalidation', function(e){
1351
+ if('form' in e.target && $(e.target).is(':invalid')){
1352
+ lazyLoad();
1255
1353
  }
1256
-
1257
1354
  });
1258
-
1259
- ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
1260
- $.expr[":"][name] = $.expr.filters[name+"-element"];
1355
+ });
1356
+ webshims.ready('WINDOWLOAD', lazyLoad);
1357
+ if(options.overrideMessages){
1358
+ options.customMessages = true;
1359
+ webshims.reTest('form-message');
1360
+ webshims.error('overrideMessages is deprecated. use customMessages instead.');
1361
+ }
1362
+ if(options.replaceValidationUI){
1363
+ webshims.ready('DOM forms', function(){
1364
+ $(document).on('firstinvalid', function(e){
1365
+ if(!e.isInvalidUIPrevented()){
1366
+ e.preventDefault();
1367
+ webshims.validityAlert.showFor( e.target );
1368
+ }
1369
+ });
1261
1370
  });
1262
-
1263
-
1264
- $.expr[":"].focus = function( elem ) {
1265
- try {
1266
- var doc = elem.ownerDocument;
1267
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
1268
- } catch(e){}
1269
- return false;
1270
- };
1271
-
1272
-
1273
- var customEvents = $.event.customEvent || {};
1274
- var isValid = function(elem){
1275
- return ($.prop(elem, 'validity') || {valid: 1}).valid;
1276
- };
1371
+ }
1372
+ });
1373
+
1374
+
1375
+ if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){
1376
+ webshims.register('form-shim-extend', function($, webshims, window, document, undefined, options){
1377
+ "use strict";
1378
+ webshims.inputTypes = webshims.inputTypes || {};
1379
+ //some helper-functions
1380
+ var cfg = webshims.cfg.forms;
1381
+ var bugs = webshims.bugs;
1382
+ var isSubmit;
1383
+
1384
+ var isNumber = function(string){
1385
+ return (typeof string == 'number' || (string && string == string * 1));
1386
+ },
1387
+ typeModels = webshims.inputTypes,
1388
+ checkTypes = {
1389
+ radio: 1,
1390
+ checkbox: 1
1391
+ },
1392
+ getType = function(elem){
1393
+ return (elem.getAttribute('type') || elem.type || '').toLowerCase();
1394
+ }
1395
+ ;
1396
+
1397
+ (function(){
1398
+ if('querySelector' in document){
1399
+ try {
1400
+ bugs.findRequired = !($('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /></form>')[0].querySelector('select:required'));
1401
+ } catch(er){
1402
+ bugs.findRequired = false;
1403
+ }
1277
1404
 
1278
1405
  if (bugs.bustedValidity || bugs.findRequired) {
1279
1406
  (function(){
@@ -1306,483 +1433,11 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1306
1433
  return matchesSelector.call(this, node, expr);
1307
1434
  };
1308
1435
  }
1309
-
1310
- })();
1311
- }
1312
-
1313
- //ToDo needs testing
1314
- var oldAttr = $.prop;
1315
- var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
1316
- $.prop = function(elem, name, val){
1317
- var ret = oldAttr.apply(this, arguments);
1318
- if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
1319
- if(isValid(elem)){
1320
- $(elem).getShadowElement().removeClass(invalidClass);
1321
- if(name == 'checked' && val) {
1322
- getGroupElements(elem).not(elem).removeClass(invalidClass).removeAttr('aria-invalid');
1323
- }
1324
- }
1325
- }
1326
- return ret;
1327
- };
1328
-
1329
- var returnValidityCause = function(validity, elem){
1330
- var ret;
1331
- $.each(validity, function(name, value){
1332
- if(value){
1333
- ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
1334
- return false;
1335
- }
1336
- });
1337
- return ret;
1338
- };
1339
-
1340
- var isInGroup = function(name){
1341
- var ret;
1342
- try {
1343
- ret = document.activeElement.name === name;
1344
- } catch(e){}
1345
- return ret;
1346
- };
1347
- /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-success instead */
1348
- var invalidClass = 'user-error';
1349
- var validClass = 'user-success';
1350
- var stopChangeTypes = {
1351
- time: 1,
1352
- date: 1,
1353
- month: 1,
1354
- datetime: 1,
1355
- week: 1,
1356
- 'datetime-local': 1
1357
- };
1358
- var switchValidityClass = function(e){
1359
- var elem, timer;
1360
- if(!e.target){return;}
1361
- elem = $(e.target).getNativeElement()[0];
1362
- if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
1363
- timer = $.data(elem, 'webshimsswitchvalidityclass');
1364
- var switchClass = function(){
1365
- if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
1366
- var validity = $.prop(elem, 'validity');
1367
- var shadowElem = $(elem).getShadowElement();
1368
- var addClass, removeClass, trigger, generaltrigger, validityCause;
1369
-
1370
- if(isWebkit && e.type == 'change' && !bugs.bustedValidity && stopChangeTypes[shadowElem.prop('type')] && shadowElem.is(':focus')){return;}
1371
-
1372
- $(elem).trigger('refreshCustomValidityRules');
1373
-
1374
- if(validity.valid){
1375
- if(!shadowElem.hasClass(validClass)){
1376
- addClass = validClass;
1377
- removeClass = invalidClass;
1378
- generaltrigger = 'changedvaliditystate';
1379
- trigger = 'changedvalid';
1380
- if(checkTypes[elem.type] && elem.checked){
1381
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
1382
- }
1383
- $.removeData(elem, 'webshimsinvalidcause');
1384
- }
1385
- } else {
1386
- validityCause = returnValidityCause(validity, elem);
1387
- if($.data(elem, 'webshimsinvalidcause') != validityCause){
1388
- $.data(elem, 'webshimsinvalidcause', validityCause);
1389
- generaltrigger = 'changedvaliditystate';
1390
- }
1391
- if(!shadowElem.hasClass(invalidClass)){
1392
- addClass = invalidClass;
1393
- removeClass = validClass;
1394
- if (checkTypes[elem.type] && !elem.checked) {
1395
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
1396
- }
1397
- trigger = 'changedinvalid';
1398
- }
1399
- }
1400
-
1401
- if(addClass){
1402
- shadowElem.addClass(addClass).removeClass(removeClass);
1403
- //jQuery 1.6.1 IE9 bug (doubble trigger bug)
1404
- setTimeout(function(){
1405
- $(elem).trigger(trigger);
1406
- }, 0);
1407
- }
1408
- if(generaltrigger){
1409
- setTimeout(function(){
1410
- $(elem).trigger(generaltrigger);
1411
- }, 0);
1412
- }
1413
-
1414
- $.removeData(elem, 'webshimsswitchvalidityclass');
1415
- };
1416
-
1417
- if(timer){
1418
- clearTimeout(timer);
1419
- }
1420
- if(e.type == 'refreshvalidityui'){
1421
- switchClass();
1422
- } else {
1423
- $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
1424
- }
1425
- };
1426
-
1427
- $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
1428
- customEvents.changedvaliditystate = true;
1429
- customEvents.refreshCustomValidityRules = true;
1430
- customEvents.changedvalid = true;
1431
- customEvents.changedinvalid = true;
1432
- customEvents.refreshvalidityui = true;
1433
-
1434
-
1435
- webshims.triggerInlineForm = function(elem, event){
1436
- $(elem).trigger(event);
1437
- };
1438
-
1439
- webshims.modules["form-core"].getGroupElements = getGroupElements;
1440
-
1441
-
1442
- var setRoot = function(){
1443
- webshims.scrollRoot = (isWebkit || document.compatMode == 'BackCompat') ?
1444
- $(document.body) :
1445
- $(document.documentElement)
1446
- ;
1447
- };
1448
- var minWidth = (Modernizr.boxSizing || Modernizr['display-table'] || $.support.getSetAttribute) ?
1449
- 'minWidth' :
1450
- 'width'
1451
- ;
1452
- setRoot();
1453
- webshims.ready('DOM', setRoot);
1454
-
1455
- webshims.getRelOffset = function(posElem, relElem){
1456
- posElem = $(posElem);
1457
- var offset = $(relElem).offset();
1458
- var bodyOffset;
1459
- $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
1460
- bodyOffset = posElem.offset();
1461
- });
1462
- offset.top -= bodyOffset.top;
1463
- offset.left -= bodyOffset.left;
1464
- return offset;
1465
- };
1466
-
1467
- webshims.wsPopover = {
1468
- _create: function(){
1469
- this.options = $.extend({}, webshims.cfg.wspopover, this.options);
1470
- this.id = webshims.wsPopover.id++;
1471
- this.eventns = '.wsoverlay'+this.id;
1472
- this.timers = {};
1473
- this.element = $('<div class="ws-popover" tabindex="-1"><div class="ws-po-outerbox"><div class="ws-po-arrow"><div class="ws-po-arrowbox" /></div><div class="ws-po-box" /></div></div>');
1474
- this.contentElement = $('.ws-po-box', this.element);
1475
- this.lastElement = $([]);
1476
- this.bindElement();
1477
-
1478
- this.element.data('wspopover', this);
1479
-
1480
- },
1481
- options: {},
1482
- content: function(html){
1483
- this.contentElement.html(html);
1484
- },
1485
- bindElement: function(){
1486
- var that = this;
1487
- var stopBlur = function(){
1488
- that.stopBlur = false;
1489
- };
1490
- this.preventBlur = function(e){
1491
- that.stopBlur = true;
1492
- clearTimeout(that.timers.stopBlur);
1493
- that.timers.stopBlur = setTimeout(stopBlur, 9);
1494
- };
1495
- this.element.on({
1496
- 'mousedown': this.preventBlur
1497
- });
1498
- },
1499
-
1500
- isInElement: function(container, contained){
1501
- return container == contained || $.contains(container, contained);
1502
- },
1503
- show: function(element){
1504
- var e = $.Event('wspopoverbeforeshow');
1505
- this.element.trigger(e);
1506
- if(e.isDefaultPrevented() || this.isVisible){return;}
1507
- this.isVisible = true;
1508
- element = $(element || this.options.prepareFor).getNativeElement() ;
1509
-
1510
- var that = this;
1511
- var visual = $(element).getShadowElement();
1512
-
1513
- this.clear();
1514
- this.element.removeClass('ws-po-visible').css('display', 'none');
1515
-
1516
- this.prepareFor(element, visual);
1517
-
1518
- this.position(visual);
1519
- that.timers.show = setTimeout(function(){
1520
- that.element.css('display', '');
1521
- that.timers.show = setTimeout(function(){
1522
- that.element.addClass('ws-po-visible').trigger('wspopovershow');
1523
- }, 9);
1524
- }, 9);
1525
- $(document).on('focusin'+this.eventns+' mousedown'+this.eventns, function(e){
1526
- if(that.options.hideOnBlur && !that.stopBlur && !that.isInElement(that.lastElement[0] || document.body, e.target) && !that.isInElement(element[0] || document.body, e.target) && !that.isInElement(that.element[0], e.target)){
1527
- that.hide();
1528
- }
1529
- });
1530
- $(window).on('resize'+this.eventns + ' pospopover'+this.eventns, function(){
1531
- clearTimeout(that.timers.repos);
1532
- that.timers.repos = setTimeout(function(){
1533
- that.position(visual);
1534
- }, 900);
1535
- });
1536
- },
1537
- prepareFor: function(element, visual){
1538
- var onBlur;
1539
- var opts = $.extend({}, this.options, $(element.prop('form') || []).data('wspopover') || {}, element.data('wspopover'));
1540
- var that = this;
1541
- var css = {};
1542
- this.lastElement = $(element).getShadowFocusElement();
1543
- if(opts.appendTo == 'element'){
1544
- this.element.insertAfter(element);
1545
- } else {
1546
- this.element.appendTo(opts.appendTo);
1547
- }
1548
-
1549
- this.element.attr({
1550
- 'data-class': element.prop('className'),
1551
- 'data-id': element.prop('id')
1552
- });
1553
-
1554
- css[minWidth] = opts.constrainWidth ? visual.outerWidth() : '';
1555
-
1556
- this.element.css(css);
1557
-
1558
- if(opts.hideOnBlur){
1559
- onBlur = function(e){
1560
- if(that.stopBlur){
1561
- e.stopImmediatePropagation();
1562
- } else {
1563
- that.hide();
1564
- }
1565
- };
1566
-
1567
- that.timers.bindBlur = setTimeout(function(){
1568
- that.lastElement.off(that.eventns).on('focusout'+that.eventns + ' blur'+that.eventns, onBlur);
1569
- that.lastElement.getNativeElement().off(that.eventns);
1570
- }, 10);
1571
-
1572
-
1573
- }
1574
-
1575
- if(!this.prepared){
1576
-
1577
- if($.fn.bgIframe){
1578
- this.element.bgIframe();
1579
- }
1580
- }
1581
- this.prepared = true;
1582
- },
1583
- clear: function(){
1584
- $(window).off(this.eventns);
1585
- $(document).off(this.eventns);
1586
-
1587
- this.stopBlur = false;
1588
- $.each(this.timers, function(timerName, val){
1589
- clearTimeout(val);
1590
- });
1591
- },
1592
- hide: function(){
1593
- var e = $.Event('wspopoverbeforehide');
1594
- this.element.trigger(e);
1595
- if(e.isDefaultPrevented() || !this.isVisible){return;}
1596
- this.isVisible = false;
1597
- var that = this;
1598
- var forceHide = function(){
1599
- that.element.css('display', 'none').attr({'data-id': '', 'data-class': '', 'hidden': 'hidden'});
1600
- clearTimeout(that.timers.forcehide);
1601
- };
1602
- this.clear();
1603
- this.element.removeClass('ws-po-visible').trigger('wspopoverhide');
1604
- $(window).on('resize'+this.eventns, forceHide);
1605
- that.timers.forcehide = setTimeout(forceHide, 999);
1606
- },
1607
- position: function(element){
1608
- var offset = webshims.getRelOffset(this.element.css({marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}).removeAttr('hidden'), element);
1609
- offset.top += element.outerHeight();
1610
- this.element.css({marginTop: '', marginLeft: '', marginRight: '', marginBottom: ''}).css(offset);
1611
- }
1612
- };
1613
-
1614
- webshims.wsPopover.id = 0;
1615
-
1616
- /* some extra validation UI */
1617
- webshims.validityAlert = (function(){
1618
-
1619
-
1620
- var focusTimer = false;
1621
-
1622
- var api = webshims.objectCreate(webshims.wsPopover, {}, options.messagePopover);
1623
- var boundHide = api.hide.bind(api);
1624
-
1625
- api.element.addClass('validity-alert').attr({role: 'alert'});
1626
- $.extend(api, {
1627
- hideDelay: 5000,
1628
- showFor: function(elem, message, noFocusElem, noBubble){
1629
-
1630
- elem = $(elem).getNativeElement();
1631
- this.clear();
1632
- this.hide();
1633
- if(!noBubble){
1634
- this.getMessage(elem, message);
1635
-
1636
- this.show(elem);
1637
- if(this.hideDelay){
1638
- this.timers.delayedHide = setTimeout(boundHide, this.hideDelay);
1639
- }
1640
-
1641
- }
1642
-
1643
- if(!noFocusElem){
1644
- this.setFocus(elem);
1645
- }
1646
- },
1647
- setFocus: function(element){
1648
- var focusElem = $(element).getShadowFocusElement();
1649
- var scrollTop = webshims.scrollRoot.scrollTop();
1650
- var elemTop = focusElem.offset().top - 30;
1651
- var smooth;
1652
-
1653
- if(scrollTop > elemTop){
1654
- webshims.scrollRoot.animate(
1655
- {scrollTop: elemTop - 5},
1656
- {
1657
- queue: false,
1658
- duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
1659
- }
1660
- );
1661
- smooth = true;
1662
- }
1663
- try {
1664
- focusElem[0].focus();
1665
- } catch(e){}
1666
- if(smooth){
1667
- webshims.scrollRoot.scrollTop(scrollTop);
1668
- setTimeout(function(){
1669
- webshims.scrollRoot.scrollTop(scrollTop);
1670
- }, 0);
1671
- }
1672
-
1673
- $(window).triggerHandler('pospopover'+this.eventns);
1674
- },
1675
- getMessage: function(elem, message){
1676
- if (!message) {
1677
- message = getContentValidationMessage(elem[0]) || elem.prop('customValidationMessage') || elem.prop('validationMessage');
1678
- }
1679
- if (message) {
1680
- api.contentElement.text(message);
1681
- } else {
1682
- this.hide();
1683
- }
1684
- }
1685
- });
1686
-
1687
-
1688
- return api;
1689
- })();
1690
-
1691
-
1692
- /* extension, but also used to fix native implementation workaround/bugfixes */
1693
- (function(){
1694
- var firstEvent,
1695
- invalids = [],
1696
- stopSubmitTimer,
1697
- form
1698
- ;
1699
-
1700
- $(document).on('invalid', function(e){
1701
- if(e.wrongWebkitInvalid){return;}
1702
- var jElm = $(e.target);
1703
- var shadowElem = jElm.getShadowElement();
1704
- if(!shadowElem.hasClass(invalidClass)){
1705
- shadowElem.addClass(invalidClass).removeClass(validClass);
1706
- setTimeout(function(){
1707
- $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
1708
- }, 0);
1709
- }
1710
-
1711
- if(!firstEvent){
1712
- //trigger firstinvalid
1713
- firstEvent = $.Event('firstinvalid');
1714
- firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
1715
- var firstSystemInvalid = $.Event('firstinvalidsystem');
1716
- $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
1717
- jElm.trigger(firstEvent);
1718
- }
1719
-
1720
- //if firstinvalid was prevented all invalids will be also prevented
1721
- if( firstEvent && firstEvent.isDefaultPrevented() ){
1722
- e.preventDefault();
1723
- }
1724
- invalids.push(e.target);
1725
- e.extraData = 'fix';
1726
- clearTimeout(stopSubmitTimer);
1727
- stopSubmitTimer = setTimeout(function(){
1728
- var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
1729
- //reset firstinvalid
1730
- firstEvent = false;
1731
- invalids = [];
1732
- $(e.target).trigger(lastEvent, lastEvent);
1733
- }, 9);
1734
- jElm = null;
1735
- shadowElem = null;
1736
- });
1737
- })();
1738
-
1739
- $.fn.getErrorMessage = function(){
1740
- var message = '';
1741
- var elem = this[0];
1742
- if(elem){
1743
- message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
1744
- }
1745
- return message;
1746
- };
1747
-
1748
- if(options.replaceValidationUI){
1749
- if(options.overrideMessages && (options.customMessages || options.customMessages == null)){
1750
- options.customMessages = true;
1751
- options.overrideMessages = false;
1752
- webshims.info("set overrideMessages to false. Use customMessages instead");
1753
- }
1754
- webshims.ready('DOM forms', function(){
1755
- $(document).on('firstinvalid', function(e){
1756
- if(!e.isInvalidUIPrevented()){
1757
- e.preventDefault();
1758
- $.webshims.validityAlert.showFor( e.target );
1759
- }
1760
- });
1761
- });
1762
- }
1763
- });
1764
-
1765
- })(jQuery);
1766
- if(!Modernizr.formvalidation || jQuery.webshims.bugs.bustedValidity){
1767
- jQuery.webshims.register('form-shim-extend', function($, webshims, window, document){
1768
- "use strict";
1769
- webshims.inputTypes = webshims.inputTypes || {};
1770
- //some helper-functions
1771
- var cfg = webshims.cfg.forms;
1772
- var isSubmit;
1773
-
1774
- var isNumber = function(string){
1775
- return (typeof string == 'number' || (string && string == string * 1));
1776
- },
1777
- typeModels = webshims.inputTypes,
1778
- checkTypes = {
1779
- radio: 1,
1780
- checkbox: 1
1781
- },
1782
- getType = function(elem){
1783
- return (elem.getAttribute('type') || elem.type || '').toLowerCase();
1436
+
1437
+ })();
1438
+ }
1784
1439
  }
1785
- ;
1440
+ })();
1786
1441
 
1787
1442
  //API to add new input types
1788
1443
  webshims.addInputType = function(type, obj){
@@ -1811,7 +1466,29 @@ var isPlaceholderOptionSelected = function(select){
1811
1466
  }
1812
1467
  return false;
1813
1468
  };
1814
-
1469
+ var modules = webshims.modules;
1470
+ var emptyJ = $([]);
1471
+ var getGroupElements = function(elem){
1472
+ elem = $(elem);
1473
+ var name;
1474
+ var form;
1475
+ var ret = emptyJ;
1476
+ if(elem[0].type == 'radio'){
1477
+ form = elem.prop('form');
1478
+ name = elem[0].name;
1479
+ if(!name){
1480
+ ret = elem;
1481
+ } else if(form){
1482
+ ret = $(form[name]);
1483
+ } else {
1484
+ ret = $(document.getElementsByName(name)).filter(function(){
1485
+ return !$.prop(this, 'form');
1486
+ });
1487
+ }
1488
+ ret = ret.filter('[type="radio"]');
1489
+ }
1490
+ return ret;
1491
+ };
1815
1492
  var validityRules = {
1816
1493
  valueMissing: function(input, val, cache){
1817
1494
  if(!input.prop('required')){return false;}
@@ -1822,7 +1499,7 @@ var validityRules = {
1822
1499
  if(cache.nodeName == 'select'){
1823
1500
  ret = (!val && (input[0].selectedIndex < 0 || isPlaceholderOptionSelected(input[0]) ));
1824
1501
  } else if(checkTypes[cache.type]){
1825
- ret = (cache.type == 'checkbox') ? !input.is(':checked') : !webshims.modules["form-core"].getGroupElements(input).filter(':checked')[0];
1502
+ ret = (cache.type == 'checkbox') ? !input.is(':checked') : !getGroupElements(input).filter(':checked')[0];
1826
1503
  } else {
1827
1504
  ret = !(val);
1828
1505
  }
@@ -2617,6 +2294,52 @@ webshims.addReady(function(context, contextElem){
2617
2294
 
2618
2295
  });
2619
2296
 
2297
+ if(!Modernizr.input.list){
2298
+ webshims.defineNodeNameProperty('datalist', 'options', {
2299
+ prop: {
2300
+ writeable: false,
2301
+ get: function(){
2302
+ var elem = this;
2303
+ var select = $('select', elem);
2304
+ var options;
2305
+ if(select[0]){
2306
+ options = select[0].options;
2307
+ } else {
2308
+ options = $('option', elem).get();
2309
+ if(options.length){
2310
+ webshims.warn('you should wrap your option-elements for a datalist in a select element to support IE and other old browsers.');
2311
+ }
2312
+ }
2313
+ return options;
2314
+ }
2315
+ }
2316
+ });
2317
+
2318
+ webshims.ready('form-datalist', function(){
2319
+ webshims.defineNodeNameProperties('input', {
2320
+ list: {
2321
+ attr: {
2322
+ get: function(){
2323
+ var val = webshims.contentAttr(this, 'list');
2324
+ return (val == null) ? undefined : val;
2325
+ },
2326
+ set: function(value){
2327
+ var elem = this;
2328
+ webshims.contentAttr(elem, 'list', value);
2329
+ webshims.objectCreate(options.shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
2330
+ $(elem).triggerHandler('listdatalistchange');
2331
+ }
2332
+ },
2333
+ initAttr: true,
2334
+ reflect: true,
2335
+ propType: 'element',
2336
+ propNodeName: 'datalist'
2337
+ }
2338
+ });
2339
+ });
2340
+
2341
+ }
2342
+
2620
2343
  if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled){
2621
2344
  (function(){
2622
2345
  (function(prop, undefined){
@@ -2868,7 +2591,9 @@ if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled){
2868
2591
  value: function(){
2869
2592
  this.removeAttribute(name);
2870
2593
  if(removeProp){
2871
- delete this.value;
2594
+ try {
2595
+ delete this.value;
2596
+ } catch(er){}
2872
2597
  }
2873
2598
  updateProgress.isInChange = name;
2874
2599
  updateProgress(this);
@@ -2967,7 +2692,7 @@ try {
2967
2692
  webshims.onNodeNamesPropertyModify('input', 'checked', function(value, boolVal){
2968
2693
  var type = this.type;
2969
2694
  if(type == 'radio' && boolVal){
2970
- webshims.modules["form-core"].getGroupElements(this).each(checkChange);
2695
+ getGroupElements(this).each(checkChange);
2971
2696
  } else if(checkInputs[type]) {
2972
2697
  $(this).each(checkChange);
2973
2698
  }
@@ -2977,7 +2702,7 @@ try {
2977
2702
 
2978
2703
  if(checkInputs[e.target.type]){
2979
2704
  if(e.target.type == 'radio'){
2980
- webshims.modules["form-core"].getGroupElements(e.target).each(checkChange);
2705
+ getGroupElements(e.target).each(checkChange);
2981
2706
  } else {
2982
2707
  $(e.target)[$.prop(e.target, 'checked') ? 'addClass' : 'removeClass']('prop-checked');
2983
2708
  }
@@ -2995,7 +2720,7 @@ try {
2995
2720
  prop = 'checked';
2996
2721
  } else if(this.nodeName.toLowerCase() == 'option'){
2997
2722
  prop = 'selected';
2998
- }
2723
+ }
2999
2724
  if(prop){
3000
2725
  $(this)[$.prop(this, prop) ? 'addClass' : 'removeClass']('prop-checked');
3001
2726
  }
@@ -3007,13 +2732,41 @@ try {
3007
2732
  }
3008
2733
 
3009
2734
  (function(){
2735
+ var bustedPlaceholder;
3010
2736
  Modernizr.textareaPlaceholder = !!('placeholder' in $('<textarea />')[0]);
3011
- if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder){return;}
2737
+ if(Modernizr.input.placeholder && options.overridePlaceholder){
2738
+ bustedPlaceholder = true;
2739
+ }
2740
+ if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder && !bustedPlaceholder){
2741
+ (function(){
2742
+ var ua = navigator.userAgent;
2743
+
2744
+ if(ua.indexOf('Mobile') != -1 && ua.indexOf('Safari') != -1){
2745
+ $(window).on('orientationchange', (function(){
2746
+ var timer;
2747
+ var retVal = function(i, value){
2748
+ return value;
2749
+ };
2750
+
2751
+ var set = function(){
2752
+ $('input[placeholder], textarea[placeholder]').attr('placeholder', retVal);
2753
+ };
2754
+ return function(e){
2755
+ clearTimeout(timer);
2756
+ timer = setTimeout(set, 9);
2757
+ };
2758
+ })());
2759
+ }
2760
+ })();
2761
+
2762
+ //abort
2763
+ return;
2764
+ }
3012
2765
 
3013
2766
  var isOver = (webshims.cfg.forms.placeholderType == 'over');
3014
2767
  var isResponsive = (webshims.cfg.forms.responsivePlaceholder);
3015
2768
  var polyfillElements = ['textarea'];
3016
- if(!Modernizr.input.placeholder){
2769
+ if(!Modernizr.input.placeholder || bustedPlaceholder){
3017
2770
  polyfillElements.push('input');
3018
2771
  }
3019
2772
 
@@ -3150,7 +2903,7 @@ try {
3150
2903
  }
3151
2904
  ;
3152
2905
 
3153
- if(webshims.modules["form-number-date-ui"].loaded){
2906
+ if(modules["form-number-date-ui"].loaded){
3154
2907
  delete allowedPlaceholder.number;
3155
2908
  }
3156
2909
 
@@ -3168,11 +2921,11 @@ try {
3168
2921
  });
3169
2922
 
3170
2923
  if((form = $.prop(elem, 'form'))){
3171
- $(form).on('reset.placeholder', function(e){
2924
+ $(elem).onWSOff('reset.placeholder', function(e){
3172
2925
  setTimeout(function(){
3173
2926
  changePlaceholderVisibility(elem, false, false, data, e.type );
3174
2927
  }, 0);
3175
- });
2928
+ }, false, form);
3176
2929
  }
3177
2930
 
3178
2931
  if(elem.type == 'password' || isOver){
@@ -3211,8 +2964,8 @@ try {
3211
2964
  data.text.css('padding'+ side, size);
3212
2965
  });
3213
2966
 
3214
- $(document)
3215
- .onTrigger('updateshadowdom', function(){
2967
+ $(elem)
2968
+ .onWSOff('updateshadowdom', function(){
3216
2969
  var height, width;
3217
2970
  if((width = elem.offsetWidth) || (height = elem.offsetHeight)){
3218
2971
  data.text
@@ -3223,27 +2976,25 @@ try {
3223
2976
  .css($(elem).position())
3224
2977
  ;
3225
2978
  }
3226
- })
2979
+ }, true)
3227
2980
  ;
3228
2981
 
3229
2982
  } else {
3230
2983
  var reset = function(e){
3231
2984
  if($(elem).hasClass('placeholder-visible')){
3232
2985
  hidePlaceholder(elem, data, '');
3233
- if(e && e.type == 'submit'){
3234
- setTimeout(function(){
3235
- if(e.isDefaultPrevented()){
3236
- changePlaceholderVisibility(elem, false, false, data );
3237
- }
3238
- }, 9);
3239
- }
2986
+ setTimeout(function(){
2987
+ if(!e || e.type != 'submit' || e.isDefaultPrevented()){
2988
+ changePlaceholderVisibility(elem, false, false, data );
2989
+ }
2990
+ }, 9);
3240
2991
  }
3241
2992
  };
3242
2993
 
3243
- $(window).on('beforeunload', reset);
2994
+ $(elem).onWSOff('beforeunload', reset, false, window);
3244
2995
  data.box = $(elem);
3245
2996
  if(form){
3246
- $(form).submit(reset);
2997
+ $(elem).onWSOff('submit', reset, false, form);
3247
2998
  }
3248
2999
  }
3249
3000
 
@@ -3276,11 +3027,20 @@ try {
3276
3027
  attr: {
3277
3028
  set: function(val){
3278
3029
  var elem = this;
3279
- webshims.contentAttr(elem, 'placeholder', val);
3030
+ if(bustedPlaceholder){
3031
+ webshims.data(elem, 'bustedPlaceholder', val);
3032
+ elem.placeholder = '';
3033
+ } else {
3034
+ webshims.contentAttr(elem, 'placeholder', val);
3035
+ }
3280
3036
  pHolder.update(elem, val);
3281
3037
  },
3282
3038
  get: function(){
3283
- return webshims.contentAttr(this, 'placeholder');
3039
+ var placeholder;
3040
+ if(bustedPlaceholder){
3041
+ placeholder = webshims.data(this, 'bustedPlaceholder');
3042
+ }
3043
+ return placeholder || webshims.contentAttr(this, 'placeholder');
3284
3044
  }
3285
3045
  },
3286
3046
  reflect: true,
@@ -3297,7 +3057,9 @@ try {
3297
3057
  set: function(val){
3298
3058
  var elem = this;
3299
3059
  var placeholder;
3300
-
3060
+ if(bustedPlaceholder){
3061
+ placeholder = webshims.data(elem, 'bustedPlaceholder');
3062
+ }
3301
3063
  if(!placeholder){
3302
3064
  placeholder = webshims.contentAttr(elem, 'placeholder');
3303
3065
  }
@@ -3467,11 +3229,15 @@ try {
3467
3229
  }); //webshims.ready end
3468
3230
  }//end formvalidation
3469
3231
 
3470
- jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
3232
+ webshims.register('form-message', function($, webshims, window, document, undefined, options){
3471
3233
  "use strict";
3234
+ if(options.overrideMessages){
3235
+ options.customMessages = true;
3236
+ webshims.error('overrideMessages is deprecated. use customMessages instead.');
3237
+ }
3472
3238
  var validityMessages = webshims.validityMessages;
3473
3239
 
3474
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
3240
+ var implementProperties = options.customMessages ? ['customValidationMessage'] : [];
3475
3241
 
3476
3242
  validityMessages.en = $.extend(true, {
3477
3243
  typeMismatch: {
@@ -3502,17 +3268,17 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
3502
3268
 
3503
3269
  if(typeof validityMessages['en'].valueMissing == 'object'){
3504
3270
  ['select', 'radio'].forEach(function(type){
3505
- validityMessages.en.valueMissing[type] = 'Please select an option.';
3271
+ validityMessages.en.valueMissing[type] = validityMessages.en.valueMissing[type] || 'Please select an option.';
3506
3272
  });
3507
3273
  }
3508
3274
  if(typeof validityMessages.en.rangeUnderflow == 'object'){
3509
3275
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
3510
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
3276
+ validityMessages.en.rangeUnderflow[type] = validityMessages.en.rangeUnderflow[type] || 'Value must be at or after {%min}.';
3511
3277
  });
3512
3278
  }
3513
3279
  if(typeof validityMessages.en.rangeOverflow == 'object'){
3514
3280
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
3515
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
3281
+ validityMessages.en.rangeOverflow[type] = validityMessages.en.rangeOverflow[type] || 'Value must be at or before {%max}.';
3516
3282
  });
3517
3283
  }
3518
3284
 
@@ -3548,17 +3314,17 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
3548
3314
 
3549
3315
  if(typeof validityMessages.de.valueMissing == 'object'){
3550
3316
  ['select', 'radio'].forEach(function(type){
3551
- validityMessages.de.valueMissing[type] = 'Bitte wählen Sie eine Option aus.';
3317
+ validityMessages.de.valueMissing[type] = validityMessages.de.valueMissing[type] || 'Bitte wählen Sie eine Option aus.';
3552
3318
  });
3553
3319
  }
3554
3320
  if(typeof validityMessages.de.rangeUnderflow == 'object'){
3555
3321
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
3556
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
3322
+ validityMessages.de.rangeUnderflow[type] = validityMessages.de.rangeUnderflow[type] || '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
3557
3323
  });
3558
3324
  }
3559
3325
  if(typeof validityMessages.de.rangeOverflow == 'object'){
3560
3326
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
3561
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
3327
+ validityMessages.de.rangeOverflow[type] = validityMessages.de.rangeOverflow[type] || '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
3562
3328
  });
3563
3329
  }
3564
3330
 
@@ -3576,12 +3342,12 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
3576
3342
  };
3577
3343
 
3578
3344
  webshims.createValidationMessage = function(elem, name){
3579
- var spinner;
3345
+ var widget;
3580
3346
  var message = getMessageFromObj(currentValidationMessage[name], elem);
3581
-
3347
+ var type = $.prop(elem, 'type');
3582
3348
  if(!message){
3583
- message = getMessageFromObj(validityMessages[''][name], elem) || 'invalid value';
3584
- webshims.info('could not find errormessage for: '+ name +' / '+ $.prop(elem, 'type') +'. in language: '+$.webshims.activeLang());
3349
+ message = getMessageFromObj(validityMessages[''][name], elem) || $.prop(elem, 'validationMessage');
3350
+ webshims.info('could not find errormessage for: '+ name +' / '+ type +'. in language: '+$.webshims.activeLang());
3585
3351
  }
3586
3352
  if(message){
3587
3353
  ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
@@ -3591,11 +3357,11 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
3591
3357
  webshims.error('no title for patternMismatch provided. Always add a title attribute.');
3592
3358
  }
3593
3359
  if(valueVals[attr]){
3594
- if(!spinner){
3595
- spinner = $(elem).getShadowElement().data('wsspinner');
3360
+ if(!widget){
3361
+ widget = $(elem).getShadowElement().data('wsWidget'+type);
3596
3362
  }
3597
- if(spinner && spinner.formatValue){
3598
- val = spinner.formatValue(val, false);
3363
+ if(widget && widget.formatValue){
3364
+ val = widget.formatValue(val, false);
3599
3365
  }
3600
3366
  }
3601
3367
  message = message.replace('{%'+ attr +'}', val);
@@ -3610,7 +3376,7 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
3610
3376
  };
3611
3377
 
3612
3378
 
3613
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
3379
+ if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){
3614
3380
  implementProperties.push('validationMessage');
3615
3381
  }
3616
3382
 
@@ -3668,9 +3434,37 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
3668
3434
 
3669
3435
  });
3670
3436
  });
3671
- jQuery.webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
3437
+ webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
3672
3438
  "use strict";
3673
- var doc = document;
3439
+ var doc = document;
3440
+ var lazyLoad = function(name){
3441
+ if(!name || typeof name != 'string'){
3442
+ name = 'DOM';
3443
+ }
3444
+ if(!lazyLoad[name+'Loaded']){
3445
+ lazyLoad[name+'Loaded'] = true;
3446
+ webshims.ready(name, function(){
3447
+ webshims.loader.loadList(['form-datalist-lazy']);
3448
+ });
3449
+ }
3450
+ };
3451
+ var noDatalistSupport = {
3452
+ submit: 1,
3453
+ button: 1,
3454
+ reset: 1,
3455
+ hidden: 1,
3456
+
3457
+ range: 1,
3458
+ date: 1,
3459
+ month: 1
3460
+ };
3461
+ if(webshims.modules["form-number-date-ui"].loaded){
3462
+ $.extend(noDatalistSupport, {
3463
+ number: 1,
3464
+ time: 1
3465
+ });
3466
+ }
3467
+
3674
3468
 
3675
3469
  /*
3676
3470
  * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed)
@@ -3706,28 +3500,6 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3706
3500
  var initializeDatalist = function(){
3707
3501
 
3708
3502
 
3709
- if(!listSupport){
3710
- webshims.defineNodeNameProperty('datalist', 'options', {
3711
- prop: {
3712
- writeable: false,
3713
- get: function(){
3714
- var elem = this;
3715
- var select = $('select', elem);
3716
- var options;
3717
- if(select[0]){
3718
- options = select[0].options;
3719
- } else {
3720
- options = $('option', elem).get();
3721
- if(options.length){
3722
- webshims.warn('you should wrap your option-elements for a datalist in a select element to support IE and other old browsers.');
3723
- }
3724
- }
3725
- return options;
3726
- }
3727
- }
3728
- });
3729
- }
3730
-
3731
3503
  var inputListProto = {
3732
3504
  //override autocomplete
3733
3505
  autocomplete: {
@@ -3787,27 +3559,8 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3787
3559
  };
3788
3560
  }
3789
3561
 
3790
- if(!listSupport){
3791
-
3792
- inputListProto['list'] = {
3793
- attr: {
3794
- get: function(){
3795
- var val = webshims.contentAttr(this, 'list');
3796
- return (val == null) ? undefined : val;
3797
- },
3798
- set: function(value){
3799
- var elem = this;
3800
- webshims.contentAttr(elem, 'list', value);
3801
- webshims.objectCreate(shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
3802
- $(elem).triggerHandler('listdatalistchange');
3803
- }
3804
- },
3805
- initAttr: true,
3806
- reflect: true,
3807
- propType: 'element',
3808
- propNodeName: 'datalist'
3809
- };
3810
- } else {
3562
+
3563
+ if(listSupport){
3811
3564
  //options only return options, if option-elements are rooted: but this makes this part of HTML5 less backwards compatible
3812
3565
  if(!($('<datalist><select><option></option></select></datalist>').prop('options') || []).length ){
3813
3566
  webshims.defineNodeNameProperty('datalist', 'options', {
@@ -3827,13 +3580,15 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3827
3580
  }
3828
3581
  });
3829
3582
  }
3830
- inputListProto['list'] = {
3583
+ inputListProto.list = {
3831
3584
  attr: {
3832
3585
  get: function(){
3833
3586
  var val = webshims.contentAttr(this, 'list');
3834
3587
  if(val != null){
3835
3588
  $.data(this, 'datalistListAttr', val);
3836
- this.removeAttribute('list');
3589
+ if(!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]){
3590
+ this.removeAttribute('list');
3591
+ }
3837
3592
  } else {
3838
3593
  val = $.data(this, 'datalistListAttr');
3839
3594
  }
@@ -3843,7 +3598,15 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3843
3598
  set: function(value){
3844
3599
  var elem = this;
3845
3600
  $.data(elem, 'datalistListAttr', value);
3846
- webshims.objectCreate(shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
3601
+ if (!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]) {
3602
+ webshims.objectCreate(shadowListProto, undefined, {
3603
+ input: elem,
3604
+ id: value,
3605
+ datalist: $.prop(elem, 'list')
3606
+ });
3607
+ } else {
3608
+ elem.setAttribute('list', value);
3609
+ }
3847
3610
  $(elem).triggerHandler('listdatalistchange');
3848
3611
  }
3849
3612
  },
@@ -3863,62 +3626,14 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3863
3626
  .each(function(){
3864
3627
  $(this).triggerHandler('updateDatalist');
3865
3628
  })
3866
-
3867
3629
  ;
3868
-
3869
3630
  });
3870
-
3871
-
3872
3631
  };
3873
3632
 
3874
3633
 
3875
3634
  /*
3876
3635
  * ShadowList
3877
3636
  */
3878
- var listidIndex = 0;
3879
- var noDatalistSupport = {
3880
- submit: 1,
3881
- button: 1,
3882
- reset: 1,
3883
- hidden: 1,
3884
-
3885
- range: 1,
3886
- date: 1,
3887
- month: 1
3888
- };
3889
- if(webshims.modules["form-number-date-ui"].loaded){
3890
- $.extend(noDatalistSupport, {
3891
- number: 1,
3892
- time: 1
3893
- });
3894
- }
3895
-
3896
- var globStoredOptions = {};
3897
- var getStoredOptions = function(name){
3898
- if(!name){return [];}
3899
- if(globStoredOptions[name]){
3900
- return globStoredOptions[name];
3901
- }
3902
- var data;
3903
- try {
3904
- data = JSON.parse(localStorage.getItem('storedDatalistOptions'+name));
3905
- } catch(e){}
3906
- globStoredOptions[name] = data || [];
3907
- return data || [];
3908
- };
3909
- var storeOptions = function(name, val){
3910
- if(!name){return;}
3911
- val = val || [];
3912
- try {
3913
- localStorage.setItem( 'storedDatalistOptions'+name, JSON.stringify(val) );
3914
- } catch(e){}
3915
- };
3916
-
3917
- var getText = function(elem){
3918
- return (elem.textContent || elem.innerText || $.text([ elem ]) || '');
3919
- };
3920
- var lReg = /</g;
3921
- var gReg = />/g;
3922
3637
 
3923
3638
  var shadowListProto = {
3924
3639
  _create: function(opts){
@@ -3926,6 +3641,7 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3926
3641
  if(noDatalistSupport[$.prop(opts.input, 'type')] || noDatalistSupport[$.attr(opts.input, 'type')]){return;}
3927
3642
  var datalist = opts.datalist;
3928
3643
  var data = $.data(opts.input, 'datalistWidget');
3644
+ var that = this;
3929
3645
  if(datalist && data && data.datalist !== datalist){
3930
3646
  data.datalist = datalist;
3931
3647
  data.id = opts.id;
@@ -3946,9 +3662,8 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3946
3662
  } else if(data && data.datalist === datalist){
3947
3663
  return;
3948
3664
  }
3949
- listidIndex++;
3950
- var that = this;
3951
- this.hideList = $.proxy(that, 'hideList');
3665
+
3666
+
3952
3667
 
3953
3668
  this.datalist = datalist;
3954
3669
  this.id = opts.id;
@@ -3956,121 +3671,21 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3956
3671
  this._autocomplete = $.attr(opts.input, 'autocomplete');
3957
3672
  $.data(opts.input, 'datalistWidget', this);
3958
3673
 
3959
- this.popover = webshims.objectCreate(webshims.wsPopover, {}, options.datalistPopover);
3960
- this.shadowList = this.popover.element.addClass('datalist-polyfill');
3961
-
3962
-
3963
- this.index = -1;
3964
- this.input = opts.input;
3965
- this.arrayOptions = [];
3966
-
3967
- this.shadowList
3968
- .delegate('li', 'mouseenter.datalistWidget mousedown.datalistWidget click.datalistWidget', function(e){
3969
- var items = $('li:not(.hidden-item)', that.shadowList);
3970
- var select = (e.type == 'mousedown' || e.type == 'click');
3971
- that.markItem(items.index(e.currentTarget), select, items);
3972
- if(e.type == 'click'){
3973
- that.hideList();
3974
- if(formsCFG.customDatalist){
3975
- $(opts.input).getNativeElement().trigger('datalistselect');
3976
- }
3977
- }
3978
- return (e.type != 'mousedown');
3979
- })
3980
- ;
3981
-
3982
- opts.input.setAttribute('autocomplete', 'off');
3983
-
3984
- $(opts.input)
3985
- .attr({
3986
- //role: 'combobox',
3987
- 'aria-haspopup': 'true'
3988
- })
3989
- .on({
3990
- 'input.datalistWidget': function(){
3991
- if(!that.triggeredByDatalist){
3992
- that.changedValue = false;
3993
- that.showHideOptions();
3994
- }
3995
- },
3996
- 'keydown.datalistWidget': function(e){
3997
- var keyCode = e.keyCode;
3998
- var activeItem;
3999
- var items;
4000
- if(keyCode == 40 && !that.showList()){
4001
- that.markItem(that.index + 1, true);
4002
- return false;
4003
- }
4004
-
4005
- if(!that.popover.isVisible){return;}
4006
-
4007
-
4008
- if(keyCode == 38){
4009
- that.markItem(that.index - 1, true);
4010
- return false;
4011
- }
4012
- if(!e.shiftKey && (keyCode == 33 || keyCode == 36)){
4013
- that.markItem(0, true);
4014
- return false;
4015
- }
4016
- if(!e.shiftKey && (keyCode == 34 || keyCode == 35)){
4017
- items = $('li:not(.hidden-item)', that.shadowList);
4018
- that.markItem(items.length - 1, true, items);
4019
- return false;
4020
- }
4021
- if(keyCode == 13 || keyCode == 27){
4022
- if (keyCode == 13){
4023
- activeItem = $('li.active-item:not(.hidden-item)', that.shadowList);
4024
- that.changeValue( $('li.active-item:not(.hidden-item)', that.shadowList) );
4025
- }
4026
- that.hideList();
4027
- if(formsCFG.customDatalist && activeItem && activeItem[0]){
4028
- $(opts.input).getNativeElement().trigger('datalistselect');
4029
- }
4030
- return false;
4031
- }
4032
- },
4033
- 'focus.datalistWidget': function(){
4034
- if($(this).hasClass('list-focus')){
4035
- that.showList();
4036
- }
4037
- },
4038
- 'mousedown.datalistWidget': function(){
4039
- if($(this).is(':focus')){
4040
- that.showList();
4041
- }
4042
- }
4043
- })
4044
- ;
4045
-
3674
+ lazyLoad('WINDOWLOAD');
4046
3675
 
4047
- $(this.datalist)
4048
- .off('updateDatalist.datalistWidget')
4049
- .on('updateDatalist.datalistWidget', $.proxy(this, '_resetListCached'))
4050
- ;
4051
-
4052
- this._resetListCached();
4053
-
4054
- if(opts.input.form && (opts.input.name || opts.input.id)){
4055
- $(opts.input.form).on('submit.datalistWidget'+opts.input.id, function(){
4056
- if(!$(opts.input).hasClass('no-datalist-cache') && that._autocomplete != 'off'){
4057
- var val = $.prop(opts.input, 'value');
4058
- var name = (opts.input.name || opts.input.id) + $.prop(opts.input, 'type');
4059
- if(!that.storedOptions){
4060
- that.storedOptions = getStoredOptions( name );
4061
- }
4062
- if(val && that.storedOptions.indexOf(val) == -1){
4063
- that.storedOptions.push(val);
4064
- storeOptions(name, that.storedOptions );
4065
- }
3676
+ if(webshims.isReady('form-datalist-lazy')){
3677
+ this._lazyCreate(opts);
3678
+ } else {
3679
+ $(opts.input).one('focus', lazyLoad);
3680
+ webshims.ready('form-datalist-lazy', function(){
3681
+ if(!that._destroyed){
3682
+ that._lazyCreate(opts);
4066
3683
  }
4067
3684
  });
4068
3685
  }
4069
- $(window).on('unload.datalist'+this.id+' beforeunload.datalist'+this.id, function(){
4070
- that.destroy();
4071
- });
4072
3686
  },
4073
- destroy: function(){
3687
+ destroy: function(e){
3688
+ var input;
4074
3689
  var autocomplete = $.attr(this.input, 'autocomplete');
4075
3690
  $(this.input)
4076
3691
  .off('.datalistWidget')
@@ -4088,268 +3703,21 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
4088
3703
  } else {
4089
3704
  $(this.input).attr('autocomplete', autocomplete);
4090
3705
  }
4091
- },
4092
- _resetListCached: function(e){
4093
- var that = this;
4094
- var forceShow;
4095
- this.needsUpdate = true;
4096
- this.lastUpdatedValue = false;
4097
- this.lastUnfoundValue = '';
4098
-
4099
- if(!this.updateTimer){
4100
- if(window.QUnit || (forceShow = ($(that.input).is(':focus') && ($(that.input).hasClass('list-focus') || $.prop(that.input, 'value'))) )){
4101
- that.updateListOptions(forceShow);
4102
- } else {
4103
- webshims.ready('WINDOWLOAD', function(){
4104
- that.updateTimer = setTimeout(function(){
4105
- that.updateListOptions();
4106
- that = null;
4107
- listidIndex = 1;
4108
- }, 200 + (100 * listidIndex));
4109
- });
4110
- }
4111
- }
4112
- },
4113
- updateListOptions: function(_forceShow){
4114
- this.needsUpdate = false;
4115
- clearTimeout(this.updateTimer);
4116
- this.updateTimer = false;
4117
-
4118
- this.searchStart = formsCFG.customDatalist && $(this.input).hasClass('search-start');
4119
- this.addMarkElement = options.addMark || $(this.input).hasClass('mark-option-text');
4120
-
4121
- var list = [];
4122
-
4123
- var values = [];
4124
- var allOptions = [];
4125
- var rElem, rItem, rOptions, rI, rLen, item, value;
4126
- for(rOptions = $.prop(this.datalist, 'options'), rI = 0, rLen = rOptions.length; rI < rLen; rI++){
4127
- rElem = rOptions[rI];
4128
- if(!rElem.disabled && (value = $(rElem).val())){
4129
- rItem = {
4130
- value: value.replace(lReg, '&lt;').replace(gReg, '&gt;'),
4131
- label: $.trim($.attr(rElem, 'label') || getText(rElem)).replace(lReg, '&lt;').replace(gReg, '&gt;'),
4132
- className: rElem.className || ''
4133
- };
4134
-
4135
- if(rItem.label){
4136
- rItem.className += ' has-option-label';
4137
- }
4138
- values.push(rItem.value);
4139
- allOptions.push(rItem);
4140
- }
4141
- }
4142
-
4143
- if(!this.storedOptions){
4144
- this.storedOptions = ($(this.input).hasClass('no-datalist-cache') || this._autocomplete == 'off') ? [] : getStoredOptions((this.input.name || this.input.id) + $.prop(this.input, 'type'));
4145
- }
4146
-
4147
- this.storedOptions.forEach(function(val, i){
4148
- if(values.indexOf(val) == -1){
4149
- allOptions.push({value: val, label: '', className: 'stored-suggest', style: ''});
4150
- }
4151
- });
4152
-
4153
- for(rI = 0, rLen = allOptions.length; rI < rLen; rI++){
4154
- item = allOptions[rI];
4155
- list[rI] = '<li class="'+ item.className +'" tabindex="-1" role="listitem">'+ this.getOptionContent(item) +'</li>';
4156
- }
4157
-
4158
- this.arrayOptions = allOptions;
4159
- this.popover.contentElement.html('<div class="datalist-box"><ul role="list">'+ list.join("\n") +'</ul></div>');
4160
-
4161
-
4162
- if(_forceShow || this.popover.isVisible){
4163
- this.showHideOptions();
4164
- }
4165
- },
4166
- getOptionContent: function(item){
4167
- var content = '';
4168
- if(options.getOptionContent){
4169
- content = options.apply(this, arguments) || '';
4170
- } else {
4171
- content = '<span class="option-value">'+ item.value +'</span>';
4172
- if(item.label){
4173
- content += ' <span class="option-label">'+ item.label +'</span>';
4174
- }
4175
- }
4176
- return content;
4177
- },
4178
- showHideOptions: function(_fromShowList){
4179
- var value = $.prop(this.input, 'value').toLowerCase();
4180
-
4181
- //first check prevent infinite loop, second creates simple lazy optimization
4182
- if(value === this.lastUpdatedValue){
4183
- return;
4184
- }
4185
- if(this.lastUnfoundValue && value.indexOf(this.lastUnfoundValue) === 0){
4186
- this.hideList();
4187
- return;
4188
- }
4189
-
4190
-
4191
- this.lastUpdatedValue = value;
4192
- var found = false;
4193
- var startSearch = this.searchStart;
4194
- var lis = $('li', this.shadowList);
4195
- var that = this;
4196
- if(value){
4197
-
4198
- this.arrayOptions.forEach(function(item, i){
4199
- var search, searchIndex, foundName;
4200
- if(!('lowerValue' in item)){
4201
- item.lowerValue = item.value.toLowerCase();
4202
- if(item.label && item.label != item.value ){
4203
- item.lowerLabel = item.label.toLowerCase();
4204
- }
4205
- }
4206
-
4207
- if(value != item.lowerValue && item.lowerLabel != value){
4208
- searchIndex = item.lowerValue.indexOf(value);
4209
- search = startSearch ? !searchIndex : searchIndex !== -1;
4210
- if(search){
4211
- foundName = 'value';
4212
- } else if(item.lowerLabel){
4213
- searchIndex = item.lowerLabel.indexOf(value);
4214
- search = startSearch ? !searchIndex : searchIndex !== -1;
4215
- foundName = 'label';
4216
- }
4217
- }
4218
-
4219
- if(search){
4220
- that.addMark($(lis[i]).removeClass('hidden-item'), item, foundName, searchIndex, value.length);
4221
- found = true;
4222
- } else {
4223
- $(lis[i]).addClass('hidden-item');
4224
- }
4225
- });
4226
- } else if(lis.length) {
4227
- this.removeMark(lis.removeClass('hidden-item'));
4228
- found = true;
4229
- }
4230
-
4231
- this.hasViewableData = found;
4232
- if(!_fromShowList && found){
4233
- this.showList();
4234
- }
4235
-
4236
- if(!found){
4237
- this.lastUnfoundValue = value;
4238
- this.hideList();
4239
- } else {
4240
- this.lastUnfoundValue = false;
4241
- }
4242
- },
4243
- otherType: {
4244
- value: 'label',
4245
- label: 'value'
4246
- },
4247
- addMark: function(elem, item, prop, start, length){
4248
- if(this.addMarkElement){
4249
- var text = item[prop].substr(start, length);
4250
- text = item[prop].replace(text ,'<mark>'+ text +'</mark>');
4251
- $('.option-'+ this.otherType[prop] +' > mark', elem).each(this._replaceMark);
4252
- $('.option-'+prop, elem).html(text);
4253
-
4254
- }
4255
- },
4256
- _replaceMark: function(){
4257
- var content = $(this).html();
4258
- $(this).replaceWith(content);
4259
- },
4260
- removeMark: function(lis){
4261
- if(this.addMarkElement){
4262
- $('mark', lis).each(this._replaceMark);
4263
- }
4264
- },
4265
- showList: function(){
4266
- if(this.popover.isVisible){return false;}
4267
- if(this.needsUpdate){
4268
- this.updateListOptions();
4269
- }
4270
- this.showHideOptions(true);
4271
- if(!this.hasViewableData){return false;}
4272
- var that = this;
4273
-
4274
- that.shadowList.find('li.active-item').removeClass('active-item');
4275
- that.popover.show(this.input);
4276
-
4277
-
4278
- return true;
4279
- },
4280
- hideList: function(){
4281
- if(!this.popover.isVisible){return false;}
4282
- var that = this;
4283
-
4284
-
4285
- this.popover.hide();
4286
- that.shadowList.removeClass('datalist-visible list-item-active');
4287
- that.index = -1;
4288
- if(that.changedValue){
4289
- that.triggeredByDatalist = true;
4290
- $(that.input).trigger('input').trigger('change');
4291
- that.changedValue = false;
4292
- that.triggeredByDatalist = false;
4293
- }
4294
-
4295
- return true;
4296
- },
4297
- scrollIntoView: function(elem){
4298
- var ul = $('ul', this.shadowList);
4299
- var div = $('div.datalist-box', this.shadowList);
4300
- var elemPos = elem.position();
4301
- var containerHeight;
4302
- elemPos.top -= (parseInt(ul.css('paddingTop'), 10) || 0) + (parseInt(ul.css('marginTop'), 10) || 0) + (parseInt(ul.css('borderTopWidth'), 10) || 0);
4303
- if(elemPos.top < 0){
4304
- div.scrollTop( div.scrollTop() + elemPos.top - 2);
4305
- return;
4306
- }
4307
- elemPos.top += elem.outerHeight();
4308
- containerHeight = div.height();
4309
- if(elemPos.top > containerHeight){
4310
- div.scrollTop( div.scrollTop() + (elemPos.top - containerHeight) + 2);
4311
- }
4312
- },
4313
- changeValue: function(activeItem){
4314
- if(!activeItem[0]){return;}
4315
- var spinner;
4316
- var newValue = $('span.option-value', activeItem).text();
4317
- var oldValue = $.prop(this.input, 'value');
4318
- if(newValue != oldValue){
4319
-
4320
- $(this.input)
4321
- .prop('value', newValue)
4322
- .triggerHandler('updateInput')
4323
- ;
4324
- this.changedValue = true;
4325
- if((spinner = $.data(this.input, 'wsspinner')) && spinner.setInput){
4326
- spinner.setInput(newValue);
4327
- }
4328
- }
4329
- },
4330
- markItem: function(index, doValue, items){
4331
- var activeItem;
4332
- var goesUp;
4333
-
4334
- items = items || $('li:not(.hidden-item)', this.shadowList);
4335
- if(!items.length){return;}
4336
- if(index < 0){
4337
- index = items.length - 1;
4338
- } else if(index >= items.length){
4339
- index = 0;
4340
- }
4341
- items.removeClass('active-item');
4342
- this.shadowList.addClass('list-item-active');
4343
- activeItem = items.filter(':eq('+ index +')').addClass('active-item');
4344
-
4345
- if(doValue){
4346
- this.changeValue(activeItem);
4347
- this.scrollIntoView(activeItem);
3706
+ if(e && e.type == 'beforeunload'){
3707
+ input = this.input;
3708
+ setTimeout(function(){
3709
+ $.attr(input, 'list', $.attr(input, 'list'));
3710
+ }, 9);
4348
3711
  }
4349
- this.index = index;
3712
+ this._destroyed = true;
4350
3713
  }
4351
3714
  };
4352
3715
 
3716
+ webshims.loader.addModule('form-datalist-lazy', {
3717
+ noAutoCallback: true,
3718
+ options: $.extend(options, {shadowListProto: shadowListProto})
3719
+ });
3720
+
4353
3721
  //init datalist update
4354
3722
  initializeDatalist();
4355
3723
  })();