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,11 +1128,15 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1041
1128
 
1042
1129
  })(jQuery, document);
1043
1130
 
1044
- jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
1131
+ webshims.register('form-message', function($, webshims, window, document, undefined, options){
1045
1132
  "use strict";
1133
+ if(options.overrideMessages){
1134
+ options.customMessages = true;
1135
+ webshims.error('overrideMessages is deprecated. use customMessages instead.');
1136
+ }
1046
1137
  var validityMessages = webshims.validityMessages;
1047
1138
 
1048
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
1139
+ var implementProperties = options.customMessages ? ['customValidationMessage'] : [];
1049
1140
 
1050
1141
  validityMessages.en = $.extend(true, {
1051
1142
  typeMismatch: {
@@ -1076,17 +1167,17 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
1076
1167
 
1077
1168
  if(typeof validityMessages['en'].valueMissing == 'object'){
1078
1169
  ['select', 'radio'].forEach(function(type){
1079
- validityMessages.en.valueMissing[type] = 'Please select an option.';
1170
+ validityMessages.en.valueMissing[type] = validityMessages.en.valueMissing[type] || 'Please select an option.';
1080
1171
  });
1081
1172
  }
1082
1173
  if(typeof validityMessages.en.rangeUnderflow == 'object'){
1083
1174
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
1084
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
1175
+ validityMessages.en.rangeUnderflow[type] = validityMessages.en.rangeUnderflow[type] || 'Value must be at or after {%min}.';
1085
1176
  });
1086
1177
  }
1087
1178
  if(typeof validityMessages.en.rangeOverflow == 'object'){
1088
1179
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
1089
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
1180
+ validityMessages.en.rangeOverflow[type] = validityMessages.en.rangeOverflow[type] || 'Value must be at or before {%max}.';
1090
1181
  });
1091
1182
  }
1092
1183
 
@@ -1122,17 +1213,17 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
1122
1213
 
1123
1214
  if(typeof validityMessages.de.valueMissing == 'object'){
1124
1215
  ['select', 'radio'].forEach(function(type){
1125
- validityMessages.de.valueMissing[type] = 'Bitte wählen Sie eine Option aus.';
1216
+ validityMessages.de.valueMissing[type] = validityMessages.de.valueMissing[type] || 'Bitte wählen Sie eine Option aus.';
1126
1217
  });
1127
1218
  }
1128
1219
  if(typeof validityMessages.de.rangeUnderflow == 'object'){
1129
1220
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
1130
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
1221
+ validityMessages.de.rangeUnderflow[type] = validityMessages.de.rangeUnderflow[type] || '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
1131
1222
  });
1132
1223
  }
1133
1224
  if(typeof validityMessages.de.rangeOverflow == 'object'){
1134
1225
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
1135
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
1226
+ validityMessages.de.rangeOverflow[type] = validityMessages.de.rangeOverflow[type] || '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
1136
1227
  });
1137
1228
  }
1138
1229
 
@@ -1150,12 +1241,12 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
1150
1241
  };
1151
1242
 
1152
1243
  webshims.createValidationMessage = function(elem, name){
1153
- var spinner;
1244
+ var widget;
1154
1245
  var message = getMessageFromObj(currentValidationMessage[name], elem);
1155
-
1246
+ var type = $.prop(elem, 'type');
1156
1247
  if(!message){
1157
- message = getMessageFromObj(validityMessages[''][name], elem) || 'invalid value';
1158
- webshims.info('could not find errormessage for: '+ name +' / '+ $.prop(elem, 'type') +'. in language: '+$.webshims.activeLang());
1248
+ message = getMessageFromObj(validityMessages[''][name], elem) || $.prop(elem, 'validationMessage');
1249
+ webshims.info('could not find errormessage for: '+ name +' / '+ type +'. in language: '+$.webshims.activeLang());
1159
1250
  }
1160
1251
  if(message){
1161
1252
  ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
@@ -1165,11 +1256,11 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
1165
1256
  webshims.error('no title for patternMismatch provided. Always add a title attribute.');
1166
1257
  }
1167
1258
  if(valueVals[attr]){
1168
- if(!spinner){
1169
- spinner = $(elem).getShadowElement().data('wsspinner');
1259
+ if(!widget){
1260
+ widget = $(elem).getShadowElement().data('wsWidget'+type);
1170
1261
  }
1171
- if(spinner && spinner.formatValue){
1172
- val = spinner.formatValue(val, false);
1262
+ if(widget && widget.formatValue){
1263
+ val = widget.formatValue(val, false);
1173
1264
  }
1174
1265
  }
1175
1266
  message = message.replace('{%'+ attr +'}', val);
@@ -1184,7 +1275,7 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
1184
1275
  };
1185
1276
 
1186
1277
 
1187
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
1278
+ if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){
1188
1279
  implementProperties.push('validationMessage');
1189
1280
  }
1190
1281
 
@@ -1,11 +1,11 @@
1
- jQuery.webshims.register('form-native-extend', function($, webshims, window, doc, undefined, options){
1
+ webshims.register('form-native-extend', function($, webshims, window, doc, undefined, options){
2
2
  "use strict";
3
3
  var Modernizr = window.Modernizr;
4
4
  var modernizrInputTypes = Modernizr.inputtypes;
5
5
  if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){return;}
6
6
  var typeModels = webshims.inputTypes;
7
+ var runTest = false;
7
8
  var validityRules = {};
8
-
9
9
  var updateValidity = (function(){
10
10
  var timer;
11
11
  var getValidity = function(){
@@ -14,13 +14,14 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
14
14
  var update = function(){
15
15
  $('input').each(getValidity);
16
16
  };
17
- return function(fast){
17
+ return function(){
18
18
  clearTimeout(timer);
19
19
  timer = setTimeout(update, 9);
20
20
  };
21
21
  })();
22
22
  webshims.addInputType = function(type, obj){
23
23
  typeModels[type] = obj;
24
+ runTest = true;
24
25
  //update validity of all implemented input types
25
26
  if($.isDOMReady && Modernizr.formvalidation && !webshims.bugs.bustedValidity){
26
27
  updateValidity();
@@ -44,26 +45,16 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
44
45
  return ret;
45
46
  });
46
47
 
47
- var overrideNativeMessages = options.overrideMessages;
48
-
49
- var overrideValidity = (!modernizrInputTypes.number || !modernizrInputTypes.time || !modernizrInputTypes.range || overrideNativeMessages);
48
+ var formsExtModule = webshims.modules['form-number-date-api'];
49
+ var overrideValidity = formsExtModule.loaded && !formsExtModule.test();
50
50
  var validityProps = ['customError','typeMismatch','rangeUnderflow','rangeOverflow','stepMismatch','tooLong','patternMismatch','valueMissing','valid'];
51
51
 
52
- var validityChanger = (overrideNativeMessages)? ['value', 'checked'] : ['value'];
52
+ var validityChanger = ['value'];
53
53
  var validityElements = [];
54
54
  var testValidity = function(elem, init){
55
- if(!elem){return;}
55
+ if(!elem && !runTest){return;}
56
56
  var type = (elem.getAttribute && elem.getAttribute('type') || elem.type || '').toLowerCase();
57
-
58
- if(!overrideNativeMessages && !typeModels[type]){
59
- return;
60
- }
61
-
62
- if(overrideNativeMessages && !init && type == 'radio' && elem.name){
63
- $(doc.getElementsByName( elem.name )).each(function(){
64
- $.prop(this, 'validity');
65
- });
66
- } else {
57
+ if(typeModels[type]){
67
58
  $.prop(elem, 'validity');
68
59
  }
69
60
  };
@@ -77,9 +68,7 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
77
68
  var elem = (name == 'input') ? $(this).getNativeElement()[0] : this;
78
69
  desc.prop._supvalue.call(elem, error);
79
70
 
80
- if(webshims.bugs.validationMessage){
81
- webshims.data(elem, 'customvalidationMessage', error);
82
- }
71
+
83
72
  if(overrideValidity){
84
73
  webshims.data(elem, 'hasCustomError', !!(error));
85
74
  testValidity(elem);
@@ -91,18 +80,13 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
91
80
  });
92
81
 
93
82
 
94
- if(overrideValidity || overrideNativeMessages){
83
+ if(overrideValidity){
95
84
  validityChanger.push('min');
96
85
  validityChanger.push('max');
97
86
  validityChanger.push('step');
98
87
  validityElements.push('input');
99
88
  }
100
- if(overrideNativeMessages){
101
- validityChanger.push('required');
102
- validityChanger.push('pattern');
103
- validityElements.push('select');
104
- validityElements.push('textarea');
105
- }
89
+
106
90
 
107
91
  if(overrideValidity){
108
92
  var stopValidity;
@@ -156,7 +140,7 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
156
140
 
157
141
  $.each(validityRules, function(rule, fn){
158
142
  validityState[rule] = fn(jElm, val, cache, validityState);
159
- if( validityState[rule] && (validityState.valid || !setCustomMessage) && (overrideNativeMessages || (typeModels[cache.type] && typeModels[cache.type].mismatch)) ) {
143
+ if( validityState[rule] && (validityState.valid || !setCustomMessage) && ((typeModels[cache.type] && typeModels[cache.type].mismatch)) ) {
160
144
  oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, rule));
161
145
  validityState.valid = false;
162
146
  setCustomMessage = true;
@@ -165,13 +149,6 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
165
149
  if(validityState.valid){
166
150
  oldSetCustomValidity[nodeName].call(elem, '');
167
151
  webshims.data(elem, 'hasCustomError', false);
168
- } else if(overrideNativeMessages && !setCustomMessage && !customError){
169
- $.each(validityState, function(name, prop){
170
- if(name !== 'valid' && prop){
171
- oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, name));
172
- return false;
173
- }
174
- });
175
152
  }
176
153
  return validityState;
177
154
  },
@@ -191,27 +168,12 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
191
168
  var inputThrottle;
192
169
  var testPassValidity = function(e){
193
170
  if(!('form' in e.target)){return;}
194
- var form = e.target.form;
195
171
  clearTimeout(inputThrottle);
196
172
  testValidity(e.target);
197
- if(form && overrideNativeMessages){
198
- $('input', form).each(function(){
199
- if(this.type == 'password'){
200
- testValidity(this);
201
- }
202
- });
203
- }
204
173
  };
205
174
 
206
175
  doc.addEventListener('change', testPassValidity, true);
207
176
 
208
- if(overrideNativeMessages){
209
- doc.addEventListener('blur', testPassValidity, true);
210
- doc.addEventListener('keydown', function(e){
211
- if(e.keyCode != 13){return;}
212
- testPassValidity(e);
213
- }, true);
214
- }
215
177
 
216
178
  doc.addEventListener('input', function(e){
217
179
  clearTimeout(inputThrottle);
@@ -224,46 +186,21 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
224
186
  var validityElementsSel = validityElements.join(',');
225
187
 
226
188
  webshims.addReady(function(context, elem){
227
- $(validityElementsSel, context).add(elem.filter(validityElementsSel)).each(function(){
228
- $.prop(this, 'validity');
229
- });
189
+ if(runTest){
190
+ $(validityElementsSel, context).add(elem.filter(validityElementsSel)).each(function(){
191
+ testValidity(this);
192
+ });
193
+ }
230
194
  });
231
195
 
232
196
 
233
- if(overrideNativeMessages){
234
- webshims.ready('DOM form-message', function(){
235
- webshims.activeLang({
236
- register: 'form-core',
237
- callback: function(){
238
- $('input, select, textarea')
239
- .getNativeElement()
240
- .each(function(){
241
- if(webshims.data(this, 'hasCustomError')){return;}
242
- var elem = this;
243
- var validity = $.prop(elem, 'validity') || {valid: true};
244
- var nodeName;
245
- if(validity.valid){return;}
246
- nodeName = (elem.nodeName || '').toLowerCase();
247
- $.each(validity, function(name, prop){
248
- if(name !== 'valid' && prop){
249
- oldSetCustomValidity[nodeName].call(elem, webshims.createValidationMessage(elem, name));
250
- return false;
251
- }
252
- });
253
- })
254
- ;
255
- }
256
- });
257
- });
258
- }
259
-
260
197
  } //end: overrideValidity
261
198
 
262
199
  webshims.defineNodeNameProperty('input', 'type', {
263
200
  prop: {
264
201
  get: function(){
265
202
  var elem = this;
266
- var type = (elem.getAttribute('type') || '').toLowerCase();
203
+ var type = (elem.getAttribute && elem.getAttribute('type') || '').toLowerCase();
267
204
  return (webshims.inputTypes[type]) ? type : elem.type;
268
205
  }
269
206
  }
@@ -271,9 +208,11 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
271
208
 
272
209
 
273
210
  });
274
- jQuery.webshims.register('form-number-date-api', function($, webshims, window, document, undefined){
211
+ webshims.register('form-number-date-api', function($, webshims, window, document, undefined, options){
275
212
  "use strict";
276
-
213
+ if(!webshims.addInputType){
214
+ webshims.error("you can not call forms-ext feature after calling forms feature. call both at once instead: $.webshims.polyfill('forms forms-ext')");
215
+ }
277
216
 
278
217
  if(!webshims.getStep){
279
218
  webshims.getStep = function(elem, type){
@@ -543,7 +482,14 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
543
482
  minDefault: 0,
544
483
  maxDefault: 100
545
484
  },
546
-
485
+ color: {
486
+ mismatch: (function(){
487
+ var cReg = /^\u0023[a-f0-9]{6}$/;
488
+ return function(val){
489
+ return (!val || val.length != 7 || !(cReg.test(val)));
490
+ };
491
+ })()
492
+ },
547
493
  date: {
548
494
  mismatch: function(val){
549
495
  if(!val || !val.split || !(/\d$/.test(val))){return true;}
@@ -741,20 +687,22 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
741
687
  // }
742
688
  };
743
689
 
744
- if(typeBugs || !supportsType('range') || !supportsType('time')){
690
+ if(typeBugs || !supportsType('range') || !supportsType('time') || !supportsType('month')){
745
691
  typeProtos.range = $.extend({}, typeProtos.number, typeProtos.range);
746
692
  typeProtos.time = $.extend({}, typeProtos.date, typeProtos.time);
747
693
  typeProtos.month = $.extend({}, typeProtos.date, typeProtos.month);
748
694
  // typeProtos['datetime-local'] = $.extend({}, typeProtos.date, typeProtos.time, typeProtos['datetime-local']);
749
695
  }
750
696
 
697
+
698
+
751
699
  //'datetime-local'
752
- ['number', 'month', 'range', 'date', 'time'].forEach(function(type){
700
+ ['number', 'month', 'range', 'date', 'time', 'color'].forEach(function(type){
753
701
  if(typeBugs || !supportsType(type)){
754
702
  webshims.addInputType(type, typeProtos[type]);
755
703
  }
756
704
  });
757
-
705
+
758
706
  if($('<input />').prop('labels') == null){
759
707
  webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
760
708
  prop: {
@@ -824,6 +772,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
824
772
  var oVal = val;
825
773
  var thumbStyle = {};
826
774
  var rangeStyle = {};
775
+
827
776
  if(!_noNormalize && parseFloat(val, 10) != val){
828
777
  val = o.min + ((o.max - o.min) / 2);
829
778
  }
@@ -833,6 +782,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
833
782
  }
834
783
  left = 100 * ((val - o.min) / (o.max - o.min));
835
784
 
785
+ if(this._init && val == o.value && oVal == val){return;}
836
786
  this.options.value = val;
837
787
  this.thumb.stop();
838
788
  this.range.stop();
@@ -902,24 +852,30 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
902
852
  $('.ws-range-ticks', trail).remove();
903
853
 
904
854
 
905
- $(this.orig).jProp('list').find('option').each(function(){
906
- o.options[$.prop(this, 'value')] = $.prop(this, 'label');
855
+ $(this.orig).jProp('list').find('option:not([disabled])').each(function(){
856
+ o.options[$.prop(this, 'value')] = $.prop(this, 'label') || '';
907
857
  });
908
858
 
909
859
  $.each(o.options, function(val, label){
910
860
  if(!isNumber(val) || val < min || val > max){return;}
911
861
  var left = 100 * ((val - min) / (max - min));
912
- var title = o.showLabels ? ' title="'+ label +'"' : '';
862
+ var title = o.showLabels && label ? ' title="'+ label +'"' : '';
913
863
  if(that.vertical){
914
864
  left = Math.abs(left - 100);
915
865
  }
916
- trail.append('<span class="ws-range-ticks"'+ title +' style="'+(that.dirs.left)+': '+left+'%;" />');
866
+
867
+ that.posCenter(
868
+ $('<span class="ws-range-ticks"'+ title +' data-label="'+label+'" style="'+(that.dirs.left)+': '+left+'%;" />').appendTo(trail)
869
+ );
917
870
  });
918
871
  },
919
872
  readonly: function(val){
920
873
  val = !!val;
921
874
  this.options.readonly = val;
922
875
  this.element.attr('aria-readonly', ''+val);
876
+ if(this._init){
877
+ this.updateMetrics();
878
+ }
923
879
  },
924
880
  disabled: function(val){
925
881
  val = !!val;
@@ -929,6 +885,9 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
929
885
  } else {
930
886
  this.element.attr({tabindex: this.options.tabindex, 'aria-disabled': 'false'});
931
887
  }
888
+ if(this._init){
889
+ this.updateMetrics();
890
+ }
932
891
  },
933
892
  tabindex: function(val){
934
893
  this.options.tabindex = val;
@@ -1008,6 +967,24 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1008
967
 
1009
968
  return val;
1010
969
  },
970
+ addRemoveClass: function(cName, add){
971
+ var isIn = this.element.prop('className').indexOf(cName) != -1;
972
+ var action;
973
+ if(!add && isIn){
974
+ action = 'removeClass';
975
+ this.element.removeClass(cName);
976
+ this.updateMetrics();
977
+ } else if(add && !isIn){
978
+ action = 'addClass';
979
+
980
+ }
981
+ if(action){
982
+ this.element[action](cName);
983
+ if(this._init){
984
+ this.updateMetrics();
985
+ }
986
+ }
987
+ },
1011
988
  addBindings: function(){
1012
989
  var leftOffset, widgetUnits, hasFocus;
1013
990
  var that = this;
@@ -1047,25 +1024,36 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1047
1024
  that.value(val, false, animate);
1048
1025
  eventTimer.call('input', val);
1049
1026
  }
1027
+ if(e && e.type == 'mousemove'){
1028
+ e.preventDefault();
1029
+ }
1050
1030
  };
1051
-
1052
1031
  var remove = function(e){
1053
1032
  if(e && e.type == 'mouseup'){
1054
1033
  eventTimer.call('input', o.value);
1055
1034
  eventTimer.call('change', o.value);
1056
1035
  }
1057
- that.element.removeClass('ws-active');
1036
+ that.addRemoveClass('ws-active');
1058
1037
  $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1038
+ $(window).off('blur', removeWin);
1039
+ };
1040
+ var removeWin = function(e){
1041
+ if(e.target == window){remove();}
1059
1042
  };
1060
1043
  var add = function(e){
1044
+ var outerWidth;
1061
1045
  e.preventDefault();
1062
1046
  $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1047
+ $(window).off('blur', removeWin);
1063
1048
  if(!o.readonly && !o.disabled){
1064
- leftOffset = that.element.focus().addClass('ws-active').offset();
1065
- widgetUnits = that.element[that.dirs.width]();
1049
+ that.element.focus();
1050
+ that.addRemoveClass('ws-active', true);
1051
+ leftOffset = that.element.focus().offset();
1052
+ widgetUnits = that.element[that.dirs.innerWidth]();
1066
1053
  if(!widgetUnits || !leftOffset){return;}
1054
+ outerWidth = that.thumb[that.dirs.outerWidth]();
1067
1055
  leftOffset = leftOffset[that.dirs.pos];
1068
- widgetUnits = 100 / (widgetUnits - ((that.thumb[that.dirs.outerWidth]() || 2) / 2));
1056
+ widgetUnits = 100 / widgetUnits;
1069
1057
  setValueFromPos(e, o.animate);
1070
1058
  $(document)
1071
1059
  .on({
@@ -1073,6 +1061,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1073
1061
  mousemove: setValueFromPos
1074
1062
  })
1075
1063
  ;
1064
+ $(window).on('blur', removeWin);
1076
1065
  e.stopPropagation();
1077
1066
  }
1078
1067
  };
@@ -1082,18 +1071,20 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1082
1071
  if(!o.disabled){
1083
1072
  eventTimer.init('input', o.value);
1084
1073
  eventTimer.init('change', o.value);
1085
- that.element.addClass('ws-focus');
1074
+ that.addRemoveClass('ws-focus', true);
1075
+ that.updateMetrics();
1086
1076
  }
1087
1077
  hasFocus = true;
1088
1078
  },
1089
1079
  blur: function(e){
1090
1080
  that.element.removeClass('ws-focus ws-active');
1081
+ that.updateMetrics();
1091
1082
  hasFocus = false;
1092
1083
  eventTimer.init('input', o.value);
1093
1084
  eventTimer.call('change', o.value);
1094
1085
  },
1095
1086
  keyup: function(){
1096
- that.element.removeClass('ws-active');
1087
+ that.addRemoveClass('ws-active');
1097
1088
  eventTimer.call('input', o.value);
1098
1089
  eventTimer.call('change', o.value);
1099
1090
  },
@@ -1118,7 +1109,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1118
1109
  step = false;
1119
1110
  }
1120
1111
  if (step) {
1121
- that.element.addClass('ws-active');
1112
+ that.addRemoveClass('ws-active', true);
1122
1113
  eventTimer.call('input', o.value);
1123
1114
  e.preventDefault();
1124
1115
  }
@@ -1140,38 +1131,88 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1140
1131
  this.thumb.on({
1141
1132
  mousedown: add
1142
1133
  });
1134
+ $(function(){
1135
+ webshims.ready('dom-support', function(){
1136
+ that.element.onWSOff('updateshadowdom', function(){
1137
+ that.updateMetrics();
1138
+ });
1139
+ });
1140
+ if(!$.fn.onWSOff){
1141
+ webshims._polyfill(['dom-support']);
1142
+ }
1143
+ });
1144
+ },
1145
+ posCenter: function(elem, outerWidth){
1146
+ var temp;
1147
+ if(this.options.calcCenter && (!this._init || this.element[0].offsetWidth)){
1148
+ if(!elem){
1149
+ elem = this.thumb;
1150
+ }
1151
+ if(!outerWidth){
1152
+ outerWidth = elem[this.dirs.outerWidth]();
1153
+ }
1154
+ outerWidth = outerWidth / -2;
1155
+ elem.css(this.dirs.marginLeft, outerWidth);
1156
+
1157
+ if(this.options.calcTrail && elem[0] == this.thumb[0]){
1158
+ temp = this.element[this.dirs.innerHeight]();
1159
+ elem.css(this.dirs.marginTop, (elem[this.dirs.outerHeight]() - temp) / -2);
1160
+ this.range.css(this.dirs.marginTop, (this.range[this.dirs.outerHeight]() - temp) / -2 );
1161
+ outerWidth *= -1;
1162
+ this.trail
1163
+ .css(this.dirs.left, outerWidth)
1164
+ .css(this.dirs.right, outerWidth)
1165
+ ;
1166
+ }
1167
+ }
1143
1168
  },
1144
1169
  updateMetrics: function(){
1145
1170
  var width = this.element.innerWidth();
1146
1171
  this.vertical = (width && this.element.innerHeight() - width > 10);
1147
1172
 
1148
1173
  this.dirs = this.vertical ?
1149
- {mouse: 'pageY', pos: 'top', min: 'max', max: 'min', left: 'top', width: 'height', outerWidth: 'outerHeight'} :
1150
- {mouse: 'pageX', pos: 'left', min: 'min', max: 'max', left: 'left', width: 'width', outerWidth: 'outerWidth'}
1174
+ {mouse: 'pageY', pos: 'top', min: 'max', max: 'min', left: 'top', right: 'bottom', width: 'height', innerWidth: 'innerHeight', innerHeight: 'innerWidth', outerWidth: 'outerHeight', outerHeight: 'outerWidth', marginTop: 'marginLeft', marginLeft: 'marginTop'} :
1175
+ {mouse: 'pageX', pos: 'left', min: 'min', max: 'max', left: 'left', right: 'right', width: 'width', innerWidth: 'innerWidth', innerHeight: 'innerHeight', outerWidth: 'outerWidth', outerHeight: 'outerHeight', marginTop: 'marginTop', marginLeft: 'marginLeft'}
1151
1176
  ;
1152
1177
  this.element
1153
1178
  [this.vertical ? 'addClass' : 'removeClass']('vertical-range')
1154
1179
  [this.vertical ? 'addClass' : 'removeClass']('horizontal-range')
1155
1180
  ;
1181
+ this.posCenter();
1156
1182
  }
1157
1183
  };
1158
1184
 
1159
1185
  $.fn.rangeUI = function(opts){
1160
- opts = $.extend({readonly: false, disabled: false, tabindex: 0, min: 0, step: 1, max: 100, value: 50, input: $.noop, change: $.noop, _change: $.noop, showLabels: true, options: {}}, opts);
1186
+ opts = $.extend({
1187
+ readonly: false,
1188
+ disabled: false,
1189
+ tabindex: 0,
1190
+ min: 0,
1191
+ step: 1,
1192
+ max: 100,
1193
+ value: 50,
1194
+ input: $.noop,
1195
+ change: $.noop,
1196
+ _change: $.noop,
1197
+ showLabels: true,
1198
+ options: {},
1199
+ calcCenter: true,
1200
+ calcTrail: true
1201
+ }, opts);
1161
1202
  return this.each(function(){
1162
- $.webshims.objectCreate(rangeProto, {
1203
+ webshims.objectCreate(rangeProto, {
1163
1204
  element: {
1164
1205
  value: $(this)
1165
1206
  }
1166
1207
  }, opts);
1167
1208
  });
1168
1209
  };
1169
- jQuery.webshims.isReady('range-ui', true);
1210
+ webshims.isReady('range-ui', true);
1170
1211
  })(jQuery);
1171
- jQuery.webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1212
+ webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1172
1213
  "use strict";
1173
1214
  var curCfg;
1174
- var formcfg = $.webshims.formcfg;
1215
+ var formcfg = webshims.formcfg;
1175
1216
 
1176
1217
  var stopPropagation = function(e){
1177
1218
  e.stopImmediatePropagation(e);
@@ -1189,7 +1230,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1189
1230
  date: {
1190
1231
  _create: function(){
1191
1232
  var obj = {
1192
- splits: [$('<input type="text" class="yy" size="4" maxlength />')[0], $('<input type="text" class="mm" maxlength="2" size="2" />')[0], $('<input type="text" class="dd ws-spin" maxlength="2" size="2" />')[0]]
1233
+ splits: [$('<input type="text" class="yy" size="4" inputmode="numeric" />')[0], $('<input type="text" class="mm" inputmode="numeric" maxlength="2" size="2" />')[0], $('<input type="text" class="dd ws-spin" inputmode="numeric" maxlength="2" size="2" />')[0]]
1193
1234
  };
1194
1235
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1], $('<span class="ws-input-seperator" />')[0], obj.splits[2]];
1195
1236
  return obj;
@@ -1215,7 +1256,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1215
1256
  month: {
1216
1257
  _create: function(){
1217
1258
  var obj = {
1218
- splits: [$('<input type="text" class="yy" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
1259
+ splits: [$('<input type="text" class="yy" inputmode="numeric" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
1219
1260
  };
1220
1261
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1]];
1221
1262
  return obj;
@@ -1235,6 +1276,23 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1235
1276
  }
1236
1277
  }
1237
1278
  };
1279
+
1280
+ var steps = {
1281
+ number: {
1282
+ step: 1
1283
+ },
1284
+ time: {
1285
+ step: 60
1286
+ },
1287
+ month: {
1288
+ step: 1,
1289
+ start: new Date()
1290
+ },
1291
+ date: {
1292
+ step: 1,
1293
+ start: new Date()
1294
+ }
1295
+ };
1238
1296
  var labelWidth = (function(){
1239
1297
  var getId = function(){
1240
1298
  return webshims.getID(this);
@@ -1259,7 +1317,8 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1259
1317
 
1260
1318
  (function(){
1261
1319
  var monthDigits = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
1262
- formcfg.de = {
1320
+
1321
+ formcfg.de = $.extend(true, {
1263
1322
  numberFormat: {
1264
1323
  ",": ".",
1265
1324
  ".": ","
@@ -1293,9 +1352,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1293
1352
  showMonthAfterYear: false,
1294
1353
  yearSuffix: ''
1295
1354
  }
1296
- };
1355
+ }, formcfg.de || {});
1297
1356
 
1298
- formcfg.en = {
1357
+ formcfg.en = $.extend(true, {
1299
1358
  numberFormat: {
1300
1359
  ".": ".",
1301
1360
  ",": ","
@@ -1327,13 +1386,17 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1327
1386
  "showMonthAfterYear": false,
1328
1387
  "yearSuffix": ""
1329
1388
  }
1330
- };
1389
+ }, formcfg['en'] || {});
1390
+ if(!formcfg['en-US']){
1391
+ formcfg['en-US'] = formcfg['en'];
1392
+ }
1393
+ if(!formcfg['']){
1394
+ formcfg[''] = formcfg['en-US'];
1395
+ }
1331
1396
 
1332
- formcfg['en-US'] = formcfg['en-US'] || formcfg['en'];
1333
- formcfg[''] = formcfg[''] || formcfg['en-US'];
1334
1397
  curCfg = formcfg[''];
1335
1398
 
1336
- var createMonthKeys = function(langCfg){
1399
+ var processLangCFG = function(langCfg){
1337
1400
  if(!langCfg.date.monthkeys){
1338
1401
  var create = function(i, name){
1339
1402
  var strNum;
@@ -1349,24 +1412,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1349
1412
  $.each(langCfg.date.monthNames, create);
1350
1413
  $.each(langCfg.date.monthNamesShort, create);
1351
1414
  }
1415
+ if(!langCfg.colorSigns){
1416
+ langCfg.colorSigns = '#abcdefABCDEF';
1417
+ }
1352
1418
  };
1353
1419
 
1354
- createMonthKeys(curCfg);
1420
+ processLangCFG(curCfg);
1355
1421
 
1356
- $.webshims.ready('dom-extend', function(){
1357
- $.webshims.activeLang({
1358
- register: 'form-core',
1359
- callback: function(){
1360
- $.each(arguments, function(i, val){
1361
- if(formcfg[val]){
1362
- curCfg = formcfg[val];
1363
- createMonthKeys(curCfg);
1364
- $(document).triggerHandler('wslocalechange');
1365
- return false;
1366
- }
1367
- });
1368
- }
1369
- });
1422
+ $.webshims.activeLang({
1423
+ register: 'form-core',
1424
+ callback: function(){
1425
+ $.each(arguments, function(i, val){
1426
+ if(formcfg[val]){
1427
+ curCfg = formcfg[val];
1428
+ processLangCFG(curCfg);
1429
+ $(document).triggerHandler('wslocalechange');
1430
+ return false;
1431
+ }
1432
+ });
1433
+ }
1370
1434
  });
1371
1435
  })();
1372
1436
 
@@ -1386,8 +1450,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1386
1450
  return val * 1;
1387
1451
  };
1388
1452
 
1389
- var createOpts = ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value'];
1390
-
1391
1453
 
1392
1454
  var formatVal = {
1393
1455
  number: function(val){
@@ -1426,6 +1488,16 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1426
1488
  }
1427
1489
 
1428
1490
  return val;
1491
+ },
1492
+ color: function(val, opts){
1493
+ var ret = '#000000';
1494
+ if(val){
1495
+ val = val.toLowerCase();
1496
+ if(val.length == 7 && createHelper('color').isValid(val)) {
1497
+ ret = val;
1498
+ }
1499
+ }
1500
+ return ret;
1429
1501
  }
1430
1502
  };
1431
1503
 
@@ -1440,7 +1512,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1440
1512
 
1441
1513
  var p = (!opts.splitInput) ? val.trim().split(/[\.\s-\/\\]+/) : val;
1442
1514
 
1443
- if(p.length == 2){
1515
+ if(p.length == 2 && p[0] && p[1]){
1444
1516
  p[0] = curCfg.date.monthkeys[p[0]] || p[0];
1445
1517
  p[1] = curCfg.date.monthkeys[p[1]] || p[1];
1446
1518
  if(p[1].length == 2){
@@ -1470,27 +1542,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1470
1542
  ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-') :
1471
1543
  ''
1472
1544
  ;
1473
- }
1474
- };
1475
-
1476
- var steps = {
1477
- number: {
1478
- step: 1
1479
1545
  },
1480
- time: {
1481
- step: 60
1482
- },
1483
- month: {
1484
- step: 1,
1485
- start: new Date()
1486
- },
1487
- date: {
1488
- step: 1,
1489
- start: new Date()
1546
+ color: function(val, opts){
1547
+ var ret = '#000000';
1548
+ if(val){
1549
+ val = val.toLowerCase();
1550
+ if (val.indexOf('#') !== 0) {
1551
+ val = '#' + val;
1552
+ }
1553
+ if(val.length == 4){
1554
+ val = '#' + val.charAt(1) + val.charAt(1) + val.charAt(2) + val.charAt(2) + val.charAt(3) + val.charAt(3);
1555
+ }
1556
+ if(val.length == 7 && createHelper('color').isValid(val)) {
1557
+ ret = val;
1558
+ }
1559
+ }
1560
+ return ret;
1490
1561
  }
1491
1562
  };
1492
1563
 
1493
-
1494
1564
  var placeholderFormat = {
1495
1565
  date: function(val, opts){
1496
1566
  var hintValue = (val || '').split('-');
@@ -1535,6 +1605,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1535
1605
  asValue: function(val){
1536
1606
  var type = (typeof val == 'object') ? 'valueAsDate' : 'valueAsNumber';
1537
1607
  return input.prop(type, val).prop('value');
1608
+ },
1609
+ isValid: function(val){
1610
+ return input.prop('value', val).is(':valid') && input.prop('value') == val;
1538
1611
  }
1539
1612
  };
1540
1613
  }
@@ -1544,244 +1617,113 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1544
1617
 
1545
1618
  steps.range = steps.number;
1546
1619
 
1547
-
1548
- var spinBtnProto = {
1620
+ var wsWidgetProto = {
1549
1621
  _create: function(){
1550
- var i;
1622
+ var i, that, timedMirror;
1551
1623
  var o = this.options;
1552
- var helper = createHelper(o.type);
1624
+ var createOpts = this.createOpts;
1625
+
1553
1626
  this.type = o.type;
1554
1627
  this.orig = o.orig;
1555
1628
 
1556
- this.elemHelper = $('<input type="'+ this.type+'" />');
1557
- this.asNumber = helper.asNumber;
1558
- this.asValue = helper.asValue;
1629
+ this.buttonWrapper = $('<span class="input-buttons '+this.type+'-input-buttons"></span>').insertAfter(this.element);
1630
+ this.options.containerElements.push(this.buttonWrapper[0]);
1559
1631
 
1560
- this.buttonWrapper = $('<span class="input-buttons '+this.type+'-input-buttons"><span unselectable="on" class="step-controls"><span class="step-up"></span><span class="step-down"></span></span></span>')
1561
- .insertAfter(this.element)
1562
- ;
1632
+ o.mirrorValidity = o.mirrorValidity && this.orig && Modernizr.formvalidation && !webshims.bugs.bustedValidity;
1563
1633
 
1564
- if(o.splitInput){
1634
+ if(o.splitInput && this._addSplitInputs){
1565
1635
  this._addSplitInputs();
1566
1636
  } else {
1567
1637
  this.inputElements = this.element;
1568
1638
  }
1569
1639
 
1570
- this.options.containerElements.push(this.buttonWrapper[0]);
1571
-
1572
- if(typeof steps[this.type].start == 'object'){
1640
+ if( steps[this.type] && typeof steps[this.type].start == 'object'){
1573
1641
  steps[this.type].start = this.asNumber(steps[this.type].start);
1574
1642
  }
1575
1643
 
1576
-
1577
-
1578
1644
  for(i = 0; i < createOpts.length; i++){
1579
- this[createOpts[i]](o[createOpts[i]]);
1580
- }
1581
-
1582
- this.element.data('wsspinner', this);
1583
-
1584
- this.addBindings();
1585
-
1586
- if(!o.min && typeof o.relMin == 'number'){
1587
- o.min = this.asValue(this.getRelNumber(o.relMin));
1588
- $.prop(this.orig, 'min', o.min);
1645
+ if(o[createOpts[i]] != null){
1646
+ this[createOpts[i]](o[createOpts[i]], o[createOpts[i]]);
1647
+ }
1589
1648
  }
1590
-
1591
- if(!o.max && typeof o.relMax == 'number'){
1592
- o.max = this.asValue(this.getRelNumber(o.relMax));
1593
- $.prop(this.orig, 'max', o.max);
1649
+ if(this.type == 'color'){
1650
+ this.inputElements.prop('maxLength', 7);
1594
1651
  }
1652
+ this.addBindings();
1653
+ $(this.element).data('wsWidget'+o.type, this);
1595
1654
 
1596
1655
  this._init = true;
1597
- },
1598
- _addSplitInputs: function(){
1599
- if(!this.inputElements){
1600
- var create = splitInputs[this.type]._create();
1601
- this.splits = create.splits;
1602
- this.inputElements = $(create.elements).prependTo(this.element).filter('input');
1603
- }
1604
- },
1605
- parseValue: function(){
1606
- var value = this.inputElements.map(function(){
1607
- return $.prop(this, 'value');
1608
- }).get();
1609
- if(!this.options.splitInput){
1610
- value = value[0];
1611
- }
1612
- return parseVal[this.type](value, this.options);
1613
- },
1614
- formatValue: function(val, noSplit){
1615
- return formatVal[this.type](val, noSplit === false ? false : this.options);
1616
- },
1617
- placeholder: function(val){
1618
- var options = this.options;
1619
- options.placeholder = val;
1620
- var placeholder = val;
1621
- if(placeholderFormat[this.type]){
1622
- placeholder = placeholderFormat[this.type](val, this.options);
1623
- }
1624
- if(options.splitInput && typeof placeholder == 'object'){
1625
- $.each(this.splits, function(i, elem){
1626
- $.prop(elem, 'placeholder', placeholder[i]);
1627
- });
1628
- } else {
1629
- this.element.prop('placeholder', placeholder);
1630
- }
1631
- },
1632
- getRelNumber: function(rel){
1633
- var start = steps[this.type].start || 0;
1634
- if(rel){
1635
- start += rel;
1636
- }
1637
- return start;
1638
- },
1639
- addZero: addZero,
1640
- _setStartInRange: function(){
1641
- var start = this.getRelNumber(this.options.relDefaultValue);
1642
- if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
1643
- start = this.minAsNumber;
1644
- } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
1645
- start = this.maxAsNumber;
1646
- }
1647
- this.elemHelper.prop('valueAsNumber', start);
1648
- this.options.defValue = this.elemHelper.prop('value');
1649
1656
 
1650
- },
1651
- reorderInputs: function(){
1652
- if(splitInputs[this.type]){
1653
- var element = this.element;
1654
- splitInputs[this.type].sort(element);
1655
- setTimeout(function(){
1656
- var data = webshims.data(element);
1657
- if(data && data.shadowData){
1658
- data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
1657
+ if(o.mirrorValidity){
1658
+ that = this;
1659
+ timedMirror = function(){
1660
+ clearTimeout(timedMirror._timerDealy);
1661
+ timedMirror._timerDealy = setTimeout(timedMirror._wsexec, 9);
1662
+ };
1663
+ timedMirror._wsexec = function(){
1664
+ clearTimeout(timedMirror._timerDealy);
1665
+ that.mirrorValidity(true);
1666
+ };
1667
+
1668
+ timedMirror();
1669
+ $(this.orig).on('change input', function(e){
1670
+ if(e.type == 'input'){
1671
+ timedMirror();
1672
+ } else {
1673
+ timedMirror._wsexec();
1659
1674
  }
1660
- }, 9);
1675
+ });
1661
1676
  }
1662
1677
  },
1663
- value: function(val){
1664
- this.valueAsNumber = this.asNumber(val);
1665
- this.options.value = val;
1666
- if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
1667
- this._setStartInRange();
1668
- } else {
1669
- this.elemHelper.prop('value', val);
1670
- this.options.defValue = "";
1671
- }
1672
-
1673
- val = formatVal[this.type](val, this.options);
1674
- if(this.options.splitInput){
1675
-
1676
- $.each(this.splits, function(i, elem){
1677
- $.prop(elem, 'value', val[i]);
1678
- });
1679
- } else {
1680
- this.element.prop('value', val);
1678
+ mirrorValidity: function(_noTest){
1679
+ //
1680
+ if(this._init && this.options.mirrorValidity){
1681
+ if(!_noTest){
1682
+ $.prop(this.orig, 'validity');
1683
+ }
1684
+ var message = $(this.orig).getErrorMessage();
1685
+ if(message !== this.lastErrorMessage){
1686
+ this.inputElements.prop('setCustomValidity', function(i, val){
1687
+ if(val._supvalue){
1688
+ val._supvalue.call(this, message);
1689
+ }
1690
+ });
1691
+ this.lastErrorMessage = message;
1692
+ }
1681
1693
  }
1682
-
1683
- this._propertyChange('value');
1684
1694
  },
1685
- initDataList: function(){
1686
- var listTimer;
1695
+ addBindings: function(){
1696
+ var isFocused;
1697
+
1687
1698
  var that = this;
1688
- var updateList = function(){
1689
- $(that.orig)
1690
- .jProp('list')
1691
- .off('updateDatalist', updateList)
1692
- .on('updateDatalist', updateList)
1693
- ;
1694
- clearTimeout(listTimer);
1695
- listTimer = setTimeout(function(){
1696
- if(that.list){
1697
- that.list();
1699
+ var o = this.options;
1700
+
1701
+ var eventTimer = (function(){
1702
+ var events = {};
1703
+ return {
1704
+ init: function(name, curVal, fn){
1705
+ if(!events[name]){
1706
+ events[name] = {fn: fn};
1707
+ $(that.orig).on(name, function(){
1708
+ events[name].val = $.prop(that.orig, 'value');
1709
+ });
1710
+ }
1711
+ events[name].val = curVal;
1712
+ },
1713
+ call: function(name, val){
1714
+ if(events[name] && events[name].val != val){
1715
+ clearTimeout(events[name].timer);
1716
+ events[name].val = val;
1717
+ events[name].timer = setTimeout(function(){
1718
+ events[name].fn(val, that);
1719
+ }, 9);
1720
+ }
1698
1721
  }
1699
- }, 9);
1700
-
1701
- };
1702
-
1703
- $(this.orig).onTrigger('listdatalistchange', updateList);
1704
- },
1705
- getOptions: function(){
1706
- var options = {};
1707
- var datalist = $(this.orig).jProp('list');
1708
- datalist.find('option').each(function(){
1709
- options[$.prop(this, 'value')] = $.prop(this, 'label');
1710
- });
1711
- return [options, datalist.data('label')];
1712
- },
1713
- list: function(val){
1714
- if(this.type == 'number' || this.type == 'time'){
1715
- this.element.attr('list', $.attr(this.orig, 'list'));
1716
- }
1717
- this.options.list = val;
1718
- this._propertyChange('list');
1719
- },
1720
- _propertyChange: $.noop,
1721
- tabindex: function(val){
1722
- this.options.tabindex = val;
1723
- this.inputElements.prop('tabindex', this.options.tabindex);
1724
- },
1725
- title: function(val){
1726
- this.options.title = val;
1727
- this.element.prop('title', this.options.title);
1728
- },
1729
-
1730
- min: function(val){
1731
- this.elemHelper.prop('min', val);
1732
- this.minAsNumber = this.asNumber(val);
1733
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
1734
- this._setStartInRange();
1735
- }
1736
- this.options.min = val;
1737
- this._propertyChange('min');
1738
- },
1739
- max: function(val){
1740
- this.elemHelper.prop('max', val);
1741
- this.maxAsNumber = this.asNumber(val);
1742
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
1743
- this._setStartInRange();
1744
- }
1745
- this.options.max = val;
1746
- this._propertyChange('max');
1747
- },
1748
- step: function(val){
1749
- var defStep = steps[this.type];
1750
- this.options.step = val;
1751
- this.elemHelper.prop('step', retDefault(val, defStep.step));
1752
- },
1753
- addBindings: function(){
1754
- var isFocused;
1755
-
1756
- var that = this;
1757
- var o = this.options;
1758
-
1759
- var eventTimer = (function(){
1760
- var events = {};
1761
- return {
1762
- init: function(name, curVal, fn){
1763
- if(!events[name]){
1764
- events[name] = {fn: fn};
1765
- $(that.orig).on(name, function(){
1766
- events[name].val = $.prop(that.orig, 'value');
1767
- });
1768
- }
1769
- events[name].val = curVal;
1770
- },
1771
- call: function(name, val){
1772
- if(events[name] && events[name].val != val){
1773
- clearTimeout(events[name].timer);
1774
- events[name].val = val;
1775
- events[name].timer = setTimeout(function(){
1776
- events[name].fn(val, that);
1777
- }, 9);
1778
- }
1779
- }
1780
- };
1781
- })();
1782
- var initChangeEvents = function(){
1783
- eventTimer.init('input', $.prop(that.orig, 'value'), that.options.input);
1784
- eventTimer.init('change', $.prop(that.orig, 'value'), that.options.change);
1722
+ };
1723
+ })();
1724
+ var initChangeEvents = function(){
1725
+ eventTimer.init('input', $.prop(that.orig, 'value'), that.options.input);
1726
+ eventTimer.init('change', $.prop(that.orig, 'value'), that.options.change);
1785
1727
  };
1786
1728
 
1787
1729
  var step = {};
@@ -1801,6 +1743,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1801
1743
  var val;
1802
1744
  clearTimeout(timer);
1803
1745
  val = that.parseValue();
1746
+ if(that.type == 'color'){
1747
+ that.inputElements.val(val);
1748
+ }
1804
1749
  $.prop(that.orig, 'value', val);
1805
1750
  eventTimer.call('input', val);
1806
1751
  if(!e || e.type != 'wsupdatevalue'){
@@ -1837,6 +1782,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1837
1782
  ;
1838
1783
  setTimeout(function(){
1839
1784
  if(that.popover){
1785
+ that.popover.element.on('wspopoverhide', onBlur);
1840
1786
  $('> *', that.popover.element)
1841
1787
  .on({
1842
1788
  'focusin': onFocus,
@@ -1917,7 +1863,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1917
1863
  e.preventDefault();
1918
1864
  }
1919
1865
  }
1920
- }
1866
+ };
1921
1867
  })()
1922
1868
  };
1923
1869
  var mouseDownInit = function(){
@@ -1941,28 +1887,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1941
1887
  };
1942
1888
  })();
1943
1889
 
1944
- ['stepUp', 'stepDown'].forEach(function(name){
1945
- step[name] = function(factor){
1946
- if(!o.disabled && !o.readonly){
1947
- if(!isFocused){
1948
- mouseDownInit();
1949
- }
1950
- var ret = false;
1951
- if (!factor) {
1952
- factor = 1;
1953
- }
1954
- try {
1955
- that.elemHelper[name](factor);
1956
- ret = that.elemHelper.prop('value');
1957
- that.value(ret);
1958
- eventTimer.call('input', ret);
1959
- } catch (er) {}
1960
- return ret;
1961
- }
1962
- };
1963
- });
1964
-
1965
-
1966
1890
 
1967
1891
  this.buttonWrapper.on('mousedown', mouseDownInit);
1968
1892
 
@@ -1979,960 +1903,415 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1979
1903
 
1980
1904
  this.inputElements.on(elementEvts);
1981
1905
 
1982
- if(!o.noSpinbtn){
1983
- spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
1984
- if(delta && isFocused && !o.disabled){
1985
- step[delta > 0 ? 'stepUp' : 'stepDown']();
1986
- e.preventDefault();
1987
- }
1988
- };
1989
- spinEvents.keydown = function(e){
1990
- if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
1991
- var stepped = true;
1992
- var code = e.keyCode;
1993
- if (code == 38) {
1994
- step.stepUp();
1995
- } else if (code == 40) {
1996
- step.stepDown();
1997
- } else {
1998
- stepped = false;
1999
- }
2000
- if(stepped){
2001
- e.preventDefault();
2002
- }
2003
- };
2004
-
2005
- spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
2006
- }
2007
-
2008
-
2009
- if(!o.splitInput){
2010
- $(document).on('wslocalechange',function(){
2011
- if(o.value){
2012
- that.value(o.value);
2013
- }
2014
-
2015
- if(placeholderFormat[that.type] && o.placeholder){
2016
- that.placeholder(o.placeholder);
2017
- }
2018
- });
2019
- } else {
2020
- $(document).onTrigger('wslocalechange',function(){
2021
- that.reorderInputs();
1906
+ if(steps[this.type]){
1907
+ ['stepUp', 'stepDown'].forEach(function(name){
1908
+ step[name] = function(factor){
1909
+ if(!o.disabled && !o.readonly){
1910
+ if(!isFocused){
1911
+ mouseDownInit();
1912
+ }
1913
+ var ret = false;
1914
+ if (!factor) {
1915
+ factor = 1;
1916
+ }
1917
+ try {
1918
+ that.elemHelper[name](factor);
1919
+ ret = that.elemHelper.prop('value');
1920
+ that.value(ret);
1921
+ eventTimer.call('input', ret);
1922
+ } catch (er) {}
1923
+ return ret;
1924
+ }
1925
+ };
2022
1926
  });
2023
- }
2024
-
2025
- $('.step-up', this.buttonWrapper)
2026
- .on({
2027
- 'mousepressstart mousepressend': mousePress,
2028
- 'mousedown mousepress': function(e){
2029
- step.stepUp();
2030
- }
2031
- })
2032
- ;
2033
- $('.step-down', this.buttonWrapper)
2034
- .on({
2035
- 'mousepressstart mousepressend': mousePress,
2036
- 'mousedown mousepress': function(e){
2037
- step.stepDown();
2038
- }
2039
- })
2040
- ;
2041
- initChangeEvents();
2042
- }
2043
- };
2044
-
2045
- ['readonly', 'disabled'].forEach(function(name){
2046
- spinBtnProto[name] = function(val){
2047
- if(this.options[name] != val || !this._init){
2048
- this.options[name] = !!val;
2049
- if(name == 'readonly' && this.options.noInput){
2050
- this.element
2051
- .prop(name, true)
2052
- .attr({'aria-readonly': this.options[name]})
2053
- ;
2054
- } else {
2055
- this.element.prop(name, this.options[name]);
1927
+ if(!o.noSpinbtn){
1928
+ spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
1929
+ if(delta && isFocused && !o.disabled){
1930
+ step[delta > 0 ? 'stepUp' : 'stepDown']();
1931
+ e.preventDefault();
1932
+ }
1933
+ };
1934
+ spinEvents.keydown = function(e){
1935
+ if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
1936
+ var stepped = true;
1937
+ var code = e.keyCode;
1938
+ if (code == 38) {
1939
+ step.stepUp();
1940
+ } else if (code == 40) {
1941
+ step.stepDown();
1942
+ } else {
1943
+ stepped = false;
1944
+ }
1945
+ if(stepped){
1946
+ e.preventDefault();
1947
+ }
1948
+ };
1949
+
1950
+ spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
2056
1951
  }
2057
- this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
1952
+ $(this.buttonWrapper)
1953
+ .on('mousepressstart mousepressend', '.step-up, .step-down', mousePress)
1954
+ .on('mousedown mousepress', '.step-up', function(e){
1955
+ step.stepUp();
1956
+ })
1957
+ .on('mousedown mousepress', '.step-down', function(e){
1958
+ step.stepDown();
1959
+ })
1960
+ ;
2058
1961
  }
2059
- };
2060
- });
2061
-
2062
-
2063
- $.fn.spinbtnUI = function(opts){
2064
- opts = $.extend({
2065
- monthNames: 'monthNames',
2066
- size: 1,
2067
- startView: 0
2068
- }, opts);
2069
- return this.each(function(){
2070
- $.webshims.objectCreate(spinBtnProto, {
2071
- element: {
2072
- value: $(this)
2073
- }
2074
- }, opts);
2075
- });
2076
- };
2077
- })();
2078
-
2079
- (function(){
2080
- var picker = {};
2081
- var disable = {
2082
-
2083
- };
2084
-
2085
- var getDateArray = function(date){
2086
- var ret = [date.getFullYear(), addZero(date.getMonth() + 1), addZero(date.getDate())];
2087
- ret.month = ret[0]+'-'+ret[1];
2088
- ret.date = ret[0]+'-'+ret[1]+'-'+ret[2];
2089
- return ret;
2090
- };
2091
- var today = getDateArray(new Date());
1962
+ if(this.type != 'color'){
1963
+ (function(){
1964
+ var localeChange ;
1965
+ if(!o.splitInput){
1966
+ localeChange = function(){
1967
+ if(o.value){
1968
+ that.value(o.value);
1969
+ }
2092
1970
 
2093
- var _setFocus = function(element, _noFocus){
2094
- var setFocus, that;
2095
- element = $(element || this.activeButton);
2096
- this.activeButton.attr({tabindex: '-1', 'aria-selected': 'false'});
2097
- this.activeButton = element.attr({tabindex: '0', 'aria-selected': 'true'});
2098
- this.index = this.buttons.index(this.activeButton[0]);
2099
-
2100
- clearTimeout(this.timer);
2101
-
2102
- if(!this.popover.openedByFocus && !_noFocus){
2103
- that = this;
2104
- setFocus = function(noTrigger){
2105
- clearTimeout(that.timer);
2106
- that.timer = setTimeout(function(){
2107
- if(element[0]){
2108
- element[0].focus();
2109
- if(noTrigger !== true && !element.is(':focus')){
2110
- setFocus(true);
2111
- }
1971
+ if(placeholderFormat[that.type] && o.placeholder){
1972
+ that.placeholder(o.placeholder);
1973
+ }
1974
+ };
1975
+ } else {
1976
+ localeChange = function(){
1977
+ that.reorderInputs();
1978
+ };
1979
+ that.reorderInputs();
2112
1980
  }
2113
- }, that.popover.isVisible ? 99 : 360);
2114
- };
2115
- this.popover.activateElement(element);
2116
- setFocus();
2117
- }
2118
-
2119
- };
2120
-
2121
- var _initialFocus = function(){
2122
- var sel;
2123
- if(this.popover.navedInitFocus){
2124
- sel = this.popover.navedInitFocus.sel || this.popover.navedInitFocus;
2125
- if((!this.activeButton || !this.activeButton[0]) && this.buttons[sel]){
2126
- this.activeButton = this.buttons[sel]();
2127
- } else if(sel){
2128
- this.activeButton = $(sel, this.element);
1981
+ $(that.orig).onWSOff('wslocalechange', localeChange);
1982
+ })();
2129
1983
  }
2130
1984
 
2131
- if(!this.activeButton[0] && this.popover.navedInitFocus.alt){
2132
- this.activeButton = this.buttons[this.popover.navedInitFocus.alt]();
1985
+ initChangeEvents();
1986
+ },
1987
+ value: function(val){
1988
+ if(!this._init || val !== this.options.value){
1989
+ this.element.val(this.formatValue(val));
1990
+ this.options.value = val;
1991
+ this._propertyChange('value');
1992
+ this.mirrorValidity();
2133
1993
  }
2134
- }
2135
-
2136
- if(!this.activeButton || !this.activeButton[0]){
2137
- this.activeButton = this.buttons.filter('.checked-value');
2138
- }
2139
-
2140
- if(!this.activeButton[0]){
2141
- this.activeButton = this.buttons.filter('.this-value');
2142
- }
2143
- if(!this.activeButton[0]){
2144
- this.activeButton = this.buttons.eq(0);
2145
- }
2146
-
2147
- this.setFocus(this.activeButton, this.opts.noFocus);
2148
- };
2149
-
2150
-
2151
- webshims.ListBox = function (element, popover, opts){
2152
- this.element = $('ul', element);
2153
- this.popover = popover;
2154
- this.opts = opts || {};
2155
- this.buttons = $('button:not(:disabled)', this.element);
2156
-
2157
-
2158
- this.ons(this);
2159
- this._initialFocus();
2160
- };
2161
-
2162
- webshims.ListBox.prototype = {
2163
- setFocus: _setFocus,
2164
- _initialFocus: _initialFocus,
2165
- prev: function(){
2166
- var index = this.index - 1;
2167
- if(index < 0){
2168
- if(this.opts.prev){
2169
- this.popover.navedInitFocus = 'last';
2170
- this.popover.actionFn(this.opts.prev);
2171
- this.popover.navedInitFocus = false;
2172
- }
2173
- } else {
2174
- this.setFocus(this.buttons.eq(index));
1994
+
1995
+ },
1996
+ required: function(val, boolVal){
1997
+ this.inputElements.attr({'aria-required': ''+boolVal});
1998
+ this.mirrorValidity();
1999
+ },
2000
+ parseValue: function(){
2001
+ var value = this.inputElements.map(function(){
2002
+ return $.prop(this, 'value');
2003
+ }).get();
2004
+ if(!this.options.splitInput){
2005
+ value = value[0];
2175
2006
  }
2007
+ return parseVal[this.type](value, this.options);
2176
2008
  },
2177
- next: function(){
2178
- var index = this.index + 1;
2179
- if(index >= this.buttons.length){
2180
- if(this.opts.next){
2181
- this.popover.navedInitFocus = 'first';
2182
- this.popover.actionFn(this.opts.next);
2183
- this.popover.navedInitFocus = false;
2184
- }
2009
+ formatValue: function(val, noSplit){
2010
+ return formatVal[this.type](val, noSplit === false ? false : this.options);
2011
+ },
2012
+ createOpts: ['readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
2013
+ placeholder: function(val){
2014
+ var options = this.options;
2015
+ options.placeholder = val;
2016
+ var placeholder = val;
2017
+ if(placeholderFormat[this.type]){
2018
+ placeholder = placeholderFormat[this.type](val, this.options);
2019
+ }
2020
+ if(options.splitInput && typeof placeholder == 'object'){
2021
+ $.each(this.splits, function(i, elem){
2022
+ $.prop(elem, 'placeholder', placeholder[i]);
2023
+ });
2185
2024
  } else {
2186
- this.setFocus(this.buttons.eq(index));
2025
+ this.element.prop('placeholder', placeholder);
2187
2026
  }
2188
2027
  },
2189
- ons: function(that){
2190
- this.element
2191
- .on({
2192
- 'keydown': function(e){
2193
- var handled;
2194
- var key = e.keyCode;
2195
- if(e.ctrlKey){return;}
2196
- if(key == 36 || key == 33){
2197
- that.setFocus(that.buttons.eq(0));
2198
- handled = true;
2199
- } else if(key == 34 || key == 35){
2200
- that.setFocus(that.buttons.eq(that.buttons.length - 1));
2201
- handled = true;
2202
- } else if(key == 38 || key == 37){
2203
- that.prev();
2204
- handled = true;
2205
- } else if(key == 40 || key == 39){
2206
- that.next();
2207
- handled = true;
2208
- }
2209
- if(handled){
2210
- return false;
2211
- }
2028
+ initDataList: function(){
2029
+ var listTimer;
2030
+ var that = this;
2031
+ var updateList = function(){
2032
+ $(that.orig)
2033
+ .jProp('list')
2034
+ .off('updateDatalist', updateList)
2035
+ .on('updateDatalist', updateList)
2036
+ ;
2037
+ clearTimeout(listTimer);
2038
+ listTimer = setTimeout(function(){
2039
+ if(that.list){
2040
+ that.list();
2212
2041
  }
2213
- })
2214
- ;
2215
- }
2216
- };
2217
-
2218
- webshims.Grid = function (element, popover, opts){
2219
- this.element = $('tbody', element);
2220
- this.popover = popover;
2221
- this.opts = opts || {};
2222
- this.buttons = $('button:not(:disabled,.othermonth)', this.element);
2223
-
2224
- this.ons(this);
2225
-
2226
- this._initialFocus();
2227
- if(this.popover.openedByFocus){
2228
- this.popover.activeElement = this.activeButton;
2229
- }
2230
- };
2231
-
2232
-
2233
-
2234
- webshims.Grid.prototype = {
2235
- setFocus: _setFocus,
2236
- _initialFocus: _initialFocus,
2237
-
2238
- first: function(){
2239
- this.setFocus(this.buttons.eq(0));
2042
+ }, 9);
2043
+
2044
+ };
2045
+
2046
+ $(this.orig).onTrigger('listdatalistchange', updateList);
2240
2047
  },
2241
- last: function(){
2242
- this.setFocus(this.buttons.eq(this.buttons.length - 1));
2048
+ getOptions: function(){
2049
+ var options = {};
2050
+ var datalist = $(this.orig).jProp('list');
2051
+ datalist.find('option').each(function(){
2052
+ options[$.prop(this, 'value')] = $.prop(this, 'label');
2053
+ });
2054
+ return [options, datalist.data('label')];
2243
2055
  },
2244
- upPage: function(){
2245
- $('.ws-picker-header > button:not(:disabled)', this.popover.element).trigger('click');
2056
+ list: function(val){
2057
+ if(this.type == 'number' || this.type == 'time'){
2058
+ this.element.attr('list', $.attr(this.orig, 'list'));
2059
+ }
2060
+ this.options.list = val;
2061
+ this._propertyChange('list');
2246
2062
  },
2247
- downPage: function(){
2248
- this.activeButton.filter(':not([data-action="changeInput"])').trigger('click');
2063
+ _propertyChange: $.noop,
2064
+ tabindex: function(val){
2065
+ this.options.tabindex = val;
2066
+ this.inputElements.prop('tabindex', this.options.tabindex);
2067
+ $('button', this.buttonWrapper).prop('tabindex', this.options.tabindex);
2249
2068
  },
2250
- ons: function(that){
2251
- this.element
2252
- .on({
2253
- 'keydown': function(e){
2254
- var handled;
2255
- var key = e.keyCode;
2256
-
2257
- if(e.shiftKey){return;}
2258
-
2259
- if((e.ctrlKey && key == 40)){
2260
- handled = 'downPage';
2261
- } else if((e.ctrlKey && key == 38)){
2262
- handled = 'upPage';
2263
- } else if(key == 33 || (e.ctrlKey && key == 37)){
2264
- handled = 'prevPage';
2265
- } else if(key == 34 || (e.ctrlKey && key == 39)){
2266
- handled = 'nextPage';
2267
- } else if(e.keyCode == 36 || e.keyCode == 33){
2268
- handled = 'first';
2269
- } else if(e.keyCode == 35){
2270
- handled = 'last';
2271
- } else if(e.keyCode == 38){
2272
- handled = 'up';
2273
- } else if(e.keyCode == 37){
2274
- handled = 'prev';
2275
- } else if(e.keyCode == 40){
2276
- handled = 'down';
2277
- } else if(e.keyCode == 39){
2278
- handled = 'next';
2279
- }
2280
- if(handled){
2281
- that[handled]();
2282
- return false;
2283
- }
2284
- }
2285
- })
2286
- ;
2287
- }
2288
- };
2289
- $.each({
2290
- prevPage: {get: 'last', action: 'prev'},
2291
- nextPage: {get: 'first', action: 'next'}
2292
- }, function(name, val){
2293
- webshims.Grid.prototype[name] = function(){
2294
- if(this.opts[val.action]){
2295
- this.popover.navedInitFocus = {
2296
- sel: 'button[data-id="'+ this.activeButton.attr('data-id') +'"]:not(:disabled,.othermonth)',
2297
- alt: val.get
2298
- };
2299
- this.popover.actionFn(this.opts[val.action]);
2300
- this.popover.navedInitFocus = false;
2301
- }
2302
- };
2303
- });
2304
-
2305
- $.each({
2306
- up: {traverse: 'prevAll', get: 'last', action: 'prev', reverse: true},
2307
- down: {traverse: 'nextAll', get: 'first', action: 'next'}
2308
- }, function(name, val){
2309
- webshims.Grid.prototype[name] = function(){
2310
- var cellIndex = this.activeButton.closest('td').prop('cellIndex');
2311
- var sel = 'td:nth-child('+(cellIndex + 1)+') button:not(:disabled,.othermonth)';
2312
- var button = this.activeButton.closest('tr')[val.traverse]();
2313
-
2314
- if(val.reverse){
2315
- button = $(button.get().reverse());
2316
- }
2317
- button = button.find(sel)[val.get]();
2318
-
2319
- if(!button[0]){
2320
- if(this.opts[val.action]){
2321
- this.popover.navedInitFocus = sel+':'+val.get;
2322
- this.popover.actionFn(this.opts[val.action]);
2323
- this.popover.navedInitFocus = false;
2324
- }
2325
- } else {
2326
- this.setFocus(button.eq(0));
2327
- }
2328
- };
2329
- });
2330
-
2331
- $.each({
2332
- prev: {traverse: 'prevAll',get: 'last', reverse: true},
2333
- next: {traverse: 'nextAll', get: 'first'}
2334
- }, function(name, val){
2335
- webshims.Grid.prototype[name] = function(){
2336
- var sel = 'button:not(:disabled,.othermonth)';
2337
- var button = this.activeButton.closest('td')[val.traverse]('td');
2338
- if(val.reverse){
2339
- button = $(button.get().reverse());
2340
- }
2341
- button = button.find(sel)[val.get]();
2342
- if(!button[0]){
2343
- button = this.activeButton.closest('tr')[val.traverse]('tr');
2344
- if(val.reverse){
2345
- button = $(button.get().reverse());
2346
- }
2347
- button = button.find(sel)[val.get]();
2069
+ title: function(val){
2070
+ if(!val && this.orig && $.attr(this.orig, 'title') == null){
2071
+ val = null;
2348
2072
  }
2349
-
2350
- if(!button[0]){
2351
- if(this.opts[name]){
2352
- this.popover.navedInitFocus = val.get;
2353
- this.popover.actionFn(this.opts[name]);
2354
- this.popover.navedInitFocus = false;
2355
- }
2073
+ this.options.title = val;
2074
+ if(val == null){
2075
+ this.inputElements.removeAttr('title');
2356
2076
  } else {
2357
- this.setFocus(button.eq(0));
2358
- }
2359
- };
2360
- });
2361
-
2362
- picker.getWeek = function(date){
2363
- var onejan = new Date(date.getFullYear(),0,1);
2364
- return Math.ceil((((date - onejan) / 86400000) + onejan.getDay()+1)/7);
2365
- };
2366
- picker.getYearList = function(value, data){
2367
- var j, i, val, disabled, lis, prevDisabled, nextDisabled, classStr, classArray, start;
2368
-
2369
-
2370
- var size = data.options.size;
2371
- var max = data.options.max.split('-');
2372
- var min = data.options.min.split('-');
2373
- var currentValue = data.options.value.split('-');
2374
- var xthCorrect = 0;
2375
- var enabled = 0;
2376
- var str = '';
2377
- var rowNum = 0;
2378
-
2379
- if(data.options.useDecadeBase == 'max' && max[0]){
2380
- xthCorrect = 11 - (max[0] % 12);
2381
- } else if(data.options.useDecadeBase == 'min' && min[0]){
2382
- xthCorrect = 11 - (min[0] % 12);
2383
- }
2384
-
2385
- value = value[0] * 1;
2386
- start = value - ((value + xthCorrect) % (12 * size));
2387
-
2388
-
2389
-
2390
- for(j = 0; j < size; j++){
2391
- if(j){
2392
- start += 12;
2393
- } else {
2394
- prevDisabled = picker.isInRange([start-1], max, min) ? {'data-action': 'setYearList','value': start-1} : false;
2395
- }
2396
-
2397
- str += '<div class="year-list picker-list ws-index-'+ j +'"><div class="ws-picker-header"><button disabled="disabled">'+ start +' – '+(start + 11)+'</button></div>';
2398
- lis = [];
2399
- for(i = 0; i < 12; i++){
2400
- val = start + i ;
2401
- classArray = [];
2402
- if( !picker.isInRange([val], max, min) ){
2403
- disabled = ' disabled=""';
2404
- } else {
2405
- disabled = '';
2406
- enabled++;
2407
- }
2408
-
2409
- if(val == today[0]){
2410
- classArray.push('this-value');
2411
- }
2412
-
2413
- if(currentValue[0] == val){
2414
- classArray.push('checked-value');
2415
- }
2416
-
2417
- classStr = classArray.length ? ' class="'+ (classArray.join(' ')) +'"' : '';
2418
-
2419
- if(i && !(i % 3)){
2420
- rowNum++;
2421
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2422
- }
2423
- lis.push('<td class="ws-item-'+ i +'" role="presentation"><button data-id="year-'+ i +'" type="button"'+ disabled + classStr +' data-action="setMonthList" value="'+val+'" tabindex="-1" role="gridcell">'+val+'</button></td>');
2077
+ this.inputElements.prop('title', this.options.title);
2424
2078
  }
2425
- if(j == size - 1){
2426
- nextDisabled = picker.isInRange([val+1], max, min) ? {'data-action': 'setYearList','value': val+1} : false;
2427
- }
2428
- str += '<div class="picker-grid"><table role="grid" aria-label="'+ start +' – '+(start + 11)+'"><tbody><tr class="ws-row-0">'+ (lis.join(''))+ '</tr></tbody></table></div></div>';
2429
2079
  }
2430
-
2431
- return {
2432
- enabled: enabled,
2433
- main: str,
2434
- next: nextDisabled,
2435
- prev: prevDisabled,
2436
- type: 'Grid'
2437
- };
2438
2080
  };
2439
2081
 
2440
2082
 
2441
- picker.getMonthList = function(value, data){
2442
-
2443
- var j, i, name, val, disabled, lis, fullyDisabled, prevDisabled, nextDisabled, classStr, classArray;
2444
- var o = data.options;
2445
- var size = o.size;
2446
- var max = o.max.split('-');
2447
- var min = o.min.split('-');
2448
- var currentValue = o.value.split('-');
2449
- var enabled = 0;
2450
- var rowNum = 0;
2451
- var str = '';
2452
-
2453
- value = value[0] - Math.floor((size - 1) / 2);
2454
- for(j = 0; j < size; j++){
2455
- if(j){
2456
- value++;
2457
- } else {
2458
- prevDisabled = picker.isInRange([value-1], max, min) ? {'data-action': 'setMonthList','value': value-1} : false;
2459
- }
2460
- if(j == size - 1){
2461
- nextDisabled = picker.isInRange([value+1], max, min) ? {'data-action': 'setMonthList','value': value+1} : false;
2462
- }
2463
- lis = [];
2464
-
2465
- if( !picker.isInRange([value, '01'], max, min) && !picker.isInRange([value, '12'], max, min)){
2466
- disabled = ' disabled=""';
2467
- fullyDisabled = true;
2468
- } else {
2469
- fullyDisabled = false;
2470
- disabled = '';
2471
- }
2472
-
2473
- if(o.minView >= 1){
2474
- disabled = ' disabled=""';
2475
- }
2476
-
2477
- str += '<div class="month-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">';
2478
-
2479
- str += o.selectNav ?
2480
- '<select data-action="setMonthList" class="year-select">'+ picker.createYearSelect(value, max, min).join('') +'</select>' :
2481
- '<button data-action="setYearList"'+disabled+' value="'+ value +'" tabindex="-1">'+ value +'</button>';
2482
- str += '</div>';
2483
-
2484
- for(i = 0; i < 12; i++){
2485
- val = curCfg.date.monthkeys[i+1];
2486
- name = (curCfg.date[o.monthNames] || curCfg.date.monthNames)[i];
2487
- classArray = [];
2488
- if(fullyDisabled || !picker.isInRange([value, val], max, min) ){
2489
- disabled = ' disabled=""';
2490
- } else {
2491
- disabled = '';
2492
- enabled++;
2493
- }
2494
-
2495
- if(value == today[0] && today[1] == val){
2496
- classArray.push('this-value');
2497
- }
2498
-
2499
- if(currentValue[0] == value && currentValue[1] == val){
2500
- classArray.push('checked-value');
2501
- }
2502
-
2503
- classStr = (classArray.length) ? ' class="'+ (classArray.join(' ')) +'"' : '';
2504
- if(i && !(i % 3)){
2505
- rowNum++;
2506
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2083
+ ['readonly', 'disabled'].forEach(function(name){
2084
+ var isDisabled = name == 'disabled';
2085
+ wsWidgetProto[name] = function(val, boolVal){
2086
+ if(this.options[name] != boolVal || !this._init){
2087
+ this.options[name] = !!boolVal;
2088
+ this.inputElements.prop(name, this.options[name]);
2089
+ this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
2090
+ if(isDisabled){
2091
+ $('button', this.buttonWrapper).prop('disabled', this.options[name]);
2507
2092
  }
2508
-
2509
- lis.push('<td class="ws-item-'+ i +'" role="presentation"><button data-id="month-'+ i +'" type="button"'+ disabled + classStr +' data-action="'+ (data.type == 'month' ? 'changeInput' : 'setDayList' ) +'" value="'+value+'-'+val+'" tabindex="-1" role="gridcell" aria-label="'+ curCfg.date.monthNames[i] +'">'+name+'</button></td>');
2510
-
2511
2093
  }
2512
-
2513
- str += '<div class="picker-grid"><table role="grid" aria-label="'+value+'"><tbody><tr class="ws-row-0">'+ (lis.join(''))+ '</tr></tbody></table></div></div>';
2514
- }
2515
-
2516
- return {
2517
- enabled: enabled,
2518
- main: str,
2519
- prev: prevDisabled,
2520
- next: nextDisabled,
2521
- type: 'Grid'
2522
2094
  };
2523
- };
2524
-
2095
+ });
2525
2096
 
2526
- picker.getDayList = function(value, data){
2527
-
2528
- var j, i, k, day, nDay, name, val, disabled, lis, prevDisabled, nextDisabled, addTr, week, rowNum;
2529
-
2530
- var lastMotnh, curMonth, otherMonth, dateArray, monthName, fullMonthName, buttonStr, date2, classArray;
2531
- var o = data.options;
2532
- var size = o.size;
2533
- var max = o.max.split('-');
2534
- var min = o.min.split('-');
2535
- var currentValue = o.value.split('-');
2536
- var monthNames = curCfg.date[o.monthNamesHead] || curCfg.date[o.monthNames] || curCfg.date.monthNames;
2537
- var enabled = 0;
2538
- var str = [];
2539
- var date = new Date(value[0], value[1] - 1, 1);
2540
-
2541
- date.setMonth(date.getMonth() - Math.floor((size - 1) / 2));
2542
-
2543
- for(j = 0; j < size; j++){
2544
- date.setDate(1);
2545
- lastMotnh = date.getMonth();
2546
- rowNum = 0;
2547
- if(!j){
2548
- date2 = new Date(date.getTime());
2549
- date2.setDate(-1);
2550
- dateArray = getDateArray(date2);
2551
- prevDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray[0]+'-'+dateArray[1]} : false;
2552
- }
2553
-
2554
- dateArray = getDateArray(date);
2555
-
2556
- str.push('<div class="day-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">');
2557
- if( o.selectNav ){
2558
- monthName = ['<select data-action="setDayList" class="month-select" tabindex="0">'+ picker.createMonthSelect(dateArray, max, min, monthNames).join('') +'</select>', '<select data-action="setDayList" class="year-select" tabindex="0">'+ picker.createYearSelect(dateArray[0], max, min, '-'+dateArray[1]).join('') +'</select>'];
2559
- if(curCfg.date.showMonthAfterYear){
2560
- monthName.reverse();
2561
- }
2562
- str.push( monthName.join(' ') );
2563
- }
2097
+ var spinBtnProto = $.extend({}, wsWidgetProto, {
2098
+ _create: function(){
2099
+ var o = this.options;
2100
+ var helper = createHelper(o.type);
2564
2101
 
2565
- fullMonthName = [curCfg.date.monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
2566
- monthName = [monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
2567
- if(curCfg.date.showMonthAfterYear){
2568
- monthName.reverse();
2569
- fullMonthName.reverse();
2570
- }
2102
+ this.elemHelper = $('<input type="'+ o.type+'" />');
2103
+ this.asNumber = helper.asNumber;
2104
+ this.asValue = helper.asValue;
2105
+
2106
+ wsWidgetProto._create.apply(this, arguments);
2107
+ this._init = false;
2108
+
2109
+ this.buttonWrapper.html('<span unselectable="on" class="step-controls"><span class="step-up"></span><span class="step-down"></span></span>');
2571
2110
 
2572
- if(!data.options.selectNav) {
2573
- str.push(
2574
- '<button data-action="setMonthList"'+ (o.minView >= 2 ? ' disabled="" ' : '') +' value="'+ dateArray.date +'" tabindex="-1">'+ monthName.join(' ') +'</button>'
2575
- );
2111
+ if(this.type == 'number'){
2112
+ this.inputElements.attr('inputmode', 'numeric');
2576
2113
  }
2577
2114
 
2578
2115
 
2579
- str.push('</div><div class="picker-grid"><table role="grid" aria-label="'+ fullMonthName.join(' ') +'"><thead><tr>');
2116
+ if(!o.min && typeof o.relMin == 'number'){
2117
+ o.min = this.asValue(this.getRelNumber(o.relMin));
2118
+ $.prop(this.orig, 'min', o.min);
2119
+ }
2580
2120
 
2581
- if(data.options.showWeek){
2582
- str.push('<th class="week-header">'+ curCfg.date.weekHeader +'</th>');
2121
+ if(!o.max && typeof o.relMax == 'number'){
2122
+ o.max = this.asValue(this.getRelNumber(o.relMax));
2123
+ $.prop(this.orig, 'max', o.max);
2583
2124
  }
2584
- for(k = curCfg.date.firstDay; k < curCfg.date.dayNamesShort.length; k++){
2585
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2125
+ this._init = true;
2126
+ },
2127
+ createOpts: ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
2128
+ _addSplitInputs: function(){
2129
+ if(!this.inputElements){
2130
+ var create = splitInputs[this.type]._create();
2131
+ this.splits = create.splits;
2132
+ this.inputElements = $(create.elements).prependTo(this.element).filter('input');
2586
2133
  }
2587
- k = curCfg.date.firstDay;
2588
- while(k--){
2589
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2134
+ },
2135
+
2136
+ getRelNumber: function(rel){
2137
+ var start = steps[this.type].start || 0;
2138
+ if(rel){
2139
+ start += rel;
2590
2140
  }
2591
- str.push('</tr></thead><tbody><tr class="ws-row-0">');
2592
-
2593
- if(data.options.showWeek) {
2594
- week = picker.getWeek(date);
2595
- str.push('<td class="week-cell">'+ week +'</td>');
2141
+ return start;
2142
+ },
2143
+ addZero: addZero,
2144
+ _setStartInRange: function(){
2145
+ var start = this.getRelNumber(this.options.relDefaultValue);
2146
+ if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
2147
+ start = this.minAsNumber;
2148
+ } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
2149
+ start = this.maxAsNumber;
2596
2150
  }
2151
+ this.elemHelper.prop('valueAsNumber', start);
2152
+ this.options.defValue = this.elemHelper.prop('value');
2597
2153
 
2598
- for (i = 0; i < 99; i++) {
2599
- addTr = (i && !(i % 7));
2600
- curMonth = date.getMonth();
2601
- otherMonth = lastMotnh != curMonth;
2602
- day = date.getDay();
2603
- classArray = [];
2604
-
2605
- if(addTr && otherMonth ){
2606
- str.push('</tr>');
2607
- break;
2608
- }
2609
- if(addTr){
2610
- rowNum++;
2611
- str.push('</tr><tr class="ws-row-'+ rowNum +'">');
2612
- if(data.options.showWeek) {
2613
- week++;
2614
- str.push('<td class="week-cell">'+ week +'</td>');
2615
- }
2616
- }
2617
-
2618
- if(!i){
2619
-
2620
- if(day != curCfg.date.firstDay){
2621
- nDay = day - curCfg.date.firstDay;
2622
- if(nDay < 0){
2623
- nDay += 7;
2624
- }
2625
- date.setDate(date.getDate() - nDay);
2626
- day = date.getDay();
2627
- curMonth = date.getMonth();
2628
- otherMonth = lastMotnh != curMonth;
2154
+ },
2155
+ reorderInputs: function(){
2156
+ if(splitInputs[this.type]){
2157
+ var element = this.element;
2158
+ splitInputs[this.type].sort(element);
2159
+ setTimeout(function(){
2160
+ var data = webshims.data(element);
2161
+ if(data && data.shadowData){
2162
+ data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
2629
2163
  }
2630
- }
2631
-
2632
- dateArray = getDateArray(date);
2633
- buttonStr = '<td role="presentation" class="day-'+ day +'"><button data-id="day-'+ date.getDate() +'" role="gridcell" data-action="changeInput" value="'+ (dateArray.join('-')) +'"';
2164
+ }, 9);
2165
+ }
2166
+ },
2167
+ value: function(val){
2168
+
2169
+ if(!this._init || this.options.value !== val){
2170
+ this.valueAsNumber = this.asNumber(val);
2171
+ this.options.value = val;
2634
2172
 
2635
- if(otherMonth){
2636
- classArray.push('othermonth');
2173
+ if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
2174
+ this._setStartInRange();
2637
2175
  } else {
2638
- classArray.push('day-'+date.getDate());
2639
- }
2640
-
2641
- if(dateArray[0] == today[0] && today[1] == dateArray[1] && today[2] == dateArray[2]){
2642
- classArray.push('this-value');
2643
- }
2644
-
2645
- if(currentValue[0] == dateArray[0] && dateArray[1] == currentValue[1] && dateArray[2] == currentValue[2]){
2646
- classArray.push('checked-value');
2647
- }
2648
-
2649
- if(classArray.length){
2650
- buttonStr += ' class="'+ classArray.join(' ') +'"';
2176
+ this.elemHelper.prop('value', val);
2177
+ this.options.defValue = "";
2651
2178
  }
2652
2179
 
2653
- if(!picker.isInRange(dateArray, max, min) || (data.options.disableDays && $.inArray(day, data.options.disableDays) != -1)){
2654
- buttonStr += ' disabled=""';
2180
+ val = formatVal[this.type](val, this.options);
2181
+ if(this.options.splitInput){
2182
+ $.each(this.splits, function(i, elem){
2183
+ $.prop(elem, 'value', val[i]);
2184
+ });
2185
+ } else {
2186
+ this.element.prop('value', val);
2655
2187
  }
2656
-
2657
- str.push(buttonStr+' tabindex="-1">'+ date.getDate() +'</button></td>');
2658
-
2659
- date.setDate(date.getDate() + 1);
2660
- }
2661
- str.push('</tbody></table></div></div>');
2662
- if(j == size - 1){
2663
- dateArray = getDateArray(date);
2664
- dateArray[2] = 1;
2665
- nextDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray.date} : false;
2188
+ this._propertyChange('value');
2189
+ this.mirrorValidity();
2666
2190
  }
2191
+ },
2192
+ step: function(val){
2193
+ var defStep = steps[this.type];
2194
+ this.options.step = val;
2195
+ this.elemHelper.prop('step', retDefault(val, defStep.step));
2196
+ this.mirrorValidity();
2667
2197
  }
2668
-
2669
-
2670
- return {
2671
- enabled: 9,
2672
- main: str.join(''),
2673
- prev: prevDisabled,
2674
- next: nextDisabled,
2675
- type: 'Grid'
2676
- };
2677
- };
2198
+ });
2678
2199
 
2679
- picker.isInRange = function(values, max, min){
2680
- var i;
2681
- var ret = true;
2682
- for(i = 0; i < values.length; i++){
2683
-
2684
- if(min[i] && min[i] > values[i]){
2685
- ret = false;
2686
- break;
2687
- } else if( !(min[i] && min[i] == values[i]) ){
2688
- break;
2200
+ $.each({min: 1, max: -1}, function(name, factor){
2201
+ var numName = name +'AsNumber';
2202
+ spinBtnProto[name] = function(val){
2203
+ this.elemHelper.prop(name, val);
2204
+ this[numName] = this.asNumber(val);
2205
+ if(this.valueAsNumber != null && (isNaN(this.valueAsNumber) || (!isNaN(this[numName]) && (this.valueAsNumber * factor) < (this[numName] * factor)))){
2206
+ this._setStartInRange();
2689
2207
  }
2690
- }
2691
- if(ret){
2692
- for(i = 0; i < values.length; i++){
2693
-
2694
- if((max[i] && max[i] < values[i])){
2695
- ret = false;
2696
- break;
2697
- } else if( !(max[i] && max[i] == values[i]) ){
2698
- break;
2208
+ this.options[name] = val;
2209
+ this._propertyChange(name);
2210
+ this.mirrorValidity();
2211
+ };
2212
+ });
2213
+
2214
+ $.fn.wsBaseWidget = function(opts){
2215
+ opts = $.extend({}, opts);
2216
+ return this.each(function(){
2217
+ $.webshims.objectCreate(wsWidgetProto, {
2218
+ element: {
2219
+ value: $(this)
2699
2220
  }
2700
- }
2701
- }
2702
- return ret;
2221
+ }, opts);
2222
+ });
2703
2223
  };
2704
2224
 
2705
- picker.createMonthSelect = function(value, max, min, monthNames){
2706
- if(!monthNames){
2707
- monthNames = curCfg.date.monthNames;
2708
- }
2709
-
2710
- var selected;
2711
- var i = 0;
2712
- var options = [];
2713
- var tempVal = value[1]-1;
2714
- for(; i < monthNames.length; i++){
2715
- selected = tempVal == i ? ' selected=""' : '';
2716
- if(selected || picker.isInRange([value[0], i+1], max, min)){
2717
- options.push('<option value="'+ value[0]+'-'+addZero(i+1) + '"'+selected+'>'+ monthNames[i] +'</option>');
2718
- }
2225
+ $.fn.spinbtnUI = function(opts){
2226
+ opts = $.extend({
2227
+ monthNames: 'monthNames',
2228
+ size: 1,
2229
+ startView: 0
2230
+ }, opts);
2231
+ return this.each(function(){
2232
+ $.webshims.objectCreate(spinBtnProto, {
2233
+ element: {
2234
+ value: $(this)
2235
+ }
2236
+ }, opts);
2237
+ });
2238
+ };
2239
+ })();
2240
+
2241
+ (function(){
2242
+ var picker = {};
2243
+
2244
+ var loadPicker = function(type, name){
2245
+ type = (type == 'color' ? 'color' : 'forms')+'-picker';
2246
+ if(!loadPicker[name+'Loaded'+type]){
2247
+ loadPicker[name+'Loaded'+type] = true;
2248
+ webshims.ready(name, function(){
2249
+ webshims.loader.loadList([type]);
2250
+ });
2719
2251
  }
2720
- return options;
2252
+ return type;
2721
2253
  };
2254
+ options.addZero = addZero;
2255
+ webshims.loader.addModule('forms-picker', {
2256
+ noAutoCallback: true,
2257
+ options: options
2258
+ });
2259
+ webshims.loader.addModule('color-picker', {
2260
+ noAutoCallback: true,
2261
+ css: 'jpicker/jpicker.css',
2262
+ options: options
2263
+ });
2722
2264
 
2723
- picker.createYearSelect = function(value, max, min, valueAdd){
2724
-
2725
- var temp;
2726
- var goUp = true;
2727
- var goDown = true;
2728
- var options = ['<option selected="">'+ value + '</option>'];
2729
- var i = 0;
2730
- if(!valueAdd){
2731
- valueAdd = '';
2732
- }
2733
- while(i < 8 && (goUp || goDown)){
2734
- i++;
2735
- temp = value-i;
2736
- if(goUp && picker.isInRange([temp], max, min)){
2737
- options.unshift('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
2738
- } else {
2739
- goUp = false;
2740
- }
2741
- temp = value + i;
2742
- if(goDown && picker.isInRange([temp], max, min)){
2743
- options.push('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
2744
- } else {
2745
- goDown = false;
2746
- }
2265
+ picker._genericSetFocus = function(element, _noFocus){
2266
+ element = $(element || this.activeButton);
2267
+ if(!this.popover.openedByFocus && !_noFocus){
2268
+ var that = this;
2269
+ var setFocus = function(noTrigger){
2270
+ clearTimeout(that.timer);
2271
+ that.timer = setTimeout(function(){
2272
+ if(element[0]){
2273
+ element[0].focus();
2274
+ if(noTrigger !== true && !element.is(':focus')){
2275
+ setFocus(true);
2276
+ }
2277
+ }
2278
+ }, that.popover.isVisible ? 99 : 360);
2279
+ };
2280
+ this.popover.activateElement(element);
2281
+ setFocus();
2747
2282
  }
2748
- return options;
2749
2283
  };
2750
-
2751
- var actions = {
2284
+
2285
+ picker._actions = {
2752
2286
  changeInput: function(val, popover, data){
2287
+ picker._actions.cancel(val, popover, data);
2288
+ data.setChange(val);
2289
+ },
2290
+ cancel: function(val, popover, data){
2753
2291
  popover.stopOpen = true;
2754
2292
  data.element.getShadowFocusElement().focus();
2755
2293
  setTimeout(function(){
2756
2294
  popover.stopOpen = false;
2757
2295
  }, 9);
2758
2296
  popover.hide();
2759
- data.setChange(val);
2760
2297
  }
2761
2298
  };
2762
2299
 
2763
- (function(){
2764
- var retNames = function(name){
2765
- return 'get'+name+'List';
2766
- };
2767
- var retSetNames = function(name){
2768
- return 'set'+name+'List';
2769
- };
2770
- var stops = {
2771
- date: 'Day',
2772
- week: 'Day',
2773
- month: 'Month'
2774
- };
2775
-
2776
- $.each({'setYearList' : ['Year', 'Month', 'Day'], 'setMonthList': ['Month', 'Day'], 'setDayList': ['Day']}, function(setName, names){
2777
- var getNames = names.map(retNames);
2778
- var setNames = names.map(retSetNames);
2779
- actions[setName] = function(val, popover, data, startAt){
2780
- val = ''+val;
2781
- var o = data.options;
2782
- var values = val.split('-');
2783
- if(!startAt){
2784
- startAt = 0;
2785
- }
2786
- $.each(getNames, function(i, item){
2787
- if(i >= startAt){
2788
- var content = picker[item](values, data);
2789
-
2790
- if( values.length < 2 || content.enabled > 1 || stops[data.type] === names[i]){
2791
- popover.element
2792
- .attr({'data-currentview': setNames[i]})
2793
- .addClass('ws-size-'+o.size)
2794
- .data('pickercontent', {
2795
- data: data,
2796
- content: content,
2797
- values: values
2798
- })
2799
- ;
2800
- popover.bodyElement.html(content.main);
2801
- if(content.prev){
2802
- popover.prevElement
2803
- .attr(content.prev)
2804
- .prop({disabled: false})
2805
- ;
2806
- } else {
2807
- popover.prevElement
2808
- .removeAttr('data-action')
2809
- .prop({disabled: true})
2810
- ;
2811
- }
2812
- if(content.next){
2813
- popover.nextElement
2814
- .attr(content.next)
2815
- .prop({disabled: false})
2816
- ;
2817
- } else {
2818
- popover.nextElement
2819
- .removeAttr('data-action')
2820
- .prop({disabled: true})
2821
- ;
2822
- }
2823
- if(webshims[content.type]){
2824
- new webshims[content.type](popover.bodyElement.children(), popover, content);
2825
- }
2826
- popover.element.trigger('pickerchange');
2827
- return false;
2828
- }
2829
- }
2830
- });
2831
- };
2832
- });
2833
- })();
2834
2300
 
2835
2301
  picker.commonInit = function(data, popover){
2836
- var actionfn = function(e){
2837
- if(!$(this).is('.othermonth') || $(this).css('cursor') == 'pointer'){
2838
- popover.actionFn({
2839
- 'data-action': $.attr(this, 'data-action'),
2840
- value: $(this).val() || $.attr(this, 'value')
2841
- });
2842
- }
2843
- return false;
2844
- };
2845
- var id = new Date().getTime();
2846
- var generateList = function(o, max, min){
2847
- var options = [];
2848
- var label = '';
2849
- var labelId = '';
2850
- o.options = data.getOptions() || {};
2851
- $('div.ws-options', popover.contentElement).remove();
2852
- $.each(o.options[0], function(val, label){
2853
- var disabled = picker.isInRange(val.split('-'), o.maxS, o.minS) ?
2854
- '' :
2855
- ' disabled="" '
2856
- ;
2857
- options.push('<li role="presentation"><button value="'+ val +'" '+disabled+' data-action="changeInput" tabindex="-1" role="option">'+ (label || data.formatValue(val, false)) +'</button></li>');
2858
- });
2859
- if(options.length){
2860
- id++;
2861
- if(o.options[1]){
2862
- labelId = 'datalist-'+id;
2863
- label = '<h5 id="'+labelId+'">'+ o.options[1] +'</h5>';
2864
- labelId = ' aria-labelledbyid="'+ labelId +'" ';
2865
- }
2866
- new webshims.ListBox($('<div class="ws-options">'+label+'<ul role="listbox" '+ labelId +'>'+ options.join('') +'</div>').insertAfter(popover.bodyElement)[0], popover, {noFocus: true});
2867
- }
2868
- };
2869
- var updateContent = function(){
2870
- if(popover.isDirty){
2871
- var o = data.options;
2872
- o.maxS = o.max.split('-');
2873
- o.minS = o.min.split('-');
2874
-
2875
- $('button', popover.buttonRow).each(function(){
2876
- var text;
2877
- if($(this).is('.ws-empty')){
2878
- text = curCfg.date.clear;
2879
- if(!text){
2880
- text = formcfg[''].date.clear || 'clear';
2881
- webshims.warn("could not get clear text from form cfg");
2882
- }
2883
- } else if($(this).is('.ws-current')){
2884
- text = (curCfg[data.type] || {}).currentText;
2885
- if(!text){
2886
- text = (formcfg[''][[data.type]] || {}).currentText || 'current';
2887
- webshims.warn("could not get currentText from form cfg");
2888
- }
2889
- $.prop(this, 'disabled', !picker.isInRange(today[data.type].split('-'), o.maxS, o.minS));
2890
- }
2891
- if(text){
2892
- $(this).text(text).attr({'aria-label': text});
2893
- if(webshims.assumeARIA){
2894
- $.attr(this, 'aria-label', text);
2895
- }
2896
- }
2897
-
2898
- });
2899
- popover.nextElement.attr({'aria-label': curCfg.date.nextText});
2900
- $('> span', popover.nextElement).html(curCfg.date.nextText);
2901
- popover.prevElement.attr({'aria-label': curCfg.date.prevText});
2902
- $('> span', popover.prevElement).html(curCfg.date.prevText);
2903
-
2904
- generateList(o, o.maxS, o.minS);
2905
-
2906
- }
2907
- $('button.ws-empty', popover.buttonRow).prop('disabled', $.prop(data.orig, 'required'));
2908
- popover.isDirty = false;
2909
- };
2910
-
2911
- popover.actionFn = function(obj){
2912
- if(actions[obj['data-action']]){
2913
- actions[obj['data-action']](obj.value, popover, data, 0);
2914
- } else {
2915
- webshims.warn('no action for '+ obj['data-action']);
2916
- }
2917
- };
2918
-
2919
- popover.contentElement.html('<button class="ws-prev" tabindex="0"><span></span></button> <button class="ws-next" tabindex="0"><span></span></button><div class="ws-picker-body"></div><div class="ws-button-row"><button type="button" class="ws-current" data-action="changeInput" value="'+today[data.type]+'" tabindex="0"></button> <button type="button" data-action="changeInput" value="" class="ws-empty" tabindex="0"></button></div>');
2920
- popover.nextElement = $('button.ws-next', popover.contentElement);
2921
- popover.prevElement = $('button.ws-prev', popover.contentElement);
2922
- popover.bodyElement = $('div.ws-picker-body', popover.contentElement);
2923
- popover.buttonRow = $('div.ws-button-row', popover.contentElement);
2302
+ var tabbable;
2924
2303
 
2925
2304
  popover.isDirty = true;
2926
2305
 
2927
- popover.contentElement
2928
- .on('click', 'button[data-action]', actionfn)
2929
- .on('change', 'select[data-action]', actionfn)
2930
- ;
2931
-
2306
+ popover.element.on('updatepickercontent pickerchange', function(){
2307
+ tabbable = false;
2308
+ });
2932
2309
  popover.contentElement.on({
2933
2310
  keydown: function(e){
2934
2311
  if(e.keyCode == 9){
2935
- var tabbable = $('[tabindex="0"]:not(:disabled)', this).filter(':visible');
2312
+ if(!tabbable){
2313
+ tabbable = $('input:not(:disabled), [tabindex="0"]:not(:disabled)', this).filter(':visible');
2314
+ }
2936
2315
  var index = tabbable.index(e.target);
2937
2316
  if(e.shiftKey && index <= 0){
2938
2317
  tabbable.last().focus();
@@ -2950,18 +2329,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2950
2329
  }
2951
2330
  });
2952
2331
 
2953
- $(data.options.orig).on('input', function(){
2954
- var currentView;
2955
- if(data.options.updateOnInput && popover.isVisible && data.options.value && (currentView = popover.element.attr('data-currentview'))){
2956
- actions[currentView]( data.options.value , popover, data, 0);
2957
- }
2958
- });
2959
-
2960
2332
  data._propertyChange = (function(){
2961
2333
  var timer;
2962
2334
  var update = function(){
2963
2335
  if(popover.isVisible){
2964
- updateContent();
2336
+ popover.element.triggerHandler('updatepickercontent');
2965
2337
  }
2966
2338
  };
2967
2339
  return function(prop){
@@ -2987,50 +2359,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2987
2359
  popover.element.on({
2988
2360
  wspopoverbeforeshow: function(){
2989
2361
  data.element.triggerHandler('wsupdatevalue');
2990
- updateContent();
2362
+ popover.element.triggerHandler('updatepickercontent');
2991
2363
  }
2992
2364
  });
2993
2365
 
2994
- $(document).onTrigger('wslocalechange', data._propertyChange);
2366
+
2367
+ $(data.orig).on('remove', function(e){
2368
+ if(!e.originalEvent){
2369
+ $(document).off('wslocalechange', data._propertyChange);
2370
+ }
2371
+ });
2995
2372
  };
2996
2373
 
2374
+
2997
2375
  picker._common = function(data){
2998
2376
  var popover = webshims.objectCreate(webshims.wsPopover, {}, {prepareFor: data.element});
2999
2377
  var opener = $('<button type="button" class="ws-popover-opener"><span /></button>').appendTo(data.buttonWrapper);
3000
2378
  var options = data.options;
3001
- var init = false;
3002
2379
 
2380
+ var showPickerContent = function(){
2381
+ (picker[data.type].showPickerContent || picker.showPickerContent)(data, popover);
2382
+ };
3003
2383
  var show = function(){
2384
+ var type = loadPicker(data.type, 'DOM');
3004
2385
  if(!options.disabled && !options.readonly && !popover.isVisible){
3005
- if(!init){
3006
- picker.commonInit(data, popover);
3007
- }
3008
-
3009
- if(!init || data.options.restartView) {
3010
- actions.setYearList( options.defValue || options.value, popover, data, data.options.startView);
3011
- } else {
3012
- actions[popover.element.attr('data-currentview') || 'setYearList']( options.defValue || options.value, popover, data, 0);
3013
- }
3014
-
3015
- init = true;
2386
+ webshims.ready(type, showPickerContent);
3016
2387
  popover.show(data.element);
3017
2388
  }
3018
2389
  };
3019
2390
 
3020
2391
  options.containerElements.push(popover.element[0]);
3021
2392
 
3022
- if(!options.startView){
3023
- options.startView = 0;
3024
- }
3025
- if(!options.minView){
3026
- options.minView = 0;
3027
- }
3028
- if(options.startView < options.minView){
3029
- options.minView = options.startView;
3030
- webshims.warn("wrong config for minView/startView.");
3031
- }
3032
- if(!options.size){
3033
- options.size = 1;
2393
+ if(data.type != 'color'){
2394
+ if(!options.startView){
2395
+ options.startView = 0;
2396
+ }
2397
+ if(!options.minView){
2398
+ options.minView = 0;
2399
+ }
2400
+ if(options.startView < options.minView){
2401
+ options.startView = options.minView;
2402
+ webshims.warn("wrong config for minView/startView.");
2403
+ }
2404
+ if(!options.size){
2405
+ options.size = 1;
2406
+ }
3034
2407
  }
3035
2408
 
3036
2409
  popover.element
@@ -3057,10 +2430,15 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3057
2430
  labelWidth(popover.element.children('div.ws-po-outerbox').attr({role: 'group'}), options.labels, true);
3058
2431
  labelWidth(opener, options.labels, true);
3059
2432
 
2433
+ if(options.tabindex != null){
2434
+ opener.attr({tabindex: options.tabindex});
2435
+ }
2436
+
2437
+ if(options.disabled){
2438
+ opener.prop({disabled: true});
2439
+ }
2440
+
3060
2441
  opener
3061
- .attr({
3062
- 'tabindex': options.labels.length ? 0 : '-1'
3063
- })
3064
2442
  .on({
3065
2443
  mousedown: function(){
3066
2444
  stopPropagation.apply(this, arguments);
@@ -3105,10 +2483,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3105
2483
  });
3106
2484
  })();
3107
2485
  data.popover = popover;
2486
+ data.opener = opener;
2487
+ $(data.orig).on('remove', function(e){
2488
+ if(!e.originalEvent){
2489
+ opener.remove();
2490
+ popover.element.remove();
2491
+ }
2492
+ });
2493
+
2494
+ loadPicker(data.type, 'WINDOWLOAD');
3108
2495
  };
3109
2496
 
3110
2497
  picker.month = picker._common;
3111
- picker.date = picker.month;
2498
+ picker.date = picker._common;
2499
+ picker.color = function(data){
2500
+ var ret = picker._common.apply(this, arguments);
2501
+ var alpha = $(data.orig).data('alphacontrol');
2502
+ var colorIndicator = data.opener
2503
+ .prepend('<span class="ws-color-indicator-bg"><span class="ws-color-indicator" /></span>')
2504
+ .find('.ws-color-indicator')
2505
+ ;
2506
+ var showColor = function(){
2507
+ colorIndicator.css({backgroundColor: $.prop(this, 'value') || '#000'})
2508
+ };
2509
+ var showOpacity = (function(){
2510
+ var timer;
2511
+ var show = function(){
2512
+ try {
2513
+ var value = data.alpha.prop('valueAsNumber') / (data.alpha.prop('max') || 1);
2514
+ if(!isNaN(value)){
2515
+ colorIndicator.css({opacity: value});
2516
+ }
2517
+ } catch(er){}
2518
+
2519
+ };
2520
+ return function(e){
2521
+ clearTimeout(timer);
2522
+ timer = setTimeout(show, !e || e.type == 'change' ? 4: 40);
2523
+ };
2524
+ })();
2525
+ data.alpha = (alpha) ? $('#'+alpha) : $([]);
2526
+
2527
+ $(data.orig).on('wsupdatevalue change', showColor).each(showColor);
2528
+ data.alpha.on('wsupdatevalue change input', showOpacity).each(showOpacity);
2529
+ return ret;
2530
+ };
3112
2531
 
3113
2532
  webshims.picker = picker;
3114
2533
  })();
@@ -3129,6 +2548,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3129
2548
  'max',
3130
2549
  'step',
3131
2550
  'title',
2551
+ 'required',
3132
2552
  'placeholder'
3133
2553
  ];
3134
2554
 
@@ -3137,11 +2557,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3137
2557
 
3138
2558
  $.each(copyProps.concat(copyAttrs), function(i, name){
3139
2559
  var fnName = name.replace(/^data\-/, '');
3140
- webshims.onNodeNamesPropertyModify('input', name, function(val){
2560
+ webshims.onNodeNamesPropertyModify('input', name, function(val, boolVal){
3141
2561
  if(!stopCircular){
3142
2562
  var shadowData = webshims.data(this, 'shadowData');
3143
2563
  if(shadowData && shadowData.data && shadowData.nativeElement === this && shadowData.data[fnName]){
3144
- shadowData.data[fnName](val);
2564
+ shadowData.data[fnName](val, boolVal);
3145
2565
  }
3146
2566
  }
3147
2567
  });
@@ -3172,6 +2592,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3172
2592
  var sizeInput = function(data){
3173
2593
  var init;
3174
2594
  var updateStyles = function(){
2595
+ $(data.orig).removeClass('ws-important-hide');
3175
2596
  $.style( data.orig, 'display', '' );
3176
2597
  var hasButtons, marginR, marginL;
3177
2598
  var correctWidth = 0.6;
@@ -3205,13 +2626,14 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3205
2626
  data.element.outerWidth( $(data.orig).outerWidth() - correctWidth );
3206
2627
  }
3207
2628
  init = true;
3208
- $.style( data.orig, 'display', 'none' );
2629
+ $(data.orig).addClass('ws-important-hide');
3209
2630
  };
3210
- $(document).onTrigger('updateshadowdom', updateStyles);
2631
+ data.element.onWSOff('updateshadowdom', updateStyles, true);
3211
2632
  };
3212
2633
 
3213
2634
 
3214
2635
  var implementType = function(){
2636
+
3215
2637
  var type = $.prop(this, 'type');
3216
2638
 
3217
2639
  var i, opts, data, optsName, labels;
@@ -3266,7 +2688,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3266
2688
  data.shim.options.containerElements.push(data.shim.element[0]);
3267
2689
 
3268
2690
  labelWidth($(this).getShadowFocusElement(), labels);
3269
- $.attr(this, 'required', $.attr(this, 'required'));
2691
+
3270
2692
  $(this).on('change', function(e){
3271
2693
  if(!stopCircular){
3272
2694
  data.shim.value($.prop(this, 'value'));
@@ -3325,18 +2747,13 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3325
2747
 
3326
2748
  if(opts.calculateWidth){
3327
2749
  sizeInput(data.shim);
2750
+ } else {
2751
+ $(this).css({display: 'none'});
3328
2752
  }
3329
- $(this).css({display: 'none'});
3330
2753
  }
2754
+
3331
2755
  };
3332
2756
 
3333
- if(!modernizrInputTypes.range || options.replaceUI){
3334
- extendType('range', {
3335
- _create: function(opts, set){
3336
- return $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
3337
- }
3338
- });
3339
- }
3340
2757
 
3341
2758
  if(Modernizr.formvalidation){
3342
2759
  ['input', 'form'].forEach(function(name){
@@ -3353,12 +2770,20 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3353
2770
  });
3354
2771
  }
3355
2772
 
2773
+ if(!modernizrInputTypes.range || options.replaceUI){
2774
+ extendType('range', {
2775
+ _create: function(opts, set){
2776
+ var data = $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
2777
+ return data;
2778
+ }
2779
+ });
2780
+ }
3356
2781
 
3357
- ['number', 'time', 'month', 'date'].forEach(function(name){
3358
- if(!modernizrInputTypes[name] || options.replaceUI){
2782
+ var isStupid = navigator.userAgent.indexOf('MSIE 10.0') != -1 && navigator.userAgent.indexOf('Touch') == -1;
2783
+ ['number', 'time', 'month', 'date', 'color'].forEach(function(name){
2784
+ if(!modernizrInputTypes[name] || options.replaceUI || (name == 'number' && isStupid)){
3359
2785
  extendType(name, {
3360
2786
  _create: function(opts, set){
3361
-
3362
2787
  if(opts.splitInput && !splitInputs[name]){
3363
2788
  webshims.warn('splitInput not supported for '+ name);
3364
2789
  opts.splitInput = false;
@@ -3366,11 +2791,12 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3366
2791
  var markup = opts.splitInput ?
3367
2792
  '<span class="ws-'+name+' ws-input" role="group"></span>' :
3368
2793
  '<input class="ws-'+name+'" type="text" />';
3369
- var data = $(markup) //role="spinbutton"???
3370
- .insertAfter(opts.orig)
3371
- .spinbtnUI(opts)
3372
- .data('wsspinner')
3373
- ;
2794
+ var data = $(markup).insertAfter(opts.orig);
2795
+ if(steps[name]){
2796
+ data = data.spinbtnUI(opts).data('wsWidget'+name);
2797
+ } else {
2798
+ data = data.wsBaseWidget(opts).data('wsWidget'+name);
2799
+ }
3374
2800
  if(webshims.picker && webshims.picker[name]){
3375
2801
  webshims.picker[name](data);
3376
2802
  }