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,12 @@
1
- jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
1
+ webshims.register('form-message', function($, webshims, window, document, undefined, options){
2
2
  "use strict";
3
+ if(options.overrideMessages){
4
+ options.customMessages = true;
5
+ webshims.error('overrideMessages is deprecated. use customMessages instead.');
6
+ }
3
7
  var validityMessages = webshims.validityMessages;
4
8
 
5
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
9
+ var implementProperties = options.customMessages ? ['customValidationMessage'] : [];
6
10
 
7
11
  validityMessages.en = $.extend(true, {
8
12
  typeMismatch: {
@@ -33,17 +37,17 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
33
37
 
34
38
  if(typeof validityMessages['en'].valueMissing == 'object'){
35
39
  ['select', 'radio'].forEach(function(type){
36
- validityMessages.en.valueMissing[type] = 'Please select an option.';
40
+ validityMessages.en.valueMissing[type] = validityMessages.en.valueMissing[type] || 'Please select an option.';
37
41
  });
38
42
  }
39
43
  if(typeof validityMessages.en.rangeUnderflow == 'object'){
40
44
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
41
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
45
+ validityMessages.en.rangeUnderflow[type] = validityMessages.en.rangeUnderflow[type] || 'Value must be at or after {%min}.';
42
46
  });
43
47
  }
44
48
  if(typeof validityMessages.en.rangeOverflow == 'object'){
45
49
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
46
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
50
+ validityMessages.en.rangeOverflow[type] = validityMessages.en.rangeOverflow[type] || 'Value must be at or before {%max}.';
47
51
  });
48
52
  }
49
53
 
@@ -79,17 +83,17 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
79
83
 
80
84
  if(typeof validityMessages.de.valueMissing == 'object'){
81
85
  ['select', 'radio'].forEach(function(type){
82
- validityMessages.de.valueMissing[type] = 'Bitte wählen Sie eine Option aus.';
86
+ validityMessages.de.valueMissing[type] = validityMessages.de.valueMissing[type] || 'Bitte wählen Sie eine Option aus.';
83
87
  });
84
88
  }
85
89
  if(typeof validityMessages.de.rangeUnderflow == 'object'){
86
90
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
87
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
91
+ validityMessages.de.rangeUnderflow[type] = validityMessages.de.rangeUnderflow[type] || '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
88
92
  });
89
93
  }
90
94
  if(typeof validityMessages.de.rangeOverflow == 'object'){
91
95
  ['date', 'time', 'datetime-local', 'month'].forEach(function(type){
92
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
96
+ validityMessages.de.rangeOverflow[type] = validityMessages.de.rangeOverflow[type] || '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
93
97
  });
94
98
  }
95
99
 
@@ -107,12 +111,12 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
107
111
  };
108
112
 
109
113
  webshims.createValidationMessage = function(elem, name){
110
- var spinner;
114
+ var widget;
111
115
  var message = getMessageFromObj(currentValidationMessage[name], elem);
112
-
116
+ var type = $.prop(elem, 'type');
113
117
  if(!message){
114
- message = getMessageFromObj(validityMessages[''][name], elem) || 'invalid value';
115
- webshims.info('could not find errormessage for: '+ name +' / '+ $.prop(elem, 'type') +'. in language: '+$.webshims.activeLang());
118
+ message = getMessageFromObj(validityMessages[''][name], elem) || $.prop(elem, 'validationMessage');
119
+ webshims.info('could not find errormessage for: '+ name +' / '+ type +'. in language: '+$.webshims.activeLang());
116
120
  }
117
121
  if(message){
118
122
  ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
@@ -122,11 +126,11 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
122
126
  webshims.error('no title for patternMismatch provided. Always add a title attribute.');
123
127
  }
124
128
  if(valueVals[attr]){
125
- if(!spinner){
126
- spinner = $(elem).getShadowElement().data('wsspinner');
129
+ if(!widget){
130
+ widget = $(elem).getShadowElement().data('wsWidget'+type);
127
131
  }
128
- if(spinner && spinner.formatValue){
129
- val = spinner.formatValue(val, false);
132
+ if(widget && widget.formatValue){
133
+ val = widget.formatValue(val, false);
130
134
  }
131
135
  }
132
136
  message = message.replace('{%'+ attr +'}', val);
@@ -141,7 +145,7 @@ jQuery.webshims.register('form-message', function($, webshims, window, document,
141
145
  };
142
146
 
143
147
 
144
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
148
+ if(!Modernizr.formvalidation || webshims.bugs.bustedValidity){
145
149
  implementProperties.push('validationMessage');
146
150
  }
147
151
 
@@ -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
  }
@@ -1,6 +1,8 @@
1
- jQuery.webshims.register('form-number-date-api', function($, webshims, window, document, undefined){
1
+ webshims.register('form-number-date-api', function($, webshims, window, document, undefined, options){
2
2
  "use strict";
3
-
3
+ if(!webshims.addInputType){
4
+ webshims.error("you can not call forms-ext feature after calling forms feature. call both at once instead: $.webshims.polyfill('forms forms-ext')");
5
+ }
4
6
 
5
7
  if(!webshims.getStep){
6
8
  webshims.getStep = function(elem, type){
@@ -270,7 +272,14 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
270
272
  minDefault: 0,
271
273
  maxDefault: 100
272
274
  },
273
-
275
+ color: {
276
+ mismatch: (function(){
277
+ var cReg = /^\u0023[a-f0-9]{6}$/;
278
+ return function(val){
279
+ return (!val || val.length != 7 || !(cReg.test(val)));
280
+ };
281
+ })()
282
+ },
274
283
  date: {
275
284
  mismatch: function(val){
276
285
  if(!val || !val.split || !(/\d$/.test(val))){return true;}
@@ -468,20 +477,22 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
468
477
  // }
469
478
  };
470
479
 
471
- if(typeBugs || !supportsType('range') || !supportsType('time')){
480
+ if(typeBugs || !supportsType('range') || !supportsType('time') || !supportsType('month')){
472
481
  typeProtos.range = $.extend({}, typeProtos.number, typeProtos.range);
473
482
  typeProtos.time = $.extend({}, typeProtos.date, typeProtos.time);
474
483
  typeProtos.month = $.extend({}, typeProtos.date, typeProtos.month);
475
484
  // typeProtos['datetime-local'] = $.extend({}, typeProtos.date, typeProtos.time, typeProtos['datetime-local']);
476
485
  }
477
486
 
487
+
488
+
478
489
  //'datetime-local'
479
- ['number', 'month', 'range', 'date', 'time'].forEach(function(type){
490
+ ['number', 'month', 'range', 'date', 'time', 'color'].forEach(function(type){
480
491
  if(typeBugs || !supportsType(type)){
481
492
  webshims.addInputType(type, typeProtos[type]);
482
493
  }
483
494
  });
484
-
495
+
485
496
  if($('<input />').prop('labels') == null){
486
497
  webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
487
498
  prop: {
@@ -1,7 +1,7 @@
1
- jQuery.webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1
+ webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
2
2
  "use strict";
3
3
  var curCfg;
4
- var formcfg = $.webshims.formcfg;
4
+ var formcfg = webshims.formcfg;
5
5
 
6
6
  var stopPropagation = function(e){
7
7
  e.stopImmediatePropagation(e);
@@ -19,7 +19,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
19
19
  date: {
20
20
  _create: function(){
21
21
  var obj = {
22
- 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]]
22
+ 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]]
23
23
  };
24
24
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1], $('<span class="ws-input-seperator" />')[0], obj.splits[2]];
25
25
  return obj;
@@ -45,7 +45,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
45
45
  month: {
46
46
  _create: function(){
47
47
  var obj = {
48
- splits: [$('<input type="text" class="yy" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
48
+ splits: [$('<input type="text" class="yy" inputmode="numeric" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
49
49
  };
50
50
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1]];
51
51
  return obj;
@@ -65,6 +65,23 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
65
65
  }
66
66
  }
67
67
  };
68
+
69
+ var steps = {
70
+ number: {
71
+ step: 1
72
+ },
73
+ time: {
74
+ step: 60
75
+ },
76
+ month: {
77
+ step: 1,
78
+ start: new Date()
79
+ },
80
+ date: {
81
+ step: 1,
82
+ start: new Date()
83
+ }
84
+ };
68
85
  var labelWidth = (function(){
69
86
  var getId = function(){
70
87
  return webshims.getID(this);
@@ -89,7 +106,8 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
89
106
 
90
107
  (function(){
91
108
  var monthDigits = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
92
- formcfg.de = {
109
+
110
+ formcfg.de = $.extend(true, {
93
111
  numberFormat: {
94
112
  ",": ".",
95
113
  ".": ","
@@ -123,9 +141,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
123
141
  showMonthAfterYear: false,
124
142
  yearSuffix: ''
125
143
  }
126
- };
144
+ }, formcfg.de || {});
127
145
 
128
- formcfg.en = {
146
+ formcfg.en = $.extend(true, {
129
147
  numberFormat: {
130
148
  ".": ".",
131
149
  ",": ","
@@ -157,13 +175,17 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
157
175
  "showMonthAfterYear": false,
158
176
  "yearSuffix": ""
159
177
  }
160
- };
178
+ }, formcfg['en'] || {});
179
+ if(!formcfg['en-US']){
180
+ formcfg['en-US'] = formcfg['en'];
181
+ }
182
+ if(!formcfg['']){
183
+ formcfg[''] = formcfg['en-US'];
184
+ }
161
185
 
162
- formcfg['en-US'] = formcfg['en-US'] || formcfg['en'];
163
- formcfg[''] = formcfg[''] || formcfg['en-US'];
164
186
  curCfg = formcfg[''];
165
187
 
166
- var createMonthKeys = function(langCfg){
188
+ var processLangCFG = function(langCfg){
167
189
  if(!langCfg.date.monthkeys){
168
190
  var create = function(i, name){
169
191
  var strNum;
@@ -179,24 +201,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
179
201
  $.each(langCfg.date.monthNames, create);
180
202
  $.each(langCfg.date.monthNamesShort, create);
181
203
  }
204
+ if(!langCfg.colorSigns){
205
+ langCfg.colorSigns = '#abcdefABCDEF';
206
+ }
182
207
  };
183
208
 
184
- createMonthKeys(curCfg);
209
+ processLangCFG(curCfg);
185
210
 
186
- $.webshims.ready('dom-extend', function(){
187
- $.webshims.activeLang({
188
- register: 'form-core',
189
- callback: function(){
190
- $.each(arguments, function(i, val){
191
- if(formcfg[val]){
192
- curCfg = formcfg[val];
193
- createMonthKeys(curCfg);
194
- $(document).triggerHandler('wslocalechange');
195
- return false;
196
- }
197
- });
198
- }
199
- });
211
+ $.webshims.activeLang({
212
+ register: 'form-core',
213
+ callback: function(){
214
+ $.each(arguments, function(i, val){
215
+ if(formcfg[val]){
216
+ curCfg = formcfg[val];
217
+ processLangCFG(curCfg);
218
+ $(document).triggerHandler('wslocalechange');
219
+ return false;
220
+ }
221
+ });
222
+ }
200
223
  });
201
224
  })();
202
225
 
@@ -216,8 +239,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
216
239
  return val * 1;
217
240
  };
218
241
 
219
- var createOpts = ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value'];
220
-
221
242
 
222
243
  var formatVal = {
223
244
  number: function(val){
@@ -256,6 +277,16 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
256
277
  }
257
278
 
258
279
  return val;
280
+ },
281
+ color: function(val, opts){
282
+ var ret = '#000000';
283
+ if(val){
284
+ val = val.toLowerCase();
285
+ if(val.length == 7 && createHelper('color').isValid(val)) {
286
+ ret = val;
287
+ }
288
+ }
289
+ return ret;
259
290
  }
260
291
  };
261
292
 
@@ -270,7 +301,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
270
301
 
271
302
  var p = (!opts.splitInput) ? val.trim().split(/[\.\s-\/\\]+/) : val;
272
303
 
273
- if(p.length == 2){
304
+ if(p.length == 2 && p[0] && p[1]){
274
305
  p[0] = curCfg.date.monthkeys[p[0]] || p[0];
275
306
  p[1] = curCfg.date.monthkeys[p[1]] || p[1];
276
307
  if(p[1].length == 2){
@@ -300,27 +331,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
300
331
  ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-') :
301
332
  ''
302
333
  ;
303
- }
304
- };
305
-
306
- var steps = {
307
- number: {
308
- step: 1
309
- },
310
- time: {
311
- step: 60
312
- },
313
- month: {
314
- step: 1,
315
- start: new Date()
316
334
  },
317
- date: {
318
- step: 1,
319
- start: new Date()
335
+ color: function(val, opts){
336
+ var ret = '#000000';
337
+ if(val){
338
+ val = val.toLowerCase();
339
+ if (val.indexOf('#') !== 0) {
340
+ val = '#' + val;
341
+ }
342
+ if(val.length == 4){
343
+ val = '#' + val.charAt(1) + val.charAt(1) + val.charAt(2) + val.charAt(2) + val.charAt(3) + val.charAt(3);
344
+ }
345
+ if(val.length == 7 && createHelper('color').isValid(val)) {
346
+ ret = val;
347
+ }
348
+ }
349
+ return ret;
320
350
  }
321
351
  };
322
352
 
323
-
324
353
  var placeholderFormat = {
325
354
  date: function(val, opts){
326
355
  var hintValue = (val || '').split('-');
@@ -365,6 +394,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
365
394
  asValue: function(val){
366
395
  var type = (typeof val == 'object') ? 'valueAsDate' : 'valueAsNumber';
367
396
  return input.prop(type, val).prop('value');
397
+ },
398
+ isValid: function(val){
399
+ return input.prop('value', val).is(':valid') && input.prop('value') == val;
368
400
  }
369
401
  };
370
402
  }
@@ -374,211 +406,80 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
374
406
 
375
407
  steps.range = steps.number;
376
408
 
377
-
378
- var spinBtnProto = {
409
+ var wsWidgetProto = {
379
410
  _create: function(){
380
- var i;
411
+ var i, that, timedMirror;
381
412
  var o = this.options;
382
- var helper = createHelper(o.type);
413
+ var createOpts = this.createOpts;
414
+
383
415
  this.type = o.type;
384
416
  this.orig = o.orig;
385
417
 
386
- this.elemHelper = $('<input type="'+ this.type+'" />');
387
- this.asNumber = helper.asNumber;
388
- this.asValue = helper.asValue;
418
+ this.buttonWrapper = $('<span class="input-buttons '+this.type+'-input-buttons"></span>').insertAfter(this.element);
419
+ this.options.containerElements.push(this.buttonWrapper[0]);
389
420
 
390
- 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>')
391
- .insertAfter(this.element)
392
- ;
421
+ o.mirrorValidity = o.mirrorValidity && this.orig && Modernizr.formvalidation && !webshims.bugs.bustedValidity;
393
422
 
394
- if(o.splitInput){
423
+ if(o.splitInput && this._addSplitInputs){
395
424
  this._addSplitInputs();
396
425
  } else {
397
426
  this.inputElements = this.element;
398
427
  }
399
428
 
400
- this.options.containerElements.push(this.buttonWrapper[0]);
401
-
402
- if(typeof steps[this.type].start == 'object'){
429
+ if( steps[this.type] && typeof steps[this.type].start == 'object'){
403
430
  steps[this.type].start = this.asNumber(steps[this.type].start);
404
431
  }
405
432
 
406
-
407
-
408
433
  for(i = 0; i < createOpts.length; i++){
409
- this[createOpts[i]](o[createOpts[i]]);
410
- }
411
-
412
- this.element.data('wsspinner', this);
413
-
414
- this.addBindings();
415
-
416
- if(!o.min && typeof o.relMin == 'number'){
417
- o.min = this.asValue(this.getRelNumber(o.relMin));
418
- $.prop(this.orig, 'min', o.min);
434
+ if(o[createOpts[i]] != null){
435
+ this[createOpts[i]](o[createOpts[i]], o[createOpts[i]]);
436
+ }
419
437
  }
420
-
421
- if(!o.max && typeof o.relMax == 'number'){
422
- o.max = this.asValue(this.getRelNumber(o.relMax));
423
- $.prop(this.orig, 'max', o.max);
438
+ if(this.type == 'color'){
439
+ this.inputElements.prop('maxLength', 7);
424
440
  }
441
+ this.addBindings();
442
+ $(this.element).data('wsWidget'+o.type, this);
425
443
 
426
444
  this._init = true;
427
- },
428
- _addSplitInputs: function(){
429
- if(!this.inputElements){
430
- var create = splitInputs[this.type]._create();
431
- this.splits = create.splits;
432
- this.inputElements = $(create.elements).prependTo(this.element).filter('input');
433
- }
434
- },
435
- parseValue: function(){
436
- var value = this.inputElements.map(function(){
437
- return $.prop(this, 'value');
438
- }).get();
439
- if(!this.options.splitInput){
440
- value = value[0];
441
- }
442
- return parseVal[this.type](value, this.options);
443
- },
444
- formatValue: function(val, noSplit){
445
- return formatVal[this.type](val, noSplit === false ? false : this.options);
446
- },
447
- placeholder: function(val){
448
- var options = this.options;
449
- options.placeholder = val;
450
- var placeholder = val;
451
- if(placeholderFormat[this.type]){
452
- placeholder = placeholderFormat[this.type](val, this.options);
453
- }
454
- if(options.splitInput && typeof placeholder == 'object'){
455
- $.each(this.splits, function(i, elem){
456
- $.prop(elem, 'placeholder', placeholder[i]);
457
- });
458
- } else {
459
- this.element.prop('placeholder', placeholder);
460
- }
461
- },
462
- getRelNumber: function(rel){
463
- var start = steps[this.type].start || 0;
464
- if(rel){
465
- start += rel;
466
- }
467
- return start;
468
- },
469
- addZero: addZero,
470
- _setStartInRange: function(){
471
- var start = this.getRelNumber(this.options.relDefaultValue);
472
- if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
473
- start = this.minAsNumber;
474
- } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
475
- start = this.maxAsNumber;
476
- }
477
- this.elemHelper.prop('valueAsNumber', start);
478
- this.options.defValue = this.elemHelper.prop('value');
479
-
480
- },
481
- reorderInputs: function(){
482
- if(splitInputs[this.type]){
483
- var element = this.element;
484
- splitInputs[this.type].sort(element);
485
- setTimeout(function(){
486
- var data = webshims.data(element);
487
- if(data && data.shadowData){
488
- data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
489
- }
490
- }, 9);
491
- }
492
- },
493
- value: function(val){
494
- this.valueAsNumber = this.asNumber(val);
495
- this.options.value = val;
496
- if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
497
- this._setStartInRange();
498
- } else {
499
- this.elemHelper.prop('value', val);
500
- this.options.defValue = "";
501
- }
502
445
 
503
- val = formatVal[this.type](val, this.options);
504
- if(this.options.splitInput){
446
+ if(o.mirrorValidity){
447
+ that = this;
448
+ timedMirror = function(){
449
+ clearTimeout(timedMirror._timerDealy);
450
+ timedMirror._timerDealy = setTimeout(timedMirror._wsexec, 9);
451
+ };
452
+ timedMirror._wsexec = function(){
453
+ clearTimeout(timedMirror._timerDealy);
454
+ that.mirrorValidity(true);
455
+ };
505
456
 
506
- $.each(this.splits, function(i, elem){
507
- $.prop(elem, 'value', val[i]);
508
- });
509
- } else {
510
- this.element.prop('value', val);
511
- }
512
-
513
- this._propertyChange('value');
514
- },
515
- initDataList: function(){
516
- var listTimer;
517
- var that = this;
518
- var updateList = function(){
519
- $(that.orig)
520
- .jProp('list')
521
- .off('updateDatalist', updateList)
522
- .on('updateDatalist', updateList)
523
- ;
524
- clearTimeout(listTimer);
525
- listTimer = setTimeout(function(){
526
- if(that.list){
527
- that.list();
457
+ timedMirror();
458
+ $(this.orig).on('change input', function(e){
459
+ if(e.type == 'input'){
460
+ timedMirror();
461
+ } else {
462
+ timedMirror._wsexec();
528
463
  }
529
- }, 9);
530
-
531
- };
532
-
533
- $(this.orig).onTrigger('listdatalistchange', updateList);
534
- },
535
- getOptions: function(){
536
- var options = {};
537
- var datalist = $(this.orig).jProp('list');
538
- datalist.find('option').each(function(){
539
- options[$.prop(this, 'value')] = $.prop(this, 'label');
540
- });
541
- return [options, datalist.data('label')];
542
- },
543
- list: function(val){
544
- if(this.type == 'number' || this.type == 'time'){
545
- this.element.attr('list', $.attr(this.orig, 'list'));
546
- }
547
- this.options.list = val;
548
- this._propertyChange('list');
549
- },
550
- _propertyChange: $.noop,
551
- tabindex: function(val){
552
- this.options.tabindex = val;
553
- this.inputElements.prop('tabindex', this.options.tabindex);
554
- },
555
- title: function(val){
556
- this.options.title = val;
557
- this.element.prop('title', this.options.title);
558
- },
559
-
560
- min: function(val){
561
- this.elemHelper.prop('min', val);
562
- this.minAsNumber = this.asNumber(val);
563
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
564
- this._setStartInRange();
464
+ });
565
465
  }
566
- this.options.min = val;
567
- this._propertyChange('min');
568
466
  },
569
- max: function(val){
570
- this.elemHelper.prop('max', val);
571
- this.maxAsNumber = this.asNumber(val);
572
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
573
- this._setStartInRange();
467
+ mirrorValidity: function(_noTest){
468
+ //
469
+ if(this._init && this.options.mirrorValidity){
470
+ if(!_noTest){
471
+ $.prop(this.orig, 'validity');
472
+ }
473
+ var message = $(this.orig).getErrorMessage();
474
+ if(message !== this.lastErrorMessage){
475
+ this.inputElements.prop('setCustomValidity', function(i, val){
476
+ if(val._supvalue){
477
+ val._supvalue.call(this, message);
478
+ }
479
+ });
480
+ this.lastErrorMessage = message;
481
+ }
574
482
  }
575
- this.options.max = val;
576
- this._propertyChange('max');
577
- },
578
- step: function(val){
579
- var defStep = steps[this.type];
580
- this.options.step = val;
581
- this.elemHelper.prop('step', retDefault(val, defStep.step));
582
483
  },
583
484
  addBindings: function(){
584
485
  var isFocused;
@@ -631,6 +532,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
631
532
  var val;
632
533
  clearTimeout(timer);
633
534
  val = that.parseValue();
535
+ if(that.type == 'color'){
536
+ that.inputElements.val(val);
537
+ }
634
538
  $.prop(that.orig, 'value', val);
635
539
  eventTimer.call('input', val);
636
540
  if(!e || e.type != 'wsupdatevalue'){
@@ -667,6 +571,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
667
571
  ;
668
572
  setTimeout(function(){
669
573
  if(that.popover){
574
+ that.popover.element.on('wspopoverhide', onBlur);
670
575
  $('> *', that.popover.element)
671
576
  .on({
672
577
  'focusin': onFocus,
@@ -747,7 +652,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
747
652
  e.preventDefault();
748
653
  }
749
654
  }
750
- }
655
+ };
751
656
  })()
752
657
  };
753
658
  var mouseDownInit = function(){
@@ -771,28 +676,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
771
676
  };
772
677
  })();
773
678
 
774
- ['stepUp', 'stepDown'].forEach(function(name){
775
- step[name] = function(factor){
776
- if(!o.disabled && !o.readonly){
777
- if(!isFocused){
778
- mouseDownInit();
779
- }
780
- var ret = false;
781
- if (!factor) {
782
- factor = 1;
783
- }
784
- try {
785
- that.elemHelper[name](factor);
786
- ret = that.elemHelper.prop('value');
787
- that.value(ret);
788
- eventTimer.call('input', ret);
789
- } catch (er) {}
790
- return ret;
791
- }
792
- };
793
- });
794
-
795
-
796
679
 
797
680
  this.buttonWrapper.on('mousedown', mouseDownInit);
798
681
 
@@ -809,960 +692,415 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
809
692
 
810
693
  this.inputElements.on(elementEvts);
811
694
 
812
- if(!o.noSpinbtn){
813
- spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
814
- if(delta && isFocused && !o.disabled){
815
- step[delta > 0 ? 'stepUp' : 'stepDown']();
816
- e.preventDefault();
817
- }
818
- };
819
- spinEvents.keydown = function(e){
820
- if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
821
- var stepped = true;
822
- var code = e.keyCode;
823
- if (code == 38) {
824
- step.stepUp();
825
- } else if (code == 40) {
826
- step.stepDown();
695
+ if(steps[this.type]){
696
+ ['stepUp', 'stepDown'].forEach(function(name){
697
+ step[name] = function(factor){
698
+ if(!o.disabled && !o.readonly){
699
+ if(!isFocused){
700
+ mouseDownInit();
701
+ }
702
+ var ret = false;
703
+ if (!factor) {
704
+ factor = 1;
705
+ }
706
+ try {
707
+ that.elemHelper[name](factor);
708
+ ret = that.elemHelper.prop('value');
709
+ that.value(ret);
710
+ eventTimer.call('input', ret);
711
+ } catch (er) {}
712
+ return ret;
713
+ }
714
+ };
715
+ });
716
+ if(!o.noSpinbtn){
717
+ spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
718
+ if(delta && isFocused && !o.disabled){
719
+ step[delta > 0 ? 'stepUp' : 'stepDown']();
720
+ e.preventDefault();
721
+ }
722
+ };
723
+ spinEvents.keydown = function(e){
724
+ if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
725
+ var stepped = true;
726
+ var code = e.keyCode;
727
+ if (code == 38) {
728
+ step.stepUp();
729
+ } else if (code == 40) {
730
+ step.stepDown();
731
+ } else {
732
+ stepped = false;
733
+ }
734
+ if(stepped){
735
+ e.preventDefault();
736
+ }
737
+ };
738
+
739
+ spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
740
+ }
741
+ $(this.buttonWrapper)
742
+ .on('mousepressstart mousepressend', '.step-up, .step-down', mousePress)
743
+ .on('mousedown mousepress', '.step-up', function(e){
744
+ step.stepUp();
745
+ })
746
+ .on('mousedown mousepress', '.step-down', function(e){
747
+ step.stepDown();
748
+ })
749
+ ;
750
+ }
751
+ if(this.type != 'color'){
752
+ (function(){
753
+ var localeChange ;
754
+ if(!o.splitInput){
755
+ localeChange = function(){
756
+ if(o.value){
757
+ that.value(o.value);
758
+ }
759
+
760
+ if(placeholderFormat[that.type] && o.placeholder){
761
+ that.placeholder(o.placeholder);
762
+ }
763
+ };
827
764
  } else {
828
- stepped = false;
829
- }
830
- if(stepped){
831
- e.preventDefault();
765
+ localeChange = function(){
766
+ that.reorderInputs();
767
+ };
768
+ that.reorderInputs();
832
769
  }
833
- };
834
-
835
- spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
770
+ $(that.orig).onWSOff('wslocalechange', localeChange);
771
+ })();
836
772
  }
837
773
 
838
-
839
- if(!o.splitInput){
840
- $(document).on('wslocalechange',function(){
841
- if(o.value){
842
- that.value(o.value);
843
- }
844
-
845
- if(placeholderFormat[that.type] && o.placeholder){
846
- that.placeholder(o.placeholder);
847
- }
848
- });
849
- } else {
850
- $(document).onTrigger('wslocalechange',function(){
851
- that.reorderInputs();
852
- });
774
+ initChangeEvents();
775
+ },
776
+ value: function(val){
777
+ if(!this._init || val !== this.options.value){
778
+ this.element.val(this.formatValue(val));
779
+ this.options.value = val;
780
+ this._propertyChange('value');
781
+ this.mirrorValidity();
853
782
  }
854
783
 
855
- $('.step-up', this.buttonWrapper)
856
- .on({
857
- 'mousepressstart mousepressend': mousePress,
858
- 'mousedown mousepress': function(e){
859
- step.stepUp();
860
- }
861
- })
862
- ;
863
- $('.step-down', this.buttonWrapper)
864
- .on({
865
- 'mousepressstart mousepressend': mousePress,
866
- 'mousedown mousepress': function(e){
867
- step.stepDown();
868
- }
869
- })
870
- ;
871
- initChangeEvents();
872
- }
873
- };
874
-
875
- ['readonly', 'disabled'].forEach(function(name){
876
- spinBtnProto[name] = function(val){
877
- if(this.options[name] != val || !this._init){
878
- this.options[name] = !!val;
879
- if(name == 'readonly' && this.options.noInput){
880
- this.element
881
- .prop(name, true)
882
- .attr({'aria-readonly': this.options[name]})
883
- ;
884
- } else {
885
- this.element.prop(name, this.options[name]);
886
- }
887
- this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
888
- }
889
- };
890
- });
891
-
892
-
893
- $.fn.spinbtnUI = function(opts){
894
- opts = $.extend({
895
- monthNames: 'monthNames',
896
- size: 1,
897
- startView: 0
898
- }, opts);
899
- return this.each(function(){
900
- $.webshims.objectCreate(spinBtnProto, {
901
- element: {
902
- value: $(this)
903
- }
904
- }, opts);
905
- });
906
- };
907
- })();
908
-
909
- (function(){
910
- var picker = {};
911
- var disable = {
912
-
913
- };
914
-
915
- var getDateArray = function(date){
916
- var ret = [date.getFullYear(), addZero(date.getMonth() + 1), addZero(date.getDate())];
917
- ret.month = ret[0]+'-'+ret[1];
918
- ret.date = ret[0]+'-'+ret[1]+'-'+ret[2];
919
- return ret;
920
- };
921
- var today = getDateArray(new Date());
922
-
923
- var _setFocus = function(element, _noFocus){
924
- var setFocus, that;
925
- element = $(element || this.activeButton);
926
- this.activeButton.attr({tabindex: '-1', 'aria-selected': 'false'});
927
- this.activeButton = element.attr({tabindex: '0', 'aria-selected': 'true'});
928
- this.index = this.buttons.index(this.activeButton[0]);
929
-
930
- clearTimeout(this.timer);
931
-
932
- if(!this.popover.openedByFocus && !_noFocus){
933
- that = this;
934
- setFocus = function(noTrigger){
935
- clearTimeout(that.timer);
936
- that.timer = setTimeout(function(){
937
- if(element[0]){
938
- element[0].focus();
939
- if(noTrigger !== true && !element.is(':focus')){
940
- setFocus(true);
941
- }
942
- }
943
- }, that.popover.isVisible ? 99 : 360);
944
- };
945
- this.popover.activateElement(element);
946
- setFocus();
947
- }
948
-
949
- };
950
-
951
- var _initialFocus = function(){
952
- var sel;
953
- if(this.popover.navedInitFocus){
954
- sel = this.popover.navedInitFocus.sel || this.popover.navedInitFocus;
955
- if((!this.activeButton || !this.activeButton[0]) && this.buttons[sel]){
956
- this.activeButton = this.buttons[sel]();
957
- } else if(sel){
958
- this.activeButton = $(sel, this.element);
959
- }
960
-
961
- if(!this.activeButton[0] && this.popover.navedInitFocus.alt){
962
- this.activeButton = this.buttons[this.popover.navedInitFocus.alt]();
963
- }
964
- }
965
-
966
- if(!this.activeButton || !this.activeButton[0]){
967
- this.activeButton = this.buttons.filter('.checked-value');
968
- }
969
-
970
- if(!this.activeButton[0]){
971
- this.activeButton = this.buttons.filter('.this-value');
972
- }
973
- if(!this.activeButton[0]){
974
- this.activeButton = this.buttons.eq(0);
975
- }
976
-
977
- this.setFocus(this.activeButton, this.opts.noFocus);
978
- };
979
-
980
-
981
- webshims.ListBox = function (element, popover, opts){
982
- this.element = $('ul', element);
983
- this.popover = popover;
984
- this.opts = opts || {};
985
- this.buttons = $('button:not(:disabled)', this.element);
986
-
987
-
988
- this.ons(this);
989
- this._initialFocus();
990
- };
991
-
992
- webshims.ListBox.prototype = {
993
- setFocus: _setFocus,
994
- _initialFocus: _initialFocus,
995
- prev: function(){
996
- var index = this.index - 1;
997
- if(index < 0){
998
- if(this.opts.prev){
999
- this.popover.navedInitFocus = 'last';
1000
- this.popover.actionFn(this.opts.prev);
1001
- this.popover.navedInitFocus = false;
1002
- }
1003
- } else {
1004
- this.setFocus(this.buttons.eq(index));
784
+ },
785
+ required: function(val, boolVal){
786
+ this.inputElements.attr({'aria-required': ''+boolVal});
787
+ this.mirrorValidity();
788
+ },
789
+ parseValue: function(){
790
+ var value = this.inputElements.map(function(){
791
+ return $.prop(this, 'value');
792
+ }).get();
793
+ if(!this.options.splitInput){
794
+ value = value[0];
1005
795
  }
796
+ return parseVal[this.type](value, this.options);
1006
797
  },
1007
- next: function(){
1008
- var index = this.index + 1;
1009
- if(index >= this.buttons.length){
1010
- if(this.opts.next){
1011
- this.popover.navedInitFocus = 'first';
1012
- this.popover.actionFn(this.opts.next);
1013
- this.popover.navedInitFocus = false;
1014
- }
798
+ formatValue: function(val, noSplit){
799
+ return formatVal[this.type](val, noSplit === false ? false : this.options);
800
+ },
801
+ createOpts: ['readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
802
+ placeholder: function(val){
803
+ var options = this.options;
804
+ options.placeholder = val;
805
+ var placeholder = val;
806
+ if(placeholderFormat[this.type]){
807
+ placeholder = placeholderFormat[this.type](val, this.options);
808
+ }
809
+ if(options.splitInput && typeof placeholder == 'object'){
810
+ $.each(this.splits, function(i, elem){
811
+ $.prop(elem, 'placeholder', placeholder[i]);
812
+ });
1015
813
  } else {
1016
- this.setFocus(this.buttons.eq(index));
814
+ this.element.prop('placeholder', placeholder);
1017
815
  }
1018
816
  },
1019
- ons: function(that){
1020
- this.element
1021
- .on({
1022
- 'keydown': function(e){
1023
- var handled;
1024
- var key = e.keyCode;
1025
- if(e.ctrlKey){return;}
1026
- if(key == 36 || key == 33){
1027
- that.setFocus(that.buttons.eq(0));
1028
- handled = true;
1029
- } else if(key == 34 || key == 35){
1030
- that.setFocus(that.buttons.eq(that.buttons.length - 1));
1031
- handled = true;
1032
- } else if(key == 38 || key == 37){
1033
- that.prev();
1034
- handled = true;
1035
- } else if(key == 40 || key == 39){
1036
- that.next();
1037
- handled = true;
1038
- }
1039
- if(handled){
1040
- return false;
1041
- }
817
+ initDataList: function(){
818
+ var listTimer;
819
+ var that = this;
820
+ var updateList = function(){
821
+ $(that.orig)
822
+ .jProp('list')
823
+ .off('updateDatalist', updateList)
824
+ .on('updateDatalist', updateList)
825
+ ;
826
+ clearTimeout(listTimer);
827
+ listTimer = setTimeout(function(){
828
+ if(that.list){
829
+ that.list();
1042
830
  }
1043
- })
1044
- ;
1045
- }
1046
- };
1047
-
1048
- webshims.Grid = function (element, popover, opts){
1049
- this.element = $('tbody', element);
1050
- this.popover = popover;
1051
- this.opts = opts || {};
1052
- this.buttons = $('button:not(:disabled,.othermonth)', this.element);
1053
-
1054
- this.ons(this);
1055
-
1056
- this._initialFocus();
1057
- if(this.popover.openedByFocus){
1058
- this.popover.activeElement = this.activeButton;
1059
- }
1060
- };
1061
-
1062
-
1063
-
1064
- webshims.Grid.prototype = {
1065
- setFocus: _setFocus,
1066
- _initialFocus: _initialFocus,
1067
-
1068
- first: function(){
1069
- this.setFocus(this.buttons.eq(0));
831
+ }, 9);
832
+
833
+ };
834
+
835
+ $(this.orig).onTrigger('listdatalistchange', updateList);
1070
836
  },
1071
- last: function(){
1072
- this.setFocus(this.buttons.eq(this.buttons.length - 1));
837
+ getOptions: function(){
838
+ var options = {};
839
+ var datalist = $(this.orig).jProp('list');
840
+ datalist.find('option').each(function(){
841
+ options[$.prop(this, 'value')] = $.prop(this, 'label');
842
+ });
843
+ return [options, datalist.data('label')];
1073
844
  },
1074
- upPage: function(){
1075
- $('.ws-picker-header > button:not(:disabled)', this.popover.element).trigger('click');
845
+ list: function(val){
846
+ if(this.type == 'number' || this.type == 'time'){
847
+ this.element.attr('list', $.attr(this.orig, 'list'));
848
+ }
849
+ this.options.list = val;
850
+ this._propertyChange('list');
1076
851
  },
1077
- downPage: function(){
1078
- this.activeButton.filter(':not([data-action="changeInput"])').trigger('click');
852
+ _propertyChange: $.noop,
853
+ tabindex: function(val){
854
+ this.options.tabindex = val;
855
+ this.inputElements.prop('tabindex', this.options.tabindex);
856
+ $('button', this.buttonWrapper).prop('tabindex', this.options.tabindex);
1079
857
  },
1080
- ons: function(that){
1081
- this.element
1082
- .on({
1083
- 'keydown': function(e){
1084
- var handled;
1085
- var key = e.keyCode;
1086
-
1087
- if(e.shiftKey){return;}
1088
-
1089
- if((e.ctrlKey && key == 40)){
1090
- handled = 'downPage';
1091
- } else if((e.ctrlKey && key == 38)){
1092
- handled = 'upPage';
1093
- } else if(key == 33 || (e.ctrlKey && key == 37)){
1094
- handled = 'prevPage';
1095
- } else if(key == 34 || (e.ctrlKey && key == 39)){
1096
- handled = 'nextPage';
1097
- } else if(e.keyCode == 36 || e.keyCode == 33){
1098
- handled = 'first';
1099
- } else if(e.keyCode == 35){
1100
- handled = 'last';
1101
- } else if(e.keyCode == 38){
1102
- handled = 'up';
1103
- } else if(e.keyCode == 37){
1104
- handled = 'prev';
1105
- } else if(e.keyCode == 40){
1106
- handled = 'down';
1107
- } else if(e.keyCode == 39){
1108
- handled = 'next';
1109
- }
1110
- if(handled){
1111
- that[handled]();
1112
- return false;
1113
- }
1114
- }
1115
- })
1116
- ;
1117
- }
1118
- };
1119
- $.each({
1120
- prevPage: {get: 'last', action: 'prev'},
1121
- nextPage: {get: 'first', action: 'next'}
1122
- }, function(name, val){
1123
- webshims.Grid.prototype[name] = function(){
1124
- if(this.opts[val.action]){
1125
- this.popover.navedInitFocus = {
1126
- sel: 'button[data-id="'+ this.activeButton.attr('data-id') +'"]:not(:disabled,.othermonth)',
1127
- alt: val.get
1128
- };
1129
- this.popover.actionFn(this.opts[val.action]);
1130
- this.popover.navedInitFocus = false;
1131
- }
1132
- };
1133
- });
1134
-
1135
- $.each({
1136
- up: {traverse: 'prevAll', get: 'last', action: 'prev', reverse: true},
1137
- down: {traverse: 'nextAll', get: 'first', action: 'next'}
1138
- }, function(name, val){
1139
- webshims.Grid.prototype[name] = function(){
1140
- var cellIndex = this.activeButton.closest('td').prop('cellIndex');
1141
- var sel = 'td:nth-child('+(cellIndex + 1)+') button:not(:disabled,.othermonth)';
1142
- var button = this.activeButton.closest('tr')[val.traverse]();
1143
-
1144
- if(val.reverse){
1145
- button = $(button.get().reverse());
1146
- }
1147
- button = button.find(sel)[val.get]();
1148
-
1149
- if(!button[0]){
1150
- if(this.opts[val.action]){
1151
- this.popover.navedInitFocus = sel+':'+val.get;
1152
- this.popover.actionFn(this.opts[val.action]);
1153
- this.popover.navedInitFocus = false;
1154
- }
1155
- } else {
1156
- this.setFocus(button.eq(0));
1157
- }
1158
- };
1159
- });
1160
-
1161
- $.each({
1162
- prev: {traverse: 'prevAll',get: 'last', reverse: true},
1163
- next: {traverse: 'nextAll', get: 'first'}
1164
- }, function(name, val){
1165
- webshims.Grid.prototype[name] = function(){
1166
- var sel = 'button:not(:disabled,.othermonth)';
1167
- var button = this.activeButton.closest('td')[val.traverse]('td');
1168
- if(val.reverse){
1169
- button = $(button.get().reverse());
1170
- }
1171
- button = button.find(sel)[val.get]();
1172
- if(!button[0]){
1173
- button = this.activeButton.closest('tr')[val.traverse]('tr');
1174
- if(val.reverse){
1175
- button = $(button.get().reverse());
1176
- }
1177
- button = button.find(sel)[val.get]();
858
+ title: function(val){
859
+ if(!val && this.orig && $.attr(this.orig, 'title') == null){
860
+ val = null;
1178
861
  }
1179
-
1180
- if(!button[0]){
1181
- if(this.opts[name]){
1182
- this.popover.navedInitFocus = val.get;
1183
- this.popover.actionFn(this.opts[name]);
1184
- this.popover.navedInitFocus = false;
1185
- }
862
+ this.options.title = val;
863
+ if(val == null){
864
+ this.inputElements.removeAttr('title');
1186
865
  } else {
1187
- this.setFocus(button.eq(0));
866
+ this.inputElements.prop('title', this.options.title);
1188
867
  }
1189
- };
1190
- });
1191
-
1192
- picker.getWeek = function(date){
1193
- var onejan = new Date(date.getFullYear(),0,1);
1194
- return Math.ceil((((date - onejan) / 86400000) + onejan.getDay()+1)/7);
1195
- };
1196
- picker.getYearList = function(value, data){
1197
- var j, i, val, disabled, lis, prevDisabled, nextDisabled, classStr, classArray, start;
1198
-
1199
-
1200
- var size = data.options.size;
1201
- var max = data.options.max.split('-');
1202
- var min = data.options.min.split('-');
1203
- var currentValue = data.options.value.split('-');
1204
- var xthCorrect = 0;
1205
- var enabled = 0;
1206
- var str = '';
1207
- var rowNum = 0;
1208
-
1209
- if(data.options.useDecadeBase == 'max' && max[0]){
1210
- xthCorrect = 11 - (max[0] % 12);
1211
- } else if(data.options.useDecadeBase == 'min' && min[0]){
1212
- xthCorrect = 11 - (min[0] % 12);
1213
868
  }
1214
-
1215
- value = value[0] * 1;
1216
- start = value - ((value + xthCorrect) % (12 * size));
1217
-
1218
-
1219
-
1220
- for(j = 0; j < size; j++){
1221
- if(j){
1222
- start += 12;
1223
- } else {
1224
- prevDisabled = picker.isInRange([start-1], max, min) ? {'data-action': 'setYearList','value': start-1} : false;
1225
- }
1226
-
1227
- str += '<div class="year-list picker-list ws-index-'+ j +'"><div class="ws-picker-header"><button disabled="disabled">'+ start +' – '+(start + 11)+'</button></div>';
1228
- lis = [];
1229
- for(i = 0; i < 12; i++){
1230
- val = start + i ;
1231
- classArray = [];
1232
- if( !picker.isInRange([val], max, min) ){
1233
- disabled = ' disabled=""';
1234
- } else {
1235
- disabled = '';
1236
- enabled++;
1237
- }
1238
-
1239
- if(val == today[0]){
1240
- classArray.push('this-value');
1241
- }
1242
-
1243
- if(currentValue[0] == val){
1244
- classArray.push('checked-value');
1245
- }
1246
-
1247
- classStr = classArray.length ? ' class="'+ (classArray.join(' ')) +'"' : '';
1248
-
1249
- if(i && !(i % 3)){
1250
- rowNum++;
1251
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
1252
- }
1253
- 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>');
1254
- }
1255
- if(j == size - 1){
1256
- nextDisabled = picker.isInRange([val+1], max, min) ? {'data-action': 'setYearList','value': val+1} : false;
1257
- }
1258
- 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>';
1259
- }
1260
-
1261
- return {
1262
- enabled: enabled,
1263
- main: str,
1264
- next: nextDisabled,
1265
- prev: prevDisabled,
1266
- type: 'Grid'
1267
- };
1268
869
  };
1269
870
 
1270
871
 
1271
- picker.getMonthList = function(value, data){
1272
-
1273
- var j, i, name, val, disabled, lis, fullyDisabled, prevDisabled, nextDisabled, classStr, classArray;
1274
- var o = data.options;
1275
- var size = o.size;
1276
- var max = o.max.split('-');
1277
- var min = o.min.split('-');
1278
- var currentValue = o.value.split('-');
1279
- var enabled = 0;
1280
- var rowNum = 0;
1281
- var str = '';
1282
-
1283
- value = value[0] - Math.floor((size - 1) / 2);
1284
- for(j = 0; j < size; j++){
1285
- if(j){
1286
- value++;
1287
- } else {
1288
- prevDisabled = picker.isInRange([value-1], max, min) ? {'data-action': 'setMonthList','value': value-1} : false;
1289
- }
1290
- if(j == size - 1){
1291
- nextDisabled = picker.isInRange([value+1], max, min) ? {'data-action': 'setMonthList','value': value+1} : false;
1292
- }
1293
- lis = [];
1294
-
1295
- if( !picker.isInRange([value, '01'], max, min) && !picker.isInRange([value, '12'], max, min)){
1296
- disabled = ' disabled=""';
1297
- fullyDisabled = true;
1298
- } else {
1299
- fullyDisabled = false;
1300
- disabled = '';
1301
- }
1302
-
1303
- if(o.minView >= 1){
1304
- disabled = ' disabled=""';
1305
- }
1306
-
1307
- str += '<div class="month-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">';
1308
-
1309
- str += o.selectNav ?
1310
- '<select data-action="setMonthList" class="year-select">'+ picker.createYearSelect(value, max, min).join('') +'</select>' :
1311
- '<button data-action="setYearList"'+disabled+' value="'+ value +'" tabindex="-1">'+ value +'</button>';
1312
- str += '</div>';
1313
-
1314
- for(i = 0; i < 12; i++){
1315
- val = curCfg.date.monthkeys[i+1];
1316
- name = (curCfg.date[o.monthNames] || curCfg.date.monthNames)[i];
1317
- classArray = [];
1318
- if(fullyDisabled || !picker.isInRange([value, val], max, min) ){
1319
- disabled = ' disabled=""';
1320
- } else {
1321
- disabled = '';
1322
- enabled++;
1323
- }
1324
-
1325
- if(value == today[0] && today[1] == val){
1326
- classArray.push('this-value');
1327
- }
1328
-
1329
- if(currentValue[0] == value && currentValue[1] == val){
1330
- classArray.push('checked-value');
1331
- }
1332
-
1333
- classStr = (classArray.length) ? ' class="'+ (classArray.join(' ')) +'"' : '';
1334
- if(i && !(i % 3)){
1335
- rowNum++;
1336
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
872
+ ['readonly', 'disabled'].forEach(function(name){
873
+ var isDisabled = name == 'disabled';
874
+ wsWidgetProto[name] = function(val, boolVal){
875
+ if(this.options[name] != boolVal || !this._init){
876
+ this.options[name] = !!boolVal;
877
+ this.inputElements.prop(name, this.options[name]);
878
+ this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
879
+ if(isDisabled){
880
+ $('button', this.buttonWrapper).prop('disabled', this.options[name]);
1337
881
  }
1338
-
1339
- 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>');
1340
-
1341
882
  }
1342
-
1343
- str += '<div class="picker-grid"><table role="grid" aria-label="'+value+'"><tbody><tr class="ws-row-0">'+ (lis.join(''))+ '</tr></tbody></table></div></div>';
1344
- }
1345
-
1346
- return {
1347
- enabled: enabled,
1348
- main: str,
1349
- prev: prevDisabled,
1350
- next: nextDisabled,
1351
- type: 'Grid'
1352
883
  };
1353
- };
1354
-
884
+ });
1355
885
 
1356
- picker.getDayList = function(value, data){
1357
-
1358
- var j, i, k, day, nDay, name, val, disabled, lis, prevDisabled, nextDisabled, addTr, week, rowNum;
1359
-
1360
- var lastMotnh, curMonth, otherMonth, dateArray, monthName, fullMonthName, buttonStr, date2, classArray;
1361
- var o = data.options;
1362
- var size = o.size;
1363
- var max = o.max.split('-');
1364
- var min = o.min.split('-');
1365
- var currentValue = o.value.split('-');
1366
- var monthNames = curCfg.date[o.monthNamesHead] || curCfg.date[o.monthNames] || curCfg.date.monthNames;
1367
- var enabled = 0;
1368
- var str = [];
1369
- var date = new Date(value[0], value[1] - 1, 1);
1370
-
1371
- date.setMonth(date.getMonth() - Math.floor((size - 1) / 2));
1372
-
1373
- for(j = 0; j < size; j++){
1374
- date.setDate(1);
1375
- lastMotnh = date.getMonth();
1376
- rowNum = 0;
1377
- if(!j){
1378
- date2 = new Date(date.getTime());
1379
- date2.setDate(-1);
1380
- dateArray = getDateArray(date2);
1381
- prevDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray[0]+'-'+dateArray[1]} : false;
1382
- }
886
+ var spinBtnProto = $.extend({}, wsWidgetProto, {
887
+ _create: function(){
888
+ var o = this.options;
889
+ var helper = createHelper(o.type);
1383
890
 
1384
- dateArray = getDateArray(date);
891
+ this.elemHelper = $('<input type="'+ o.type+'" />');
892
+ this.asNumber = helper.asNumber;
893
+ this.asValue = helper.asValue;
1385
894
 
1386
- str.push('<div class="day-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">');
1387
- if( o.selectNav ){
1388
- 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>'];
1389
- if(curCfg.date.showMonthAfterYear){
1390
- monthName.reverse();
1391
- }
1392
- str.push( monthName.join(' ') );
1393
- }
895
+ wsWidgetProto._create.apply(this, arguments);
896
+ this._init = false;
1394
897
 
1395
- fullMonthName = [curCfg.date.monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
1396
- monthName = [monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
1397
- if(curCfg.date.showMonthAfterYear){
1398
- monthName.reverse();
1399
- fullMonthName.reverse();
1400
- }
898
+ this.buttonWrapper.html('<span unselectable="on" class="step-controls"><span class="step-up"></span><span class="step-down"></span></span>');
1401
899
 
1402
- if(!data.options.selectNav) {
1403
- str.push(
1404
- '<button data-action="setMonthList"'+ (o.minView >= 2 ? ' disabled="" ' : '') +' value="'+ dateArray.date +'" tabindex="-1">'+ monthName.join(' ') +'</button>'
1405
- );
900
+ if(this.type == 'number'){
901
+ this.inputElements.attr('inputmode', 'numeric');
1406
902
  }
1407
903
 
1408
904
 
1409
- str.push('</div><div class="picker-grid"><table role="grid" aria-label="'+ fullMonthName.join(' ') +'"><thead><tr>');
905
+ if(!o.min && typeof o.relMin == 'number'){
906
+ o.min = this.asValue(this.getRelNumber(o.relMin));
907
+ $.prop(this.orig, 'min', o.min);
908
+ }
1410
909
 
1411
- if(data.options.showWeek){
1412
- str.push('<th class="week-header">'+ curCfg.date.weekHeader +'</th>');
910
+ if(!o.max && typeof o.relMax == 'number'){
911
+ o.max = this.asValue(this.getRelNumber(o.relMax));
912
+ $.prop(this.orig, 'max', o.max);
1413
913
  }
1414
- for(k = curCfg.date.firstDay; k < curCfg.date.dayNamesShort.length; k++){
1415
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
914
+ this._init = true;
915
+ },
916
+ createOpts: ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
917
+ _addSplitInputs: function(){
918
+ if(!this.inputElements){
919
+ var create = splitInputs[this.type]._create();
920
+ this.splits = create.splits;
921
+ this.inputElements = $(create.elements).prependTo(this.element).filter('input');
1416
922
  }
1417
- k = curCfg.date.firstDay;
1418
- while(k--){
1419
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
923
+ },
924
+
925
+ getRelNumber: function(rel){
926
+ var start = steps[this.type].start || 0;
927
+ if(rel){
928
+ start += rel;
1420
929
  }
1421
- str.push('</tr></thead><tbody><tr class="ws-row-0">');
1422
-
1423
- if(data.options.showWeek) {
1424
- week = picker.getWeek(date);
1425
- str.push('<td class="week-cell">'+ week +'</td>');
930
+ return start;
931
+ },
932
+ addZero: addZero,
933
+ _setStartInRange: function(){
934
+ var start = this.getRelNumber(this.options.relDefaultValue);
935
+ if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
936
+ start = this.minAsNumber;
937
+ } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
938
+ start = this.maxAsNumber;
1426
939
  }
940
+ this.elemHelper.prop('valueAsNumber', start);
941
+ this.options.defValue = this.elemHelper.prop('value');
1427
942
 
1428
- for (i = 0; i < 99; i++) {
1429
- addTr = (i && !(i % 7));
1430
- curMonth = date.getMonth();
1431
- otherMonth = lastMotnh != curMonth;
1432
- day = date.getDay();
1433
- classArray = [];
1434
-
1435
- if(addTr && otherMonth ){
1436
- str.push('</tr>');
1437
- break;
1438
- }
1439
- if(addTr){
1440
- rowNum++;
1441
- str.push('</tr><tr class="ws-row-'+ rowNum +'">');
1442
- if(data.options.showWeek) {
1443
- week++;
1444
- str.push('<td class="week-cell">'+ week +'</td>');
1445
- }
1446
- }
1447
-
1448
- if(!i){
1449
-
1450
- if(day != curCfg.date.firstDay){
1451
- nDay = day - curCfg.date.firstDay;
1452
- if(nDay < 0){
1453
- nDay += 7;
1454
- }
1455
- date.setDate(date.getDate() - nDay);
1456
- day = date.getDay();
1457
- curMonth = date.getMonth();
1458
- otherMonth = lastMotnh != curMonth;
943
+ },
944
+ reorderInputs: function(){
945
+ if(splitInputs[this.type]){
946
+ var element = this.element;
947
+ splitInputs[this.type].sort(element);
948
+ setTimeout(function(){
949
+ var data = webshims.data(element);
950
+ if(data && data.shadowData){
951
+ data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
1459
952
  }
1460
- }
1461
-
1462
- dateArray = getDateArray(date);
1463
- buttonStr = '<td role="presentation" class="day-'+ day +'"><button data-id="day-'+ date.getDate() +'" role="gridcell" data-action="changeInput" value="'+ (dateArray.join('-')) +'"';
953
+ }, 9);
954
+ }
955
+ },
956
+ value: function(val){
957
+
958
+ if(!this._init || this.options.value !== val){
959
+ this.valueAsNumber = this.asNumber(val);
960
+ this.options.value = val;
1464
961
 
1465
- if(otherMonth){
1466
- classArray.push('othermonth');
962
+ if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
963
+ this._setStartInRange();
1467
964
  } else {
1468
- classArray.push('day-'+date.getDate());
1469
- }
1470
-
1471
- if(dateArray[0] == today[0] && today[1] == dateArray[1] && today[2] == dateArray[2]){
1472
- classArray.push('this-value');
965
+ this.elemHelper.prop('value', val);
966
+ this.options.defValue = "";
1473
967
  }
1474
968
 
1475
- if(currentValue[0] == dateArray[0] && dateArray[1] == currentValue[1] && dateArray[2] == currentValue[2]){
1476
- classArray.push('checked-value');
1477
- }
1478
-
1479
- if(classArray.length){
1480
- buttonStr += ' class="'+ classArray.join(' ') +'"';
1481
- }
1482
-
1483
- if(!picker.isInRange(dateArray, max, min) || (data.options.disableDays && $.inArray(day, data.options.disableDays) != -1)){
1484
- buttonStr += ' disabled=""';
969
+ val = formatVal[this.type](val, this.options);
970
+ if(this.options.splitInput){
971
+ $.each(this.splits, function(i, elem){
972
+ $.prop(elem, 'value', val[i]);
973
+ });
974
+ } else {
975
+ this.element.prop('value', val);
1485
976
  }
1486
-
1487
- str.push(buttonStr+' tabindex="-1">'+ date.getDate() +'</button></td>');
1488
-
1489
- date.setDate(date.getDate() + 1);
1490
- }
1491
- str.push('</tbody></table></div></div>');
1492
- if(j == size - 1){
1493
- dateArray = getDateArray(date);
1494
- dateArray[2] = 1;
1495
- nextDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray.date} : false;
977
+ this._propertyChange('value');
978
+ this.mirrorValidity();
1496
979
  }
980
+ },
981
+ step: function(val){
982
+ var defStep = steps[this.type];
983
+ this.options.step = val;
984
+ this.elemHelper.prop('step', retDefault(val, defStep.step));
985
+ this.mirrorValidity();
1497
986
  }
1498
-
1499
-
1500
- return {
1501
- enabled: 9,
1502
- main: str.join(''),
1503
- prev: prevDisabled,
1504
- next: nextDisabled,
1505
- type: 'Grid'
1506
- };
1507
- };
987
+ });
1508
988
 
1509
- picker.isInRange = function(values, max, min){
1510
- var i;
1511
- var ret = true;
1512
- for(i = 0; i < values.length; i++){
1513
-
1514
- if(min[i] && min[i] > values[i]){
1515
- ret = false;
1516
- break;
1517
- } else if( !(min[i] && min[i] == values[i]) ){
1518
- break;
989
+ $.each({min: 1, max: -1}, function(name, factor){
990
+ var numName = name +'AsNumber';
991
+ spinBtnProto[name] = function(val){
992
+ this.elemHelper.prop(name, val);
993
+ this[numName] = this.asNumber(val);
994
+ if(this.valueAsNumber != null && (isNaN(this.valueAsNumber) || (!isNaN(this[numName]) && (this.valueAsNumber * factor) < (this[numName] * factor)))){
995
+ this._setStartInRange();
1519
996
  }
1520
- }
1521
- if(ret){
1522
- for(i = 0; i < values.length; i++){
1523
-
1524
- if((max[i] && max[i] < values[i])){
1525
- ret = false;
1526
- break;
1527
- } else if( !(max[i] && max[i] == values[i]) ){
1528
- break;
997
+ this.options[name] = val;
998
+ this._propertyChange(name);
999
+ this.mirrorValidity();
1000
+ };
1001
+ });
1002
+
1003
+ $.fn.wsBaseWidget = function(opts){
1004
+ opts = $.extend({}, opts);
1005
+ return this.each(function(){
1006
+ $.webshims.objectCreate(wsWidgetProto, {
1007
+ element: {
1008
+ value: $(this)
1529
1009
  }
1530
- }
1531
- }
1532
- return ret;
1010
+ }, opts);
1011
+ });
1533
1012
  };
1534
1013
 
1535
- picker.createMonthSelect = function(value, max, min, monthNames){
1536
- if(!monthNames){
1537
- monthNames = curCfg.date.monthNames;
1538
- }
1539
-
1540
- var selected;
1541
- var i = 0;
1542
- var options = [];
1543
- var tempVal = value[1]-1;
1544
- for(; i < monthNames.length; i++){
1545
- selected = tempVal == i ? ' selected=""' : '';
1546
- if(selected || picker.isInRange([value[0], i+1], max, min)){
1547
- options.push('<option value="'+ value[0]+'-'+addZero(i+1) + '"'+selected+'>'+ monthNames[i] +'</option>');
1548
- }
1014
+ $.fn.spinbtnUI = function(opts){
1015
+ opts = $.extend({
1016
+ monthNames: 'monthNames',
1017
+ size: 1,
1018
+ startView: 0
1019
+ }, opts);
1020
+ return this.each(function(){
1021
+ $.webshims.objectCreate(spinBtnProto, {
1022
+ element: {
1023
+ value: $(this)
1024
+ }
1025
+ }, opts);
1026
+ });
1027
+ };
1028
+ })();
1029
+
1030
+ (function(){
1031
+ var picker = {};
1032
+
1033
+ var loadPicker = function(type, name){
1034
+ type = (type == 'color' ? 'color' : 'forms')+'-picker';
1035
+ if(!loadPicker[name+'Loaded'+type]){
1036
+ loadPicker[name+'Loaded'+type] = true;
1037
+ webshims.ready(name, function(){
1038
+ webshims.loader.loadList([type]);
1039
+ });
1549
1040
  }
1550
- return options;
1041
+ return type;
1551
1042
  };
1043
+ options.addZero = addZero;
1044
+ webshims.loader.addModule('forms-picker', {
1045
+ noAutoCallback: true,
1046
+ options: options
1047
+ });
1048
+ webshims.loader.addModule('color-picker', {
1049
+ noAutoCallback: true,
1050
+ css: 'jpicker/jpicker.css',
1051
+ options: options
1052
+ });
1552
1053
 
1553
- picker.createYearSelect = function(value, max, min, valueAdd){
1554
-
1555
- var temp;
1556
- var goUp = true;
1557
- var goDown = true;
1558
- var options = ['<option selected="">'+ value + '</option>'];
1559
- var i = 0;
1560
- if(!valueAdd){
1561
- valueAdd = '';
1562
- }
1563
- while(i < 8 && (goUp || goDown)){
1564
- i++;
1565
- temp = value-i;
1566
- if(goUp && picker.isInRange([temp], max, min)){
1567
- options.unshift('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
1568
- } else {
1569
- goUp = false;
1570
- }
1571
- temp = value + i;
1572
- if(goDown && picker.isInRange([temp], max, min)){
1573
- options.push('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
1574
- } else {
1575
- goDown = false;
1576
- }
1054
+ picker._genericSetFocus = function(element, _noFocus){
1055
+ element = $(element || this.activeButton);
1056
+ if(!this.popover.openedByFocus && !_noFocus){
1057
+ var that = this;
1058
+ var setFocus = function(noTrigger){
1059
+ clearTimeout(that.timer);
1060
+ that.timer = setTimeout(function(){
1061
+ if(element[0]){
1062
+ element[0].focus();
1063
+ if(noTrigger !== true && !element.is(':focus')){
1064
+ setFocus(true);
1065
+ }
1066
+ }
1067
+ }, that.popover.isVisible ? 99 : 360);
1068
+ };
1069
+ this.popover.activateElement(element);
1070
+ setFocus();
1577
1071
  }
1578
- return options;
1579
1072
  };
1580
-
1581
- var actions = {
1073
+
1074
+ picker._actions = {
1582
1075
  changeInput: function(val, popover, data){
1076
+ picker._actions.cancel(val, popover, data);
1077
+ data.setChange(val);
1078
+ },
1079
+ cancel: function(val, popover, data){
1583
1080
  popover.stopOpen = true;
1584
1081
  data.element.getShadowFocusElement().focus();
1585
1082
  setTimeout(function(){
1586
1083
  popover.stopOpen = false;
1587
1084
  }, 9);
1588
1085
  popover.hide();
1589
- data.setChange(val);
1590
1086
  }
1591
1087
  };
1592
1088
 
1593
- (function(){
1594
- var retNames = function(name){
1595
- return 'get'+name+'List';
1596
- };
1597
- var retSetNames = function(name){
1598
- return 'set'+name+'List';
1599
- };
1600
- var stops = {
1601
- date: 'Day',
1602
- week: 'Day',
1603
- month: 'Month'
1604
- };
1605
-
1606
- $.each({'setYearList' : ['Year', 'Month', 'Day'], 'setMonthList': ['Month', 'Day'], 'setDayList': ['Day']}, function(setName, names){
1607
- var getNames = names.map(retNames);
1608
- var setNames = names.map(retSetNames);
1609
- actions[setName] = function(val, popover, data, startAt){
1610
- val = ''+val;
1611
- var o = data.options;
1612
- var values = val.split('-');
1613
- if(!startAt){
1614
- startAt = 0;
1615
- }
1616
- $.each(getNames, function(i, item){
1617
- if(i >= startAt){
1618
- var content = picker[item](values, data);
1619
-
1620
- if( values.length < 2 || content.enabled > 1 || stops[data.type] === names[i]){
1621
- popover.element
1622
- .attr({'data-currentview': setNames[i]})
1623
- .addClass('ws-size-'+o.size)
1624
- .data('pickercontent', {
1625
- data: data,
1626
- content: content,
1627
- values: values
1628
- })
1629
- ;
1630
- popover.bodyElement.html(content.main);
1631
- if(content.prev){
1632
- popover.prevElement
1633
- .attr(content.prev)
1634
- .prop({disabled: false})
1635
- ;
1636
- } else {
1637
- popover.prevElement
1638
- .removeAttr('data-action')
1639
- .prop({disabled: true})
1640
- ;
1641
- }
1642
- if(content.next){
1643
- popover.nextElement
1644
- .attr(content.next)
1645
- .prop({disabled: false})
1646
- ;
1647
- } else {
1648
- popover.nextElement
1649
- .removeAttr('data-action')
1650
- .prop({disabled: true})
1651
- ;
1652
- }
1653
- if(webshims[content.type]){
1654
- new webshims[content.type](popover.bodyElement.children(), popover, content);
1655
- }
1656
- popover.element.trigger('pickerchange');
1657
- return false;
1658
- }
1659
- }
1660
- });
1661
- };
1662
- });
1663
- })();
1664
1089
 
1665
1090
  picker.commonInit = function(data, popover){
1666
- var actionfn = function(e){
1667
- if(!$(this).is('.othermonth') || $(this).css('cursor') == 'pointer'){
1668
- popover.actionFn({
1669
- 'data-action': $.attr(this, 'data-action'),
1670
- value: $(this).val() || $.attr(this, 'value')
1671
- });
1672
- }
1673
- return false;
1674
- };
1675
- var id = new Date().getTime();
1676
- var generateList = function(o, max, min){
1677
- var options = [];
1678
- var label = '';
1679
- var labelId = '';
1680
- o.options = data.getOptions() || {};
1681
- $('div.ws-options', popover.contentElement).remove();
1682
- $.each(o.options[0], function(val, label){
1683
- var disabled = picker.isInRange(val.split('-'), o.maxS, o.minS) ?
1684
- '' :
1685
- ' disabled="" '
1686
- ;
1687
- options.push('<li role="presentation"><button value="'+ val +'" '+disabled+' data-action="changeInput" tabindex="-1" role="option">'+ (label || data.formatValue(val, false)) +'</button></li>');
1688
- });
1689
- if(options.length){
1690
- id++;
1691
- if(o.options[1]){
1692
- labelId = 'datalist-'+id;
1693
- label = '<h5 id="'+labelId+'">'+ o.options[1] +'</h5>';
1694
- labelId = ' aria-labelledbyid="'+ labelId +'" ';
1695
- }
1696
- new webshims.ListBox($('<div class="ws-options">'+label+'<ul role="listbox" '+ labelId +'>'+ options.join('') +'</div>').insertAfter(popover.bodyElement)[0], popover, {noFocus: true});
1697
- }
1698
- };
1699
- var updateContent = function(){
1700
- if(popover.isDirty){
1701
- var o = data.options;
1702
- o.maxS = o.max.split('-');
1703
- o.minS = o.min.split('-');
1704
-
1705
- $('button', popover.buttonRow).each(function(){
1706
- var text;
1707
- if($(this).is('.ws-empty')){
1708
- text = curCfg.date.clear;
1709
- if(!text){
1710
- text = formcfg[''].date.clear || 'clear';
1711
- webshims.warn("could not get clear text from form cfg");
1712
- }
1713
- } else if($(this).is('.ws-current')){
1714
- text = (curCfg[data.type] || {}).currentText;
1715
- if(!text){
1716
- text = (formcfg[''][[data.type]] || {}).currentText || 'current';
1717
- webshims.warn("could not get currentText from form cfg");
1718
- }
1719
- $.prop(this, 'disabled', !picker.isInRange(today[data.type].split('-'), o.maxS, o.minS));
1720
- }
1721
- if(text){
1722
- $(this).text(text).attr({'aria-label': text});
1723
- if(webshims.assumeARIA){
1724
- $.attr(this, 'aria-label', text);
1725
- }
1726
- }
1727
-
1728
- });
1729
- popover.nextElement.attr({'aria-label': curCfg.date.nextText});
1730
- $('> span', popover.nextElement).html(curCfg.date.nextText);
1731
- popover.prevElement.attr({'aria-label': curCfg.date.prevText});
1732
- $('> span', popover.prevElement).html(curCfg.date.prevText);
1733
-
1734
- generateList(o, o.maxS, o.minS);
1735
-
1736
- }
1737
- $('button.ws-empty', popover.buttonRow).prop('disabled', $.prop(data.orig, 'required'));
1738
- popover.isDirty = false;
1739
- };
1740
-
1741
- popover.actionFn = function(obj){
1742
- if(actions[obj['data-action']]){
1743
- actions[obj['data-action']](obj.value, popover, data, 0);
1744
- } else {
1745
- webshims.warn('no action for '+ obj['data-action']);
1746
- }
1747
- };
1748
-
1749
- 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>');
1750
- popover.nextElement = $('button.ws-next', popover.contentElement);
1751
- popover.prevElement = $('button.ws-prev', popover.contentElement);
1752
- popover.bodyElement = $('div.ws-picker-body', popover.contentElement);
1753
- popover.buttonRow = $('div.ws-button-row', popover.contentElement);
1091
+ var tabbable;
1754
1092
 
1755
1093
  popover.isDirty = true;
1756
1094
 
1757
- popover.contentElement
1758
- .on('click', 'button[data-action]', actionfn)
1759
- .on('change', 'select[data-action]', actionfn)
1760
- ;
1761
-
1095
+ popover.element.on('updatepickercontent pickerchange', function(){
1096
+ tabbable = false;
1097
+ });
1762
1098
  popover.contentElement.on({
1763
1099
  keydown: function(e){
1764
1100
  if(e.keyCode == 9){
1765
- var tabbable = $('[tabindex="0"]:not(:disabled)', this).filter(':visible');
1101
+ if(!tabbable){
1102
+ tabbable = $('input:not(:disabled), [tabindex="0"]:not(:disabled)', this).filter(':visible');
1103
+ }
1766
1104
  var index = tabbable.index(e.target);
1767
1105
  if(e.shiftKey && index <= 0){
1768
1106
  tabbable.last().focus();
@@ -1780,18 +1118,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1780
1118
  }
1781
1119
  });
1782
1120
 
1783
- $(data.options.orig).on('input', function(){
1784
- var currentView;
1785
- if(data.options.updateOnInput && popover.isVisible && data.options.value && (currentView = popover.element.attr('data-currentview'))){
1786
- actions[currentView]( data.options.value , popover, data, 0);
1787
- }
1788
- });
1789
-
1790
1121
  data._propertyChange = (function(){
1791
1122
  var timer;
1792
1123
  var update = function(){
1793
1124
  if(popover.isVisible){
1794
- updateContent();
1125
+ popover.element.triggerHandler('updatepickercontent');
1795
1126
  }
1796
1127
  };
1797
1128
  return function(prop){
@@ -1817,50 +1148,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1817
1148
  popover.element.on({
1818
1149
  wspopoverbeforeshow: function(){
1819
1150
  data.element.triggerHandler('wsupdatevalue');
1820
- updateContent();
1151
+ popover.element.triggerHandler('updatepickercontent');
1821
1152
  }
1822
1153
  });
1823
1154
 
1824
- $(document).onTrigger('wslocalechange', data._propertyChange);
1155
+
1156
+ $(data.orig).on('remove', function(e){
1157
+ if(!e.originalEvent){
1158
+ $(document).off('wslocalechange', data._propertyChange);
1159
+ }
1160
+ });
1825
1161
  };
1826
1162
 
1163
+
1827
1164
  picker._common = function(data){
1828
1165
  var popover = webshims.objectCreate(webshims.wsPopover, {}, {prepareFor: data.element});
1829
1166
  var opener = $('<button type="button" class="ws-popover-opener"><span /></button>').appendTo(data.buttonWrapper);
1830
1167
  var options = data.options;
1831
- var init = false;
1832
1168
 
1169
+ var showPickerContent = function(){
1170
+ (picker[data.type].showPickerContent || picker.showPickerContent)(data, popover);
1171
+ };
1833
1172
  var show = function(){
1173
+ var type = loadPicker(data.type, 'DOM');
1834
1174
  if(!options.disabled && !options.readonly && !popover.isVisible){
1835
- if(!init){
1836
- picker.commonInit(data, popover);
1837
- }
1838
-
1839
- if(!init || data.options.restartView) {
1840
- actions.setYearList( options.defValue || options.value, popover, data, data.options.startView);
1841
- } else {
1842
- actions[popover.element.attr('data-currentview') || 'setYearList']( options.defValue || options.value, popover, data, 0);
1843
- }
1844
-
1845
- init = true;
1175
+ webshims.ready(type, showPickerContent);
1846
1176
  popover.show(data.element);
1847
1177
  }
1848
1178
  };
1849
1179
 
1850
1180
  options.containerElements.push(popover.element[0]);
1851
1181
 
1852
- if(!options.startView){
1853
- options.startView = 0;
1854
- }
1855
- if(!options.minView){
1856
- options.minView = 0;
1857
- }
1858
- if(options.startView < options.minView){
1859
- options.minView = options.startView;
1860
- webshims.warn("wrong config for minView/startView.");
1861
- }
1862
- if(!options.size){
1863
- options.size = 1;
1182
+ if(data.type != 'color'){
1183
+ if(!options.startView){
1184
+ options.startView = 0;
1185
+ }
1186
+ if(!options.minView){
1187
+ options.minView = 0;
1188
+ }
1189
+ if(options.startView < options.minView){
1190
+ options.startView = options.minView;
1191
+ webshims.warn("wrong config for minView/startView.");
1192
+ }
1193
+ if(!options.size){
1194
+ options.size = 1;
1195
+ }
1864
1196
  }
1865
1197
 
1866
1198
  popover.element
@@ -1887,10 +1219,15 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1887
1219
  labelWidth(popover.element.children('div.ws-po-outerbox').attr({role: 'group'}), options.labels, true);
1888
1220
  labelWidth(opener, options.labels, true);
1889
1221
 
1222
+ if(options.tabindex != null){
1223
+ opener.attr({tabindex: options.tabindex});
1224
+ }
1225
+
1226
+ if(options.disabled){
1227
+ opener.prop({disabled: true});
1228
+ }
1229
+
1890
1230
  opener
1891
- .attr({
1892
- 'tabindex': options.labels.length ? 0 : '-1'
1893
- })
1894
1231
  .on({
1895
1232
  mousedown: function(){
1896
1233
  stopPropagation.apply(this, arguments);
@@ -1935,10 +1272,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1935
1272
  });
1936
1273
  })();
1937
1274
  data.popover = popover;
1275
+ data.opener = opener;
1276
+ $(data.orig).on('remove', function(e){
1277
+ if(!e.originalEvent){
1278
+ opener.remove();
1279
+ popover.element.remove();
1280
+ }
1281
+ });
1282
+
1283
+ loadPicker(data.type, 'WINDOWLOAD');
1938
1284
  };
1939
1285
 
1940
1286
  picker.month = picker._common;
1941
- picker.date = picker.month;
1287
+ picker.date = picker._common;
1288
+ picker.color = function(data){
1289
+ var ret = picker._common.apply(this, arguments);
1290
+ var alpha = $(data.orig).data('alphacontrol');
1291
+ var colorIndicator = data.opener
1292
+ .prepend('<span class="ws-color-indicator-bg"><span class="ws-color-indicator" /></span>')
1293
+ .find('.ws-color-indicator')
1294
+ ;
1295
+ var showColor = function(){
1296
+ colorIndicator.css({backgroundColor: $.prop(this, 'value') || '#000'})
1297
+ };
1298
+ var showOpacity = (function(){
1299
+ var timer;
1300
+ var show = function(){
1301
+ try {
1302
+ var value = data.alpha.prop('valueAsNumber') / (data.alpha.prop('max') || 1);
1303
+ if(!isNaN(value)){
1304
+ colorIndicator.css({opacity: value});
1305
+ }
1306
+ } catch(er){}
1307
+
1308
+ };
1309
+ return function(e){
1310
+ clearTimeout(timer);
1311
+ timer = setTimeout(show, !e || e.type == 'change' ? 4: 40);
1312
+ };
1313
+ })();
1314
+ data.alpha = (alpha) ? $('#'+alpha) : $([]);
1315
+
1316
+ $(data.orig).on('wsupdatevalue change', showColor).each(showColor);
1317
+ data.alpha.on('wsupdatevalue change input', showOpacity).each(showOpacity);
1318
+ return ret;
1319
+ };
1942
1320
 
1943
1321
  webshims.picker = picker;
1944
1322
  })();
@@ -1959,6 +1337,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1959
1337
  'max',
1960
1338
  'step',
1961
1339
  'title',
1340
+ 'required',
1962
1341
  'placeholder'
1963
1342
  ];
1964
1343
 
@@ -1967,11 +1346,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1967
1346
 
1968
1347
  $.each(copyProps.concat(copyAttrs), function(i, name){
1969
1348
  var fnName = name.replace(/^data\-/, '');
1970
- webshims.onNodeNamesPropertyModify('input', name, function(val){
1349
+ webshims.onNodeNamesPropertyModify('input', name, function(val, boolVal){
1971
1350
  if(!stopCircular){
1972
1351
  var shadowData = webshims.data(this, 'shadowData');
1973
1352
  if(shadowData && shadowData.data && shadowData.nativeElement === this && shadowData.data[fnName]){
1974
- shadowData.data[fnName](val);
1353
+ shadowData.data[fnName](val, boolVal);
1975
1354
  }
1976
1355
  }
1977
1356
  });
@@ -2002,6 +1381,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2002
1381
  var sizeInput = function(data){
2003
1382
  var init;
2004
1383
  var updateStyles = function(){
1384
+ $(data.orig).removeClass('ws-important-hide');
2005
1385
  $.style( data.orig, 'display', '' );
2006
1386
  var hasButtons, marginR, marginL;
2007
1387
  var correctWidth = 0.6;
@@ -2035,13 +1415,14 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2035
1415
  data.element.outerWidth( $(data.orig).outerWidth() - correctWidth );
2036
1416
  }
2037
1417
  init = true;
2038
- $.style( data.orig, 'display', 'none' );
1418
+ $(data.orig).addClass('ws-important-hide');
2039
1419
  };
2040
- $(document).onTrigger('updateshadowdom', updateStyles);
1420
+ data.element.onWSOff('updateshadowdom', updateStyles, true);
2041
1421
  };
2042
1422
 
2043
1423
 
2044
1424
  var implementType = function(){
1425
+
2045
1426
  var type = $.prop(this, 'type');
2046
1427
 
2047
1428
  var i, opts, data, optsName, labels;
@@ -2096,7 +1477,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2096
1477
  data.shim.options.containerElements.push(data.shim.element[0]);
2097
1478
 
2098
1479
  labelWidth($(this).getShadowFocusElement(), labels);
2099
- $.attr(this, 'required', $.attr(this, 'required'));
1480
+
2100
1481
  $(this).on('change', function(e){
2101
1482
  if(!stopCircular){
2102
1483
  data.shim.value($.prop(this, 'value'));
@@ -2155,18 +1536,13 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2155
1536
 
2156
1537
  if(opts.calculateWidth){
2157
1538
  sizeInput(data.shim);
1539
+ } else {
1540
+ $(this).css({display: 'none'});
2158
1541
  }
2159
- $(this).css({display: 'none'});
2160
1542
  }
1543
+
2161
1544
  };
2162
1545
 
2163
- if(!modernizrInputTypes.range || options.replaceUI){
2164
- extendType('range', {
2165
- _create: function(opts, set){
2166
- return $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
2167
- }
2168
- });
2169
- }
2170
1546
 
2171
1547
  if(Modernizr.formvalidation){
2172
1548
  ['input', 'form'].forEach(function(name){
@@ -2183,12 +1559,20 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2183
1559
  });
2184
1560
  }
2185
1561
 
1562
+ if(!modernizrInputTypes.range || options.replaceUI){
1563
+ extendType('range', {
1564
+ _create: function(opts, set){
1565
+ var data = $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
1566
+ return data;
1567
+ }
1568
+ });
1569
+ }
2186
1570
 
2187
- ['number', 'time', 'month', 'date'].forEach(function(name){
2188
- if(!modernizrInputTypes[name] || options.replaceUI){
1571
+ var isStupid = navigator.userAgent.indexOf('MSIE 10.0') != -1 && navigator.userAgent.indexOf('Touch') == -1;
1572
+ ['number', 'time', 'month', 'date', 'color'].forEach(function(name){
1573
+ if(!modernizrInputTypes[name] || options.replaceUI || (name == 'number' && isStupid)){
2189
1574
  extendType(name, {
2190
1575
  _create: function(opts, set){
2191
-
2192
1576
  if(opts.splitInput && !splitInputs[name]){
2193
1577
  webshims.warn('splitInput not supported for '+ name);
2194
1578
  opts.splitInput = false;
@@ -2196,11 +1580,12 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2196
1580
  var markup = opts.splitInput ?
2197
1581
  '<span class="ws-'+name+' ws-input" role="group"></span>' :
2198
1582
  '<input class="ws-'+name+'" type="text" />';
2199
- var data = $(markup) //role="spinbutton"???
2200
- .insertAfter(opts.orig)
2201
- .spinbtnUI(opts)
2202
- .data('wsspinner')
2203
- ;
1583
+ var data = $(markup).insertAfter(opts.orig);
1584
+ if(steps[name]){
1585
+ data = data.spinbtnUI(opts).data('wsWidget'+name);
1586
+ } else {
1587
+ data = data.wsBaseWidget(opts).data('wsWidget'+name);
1588
+ }
2204
1589
  if(webshims.picker && webshims.picker[name]){
2205
1590
  webshims.picker[name](data);
2206
1591
  }