webshims-rails 1.11.6.1 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/webshims/polyfiller.js +126 -72
  4. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/canvas2png.js +9 -4
  5. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.js +32 -26
  6. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.swf +0 -0
  7. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/proxy.php +25 -4
  8. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/save.php +9 -3
  9. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/canvas2png.js +9 -4
  10. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  11. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  12. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flashcanvas.js +36 -30
  13. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/proxy.php +25 -4
  14. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/save.php +9 -3
  15. data/vendor/assets/javascripts/webshims/shims/combos/1.js +13 -6
  16. data/vendor/assets/javascripts/webshims/shims/combos/10.js +156 -143
  17. data/vendor/assets/javascripts/webshims/shims/combos/11.js +97 -84
  18. data/vendor/assets/javascripts/webshims/shims/combos/12.js +2 -4
  19. data/vendor/assets/javascripts/webshims/shims/combos/13.js +1 -2
  20. data/vendor/assets/javascripts/webshims/shims/combos/14.js +956 -2819
  21. data/vendor/assets/javascripts/webshims/shims/combos/15.js +73 -67
  22. data/vendor/assets/javascripts/webshims/shims/combos/16.js +75 -71
  23. data/vendor/assets/javascripts/webshims/shims/combos/17.js +118 -89
  24. data/vendor/assets/javascripts/webshims/shims/combos/18.js +119 -91
  25. data/vendor/assets/javascripts/webshims/shims/combos/19.js +62 -65
  26. data/vendor/assets/javascripts/webshims/shims/combos/2.js +73 -67
  27. data/vendor/assets/javascripts/webshims/shims/combos/20.js +61 -63
  28. data/vendor/assets/javascripts/webshims/shims/combos/21.js +3 -6
  29. data/vendor/assets/javascripts/webshims/shims/combos/22.js +1 -2
  30. data/vendor/assets/javascripts/webshims/shims/combos/23.js +1 -2
  31. data/vendor/assets/javascripts/webshims/shims/combos/24.js +22 -12
  32. data/vendor/assets/javascripts/webshims/shims/combos/25.js +63 -67
  33. data/vendor/assets/javascripts/webshims/shims/combos/26.js +59 -59
  34. data/vendor/assets/javascripts/webshims/shims/combos/27.js +1 -2
  35. data/vendor/assets/javascripts/webshims/shims/combos/28.js +1915 -0
  36. data/vendor/assets/javascripts/webshims/shims/combos/29.js +817 -0
  37. data/vendor/assets/javascripts/webshims/shims/combos/3.js +71 -63
  38. data/vendor/assets/javascripts/webshims/shims/combos/30.js +72 -65
  39. data/vendor/assets/javascripts/webshims/shims/combos/31.js +71 -63
  40. data/vendor/assets/javascripts/webshims/shims/combos/32.js +2343 -0
  41. data/vendor/assets/javascripts/webshims/shims/combos/33.js +897 -0
  42. data/vendor/assets/javascripts/webshims/shims/combos/4.js +59 -59
  43. data/vendor/assets/javascripts/webshims/shims/combos/5.js +119 -91
  44. data/vendor/assets/javascripts/webshims/shims/combos/6.js +120 -93
  45. data/vendor/assets/javascripts/webshims/shims/combos/7.js +74 -69
  46. data/vendor/assets/javascripts/webshims/shims/combos/8.js +73 -67
  47. data/vendor/assets/javascripts/webshims/shims/combos/9.js +157 -145
  48. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +58 -57
  49. data/vendor/assets/javascripts/webshims/shims/form-combat.js +0 -1
  50. data/vendor/assets/javascripts/webshims/shims/form-core.js +12 -3
  51. data/vendor/assets/javascripts/webshims/shims/form-datalist-lazy.js +4 -3
  52. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +20 -3
  53. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +78 -71
  54. data/vendor/assets/javascripts/webshims/shims/form-shim-extend2.js +21 -10
  55. data/vendor/assets/javascripts/webshims/shims/form-validation.js +39 -27
  56. data/vendor/assets/javascripts/webshims/shims/forms-picker.js +173 -128
  57. data/vendor/assets/javascripts/webshims/shims/i18n/{formcfg-ch-ZN.js → formcfg-ch-CN.js} +0 -0
  58. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-en.js +0 -2
  59. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-zh-CN.js +65 -0
  60. data/vendor/assets/javascripts/webshims/shims/plugins/jquery.ui.position.js +1 -1
  61. data/vendor/assets/javascripts/webshims/shims/range-ui.js +18 -11
  62. data/vendor/assets/javascripts/webshims/shims/styles/forms-ext.css +221 -153
  63. data/vendor/assets/javascripts/webshims/shims/styles/progress.gif +0 -0
  64. data/vendor/assets/javascripts/webshims/shims/styles/progress.png +0 -0
  65. data/vendor/assets/javascripts/webshims/shims/styles/scss/_extends.scss +5 -0
  66. data/vendor/assets/javascripts/webshims/shims/styles/scss/forms-ext.scss +273 -177
  67. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +113 -98
  68. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +114 -88
  69. data/vendor/assets/javascripts/webshims/shims/track-ui.js +2 -2
  70. metadata +10 -7
  71. data/vendor/assets/javascripts/webshims/extras/mousepress.js +0 -60
  72. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Thumbs.db +0 -0
  73. data/vendor/assets/javascripts/webshims/shims/json-storage.js +0 -316
  74. data/vendor/assets/javascripts/webshims/shims/mediagroup.js +0 -29
@@ -0,0 +1,897 @@
1
+ webshims.register('form-number-date-api', function($, webshims, window, document, undefined, options){
2
+ "use strict";
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
+ }
6
+
7
+ if(!webshims.getStep){
8
+ webshims.getStep = function(elem, type){
9
+ var step = $.attr(elem, 'step');
10
+ if(step === 'any'){
11
+ return step;
12
+ }
13
+ type = type || getType(elem);
14
+ if(!typeModels[type] || !typeModels[type].step){
15
+ return step;
16
+ }
17
+ step = typeProtos.number.asNumber(step);
18
+ return ((!isNaN(step) && step > 0) ? step : typeModels[type].step) * (typeModels[type].stepScaleFactor || 1);
19
+ };
20
+ }
21
+ if(!webshims.addMinMaxNumberToCache){
22
+ webshims.addMinMaxNumberToCache = function(attr, elem, cache){
23
+ if (!(attr+'AsNumber' in cache)) {
24
+ cache[attr+'AsNumber'] = typeModels[cache.type].asNumber(elem.attr(attr));
25
+ if(isNaN(cache[attr+'AsNumber']) && (attr+'Default' in typeModels[cache.type])){
26
+ cache[attr+'AsNumber'] = typeModels[cache.type][attr+'Default'];
27
+ }
28
+ }
29
+ };
30
+ }
31
+
32
+ var nan = parseInt('NaN', 10),
33
+ doc = document,
34
+ typeModels = webshims.inputTypes,
35
+ isNumber = function(string){
36
+ return (typeof string == 'number' || (string && string == string * 1));
37
+ },
38
+ supportsType = function(type){
39
+ return ($('<input type="'+type+'" />').prop('type') === type);
40
+ },
41
+ getType = function(elem){
42
+ return (elem.getAttribute('type') || '').toLowerCase();
43
+ },
44
+ isDateTimePart = function(string){
45
+ return (string && !(isNaN(string * 1)));
46
+ },
47
+ addMinMaxNumberToCache = webshims.addMinMaxNumberToCache,
48
+ addleadingZero = function(val, len){
49
+ val = ''+val;
50
+ len = len - val.length;
51
+ for(var i = 0; i < len; i++){
52
+ val = '0'+val;
53
+ }
54
+ return val;
55
+ },
56
+ EPS = 1e-7,
57
+ typeBugs = webshims.bugs.bustedValidity
58
+ ;
59
+
60
+ webshims.addValidityRule('stepMismatch', function(input, val, cache, validityState){
61
+ if(val === ''){return false;}
62
+ if(!('type' in cache)){
63
+ cache.type = getType(input[0]);
64
+ }
65
+ if(cache.type == 'week'){return false;}
66
+ var base, attrVal;
67
+ var ret = (validityState || {}).stepMismatch || false;
68
+ if(typeModels[cache.type] && typeModels[cache.type].step){
69
+ if( !('step' in cache) ){
70
+ cache.step = webshims.getStep(input[0], cache.type);
71
+ }
72
+
73
+ if(cache.step == 'any'){return false;}
74
+
75
+ if(!('valueAsNumber' in cache)){
76
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
77
+ }
78
+ if(isNaN(cache.valueAsNumber)){return false;}
79
+
80
+ addMinMaxNumberToCache('min', input, cache);
81
+ base = cache.minAsNumber;
82
+
83
+ if(isNaN(base) && (attrVal = input.prop('defaultValue'))){
84
+ base = typeModels[cache.type].asNumber( attrVal );
85
+ }
86
+
87
+ if(isNaN(base)){
88
+ base = typeModels[cache.type].stepBase || 0;
89
+ }
90
+
91
+ ret = Math.abs((cache.valueAsNumber - base) % cache.step);
92
+
93
+ ret = !( ret <= EPS || Math.abs(ret - cache.step) <= EPS );
94
+ }
95
+ return ret;
96
+ });
97
+
98
+
99
+
100
+ [{name: 'rangeOverflow', attr: 'max', factor: 1}, {name: 'rangeUnderflow', attr: 'min', factor: -1}].forEach(function(data, i){
101
+ webshims.addValidityRule(data.name, function(input, val, cache, validityState) {
102
+ var ret = (validityState || {})[data.name] || false;
103
+ if(val === ''){return ret;}
104
+ if (!('type' in cache)) {
105
+ cache.type = getType(input[0]);
106
+ }
107
+ if (typeModels[cache.type] && typeModels[cache.type].asNumber) {
108
+ if(!('valueAsNumber' in cache)){
109
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
110
+ }
111
+ if(isNaN(cache.valueAsNumber)){
112
+ return false;
113
+ }
114
+
115
+ addMinMaxNumberToCache(data.attr, input, cache);
116
+
117
+ if(isNaN(cache[data.attr+'AsNumber'])){
118
+ return ret;
119
+ }
120
+ ret = ( cache[data.attr+'AsNumber'] * data.factor < cache.valueAsNumber * data.factor - EPS );
121
+ }
122
+ return ret;
123
+ });
124
+ });
125
+
126
+ webshims.reflectProperties(['input'], ['max', 'min', 'step']);
127
+
128
+
129
+ //IDLs and methods, that aren't part of constrain validation, but strongly tight to it
130
+ var valueAsNumberDescriptor = webshims.defineNodeNameProperty('input', 'valueAsNumber', {
131
+ prop: {
132
+ get: function(){
133
+ var elem = this;
134
+ var type = getType(elem);
135
+ var ret = (typeModels[type] && typeModels[type].asNumber) ?
136
+ typeModels[type].asNumber($.prop(elem, 'value')) :
137
+ (valueAsNumberDescriptor.prop._supget && valueAsNumberDescriptor.prop._supget.apply(elem, arguments));
138
+ if(ret == null){
139
+ ret = nan;
140
+ }
141
+ return ret;
142
+ },
143
+ set: function(val){
144
+ var elem = this;
145
+ var type = getType(elem);
146
+ if(typeModels[type] && typeModels[type].numberToString){
147
+ //is NaN a number?
148
+ if(isNaN(val)){
149
+ $.prop(elem, 'value', '');
150
+ return;
151
+ }
152
+ var set = typeModels[type].numberToString(val);
153
+ if(set !== false){
154
+ $.prop(elem, 'value', set);
155
+ } else {
156
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
157
+ }
158
+ } else if(valueAsNumberDescriptor.prop._supset) {
159
+ valueAsNumberDescriptor.prop._supset.apply(elem, arguments);
160
+ }
161
+ }
162
+ }
163
+ });
164
+
165
+ var valueAsDateDescriptor = webshims.defineNodeNameProperty('input', 'valueAsDate', {
166
+ prop: {
167
+ get: function(){
168
+ var elem = this;
169
+ var type = getType(elem);
170
+ return (typeModels[type] && typeModels[type].asDate && !typeModels[type].noAsDate) ?
171
+ typeModels[type].asDate($.prop(elem, 'value')) :
172
+ valueAsDateDescriptor.prop._supget && valueAsDateDescriptor.prop._supget.call(elem) || null;
173
+ },
174
+ set: function(value){
175
+ var elem = this;
176
+ var type = getType(elem);
177
+ if(typeModels[type] && typeModels[type].dateToString && !typeModels[type].noAsDate){
178
+
179
+ if(value === null){
180
+ $.prop(elem, 'value', '');
181
+ return '';
182
+ }
183
+ var set = typeModels[type].dateToString(value);
184
+ if(set !== false){
185
+ $.prop(elem, 'value', set);
186
+ return set;
187
+ } else {
188
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
189
+ }
190
+ } else {
191
+ return valueAsDateDescriptor.prop._supset && valueAsDateDescriptor.prop._supset.apply(elem, arguments) || null;
192
+ }
193
+ }
194
+ }
195
+ });
196
+
197
+ $.each({stepUp: 1, stepDown: -1}, function(name, stepFactor){
198
+ var stepDescriptor = webshims.defineNodeNameProperty('input', name, {
199
+ prop: {
200
+ value: function(factor){
201
+ var step, val, dateVal, valModStep, alignValue, cache, base, attrVal;
202
+ var type = getType(this);
203
+ if(typeModels[type] && typeModels[type].asNumber){
204
+ cache = {type: type};
205
+ if(!factor){
206
+ factor = 1;
207
+ webshims.warn("you should always use a factor for stepUp/stepDown");
208
+ }
209
+ factor *= stepFactor;
210
+
211
+ val = $.prop(this, 'valueAsNumber');
212
+
213
+ if(isNaN(val)){
214
+ webshims.info("valueAsNumber is NaN can't apply stepUp/stepDown ");
215
+ throw('invalid state error');
216
+ }
217
+
218
+ step = webshims.getStep(this, type);
219
+
220
+ if(step == 'any'){
221
+ webshims.info("step is 'any' can't apply stepUp/stepDown");
222
+ throw('invalid state error');
223
+ }
224
+
225
+ webshims.addMinMaxNumberToCache('min', $(this), cache);
226
+ webshims.addMinMaxNumberToCache('max', $(this), cache);
227
+
228
+ base = cache.minAsNumber;
229
+
230
+ if(isNaN(base) && (attrVal = $.prop(this, 'defaultValue'))){
231
+ base = typeModels[type].asNumber( attrVal );
232
+ }
233
+
234
+ if(!base){
235
+ base = 0;
236
+ }
237
+
238
+ step *= factor;
239
+
240
+ val = (val + step).toFixed(5) * 1;
241
+
242
+ valModStep = (val - base) % step;
243
+
244
+ if ( valModStep && (Math.abs(valModStep) > EPS) ) {
245
+ alignValue = val - valModStep;
246
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
247
+ val = alignValue.toFixed(5) * 1;
248
+ }
249
+
250
+ if( (!isNaN(cache.maxAsNumber) && val > cache.maxAsNumber) || (!isNaN(cache.minAsNumber) && val < cache.minAsNumber) ){
251
+ webshims.info("max/min overflow can't apply stepUp/stepDown");
252
+ throw('invalid state error');
253
+ }
254
+
255
+ $.prop(this, 'valueAsNumber', val);
256
+
257
+ } else if(stepDescriptor.prop && stepDescriptor.prop._supvalue){
258
+ return stepDescriptor.prop._supvalue.apply(this, arguments);
259
+ } else {
260
+ webshims.info("no step method for type: "+ type);
261
+ throw('invalid state error');
262
+ }
263
+ }
264
+ }
265
+ });
266
+ });
267
+
268
+ /*
269
+ * ToDO: WEEK
270
+ */
271
+ // var getWeek = function(date){
272
+ // var time;
273
+ // var checkDate = new Date(date.getTime());
274
+ //
275
+ // checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
276
+ //
277
+ // time = checkDate.getTime();
278
+ // checkDate.setMonth(0);
279
+ // checkDate.setDate(1);
280
+ // return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
281
+ // };
282
+ //
283
+ // var setWeek = function(year, week){
284
+ // var date = new Date(year, 0, 1);
285
+ //
286
+ // week = (week - 1) * 86400000 * 7;
287
+ // date = new Date(date.getTime() + week);
288
+ // date.setDate(date.getDate() + 1 - (date.getDay() || 7));
289
+ // return date;
290
+ // };
291
+
292
+ var typeProtos = {
293
+
294
+ number: {
295
+ bad: function(val){
296
+ return !(isNumber(val));
297
+ },
298
+ step: 1,
299
+ //stepBase: 0, 0 = default
300
+ stepScaleFactor: 1,
301
+ asNumber: function(str){
302
+ return (isNumber(str)) ? str * 1 : nan;
303
+ },
304
+ numberToString: function(num){
305
+ return (isNumber(num)) ? num : false;
306
+ }
307
+ },
308
+
309
+ range: {
310
+ minDefault: 0,
311
+ maxDefault: 100
312
+ },
313
+ color: {
314
+ bad: (function(){
315
+ var cReg = /^\u0023[a-f0-9]{6}$/;
316
+ return function(val){
317
+ return (!val || val.length != 7 || !(cReg.test(val)));
318
+ };
319
+ })()
320
+ },
321
+ date: {
322
+ bad: function(val){
323
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
324
+ var i;
325
+ var valA = val.split(/\u002D/);
326
+ if(valA.length !== 3){return true;}
327
+ var ret = false;
328
+
329
+
330
+ if(valA[0].length < 4 || valA[1].length != 2 || valA[1] > 12 || valA[2].length != 2 || valA[2] > 33){
331
+ ret = true;
332
+ } else {
333
+ for(i = 0; i < 3; i++){
334
+ if(!isDateTimePart(valA[i])){
335
+ ret = true;
336
+ break;
337
+ }
338
+ }
339
+ }
340
+
341
+ return ret || (val !== this.dateToString( this.asDate(val, true) ) );
342
+ },
343
+ step: 1,
344
+ //stepBase: 0, 0 = default
345
+ stepScaleFactor: 86400000,
346
+ asDate: function(val, _noMismatch){
347
+ if(!_noMismatch && this.bad(val)){
348
+ return null;
349
+ }
350
+ return new Date(this.asNumber(val, true));
351
+ },
352
+ asNumber: function(str, _noMismatch){
353
+ var ret = nan;
354
+ if(_noMismatch || !this.bad(str)){
355
+ str = str.split(/\u002D/);
356
+ ret = Date.UTC(str[0], str[1] - 1, str[2]);
357
+ }
358
+ return ret;
359
+ },
360
+ numberToString: function(num){
361
+ return (isNumber(num)) ? this.dateToString(new Date( num * 1)) : false;
362
+ },
363
+ dateToString: function(date){
364
+ return (date && date.getFullYear) ? addleadingZero(date.getUTCFullYear(), 4) +'-'+ addleadingZero(date.getUTCMonth()+1, 2) +'-'+ addleadingZero(date.getUTCDate(), 2) : false;
365
+ }
366
+ },
367
+ /*
368
+ * ToDO: WEEK
369
+ */
370
+ // week: {
371
+ // bad: function(val){
372
+ // if(!val || !val.split){return true;}
373
+ // var valA = val.split('-W');
374
+ // var ret = true;
375
+ // if(valA.length == 2 && valA[0].length > 3 && valA.length == 2){
376
+ // ret = this.dateToString(setWeek(valA[0], valA[1])) != val;
377
+ // }
378
+ // return ret;
379
+ // },
380
+ // step: 1,
381
+ // stepScaleFactor: 604800000,
382
+ // stepBase: -259200000,
383
+ // asDate: function(str, _noMismatch){
384
+ // var ret = null;
385
+ // if(_noMismatch || !this.bad(str)){
386
+ // ret = str.split('-W');
387
+ // ret = setWeek(ret[0], ret[1]);
388
+ // }
389
+ // return ret;
390
+ // },
391
+ // asNumber: function(str, _noMismatch){
392
+ // var ret = nan;
393
+ // var date = this.asDate(str, _noMismatch);
394
+ // if(date && date.getUTCFullYear){
395
+ // ret = date.getTime();
396
+ // }
397
+ // return ret;
398
+ // },
399
+ // dateToString: function(date){
400
+ // var week, checkDate;
401
+ // var ret = false;
402
+ // if(date && date.getFullYear){
403
+ // week = getWeek(date);
404
+ // if(week == 1){
405
+ // checkDate = new Date(date.getTime());
406
+ // checkDate.setDate(checkDate.getDate() + 7);
407
+ // date.setUTCFullYear(checkDate.getUTCFullYear());
408
+ // }
409
+ // ret = addleadingZero(date.getUTCFullYear(), 4) +'-W'+addleadingZero(week, 2);
410
+ // }
411
+ // return ret;
412
+ // },
413
+ // numberToString: function(num){
414
+ // return (isNumber(num)) ? this.dateToString(new Date( num * 1)) : false;
415
+ // }
416
+ // },
417
+ time: {
418
+ bad: function(val, _getParsed){
419
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
420
+ val = val.split(/\u003A/);
421
+ if(val.length < 2 || val.length > 3){return true;}
422
+ var ret = false,
423
+ sFraction;
424
+ if(val[2]){
425
+ val[2] = val[2].split(/\u002E/);
426
+ sFraction = parseInt(val[2][1], 10);
427
+ val[2] = val[2][0];
428
+ }
429
+ $.each(val, function(i, part){
430
+ if(!isDateTimePart(part) || part.length !== 2){
431
+ ret = true;
432
+ return false;
433
+ }
434
+ });
435
+ if(ret){return true;}
436
+ if(val[0] > 23 || val[0] < 0 || val[1] > 59 || val[1] < 0){
437
+ return true;
438
+ }
439
+ if(val[2] && (val[2] > 59 || val[2] < 0 )){
440
+ return true;
441
+ }
442
+ if(sFraction && isNaN(sFraction)){
443
+ return true;
444
+ }
445
+ if(sFraction){
446
+ if(sFraction < 100){
447
+ sFraction *= 100;
448
+ } else if(sFraction < 10){
449
+ sFraction *= 10;
450
+ }
451
+ }
452
+ return (_getParsed === true) ? [val, sFraction] : false;
453
+ },
454
+ step: 60,
455
+ stepBase: 0,
456
+ stepScaleFactor: 1000,
457
+ asDate: function(val){
458
+ val = new Date(this.asNumber(val));
459
+ return (isNaN(val)) ? null : val;
460
+ },
461
+ asNumber: function(val){
462
+ var ret = nan;
463
+ val = this.bad(val, true);
464
+ if(val !== true){
465
+ ret = Date.UTC('1970', 0, 1, val[0][0], val[0][1], val[0][2] || 0);
466
+ if(val[1]){
467
+ ret += val[1];
468
+ }
469
+ }
470
+ return ret;
471
+ },
472
+ dateToString: function(date){
473
+ if(date && date.getUTCHours){
474
+ var str = addleadingZero(date.getUTCHours(), 2) +':'+ addleadingZero(date.getUTCMinutes(), 2),
475
+ tmp = date.getSeconds()
476
+ ;
477
+ if(tmp != "0"){
478
+ str += ':'+ addleadingZero(tmp, 2);
479
+ }
480
+ tmp = date.getUTCMilliseconds();
481
+ if(tmp != "0"){
482
+ str += '.'+ addleadingZero(tmp, 3);
483
+ }
484
+ return str;
485
+ } else {
486
+ return false;
487
+ }
488
+ }
489
+ },
490
+ month: {
491
+ bad: function(val){
492
+ return typeProtos.date.bad(val+'-01');
493
+ },
494
+ step: 1,
495
+ stepScaleFactor: false,
496
+ //stepBase: 0, 0 = default
497
+ asDate: function(val){
498
+ return new Date(typeProtos.date.asNumber(val+'-01'));
499
+ },
500
+ asNumber: function(val){
501
+ //1970-01
502
+ var ret = nan;
503
+ if(val && !this.bad(val)){
504
+ val = val.split(/\u002D/);
505
+ val[0] = (val[0] * 1) - 1970;
506
+ val[1] = (val[1] * 1) - 1;
507
+ ret = (val[0] * 12) + val[1];
508
+ }
509
+ return ret;
510
+ },
511
+ numberToString: function(num){
512
+ var mod;
513
+ var ret = false;
514
+ if(isNumber(num)){
515
+ mod = (num % 12);
516
+ num = ((num - mod) / 12) + 1970;
517
+ mod += 1;
518
+ if(mod < 1){
519
+ num -= 1;
520
+ mod += 12;
521
+ }
522
+ ret = addleadingZero(num, 4)+'-'+addleadingZero(mod, 2);
523
+
524
+ }
525
+
526
+ return ret;
527
+ },
528
+ dateToString: function(date){
529
+ if(date && date.getUTCHours){
530
+ var str = typeProtos.date.dateToString(date);
531
+ return (str.split && (str = str.split(/\u002D/))) ? str[0]+'-'+str[1] : false;
532
+ } else {
533
+ return false;
534
+ }
535
+ }
536
+ }
537
+ ,'datetime-local': {
538
+ bad: function(val, _getParsed){
539
+ if(!val || !val.split || (val+'special').split(/\u0054/).length !== 2){return true;}
540
+ val = val.split(/\u0054/);
541
+ return ( typeProtos.date.bad(val[0]) || typeProtos.time.bad(val[1], _getParsed) );
542
+ },
543
+ noAsDate: true,
544
+ asDate: function(val){
545
+ val = new Date(this.asNumber(val));
546
+
547
+ return (isNaN(val)) ? null : val;
548
+ },
549
+ asNumber: function(val){
550
+ var ret = nan;
551
+ var time = this.bad(val, true);
552
+ if(time !== true){
553
+ val = val.split(/\u0054/)[0].split(/\u002D/);
554
+
555
+ ret = Date.UTC(val[0], val[1] - 1, val[2], time[0][0], time[0][1], time[0][2] || 0);
556
+ if(time[1]){
557
+ ret += time[1];
558
+ }
559
+ }
560
+ return ret;
561
+ },
562
+ dateToString: function(date, _getParsed){
563
+ return typeProtos.date.dateToString(date) +'T'+ typeProtos.time.dateToString(date, _getParsed);
564
+ }
565
+ }
566
+ };
567
+
568
+ if(typeBugs || !supportsType('range') || !supportsType('time') || !supportsType('month') || !supportsType('datetime-local')){
569
+ typeProtos.range = $.extend({}, typeProtos.number, typeProtos.range);
570
+ typeProtos.time = $.extend({}, typeProtos.date, typeProtos.time);
571
+ typeProtos.month = $.extend({}, typeProtos.date, typeProtos.month);
572
+ typeProtos['datetime-local'] = $.extend({}, typeProtos.date, typeProtos.time, typeProtos['datetime-local']);
573
+ }
574
+
575
+ //
576
+ ['number', 'month', 'range', 'date', 'time', 'color', 'datetime-local'].forEach(function(type){
577
+ if(typeBugs || !supportsType(type)){
578
+ webshims.addInputType(type, typeProtos[type]);
579
+ }
580
+ });
581
+
582
+ if($('<input />').prop('labels') == null){
583
+ webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
584
+ prop: {
585
+ get: function(){
586
+ if(this.type == 'hidden'){return null;}
587
+ var id = this.id;
588
+ var labels = $(this)
589
+ .closest('label')
590
+ .filter(function(){
591
+ var hFor = (this.attributes['for'] || {});
592
+ return (!hFor.specified || hFor.value == id);
593
+ })
594
+ ;
595
+
596
+ if(id) {
597
+ labels = labels.add('label[for="'+ id +'"]');
598
+ }
599
+ return labels.get();
600
+ },
601
+ writeable: false
602
+ }
603
+ });
604
+ }
605
+
606
+ });;webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
607
+ "use strict";
608
+ var doc = document;
609
+ var lazyLoad = function(name){
610
+ if(!name || typeof name != 'string'){
611
+ name = 'DOM';
612
+ }
613
+ if(!lazyLoad[name+'Loaded']){
614
+ lazyLoad[name+'Loaded'] = true;
615
+ webshims.ready(name, function(){
616
+ webshims.loader.loadList(['form-datalist-lazy']);
617
+ });
618
+ }
619
+ };
620
+ var noDatalistSupport = {
621
+ submit: 1,
622
+ button: 1,
623
+ reset: 1,
624
+ hidden: 1,
625
+
626
+ range: 1,
627
+ date: 1,
628
+ month: 1
629
+ };
630
+ if(webshims.modules["form-number-date-ui"].loaded){
631
+ $.extend(noDatalistSupport, {
632
+ number: 1,
633
+ time: 1
634
+ });
635
+ }
636
+
637
+
638
+ /*
639
+ * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed)
640
+ */
641
+ webshims.propTypes.element = function(descs, name){
642
+ webshims.createPropDefault(descs, 'attr');
643
+ if(descs.prop){return;}
644
+ descs.prop = {
645
+ get: function(){
646
+ var elem = $.attr(this, name);
647
+ if(elem){
648
+ elem = document.getElementById(elem);
649
+ if(elem && descs.propNodeName && !$.nodeName(elem, descs.propNodeName)){
650
+ elem = null;
651
+ }
652
+ }
653
+ return elem || null;
654
+ },
655
+ writeable: false
656
+ };
657
+ };
658
+
659
+
660
+ /*
661
+ * Implements datalist element and list attribute
662
+ */
663
+
664
+ (function(){
665
+ var formsCFG = $.webshims.cfg.forms;
666
+ var listSupport = Modernizr.input.list;
667
+ if(listSupport && !formsCFG.customDatalist){return;}
668
+
669
+ var initializeDatalist = function(){
670
+
671
+ var updateDatlistAndOptions = function(){
672
+ var id;
673
+ if(!$.data(this, 'datalistWidgetData') && (id = $.prop(this, 'id'))){
674
+ $('input[list="'+ id +'"], input[data-wslist="'+ id +'"]').eq(0).attr('list', id);
675
+ } else {
676
+ $(this).triggerHandler('updateDatalist');
677
+ }
678
+ };
679
+
680
+ var inputListProto = {
681
+ //override autocomplete
682
+ autocomplete: {
683
+ attr: {
684
+ get: function(){
685
+ var elem = this;
686
+ var data = $.data(elem, 'datalistWidget');
687
+ if(data){
688
+ return data._autocomplete;
689
+ }
690
+ return ('autocomplete' in elem) ? elem.autocomplete : elem.getAttribute('autocomplete');
691
+ },
692
+ set: function(value){
693
+ var elem = this;
694
+ var data = $.data(elem, 'datalistWidget');
695
+ if(data){
696
+ data._autocomplete = value;
697
+ if(value == 'off'){
698
+ data.hideList();
699
+ }
700
+ } else {
701
+ if('autocomplete' in elem){
702
+ elem.autocomplete = value;
703
+ } else {
704
+ elem.setAttribute('autocomplete', value);
705
+ }
706
+ }
707
+ }
708
+ }
709
+ }
710
+ };
711
+
712
+ if(listSupport){
713
+ //options only return options, if option-elements are rooted: but this makes this part of HTML5 less backwards compatible
714
+ if(!($('<datalist><select><option></option></select></datalist>').prop('options') || []).length ){
715
+ webshims.defineNodeNameProperty('datalist', 'options', {
716
+ prop: {
717
+ writeable: false,
718
+ get: function(){
719
+ var options = this.options || [];
720
+ if(!options.length){
721
+ var elem = this;
722
+ var select = $('select', elem);
723
+ if(select[0] && select[0].options && select[0].options.length){
724
+ options = select[0].options;
725
+ }
726
+ }
727
+ return options;
728
+ }
729
+ }
730
+ });
731
+ }
732
+ inputListProto.list = {
733
+ attr: {
734
+ get: function(){
735
+ var val = webshims.contentAttr(this, 'list');
736
+ if(val != null){
737
+ $.data(this, 'datalistListAttr', val);
738
+ if(!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]){
739
+ this.removeAttribute('list');
740
+ }
741
+ } else {
742
+ val = $.data(this, 'datalistListAttr');
743
+ }
744
+
745
+ return (val == null) ? undefined : val;
746
+ },
747
+ set: function(value){
748
+ var elem = this;
749
+ $.data(elem, 'datalistListAttr', value);
750
+ if (!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]) {
751
+ webshims.objectCreate(shadowListProto, undefined, {
752
+ input: elem,
753
+ id: value,
754
+ datalist: $.prop(elem, 'list')
755
+ });
756
+ elem.setAttribute('data-wslist', value);
757
+ } else {
758
+ elem.setAttribute('list', value);
759
+ }
760
+ $(elem).triggerHandler('listdatalistchange');
761
+ }
762
+ },
763
+ initAttr: true,
764
+ reflect: true,
765
+ propType: 'element',
766
+ propNodeName: 'datalist'
767
+ };
768
+ } else {
769
+ webshims.defineNodeNameProperties('input', {
770
+ list: {
771
+ attr: {
772
+ get: function(){
773
+ var val = webshims.contentAttr(this, 'list');
774
+ return (val == null) ? undefined : val;
775
+ },
776
+ set: function(value){
777
+ var elem = this;
778
+ webshims.contentAttr(elem, 'list', value);
779
+ webshims.objectCreate(options.shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
780
+ $(elem).triggerHandler('listdatalistchange');
781
+ }
782
+ },
783
+ initAttr: true,
784
+ reflect: true,
785
+ propType: 'element',
786
+ propNodeName: 'datalist'
787
+ }
788
+ });
789
+ }
790
+
791
+ webshims.defineNodeNameProperties('input', inputListProto);
792
+
793
+ webshims.addReady(function(context, contextElem){
794
+ contextElem
795
+ .filter('datalist > select, datalist, datalist > option, datalist > select > option')
796
+ .closest('datalist')
797
+ .each(updateDatlistAndOptions)
798
+ ;
799
+ });
800
+ };
801
+
802
+
803
+ /*
804
+ * ShadowList
805
+ */
806
+
807
+ var shadowListProto = {
808
+ _create: function(opts){
809
+
810
+ if(noDatalistSupport[$.prop(opts.input, 'type')] || noDatalistSupport[$.attr(opts.input, 'type')]){return;}
811
+ var datalist = opts.datalist;
812
+ var data = $.data(opts.input, 'datalistWidget');
813
+ var that = this;
814
+ if(datalist && data && data.datalist !== datalist){
815
+ data.datalist = datalist;
816
+ data.id = opts.id;
817
+
818
+
819
+ $(data.datalist)
820
+ .off('updateDatalist.datalistWidget')
821
+ .on('updateDatalist.datalistWidget', $.proxy(data, '_resetListCached'))
822
+ ;
823
+
824
+ data._resetListCached();
825
+ return;
826
+ } else if(!datalist){
827
+ if(data){
828
+ data.destroy();
829
+ }
830
+ return;
831
+ } else if(data && data.datalist === datalist){
832
+ return;
833
+ }
834
+
835
+
836
+
837
+ this.datalist = datalist;
838
+ this.id = opts.id;
839
+ this.hasViewableData = true;
840
+ this._autocomplete = $.attr(opts.input, 'autocomplete');
841
+ $.data(opts.input, 'datalistWidget', this);
842
+ $.data(datalist, 'datalistWidgetData', this);
843
+
844
+ lazyLoad('WINDOWLOAD');
845
+
846
+ if(webshims.isReady('form-datalist-lazy')){
847
+ this._lazyCreate(opts);
848
+ } else {
849
+ $(opts.input).one('focus', lazyLoad);
850
+ webshims.ready('form-datalist-lazy', function(){
851
+ if(!that._destroyed){
852
+ that._lazyCreate(opts);
853
+ }
854
+ });
855
+ }
856
+ },
857
+ destroy: function(e){
858
+ var input;
859
+ var autocomplete = $.attr(this.input, 'autocomplete');
860
+ $(this.input)
861
+ .off('.datalistWidget')
862
+ .removeData('datalistWidget')
863
+ ;
864
+ this.shadowList.remove();
865
+ $(document).off('.datalist'+this.id);
866
+ $(window).off('.datalist'+this.id);
867
+ if(this.input.form && this.input.id){
868
+ $(this.input.form).off('submit.datalistWidget'+this.input.id);
869
+ }
870
+ this.input.removeAttribute('aria-haspopup');
871
+ if(autocomplete === undefined){
872
+ this.input.removeAttribute('autocomplete');
873
+ } else {
874
+ $(this.input).attr('autocomplete', autocomplete);
875
+ }
876
+ if(e && e.type == 'beforeunload'){
877
+ input = this.input;
878
+ setTimeout(function(){
879
+ $.attr(input, 'list', $.attr(input, 'list'));
880
+ }, 9);
881
+ }
882
+ this._destroyed = true;
883
+ }
884
+ };
885
+
886
+ webshims.loader.addModule('form-datalist-lazy', {
887
+ noAutoCallback: true,
888
+ options: $.extend(options, {shadowListProto: shadowListProto})
889
+ });
890
+ if(!options.list){
891
+ options.list = {};
892
+ }
893
+ //init datalist update
894
+ initializeDatalist();
895
+ })();
896
+
897
+ });