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
@@ -801,9 +801,11 @@ if((!advancedObjectProperties || !Object.create || !Object.defineProperties || !
801
801
 
802
802
 
803
803
 
804
- jQuery.webshims.register('form-number-date-api', function($, webshims, window, document, undefined){
804
+ webshims.register('form-number-date-api', function($, webshims, window, document, undefined, options){
805
805
  "use strict";
806
-
806
+ if(!webshims.addInputType){
807
+ webshims.error("you can not call forms-ext feature after calling forms feature. call both at once instead: $.webshims.polyfill('forms forms-ext')");
808
+ }
807
809
 
808
810
  if(!webshims.getStep){
809
811
  webshims.getStep = function(elem, type){
@@ -1073,7 +1075,14 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1073
1075
  minDefault: 0,
1074
1076
  maxDefault: 100
1075
1077
  },
1076
-
1078
+ color: {
1079
+ mismatch: (function(){
1080
+ var cReg = /^\u0023[a-f0-9]{6}$/;
1081
+ return function(val){
1082
+ return (!val || val.length != 7 || !(cReg.test(val)));
1083
+ };
1084
+ })()
1085
+ },
1077
1086
  date: {
1078
1087
  mismatch: function(val){
1079
1088
  if(!val || !val.split || !(/\d$/.test(val))){return true;}
@@ -1271,20 +1280,22 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1271
1280
  // }
1272
1281
  };
1273
1282
 
1274
- if(typeBugs || !supportsType('range') || !supportsType('time')){
1283
+ if(typeBugs || !supportsType('range') || !supportsType('time') || !supportsType('month')){
1275
1284
  typeProtos.range = $.extend({}, typeProtos.number, typeProtos.range);
1276
1285
  typeProtos.time = $.extend({}, typeProtos.date, typeProtos.time);
1277
1286
  typeProtos.month = $.extend({}, typeProtos.date, typeProtos.month);
1278
1287
  // typeProtos['datetime-local'] = $.extend({}, typeProtos.date, typeProtos.time, typeProtos['datetime-local']);
1279
1288
  }
1280
1289
 
1290
+
1291
+
1281
1292
  //'datetime-local'
1282
- ['number', 'month', 'range', 'date', 'time'].forEach(function(type){
1293
+ ['number', 'month', 'range', 'date', 'time', 'color'].forEach(function(type){
1283
1294
  if(typeBugs || !supportsType(type)){
1284
1295
  webshims.addInputType(type, typeProtos[type]);
1285
1296
  }
1286
1297
  });
1287
-
1298
+
1288
1299
  if($('<input />').prop('labels') == null){
1289
1300
  webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
1290
1301
  prop: {
@@ -1354,6 +1365,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1354
1365
  var oVal = val;
1355
1366
  var thumbStyle = {};
1356
1367
  var rangeStyle = {};
1368
+
1357
1369
  if(!_noNormalize && parseFloat(val, 10) != val){
1358
1370
  val = o.min + ((o.max - o.min) / 2);
1359
1371
  }
@@ -1363,6 +1375,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1363
1375
  }
1364
1376
  left = 100 * ((val - o.min) / (o.max - o.min));
1365
1377
 
1378
+ if(this._init && val == o.value && oVal == val){return;}
1366
1379
  this.options.value = val;
1367
1380
  this.thumb.stop();
1368
1381
  this.range.stop();
@@ -1432,24 +1445,30 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1432
1445
  $('.ws-range-ticks', trail).remove();
1433
1446
 
1434
1447
 
1435
- $(this.orig).jProp('list').find('option').each(function(){
1436
- o.options[$.prop(this, 'value')] = $.prop(this, 'label');
1448
+ $(this.orig).jProp('list').find('option:not([disabled])').each(function(){
1449
+ o.options[$.prop(this, 'value')] = $.prop(this, 'label') || '';
1437
1450
  });
1438
1451
 
1439
1452
  $.each(o.options, function(val, label){
1440
1453
  if(!isNumber(val) || val < min || val > max){return;}
1441
1454
  var left = 100 * ((val - min) / (max - min));
1442
- var title = o.showLabels ? ' title="'+ label +'"' : '';
1455
+ var title = o.showLabels && label ? ' title="'+ label +'"' : '';
1443
1456
  if(that.vertical){
1444
1457
  left = Math.abs(left - 100);
1445
1458
  }
1446
- trail.append('<span class="ws-range-ticks"'+ title +' style="'+(that.dirs.left)+': '+left+'%;" />');
1459
+
1460
+ that.posCenter(
1461
+ $('<span class="ws-range-ticks"'+ title +' data-label="'+label+'" style="'+(that.dirs.left)+': '+left+'%;" />').appendTo(trail)
1462
+ );
1447
1463
  });
1448
1464
  },
1449
1465
  readonly: function(val){
1450
1466
  val = !!val;
1451
1467
  this.options.readonly = val;
1452
1468
  this.element.attr('aria-readonly', ''+val);
1469
+ if(this._init){
1470
+ this.updateMetrics();
1471
+ }
1453
1472
  },
1454
1473
  disabled: function(val){
1455
1474
  val = !!val;
@@ -1459,6 +1478,9 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1459
1478
  } else {
1460
1479
  this.element.attr({tabindex: this.options.tabindex, 'aria-disabled': 'false'});
1461
1480
  }
1481
+ if(this._init){
1482
+ this.updateMetrics();
1483
+ }
1462
1484
  },
1463
1485
  tabindex: function(val){
1464
1486
  this.options.tabindex = val;
@@ -1538,6 +1560,24 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1538
1560
 
1539
1561
  return val;
1540
1562
  },
1563
+ addRemoveClass: function(cName, add){
1564
+ var isIn = this.element.prop('className').indexOf(cName) != -1;
1565
+ var action;
1566
+ if(!add && isIn){
1567
+ action = 'removeClass';
1568
+ this.element.removeClass(cName);
1569
+ this.updateMetrics();
1570
+ } else if(add && !isIn){
1571
+ action = 'addClass';
1572
+
1573
+ }
1574
+ if(action){
1575
+ this.element[action](cName);
1576
+ if(this._init){
1577
+ this.updateMetrics();
1578
+ }
1579
+ }
1580
+ },
1541
1581
  addBindings: function(){
1542
1582
  var leftOffset, widgetUnits, hasFocus;
1543
1583
  var that = this;
@@ -1577,25 +1617,36 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1577
1617
  that.value(val, false, animate);
1578
1618
  eventTimer.call('input', val);
1579
1619
  }
1620
+ if(e && e.type == 'mousemove'){
1621
+ e.preventDefault();
1622
+ }
1580
1623
  };
1581
-
1582
1624
  var remove = function(e){
1583
1625
  if(e && e.type == 'mouseup'){
1584
1626
  eventTimer.call('input', o.value);
1585
1627
  eventTimer.call('change', o.value);
1586
1628
  }
1587
- that.element.removeClass('ws-active');
1629
+ that.addRemoveClass('ws-active');
1588
1630
  $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1631
+ $(window).off('blur', removeWin);
1632
+ };
1633
+ var removeWin = function(e){
1634
+ if(e.target == window){remove();}
1589
1635
  };
1590
1636
  var add = function(e){
1637
+ var outerWidth;
1591
1638
  e.preventDefault();
1592
1639
  $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1640
+ $(window).off('blur', removeWin);
1593
1641
  if(!o.readonly && !o.disabled){
1594
- leftOffset = that.element.focus().addClass('ws-active').offset();
1595
- widgetUnits = that.element[that.dirs.width]();
1642
+ that.element.focus();
1643
+ that.addRemoveClass('ws-active', true);
1644
+ leftOffset = that.element.focus().offset();
1645
+ widgetUnits = that.element[that.dirs.innerWidth]();
1596
1646
  if(!widgetUnits || !leftOffset){return;}
1647
+ outerWidth = that.thumb[that.dirs.outerWidth]();
1597
1648
  leftOffset = leftOffset[that.dirs.pos];
1598
- widgetUnits = 100 / (widgetUnits - ((that.thumb[that.dirs.outerWidth]() || 2) / 2));
1649
+ widgetUnits = 100 / widgetUnits;
1599
1650
  setValueFromPos(e, o.animate);
1600
1651
  $(document)
1601
1652
  .on({
@@ -1603,6 +1654,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1603
1654
  mousemove: setValueFromPos
1604
1655
  })
1605
1656
  ;
1657
+ $(window).on('blur', removeWin);
1606
1658
  e.stopPropagation();
1607
1659
  }
1608
1660
  };
@@ -1612,18 +1664,20 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1612
1664
  if(!o.disabled){
1613
1665
  eventTimer.init('input', o.value);
1614
1666
  eventTimer.init('change', o.value);
1615
- that.element.addClass('ws-focus');
1667
+ that.addRemoveClass('ws-focus', true);
1668
+ that.updateMetrics();
1616
1669
  }
1617
1670
  hasFocus = true;
1618
1671
  },
1619
1672
  blur: function(e){
1620
1673
  that.element.removeClass('ws-focus ws-active');
1674
+ that.updateMetrics();
1621
1675
  hasFocus = false;
1622
1676
  eventTimer.init('input', o.value);
1623
1677
  eventTimer.call('change', o.value);
1624
1678
  },
1625
1679
  keyup: function(){
1626
- that.element.removeClass('ws-active');
1680
+ that.addRemoveClass('ws-active');
1627
1681
  eventTimer.call('input', o.value);
1628
1682
  eventTimer.call('change', o.value);
1629
1683
  },
@@ -1648,7 +1702,7 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1648
1702
  step = false;
1649
1703
  }
1650
1704
  if (step) {
1651
- that.element.addClass('ws-active');
1705
+ that.addRemoveClass('ws-active', true);
1652
1706
  eventTimer.call('input', o.value);
1653
1707
  e.preventDefault();
1654
1708
  }
@@ -1670,38 +1724,88 @@ jQuery.webshims.register('form-number-date-api', function($, webshims, window, d
1670
1724
  this.thumb.on({
1671
1725
  mousedown: add
1672
1726
  });
1727
+ $(function(){
1728
+ webshims.ready('dom-support', function(){
1729
+ that.element.onWSOff('updateshadowdom', function(){
1730
+ that.updateMetrics();
1731
+ });
1732
+ });
1733
+ if(!$.fn.onWSOff){
1734
+ webshims._polyfill(['dom-support']);
1735
+ }
1736
+ });
1737
+ },
1738
+ posCenter: function(elem, outerWidth){
1739
+ var temp;
1740
+ if(this.options.calcCenter && (!this._init || this.element[0].offsetWidth)){
1741
+ if(!elem){
1742
+ elem = this.thumb;
1743
+ }
1744
+ if(!outerWidth){
1745
+ outerWidth = elem[this.dirs.outerWidth]();
1746
+ }
1747
+ outerWidth = outerWidth / -2;
1748
+ elem.css(this.dirs.marginLeft, outerWidth);
1749
+
1750
+ if(this.options.calcTrail && elem[0] == this.thumb[0]){
1751
+ temp = this.element[this.dirs.innerHeight]();
1752
+ elem.css(this.dirs.marginTop, (elem[this.dirs.outerHeight]() - temp) / -2);
1753
+ this.range.css(this.dirs.marginTop, (this.range[this.dirs.outerHeight]() - temp) / -2 );
1754
+ outerWidth *= -1;
1755
+ this.trail
1756
+ .css(this.dirs.left, outerWidth)
1757
+ .css(this.dirs.right, outerWidth)
1758
+ ;
1759
+ }
1760
+ }
1673
1761
  },
1674
1762
  updateMetrics: function(){
1675
1763
  var width = this.element.innerWidth();
1676
1764
  this.vertical = (width && this.element.innerHeight() - width > 10);
1677
1765
 
1678
1766
  this.dirs = this.vertical ?
1679
- {mouse: 'pageY', pos: 'top', min: 'max', max: 'min', left: 'top', width: 'height', outerWidth: 'outerHeight'} :
1680
- {mouse: 'pageX', pos: 'left', min: 'min', max: 'max', left: 'left', width: 'width', outerWidth: 'outerWidth'}
1767
+ {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'} :
1768
+ {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'}
1681
1769
  ;
1682
1770
  this.element
1683
1771
  [this.vertical ? 'addClass' : 'removeClass']('vertical-range')
1684
1772
  [this.vertical ? 'addClass' : 'removeClass']('horizontal-range')
1685
1773
  ;
1774
+ this.posCenter();
1686
1775
  }
1687
1776
  };
1688
1777
 
1689
1778
  $.fn.rangeUI = function(opts){
1690
- 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);
1779
+ opts = $.extend({
1780
+ readonly: false,
1781
+ disabled: false,
1782
+ tabindex: 0,
1783
+ min: 0,
1784
+ step: 1,
1785
+ max: 100,
1786
+ value: 50,
1787
+ input: $.noop,
1788
+ change: $.noop,
1789
+ _change: $.noop,
1790
+ showLabels: true,
1791
+ options: {},
1792
+ calcCenter: true,
1793
+ calcTrail: true
1794
+ }, opts);
1691
1795
  return this.each(function(){
1692
- $.webshims.objectCreate(rangeProto, {
1796
+ webshims.objectCreate(rangeProto, {
1693
1797
  element: {
1694
1798
  value: $(this)
1695
1799
  }
1696
1800
  }, opts);
1697
1801
  });
1698
1802
  };
1699
- jQuery.webshims.isReady('range-ui', true);
1803
+ webshims.isReady('range-ui', true);
1700
1804
  })(jQuery);
1701
- jQuery.webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1805
+ webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1702
1806
  "use strict";
1703
1807
  var curCfg;
1704
- var formcfg = $.webshims.formcfg;
1808
+ var formcfg = webshims.formcfg;
1705
1809
 
1706
1810
  var stopPropagation = function(e){
1707
1811
  e.stopImmediatePropagation(e);
@@ -1719,7 +1823,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1719
1823
  date: {
1720
1824
  _create: function(){
1721
1825
  var obj = {
1722
- 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]]
1826
+ 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]]
1723
1827
  };
1724
1828
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1], $('<span class="ws-input-seperator" />')[0], obj.splits[2]];
1725
1829
  return obj;
@@ -1745,7 +1849,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1745
1849
  month: {
1746
1850
  _create: function(){
1747
1851
  var obj = {
1748
- splits: [$('<input type="text" class="yy" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
1852
+ splits: [$('<input type="text" class="yy" inputmode="numeric" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
1749
1853
  };
1750
1854
  obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1]];
1751
1855
  return obj;
@@ -1765,6 +1869,23 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1765
1869
  }
1766
1870
  }
1767
1871
  };
1872
+
1873
+ var steps = {
1874
+ number: {
1875
+ step: 1
1876
+ },
1877
+ time: {
1878
+ step: 60
1879
+ },
1880
+ month: {
1881
+ step: 1,
1882
+ start: new Date()
1883
+ },
1884
+ date: {
1885
+ step: 1,
1886
+ start: new Date()
1887
+ }
1888
+ };
1768
1889
  var labelWidth = (function(){
1769
1890
  var getId = function(){
1770
1891
  return webshims.getID(this);
@@ -1789,7 +1910,8 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1789
1910
 
1790
1911
  (function(){
1791
1912
  var monthDigits = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
1792
- formcfg.de = {
1913
+
1914
+ formcfg.de = $.extend(true, {
1793
1915
  numberFormat: {
1794
1916
  ",": ".",
1795
1917
  ".": ","
@@ -1823,9 +1945,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1823
1945
  showMonthAfterYear: false,
1824
1946
  yearSuffix: ''
1825
1947
  }
1826
- };
1948
+ }, formcfg.de || {});
1827
1949
 
1828
- formcfg.en = {
1950
+ formcfg.en = $.extend(true, {
1829
1951
  numberFormat: {
1830
1952
  ".": ".",
1831
1953
  ",": ","
@@ -1857,13 +1979,17 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1857
1979
  "showMonthAfterYear": false,
1858
1980
  "yearSuffix": ""
1859
1981
  }
1860
- };
1982
+ }, formcfg['en'] || {});
1983
+ if(!formcfg['en-US']){
1984
+ formcfg['en-US'] = formcfg['en'];
1985
+ }
1986
+ if(!formcfg['']){
1987
+ formcfg[''] = formcfg['en-US'];
1988
+ }
1861
1989
 
1862
- formcfg['en-US'] = formcfg['en-US'] || formcfg['en'];
1863
- formcfg[''] = formcfg[''] || formcfg['en-US'];
1864
1990
  curCfg = formcfg[''];
1865
1991
 
1866
- var createMonthKeys = function(langCfg){
1992
+ var processLangCFG = function(langCfg){
1867
1993
  if(!langCfg.date.monthkeys){
1868
1994
  var create = function(i, name){
1869
1995
  var strNum;
@@ -1879,24 +2005,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1879
2005
  $.each(langCfg.date.monthNames, create);
1880
2006
  $.each(langCfg.date.monthNamesShort, create);
1881
2007
  }
2008
+ if(!langCfg.colorSigns){
2009
+ langCfg.colorSigns = '#abcdefABCDEF';
2010
+ }
1882
2011
  };
1883
2012
 
1884
- createMonthKeys(curCfg);
2013
+ processLangCFG(curCfg);
1885
2014
 
1886
- $.webshims.ready('dom-extend', function(){
1887
- $.webshims.activeLang({
1888
- register: 'form-core',
1889
- callback: function(){
1890
- $.each(arguments, function(i, val){
1891
- if(formcfg[val]){
1892
- curCfg = formcfg[val];
1893
- createMonthKeys(curCfg);
1894
- $(document).triggerHandler('wslocalechange');
1895
- return false;
1896
- }
1897
- });
1898
- }
1899
- });
2015
+ $.webshims.activeLang({
2016
+ register: 'form-core',
2017
+ callback: function(){
2018
+ $.each(arguments, function(i, val){
2019
+ if(formcfg[val]){
2020
+ curCfg = formcfg[val];
2021
+ processLangCFG(curCfg);
2022
+ $(document).triggerHandler('wslocalechange');
2023
+ return false;
2024
+ }
2025
+ });
2026
+ }
1900
2027
  });
1901
2028
  })();
1902
2029
 
@@ -1916,8 +2043,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1916
2043
  return val * 1;
1917
2044
  };
1918
2045
 
1919
- var createOpts = ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value'];
1920
-
1921
2046
 
1922
2047
  var formatVal = {
1923
2048
  number: function(val){
@@ -1956,6 +2081,16 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1956
2081
  }
1957
2082
 
1958
2083
  return val;
2084
+ },
2085
+ color: function(val, opts){
2086
+ var ret = '#000000';
2087
+ if(val){
2088
+ val = val.toLowerCase();
2089
+ if(val.length == 7 && createHelper('color').isValid(val)) {
2090
+ ret = val;
2091
+ }
2092
+ }
2093
+ return ret;
1959
2094
  }
1960
2095
  };
1961
2096
 
@@ -1970,7 +2105,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
1970
2105
 
1971
2106
  var p = (!opts.splitInput) ? val.trim().split(/[\.\s-\/\\]+/) : val;
1972
2107
 
1973
- if(p.length == 2){
2108
+ if(p.length == 2 && p[0] && p[1]){
1974
2109
  p[0] = curCfg.date.monthkeys[p[0]] || p[0];
1975
2110
  p[1] = curCfg.date.monthkeys[p[1]] || p[1];
1976
2111
  if(p[1].length == 2){
@@ -2000,27 +2135,25 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2000
2135
  ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-') :
2001
2136
  ''
2002
2137
  ;
2003
- }
2004
- };
2005
-
2006
- var steps = {
2007
- number: {
2008
- step: 1
2009
- },
2010
- time: {
2011
- step: 60
2012
- },
2013
- month: {
2014
- step: 1,
2015
- start: new Date()
2016
2138
  },
2017
- date: {
2018
- step: 1,
2019
- start: new Date()
2139
+ color: function(val, opts){
2140
+ var ret = '#000000';
2141
+ if(val){
2142
+ val = val.toLowerCase();
2143
+ if (val.indexOf('#') !== 0) {
2144
+ val = '#' + val;
2145
+ }
2146
+ if(val.length == 4){
2147
+ val = '#' + val.charAt(1) + val.charAt(1) + val.charAt(2) + val.charAt(2) + val.charAt(3) + val.charAt(3);
2148
+ }
2149
+ if(val.length == 7 && createHelper('color').isValid(val)) {
2150
+ ret = val;
2151
+ }
2152
+ }
2153
+ return ret;
2020
2154
  }
2021
2155
  };
2022
2156
 
2023
-
2024
2157
  var placeholderFormat = {
2025
2158
  date: function(val, opts){
2026
2159
  var hintValue = (val || '').split('-');
@@ -2065,6 +2198,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2065
2198
  asValue: function(val){
2066
2199
  var type = (typeof val == 'object') ? 'valueAsDate' : 'valueAsNumber';
2067
2200
  return input.prop(type, val).prop('value');
2201
+ },
2202
+ isValid: function(val){
2203
+ return input.prop('value', val).is(':valid') && input.prop('value') == val;
2068
2204
  }
2069
2205
  };
2070
2206
  }
@@ -2074,211 +2210,80 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2074
2210
 
2075
2211
  steps.range = steps.number;
2076
2212
 
2077
-
2078
- var spinBtnProto = {
2213
+ var wsWidgetProto = {
2079
2214
  _create: function(){
2080
- var i;
2215
+ var i, that, timedMirror;
2081
2216
  var o = this.options;
2082
- var helper = createHelper(o.type);
2217
+ var createOpts = this.createOpts;
2218
+
2083
2219
  this.type = o.type;
2084
2220
  this.orig = o.orig;
2085
2221
 
2086
- this.elemHelper = $('<input type="'+ this.type+'" />');
2087
- this.asNumber = helper.asNumber;
2088
- this.asValue = helper.asValue;
2222
+ this.buttonWrapper = $('<span class="input-buttons '+this.type+'-input-buttons"></span>').insertAfter(this.element);
2223
+ this.options.containerElements.push(this.buttonWrapper[0]);
2089
2224
 
2090
- 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>')
2091
- .insertAfter(this.element)
2092
- ;
2225
+ o.mirrorValidity = o.mirrorValidity && this.orig && Modernizr.formvalidation && !webshims.bugs.bustedValidity;
2093
2226
 
2094
- if(o.splitInput){
2227
+ if(o.splitInput && this._addSplitInputs){
2095
2228
  this._addSplitInputs();
2096
2229
  } else {
2097
2230
  this.inputElements = this.element;
2098
2231
  }
2099
2232
 
2100
- this.options.containerElements.push(this.buttonWrapper[0]);
2101
-
2102
- if(typeof steps[this.type].start == 'object'){
2233
+ if( steps[this.type] && typeof steps[this.type].start == 'object'){
2103
2234
  steps[this.type].start = this.asNumber(steps[this.type].start);
2104
2235
  }
2105
2236
 
2106
-
2107
-
2108
2237
  for(i = 0; i < createOpts.length; i++){
2109
- this[createOpts[i]](o[createOpts[i]]);
2110
- }
2111
-
2112
- this.element.data('wsspinner', this);
2113
-
2114
- this.addBindings();
2115
-
2116
- if(!o.min && typeof o.relMin == 'number'){
2117
- o.min = this.asValue(this.getRelNumber(o.relMin));
2118
- $.prop(this.orig, 'min', o.min);
2238
+ if(o[createOpts[i]] != null){
2239
+ this[createOpts[i]](o[createOpts[i]], o[createOpts[i]]);
2240
+ }
2119
2241
  }
2120
-
2121
- if(!o.max && typeof o.relMax == 'number'){
2122
- o.max = this.asValue(this.getRelNumber(o.relMax));
2123
- $.prop(this.orig, 'max', o.max);
2242
+ if(this.type == 'color'){
2243
+ this.inputElements.prop('maxLength', 7);
2124
2244
  }
2245
+ this.addBindings();
2246
+ $(this.element).data('wsWidget'+o.type, this);
2125
2247
 
2126
2248
  this._init = true;
2127
- },
2128
- _addSplitInputs: function(){
2129
- if(!this.inputElements){
2130
- var create = splitInputs[this.type]._create();
2131
- this.splits = create.splits;
2132
- this.inputElements = $(create.elements).prependTo(this.element).filter('input');
2133
- }
2134
- },
2135
- parseValue: function(){
2136
- var value = this.inputElements.map(function(){
2137
- return $.prop(this, 'value');
2138
- }).get();
2139
- if(!this.options.splitInput){
2140
- value = value[0];
2141
- }
2142
- return parseVal[this.type](value, this.options);
2143
- },
2144
- formatValue: function(val, noSplit){
2145
- return formatVal[this.type](val, noSplit === false ? false : this.options);
2146
- },
2147
- placeholder: function(val){
2148
- var options = this.options;
2149
- options.placeholder = val;
2150
- var placeholder = val;
2151
- if(placeholderFormat[this.type]){
2152
- placeholder = placeholderFormat[this.type](val, this.options);
2153
- }
2154
- if(options.splitInput && typeof placeholder == 'object'){
2155
- $.each(this.splits, function(i, elem){
2156
- $.prop(elem, 'placeholder', placeholder[i]);
2157
- });
2158
- } else {
2159
- this.element.prop('placeholder', placeholder);
2160
- }
2161
- },
2162
- getRelNumber: function(rel){
2163
- var start = steps[this.type].start || 0;
2164
- if(rel){
2165
- start += rel;
2166
- }
2167
- return start;
2168
- },
2169
- addZero: addZero,
2170
- _setStartInRange: function(){
2171
- var start = this.getRelNumber(this.options.relDefaultValue);
2172
- if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
2173
- start = this.minAsNumber;
2174
- } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
2175
- start = this.maxAsNumber;
2176
- }
2177
- this.elemHelper.prop('valueAsNumber', start);
2178
- this.options.defValue = this.elemHelper.prop('value');
2179
-
2180
- },
2181
- reorderInputs: function(){
2182
- if(splitInputs[this.type]){
2183
- var element = this.element;
2184
- splitInputs[this.type].sort(element);
2185
- setTimeout(function(){
2186
- var data = webshims.data(element);
2187
- if(data && data.shadowData){
2188
- data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
2189
- }
2190
- }, 9);
2191
- }
2192
- },
2193
- value: function(val){
2194
- this.valueAsNumber = this.asNumber(val);
2195
- this.options.value = val;
2196
- if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
2197
- this._setStartInRange();
2198
- } else {
2199
- this.elemHelper.prop('value', val);
2200
- this.options.defValue = "";
2201
- }
2202
2249
 
2203
- val = formatVal[this.type](val, this.options);
2204
- if(this.options.splitInput){
2250
+ if(o.mirrorValidity){
2251
+ that = this;
2252
+ timedMirror = function(){
2253
+ clearTimeout(timedMirror._timerDealy);
2254
+ timedMirror._timerDealy = setTimeout(timedMirror._wsexec, 9);
2255
+ };
2256
+ timedMirror._wsexec = function(){
2257
+ clearTimeout(timedMirror._timerDealy);
2258
+ that.mirrorValidity(true);
2259
+ };
2205
2260
 
2206
- $.each(this.splits, function(i, elem){
2207
- $.prop(elem, 'value', val[i]);
2208
- });
2209
- } else {
2210
- this.element.prop('value', val);
2211
- }
2212
-
2213
- this._propertyChange('value');
2214
- },
2215
- initDataList: function(){
2216
- var listTimer;
2217
- var that = this;
2218
- var updateList = function(){
2219
- $(that.orig)
2220
- .jProp('list')
2221
- .off('updateDatalist', updateList)
2222
- .on('updateDatalist', updateList)
2223
- ;
2224
- clearTimeout(listTimer);
2225
- listTimer = setTimeout(function(){
2226
- if(that.list){
2227
- that.list();
2261
+ timedMirror();
2262
+ $(this.orig).on('change input', function(e){
2263
+ if(e.type == 'input'){
2264
+ timedMirror();
2265
+ } else {
2266
+ timedMirror._wsexec();
2228
2267
  }
2229
- }, 9);
2230
-
2231
- };
2232
-
2233
- $(this.orig).onTrigger('listdatalistchange', updateList);
2234
- },
2235
- getOptions: function(){
2236
- var options = {};
2237
- var datalist = $(this.orig).jProp('list');
2238
- datalist.find('option').each(function(){
2239
- options[$.prop(this, 'value')] = $.prop(this, 'label');
2240
- });
2241
- return [options, datalist.data('label')];
2242
- },
2243
- list: function(val){
2244
- if(this.type == 'number' || this.type == 'time'){
2245
- this.element.attr('list', $.attr(this.orig, 'list'));
2246
- }
2247
- this.options.list = val;
2248
- this._propertyChange('list');
2249
- },
2250
- _propertyChange: $.noop,
2251
- tabindex: function(val){
2252
- this.options.tabindex = val;
2253
- this.inputElements.prop('tabindex', this.options.tabindex);
2254
- },
2255
- title: function(val){
2256
- this.options.title = val;
2257
- this.element.prop('title', this.options.title);
2258
- },
2259
-
2260
- min: function(val){
2261
- this.elemHelper.prop('min', val);
2262
- this.minAsNumber = this.asNumber(val);
2263
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
2264
- this._setStartInRange();
2268
+ });
2265
2269
  }
2266
- this.options.min = val;
2267
- this._propertyChange('min');
2268
2270
  },
2269
- max: function(val){
2270
- this.elemHelper.prop('max', val);
2271
- this.maxAsNumber = this.asNumber(val);
2272
- if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
2273
- this._setStartInRange();
2271
+ mirrorValidity: function(_noTest){
2272
+ //
2273
+ if(this._init && this.options.mirrorValidity){
2274
+ if(!_noTest){
2275
+ $.prop(this.orig, 'validity');
2276
+ }
2277
+ var message = $(this.orig).getErrorMessage();
2278
+ if(message !== this.lastErrorMessage){
2279
+ this.inputElements.prop('setCustomValidity', function(i, val){
2280
+ if(val._supvalue){
2281
+ val._supvalue.call(this, message);
2282
+ }
2283
+ });
2284
+ this.lastErrorMessage = message;
2285
+ }
2274
2286
  }
2275
- this.options.max = val;
2276
- this._propertyChange('max');
2277
- },
2278
- step: function(val){
2279
- var defStep = steps[this.type];
2280
- this.options.step = val;
2281
- this.elemHelper.prop('step', retDefault(val, defStep.step));
2282
2287
  },
2283
2288
  addBindings: function(){
2284
2289
  var isFocused;
@@ -2331,6 +2336,9 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2331
2336
  var val;
2332
2337
  clearTimeout(timer);
2333
2338
  val = that.parseValue();
2339
+ if(that.type == 'color'){
2340
+ that.inputElements.val(val);
2341
+ }
2334
2342
  $.prop(that.orig, 'value', val);
2335
2343
  eventTimer.call('input', val);
2336
2344
  if(!e || e.type != 'wsupdatevalue'){
@@ -2367,6 +2375,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2367
2375
  ;
2368
2376
  setTimeout(function(){
2369
2377
  if(that.popover){
2378
+ that.popover.element.on('wspopoverhide', onBlur);
2370
2379
  $('> *', that.popover.element)
2371
2380
  .on({
2372
2381
  'focusin': onFocus,
@@ -2447,7 +2456,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2447
2456
  e.preventDefault();
2448
2457
  }
2449
2458
  }
2450
- }
2459
+ };
2451
2460
  })()
2452
2461
  };
2453
2462
  var mouseDownInit = function(){
@@ -2471,28 +2480,6 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2471
2480
  };
2472
2481
  })();
2473
2482
 
2474
- ['stepUp', 'stepDown'].forEach(function(name){
2475
- step[name] = function(factor){
2476
- if(!o.disabled && !o.readonly){
2477
- if(!isFocused){
2478
- mouseDownInit();
2479
- }
2480
- var ret = false;
2481
- if (!factor) {
2482
- factor = 1;
2483
- }
2484
- try {
2485
- that.elemHelper[name](factor);
2486
- ret = that.elemHelper.prop('value');
2487
- that.value(ret);
2488
- eventTimer.call('input', ret);
2489
- } catch (er) {}
2490
- return ret;
2491
- }
2492
- };
2493
- });
2494
-
2495
-
2496
2483
 
2497
2484
  this.buttonWrapper.on('mousedown', mouseDownInit);
2498
2485
 
@@ -2509,960 +2496,415 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
2509
2496
 
2510
2497
  this.inputElements.on(elementEvts);
2511
2498
 
2512
- if(!o.noSpinbtn){
2513
- spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
2514
- if(delta && isFocused && !o.disabled){
2515
- step[delta > 0 ? 'stepUp' : 'stepDown']();
2516
- e.preventDefault();
2517
- }
2518
- };
2519
- spinEvents.keydown = function(e){
2520
- if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
2521
- var stepped = true;
2522
- var code = e.keyCode;
2523
- if (code == 38) {
2524
- step.stepUp();
2525
- } else if (code == 40) {
2526
- step.stepDown();
2527
- } else {
2528
- stepped = false;
2529
- }
2530
- if(stepped){
2531
- e.preventDefault();
2532
- }
2533
- };
2534
-
2535
- spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
2536
- }
2537
-
2538
-
2539
- if(!o.splitInput){
2540
- $(document).on('wslocalechange',function(){
2541
- if(o.value){
2542
- that.value(o.value);
2543
- }
2544
-
2545
- if(placeholderFormat[that.type] && o.placeholder){
2546
- that.placeholder(o.placeholder);
2547
- }
2548
- });
2549
- } else {
2550
- $(document).onTrigger('wslocalechange',function(){
2551
- that.reorderInputs();
2499
+ if(steps[this.type]){
2500
+ ['stepUp', 'stepDown'].forEach(function(name){
2501
+ step[name] = function(factor){
2502
+ if(!o.disabled && !o.readonly){
2503
+ if(!isFocused){
2504
+ mouseDownInit();
2505
+ }
2506
+ var ret = false;
2507
+ if (!factor) {
2508
+ factor = 1;
2509
+ }
2510
+ try {
2511
+ that.elemHelper[name](factor);
2512
+ ret = that.elemHelper.prop('value');
2513
+ that.value(ret);
2514
+ eventTimer.call('input', ret);
2515
+ } catch (er) {}
2516
+ return ret;
2517
+ }
2518
+ };
2552
2519
  });
2553
- }
2554
-
2555
- $('.step-up', this.buttonWrapper)
2556
- .on({
2557
- 'mousepressstart mousepressend': mousePress,
2558
- 'mousedown mousepress': function(e){
2559
- step.stepUp();
2560
- }
2561
- })
2562
- ;
2563
- $('.step-down', this.buttonWrapper)
2564
- .on({
2565
- 'mousepressstart mousepressend': mousePress,
2566
- 'mousedown mousepress': function(e){
2567
- step.stepDown();
2568
- }
2569
- })
2570
- ;
2571
- initChangeEvents();
2572
- }
2573
- };
2574
-
2575
- ['readonly', 'disabled'].forEach(function(name){
2576
- spinBtnProto[name] = function(val){
2577
- if(this.options[name] != val || !this._init){
2578
- this.options[name] = !!val;
2579
- if(name == 'readonly' && this.options.noInput){
2580
- this.element
2581
- .prop(name, true)
2582
- .attr({'aria-readonly': this.options[name]})
2583
- ;
2584
- } else {
2585
- this.element.prop(name, this.options[name]);
2520
+ if(!o.noSpinbtn){
2521
+ spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
2522
+ if(delta && isFocused && !o.disabled){
2523
+ step[delta > 0 ? 'stepUp' : 'stepDown']();
2524
+ e.preventDefault();
2525
+ }
2526
+ };
2527
+ spinEvents.keydown = function(e){
2528
+ if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
2529
+ var stepped = true;
2530
+ var code = e.keyCode;
2531
+ if (code == 38) {
2532
+ step.stepUp();
2533
+ } else if (code == 40) {
2534
+ step.stepDown();
2535
+ } else {
2536
+ stepped = false;
2537
+ }
2538
+ if(stepped){
2539
+ e.preventDefault();
2540
+ }
2541
+ };
2542
+
2543
+ spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
2586
2544
  }
2587
- this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
2545
+ $(this.buttonWrapper)
2546
+ .on('mousepressstart mousepressend', '.step-up, .step-down', mousePress)
2547
+ .on('mousedown mousepress', '.step-up', function(e){
2548
+ step.stepUp();
2549
+ })
2550
+ .on('mousedown mousepress', '.step-down', function(e){
2551
+ step.stepDown();
2552
+ })
2553
+ ;
2588
2554
  }
2589
- };
2590
- });
2591
-
2592
-
2593
- $.fn.spinbtnUI = function(opts){
2594
- opts = $.extend({
2595
- monthNames: 'monthNames',
2596
- size: 1,
2597
- startView: 0
2598
- }, opts);
2599
- return this.each(function(){
2600
- $.webshims.objectCreate(spinBtnProto, {
2601
- element: {
2602
- value: $(this)
2603
- }
2604
- }, opts);
2605
- });
2606
- };
2607
- })();
2608
-
2609
- (function(){
2610
- var picker = {};
2611
- var disable = {
2612
-
2613
- };
2614
-
2615
- var getDateArray = function(date){
2616
- var ret = [date.getFullYear(), addZero(date.getMonth() + 1), addZero(date.getDate())];
2617
- ret.month = ret[0]+'-'+ret[1];
2618
- ret.date = ret[0]+'-'+ret[1]+'-'+ret[2];
2619
- return ret;
2620
- };
2621
- var today = getDateArray(new Date());
2555
+ if(this.type != 'color'){
2556
+ (function(){
2557
+ var localeChange ;
2558
+ if(!o.splitInput){
2559
+ localeChange = function(){
2560
+ if(o.value){
2561
+ that.value(o.value);
2562
+ }
2622
2563
 
2623
- var _setFocus = function(element, _noFocus){
2624
- var setFocus, that;
2625
- element = $(element || this.activeButton);
2626
- this.activeButton.attr({tabindex: '-1', 'aria-selected': 'false'});
2627
- this.activeButton = element.attr({tabindex: '0', 'aria-selected': 'true'});
2628
- this.index = this.buttons.index(this.activeButton[0]);
2629
-
2630
- clearTimeout(this.timer);
2631
-
2632
- if(!this.popover.openedByFocus && !_noFocus){
2633
- that = this;
2634
- setFocus = function(noTrigger){
2635
- clearTimeout(that.timer);
2636
- that.timer = setTimeout(function(){
2637
- if(element[0]){
2638
- element[0].focus();
2639
- if(noTrigger !== true && !element.is(':focus')){
2640
- setFocus(true);
2641
- }
2564
+ if(placeholderFormat[that.type] && o.placeholder){
2565
+ that.placeholder(o.placeholder);
2566
+ }
2567
+ };
2568
+ } else {
2569
+ localeChange = function(){
2570
+ that.reorderInputs();
2571
+ };
2572
+ that.reorderInputs();
2642
2573
  }
2643
- }, that.popover.isVisible ? 99 : 360);
2644
- };
2645
- this.popover.activateElement(element);
2646
- setFocus();
2647
- }
2648
-
2649
- };
2650
-
2651
- var _initialFocus = function(){
2652
- var sel;
2653
- if(this.popover.navedInitFocus){
2654
- sel = this.popover.navedInitFocus.sel || this.popover.navedInitFocus;
2655
- if((!this.activeButton || !this.activeButton[0]) && this.buttons[sel]){
2656
- this.activeButton = this.buttons[sel]();
2657
- } else if(sel){
2658
- this.activeButton = $(sel, this.element);
2574
+ $(that.orig).onWSOff('wslocalechange', localeChange);
2575
+ })();
2659
2576
  }
2660
2577
 
2661
- if(!this.activeButton[0] && this.popover.navedInitFocus.alt){
2662
- this.activeButton = this.buttons[this.popover.navedInitFocus.alt]();
2578
+ initChangeEvents();
2579
+ },
2580
+ value: function(val){
2581
+ if(!this._init || val !== this.options.value){
2582
+ this.element.val(this.formatValue(val));
2583
+ this.options.value = val;
2584
+ this._propertyChange('value');
2585
+ this.mirrorValidity();
2663
2586
  }
2664
- }
2665
-
2666
- if(!this.activeButton || !this.activeButton[0]){
2667
- this.activeButton = this.buttons.filter('.checked-value');
2668
- }
2669
-
2670
- if(!this.activeButton[0]){
2671
- this.activeButton = this.buttons.filter('.this-value');
2672
- }
2673
- if(!this.activeButton[0]){
2674
- this.activeButton = this.buttons.eq(0);
2675
- }
2676
-
2677
- this.setFocus(this.activeButton, this.opts.noFocus);
2678
- };
2679
-
2680
-
2681
- webshims.ListBox = function (element, popover, opts){
2682
- this.element = $('ul', element);
2683
- this.popover = popover;
2684
- this.opts = opts || {};
2685
- this.buttons = $('button:not(:disabled)', this.element);
2686
-
2687
-
2688
- this.ons(this);
2689
- this._initialFocus();
2690
- };
2691
-
2692
- webshims.ListBox.prototype = {
2693
- setFocus: _setFocus,
2694
- _initialFocus: _initialFocus,
2695
- prev: function(){
2696
- var index = this.index - 1;
2697
- if(index < 0){
2698
- if(this.opts.prev){
2699
- this.popover.navedInitFocus = 'last';
2700
- this.popover.actionFn(this.opts.prev);
2701
- this.popover.navedInitFocus = false;
2702
- }
2703
- } else {
2704
- this.setFocus(this.buttons.eq(index));
2587
+
2588
+ },
2589
+ required: function(val, boolVal){
2590
+ this.inputElements.attr({'aria-required': ''+boolVal});
2591
+ this.mirrorValidity();
2592
+ },
2593
+ parseValue: function(){
2594
+ var value = this.inputElements.map(function(){
2595
+ return $.prop(this, 'value');
2596
+ }).get();
2597
+ if(!this.options.splitInput){
2598
+ value = value[0];
2705
2599
  }
2600
+ return parseVal[this.type](value, this.options);
2706
2601
  },
2707
- next: function(){
2708
- var index = this.index + 1;
2709
- if(index >= this.buttons.length){
2710
- if(this.opts.next){
2711
- this.popover.navedInitFocus = 'first';
2712
- this.popover.actionFn(this.opts.next);
2713
- this.popover.navedInitFocus = false;
2714
- }
2602
+ formatValue: function(val, noSplit){
2603
+ return formatVal[this.type](val, noSplit === false ? false : this.options);
2604
+ },
2605
+ createOpts: ['readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
2606
+ placeholder: function(val){
2607
+ var options = this.options;
2608
+ options.placeholder = val;
2609
+ var placeholder = val;
2610
+ if(placeholderFormat[this.type]){
2611
+ placeholder = placeholderFormat[this.type](val, this.options);
2612
+ }
2613
+ if(options.splitInput && typeof placeholder == 'object'){
2614
+ $.each(this.splits, function(i, elem){
2615
+ $.prop(elem, 'placeholder', placeholder[i]);
2616
+ });
2715
2617
  } else {
2716
- this.setFocus(this.buttons.eq(index));
2618
+ this.element.prop('placeholder', placeholder);
2717
2619
  }
2718
2620
  },
2719
- ons: function(that){
2720
- this.element
2721
- .on({
2722
- 'keydown': function(e){
2723
- var handled;
2724
- var key = e.keyCode;
2725
- if(e.ctrlKey){return;}
2726
- if(key == 36 || key == 33){
2727
- that.setFocus(that.buttons.eq(0));
2728
- handled = true;
2729
- } else if(key == 34 || key == 35){
2730
- that.setFocus(that.buttons.eq(that.buttons.length - 1));
2731
- handled = true;
2732
- } else if(key == 38 || key == 37){
2733
- that.prev();
2734
- handled = true;
2735
- } else if(key == 40 || key == 39){
2736
- that.next();
2737
- handled = true;
2738
- }
2739
- if(handled){
2740
- return false;
2741
- }
2621
+ initDataList: function(){
2622
+ var listTimer;
2623
+ var that = this;
2624
+ var updateList = function(){
2625
+ $(that.orig)
2626
+ .jProp('list')
2627
+ .off('updateDatalist', updateList)
2628
+ .on('updateDatalist', updateList)
2629
+ ;
2630
+ clearTimeout(listTimer);
2631
+ listTimer = setTimeout(function(){
2632
+ if(that.list){
2633
+ that.list();
2742
2634
  }
2743
- })
2744
- ;
2745
- }
2746
- };
2747
-
2748
- webshims.Grid = function (element, popover, opts){
2749
- this.element = $('tbody', element);
2750
- this.popover = popover;
2751
- this.opts = opts || {};
2752
- this.buttons = $('button:not(:disabled,.othermonth)', this.element);
2753
-
2754
- this.ons(this);
2755
-
2756
- this._initialFocus();
2757
- if(this.popover.openedByFocus){
2758
- this.popover.activeElement = this.activeButton;
2759
- }
2760
- };
2761
-
2762
-
2763
-
2764
- webshims.Grid.prototype = {
2765
- setFocus: _setFocus,
2766
- _initialFocus: _initialFocus,
2767
-
2768
- first: function(){
2769
- this.setFocus(this.buttons.eq(0));
2635
+ }, 9);
2636
+
2637
+ };
2638
+
2639
+ $(this.orig).onTrigger('listdatalistchange', updateList);
2770
2640
  },
2771
- last: function(){
2772
- this.setFocus(this.buttons.eq(this.buttons.length - 1));
2641
+ getOptions: function(){
2642
+ var options = {};
2643
+ var datalist = $(this.orig).jProp('list');
2644
+ datalist.find('option').each(function(){
2645
+ options[$.prop(this, 'value')] = $.prop(this, 'label');
2646
+ });
2647
+ return [options, datalist.data('label')];
2773
2648
  },
2774
- upPage: function(){
2775
- $('.ws-picker-header > button:not(:disabled)', this.popover.element).trigger('click');
2649
+ list: function(val){
2650
+ if(this.type == 'number' || this.type == 'time'){
2651
+ this.element.attr('list', $.attr(this.orig, 'list'));
2652
+ }
2653
+ this.options.list = val;
2654
+ this._propertyChange('list');
2776
2655
  },
2777
- downPage: function(){
2778
- this.activeButton.filter(':not([data-action="changeInput"])').trigger('click');
2656
+ _propertyChange: $.noop,
2657
+ tabindex: function(val){
2658
+ this.options.tabindex = val;
2659
+ this.inputElements.prop('tabindex', this.options.tabindex);
2660
+ $('button', this.buttonWrapper).prop('tabindex', this.options.tabindex);
2779
2661
  },
2780
- ons: function(that){
2781
- this.element
2782
- .on({
2783
- 'keydown': function(e){
2784
- var handled;
2785
- var key = e.keyCode;
2786
-
2787
- if(e.shiftKey){return;}
2788
-
2789
- if((e.ctrlKey && key == 40)){
2790
- handled = 'downPage';
2791
- } else if((e.ctrlKey && key == 38)){
2792
- handled = 'upPage';
2793
- } else if(key == 33 || (e.ctrlKey && key == 37)){
2794
- handled = 'prevPage';
2795
- } else if(key == 34 || (e.ctrlKey && key == 39)){
2796
- handled = 'nextPage';
2797
- } else if(e.keyCode == 36 || e.keyCode == 33){
2798
- handled = 'first';
2799
- } else if(e.keyCode == 35){
2800
- handled = 'last';
2801
- } else if(e.keyCode == 38){
2802
- handled = 'up';
2803
- } else if(e.keyCode == 37){
2804
- handled = 'prev';
2805
- } else if(e.keyCode == 40){
2806
- handled = 'down';
2807
- } else if(e.keyCode == 39){
2808
- handled = 'next';
2809
- }
2810
- if(handled){
2811
- that[handled]();
2812
- return false;
2813
- }
2814
- }
2815
- })
2816
- ;
2817
- }
2818
- };
2819
- $.each({
2820
- prevPage: {get: 'last', action: 'prev'},
2821
- nextPage: {get: 'first', action: 'next'}
2822
- }, function(name, val){
2823
- webshims.Grid.prototype[name] = function(){
2824
- if(this.opts[val.action]){
2825
- this.popover.navedInitFocus = {
2826
- sel: 'button[data-id="'+ this.activeButton.attr('data-id') +'"]:not(:disabled,.othermonth)',
2827
- alt: val.get
2828
- };
2829
- this.popover.actionFn(this.opts[val.action]);
2830
- this.popover.navedInitFocus = false;
2831
- }
2832
- };
2833
- });
2834
-
2835
- $.each({
2836
- up: {traverse: 'prevAll', get: 'last', action: 'prev', reverse: true},
2837
- down: {traverse: 'nextAll', get: 'first', action: 'next'}
2838
- }, function(name, val){
2839
- webshims.Grid.prototype[name] = function(){
2840
- var cellIndex = this.activeButton.closest('td').prop('cellIndex');
2841
- var sel = 'td:nth-child('+(cellIndex + 1)+') button:not(:disabled,.othermonth)';
2842
- var button = this.activeButton.closest('tr')[val.traverse]();
2843
-
2844
- if(val.reverse){
2845
- button = $(button.get().reverse());
2846
- }
2847
- button = button.find(sel)[val.get]();
2848
-
2849
- if(!button[0]){
2850
- if(this.opts[val.action]){
2851
- this.popover.navedInitFocus = sel+':'+val.get;
2852
- this.popover.actionFn(this.opts[val.action]);
2853
- this.popover.navedInitFocus = false;
2854
- }
2855
- } else {
2856
- this.setFocus(button.eq(0));
2857
- }
2858
- };
2859
- });
2860
-
2861
- $.each({
2862
- prev: {traverse: 'prevAll',get: 'last', reverse: true},
2863
- next: {traverse: 'nextAll', get: 'first'}
2864
- }, function(name, val){
2865
- webshims.Grid.prototype[name] = function(){
2866
- var sel = 'button:not(:disabled,.othermonth)';
2867
- var button = this.activeButton.closest('td')[val.traverse]('td');
2868
- if(val.reverse){
2869
- button = $(button.get().reverse());
2870
- }
2871
- button = button.find(sel)[val.get]();
2872
- if(!button[0]){
2873
- button = this.activeButton.closest('tr')[val.traverse]('tr');
2874
- if(val.reverse){
2875
- button = $(button.get().reverse());
2876
- }
2877
- button = button.find(sel)[val.get]();
2662
+ title: function(val){
2663
+ if(!val && this.orig && $.attr(this.orig, 'title') == null){
2664
+ val = null;
2878
2665
  }
2879
-
2880
- if(!button[0]){
2881
- if(this.opts[name]){
2882
- this.popover.navedInitFocus = val.get;
2883
- this.popover.actionFn(this.opts[name]);
2884
- this.popover.navedInitFocus = false;
2885
- }
2666
+ this.options.title = val;
2667
+ if(val == null){
2668
+ this.inputElements.removeAttr('title');
2886
2669
  } else {
2887
- this.setFocus(button.eq(0));
2888
- }
2889
- };
2890
- });
2891
-
2892
- picker.getWeek = function(date){
2893
- var onejan = new Date(date.getFullYear(),0,1);
2894
- return Math.ceil((((date - onejan) / 86400000) + onejan.getDay()+1)/7);
2895
- };
2896
- picker.getYearList = function(value, data){
2897
- var j, i, val, disabled, lis, prevDisabled, nextDisabled, classStr, classArray, start;
2898
-
2899
-
2900
- var size = data.options.size;
2901
- var max = data.options.max.split('-');
2902
- var min = data.options.min.split('-');
2903
- var currentValue = data.options.value.split('-');
2904
- var xthCorrect = 0;
2905
- var enabled = 0;
2906
- var str = '';
2907
- var rowNum = 0;
2908
-
2909
- if(data.options.useDecadeBase == 'max' && max[0]){
2910
- xthCorrect = 11 - (max[0] % 12);
2911
- } else if(data.options.useDecadeBase == 'min' && min[0]){
2912
- xthCorrect = 11 - (min[0] % 12);
2913
- }
2914
-
2915
- value = value[0] * 1;
2916
- start = value - ((value + xthCorrect) % (12 * size));
2917
-
2918
-
2919
-
2920
- for(j = 0; j < size; j++){
2921
- if(j){
2922
- start += 12;
2923
- } else {
2924
- prevDisabled = picker.isInRange([start-1], max, min) ? {'data-action': 'setYearList','value': start-1} : false;
2925
- }
2926
-
2927
- str += '<div class="year-list picker-list ws-index-'+ j +'"><div class="ws-picker-header"><button disabled="disabled">'+ start +' – '+(start + 11)+'</button></div>';
2928
- lis = [];
2929
- for(i = 0; i < 12; i++){
2930
- val = start + i ;
2931
- classArray = [];
2932
- if( !picker.isInRange([val], max, min) ){
2933
- disabled = ' disabled=""';
2934
- } else {
2935
- disabled = '';
2936
- enabled++;
2937
- }
2938
-
2939
- if(val == today[0]){
2940
- classArray.push('this-value');
2941
- }
2942
-
2943
- if(currentValue[0] == val){
2944
- classArray.push('checked-value');
2945
- }
2946
-
2947
- classStr = classArray.length ? ' class="'+ (classArray.join(' ')) +'"' : '';
2948
-
2949
- if(i && !(i % 3)){
2950
- rowNum++;
2951
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2952
- }
2953
- 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>');
2670
+ this.inputElements.prop('title', this.options.title);
2954
2671
  }
2955
- if(j == size - 1){
2956
- nextDisabled = picker.isInRange([val+1], max, min) ? {'data-action': 'setYearList','value': val+1} : false;
2957
- }
2958
- 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>';
2959
2672
  }
2960
-
2961
- return {
2962
- enabled: enabled,
2963
- main: str,
2964
- next: nextDisabled,
2965
- prev: prevDisabled,
2966
- type: 'Grid'
2967
- };
2968
2673
  };
2969
2674
 
2970
2675
 
2971
- picker.getMonthList = function(value, data){
2972
-
2973
- var j, i, name, val, disabled, lis, fullyDisabled, prevDisabled, nextDisabled, classStr, classArray;
2974
- var o = data.options;
2975
- var size = o.size;
2976
- var max = o.max.split('-');
2977
- var min = o.min.split('-');
2978
- var currentValue = o.value.split('-');
2979
- var enabled = 0;
2980
- var rowNum = 0;
2981
- var str = '';
2982
-
2983
- value = value[0] - Math.floor((size - 1) / 2);
2984
- for(j = 0; j < size; j++){
2985
- if(j){
2986
- value++;
2987
- } else {
2988
- prevDisabled = picker.isInRange([value-1], max, min) ? {'data-action': 'setMonthList','value': value-1} : false;
2989
- }
2990
- if(j == size - 1){
2991
- nextDisabled = picker.isInRange([value+1], max, min) ? {'data-action': 'setMonthList','value': value+1} : false;
2992
- }
2993
- lis = [];
2994
-
2995
- if( !picker.isInRange([value, '01'], max, min) && !picker.isInRange([value, '12'], max, min)){
2996
- disabled = ' disabled=""';
2997
- fullyDisabled = true;
2998
- } else {
2999
- fullyDisabled = false;
3000
- disabled = '';
3001
- }
3002
-
3003
- if(o.minView >= 1){
3004
- disabled = ' disabled=""';
3005
- }
3006
-
3007
- str += '<div class="month-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">';
3008
-
3009
- str += o.selectNav ?
3010
- '<select data-action="setMonthList" class="year-select">'+ picker.createYearSelect(value, max, min).join('') +'</select>' :
3011
- '<button data-action="setYearList"'+disabled+' value="'+ value +'" tabindex="-1">'+ value +'</button>';
3012
- str += '</div>';
3013
-
3014
- for(i = 0; i < 12; i++){
3015
- val = curCfg.date.monthkeys[i+1];
3016
- name = (curCfg.date[o.monthNames] || curCfg.date.monthNames)[i];
3017
- classArray = [];
3018
- if(fullyDisabled || !picker.isInRange([value, val], max, min) ){
3019
- disabled = ' disabled=""';
3020
- } else {
3021
- disabled = '';
3022
- enabled++;
3023
- }
3024
-
3025
- if(value == today[0] && today[1] == val){
3026
- classArray.push('this-value');
3027
- }
3028
-
3029
- if(currentValue[0] == value && currentValue[1] == val){
3030
- classArray.push('checked-value');
3031
- }
3032
-
3033
- classStr = (classArray.length) ? ' class="'+ (classArray.join(' ')) +'"' : '';
3034
- if(i && !(i % 3)){
3035
- rowNum++;
3036
- lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2676
+ ['readonly', 'disabled'].forEach(function(name){
2677
+ var isDisabled = name == 'disabled';
2678
+ wsWidgetProto[name] = function(val, boolVal){
2679
+ if(this.options[name] != boolVal || !this._init){
2680
+ this.options[name] = !!boolVal;
2681
+ this.inputElements.prop(name, this.options[name]);
2682
+ this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
2683
+ if(isDisabled){
2684
+ $('button', this.buttonWrapper).prop('disabled', this.options[name]);
3037
2685
  }
3038
-
3039
- 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>');
3040
-
3041
2686
  }
3042
-
3043
- str += '<div class="picker-grid"><table role="grid" aria-label="'+value+'"><tbody><tr class="ws-row-0">'+ (lis.join(''))+ '</tr></tbody></table></div></div>';
3044
- }
3045
-
3046
- return {
3047
- enabled: enabled,
3048
- main: str,
3049
- prev: prevDisabled,
3050
- next: nextDisabled,
3051
- type: 'Grid'
3052
2687
  };
3053
- };
3054
-
2688
+ });
3055
2689
 
3056
- picker.getDayList = function(value, data){
3057
-
3058
- var j, i, k, day, nDay, name, val, disabled, lis, prevDisabled, nextDisabled, addTr, week, rowNum;
3059
-
3060
- var lastMotnh, curMonth, otherMonth, dateArray, monthName, fullMonthName, buttonStr, date2, classArray;
3061
- var o = data.options;
3062
- var size = o.size;
3063
- var max = o.max.split('-');
3064
- var min = o.min.split('-');
3065
- var currentValue = o.value.split('-');
3066
- var monthNames = curCfg.date[o.monthNamesHead] || curCfg.date[o.monthNames] || curCfg.date.monthNames;
3067
- var enabled = 0;
3068
- var str = [];
3069
- var date = new Date(value[0], value[1] - 1, 1);
3070
-
3071
- date.setMonth(date.getMonth() - Math.floor((size - 1) / 2));
3072
-
3073
- for(j = 0; j < size; j++){
3074
- date.setDate(1);
3075
- lastMotnh = date.getMonth();
3076
- rowNum = 0;
3077
- if(!j){
3078
- date2 = new Date(date.getTime());
3079
- date2.setDate(-1);
3080
- dateArray = getDateArray(date2);
3081
- prevDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray[0]+'-'+dateArray[1]} : false;
3082
- }
3083
-
3084
- dateArray = getDateArray(date);
3085
-
3086
- str.push('<div class="day-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">');
3087
- if( o.selectNav ){
3088
- 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>'];
3089
- if(curCfg.date.showMonthAfterYear){
3090
- monthName.reverse();
3091
- }
3092
- str.push( monthName.join(' ') );
3093
- }
2690
+ var spinBtnProto = $.extend({}, wsWidgetProto, {
2691
+ _create: function(){
2692
+ var o = this.options;
2693
+ var helper = createHelper(o.type);
3094
2694
 
3095
- fullMonthName = [curCfg.date.monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
3096
- monthName = [monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
3097
- if(curCfg.date.showMonthAfterYear){
3098
- monthName.reverse();
3099
- fullMonthName.reverse();
3100
- }
2695
+ this.elemHelper = $('<input type="'+ o.type+'" />');
2696
+ this.asNumber = helper.asNumber;
2697
+ this.asValue = helper.asValue;
2698
+
2699
+ wsWidgetProto._create.apply(this, arguments);
2700
+ this._init = false;
2701
+
2702
+ this.buttonWrapper.html('<span unselectable="on" class="step-controls"><span class="step-up"></span><span class="step-down"></span></span>');
3101
2703
 
3102
- if(!data.options.selectNav) {
3103
- str.push(
3104
- '<button data-action="setMonthList"'+ (o.minView >= 2 ? ' disabled="" ' : '') +' value="'+ dateArray.date +'" tabindex="-1">'+ monthName.join(' ') +'</button>'
3105
- );
2704
+ if(this.type == 'number'){
2705
+ this.inputElements.attr('inputmode', 'numeric');
3106
2706
  }
3107
2707
 
3108
2708
 
3109
- str.push('</div><div class="picker-grid"><table role="grid" aria-label="'+ fullMonthName.join(' ') +'"><thead><tr>');
2709
+ if(!o.min && typeof o.relMin == 'number'){
2710
+ o.min = this.asValue(this.getRelNumber(o.relMin));
2711
+ $.prop(this.orig, 'min', o.min);
2712
+ }
3110
2713
 
3111
- if(data.options.showWeek){
3112
- str.push('<th class="week-header">'+ curCfg.date.weekHeader +'</th>');
2714
+ if(!o.max && typeof o.relMax == 'number'){
2715
+ o.max = this.asValue(this.getRelNumber(o.relMax));
2716
+ $.prop(this.orig, 'max', o.max);
3113
2717
  }
3114
- for(k = curCfg.date.firstDay; k < curCfg.date.dayNamesShort.length; k++){
3115
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2718
+ this._init = true;
2719
+ },
2720
+ createOpts: ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value', 'required'],
2721
+ _addSplitInputs: function(){
2722
+ if(!this.inputElements){
2723
+ var create = splitInputs[this.type]._create();
2724
+ this.splits = create.splits;
2725
+ this.inputElements = $(create.elements).prependTo(this.element).filter('input');
3116
2726
  }
3117
- k = curCfg.date.firstDay;
3118
- while(k--){
3119
- str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2727
+ },
2728
+
2729
+ getRelNumber: function(rel){
2730
+ var start = steps[this.type].start || 0;
2731
+ if(rel){
2732
+ start += rel;
3120
2733
  }
3121
- str.push('</tr></thead><tbody><tr class="ws-row-0">');
3122
-
3123
- if(data.options.showWeek) {
3124
- week = picker.getWeek(date);
3125
- str.push('<td class="week-cell">'+ week +'</td>');
2734
+ return start;
2735
+ },
2736
+ addZero: addZero,
2737
+ _setStartInRange: function(){
2738
+ var start = this.getRelNumber(this.options.relDefaultValue);
2739
+ if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
2740
+ start = this.minAsNumber;
2741
+ } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
2742
+ start = this.maxAsNumber;
3126
2743
  }
2744
+ this.elemHelper.prop('valueAsNumber', start);
2745
+ this.options.defValue = this.elemHelper.prop('value');
3127
2746
 
3128
- for (i = 0; i < 99; i++) {
3129
- addTr = (i && !(i % 7));
3130
- curMonth = date.getMonth();
3131
- otherMonth = lastMotnh != curMonth;
3132
- day = date.getDay();
3133
- classArray = [];
3134
-
3135
- if(addTr && otherMonth ){
3136
- str.push('</tr>');
3137
- break;
3138
- }
3139
- if(addTr){
3140
- rowNum++;
3141
- str.push('</tr><tr class="ws-row-'+ rowNum +'">');
3142
- if(data.options.showWeek) {
3143
- week++;
3144
- str.push('<td class="week-cell">'+ week +'</td>');
3145
- }
3146
- }
3147
-
3148
- if(!i){
3149
-
3150
- if(day != curCfg.date.firstDay){
3151
- nDay = day - curCfg.date.firstDay;
3152
- if(nDay < 0){
3153
- nDay += 7;
3154
- }
3155
- date.setDate(date.getDate() - nDay);
3156
- day = date.getDay();
3157
- curMonth = date.getMonth();
3158
- otherMonth = lastMotnh != curMonth;
2747
+ },
2748
+ reorderInputs: function(){
2749
+ if(splitInputs[this.type]){
2750
+ var element = this.element;
2751
+ splitInputs[this.type].sort(element);
2752
+ setTimeout(function(){
2753
+ var data = webshims.data(element);
2754
+ if(data && data.shadowData){
2755
+ data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
3159
2756
  }
3160
- }
3161
-
3162
- dateArray = getDateArray(date);
3163
- buttonStr = '<td role="presentation" class="day-'+ day +'"><button data-id="day-'+ date.getDate() +'" role="gridcell" data-action="changeInput" value="'+ (dateArray.join('-')) +'"';
2757
+ }, 9);
2758
+ }
2759
+ },
2760
+ value: function(val){
2761
+
2762
+ if(!this._init || this.options.value !== val){
2763
+ this.valueAsNumber = this.asNumber(val);
2764
+ this.options.value = val;
3164
2765
 
3165
- if(otherMonth){
3166
- classArray.push('othermonth');
2766
+ if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
2767
+ this._setStartInRange();
3167
2768
  } else {
3168
- classArray.push('day-'+date.getDate());
3169
- }
3170
-
3171
- if(dateArray[0] == today[0] && today[1] == dateArray[1] && today[2] == dateArray[2]){
3172
- classArray.push('this-value');
3173
- }
3174
-
3175
- if(currentValue[0] == dateArray[0] && dateArray[1] == currentValue[1] && dateArray[2] == currentValue[2]){
3176
- classArray.push('checked-value');
3177
- }
3178
-
3179
- if(classArray.length){
3180
- buttonStr += ' class="'+ classArray.join(' ') +'"';
2769
+ this.elemHelper.prop('value', val);
2770
+ this.options.defValue = "";
3181
2771
  }
3182
2772
 
3183
- if(!picker.isInRange(dateArray, max, min) || (data.options.disableDays && $.inArray(day, data.options.disableDays) != -1)){
3184
- buttonStr += ' disabled=""';
2773
+ val = formatVal[this.type](val, this.options);
2774
+ if(this.options.splitInput){
2775
+ $.each(this.splits, function(i, elem){
2776
+ $.prop(elem, 'value', val[i]);
2777
+ });
2778
+ } else {
2779
+ this.element.prop('value', val);
3185
2780
  }
3186
-
3187
- str.push(buttonStr+' tabindex="-1">'+ date.getDate() +'</button></td>');
3188
-
3189
- date.setDate(date.getDate() + 1);
3190
- }
3191
- str.push('</tbody></table></div></div>');
3192
- if(j == size - 1){
3193
- dateArray = getDateArray(date);
3194
- dateArray[2] = 1;
3195
- nextDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray.date} : false;
2781
+ this._propertyChange('value');
2782
+ this.mirrorValidity();
3196
2783
  }
2784
+ },
2785
+ step: function(val){
2786
+ var defStep = steps[this.type];
2787
+ this.options.step = val;
2788
+ this.elemHelper.prop('step', retDefault(val, defStep.step));
2789
+ this.mirrorValidity();
3197
2790
  }
3198
-
3199
-
3200
- return {
3201
- enabled: 9,
3202
- main: str.join(''),
3203
- prev: prevDisabled,
3204
- next: nextDisabled,
3205
- type: 'Grid'
3206
- };
3207
- };
2791
+ });
3208
2792
 
3209
- picker.isInRange = function(values, max, min){
3210
- var i;
3211
- var ret = true;
3212
- for(i = 0; i < values.length; i++){
3213
-
3214
- if(min[i] && min[i] > values[i]){
3215
- ret = false;
3216
- break;
3217
- } else if( !(min[i] && min[i] == values[i]) ){
3218
- break;
2793
+ $.each({min: 1, max: -1}, function(name, factor){
2794
+ var numName = name +'AsNumber';
2795
+ spinBtnProto[name] = function(val){
2796
+ this.elemHelper.prop(name, val);
2797
+ this[numName] = this.asNumber(val);
2798
+ if(this.valueAsNumber != null && (isNaN(this.valueAsNumber) || (!isNaN(this[numName]) && (this.valueAsNumber * factor) < (this[numName] * factor)))){
2799
+ this._setStartInRange();
3219
2800
  }
3220
- }
3221
- if(ret){
3222
- for(i = 0; i < values.length; i++){
3223
-
3224
- if((max[i] && max[i] < values[i])){
3225
- ret = false;
3226
- break;
3227
- } else if( !(max[i] && max[i] == values[i]) ){
3228
- break;
2801
+ this.options[name] = val;
2802
+ this._propertyChange(name);
2803
+ this.mirrorValidity();
2804
+ };
2805
+ });
2806
+
2807
+ $.fn.wsBaseWidget = function(opts){
2808
+ opts = $.extend({}, opts);
2809
+ return this.each(function(){
2810
+ $.webshims.objectCreate(wsWidgetProto, {
2811
+ element: {
2812
+ value: $(this)
3229
2813
  }
3230
- }
3231
- }
3232
- return ret;
2814
+ }, opts);
2815
+ });
3233
2816
  };
3234
2817
 
3235
- picker.createMonthSelect = function(value, max, min, monthNames){
3236
- if(!monthNames){
3237
- monthNames = curCfg.date.monthNames;
3238
- }
3239
-
3240
- var selected;
3241
- var i = 0;
3242
- var options = [];
3243
- var tempVal = value[1]-1;
3244
- for(; i < monthNames.length; i++){
3245
- selected = tempVal == i ? ' selected=""' : '';
3246
- if(selected || picker.isInRange([value[0], i+1], max, min)){
3247
- options.push('<option value="'+ value[0]+'-'+addZero(i+1) + '"'+selected+'>'+ monthNames[i] +'</option>');
3248
- }
2818
+ $.fn.spinbtnUI = function(opts){
2819
+ opts = $.extend({
2820
+ monthNames: 'monthNames',
2821
+ size: 1,
2822
+ startView: 0
2823
+ }, opts);
2824
+ return this.each(function(){
2825
+ $.webshims.objectCreate(spinBtnProto, {
2826
+ element: {
2827
+ value: $(this)
2828
+ }
2829
+ }, opts);
2830
+ });
2831
+ };
2832
+ })();
2833
+
2834
+ (function(){
2835
+ var picker = {};
2836
+
2837
+ var loadPicker = function(type, name){
2838
+ type = (type == 'color' ? 'color' : 'forms')+'-picker';
2839
+ if(!loadPicker[name+'Loaded'+type]){
2840
+ loadPicker[name+'Loaded'+type] = true;
2841
+ webshims.ready(name, function(){
2842
+ webshims.loader.loadList([type]);
2843
+ });
3249
2844
  }
3250
- return options;
2845
+ return type;
3251
2846
  };
2847
+ options.addZero = addZero;
2848
+ webshims.loader.addModule('forms-picker', {
2849
+ noAutoCallback: true,
2850
+ options: options
2851
+ });
2852
+ webshims.loader.addModule('color-picker', {
2853
+ noAutoCallback: true,
2854
+ css: 'jpicker/jpicker.css',
2855
+ options: options
2856
+ });
3252
2857
 
3253
- picker.createYearSelect = function(value, max, min, valueAdd){
3254
-
3255
- var temp;
3256
- var goUp = true;
3257
- var goDown = true;
3258
- var options = ['<option selected="">'+ value + '</option>'];
3259
- var i = 0;
3260
- if(!valueAdd){
3261
- valueAdd = '';
3262
- }
3263
- while(i < 8 && (goUp || goDown)){
3264
- i++;
3265
- temp = value-i;
3266
- if(goUp && picker.isInRange([temp], max, min)){
3267
- options.unshift('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
3268
- } else {
3269
- goUp = false;
3270
- }
3271
- temp = value + i;
3272
- if(goDown && picker.isInRange([temp], max, min)){
3273
- options.push('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
3274
- } else {
3275
- goDown = false;
3276
- }
2858
+ picker._genericSetFocus = function(element, _noFocus){
2859
+ element = $(element || this.activeButton);
2860
+ if(!this.popover.openedByFocus && !_noFocus){
2861
+ var that = this;
2862
+ var setFocus = function(noTrigger){
2863
+ clearTimeout(that.timer);
2864
+ that.timer = setTimeout(function(){
2865
+ if(element[0]){
2866
+ element[0].focus();
2867
+ if(noTrigger !== true && !element.is(':focus')){
2868
+ setFocus(true);
2869
+ }
2870
+ }
2871
+ }, that.popover.isVisible ? 99 : 360);
2872
+ };
2873
+ this.popover.activateElement(element);
2874
+ setFocus();
3277
2875
  }
3278
- return options;
3279
2876
  };
3280
-
3281
- var actions = {
2877
+
2878
+ picker._actions = {
3282
2879
  changeInput: function(val, popover, data){
2880
+ picker._actions.cancel(val, popover, data);
2881
+ data.setChange(val);
2882
+ },
2883
+ cancel: function(val, popover, data){
3283
2884
  popover.stopOpen = true;
3284
2885
  data.element.getShadowFocusElement().focus();
3285
2886
  setTimeout(function(){
3286
2887
  popover.stopOpen = false;
3287
2888
  }, 9);
3288
2889
  popover.hide();
3289
- data.setChange(val);
3290
2890
  }
3291
2891
  };
3292
2892
 
3293
- (function(){
3294
- var retNames = function(name){
3295
- return 'get'+name+'List';
3296
- };
3297
- var retSetNames = function(name){
3298
- return 'set'+name+'List';
3299
- };
3300
- var stops = {
3301
- date: 'Day',
3302
- week: 'Day',
3303
- month: 'Month'
3304
- };
3305
-
3306
- $.each({'setYearList' : ['Year', 'Month', 'Day'], 'setMonthList': ['Month', 'Day'], 'setDayList': ['Day']}, function(setName, names){
3307
- var getNames = names.map(retNames);
3308
- var setNames = names.map(retSetNames);
3309
- actions[setName] = function(val, popover, data, startAt){
3310
- val = ''+val;
3311
- var o = data.options;
3312
- var values = val.split('-');
3313
- if(!startAt){
3314
- startAt = 0;
3315
- }
3316
- $.each(getNames, function(i, item){
3317
- if(i >= startAt){
3318
- var content = picker[item](values, data);
3319
-
3320
- if( values.length < 2 || content.enabled > 1 || stops[data.type] === names[i]){
3321
- popover.element
3322
- .attr({'data-currentview': setNames[i]})
3323
- .addClass('ws-size-'+o.size)
3324
- .data('pickercontent', {
3325
- data: data,
3326
- content: content,
3327
- values: values
3328
- })
3329
- ;
3330
- popover.bodyElement.html(content.main);
3331
- if(content.prev){
3332
- popover.prevElement
3333
- .attr(content.prev)
3334
- .prop({disabled: false})
3335
- ;
3336
- } else {
3337
- popover.prevElement
3338
- .removeAttr('data-action')
3339
- .prop({disabled: true})
3340
- ;
3341
- }
3342
- if(content.next){
3343
- popover.nextElement
3344
- .attr(content.next)
3345
- .prop({disabled: false})
3346
- ;
3347
- } else {
3348
- popover.nextElement
3349
- .removeAttr('data-action')
3350
- .prop({disabled: true})
3351
- ;
3352
- }
3353
- if(webshims[content.type]){
3354
- new webshims[content.type](popover.bodyElement.children(), popover, content);
3355
- }
3356
- popover.element.trigger('pickerchange');
3357
- return false;
3358
- }
3359
- }
3360
- });
3361
- };
3362
- });
3363
- })();
3364
2893
 
3365
2894
  picker.commonInit = function(data, popover){
3366
- var actionfn = function(e){
3367
- if(!$(this).is('.othermonth') || $(this).css('cursor') == 'pointer'){
3368
- popover.actionFn({
3369
- 'data-action': $.attr(this, 'data-action'),
3370
- value: $(this).val() || $.attr(this, 'value')
3371
- });
3372
- }
3373
- return false;
3374
- };
3375
- var id = new Date().getTime();
3376
- var generateList = function(o, max, min){
3377
- var options = [];
3378
- var label = '';
3379
- var labelId = '';
3380
- o.options = data.getOptions() || {};
3381
- $('div.ws-options', popover.contentElement).remove();
3382
- $.each(o.options[0], function(val, label){
3383
- var disabled = picker.isInRange(val.split('-'), o.maxS, o.minS) ?
3384
- '' :
3385
- ' disabled="" '
3386
- ;
3387
- options.push('<li role="presentation"><button value="'+ val +'" '+disabled+' data-action="changeInput" tabindex="-1" role="option">'+ (label || data.formatValue(val, false)) +'</button></li>');
3388
- });
3389
- if(options.length){
3390
- id++;
3391
- if(o.options[1]){
3392
- labelId = 'datalist-'+id;
3393
- label = '<h5 id="'+labelId+'">'+ o.options[1] +'</h5>';
3394
- labelId = ' aria-labelledbyid="'+ labelId +'" ';
3395
- }
3396
- new webshims.ListBox($('<div class="ws-options">'+label+'<ul role="listbox" '+ labelId +'>'+ options.join('') +'</div>').insertAfter(popover.bodyElement)[0], popover, {noFocus: true});
3397
- }
3398
- };
3399
- var updateContent = function(){
3400
- if(popover.isDirty){
3401
- var o = data.options;
3402
- o.maxS = o.max.split('-');
3403
- o.minS = o.min.split('-');
3404
-
3405
- $('button', popover.buttonRow).each(function(){
3406
- var text;
3407
- if($(this).is('.ws-empty')){
3408
- text = curCfg.date.clear;
3409
- if(!text){
3410
- text = formcfg[''].date.clear || 'clear';
3411
- webshims.warn("could not get clear text from form cfg");
3412
- }
3413
- } else if($(this).is('.ws-current')){
3414
- text = (curCfg[data.type] || {}).currentText;
3415
- if(!text){
3416
- text = (formcfg[''][[data.type]] || {}).currentText || 'current';
3417
- webshims.warn("could not get currentText from form cfg");
3418
- }
3419
- $.prop(this, 'disabled', !picker.isInRange(today[data.type].split('-'), o.maxS, o.minS));
3420
- }
3421
- if(text){
3422
- $(this).text(text).attr({'aria-label': text});
3423
- if(webshims.assumeARIA){
3424
- $.attr(this, 'aria-label', text);
3425
- }
3426
- }
3427
-
3428
- });
3429
- popover.nextElement.attr({'aria-label': curCfg.date.nextText});
3430
- $('> span', popover.nextElement).html(curCfg.date.nextText);
3431
- popover.prevElement.attr({'aria-label': curCfg.date.prevText});
3432
- $('> span', popover.prevElement).html(curCfg.date.prevText);
3433
-
3434
- generateList(o, o.maxS, o.minS);
3435
-
3436
- }
3437
- $('button.ws-empty', popover.buttonRow).prop('disabled', $.prop(data.orig, 'required'));
3438
- popover.isDirty = false;
3439
- };
3440
-
3441
- popover.actionFn = function(obj){
3442
- if(actions[obj['data-action']]){
3443
- actions[obj['data-action']](obj.value, popover, data, 0);
3444
- } else {
3445
- webshims.warn('no action for '+ obj['data-action']);
3446
- }
3447
- };
3448
-
3449
- 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>');
3450
- popover.nextElement = $('button.ws-next', popover.contentElement);
3451
- popover.prevElement = $('button.ws-prev', popover.contentElement);
3452
- popover.bodyElement = $('div.ws-picker-body', popover.contentElement);
3453
- popover.buttonRow = $('div.ws-button-row', popover.contentElement);
2895
+ var tabbable;
3454
2896
 
3455
2897
  popover.isDirty = true;
3456
2898
 
3457
- popover.contentElement
3458
- .on('click', 'button[data-action]', actionfn)
3459
- .on('change', 'select[data-action]', actionfn)
3460
- ;
3461
-
2899
+ popover.element.on('updatepickercontent pickerchange', function(){
2900
+ tabbable = false;
2901
+ });
3462
2902
  popover.contentElement.on({
3463
2903
  keydown: function(e){
3464
2904
  if(e.keyCode == 9){
3465
- var tabbable = $('[tabindex="0"]:not(:disabled)', this).filter(':visible');
2905
+ if(!tabbable){
2906
+ tabbable = $('input:not(:disabled), [tabindex="0"]:not(:disabled)', this).filter(':visible');
2907
+ }
3466
2908
  var index = tabbable.index(e.target);
3467
2909
  if(e.shiftKey && index <= 0){
3468
2910
  tabbable.last().focus();
@@ -3480,18 +2922,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3480
2922
  }
3481
2923
  });
3482
2924
 
3483
- $(data.options.orig).on('input', function(){
3484
- var currentView;
3485
- if(data.options.updateOnInput && popover.isVisible && data.options.value && (currentView = popover.element.attr('data-currentview'))){
3486
- actions[currentView]( data.options.value , popover, data, 0);
3487
- }
3488
- });
3489
-
3490
2925
  data._propertyChange = (function(){
3491
2926
  var timer;
3492
2927
  var update = function(){
3493
2928
  if(popover.isVisible){
3494
- updateContent();
2929
+ popover.element.triggerHandler('updatepickercontent');
3495
2930
  }
3496
2931
  };
3497
2932
  return function(prop){
@@ -3517,50 +2952,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3517
2952
  popover.element.on({
3518
2953
  wspopoverbeforeshow: function(){
3519
2954
  data.element.triggerHandler('wsupdatevalue');
3520
- updateContent();
2955
+ popover.element.triggerHandler('updatepickercontent');
3521
2956
  }
3522
2957
  });
3523
2958
 
3524
- $(document).onTrigger('wslocalechange', data._propertyChange);
2959
+
2960
+ $(data.orig).on('remove', function(e){
2961
+ if(!e.originalEvent){
2962
+ $(document).off('wslocalechange', data._propertyChange);
2963
+ }
2964
+ });
3525
2965
  };
3526
2966
 
2967
+
3527
2968
  picker._common = function(data){
3528
2969
  var popover = webshims.objectCreate(webshims.wsPopover, {}, {prepareFor: data.element});
3529
2970
  var opener = $('<button type="button" class="ws-popover-opener"><span /></button>').appendTo(data.buttonWrapper);
3530
2971
  var options = data.options;
3531
- var init = false;
3532
2972
 
2973
+ var showPickerContent = function(){
2974
+ (picker[data.type].showPickerContent || picker.showPickerContent)(data, popover);
2975
+ };
3533
2976
  var show = function(){
2977
+ var type = loadPicker(data.type, 'DOM');
3534
2978
  if(!options.disabled && !options.readonly && !popover.isVisible){
3535
- if(!init){
3536
- picker.commonInit(data, popover);
3537
- }
3538
-
3539
- if(!init || data.options.restartView) {
3540
- actions.setYearList( options.defValue || options.value, popover, data, data.options.startView);
3541
- } else {
3542
- actions[popover.element.attr('data-currentview') || 'setYearList']( options.defValue || options.value, popover, data, 0);
3543
- }
3544
-
3545
- init = true;
2979
+ webshims.ready(type, showPickerContent);
3546
2980
  popover.show(data.element);
3547
2981
  }
3548
2982
  };
3549
2983
 
3550
2984
  options.containerElements.push(popover.element[0]);
3551
2985
 
3552
- if(!options.startView){
3553
- options.startView = 0;
3554
- }
3555
- if(!options.minView){
3556
- options.minView = 0;
3557
- }
3558
- if(options.startView < options.minView){
3559
- options.minView = options.startView;
3560
- webshims.warn("wrong config for minView/startView.");
3561
- }
3562
- if(!options.size){
3563
- options.size = 1;
2986
+ if(data.type != 'color'){
2987
+ if(!options.startView){
2988
+ options.startView = 0;
2989
+ }
2990
+ if(!options.minView){
2991
+ options.minView = 0;
2992
+ }
2993
+ if(options.startView < options.minView){
2994
+ options.startView = options.minView;
2995
+ webshims.warn("wrong config for minView/startView.");
2996
+ }
2997
+ if(!options.size){
2998
+ options.size = 1;
2999
+ }
3564
3000
  }
3565
3001
 
3566
3002
  popover.element
@@ -3587,10 +3023,15 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3587
3023
  labelWidth(popover.element.children('div.ws-po-outerbox').attr({role: 'group'}), options.labels, true);
3588
3024
  labelWidth(opener, options.labels, true);
3589
3025
 
3026
+ if(options.tabindex != null){
3027
+ opener.attr({tabindex: options.tabindex});
3028
+ }
3029
+
3030
+ if(options.disabled){
3031
+ opener.prop({disabled: true});
3032
+ }
3033
+
3590
3034
  opener
3591
- .attr({
3592
- 'tabindex': options.labels.length ? 0 : '-1'
3593
- })
3594
3035
  .on({
3595
3036
  mousedown: function(){
3596
3037
  stopPropagation.apply(this, arguments);
@@ -3635,10 +3076,51 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3635
3076
  });
3636
3077
  })();
3637
3078
  data.popover = popover;
3079
+ data.opener = opener;
3080
+ $(data.orig).on('remove', function(e){
3081
+ if(!e.originalEvent){
3082
+ opener.remove();
3083
+ popover.element.remove();
3084
+ }
3085
+ });
3086
+
3087
+ loadPicker(data.type, 'WINDOWLOAD');
3638
3088
  };
3639
3089
 
3640
3090
  picker.month = picker._common;
3641
- picker.date = picker.month;
3091
+ picker.date = picker._common;
3092
+ picker.color = function(data){
3093
+ var ret = picker._common.apply(this, arguments);
3094
+ var alpha = $(data.orig).data('alphacontrol');
3095
+ var colorIndicator = data.opener
3096
+ .prepend('<span class="ws-color-indicator-bg"><span class="ws-color-indicator" /></span>')
3097
+ .find('.ws-color-indicator')
3098
+ ;
3099
+ var showColor = function(){
3100
+ colorIndicator.css({backgroundColor: $.prop(this, 'value') || '#000'})
3101
+ };
3102
+ var showOpacity = (function(){
3103
+ var timer;
3104
+ var show = function(){
3105
+ try {
3106
+ var value = data.alpha.prop('valueAsNumber') / (data.alpha.prop('max') || 1);
3107
+ if(!isNaN(value)){
3108
+ colorIndicator.css({opacity: value});
3109
+ }
3110
+ } catch(er){}
3111
+
3112
+ };
3113
+ return function(e){
3114
+ clearTimeout(timer);
3115
+ timer = setTimeout(show, !e || e.type == 'change' ? 4: 40);
3116
+ };
3117
+ })();
3118
+ data.alpha = (alpha) ? $('#'+alpha) : $([]);
3119
+
3120
+ $(data.orig).on('wsupdatevalue change', showColor).each(showColor);
3121
+ data.alpha.on('wsupdatevalue change input', showOpacity).each(showOpacity);
3122
+ return ret;
3123
+ };
3642
3124
 
3643
3125
  webshims.picker = picker;
3644
3126
  })();
@@ -3659,6 +3141,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3659
3141
  'max',
3660
3142
  'step',
3661
3143
  'title',
3144
+ 'required',
3662
3145
  'placeholder'
3663
3146
  ];
3664
3147
 
@@ -3667,11 +3150,11 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3667
3150
 
3668
3151
  $.each(copyProps.concat(copyAttrs), function(i, name){
3669
3152
  var fnName = name.replace(/^data\-/, '');
3670
- webshims.onNodeNamesPropertyModify('input', name, function(val){
3153
+ webshims.onNodeNamesPropertyModify('input', name, function(val, boolVal){
3671
3154
  if(!stopCircular){
3672
3155
  var shadowData = webshims.data(this, 'shadowData');
3673
3156
  if(shadowData && shadowData.data && shadowData.nativeElement === this && shadowData.data[fnName]){
3674
- shadowData.data[fnName](val);
3157
+ shadowData.data[fnName](val, boolVal);
3675
3158
  }
3676
3159
  }
3677
3160
  });
@@ -3702,6 +3185,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3702
3185
  var sizeInput = function(data){
3703
3186
  var init;
3704
3187
  var updateStyles = function(){
3188
+ $(data.orig).removeClass('ws-important-hide');
3705
3189
  $.style( data.orig, 'display', '' );
3706
3190
  var hasButtons, marginR, marginL;
3707
3191
  var correctWidth = 0.6;
@@ -3735,13 +3219,14 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3735
3219
  data.element.outerWidth( $(data.orig).outerWidth() - correctWidth );
3736
3220
  }
3737
3221
  init = true;
3738
- $.style( data.orig, 'display', 'none' );
3222
+ $(data.orig).addClass('ws-important-hide');
3739
3223
  };
3740
- $(document).onTrigger('updateshadowdom', updateStyles);
3224
+ data.element.onWSOff('updateshadowdom', updateStyles, true);
3741
3225
  };
3742
3226
 
3743
3227
 
3744
3228
  var implementType = function(){
3229
+
3745
3230
  var type = $.prop(this, 'type');
3746
3231
 
3747
3232
  var i, opts, data, optsName, labels;
@@ -3796,7 +3281,7 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3796
3281
  data.shim.options.containerElements.push(data.shim.element[0]);
3797
3282
 
3798
3283
  labelWidth($(this).getShadowFocusElement(), labels);
3799
- $.attr(this, 'required', $.attr(this, 'required'));
3284
+
3800
3285
  $(this).on('change', function(e){
3801
3286
  if(!stopCircular){
3802
3287
  data.shim.value($.prop(this, 'value'));
@@ -3855,18 +3340,13 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3855
3340
 
3856
3341
  if(opts.calculateWidth){
3857
3342
  sizeInput(data.shim);
3343
+ } else {
3344
+ $(this).css({display: 'none'});
3858
3345
  }
3859
- $(this).css({display: 'none'});
3860
3346
  }
3347
+
3861
3348
  };
3862
3349
 
3863
- if(!modernizrInputTypes.range || options.replaceUI){
3864
- extendType('range', {
3865
- _create: function(opts, set){
3866
- return $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
3867
- }
3868
- });
3869
- }
3870
3350
 
3871
3351
  if(Modernizr.formvalidation){
3872
3352
  ['input', 'form'].forEach(function(name){
@@ -3883,12 +3363,20 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3883
3363
  });
3884
3364
  }
3885
3365
 
3366
+ if(!modernizrInputTypes.range || options.replaceUI){
3367
+ extendType('range', {
3368
+ _create: function(opts, set){
3369
+ var data = $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
3370
+ return data;
3371
+ }
3372
+ });
3373
+ }
3886
3374
 
3887
- ['number', 'time', 'month', 'date'].forEach(function(name){
3888
- if(!modernizrInputTypes[name] || options.replaceUI){
3375
+ var isStupid = navigator.userAgent.indexOf('MSIE 10.0') != -1 && navigator.userAgent.indexOf('Touch') == -1;
3376
+ ['number', 'time', 'month', 'date', 'color'].forEach(function(name){
3377
+ if(!modernizrInputTypes[name] || options.replaceUI || (name == 'number' && isStupid)){
3889
3378
  extendType(name, {
3890
3379
  _create: function(opts, set){
3891
-
3892
3380
  if(opts.splitInput && !splitInputs[name]){
3893
3381
  webshims.warn('splitInput not supported for '+ name);
3894
3382
  opts.splitInput = false;
@@ -3896,11 +3384,12 @@ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, do
3896
3384
  var markup = opts.splitInput ?
3897
3385
  '<span class="ws-'+name+' ws-input" role="group"></span>' :
3898
3386
  '<input class="ws-'+name+'" type="text" />';
3899
- var data = $(markup) //role="spinbutton"???
3900
- .insertAfter(opts.orig)
3901
- .spinbtnUI(opts)
3902
- .data('wsspinner')
3903
- ;
3387
+ var data = $(markup).insertAfter(opts.orig);
3388
+ if(steps[name]){
3389
+ data = data.spinbtnUI(opts).data('wsWidget'+name);
3390
+ } else {
3391
+ data = data.wsBaseWidget(opts).data('wsWidget'+name);
3392
+ }
3904
3393
  if(webshims.picker && webshims.picker[name]){
3905
3394
  webshims.picker[name](data);
3906
3395
  }