webshims-rails 1.10.3 → 1.10.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +8 -8
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/webshims/polyfiller.js +96 -73
  4. data/vendor/assets/javascripts/webshims/shims/color-picker.js +2415 -0
  5. data/vendor/assets/javascripts/webshims/shims/combos/1.js +248 -745
  6. data/vendor/assets/javascripts/webshims/shims/combos/10.js +771 -1206
  7. data/vendor/assets/javascripts/webshims/shims/combos/11.js +679 -1201
  8. data/vendor/assets/javascripts/webshims/shims/combos/12.js +46 -65
  9. data/vendor/assets/javascripts/webshims/shims/combos/13.js +45 -64
  10. data/vendor/assets/javascripts/webshims/shims/combos/14.js +94 -7
  11. data/vendor/assets/javascripts/webshims/shims/combos/15.js +557 -1189
  12. data/vendor/assets/javascripts/webshims/shims/combos/16.js +598 -1249
  13. data/vendor/assets/javascripts/webshims/shims/combos/17.js +697 -1208
  14. data/vendor/assets/javascripts/webshims/shims/combos/18.js +697 -1208
  15. data/vendor/assets/javascripts/webshims/shims/combos/19.js +145 -78
  16. data/vendor/assets/javascripts/webshims/shims/combos/2.js +472 -1280
  17. data/vendor/assets/javascripts/webshims/shims/combos/20.js +144 -77
  18. data/vendor/assets/javascripts/webshims/shims/combos/21.js +14 -15
  19. data/vendor/assets/javascripts/webshims/shims/combos/22.js +2 -2
  20. data/vendor/assets/javascripts/webshims/shims/combos/23.js +45 -64
  21. data/vendor/assets/javascripts/webshims/shims/combos/24.js +848 -0
  22. data/vendor/assets/javascripts/webshims/shims/combos/25.js +4373 -0
  23. data/vendor/assets/javascripts/webshims/shims/combos/26.js +1516 -0
  24. data/vendor/assets/javascripts/webshims/shims/combos/27.js +884 -0
  25. data/vendor/assets/javascripts/webshims/shims/combos/28.js +2067 -0
  26. data/vendor/assets/javascripts/webshims/shims/combos/29.js +1156 -0
  27. data/vendor/assets/javascripts/webshims/shims/combos/3.js +313 -700
  28. data/vendor/assets/javascripts/webshims/shims/combos/30.js +1868 -0
  29. data/vendor/assets/javascripts/webshims/shims/combos/31.js +1663 -0
  30. data/vendor/assets/javascripts/webshims/shims/combos/4.js +111 -20
  31. data/vendor/assets/javascripts/webshims/shims/combos/5.js +747 -1321
  32. data/vendor/assets/javascripts/webshims/shims/combos/6.js +837 -1809
  33. data/vendor/assets/javascripts/webshims/shims/combos/7.js +435 -1239
  34. data/vendor/assets/javascripts/webshims/shims/combos/8.js +360 -766
  35. data/vendor/assets/javascripts/webshims/shims/combos/9.js +843 -1676
  36. data/vendor/assets/javascripts/webshims/shims/details.js +1 -1
  37. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +90 -3
  38. data/vendor/assets/javascripts/webshims/shims/filereader.js +386 -0
  39. data/vendor/assets/javascripts/webshims/shims/form-core.js +201 -680
  40. data/vendor/assets/javascripts/webshims/shims/form-datalist-lazy.js +418 -0
  41. data/vendor/assets/javascripts/webshims/shims/form-datalist.js +69 -467
  42. data/vendor/assets/javascripts/webshims/shims/form-message.js +21 -17
  43. data/vendor/assets/javascripts/webshims/shims/form-native-extend.js +19 -82
  44. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +17 -6
  45. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +570 -1185
  46. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +181 -28
  47. data/vendor/assets/javascripts/webshims/shims/form-validation.js +599 -0
  48. data/vendor/assets/javascripts/webshims/{extras/custom-validity.js → shims/form-validators.js} +33 -38
  49. data/vendor/assets/javascripts/webshims/shims/forms-picker.js +865 -0
  50. data/vendor/assets/javascripts/webshims/shims/geolocation.js +2 -2
  51. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-de.txt +37 -34
  52. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-en.txt +88 -48
  53. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-lt.js +74 -0
  54. data/vendor/assets/javascripts/webshims/shims/jpicker/ChangeLog.txt +121 -0
  55. data/vendor/assets/javascripts/webshims/shims/jpicker/ReadMe.txt +47 -0
  56. data/vendor/assets/javascripts/webshims/shims/jpicker/images/AlphaBar.png +0 -0
  57. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Bars.png +0 -0
  58. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Maps.png +0 -0
  59. data/vendor/assets/javascripts/webshims/shims/jpicker/images/NoColor.png +0 -0
  60. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Thumbs.db +0 -0
  61. data/vendor/assets/javascripts/webshims/shims/jpicker/images/bar-opacity.png +0 -0
  62. data/vendor/assets/javascripts/webshims/shims/jpicker/images/map-opacity.png +0 -0
  63. data/vendor/assets/javascripts/webshims/shims/jpicker/images/mappoint.gif +0 -0
  64. data/vendor/assets/javascripts/webshims/shims/jpicker/images/picker.gif +0 -0
  65. data/vendor/assets/javascripts/webshims/shims/jpicker/images/preview-opacity.png +0 -0
  66. data/vendor/assets/javascripts/webshims/shims/jpicker/images/rangearrows.gif +0 -0
  67. data/vendor/assets/javascripts/webshims/shims/jpicker/jpicker.css +257 -0
  68. data/vendor/assets/javascripts/webshims/shims/json-storage.js +4 -4
  69. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +44 -63
  70. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +10 -11
  71. data/vendor/assets/javascripts/webshims/shims/mediaelement-native-fix.js +2 -1
  72. data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +5 -3
  73. data/vendor/assets/javascripts/webshims/shims/range-ui.js +110 -17
  74. data/vendor/assets/javascripts/webshims/shims/styles/forms.png +0 -0
  75. data/vendor/assets/javascripts/webshims/shims/styles/range-track.png +0 -0
  76. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +104 -21
  77. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +90 -16
  78. data/vendor/assets/javascripts/webshims/shims/styles/vertical-range.png +0 -0
  79. data/vendor/assets/javascripts/webshims/shims/swf/filereader.swf +0 -0
  80. data/vendor/assets/javascripts/webshims/shims/swfmini.js +1 -1
  81. data/vendor/assets/javascripts/webshims/shims/track-ui.js +35 -3
  82. data/vendor/assets/javascripts/webshims/shims/track.js +1 -1
  83. metadata +33 -3
@@ -1,8 +1,8 @@
1
1
  //DOM-Extension helper
2
- jQuery.webshims.register('dom-extend', function($, webshims, window, document, undefined){
2
+ webshims.register('dom-extend', function($, webshims, window, document, undefined){
3
3
  "use strict";
4
4
 
5
- webshims.assumeARIA = Modernizr.localstorage || Modernizr.video || Modernizr.boxsizing;
5
+ webshims.assumeARIA = $.support.getSetAttribute || Modernizr.canvas || Modernizr.video || Modernizr.boxsizing;
6
6
 
7
7
  if($('<input type="email" />').attr('type') == 'text' || $('<form />').attr('novalidate') === "" || ('required' in $('<input />')[0].attributes)){
8
8
  webshims.error("IE browser modes are busted in IE10. Please test your HTML/CSS/JS with a real IE version or at least IETester or similiar tools");
@@ -11,6 +11,57 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
11
11
  if(!$.parseHTML){
12
12
  webshims.error("Webshims needs jQuery 1.8+ to work properly. Please update your jQuery version or downgrade webshims.");
13
13
  }
14
+ if (!webshims.cfg.no$Switch) {
15
+ var switch$ = function(){
16
+ if (window.jQuery && (!window.$ || window.jQuery == window.$) && !window.jQuery.webshims) {
17
+ webshims.error("jQuery was included more than once. Make sure to include it only once! Webshims and other Plugins might not work properly.");
18
+ if (window.$) {
19
+ window.$ = webshims.$;
20
+ }
21
+ window.jQuery = webshims.$;
22
+ }
23
+ if(webshims.M != Modernizr){
24
+ webshims.error("Modernizr was included more than once. Make sure to include it only once! Webshims and other scripts might not work properly.");
25
+ for(var i in Modernizr){
26
+ if(!(i in webshims.M)){
27
+ webshims.M[i] = Modernizr[i];
28
+ }
29
+ }
30
+ Modernizr = webshims.M;
31
+ }
32
+ };
33
+ switch$();
34
+ setTimeout(switch$, 90);
35
+ $(switch$);
36
+ }
37
+ // (function(){
38
+ // var hostNames = {
39
+ // 'afarkas.github.io': 1,
40
+ // localhost: 1,
41
+ // '127.0.0.1': 1
42
+ // };
43
+ //
44
+ // if( webshims.debug && (hostNames[location.hostname] || location.protocol == 'file:') ){
45
+ // var list = $('<ul class="webshims-debug-list" />');
46
+ // webshims.errorLog.push = function(message){
47
+ // list.appendTo('body');
48
+ // $('<li style="display: none;">'+ message +'</li>')
49
+ // .appendTo(list)
50
+ // .slideDown()
51
+ // .delay(3000)
52
+ // .slideUp(function(){
53
+ // $(this).remove();
54
+ // if(!$('li', list).length){
55
+ // list.detach();
56
+ // }
57
+ // })
58
+ // ;
59
+ // };
60
+ // $.each(webshims.errorLog, function(i, message){
61
+ // webshims.errorLog.push(message);
62
+ // });
63
+ // }
64
+ // })();
14
65
 
15
66
  //shortcus
16
67
  var modules = webshims.modules;
@@ -28,6 +79,24 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
28
79
  return (_argless) ? oldVal.call($(elem)) : oldVal.call($(elem), val);
29
80
  };
30
81
 
82
+ //jquery mobile and jquery ui
83
+ if(!$.widget){
84
+ (function(){
85
+ var _cleanData = $.cleanData;
86
+ $.cleanData = function( elems ) {
87
+ if(!$.widget){
88
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
89
+ try {
90
+ $( elem ).triggerHandler( "remove" );
91
+ // http://bugs.jquery.com/ticket/8235
92
+ } catch( e ) {}
93
+ }
94
+ }
95
+ _cleanData( elems );
96
+ };
97
+ })();
98
+ }
99
+
31
100
 
32
101
  $.fn.val = function(val){
33
102
  var elem = this[0];
@@ -61,6 +130,18 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
61
130
  return this.on(evt, fn).each(fn);
62
131
  };
63
132
 
133
+ $.fn.onWSOff = function(evt, fn, trigger, evtDel){
134
+ if(!evtDel){
135
+ evtDel = document;
136
+ }
137
+ $(evtDel)[trigger ? 'onTrigger' : 'on'](evt, fn);
138
+ this.on('remove', function(e){
139
+ if(!e.originalEvent){
140
+ $(evtDel).off(evt, fn);
141
+ }
142
+ });
143
+ };
144
+
64
145
  var dataID = '_webshimsLib'+ (Math.round(Math.random() * 1000));
65
146
  var elementData = function(elem, key, val){
66
147
  elem = elem.jquery ? elem[0] : elem;
@@ -422,7 +503,7 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
422
503
  implement: function(elem, type){
423
504
  var data = elementData(elem, 'implemented') || elementData(elem, 'implemented', {});
424
505
  if(data[type]){
425
- webshims.info(type +' already implemented for element #'+elem.id);
506
+ webshims.warn(type +' already implemented for element #'+elem.id);
426
507
  return false;
427
508
  }
428
509
  data[type] = true;
@@ -566,6 +647,12 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
566
647
  shadowFocusElementData = $.data(opts.shadowFocusElement, dataID) || $.data(opts.shadowFocusElement, dataID, shadowFocusElementData);
567
648
  }
568
649
 
650
+ $(nativeElem).on('remove', function(e){
651
+ if (!e.originalEvent) {
652
+ $(shadowElem).remove();
653
+ }
654
+ });
655
+
569
656
  nativeData.hasShadow = shadowElem;
570
657
  shadowFocusElementData.nativeElement = shadowData.nativeElement = nativeElem;
571
658
  shadowFocusElementData.shadowData = shadowData.shadowData = nativeData.shadowData = {
@@ -1085,6 +1172,7 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1085
1172
  var oVal = val;
1086
1173
  var thumbStyle = {};
1087
1174
  var rangeStyle = {};
1175
+
1088
1176
  if(!_noNormalize && parseFloat(val, 10) != val){
1089
1177
  val = o.min + ((o.max - o.min) / 2);
1090
1178
  }
@@ -1094,6 +1182,7 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1094
1182
  }
1095
1183
  left = 100 * ((val - o.min) / (o.max - o.min));
1096
1184
 
1185
+ if(this._init && val == o.value && oVal == val){return;}
1097
1186
  this.options.value = val;
1098
1187
  this.thumb.stop();
1099
1188
  this.range.stop();
@@ -1163,24 +1252,30 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1163
1252
  $('.ws-range-ticks', trail).remove();
1164
1253
 
1165
1254
 
1166
- $(this.orig).jProp('list').find('option').each(function(){
1167
- o.options[$.prop(this, 'value')] = $.prop(this, 'label');
1255
+ $(this.orig).jProp('list').find('option:not([disabled])').each(function(){
1256
+ o.options[$.prop(this, 'value')] = $.prop(this, 'label') || '';
1168
1257
  });
1169
1258
 
1170
1259
  $.each(o.options, function(val, label){
1171
1260
  if(!isNumber(val) || val < min || val > max){return;}
1172
1261
  var left = 100 * ((val - min) / (max - min));
1173
- var title = o.showLabels ? ' title="'+ label +'"' : '';
1262
+ var title = o.showLabels && label ? ' title="'+ label +'"' : '';
1174
1263
  if(that.vertical){
1175
1264
  left = Math.abs(left - 100);
1176
1265
  }
1177
- trail.append('<span class="ws-range-ticks"'+ title +' style="'+(that.dirs.left)+': '+left+'%;" />');
1266
+
1267
+ that.posCenter(
1268
+ $('<span class="ws-range-ticks"'+ title +' data-label="'+label+'" style="'+(that.dirs.left)+': '+left+'%;" />').appendTo(trail)
1269
+ );
1178
1270
  });
1179
1271
  },
1180
1272
  readonly: function(val){
1181
1273
  val = !!val;
1182
1274
  this.options.readonly = val;
1183
1275
  this.element.attr('aria-readonly', ''+val);
1276
+ if(this._init){
1277
+ this.updateMetrics();
1278
+ }
1184
1279
  },
1185
1280
  disabled: function(val){
1186
1281
  val = !!val;
@@ -1190,6 +1285,9 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1190
1285
  } else {
1191
1286
  this.element.attr({tabindex: this.options.tabindex, 'aria-disabled': 'false'});
1192
1287
  }
1288
+ if(this._init){
1289
+ this.updateMetrics();
1290
+ }
1193
1291
  },
1194
1292
  tabindex: function(val){
1195
1293
  this.options.tabindex = val;
@@ -1269,6 +1367,24 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1269
1367
 
1270
1368
  return val;
1271
1369
  },
1370
+ addRemoveClass: function(cName, add){
1371
+ var isIn = this.element.prop('className').indexOf(cName) != -1;
1372
+ var action;
1373
+ if(!add && isIn){
1374
+ action = 'removeClass';
1375
+ this.element.removeClass(cName);
1376
+ this.updateMetrics();
1377
+ } else if(add && !isIn){
1378
+ action = 'addClass';
1379
+
1380
+ }
1381
+ if(action){
1382
+ this.element[action](cName);
1383
+ if(this._init){
1384
+ this.updateMetrics();
1385
+ }
1386
+ }
1387
+ },
1272
1388
  addBindings: function(){
1273
1389
  var leftOffset, widgetUnits, hasFocus;
1274
1390
  var that = this;
@@ -1308,25 +1424,36 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1308
1424
  that.value(val, false, animate);
1309
1425
  eventTimer.call('input', val);
1310
1426
  }
1427
+ if(e && e.type == 'mousemove'){
1428
+ e.preventDefault();
1429
+ }
1311
1430
  };
1312
-
1313
1431
  var remove = function(e){
1314
1432
  if(e && e.type == 'mouseup'){
1315
1433
  eventTimer.call('input', o.value);
1316
1434
  eventTimer.call('change', o.value);
1317
1435
  }
1318
- that.element.removeClass('ws-active');
1436
+ that.addRemoveClass('ws-active');
1319
1437
  $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1438
+ $(window).off('blur', removeWin);
1439
+ };
1440
+ var removeWin = function(e){
1441
+ if(e.target == window){remove();}
1320
1442
  };
1321
1443
  var add = function(e){
1444
+ var outerWidth;
1322
1445
  e.preventDefault();
1323
1446
  $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1447
+ $(window).off('blur', removeWin);
1324
1448
  if(!o.readonly && !o.disabled){
1325
- leftOffset = that.element.focus().addClass('ws-active').offset();
1326
- widgetUnits = that.element[that.dirs.width]();
1449
+ that.element.focus();
1450
+ that.addRemoveClass('ws-active', true);
1451
+ leftOffset = that.element.focus().offset();
1452
+ widgetUnits = that.element[that.dirs.innerWidth]();
1327
1453
  if(!widgetUnits || !leftOffset){return;}
1454
+ outerWidth = that.thumb[that.dirs.outerWidth]();
1328
1455
  leftOffset = leftOffset[that.dirs.pos];
1329
- widgetUnits = 100 / (widgetUnits - ((that.thumb[that.dirs.outerWidth]() || 2) / 2));
1456
+ widgetUnits = 100 / widgetUnits;
1330
1457
  setValueFromPos(e, o.animate);
1331
1458
  $(document)
1332
1459
  .on({
@@ -1334,6 +1461,7 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1334
1461
  mousemove: setValueFromPos
1335
1462
  })
1336
1463
  ;
1464
+ $(window).on('blur', removeWin);
1337
1465
  e.stopPropagation();
1338
1466
  }
1339
1467
  };
@@ -1343,18 +1471,20 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1343
1471
  if(!o.disabled){
1344
1472
  eventTimer.init('input', o.value);
1345
1473
  eventTimer.init('change', o.value);
1346
- that.element.addClass('ws-focus');
1474
+ that.addRemoveClass('ws-focus', true);
1475
+ that.updateMetrics();
1347
1476
  }
1348
1477
  hasFocus = true;
1349
1478
  },
1350
1479
  blur: function(e){
1351
1480
  that.element.removeClass('ws-focus ws-active');
1481
+ that.updateMetrics();
1352
1482
  hasFocus = false;
1353
1483
  eventTimer.init('input', o.value);
1354
1484
  eventTimer.call('change', o.value);
1355
1485
  },
1356
1486
  keyup: function(){
1357
- that.element.removeClass('ws-active');
1487
+ that.addRemoveClass('ws-active');
1358
1488
  eventTimer.call('input', o.value);
1359
1489
  eventTimer.call('change', o.value);
1360
1490
  },
@@ -1379,7 +1509,7 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1379
1509
  step = false;
1380
1510
  }
1381
1511
  if (step) {
1382
- that.element.addClass('ws-active');
1512
+ that.addRemoveClass('ws-active', true);
1383
1513
  eventTimer.call('input', o.value);
1384
1514
  e.preventDefault();
1385
1515
  }
@@ -1401,38 +1531,88 @@ jQuery.webshims.register('dom-extend', function($, webshims, window, document, u
1401
1531
  this.thumb.on({
1402
1532
  mousedown: add
1403
1533
  });
1534
+ $(function(){
1535
+ webshims.ready('dom-support', function(){
1536
+ that.element.onWSOff('updateshadowdom', function(){
1537
+ that.updateMetrics();
1538
+ });
1539
+ });
1540
+ if(!$.fn.onWSOff){
1541
+ webshims._polyfill(['dom-support']);
1542
+ }
1543
+ });
1544
+ },
1545
+ posCenter: function(elem, outerWidth){
1546
+ var temp;
1547
+ if(this.options.calcCenter && (!this._init || this.element[0].offsetWidth)){
1548
+ if(!elem){
1549
+ elem = this.thumb;
1550
+ }
1551
+ if(!outerWidth){
1552
+ outerWidth = elem[this.dirs.outerWidth]();
1553
+ }
1554
+ outerWidth = outerWidth / -2;
1555
+ elem.css(this.dirs.marginLeft, outerWidth);
1556
+
1557
+ if(this.options.calcTrail && elem[0] == this.thumb[0]){
1558
+ temp = this.element[this.dirs.innerHeight]();
1559
+ elem.css(this.dirs.marginTop, (elem[this.dirs.outerHeight]() - temp) / -2);
1560
+ this.range.css(this.dirs.marginTop, (this.range[this.dirs.outerHeight]() - temp) / -2 );
1561
+ outerWidth *= -1;
1562
+ this.trail
1563
+ .css(this.dirs.left, outerWidth)
1564
+ .css(this.dirs.right, outerWidth)
1565
+ ;
1566
+ }
1567
+ }
1404
1568
  },
1405
1569
  updateMetrics: function(){
1406
1570
  var width = this.element.innerWidth();
1407
1571
  this.vertical = (width && this.element.innerHeight() - width > 10);
1408
1572
 
1409
1573
  this.dirs = this.vertical ?
1410
- {mouse: 'pageY', pos: 'top', min: 'max', max: 'min', left: 'top', width: 'height', outerWidth: 'outerHeight'} :
1411
- {mouse: 'pageX', pos: 'left', min: 'min', max: 'max', left: 'left', width: 'width', outerWidth: 'outerWidth'}
1574
+ {mouse: 'pageY', pos: 'top', min: 'max', max: 'min', left: 'top', right: 'bottom', width: 'height', innerWidth: 'innerHeight', innerHeight: 'innerWidth', outerWidth: 'outerHeight', outerHeight: 'outerWidth', marginTop: 'marginLeft', marginLeft: 'marginTop'} :
1575
+ {mouse: 'pageX', pos: 'left', min: 'min', max: 'max', left: 'left', right: 'right', width: 'width', innerWidth: 'innerWidth', innerHeight: 'innerHeight', outerWidth: 'outerWidth', outerHeight: 'outerHeight', marginTop: 'marginTop', marginLeft: 'marginLeft'}
1412
1576
  ;
1413
1577
  this.element
1414
1578
  [this.vertical ? 'addClass' : 'removeClass']('vertical-range')
1415
1579
  [this.vertical ? 'addClass' : 'removeClass']('horizontal-range')
1416
1580
  ;
1581
+ this.posCenter();
1417
1582
  }
1418
1583
  };
1419
1584
 
1420
1585
  $.fn.rangeUI = function(opts){
1421
- opts = $.extend({readonly: false, disabled: false, tabindex: 0, min: 0, step: 1, max: 100, value: 50, input: $.noop, change: $.noop, _change: $.noop, showLabels: true, options: {}}, opts);
1586
+ opts = $.extend({
1587
+ readonly: false,
1588
+ disabled: false,
1589
+ tabindex: 0,
1590
+ min: 0,
1591
+ step: 1,
1592
+ max: 100,
1593
+ value: 50,
1594
+ input: $.noop,
1595
+ change: $.noop,
1596
+ _change: $.noop,
1597
+ showLabels: true,
1598
+ options: {},
1599
+ calcCenter: true,
1600
+ calcTrail: true
1601
+ }, opts);
1422
1602
  return this.each(function(){
1423
- $.webshims.objectCreate(rangeProto, {
1603
+ webshims.objectCreate(rangeProto, {
1424
1604
  element: {
1425
1605
  value: $(this)
1426
1606
  }
1427
1607
  }, opts);
1428
1608
  });
1429
1609
  };
1430
- jQuery.webshims.isReady('range-ui', true);
1610
+ webshims.isReady('range-ui', true);
1431
1611
  })(jQuery);
1432
- jQuery.webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1612
+ webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1433
1613
  "use strict";
1434
1614
  var curCfg;
1435
- var formcfg = $.webshims.formcfg;
1615
+ var formcfg = webshims.formcfg;
1436
1616
 
1437
1617
  var stopPropagation = function(e){
1438
1618
  e.stopImmediatePropagation(e);
@@ -1450,7 +1630,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1450
1630
  date: {
1451
1631
  _create: function(){
1452
1632
  var obj = {
1453
- 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]]
1633
+ 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]]
1454
1634
  };
1455
1635
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1], $('<span class="ws-input-seperator" />')[0], obj.splits[2]];
1456
1636
  return obj;
@@ -1476,7 +1656,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1476
1656
  month: {
1477
1657
  _create: function(){
1478
1658
  var obj = {
1479
- splits: [$('<input type="text" class="yy" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
1659
+ splits: [$('<input type="text" class="yy" inputmode="numeric" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
1480
1660
  };
1481
1661
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1]];
1482
1662
  return obj;
@@ -1496,6 +1676,23 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1496
1676
  }
1497
1677
  }
1498
1678
  };
1679
+
1680
+ var steps = {
1681
+ number: {
1682
+ step: 1
1683
+ },
1684
+ time: {
1685
+ step: 60
1686
+ },
1687
+ month: {
1688
+ step: 1,
1689
+ start: new Date()
1690
+ },
1691
+ date: {
1692
+ step: 1,
1693
+ start: new Date()
1694
+ }
1695
+ };
1499
1696
  var labelWidth = (function(){
1500
1697
  var getId = function(){
1501
1698
  return webshims.getID(this);
@@ -1520,7 +1717,8 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1520
1717
 
1521
1718
  (function(){
1522
1719
  var monthDigits = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
1523
- formcfg.de = {
1720
+
1721
+ formcfg.de = $.extend(true, {
1524
1722
  numberFormat: {
1525
1723
  ",": ".",
1526
1724
  ".": ","
@@ -1554,9 +1752,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1554
1752
  showMonthAfterYear: false,
1555
1753
  yearSuffix: ''
1556
1754
  }
1557
- };
1755
+ }, formcfg.de || {});
1558
1756
 
1559
- formcfg.en = {
1757
+ formcfg.en = $.extend(true, {
1560
1758
  numberFormat: {
1561
1759
  ".": ".",
1562
1760
  ",": ","
@@ -1588,13 +1786,17 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1588
1786
  "showMonthAfterYear": false,
1589
1787
  "yearSuffix": ""
1590
1788
  }
1591
- };
1789
+ }, formcfg['en'] || {});
1790
+ if(!formcfg['en-US']){
1791
+ formcfg['en-US'] = formcfg['en'];
1792
+ }
1793
+ if(!formcfg['']){
1794
+ formcfg[''] = formcfg['en-US'];
1795
+ }
1592
1796
 
1593
- formcfg['en-US'] = formcfg['en-US'] || formcfg['en'];
1594
- formcfg[''] = formcfg[''] || formcfg['en-US'];
1595
1797
  curCfg = formcfg[''];
1596
1798
 
1597
- var createMonthKeys = function(langCfg){
1799
+ var processLangCFG = function(langCfg){
1598
1800
  if(!langCfg.date.monthkeys){
1599
1801
  var create = function(i, name){
1600
1802
  var strNum;
@@ -1610,24 +1812,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1610
1812
  $.each(langCfg.date.monthNames, create);
1611
1813
  $.each(langCfg.date.monthNamesShort, create);
1612
1814
  }
1815
+ if(!langCfg.colorSigns){
1816
+ langCfg.colorSigns = '#abcdefABCDEF';
1817
+ }
1613
1818
  };
1614
1819
 
1615
- createMonthKeys(curCfg);
1820
+ processLangCFG(curCfg);
1616
1821
 
1617
- $.webshims.ready('dom-extend', function(){
1618
- $.webshims.activeLang({
1619
- register: 'form-core',
1620
- callback: function(){
1621
- $.each(arguments, function(i, val){
1622
- if(formcfg[val]){
1623
- curCfg = formcfg[val];
1624
- createMonthKeys(curCfg);
1625
- $(document).triggerHandler('wslocalechange');
1626
- return false;
1627
- }
1628
- });
1629
- }
1630
- });
1822
+ $.webshims.activeLang({
1823
+ register: 'form-core',
1824
+ callback: function(){
1825
+ $.each(arguments, function(i, val){
1826
+ if(formcfg[val]){
1827
+ curCfg = formcfg[val];
1828
+ processLangCFG(curCfg);
1829
+ $(document).triggerHandler('wslocalechange');
1830
+ return false;
1831
+ }
1832
+ });
1833
+ }
1631
1834
  });
1632
1835
  })();
1633
1836
 
@@ -1647,8 +1850,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1647
1850
  return val * 1;
1648
1851
  };
1649
1852
 
1650
- var createOpts = ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value'];
1651
-
1652
1853
 
1653
1854
  var formatVal = {
1654
1855
  number: function(val){
@@ -1687,6 +1888,16 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1687
1888
  }
1688
1889
 
1689
1890
  return val;
1891
+ },
1892
+ color: function(val, opts){
1893
+ var ret = '#000000';
1894
+ if(val){
1895
+ val = val.toLowerCase();
1896
+ if(val.length == 7 && createHelper('color').isValid(val)) {
1897
+ ret = val;
1898
+ }
1899
+ }
1900
+ return ret;
1690
1901
  }
1691
1902
  };
1692
1903
 
@@ -1701,7 +1912,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1701
1912
 
1702
1913
  var p = (!opts.splitInput) ? val.trim().split(/[\.\s-\/\\]+/) : val;
1703
1914
 
1704
- if(p.length == 2){
1915
+ if(p.length == 2 && p[0] && p[1]){
1705
1916
  p[0] = curCfg.date.monthkeys[p[0]] || p[0];
1706
1917
  p[1] = curCfg.date.monthkeys[p[1]] || p[1];
1707
1918
  if(p[1].length == 2){
@@ -1731,27 +1942,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1731
1942
  ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-') :
1732
1943
  ''
1733
1944
  ;
1734
- }
1735
- };
1736
-
1737
- var steps = {
1738
- number: {
1739
- step: 1
1740
- },
1741
- time: {
1742
- step: 60
1743
1945
  },
1744
- month: {
1745
- step: 1,
1746
- start: new Date()
1747
- },
1748
- date: {
1749
- step: 1,
1750
- start: new Date()
1946
+ color: function(val, opts){
1947
+ var ret = '#000000';
1948
+ if(val){
1949
+ val = val.toLowerCase();
1950
+ if (val.indexOf('#') !== 0) {
1951
+ val = '#' + val;
1952
+ }
1953
+ if(val.length == 4){
1954
+ val = '#' + val.charAt(1) + val.charAt(1) + val.charAt(2) + val.charAt(2) + val.charAt(3) + val.charAt(3);
1955
+ }
1956
+ if(val.length == 7 && createHelper('color').isValid(val)) {
1957
+ ret = val;
1958
+ }
1959
+ }
1960
+ return ret;
1751
1961
  }
1752
1962
  };
1753
1963
 
1754
-
1755
1964
  var placeholderFormat = {
1756
1965
  date: function(val, opts){
1757
1966
  var hintValue = (val || '').split('-');
@@ -1796,6 +2005,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1796
2005
  asValue: function(val){
1797
2006
  var type = (typeof val == 'object') ? 'valueAsDate' : 'valueAsNumber';
1798
2007
  return input.prop(type, val).prop('value');
2008
+ },
2009
+ isValid: function(val){
2010
+ return input.prop('value', val).is(':valid') && input.prop('value') == val;
1799
2011
  }
1800
2012
  };
1801
2013
  }
@@ -1805,211 +2017,80 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1805
2017
 
1806
2018
  steps.range = steps.number;
1807
2019
 
1808
-
1809
- var spinBtnProto = {
2020
+ var wsWidgetProto = {
1810
2021
  _create: function(){
1811
- var i;
2022
+ var i, that, timedMirror;
1812
2023
  var o = this.options;
1813
- var helper = createHelper(o.type);
2024
+ var createOpts = this.createOpts;
2025
+
1814
2026
  this.type = o.type;
1815
2027
  this.orig = o.orig;
1816
2028
 
1817
- this.elemHelper = $('<input type="'+ this.type+'" />');
1818
- this.asNumber = helper.asNumber;
1819
- this.asValue = helper.asValue;
2029
+ this.buttonWrapper = $('<span class="input-buttons '+this.type+'-input-buttons"></span>').insertAfter(this.element);
2030
+ this.options.containerElements.push(this.buttonWrapper[0]);
1820
2031
 
1821
- 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>')
1822
- .insertAfter(this.element)
1823
- ;
2032
+ o.mirrorValidity = o.mirrorValidity && this.orig && Modernizr.formvalidation && !webshims.bugs.bustedValidity;
1824
2033
 
1825
- if(o.splitInput){
2034
+ if(o.splitInput && this._addSplitInputs){
1826
2035
  this._addSplitInputs();
1827
2036
  } else {
1828
2037
  this.inputElements = this.element;
1829
2038
  }
1830
2039
 
1831
- this.options.containerElements.push(this.buttonWrapper[0]);
1832
-
1833
- if(typeof steps[this.type].start == 'object'){
2040
+ if( steps[this.type] && typeof steps[this.type].start == 'object'){
1834
2041
  steps[this.type].start = this.asNumber(steps[this.type].start);
1835
2042
  }
1836
2043
 
1837
-
1838
-
1839
2044
  for(i = 0; i < createOpts.length; i++){
1840
- this[createOpts[i]](o[createOpts[i]]);
1841
- }
1842
-
1843
- this.element.data('wsspinner', this);
1844
-
1845
- this.addBindings();
1846
-
1847
- if(!o.min && typeof o.relMin == 'number'){
1848
- o.min = this.asValue(this.getRelNumber(o.relMin));
1849
- $.prop(this.orig, 'min', o.min);
2045
+ if(o[createOpts[i]] != null){
2046
+ this[createOpts[i]](o[createOpts[i]], o[createOpts[i]]);
2047
+ }
1850
2048
  }
1851
-
1852
- if(!o.max && typeof o.relMax == 'number'){
1853
- o.max = this.asValue(this.getRelNumber(o.relMax));
1854
- $.prop(this.orig, 'max', o.max);
2049
+ if(this.type == 'color'){
2050
+ this.inputElements.prop('maxLength', 7);
1855
2051
  }
2052
+ this.addBindings();
2053
+ $(this.element).data('wsWidget'+o.type, this);
1856
2054
 
1857
2055
  this._init = true;
1858
- },
1859
- _addSplitInputs: function(){
1860
- if(!this.inputElements){
1861
- var create = splitInputs[this.type]._create();
1862
- this.splits = create.splits;
1863
- this.inputElements = $(create.elements).prependTo(this.element).filter('input');
1864
- }
1865
- },
1866
- parseValue: function(){
1867
- var value = this.inputElements.map(function(){
1868
- return $.prop(this, 'value');
1869
- }).get();
1870
- if(!this.options.splitInput){
1871
- value = value[0];
1872
- }
1873
- return parseVal[this.type](value, this.options);
1874
- },
1875
- formatValue: function(val, noSplit){
1876
- return formatVal[this.type](val, noSplit === false ? false : this.options);
1877
- },
1878
- placeholder: function(val){
1879
- var options = this.options;
1880
- options.placeholder = val;
1881
- var placeholder = val;
1882
- if(placeholderFormat[this.type]){
1883
- placeholder = placeholderFormat[this.type](val, this.options);
1884
- }
1885
- if(options.splitInput && typeof placeholder == 'object'){
1886
- $.each(this.splits, function(i, elem){
1887
- $.prop(elem, 'placeholder', placeholder[i]);
1888
- });
1889
- } else {
1890
- this.element.prop('placeholder', placeholder);
1891
- }
1892
- },
1893
- getRelNumber: function(rel){
1894
- var start = steps[this.type].start || 0;
1895
- if(rel){
1896
- start += rel;
1897
- }
1898
- return start;
1899
- },
1900
- addZero: addZero,
1901
- _setStartInRange: function(){
1902
- var start = this.getRelNumber(this.options.relDefaultValue);
1903
- if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
1904
- start = this.minAsNumber;
1905
- } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
1906
- start = this.maxAsNumber;
1907
- }
1908
- this.elemHelper.prop('valueAsNumber', start);
1909
- this.options.defValue = this.elemHelper.prop('value');
1910
-
1911
- },
1912
- reorderInputs: function(){
1913
- if(splitInputs[this.type]){
1914
- var element = this.element;
1915
- splitInputs[this.type].sort(element);
1916
- setTimeout(function(){
1917
- var data = webshims.data(element);
1918
- if(data && data.shadowData){
1919
- data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
1920
- }
1921
- }, 9);
1922
- }
1923
- },
1924
- value: function(val){
1925
- this.valueAsNumber = this.asNumber(val);
1926
- this.options.value = val;
1927
- if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
1928
- this._setStartInRange();
1929
- } else {
1930
- this.elemHelper.prop('value', val);
1931
- this.options.defValue = "";
1932
- }
1933
2056
 
1934
- val = formatVal[this.type](val, this.options);
1935
- if(this.options.splitInput){
2057
+ if(o.mirrorValidity){
2058
+ that = this;
2059
+ timedMirror = function(){
2060
+ clearTimeout(timedMirror._timerDealy);
2061
+ timedMirror._timerDealy = setTimeout(timedMirror._wsexec, 9);
2062
+ };
2063
+ timedMirror._wsexec = function(){
2064
+ clearTimeout(timedMirror._timerDealy);
2065
+ that.mirrorValidity(true);
2066
+ };
1936
2067
 
1937
- $.each(this.splits, function(i, elem){
1938
- $.prop(elem, 'value', val[i]);
1939
- });
1940
- } else {
1941
- this.element.prop('value', val);
1942
- }
1943
-
1944
- this._propertyChange('value');
1945
- },
1946
- initDataList: function(){
1947
- var listTimer;
1948
- var that = this;
1949
- var updateList = function(){
1950
- $(that.orig)
1951
- .jProp('list')
1952
- .off('updateDatalist', updateList)
1953
- .on('updateDatalist', updateList)
1954
- ;
1955
- clearTimeout(listTimer);
1956
- listTimer = setTimeout(function(){
1957
- if(that.list){
1958
- that.list();
2068
+ timedMirror();
2069
+ $(this.orig).on('change input', function(e){
2070
+ if(e.type == 'input'){
2071
+ timedMirror();
2072
+ } else {
2073
+ timedMirror._wsexec();
1959
2074
  }
1960
- }, 9);
1961
-
1962
- };
1963
-
1964
- $(this.orig).onTrigger('listdatalistchange', updateList);
1965
- },
1966
- getOptions: function(){
1967
- var options = {};
1968
- var datalist = $(this.orig).jProp('list');
1969
- datalist.find('option').each(function(){
1970
- options[$.prop(this, 'value')] = $.prop(this, 'label');
1971
- });
1972
- return [options, datalist.data('label')];
1973
- },
1974
- list: function(val){
1975
- if(this.type == 'number' || this.type == 'time'){
1976
- this.element.attr('list', $.attr(this.orig, 'list'));
1977
- }
1978
- this.options.list = val;
1979
- this._propertyChange('list');
1980
- },
1981
- _propertyChange: $.noop,
1982
- tabindex: function(val){
1983
- this.options.tabindex = val;
1984
- this.inputElements.prop('tabindex', this.options.tabindex);
1985
- },
1986
- title: function(val){
1987
- this.options.title = val;
1988
- this.element.prop('title', this.options.title);
1989
- },
1990
-
1991
- min: function(val){
1992
- this.elemHelper.prop('min', val);
1993
- this.minAsNumber = this.asNumber(val);
1994
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
1995
- this._setStartInRange();
2075
+ });
1996
2076
  }
1997
- this.options.min = val;
1998
- this._propertyChange('min');
1999
2077
  },
2000
- max: function(val){
2001
- this.elemHelper.prop('max', val);
2002
- this.maxAsNumber = this.asNumber(val);
2003
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
2004
- this._setStartInRange();
2078
+ mirrorValidity: function(_noTest){
2079
+ //
2080
+ if(this._init && this.options.mirrorValidity){
2081
+ if(!_noTest){
2082
+ $.prop(this.orig, 'validity');
2083
+ }
2084
+ var message = $(this.orig).getErrorMessage();
2085
+ if(message !== this.lastErrorMessage){
2086
+ this.inputElements.prop('setCustomValidity', function(i, val){
2087
+ if(val._supvalue){
2088
+ val._supvalue.call(this, message);
2089
+ }
2090
+ });
2091
+ this.lastErrorMessage = message;
2092
+ }
2005
2093
  }
2006
- this.options.max = val;
2007
- this._propertyChange('max');
2008
- },
2009
- step: function(val){
2010
- var defStep = steps[this.type];
2011
- this.options.step = val;
2012
- this.elemHelper.prop('step', retDefault(val, defStep.step));
2013
2094
  },
2014
2095
  addBindings: function(){
2015
2096
  var isFocused;
@@ -2062,6 +2143,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2062
2143
  var val;
2063
2144
  clearTimeout(timer);
2064
2145
  val = that.parseValue();
2146
+ if(that.type == 'color'){
2147
+ that.inputElements.val(val);
2148
+ }
2065
2149
  $.prop(that.orig, 'value', val);
2066
2150
  eventTimer.call('input', val);
2067
2151
  if(!e || e.type != 'wsupdatevalue'){
@@ -2098,6 +2182,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2098
2182
  ;
2099
2183
  setTimeout(function(){
2100
2184
  if(that.popover){
2185
+ that.popover.element.on('wspopoverhide', onBlur);
2101
2186
  $('> *', that.popover.element)
2102
2187
  .on({
2103
2188
  'focusin': onFocus,
@@ -2178,7 +2263,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2178
2263
  e.preventDefault();
2179
2264
  }
2180
2265
  }
2181
- }
2266
+ };
2182
2267
  })()
2183
2268
  };
2184
2269
  var mouseDownInit = function(){
@@ -2202,28 +2287,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2202
2287
  };
2203
2288
  })();
2204
2289
 
2205
- ['stepUp', 'stepDown'].forEach(function(name){
2206
- step[name] = function(factor){
2207
- if(!o.disabled && !o.readonly){
2208
- if(!isFocused){
2209
- mouseDownInit();
2210
- }
2211
- var ret = false;
2212
- if (!factor) {
2213
- factor = 1;
2214
- }
2215
- try {
2216
- that.elemHelper[name](factor);
2217
- ret = that.elemHelper.prop('value');
2218
- that.value(ret);
2219
- eventTimer.call('input', ret);
2220
- } catch (er) {}
2221
- return ret;
2222
- }
2223
- };
2224
- });
2225
-
2226
-
2227
2290
 
2228
2291
  this.buttonWrapper.on('mousedown', mouseDownInit);
2229
2292
 
@@ -2240,960 +2303,415 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2240
2303
 
2241
2304
  this.inputElements.on(elementEvts);
2242
2305
 
2243
- if(!o.noSpinbtn){
2244
- spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
2245
- if(delta && isFocused && !o.disabled){
2246
- step[delta > 0 ? 'stepUp' : 'stepDown']();
2247
- e.preventDefault();
2248
- }
2249
- };
2250
- spinEvents.keydown = function(e){
2251
- if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
2252
- var stepped = true;
2253
- var code = e.keyCode;
2254
- if (code == 38) {
2255
- step.stepUp();
2256
- } else if (code == 40) {
2257
- step.stepDown();
2258
- } else {
2259
- stepped = false;
2260
- }
2261
- if(stepped){
2262
- e.preventDefault();
2263
- }
2264
- };
2265
-
2266
- spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
2267
- }
2268
-
2269
-
2270
- if(!o.splitInput){
2271
- $(document).on('wslocalechange',function(){
2272
- if(o.value){
2273
- that.value(o.value);
2274
- }
2275
-
2276
- if(placeholderFormat[that.type] && o.placeholder){
2277
- that.placeholder(o.placeholder);
2278
- }
2279
- });
2280
- } else {
2281
- $(document).onTrigger('wslocalechange',function(){
2282
- that.reorderInputs();
2306
+ if(steps[this.type]){
2307
+ ['stepUp', 'stepDown'].forEach(function(name){
2308
+ step[name] = function(factor){
2309
+ if(!o.disabled && !o.readonly){
2310
+ if(!isFocused){
2311
+ mouseDownInit();
2312
+ }
2313
+ var ret = false;
2314
+ if (!factor) {
2315
+ factor = 1;
2316
+ }
2317
+ try {
2318
+ that.elemHelper[name](factor);
2319
+ ret = that.elemHelper.prop('value');
2320
+ that.value(ret);
2321
+ eventTimer.call('input', ret);
2322
+ } catch (er) {}
2323
+ return ret;
2324
+ }
2325
+ };
2283
2326
  });
2284
- }
2285
-
2286
- $('.step-up', this.buttonWrapper)
2287
- .on({
2288
- 'mousepressstart mousepressend': mousePress,
2289
- 'mousedown mousepress': function(e){
2290
- step.stepUp();
2291
- }
2292
- })
2293
- ;
2294
- $('.step-down', this.buttonWrapper)
2295
- .on({
2296
- 'mousepressstart mousepressend': mousePress,
2297
- 'mousedown mousepress': function(e){
2298
- step.stepDown();
2299
- }
2300
- })
2301
- ;
2302
- initChangeEvents();
2303
- }
2304
- };
2305
-
2306
- ['readonly', 'disabled'].forEach(function(name){
2307
- spinBtnProto[name] = function(val){
2308
- if(this.options[name] != val || !this._init){
2309
- this.options[name] = !!val;
2310
- if(name == 'readonly' && this.options.noInput){
2311
- this.element
2312
- .prop(name, true)
2313
- .attr({'aria-readonly': this.options[name]})
2314
- ;
2315
- } else {
2316
- this.element.prop(name, this.options[name]);
2327
+ if(!o.noSpinbtn){
2328
+ spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
2329
+ if(delta && isFocused && !o.disabled){
2330
+ step[delta > 0 ? 'stepUp' : 'stepDown']();
2331
+ e.preventDefault();
2332
+ }
2333
+ };
2334
+ spinEvents.keydown = function(e){
2335
+ if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
2336
+ var stepped = true;
2337
+ var code = e.keyCode;
2338
+ if (code == 38) {
2339
+ step.stepUp();
2340
+ } else if (code == 40) {
2341
+ step.stepDown();
2342
+ } else {
2343
+ stepped = false;
2344
+ }
2345
+ if(stepped){
2346
+ e.preventDefault();
2347
+ }
2348
+ };
2349
+
2350
+ spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
2317
2351
  }
2318
- this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
2352
+ $(this.buttonWrapper)
2353
+ .on('mousepressstart mousepressend', '.step-up, .step-down', mousePress)
2354
+ .on('mousedown mousepress', '.step-up', function(e){
2355
+ step.stepUp();
2356
+ })
2357
+ .on('mousedown mousepress', '.step-down', function(e){
2358
+ step.stepDown();
2359
+ })
2360
+ ;
2319
2361
  }
2320
- };
2321
- });
2322
-
2323
-
2324
- $.fn.spinbtnUI = function(opts){
2325
- opts = $.extend({
2326
- monthNames: 'monthNames',
2327
- size: 1,
2328
- startView: 0
2329
- }, opts);
2330
- return this.each(function(){
2331
- $.webshims.objectCreate(spinBtnProto, {
2332
- element: {
2333
- value: $(this)
2334
- }
2335
- }, opts);
2336
- });
2337
- };
2338
- })();
2339
-
2340
- (function(){
2341
- var picker = {};
2342
- var disable = {
2343
-
2344
- };
2345
-
2346
- var getDateArray = function(date){
2347
- var ret = [date.getFullYear(), addZero(date.getMonth() + 1), addZero(date.getDate())];
2348
- ret.month = ret[0]+'-'+ret[1];
2349
- ret.date = ret[0]+'-'+ret[1]+'-'+ret[2];
2350
- return ret;
2351
- };
2352
- var today = getDateArray(new Date());
2362
+ if(this.type != 'color'){
2363
+ (function(){
2364
+ var localeChange ;
2365
+ if(!o.splitInput){
2366
+ localeChange = function(){
2367
+ if(o.value){
2368
+ that.value(o.value);
2369
+ }
2353
2370
 
2354
- var _setFocus = function(element, _noFocus){
2355
- var setFocus, that;
2356
- element = $(element || this.activeButton);
2357
- this.activeButton.attr({tabindex: '-1', 'aria-selected': 'false'});
2358
- this.activeButton = element.attr({tabindex: '0', 'aria-selected': 'true'});
2359
- this.index = this.buttons.index(this.activeButton[0]);
2360
-
2361
- clearTimeout(this.timer);
2362
-
2363
- if(!this.popover.openedByFocus && !_noFocus){
2364
- that = this;
2365
- setFocus = function(noTrigger){
2366
- clearTimeout(that.timer);
2367
- that.timer = setTimeout(function(){
2368
- if(element[0]){
2369
- element[0].focus();
2370
- if(noTrigger !== true && !element.is(':focus')){
2371
- setFocus(true);
2372
- }
2371
+ if(placeholderFormat[that.type] && o.placeholder){
2372
+ that.placeholder(o.placeholder);
2373
+ }
2374
+ };
2375
+ } else {
2376
+ localeChange = function(){
2377
+ that.reorderInputs();
2378
+ };
2379
+ that.reorderInputs();
2373
2380
  }
2374
- }, that.popover.isVisible ? 99 : 360);
2375
- };
2376
- this.popover.activateElement(element);
2377
- setFocus();
2378
- }
2379
-
2380
- };
2381
-
2382
- var _initialFocus = function(){
2383
- var sel;
2384
- if(this.popover.navedInitFocus){
2385
- sel = this.popover.navedInitFocus.sel || this.popover.navedInitFocus;
2386
- if((!this.activeButton || !this.activeButton[0]) && this.buttons[sel]){
2387
- this.activeButton = this.buttons[sel]();
2388
- } else if(sel){
2389
- this.activeButton = $(sel, this.element);
2381
+ $(that.orig).onWSOff('wslocalechange', localeChange);
2382
+ })();
2390
2383
  }
2391
2384
 
2392
- if(!this.activeButton[0] && this.popover.navedInitFocus.alt){
2393
- this.activeButton = this.buttons[this.popover.navedInitFocus.alt]();
2385
+ initChangeEvents();
2386
+ },
2387
+ value: function(val){
2388
+ if(!this._init || val !== this.options.value){
2389
+ this.element.val(this.formatValue(val));
2390
+ this.options.value = val;
2391
+ this._propertyChange('value');
2392
+ this.mirrorValidity();
2394
2393
  }
2395
- }
2396
-
2397
- if(!this.activeButton || !this.activeButton[0]){
2398
- this.activeButton = this.buttons.filter('.checked-value');
2399
- }
2400
-
2401
- if(!this.activeButton[0]){
2402
- this.activeButton = this.buttons.filter('.this-value');
2403
- }
2404
- if(!this.activeButton[0]){
2405
- this.activeButton = this.buttons.eq(0);
2406
- }
2407
-
2408
- this.setFocus(this.activeButton, this.opts.noFocus);
2409
- };
2410
-
2411
-
2412
- webshims.ListBox = function (element, popover, opts){
2413
- this.element = $('ul', element);
2414
- this.popover = popover;
2415
- this.opts = opts || {};
2416
- this.buttons = $('button:not(:disabled)', this.element);
2417
-
2418
-
2419
- this.ons(this);
2420
- this._initialFocus();
2421
- };
2422
-
2423
- webshims.ListBox.prototype = {
2424
- setFocus: _setFocus,
2425
- _initialFocus: _initialFocus,
2426
- prev: function(){
2427
- var index = this.index - 1;
2428
- if(index < 0){
2429
- if(this.opts.prev){
2430
- this.popover.navedInitFocus = 'last';
2431
- this.popover.actionFn(this.opts.prev);
2432
- this.popover.navedInitFocus = false;
2433
- }
2434
- } else {
2435
- this.setFocus(this.buttons.eq(index));
2394
+
2395
+ },
2396
+ required: function(val, boolVal){
2397
+ this.inputElements.attr({'aria-required': ''+boolVal});
2398
+ this.mirrorValidity();
2399
+ },
2400
+ parseValue: function(){
2401
+ var value = this.inputElements.map(function(){
2402
+ return $.prop(this, 'value');
2403
+ }).get();
2404
+ if(!this.options.splitInput){
2405
+ value = value[0];
2436
2406
  }
2407
+ return parseVal[this.type](value, this.options);
2437
2408
  },
2438
- next: function(){
2439
- var index = this.index + 1;
2440
- if(index >= this.buttons.length){
2441
- if(this.opts.next){
2442
- this.popover.navedInitFocus = 'first';
2443
- this.popover.actionFn(this.opts.next);
2444
- this.popover.navedInitFocus = false;
2445
- }
2409
+ formatValue: function(val, noSplit){
2410
+ return formatVal[this.type](val, noSplit === false ? false : this.options);
2411
+ },
2412
+ createOpts: ['readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
2413
+ placeholder: function(val){
2414
+ var options = this.options;
2415
+ options.placeholder = val;
2416
+ var placeholder = val;
2417
+ if(placeholderFormat[this.type]){
2418
+ placeholder = placeholderFormat[this.type](val, this.options);
2419
+ }
2420
+ if(options.splitInput && typeof placeholder == 'object'){
2421
+ $.each(this.splits, function(i, elem){
2422
+ $.prop(elem, 'placeholder', placeholder[i]);
2423
+ });
2446
2424
  } else {
2447
- this.setFocus(this.buttons.eq(index));
2425
+ this.element.prop('placeholder', placeholder);
2448
2426
  }
2449
2427
  },
2450
- ons: function(that){
2451
- this.element
2452
- .on({
2453
- 'keydown': function(e){
2454
- var handled;
2455
- var key = e.keyCode;
2456
- if(e.ctrlKey){return;}
2457
- if(key == 36 || key == 33){
2458
- that.setFocus(that.buttons.eq(0));
2459
- handled = true;
2460
- } else if(key == 34 || key == 35){
2461
- that.setFocus(that.buttons.eq(that.buttons.length - 1));
2462
- handled = true;
2463
- } else if(key == 38 || key == 37){
2464
- that.prev();
2465
- handled = true;
2466
- } else if(key == 40 || key == 39){
2467
- that.next();
2468
- handled = true;
2469
- }
2470
- if(handled){
2471
- return false;
2472
- }
2428
+ initDataList: function(){
2429
+ var listTimer;
2430
+ var that = this;
2431
+ var updateList = function(){
2432
+ $(that.orig)
2433
+ .jProp('list')
2434
+ .off('updateDatalist', updateList)
2435
+ .on('updateDatalist', updateList)
2436
+ ;
2437
+ clearTimeout(listTimer);
2438
+ listTimer = setTimeout(function(){
2439
+ if(that.list){
2440
+ that.list();
2473
2441
  }
2474
- })
2475
- ;
2476
- }
2477
- };
2478
-
2479
- webshims.Grid = function (element, popover, opts){
2480
- this.element = $('tbody', element);
2481
- this.popover = popover;
2482
- this.opts = opts || {};
2483
- this.buttons = $('button:not(:disabled,.othermonth)', this.element);
2484
-
2485
- this.ons(this);
2486
-
2487
- this._initialFocus();
2488
- if(this.popover.openedByFocus){
2489
- this.popover.activeElement = this.activeButton;
2490
- }
2491
- };
2492
-
2493
-
2494
-
2495
- webshims.Grid.prototype = {
2496
- setFocus: _setFocus,
2497
- _initialFocus: _initialFocus,
2498
-
2499
- first: function(){
2500
- this.setFocus(this.buttons.eq(0));
2442
+ }, 9);
2443
+
2444
+ };
2445
+
2446
+ $(this.orig).onTrigger('listdatalistchange', updateList);
2501
2447
  },
2502
- last: function(){
2503
- this.setFocus(this.buttons.eq(this.buttons.length - 1));
2448
+ getOptions: function(){
2449
+ var options = {};
2450
+ var datalist = $(this.orig).jProp('list');
2451
+ datalist.find('option').each(function(){
2452
+ options[$.prop(this, 'value')] = $.prop(this, 'label');
2453
+ });
2454
+ return [options, datalist.data('label')];
2504
2455
  },
2505
- upPage: function(){
2506
- $('.ws-picker-header > button:not(:disabled)', this.popover.element).trigger('click');
2456
+ list: function(val){
2457
+ if(this.type == 'number' || this.type == 'time'){
2458
+ this.element.attr('list', $.attr(this.orig, 'list'));
2459
+ }
2460
+ this.options.list = val;
2461
+ this._propertyChange('list');
2507
2462
  },
2508
- downPage: function(){
2509
- this.activeButton.filter(':not([data-action="changeInput"])').trigger('click');
2463
+ _propertyChange: $.noop,
2464
+ tabindex: function(val){
2465
+ this.options.tabindex = val;
2466
+ this.inputElements.prop('tabindex', this.options.tabindex);
2467
+ $('button', this.buttonWrapper).prop('tabindex', this.options.tabindex);
2510
2468
  },
2511
- ons: function(that){
2512
- this.element
2513
- .on({
2514
- 'keydown': function(e){
2515
- var handled;
2516
- var key = e.keyCode;
2517
-
2518
- if(e.shiftKey){return;}
2519
-
2520
- if((e.ctrlKey && key == 40)){
2521
- handled = 'downPage';
2522
- } else if((e.ctrlKey && key == 38)){
2523
- handled = 'upPage';
2524
- } else if(key == 33 || (e.ctrlKey && key == 37)){
2525
- handled = 'prevPage';
2526
- } else if(key == 34 || (e.ctrlKey && key == 39)){
2527
- handled = 'nextPage';
2528
- } else if(e.keyCode == 36 || e.keyCode == 33){
2529
- handled = 'first';
2530
- } else if(e.keyCode == 35){
2531
- handled = 'last';
2532
- } else if(e.keyCode == 38){
2533
- handled = 'up';
2534
- } else if(e.keyCode == 37){
2535
- handled = 'prev';
2536
- } else if(e.keyCode == 40){
2537
- handled = 'down';
2538
- } else if(e.keyCode == 39){
2539
- handled = 'next';
2540
- }
2541
- if(handled){
2542
- that[handled]();
2543
- return false;
2544
- }
2545
- }
2546
- })
2547
- ;
2548
- }
2549
- };
2550
- $.each({
2551
- prevPage: {get: 'last', action: 'prev'},
2552
- nextPage: {get: 'first', action: 'next'}
2553
- }, function(name, val){
2554
- webshims.Grid.prototype[name] = function(){
2555
- if(this.opts[val.action]){
2556
- this.popover.navedInitFocus = {
2557
- sel: 'button[data-id="'+ this.activeButton.attr('data-id') +'"]:not(:disabled,.othermonth)',
2558
- alt: val.get
2559
- };
2560
- this.popover.actionFn(this.opts[val.action]);
2561
- this.popover.navedInitFocus = false;
2562
- }
2563
- };
2564
- });
2565
-
2566
- $.each({
2567
- up: {traverse: 'prevAll', get: 'last', action: 'prev', reverse: true},
2568
- down: {traverse: 'nextAll', get: 'first', action: 'next'}
2569
- }, function(name, val){
2570
- webshims.Grid.prototype[name] = function(){
2571
- var cellIndex = this.activeButton.closest('td').prop('cellIndex');
2572
- var sel = 'td:nth-child('+(cellIndex + 1)+') button:not(:disabled,.othermonth)';
2573
- var button = this.activeButton.closest('tr')[val.traverse]();
2574
-
2575
- if(val.reverse){
2576
- button = $(button.get().reverse());
2577
- }
2578
- button = button.find(sel)[val.get]();
2579
-
2580
- if(!button[0]){
2581
- if(this.opts[val.action]){
2582
- this.popover.navedInitFocus = sel+':'+val.get;
2583
- this.popover.actionFn(this.opts[val.action]);
2584
- this.popover.navedInitFocus = false;
2585
- }
2586
- } else {
2587
- this.setFocus(button.eq(0));
2588
- }
2589
- };
2590
- });
2591
-
2592
- $.each({
2593
- prev: {traverse: 'prevAll',get: 'last', reverse: true},
2594
- next: {traverse: 'nextAll', get: 'first'}
2595
- }, function(name, val){
2596
- webshims.Grid.prototype[name] = function(){
2597
- var sel = 'button:not(:disabled,.othermonth)';
2598
- var button = this.activeButton.closest('td')[val.traverse]('td');
2599
- if(val.reverse){
2600
- button = $(button.get().reverse());
2601
- }
2602
- button = button.find(sel)[val.get]();
2603
- if(!button[0]){
2604
- button = this.activeButton.closest('tr')[val.traverse]('tr');
2605
- if(val.reverse){
2606
- button = $(button.get().reverse());
2607
- }
2608
- button = button.find(sel)[val.get]();
2469
+ title: function(val){
2470
+ if(!val && this.orig && $.attr(this.orig, 'title') == null){
2471
+ val = null;
2609
2472
  }
2610
-
2611
- if(!button[0]){
2612
- if(this.opts[name]){
2613
- this.popover.navedInitFocus = val.get;
2614
- this.popover.actionFn(this.opts[name]);
2615
- this.popover.navedInitFocus = false;
2616
- }
2473
+ this.options.title = val;
2474
+ if(val == null){
2475
+ this.inputElements.removeAttr('title');
2617
2476
  } else {
2618
- this.setFocus(button.eq(0));
2477
+ this.inputElements.prop('title', this.options.title);
2619
2478
  }
2620
- };
2621
- });
2622
-
2623
- picker.getWeek = function(date){
2624
- var onejan = new Date(date.getFullYear(),0,1);
2625
- return Math.ceil((((date - onejan) / 86400000) + onejan.getDay()+1)/7);
2626
- };
2627
- picker.getYearList = function(value, data){
2628
- var j, i, val, disabled, lis, prevDisabled, nextDisabled, classStr, classArray, start;
2629
-
2630
-
2631
- var size = data.options.size;
2632
- var max = data.options.max.split('-');
2633
- var min = data.options.min.split('-');
2634
- var currentValue = data.options.value.split('-');
2635
- var xthCorrect = 0;
2636
- var enabled = 0;
2637
- var str = '';
2638
- var rowNum = 0;
2639
-
2640
- if(data.options.useDecadeBase == 'max' && max[0]){
2641
- xthCorrect = 11 - (max[0] % 12);
2642
- } else if(data.options.useDecadeBase == 'min' && min[0]){
2643
- xthCorrect = 11 - (min[0] % 12);
2644
2479
  }
2645
-
2646
- value = value[0] * 1;
2647
- start = value - ((value + xthCorrect) % (12 * size));
2648
-
2649
-
2650
-
2651
- for(j = 0; j < size; j++){
2652
- if(j){
2653
- start += 12;
2654
- } else {
2655
- prevDisabled = picker.isInRange([start-1], max, min) ? {'data-action': 'setYearList','value': start-1} : false;
2656
- }
2657
-
2658
- str += '<div class="year-list picker-list ws-index-'+ j +'"><div class="ws-picker-header"><button disabled="disabled">'+ start +' – '+(start + 11)+'</button></div>';
2659
- lis = [];
2660
- for(i = 0; i < 12; i++){
2661
- val = start + i ;
2662
- classArray = [];
2663
- if( !picker.isInRange([val], max, min) ){
2664
- disabled = ' disabled=""';
2665
- } else {
2666
- disabled = '';
2667
- enabled++;
2668
- }
2669
-
2670
- if(val == today[0]){
2671
- classArray.push('this-value');
2672
- }
2673
-
2674
- if(currentValue[0] == val){
2675
- classArray.push('checked-value');
2676
- }
2677
-
2678
- classStr = classArray.length ? ' class="'+ (classArray.join(' ')) +'"' : '';
2679
-
2680
- if(i && !(i % 3)){
2681
- rowNum++;
2682
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2683
- }
2684
- 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>');
2685
- }
2686
- if(j == size - 1){
2687
- nextDisabled = picker.isInRange([val+1], max, min) ? {'data-action': 'setYearList','value': val+1} : false;
2688
- }
2689
- 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>';
2690
- }
2691
-
2692
- return {
2693
- enabled: enabled,
2694
- main: str,
2695
- next: nextDisabled,
2696
- prev: prevDisabled,
2697
- type: 'Grid'
2698
- };
2699
2480
  };
2700
2481
 
2701
2482
 
2702
- picker.getMonthList = function(value, data){
2703
-
2704
- var j, i, name, val, disabled, lis, fullyDisabled, prevDisabled, nextDisabled, classStr, classArray;
2705
- var o = data.options;
2706
- var size = o.size;
2707
- var max = o.max.split('-');
2708
- var min = o.min.split('-');
2709
- var currentValue = o.value.split('-');
2710
- var enabled = 0;
2711
- var rowNum = 0;
2712
- var str = '';
2713
-
2714
- value = value[0] - Math.floor((size - 1) / 2);
2715
- for(j = 0; j < size; j++){
2716
- if(j){
2717
- value++;
2718
- } else {
2719
- prevDisabled = picker.isInRange([value-1], max, min) ? {'data-action': 'setMonthList','value': value-1} : false;
2720
- }
2721
- if(j == size - 1){
2722
- nextDisabled = picker.isInRange([value+1], max, min) ? {'data-action': 'setMonthList','value': value+1} : false;
2723
- }
2724
- lis = [];
2725
-
2726
- if( !picker.isInRange([value, '01'], max, min) && !picker.isInRange([value, '12'], max, min)){
2727
- disabled = ' disabled=""';
2728
- fullyDisabled = true;
2729
- } else {
2730
- fullyDisabled = false;
2731
- disabled = '';
2732
- }
2733
-
2734
- if(o.minView >= 1){
2735
- disabled = ' disabled=""';
2736
- }
2737
-
2738
- str += '<div class="month-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">';
2739
-
2740
- str += o.selectNav ?
2741
- '<select data-action="setMonthList" class="year-select">'+ picker.createYearSelect(value, max, min).join('') +'</select>' :
2742
- '<button data-action="setYearList"'+disabled+' value="'+ value +'" tabindex="-1">'+ value +'</button>';
2743
- str += '</div>';
2744
-
2745
- for(i = 0; i < 12; i++){
2746
- val = curCfg.date.monthkeys[i+1];
2747
- name = (curCfg.date[o.monthNames] || curCfg.date.monthNames)[i];
2748
- classArray = [];
2749
- if(fullyDisabled || !picker.isInRange([value, val], max, min) ){
2750
- disabled = ' disabled=""';
2751
- } else {
2752
- disabled = '';
2753
- enabled++;
2754
- }
2755
-
2756
- if(value == today[0] && today[1] == val){
2757
- classArray.push('this-value');
2758
- }
2759
-
2760
- if(currentValue[0] == value && currentValue[1] == val){
2761
- classArray.push('checked-value');
2762
- }
2763
-
2764
- classStr = (classArray.length) ? ' class="'+ (classArray.join(' ')) +'"' : '';
2765
- if(i && !(i % 3)){
2766
- rowNum++;
2767
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2483
+ ['readonly', 'disabled'].forEach(function(name){
2484
+ var isDisabled = name == 'disabled';
2485
+ wsWidgetProto[name] = function(val, boolVal){
2486
+ if(this.options[name] != boolVal || !this._init){
2487
+ this.options[name] = !!boolVal;
2488
+ this.inputElements.prop(name, this.options[name]);
2489
+ this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
2490
+ if(isDisabled){
2491
+ $('button', this.buttonWrapper).prop('disabled', this.options[name]);
2768
2492
  }
2769
-
2770
- 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>');
2771
-
2772
2493
  }
2773
-
2774
- str += '<div class="picker-grid"><table role="grid" aria-label="'+value+'"><tbody><tr class="ws-row-0">'+ (lis.join(''))+ '</tr></tbody></table></div></div>';
2775
- }
2776
-
2777
- return {
2778
- enabled: enabled,
2779
- main: str,
2780
- prev: prevDisabled,
2781
- next: nextDisabled,
2782
- type: 'Grid'
2783
2494
  };
2784
- };
2785
-
2495
+ });
2786
2496
 
2787
- picker.getDayList = function(value, data){
2788
-
2789
- var j, i, k, day, nDay, name, val, disabled, lis, prevDisabled, nextDisabled, addTr, week, rowNum;
2790
-
2791
- var lastMotnh, curMonth, otherMonth, dateArray, monthName, fullMonthName, buttonStr, date2, classArray;
2792
- var o = data.options;
2793
- var size = o.size;
2794
- var max = o.max.split('-');
2795
- var min = o.min.split('-');
2796
- var currentValue = o.value.split('-');
2797
- var monthNames = curCfg.date[o.monthNamesHead] || curCfg.date[o.monthNames] || curCfg.date.monthNames;
2798
- var enabled = 0;
2799
- var str = [];
2800
- var date = new Date(value[0], value[1] - 1, 1);
2801
-
2802
- date.setMonth(date.getMonth() - Math.floor((size - 1) / 2));
2803
-
2804
- for(j = 0; j < size; j++){
2805
- date.setDate(1);
2806
- lastMotnh = date.getMonth();
2807
- rowNum = 0;
2808
- if(!j){
2809
- date2 = new Date(date.getTime());
2810
- date2.setDate(-1);
2811
- dateArray = getDateArray(date2);
2812
- prevDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray[0]+'-'+dateArray[1]} : false;
2813
- }
2497
+ var spinBtnProto = $.extend({}, wsWidgetProto, {
2498
+ _create: function(){
2499
+ var o = this.options;
2500
+ var helper = createHelper(o.type);
2814
2501
 
2815
- dateArray = getDateArray(date);
2502
+ this.elemHelper = $('<input type="'+ o.type+'" />');
2503
+ this.asNumber = helper.asNumber;
2504
+ this.asValue = helper.asValue;
2816
2505
 
2817
- str.push('<div class="day-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">');
2818
- if( o.selectNav ){
2819
- 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>'];
2820
- if(curCfg.date.showMonthAfterYear){
2821
- monthName.reverse();
2822
- }
2823
- str.push( monthName.join(' ') );
2824
- }
2506
+ wsWidgetProto._create.apply(this, arguments);
2507
+ this._init = false;
2825
2508
 
2826
- fullMonthName = [curCfg.date.monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
2827
- monthName = [monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
2828
- if(curCfg.date.showMonthAfterYear){
2829
- monthName.reverse();
2830
- fullMonthName.reverse();
2831
- }
2509
+ this.buttonWrapper.html('<span unselectable="on" class="step-controls"><span class="step-up"></span><span class="step-down"></span></span>');
2832
2510
 
2833
- if(!data.options.selectNav) {
2834
- str.push(
2835
- '<button data-action="setMonthList"'+ (o.minView >= 2 ? ' disabled="" ' : '') +' value="'+ dateArray.date +'" tabindex="-1">'+ monthName.join(' ') +'</button>'
2836
- );
2511
+ if(this.type == 'number'){
2512
+ this.inputElements.attr('inputmode', 'numeric');
2837
2513
  }
2838
2514
 
2839
2515
 
2840
- str.push('</div><div class="picker-grid"><table role="grid" aria-label="'+ fullMonthName.join(' ') +'"><thead><tr>');
2516
+ if(!o.min && typeof o.relMin == 'number'){
2517
+ o.min = this.asValue(this.getRelNumber(o.relMin));
2518
+ $.prop(this.orig, 'min', o.min);
2519
+ }
2841
2520
 
2842
- if(data.options.showWeek){
2843
- str.push('<th class="week-header">'+ curCfg.date.weekHeader +'</th>');
2521
+ if(!o.max && typeof o.relMax == 'number'){
2522
+ o.max = this.asValue(this.getRelNumber(o.relMax));
2523
+ $.prop(this.orig, 'max', o.max);
2844
2524
  }
2845
- for(k = curCfg.date.firstDay; k < curCfg.date.dayNamesShort.length; k++){
2846
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2525
+ this._init = true;
2526
+ },
2527
+ createOpts: ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
2528
+ _addSplitInputs: function(){
2529
+ if(!this.inputElements){
2530
+ var create = splitInputs[this.type]._create();
2531
+ this.splits = create.splits;
2532
+ this.inputElements = $(create.elements).prependTo(this.element).filter('input');
2847
2533
  }
2848
- k = curCfg.date.firstDay;
2849
- while(k--){
2850
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2534
+ },
2535
+
2536
+ getRelNumber: function(rel){
2537
+ var start = steps[this.type].start || 0;
2538
+ if(rel){
2539
+ start += rel;
2851
2540
  }
2852
- str.push('</tr></thead><tbody><tr class="ws-row-0">');
2853
-
2854
- if(data.options.showWeek) {
2855
- week = picker.getWeek(date);
2856
- str.push('<td class="week-cell">'+ week +'</td>');
2541
+ return start;
2542
+ },
2543
+ addZero: addZero,
2544
+ _setStartInRange: function(){
2545
+ var start = this.getRelNumber(this.options.relDefaultValue);
2546
+ if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
2547
+ start = this.minAsNumber;
2548
+ } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
2549
+ start = this.maxAsNumber;
2857
2550
  }
2551
+ this.elemHelper.prop('valueAsNumber', start);
2552
+ this.options.defValue = this.elemHelper.prop('value');
2858
2553
 
2859
- for (i = 0; i < 99; i++) {
2860
- addTr = (i && !(i % 7));
2861
- curMonth = date.getMonth();
2862
- otherMonth = lastMotnh != curMonth;
2863
- day = date.getDay();
2864
- classArray = [];
2865
-
2866
- if(addTr && otherMonth ){
2867
- str.push('</tr>');
2868
- break;
2869
- }
2870
- if(addTr){
2871
- rowNum++;
2872
- str.push('</tr><tr class="ws-row-'+ rowNum +'">');
2873
- if(data.options.showWeek) {
2874
- week++;
2875
- str.push('<td class="week-cell">'+ week +'</td>');
2876
- }
2877
- }
2878
-
2879
- if(!i){
2880
-
2881
- if(day != curCfg.date.firstDay){
2882
- nDay = day - curCfg.date.firstDay;
2883
- if(nDay < 0){
2884
- nDay += 7;
2885
- }
2886
- date.setDate(date.getDate() - nDay);
2887
- day = date.getDay();
2888
- curMonth = date.getMonth();
2889
- otherMonth = lastMotnh != curMonth;
2554
+ },
2555
+ reorderInputs: function(){
2556
+ if(splitInputs[this.type]){
2557
+ var element = this.element;
2558
+ splitInputs[this.type].sort(element);
2559
+ setTimeout(function(){
2560
+ var data = webshims.data(element);
2561
+ if(data && data.shadowData){
2562
+ data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
2890
2563
  }
2891
- }
2892
-
2893
- dateArray = getDateArray(date);
2894
- buttonStr = '<td role="presentation" class="day-'+ day +'"><button data-id="day-'+ date.getDate() +'" role="gridcell" data-action="changeInput" value="'+ (dateArray.join('-')) +'"';
2564
+ }, 9);
2565
+ }
2566
+ },
2567
+ value: function(val){
2568
+
2569
+ if(!this._init || this.options.value !== val){
2570
+ this.valueAsNumber = this.asNumber(val);
2571
+ this.options.value = val;
2895
2572
 
2896
- if(otherMonth){
2897
- classArray.push('othermonth');
2573
+ if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
2574
+ this._setStartInRange();
2898
2575
  } else {
2899
- classArray.push('day-'+date.getDate());
2900
- }
2901
-
2902
- if(dateArray[0] == today[0] && today[1] == dateArray[1] && today[2] == dateArray[2]){
2903
- classArray.push('this-value');
2576
+ this.elemHelper.prop('value', val);
2577
+ this.options.defValue = "";
2904
2578
  }
2905
2579
 
2906
- if(currentValue[0] == dateArray[0] && dateArray[1] == currentValue[1] && dateArray[2] == currentValue[2]){
2907
- classArray.push('checked-value');
2908
- }
2909
-
2910
- if(classArray.length){
2911
- buttonStr += ' class="'+ classArray.join(' ') +'"';
2912
- }
2913
-
2914
- if(!picker.isInRange(dateArray, max, min) || (data.options.disableDays && $.inArray(day, data.options.disableDays) != -1)){
2915
- buttonStr += ' disabled=""';
2580
+ val = formatVal[this.type](val, this.options);
2581
+ if(this.options.splitInput){
2582
+ $.each(this.splits, function(i, elem){
2583
+ $.prop(elem, 'value', val[i]);
2584
+ });
2585
+ } else {
2586
+ this.element.prop('value', val);
2916
2587
  }
2917
-
2918
- str.push(buttonStr+' tabindex="-1">'+ date.getDate() +'</button></td>');
2919
-
2920
- date.setDate(date.getDate() + 1);
2921
- }
2922
- str.push('</tbody></table></div></div>');
2923
- if(j == size - 1){
2924
- dateArray = getDateArray(date);
2925
- dateArray[2] = 1;
2926
- nextDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray.date} : false;
2588
+ this._propertyChange('value');
2589
+ this.mirrorValidity();
2927
2590
  }
2591
+ },
2592
+ step: function(val){
2593
+ var defStep = steps[this.type];
2594
+ this.options.step = val;
2595
+ this.elemHelper.prop('step', retDefault(val, defStep.step));
2596
+ this.mirrorValidity();
2928
2597
  }
2929
-
2930
-
2931
- return {
2932
- enabled: 9,
2933
- main: str.join(''),
2934
- prev: prevDisabled,
2935
- next: nextDisabled,
2936
- type: 'Grid'
2937
- };
2938
- };
2598
+ });
2939
2599
 
2940
- picker.isInRange = function(values, max, min){
2941
- var i;
2942
- var ret = true;
2943
- for(i = 0; i < values.length; i++){
2944
-
2945
- if(min[i] && min[i] > values[i]){
2946
- ret = false;
2947
- break;
2948
- } else if( !(min[i] && min[i] == values[i]) ){
2949
- break;
2600
+ $.each({min: 1, max: -1}, function(name, factor){
2601
+ var numName = name +'AsNumber';
2602
+ spinBtnProto[name] = function(val){
2603
+ this.elemHelper.prop(name, val);
2604
+ this[numName] = this.asNumber(val);
2605
+ if(this.valueAsNumber != null && (isNaN(this.valueAsNumber) || (!isNaN(this[numName]) && (this.valueAsNumber * factor) < (this[numName] * factor)))){
2606
+ this._setStartInRange();
2950
2607
  }
2951
- }
2952
- if(ret){
2953
- for(i = 0; i < values.length; i++){
2954
-
2955
- if((max[i] && max[i] < values[i])){
2956
- ret = false;
2957
- break;
2958
- } else if( !(max[i] && max[i] == values[i]) ){
2959
- break;
2608
+ this.options[name] = val;
2609
+ this._propertyChange(name);
2610
+ this.mirrorValidity();
2611
+ };
2612
+ });
2613
+
2614
+ $.fn.wsBaseWidget = function(opts){
2615
+ opts = $.extend({}, opts);
2616
+ return this.each(function(){
2617
+ $.webshims.objectCreate(wsWidgetProto, {
2618
+ element: {
2619
+ value: $(this)
2960
2620
  }
2961
- }
2962
- }
2963
- return ret;
2621
+ }, opts);
2622
+ });
2964
2623
  };
2965
2624
 
2966
- picker.createMonthSelect = function(value, max, min, monthNames){
2967
- if(!monthNames){
2968
- monthNames = curCfg.date.monthNames;
2969
- }
2970
-
2971
- var selected;
2972
- var i = 0;
2973
- var options = [];
2974
- var tempVal = value[1]-1;
2975
- for(; i < monthNames.length; i++){
2976
- selected = tempVal == i ? ' selected=""' : '';
2977
- if(selected || picker.isInRange([value[0], i+1], max, min)){
2978
- options.push('<option value="'+ value[0]+'-'+addZero(i+1) + '"'+selected+'>'+ monthNames[i] +'</option>');
2979
- }
2625
+ $.fn.spinbtnUI = function(opts){
2626
+ opts = $.extend({
2627
+ monthNames: 'monthNames',
2628
+ size: 1,
2629
+ startView: 0
2630
+ }, opts);
2631
+ return this.each(function(){
2632
+ $.webshims.objectCreate(spinBtnProto, {
2633
+ element: {
2634
+ value: $(this)
2635
+ }
2636
+ }, opts);
2637
+ });
2638
+ };
2639
+ })();
2640
+
2641
+ (function(){
2642
+ var picker = {};
2643
+
2644
+ var loadPicker = function(type, name){
2645
+ type = (type == 'color' ? 'color' : 'forms')+'-picker';
2646
+ if(!loadPicker[name+'Loaded'+type]){
2647
+ loadPicker[name+'Loaded'+type] = true;
2648
+ webshims.ready(name, function(){
2649
+ webshims.loader.loadList([type]);
2650
+ });
2980
2651
  }
2981
- return options;
2652
+ return type;
2982
2653
  };
2654
+ options.addZero = addZero;
2655
+ webshims.loader.addModule('forms-picker', {
2656
+ noAutoCallback: true,
2657
+ options: options
2658
+ });
2659
+ webshims.loader.addModule('color-picker', {
2660
+ noAutoCallback: true,
2661
+ css: 'jpicker/jpicker.css',
2662
+ options: options
2663
+ });
2983
2664
 
2984
- picker.createYearSelect = function(value, max, min, valueAdd){
2985
-
2986
- var temp;
2987
- var goUp = true;
2988
- var goDown = true;
2989
- var options = ['<option selected="">'+ value + '</option>'];
2990
- var i = 0;
2991
- if(!valueAdd){
2992
- valueAdd = '';
2993
- }
2994
- while(i < 8 && (goUp || goDown)){
2995
- i++;
2996
- temp = value-i;
2997
- if(goUp && picker.isInRange([temp], max, min)){
2998
- options.unshift('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
2999
- } else {
3000
- goUp = false;
3001
- }
3002
- temp = value + i;
3003
- if(goDown && picker.isInRange([temp], max, min)){
3004
- options.push('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
3005
- } else {
3006
- goDown = false;
3007
- }
2665
+ picker._genericSetFocus = function(element, _noFocus){
2666
+ element = $(element || this.activeButton);
2667
+ if(!this.popover.openedByFocus && !_noFocus){
2668
+ var that = this;
2669
+ var setFocus = function(noTrigger){
2670
+ clearTimeout(that.timer);
2671
+ that.timer = setTimeout(function(){
2672
+ if(element[0]){
2673
+ element[0].focus();
2674
+ if(noTrigger !== true && !element.is(':focus')){
2675
+ setFocus(true);
2676
+ }
2677
+ }
2678
+ }, that.popover.isVisible ? 99 : 360);
2679
+ };
2680
+ this.popover.activateElement(element);
2681
+ setFocus();
3008
2682
  }
3009
- return options;
3010
2683
  };
3011
-
3012
- var actions = {
2684
+
2685
+ picker._actions = {
3013
2686
  changeInput: function(val, popover, data){
2687
+ picker._actions.cancel(val, popover, data);
2688
+ data.setChange(val);
2689
+ },
2690
+ cancel: function(val, popover, data){
3014
2691
  popover.stopOpen = true;
3015
2692
  data.element.getShadowFocusElement().focus();
3016
2693
  setTimeout(function(){
3017
2694
  popover.stopOpen = false;
3018
2695
  }, 9);
3019
- popover.hide();
3020
- data.setChange(val);
3021
- }
3022
- };
3023
-
3024
- (function(){
3025
- var retNames = function(name){
3026
- return 'get'+name+'List';
3027
- };
3028
- var retSetNames = function(name){
3029
- return 'set'+name+'List';
3030
- };
3031
- var stops = {
3032
- date: 'Day',
3033
- week: 'Day',
3034
- month: 'Month'
3035
- };
3036
-
3037
- $.each({'setYearList' : ['Year', 'Month', 'Day'], 'setMonthList': ['Month', 'Day'], 'setDayList': ['Day']}, function(setName, names){
3038
- var getNames = names.map(retNames);
3039
- var setNames = names.map(retSetNames);
3040
- actions[setName] = function(val, popover, data, startAt){
3041
- val = ''+val;
3042
- var o = data.options;
3043
- var values = val.split('-');
3044
- if(!startAt){
3045
- startAt = 0;
3046
- }
3047
- $.each(getNames, function(i, item){
3048
- if(i >= startAt){
3049
- var content = picker[item](values, data);
3050
-
3051
- if( values.length < 2 || content.enabled > 1 || stops[data.type] === names[i]){
3052
- popover.element
3053
- .attr({'data-currentview': setNames[i]})
3054
- .addClass('ws-size-'+o.size)
3055
- .data('pickercontent', {
3056
- data: data,
3057
- content: content,
3058
- values: values
3059
- })
3060
- ;
3061
- popover.bodyElement.html(content.main);
3062
- if(content.prev){
3063
- popover.prevElement
3064
- .attr(content.prev)
3065
- .prop({disabled: false})
3066
- ;
3067
- } else {
3068
- popover.prevElement
3069
- .removeAttr('data-action')
3070
- .prop({disabled: true})
3071
- ;
3072
- }
3073
- if(content.next){
3074
- popover.nextElement
3075
- .attr(content.next)
3076
- .prop({disabled: false})
3077
- ;
3078
- } else {
3079
- popover.nextElement
3080
- .removeAttr('data-action')
3081
- .prop({disabled: true})
3082
- ;
3083
- }
3084
- if(webshims[content.type]){
3085
- new webshims[content.type](popover.bodyElement.children(), popover, content);
3086
- }
3087
- popover.element.trigger('pickerchange');
3088
- return false;
3089
- }
3090
- }
3091
- });
3092
- };
3093
- });
3094
- })();
3095
-
3096
- picker.commonInit = function(data, popover){
3097
- var actionfn = function(e){
3098
- if(!$(this).is('.othermonth') || $(this).css('cursor') == 'pointer'){
3099
- popover.actionFn({
3100
- 'data-action': $.attr(this, 'data-action'),
3101
- value: $(this).val() || $.attr(this, 'value')
3102
- });
3103
- }
3104
- return false;
3105
- };
3106
- var id = new Date().getTime();
3107
- var generateList = function(o, max, min){
3108
- var options = [];
3109
- var label = '';
3110
- var labelId = '';
3111
- o.options = data.getOptions() || {};
3112
- $('div.ws-options', popover.contentElement).remove();
3113
- $.each(o.options[0], function(val, label){
3114
- var disabled = picker.isInRange(val.split('-'), o.maxS, o.minS) ?
3115
- '' :
3116
- ' disabled="" '
3117
- ;
3118
- options.push('<li role="presentation"><button value="'+ val +'" '+disabled+' data-action="changeInput" tabindex="-1" role="option">'+ (label || data.formatValue(val, false)) +'</button></li>');
3119
- });
3120
- if(options.length){
3121
- id++;
3122
- if(o.options[1]){
3123
- labelId = 'datalist-'+id;
3124
- label = '<h5 id="'+labelId+'">'+ o.options[1] +'</h5>';
3125
- labelId = ' aria-labelledbyid="'+ labelId +'" ';
3126
- }
3127
- new webshims.ListBox($('<div class="ws-options">'+label+'<ul role="listbox" '+ labelId +'>'+ options.join('') +'</div>').insertAfter(popover.bodyElement)[0], popover, {noFocus: true});
3128
- }
3129
- };
3130
- var updateContent = function(){
3131
- if(popover.isDirty){
3132
- var o = data.options;
3133
- o.maxS = o.max.split('-');
3134
- o.minS = o.min.split('-');
3135
-
3136
- $('button', popover.buttonRow).each(function(){
3137
- var text;
3138
- if($(this).is('.ws-empty')){
3139
- text = curCfg.date.clear;
3140
- if(!text){
3141
- text = formcfg[''].date.clear || 'clear';
3142
- webshims.warn("could not get clear text from form cfg");
3143
- }
3144
- } else if($(this).is('.ws-current')){
3145
- text = (curCfg[data.type] || {}).currentText;
3146
- if(!text){
3147
- text = (formcfg[''][[data.type]] || {}).currentText || 'current';
3148
- webshims.warn("could not get currentText from form cfg");
3149
- }
3150
- $.prop(this, 'disabled', !picker.isInRange(today[data.type].split('-'), o.maxS, o.minS));
3151
- }
3152
- if(text){
3153
- $(this).text(text).attr({'aria-label': text});
3154
- if(webshims.assumeARIA){
3155
- $.attr(this, 'aria-label', text);
3156
- }
3157
- }
3158
-
3159
- });
3160
- popover.nextElement.attr({'aria-label': curCfg.date.nextText});
3161
- $('> span', popover.nextElement).html(curCfg.date.nextText);
3162
- popover.prevElement.attr({'aria-label': curCfg.date.prevText});
3163
- $('> span', popover.prevElement).html(curCfg.date.prevText);
3164
-
3165
- generateList(o, o.maxS, o.minS);
3166
-
3167
- }
3168
- $('button.ws-empty', popover.buttonRow).prop('disabled', $.prop(data.orig, 'required'));
3169
- popover.isDirty = false;
3170
- };
3171
-
3172
- popover.actionFn = function(obj){
3173
- if(actions[obj['data-action']]){
3174
- actions[obj['data-action']](obj.value, popover, data, 0);
3175
- } else {
3176
- webshims.warn('no action for '+ obj['data-action']);
3177
- }
3178
- };
3179
-
3180
- 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>');
3181
- popover.nextElement = $('button.ws-next', popover.contentElement);
3182
- popover.prevElement = $('button.ws-prev', popover.contentElement);
3183
- popover.bodyElement = $('div.ws-picker-body', popover.contentElement);
3184
- popover.buttonRow = $('div.ws-button-row', popover.contentElement);
2696
+ popover.hide();
2697
+ }
2698
+ };
2699
+
2700
+
2701
+ picker.commonInit = function(data, popover){
2702
+ var tabbable;
3185
2703
 
3186
2704
  popover.isDirty = true;
3187
2705
 
3188
- popover.contentElement
3189
- .on('click', 'button[data-action]', actionfn)
3190
- .on('change', 'select[data-action]', actionfn)
3191
- ;
3192
-
2706
+ popover.element.on('updatepickercontent pickerchange', function(){
2707
+ tabbable = false;
2708
+ });
3193
2709
  popover.contentElement.on({
3194
2710
  keydown: function(e){
3195
2711
  if(e.keyCode == 9){
3196
- var tabbable = $('[tabindex="0"]:not(:disabled)', this).filter(':visible');
2712
+ if(!tabbable){
2713
+ tabbable = $('input:not(:disabled), [tabindex="0"]:not(:disabled)', this).filter(':visible');
2714
+ }
3197
2715
  var index = tabbable.index(e.target);
3198
2716
  if(e.shiftKey && index <= 0){
3199
2717
  tabbable.last().focus();
@@ -3211,18 +2729,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3211
2729
  }
3212
2730
  });
3213
2731
 
3214
- $(data.options.orig).on('input', function(){
3215
- var currentView;
3216
- if(data.options.updateOnInput && popover.isVisible && data.options.value && (currentView = popover.element.attr('data-currentview'))){
3217
- actions[currentView]( data.options.value , popover, data, 0);
3218
- }
3219
- });
3220
-
3221
2732
  data._propertyChange = (function(){
3222
2733
  var timer;
3223
2734
  var update = function(){
3224
2735
  if(popover.isVisible){
3225
- updateContent();
2736
+ popover.element.triggerHandler('updatepickercontent');
3226
2737
  }
3227
2738
  };
3228
2739
  return function(prop){
@@ -3248,50 +2759,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3248
2759
  popover.element.on({
3249
2760
  wspopoverbeforeshow: function(){
3250
2761
  data.element.triggerHandler('wsupdatevalue');
3251
- updateContent();
2762
+ popover.element.triggerHandler('updatepickercontent');
3252
2763
  }
3253
2764
  });
3254
2765
 
3255
- $(document).onTrigger('wslocalechange', data._propertyChange);
2766
+
2767
+ $(data.orig).on('remove', function(e){
2768
+ if(!e.originalEvent){
2769
+ $(document).off('wslocalechange', data._propertyChange);
2770
+ }
2771
+ });
3256
2772
  };
3257
2773
 
2774
+
3258
2775
  picker._common = function(data){
3259
2776
  var popover = webshims.objectCreate(webshims.wsPopover, {}, {prepareFor: data.element});
3260
2777
  var opener = $('<button type="button" class="ws-popover-opener"><span /></button>').appendTo(data.buttonWrapper);
3261
2778
  var options = data.options;
3262
- var init = false;
3263
2779
 
2780
+ var showPickerContent = function(){
2781
+ (picker[data.type].showPickerContent || picker.showPickerContent)(data, popover);
2782
+ };
3264
2783
  var show = function(){
2784
+ var type = loadPicker(data.type, 'DOM');
3265
2785
  if(!options.disabled && !options.readonly && !popover.isVisible){
3266
- if(!init){
3267
- picker.commonInit(data, popover);
3268
- }
3269
-
3270
- if(!init || data.options.restartView) {
3271
- actions.setYearList( options.defValue || options.value, popover, data, data.options.startView);
3272
- } else {
3273
- actions[popover.element.attr('data-currentview') || 'setYearList']( options.defValue || options.value, popover, data, 0);
3274
- }
3275
-
3276
- init = true;
2786
+ webshims.ready(type, showPickerContent);
3277
2787
  popover.show(data.element);
3278
2788
  }
3279
2789
  };
3280
2790
 
3281
2791
  options.containerElements.push(popover.element[0]);
3282
2792
 
3283
- if(!options.startView){
3284
- options.startView = 0;
3285
- }
3286
- if(!options.minView){
3287
- options.minView = 0;
3288
- }
3289
- if(options.startView < options.minView){
3290
- options.minView = options.startView;
3291
- webshims.warn("wrong config for minView/startView.");
3292
- }
3293
- if(!options.size){
3294
- options.size = 1;
2793
+ if(data.type != 'color'){
2794
+ if(!options.startView){
2795
+ options.startView = 0;
2796
+ }
2797
+ if(!options.minView){
2798
+ options.minView = 0;
2799
+ }
2800
+ if(options.startView < options.minView){
2801
+ options.startView = options.minView;
2802
+ webshims.warn("wrong config for minView/startView.");
2803
+ }
2804
+ if(!options.size){
2805
+ options.size = 1;
2806
+ }
3295
2807
  }
3296
2808
 
3297
2809
  popover.element
@@ -3318,10 +2830,15 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3318
2830
  labelWidth(popover.element.children('div.ws-po-outerbox').attr({role: 'group'}), options.labels, true);
3319
2831
  labelWidth(opener, options.labels, true);
3320
2832
 
2833
+ if(options.tabindex != null){
2834
+ opener.attr({tabindex: options.tabindex});
2835
+ }
2836
+
2837
+ if(options.disabled){
2838
+ opener.prop({disabled: true});
2839
+ }
2840
+
3321
2841
  opener
3322
- .attr({
3323
- 'tabindex': options.labels.length ? 0 : '-1'
3324
- })
3325
2842
  .on({
3326
2843
  mousedown: function(){
3327
2844
  stopPropagation.apply(this, arguments);
@@ -3366,10 +2883,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3366
2883
  });
3367
2884
  })();
3368
2885
  data.popover = popover;
2886
+ data.opener = opener;
2887
+ $(data.orig).on('remove', function(e){
2888
+ if(!e.originalEvent){
2889
+ opener.remove();
2890
+ popover.element.remove();
2891
+ }
2892
+ });
2893
+
2894
+ loadPicker(data.type, 'WINDOWLOAD');
3369
2895
  };
3370
2896
 
3371
2897
  picker.month = picker._common;
3372
- picker.date = picker.month;
2898
+ picker.date = picker._common;
2899
+ picker.color = function(data){
2900
+ var ret = picker._common.apply(this, arguments);
2901
+ var alpha = $(data.orig).data('alphacontrol');
2902
+ var colorIndicator = data.opener
2903
+ .prepend('<span class="ws-color-indicator-bg"><span class="ws-color-indicator" /></span>')
2904
+ .find('.ws-color-indicator')
2905
+ ;
2906
+ var showColor = function(){
2907
+ colorIndicator.css({backgroundColor: $.prop(this, 'value') || '#000'})
2908
+ };
2909
+ var showOpacity = (function(){
2910
+ var timer;
2911
+ var show = function(){
2912
+ try {
2913
+ var value = data.alpha.prop('valueAsNumber') / (data.alpha.prop('max') || 1);
2914
+ if(!isNaN(value)){
2915
+ colorIndicator.css({opacity: value});
2916
+ }
2917
+ } catch(er){}
2918
+
2919
+ };
2920
+ return function(e){
2921
+ clearTimeout(timer);
2922
+ timer = setTimeout(show, !e || e.type == 'change' ? 4: 40);
2923
+ };
2924
+ })();
2925
+ data.alpha = (alpha) ? $('#'+alpha) : $([]);
2926
+
2927
+ $(data.orig).on('wsupdatevalue change', showColor).each(showColor);
2928
+ data.alpha.on('wsupdatevalue change input', showOpacity).each(showOpacity);
2929
+ return ret;
2930
+ };
3373
2931
 
3374
2932
  webshims.picker = picker;
3375
2933
  })();
@@ -3390,6 +2948,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3390
2948
  'max',
3391
2949
  'step',
3392
2950
  'title',
2951
+ 'required',
3393
2952
  'placeholder'
3394
2953
  ];
3395
2954
 
@@ -3398,11 +2957,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3398
2957
 
3399
2958
  $.each(copyProps.concat(copyAttrs), function(i, name){
3400
2959
  var fnName = name.replace(/^data\-/, '');
3401
- webshims.onNodeNamesPropertyModify('input', name, function(val){
2960
+ webshims.onNodeNamesPropertyModify('input', name, function(val, boolVal){
3402
2961
  if(!stopCircular){
3403
2962
  var shadowData = webshims.data(this, 'shadowData');
3404
2963
  if(shadowData && shadowData.data && shadowData.nativeElement === this && shadowData.data[fnName]){
3405
- shadowData.data[fnName](val);
2964
+ shadowData.data[fnName](val, boolVal);
3406
2965
  }
3407
2966
  }
3408
2967
  });
@@ -3433,6 +2992,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3433
2992
  var sizeInput = function(data){
3434
2993
  var init;
3435
2994
  var updateStyles = function(){
2995
+ $(data.orig).removeClass('ws-important-hide');
3436
2996
  $.style( data.orig, 'display', '' );
3437
2997
  var hasButtons, marginR, marginL;
3438
2998
  var correctWidth = 0.6;
@@ -3466,13 +3026,14 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3466
3026
  data.element.outerWidth( $(data.orig).outerWidth() - correctWidth );
3467
3027
  }
3468
3028
  init = true;
3469
- $.style( data.orig, 'display', 'none' );
3029
+ $(data.orig).addClass('ws-important-hide');
3470
3030
  };
3471
- $(document).onTrigger('updateshadowdom', updateStyles);
3031
+ data.element.onWSOff('updateshadowdom', updateStyles, true);
3472
3032
  };
3473
3033
 
3474
3034
 
3475
3035
  var implementType = function(){
3036
+
3476
3037
  var type = $.prop(this, 'type');
3477
3038
 
3478
3039
  var i, opts, data, optsName, labels;
@@ -3527,7 +3088,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3527
3088
  data.shim.options.containerElements.push(data.shim.element[0]);
3528
3089
 
3529
3090
  labelWidth($(this).getShadowFocusElement(), labels);
3530
- $.attr(this, 'required', $.attr(this, 'required'));
3091
+
3531
3092
  $(this).on('change', function(e){
3532
3093
  if(!stopCircular){
3533
3094
  data.shim.value($.prop(this, 'value'));
@@ -3586,18 +3147,13 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3586
3147
 
3587
3148
  if(opts.calculateWidth){
3588
3149
  sizeInput(data.shim);
3150
+ } else {
3151
+ $(this).css({display: 'none'});
3589
3152
  }
3590
- $(this).css({display: 'none'});
3591
3153
  }
3154
+
3592
3155
  };
3593
3156
 
3594
- if(!modernizrInputTypes.range || options.replaceUI){
3595
- extendType('range', {
3596
- _create: function(opts, set){
3597
- return $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
3598
- }
3599
- });
3600
- }
3601
3157
 
3602
3158
  if(Modernizr.formvalidation){
3603
3159
  ['input', 'form'].forEach(function(name){
@@ -3614,12 +3170,20 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3614
3170
  });
3615
3171
  }
3616
3172
 
3173
+ if(!modernizrInputTypes.range || options.replaceUI){
3174
+ extendType('range', {
3175
+ _create: function(opts, set){
3176
+ var data = $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
3177
+ return data;
3178
+ }
3179
+ });
3180
+ }
3617
3181
 
3618
- ['number', 'time', 'month', 'date'].forEach(function(name){
3619
- if(!modernizrInputTypes[name] || options.replaceUI){
3182
+ var isStupid = navigator.userAgent.indexOf('MSIE 10.0') != -1 && navigator.userAgent.indexOf('Touch') == -1;
3183
+ ['number', 'time', 'month', 'date', 'color'].forEach(function(name){
3184
+ if(!modernizrInputTypes[name] || options.replaceUI || (name == 'number' && isStupid)){
3620
3185
  extendType(name, {
3621
3186
  _create: function(opts, set){
3622
-
3623
3187
  if(opts.splitInput && !splitInputs[name]){
3624
3188
  webshims.warn('splitInput not supported for '+ name);
3625
3189
  opts.splitInput = false;
@@ -3627,11 +3191,12 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3627
3191
  var markup = opts.splitInput ?
3628
3192
  '<span class="ws-'+name+' ws-input" role="group"></span>' :
3629
3193
  '<input class="ws-'+name+'" type="text" />';
3630
- var data = $(markup) //role="spinbutton"???
3631
- .insertAfter(opts.orig)
3632
- .spinbtnUI(opts)
3633
- .data('wsspinner')
3634
- ;
3194
+ var data = $(markup).insertAfter(opts.orig);
3195
+ if(steps[name]){
3196
+ data = data.spinbtnUI(opts).data('wsWidget'+name);
3197
+ } else {
3198
+ data = data.wsBaseWidget(opts).data('wsWidget'+name);
3199
+ }
3635
3200
  if(webshims.picker && webshims.picker[name]){
3636
3201
  webshims.picker[name](data);
3637
3202
  }
@@ -3653,9 +3218,37 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3653
3218
  });
3654
3219
 
3655
3220
 
3656
- jQuery.webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
3221
+ webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
3657
3222
  "use strict";
3658
- var doc = document;
3223
+ var doc = document;
3224
+ var lazyLoad = function(name){
3225
+ if(!name || typeof name != 'string'){
3226
+ name = 'DOM';
3227
+ }
3228
+ if(!lazyLoad[name+'Loaded']){
3229
+ lazyLoad[name+'Loaded'] = true;
3230
+ webshims.ready(name, function(){
3231
+ webshims.loader.loadList(['form-datalist-lazy']);
3232
+ });
3233
+ }
3234
+ };
3235
+ var noDatalistSupport = {
3236
+ submit: 1,
3237
+ button: 1,
3238
+ reset: 1,
3239
+ hidden: 1,
3240
+
3241
+ range: 1,
3242
+ date: 1,
3243
+ month: 1
3244
+ };
3245
+ if(webshims.modules["form-number-date-ui"].loaded){
3246
+ $.extend(noDatalistSupport, {
3247
+ number: 1,
3248
+ time: 1
3249
+ });
3250
+ }
3251
+
3659
3252
 
3660
3253
  /*
3661
3254
  * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed)
@@ -3691,28 +3284,6 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3691
3284
  var initializeDatalist = function(){
3692
3285
 
3693
3286
 
3694
- if(!listSupport){
3695
- webshims.defineNodeNameProperty('datalist', 'options', {
3696
- prop: {
3697
- writeable: false,
3698
- get: function(){
3699
- var elem = this;
3700
- var select = $('select', elem);
3701
- var options;
3702
- if(select[0]){
3703
- options = select[0].options;
3704
- } else {
3705
- options = $('option', elem).get();
3706
- if(options.length){
3707
- webshims.warn('you should wrap your option-elements for a datalist in a select element to support IE and other old browsers.');
3708
- }
3709
- }
3710
- return options;
3711
- }
3712
- }
3713
- });
3714
- }
3715
-
3716
3287
  var inputListProto = {
3717
3288
  //override autocomplete
3718
3289
  autocomplete: {
@@ -3772,27 +3343,8 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3772
3343
  };
3773
3344
  }
3774
3345
 
3775
- if(!listSupport){
3776
-
3777
- inputListProto['list'] = {
3778
- attr: {
3779
- get: function(){
3780
- var val = webshims.contentAttr(this, 'list');
3781
- return (val == null) ? undefined : val;
3782
- },
3783
- set: function(value){
3784
- var elem = this;
3785
- webshims.contentAttr(elem, 'list', value);
3786
- webshims.objectCreate(shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
3787
- $(elem).triggerHandler('listdatalistchange');
3788
- }
3789
- },
3790
- initAttr: true,
3791
- reflect: true,
3792
- propType: 'element',
3793
- propNodeName: 'datalist'
3794
- };
3795
- } else {
3346
+
3347
+ if(listSupport){
3796
3348
  //options only return options, if option-elements are rooted: but this makes this part of HTML5 less backwards compatible
3797
3349
  if(!($('<datalist><select><option></option></select></datalist>').prop('options') || []).length ){
3798
3350
  webshims.defineNodeNameProperty('datalist', 'options', {
@@ -3812,13 +3364,15 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3812
3364
  }
3813
3365
  });
3814
3366
  }
3815
- inputListProto['list'] = {
3367
+ inputListProto.list = {
3816
3368
  attr: {
3817
3369
  get: function(){
3818
3370
  var val = webshims.contentAttr(this, 'list');
3819
3371
  if(val != null){
3820
3372
  $.data(this, 'datalistListAttr', val);
3821
- this.removeAttribute('list');
3373
+ if(!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]){
3374
+ this.removeAttribute('list');
3375
+ }
3822
3376
  } else {
3823
3377
  val = $.data(this, 'datalistListAttr');
3824
3378
  }
@@ -3828,7 +3382,15 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3828
3382
  set: function(value){
3829
3383
  var elem = this;
3830
3384
  $.data(elem, 'datalistListAttr', value);
3831
- webshims.objectCreate(shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
3385
+ if (!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]) {
3386
+ webshims.objectCreate(shadowListProto, undefined, {
3387
+ input: elem,
3388
+ id: value,
3389
+ datalist: $.prop(elem, 'list')
3390
+ });
3391
+ } else {
3392
+ elem.setAttribute('list', value);
3393
+ }
3832
3394
  $(elem).triggerHandler('listdatalistchange');
3833
3395
  }
3834
3396
  },
@@ -3848,62 +3410,14 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3848
3410
  .each(function(){
3849
3411
  $(this).triggerHandler('updateDatalist');
3850
3412
  })
3851
-
3852
3413
  ;
3853
-
3854
3414
  });
3855
-
3856
-
3857
3415
  };
3858
3416
 
3859
3417
 
3860
3418
  /*
3861
3419
  * ShadowList
3862
3420
  */
3863
- var listidIndex = 0;
3864
- var noDatalistSupport = {
3865
- submit: 1,
3866
- button: 1,
3867
- reset: 1,
3868
- hidden: 1,
3869
-
3870
- range: 1,
3871
- date: 1,
3872
- month: 1
3873
- };
3874
- if(webshims.modules["form-number-date-ui"].loaded){
3875
- $.extend(noDatalistSupport, {
3876
- number: 1,
3877
- time: 1
3878
- });
3879
- }
3880
-
3881
- var globStoredOptions = {};
3882
- var getStoredOptions = function(name){
3883
- if(!name){return [];}
3884
- if(globStoredOptions[name]){
3885
- return globStoredOptions[name];
3886
- }
3887
- var data;
3888
- try {
3889
- data = JSON.parse(localStorage.getItem('storedDatalistOptions'+name));
3890
- } catch(e){}
3891
- globStoredOptions[name] = data || [];
3892
- return data || [];
3893
- };
3894
- var storeOptions = function(name, val){
3895
- if(!name){return;}
3896
- val = val || [];
3897
- try {
3898
- localStorage.setItem( 'storedDatalistOptions'+name, JSON.stringify(val) );
3899
- } catch(e){}
3900
- };
3901
-
3902
- var getText = function(elem){
3903
- return (elem.textContent || elem.innerText || $.text([ elem ]) || '');
3904
- };
3905
- var lReg = /</g;
3906
- var gReg = />/g;
3907
3421
 
3908
3422
  var shadowListProto = {
3909
3423
  _create: function(opts){
@@ -3911,6 +3425,7 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3911
3425
  if(noDatalistSupport[$.prop(opts.input, 'type')] || noDatalistSupport[$.attr(opts.input, 'type')]){return;}
3912
3426
  var datalist = opts.datalist;
3913
3427
  var data = $.data(opts.input, 'datalistWidget');
3428
+ var that = this;
3914
3429
  if(datalist && data && data.datalist !== datalist){
3915
3430
  data.datalist = datalist;
3916
3431
  data.id = opts.id;
@@ -3931,9 +3446,8 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3931
3446
  } else if(data && data.datalist === datalist){
3932
3447
  return;
3933
3448
  }
3934
- listidIndex++;
3935
- var that = this;
3936
- this.hideList = $.proxy(that, 'hideList');
3449
+
3450
+
3937
3451
 
3938
3452
  this.datalist = datalist;
3939
3453
  this.id = opts.id;
@@ -3941,121 +3455,21 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
3941
3455
  this._autocomplete = $.attr(opts.input, 'autocomplete');
3942
3456
  $.data(opts.input, 'datalistWidget', this);
3943
3457
 
3944
- this.popover = webshims.objectCreate(webshims.wsPopover, {}, options.datalistPopover);
3945
- this.shadowList = this.popover.element.addClass('datalist-polyfill');
3946
-
3947
-
3948
- this.index = -1;
3949
- this.input = opts.input;
3950
- this.arrayOptions = [];
3951
-
3952
- this.shadowList
3953
- .delegate('li', 'mouseenter.datalistWidget mousedown.datalistWidget click.datalistWidget', function(e){
3954
- var items = $('li:not(.hidden-item)', that.shadowList);
3955
- var select = (e.type == 'mousedown' || e.type == 'click');
3956
- that.markItem(items.index(e.currentTarget), select, items);
3957
- if(e.type == 'click'){
3958
- that.hideList();
3959
- if(formsCFG.customDatalist){
3960
- $(opts.input).getNativeElement().trigger('datalistselect');
3961
- }
3962
- }
3963
- return (e.type != 'mousedown');
3964
- })
3965
- ;
3966
-
3967
- opts.input.setAttribute('autocomplete', 'off');
3968
-
3969
- $(opts.input)
3970
- .attr({
3971
- //role: 'combobox',
3972
- 'aria-haspopup': 'true'
3973
- })
3974
- .on({
3975
- 'input.datalistWidget': function(){
3976
- if(!that.triggeredByDatalist){
3977
- that.changedValue = false;
3978
- that.showHideOptions();
3979
- }
3980
- },
3981
- 'keydown.datalistWidget': function(e){
3982
- var keyCode = e.keyCode;
3983
- var activeItem;
3984
- var items;
3985
- if(keyCode == 40 && !that.showList()){
3986
- that.markItem(that.index + 1, true);
3987
- return false;
3988
- }
3989
-
3990
- if(!that.popover.isVisible){return;}
3991
-
3992
-
3993
- if(keyCode == 38){
3994
- that.markItem(that.index - 1, true);
3995
- return false;
3996
- }
3997
- if(!e.shiftKey && (keyCode == 33 || keyCode == 36)){
3998
- that.markItem(0, true);
3999
- return false;
4000
- }
4001
- if(!e.shiftKey && (keyCode == 34 || keyCode == 35)){
4002
- items = $('li:not(.hidden-item)', that.shadowList);
4003
- that.markItem(items.length - 1, true, items);
4004
- return false;
4005
- }
4006
- if(keyCode == 13 || keyCode == 27){
4007
- if (keyCode == 13){
4008
- activeItem = $('li.active-item:not(.hidden-item)', that.shadowList);
4009
- that.changeValue( $('li.active-item:not(.hidden-item)', that.shadowList) );
4010
- }
4011
- that.hideList();
4012
- if(formsCFG.customDatalist && activeItem && activeItem[0]){
4013
- $(opts.input).getNativeElement().trigger('datalistselect');
4014
- }
4015
- return false;
4016
- }
4017
- },
4018
- 'focus.datalistWidget': function(){
4019
- if($(this).hasClass('list-focus')){
4020
- that.showList();
4021
- }
4022
- },
4023
- 'mousedown.datalistWidget': function(){
4024
- if($(this).is(':focus')){
4025
- that.showList();
4026
- }
4027
- }
4028
- })
4029
- ;
4030
-
4031
-
4032
- $(this.datalist)
4033
- .off('updateDatalist.datalistWidget')
4034
- .on('updateDatalist.datalistWidget', $.proxy(this, '_resetListCached'))
4035
- ;
4036
-
4037
- this._resetListCached();
3458
+ lazyLoad('WINDOWLOAD');
4038
3459
 
4039
- if(opts.input.form && (opts.input.name || opts.input.id)){
4040
- $(opts.input.form).on('submit.datalistWidget'+opts.input.id, function(){
4041
- if(!$(opts.input).hasClass('no-datalist-cache') && that._autocomplete != 'off'){
4042
- var val = $.prop(opts.input, 'value');
4043
- var name = (opts.input.name || opts.input.id) + $.prop(opts.input, 'type');
4044
- if(!that.storedOptions){
4045
- that.storedOptions = getStoredOptions( name );
4046
- }
4047
- if(val && that.storedOptions.indexOf(val) == -1){
4048
- that.storedOptions.push(val);
4049
- storeOptions(name, that.storedOptions );
4050
- }
3460
+ if(webshims.isReady('form-datalist-lazy')){
3461
+ this._lazyCreate(opts);
3462
+ } else {
3463
+ $(opts.input).one('focus', lazyLoad);
3464
+ webshims.ready('form-datalist-lazy', function(){
3465
+ if(!that._destroyed){
3466
+ that._lazyCreate(opts);
4051
3467
  }
4052
3468
  });
4053
3469
  }
4054
- $(window).on('unload.datalist'+this.id+' beforeunload.datalist'+this.id, function(){
4055
- that.destroy();
4056
- });
4057
3470
  },
4058
- destroy: function(){
3471
+ destroy: function(e){
3472
+ var input;
4059
3473
  var autocomplete = $.attr(this.input, 'autocomplete');
4060
3474
  $(this.input)
4061
3475
  .off('.datalistWidget')
@@ -4073,268 +3487,21 @@ jQuery.webshims.register('form-datalist', function($, webshims, window, document
4073
3487
  } else {
4074
3488
  $(this.input).attr('autocomplete', autocomplete);
4075
3489
  }
4076
- },
4077
- _resetListCached: function(e){
4078
- var that = this;
4079
- var forceShow;
4080
- this.needsUpdate = true;
4081
- this.lastUpdatedValue = false;
4082
- this.lastUnfoundValue = '';
4083
-
4084
- if(!this.updateTimer){
4085
- if(window.QUnit || (forceShow = ($(that.input).is(':focus') && ($(that.input).hasClass('list-focus') || $.prop(that.input, 'value'))) )){
4086
- that.updateListOptions(forceShow);
4087
- } else {
4088
- webshims.ready('WINDOWLOAD', function(){
4089
- that.updateTimer = setTimeout(function(){
4090
- that.updateListOptions();
4091
- that = null;
4092
- listidIndex = 1;
4093
- }, 200 + (100 * listidIndex));
4094
- });
4095
- }
4096
- }
4097
- },
4098
- updateListOptions: function(_forceShow){
4099
- this.needsUpdate = false;
4100
- clearTimeout(this.updateTimer);
4101
- this.updateTimer = false;
4102
-
4103
- this.searchStart = formsCFG.customDatalist && $(this.input).hasClass('search-start');
4104
- this.addMarkElement = options.addMark || $(this.input).hasClass('mark-option-text');
4105
-
4106
- var list = [];
4107
-
4108
- var values = [];
4109
- var allOptions = [];
4110
- var rElem, rItem, rOptions, rI, rLen, item, value;
4111
- for(rOptions = $.prop(this.datalist, 'options'), rI = 0, rLen = rOptions.length; rI < rLen; rI++){
4112
- rElem = rOptions[rI];
4113
- if(!rElem.disabled && (value = $(rElem).val())){
4114
- rItem = {
4115
- value: value.replace(lReg, '&lt;').replace(gReg, '&gt;'),
4116
- label: $.trim($.attr(rElem, 'label') || getText(rElem)).replace(lReg, '&lt;').replace(gReg, '&gt;'),
4117
- className: rElem.className || ''
4118
- };
4119
-
4120
- if(rItem.label){
4121
- rItem.className += ' has-option-label';
4122
- }
4123
- values.push(rItem.value);
4124
- allOptions.push(rItem);
4125
- }
4126
- }
4127
-
4128
- if(!this.storedOptions){
4129
- this.storedOptions = ($(this.input).hasClass('no-datalist-cache') || this._autocomplete == 'off') ? [] : getStoredOptions((this.input.name || this.input.id) + $.prop(this.input, 'type'));
4130
- }
4131
-
4132
- this.storedOptions.forEach(function(val, i){
4133
- if(values.indexOf(val) == -1){
4134
- allOptions.push({value: val, label: '', className: 'stored-suggest', style: ''});
4135
- }
4136
- });
4137
-
4138
- for(rI = 0, rLen = allOptions.length; rI < rLen; rI++){
4139
- item = allOptions[rI];
4140
- list[rI] = '<li class="'+ item.className +'" tabindex="-1" role="listitem">'+ this.getOptionContent(item) +'</li>';
4141
- }
4142
-
4143
- this.arrayOptions = allOptions;
4144
- this.popover.contentElement.html('<div class="datalist-box"><ul role="list">'+ list.join("\n") +'</ul></div>');
4145
-
4146
-
4147
- if(_forceShow || this.popover.isVisible){
4148
- this.showHideOptions();
4149
- }
4150
- },
4151
- getOptionContent: function(item){
4152
- var content = '';
4153
- if(options.getOptionContent){
4154
- content = options.apply(this, arguments) || '';
4155
- } else {
4156
- content = '<span class="option-value">'+ item.value +'</span>';
4157
- if(item.label){
4158
- content += ' <span class="option-label">'+ item.label +'</span>';
4159
- }
4160
- }
4161
- return content;
4162
- },
4163
- showHideOptions: function(_fromShowList){
4164
- var value = $.prop(this.input, 'value').toLowerCase();
4165
-
4166
- //first check prevent infinite loop, second creates simple lazy optimization
4167
- if(value === this.lastUpdatedValue){
4168
- return;
4169
- }
4170
- if(this.lastUnfoundValue && value.indexOf(this.lastUnfoundValue) === 0){
4171
- this.hideList();
4172
- return;
4173
- }
4174
-
4175
-
4176
- this.lastUpdatedValue = value;
4177
- var found = false;
4178
- var startSearch = this.searchStart;
4179
- var lis = $('li', this.shadowList);
4180
- var that = this;
4181
- if(value){
4182
-
4183
- this.arrayOptions.forEach(function(item, i){
4184
- var search, searchIndex, foundName;
4185
- if(!('lowerValue' in item)){
4186
- item.lowerValue = item.value.toLowerCase();
4187
- if(item.label && item.label != item.value ){
4188
- item.lowerLabel = item.label.toLowerCase();
4189
- }
4190
- }
4191
-
4192
- if(value != item.lowerValue && item.lowerLabel != value){
4193
- searchIndex = item.lowerValue.indexOf(value);
4194
- search = startSearch ? !searchIndex : searchIndex !== -1;
4195
- if(search){
4196
- foundName = 'value';
4197
- } else if(item.lowerLabel){
4198
- searchIndex = item.lowerLabel.indexOf(value);
4199
- search = startSearch ? !searchIndex : searchIndex !== -1;
4200
- foundName = 'label';
4201
- }
4202
- }
4203
-
4204
- if(search){
4205
- that.addMark($(lis[i]).removeClass('hidden-item'), item, foundName, searchIndex, value.length);
4206
- found = true;
4207
- } else {
4208
- $(lis[i]).addClass('hidden-item');
4209
- }
4210
- });
4211
- } else if(lis.length) {
4212
- this.removeMark(lis.removeClass('hidden-item'));
4213
- found = true;
4214
- }
4215
-
4216
- this.hasViewableData = found;
4217
- if(!_fromShowList && found){
4218
- this.showList();
4219
- }
4220
-
4221
- if(!found){
4222
- this.lastUnfoundValue = value;
4223
- this.hideList();
4224
- } else {
4225
- this.lastUnfoundValue = false;
4226
- }
4227
- },
4228
- otherType: {
4229
- value: 'label',
4230
- label: 'value'
4231
- },
4232
- addMark: function(elem, item, prop, start, length){
4233
- if(this.addMarkElement){
4234
- var text = item[prop].substr(start, length);
4235
- text = item[prop].replace(text ,'<mark>'+ text +'</mark>');
4236
- $('.option-'+ this.otherType[prop] +' > mark', elem).each(this._replaceMark);
4237
- $('.option-'+prop, elem).html(text);
4238
-
4239
- }
4240
- },
4241
- _replaceMark: function(){
4242
- var content = $(this).html();
4243
- $(this).replaceWith(content);
4244
- },
4245
- removeMark: function(lis){
4246
- if(this.addMarkElement){
4247
- $('mark', lis).each(this._replaceMark);
4248
- }
4249
- },
4250
- showList: function(){
4251
- if(this.popover.isVisible){return false;}
4252
- if(this.needsUpdate){
4253
- this.updateListOptions();
4254
- }
4255
- this.showHideOptions(true);
4256
- if(!this.hasViewableData){return false;}
4257
- var that = this;
4258
-
4259
- that.shadowList.find('li.active-item').removeClass('active-item');
4260
- that.popover.show(this.input);
4261
-
4262
-
4263
- return true;
4264
- },
4265
- hideList: function(){
4266
- if(!this.popover.isVisible){return false;}
4267
- var that = this;
4268
-
4269
-
4270
- this.popover.hide();
4271
- that.shadowList.removeClass('datalist-visible list-item-active');
4272
- that.index = -1;
4273
- if(that.changedValue){
4274
- that.triggeredByDatalist = true;
4275
- $(that.input).trigger('input').trigger('change');
4276
- that.changedValue = false;
4277
- that.triggeredByDatalist = false;
4278
- }
4279
-
4280
- return true;
4281
- },
4282
- scrollIntoView: function(elem){
4283
- var ul = $('ul', this.shadowList);
4284
- var div = $('div.datalist-box', this.shadowList);
4285
- var elemPos = elem.position();
4286
- var containerHeight;
4287
- elemPos.top -= (parseInt(ul.css('paddingTop'), 10) || 0) + (parseInt(ul.css('marginTop'), 10) || 0) + (parseInt(ul.css('borderTopWidth'), 10) || 0);
4288
- if(elemPos.top < 0){
4289
- div.scrollTop( div.scrollTop() + elemPos.top - 2);
4290
- return;
4291
- }
4292
- elemPos.top += elem.outerHeight();
4293
- containerHeight = div.height();
4294
- if(elemPos.top > containerHeight){
4295
- div.scrollTop( div.scrollTop() + (elemPos.top - containerHeight) + 2);
4296
- }
4297
- },
4298
- changeValue: function(activeItem){
4299
- if(!activeItem[0]){return;}
4300
- var spinner;
4301
- var newValue = $('span.option-value', activeItem).text();
4302
- var oldValue = $.prop(this.input, 'value');
4303
- if(newValue != oldValue){
4304
-
4305
- $(this.input)
4306
- .prop('value', newValue)
4307
- .triggerHandler('updateInput')
4308
- ;
4309
- this.changedValue = true;
4310
- if((spinner = $.data(this.input, 'wsspinner')) && spinner.setInput){
4311
- spinner.setInput(newValue);
4312
- }
4313
- }
4314
- },
4315
- markItem: function(index, doValue, items){
4316
- var activeItem;
4317
- var goesUp;
4318
-
4319
- items = items || $('li:not(.hidden-item)', this.shadowList);
4320
- if(!items.length){return;}
4321
- if(index < 0){
4322
- index = items.length - 1;
4323
- } else if(index >= items.length){
4324
- index = 0;
4325
- }
4326
- items.removeClass('active-item');
4327
- this.shadowList.addClass('list-item-active');
4328
- activeItem = items.filter(':eq('+ index +')').addClass('active-item');
4329
-
4330
- if(doValue){
4331
- this.changeValue(activeItem);
4332
- this.scrollIntoView(activeItem);
3490
+ if(e && e.type == 'beforeunload'){
3491
+ input = this.input;
3492
+ setTimeout(function(){
3493
+ $.attr(input, 'list', $.attr(input, 'list'));
3494
+ }, 9);
4333
3495
  }
4334
- this.index = index;
3496
+ this._destroyed = true;
4335
3497
  }
4336
3498
  };
4337
3499
 
3500
+ webshims.loader.addModule('form-datalist-lazy', {
3501
+ noAutoCallback: true,
3502
+ options: $.extend(options, {shadowListProto: shadowListProto})
3503
+ });
3504
+
4338
3505
  //init datalist update
4339
3506
  initializeDatalist();
4340
3507
  })();