webshims-rails 1.11.6.1 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/webshims/polyfiller.js +126 -72
  4. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/canvas2png.js +9 -4
  5. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.js +32 -26
  6. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.swf +0 -0
  7. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/proxy.php +25 -4
  8. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/save.php +9 -3
  9. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/canvas2png.js +9 -4
  10. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  11. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  12. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flashcanvas.js +36 -30
  13. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/proxy.php +25 -4
  14. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/save.php +9 -3
  15. data/vendor/assets/javascripts/webshims/shims/combos/1.js +13 -6
  16. data/vendor/assets/javascripts/webshims/shims/combos/10.js +156 -143
  17. data/vendor/assets/javascripts/webshims/shims/combos/11.js +97 -84
  18. data/vendor/assets/javascripts/webshims/shims/combos/12.js +2 -4
  19. data/vendor/assets/javascripts/webshims/shims/combos/13.js +1 -2
  20. data/vendor/assets/javascripts/webshims/shims/combos/14.js +956 -2819
  21. data/vendor/assets/javascripts/webshims/shims/combos/15.js +73 -67
  22. data/vendor/assets/javascripts/webshims/shims/combos/16.js +75 -71
  23. data/vendor/assets/javascripts/webshims/shims/combos/17.js +118 -89
  24. data/vendor/assets/javascripts/webshims/shims/combos/18.js +119 -91
  25. data/vendor/assets/javascripts/webshims/shims/combos/19.js +62 -65
  26. data/vendor/assets/javascripts/webshims/shims/combos/2.js +73 -67
  27. data/vendor/assets/javascripts/webshims/shims/combos/20.js +61 -63
  28. data/vendor/assets/javascripts/webshims/shims/combos/21.js +3 -6
  29. data/vendor/assets/javascripts/webshims/shims/combos/22.js +1 -2
  30. data/vendor/assets/javascripts/webshims/shims/combos/23.js +1 -2
  31. data/vendor/assets/javascripts/webshims/shims/combos/24.js +22 -12
  32. data/vendor/assets/javascripts/webshims/shims/combos/25.js +63 -67
  33. data/vendor/assets/javascripts/webshims/shims/combos/26.js +59 -59
  34. data/vendor/assets/javascripts/webshims/shims/combos/27.js +1 -2
  35. data/vendor/assets/javascripts/webshims/shims/combos/28.js +1915 -0
  36. data/vendor/assets/javascripts/webshims/shims/combos/29.js +817 -0
  37. data/vendor/assets/javascripts/webshims/shims/combos/3.js +71 -63
  38. data/vendor/assets/javascripts/webshims/shims/combos/30.js +72 -65
  39. data/vendor/assets/javascripts/webshims/shims/combos/31.js +71 -63
  40. data/vendor/assets/javascripts/webshims/shims/combos/32.js +2343 -0
  41. data/vendor/assets/javascripts/webshims/shims/combos/33.js +897 -0
  42. data/vendor/assets/javascripts/webshims/shims/combos/4.js +59 -59
  43. data/vendor/assets/javascripts/webshims/shims/combos/5.js +119 -91
  44. data/vendor/assets/javascripts/webshims/shims/combos/6.js +120 -93
  45. data/vendor/assets/javascripts/webshims/shims/combos/7.js +74 -69
  46. data/vendor/assets/javascripts/webshims/shims/combos/8.js +73 -67
  47. data/vendor/assets/javascripts/webshims/shims/combos/9.js +157 -145
  48. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +58 -57
  49. data/vendor/assets/javascripts/webshims/shims/form-combat.js +0 -1
  50. data/vendor/assets/javascripts/webshims/shims/form-core.js +12 -3
  51. data/vendor/assets/javascripts/webshims/shims/form-datalist-lazy.js +4 -3
  52. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +20 -3
  53. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +78 -71
  54. data/vendor/assets/javascripts/webshims/shims/form-shim-extend2.js +21 -10
  55. data/vendor/assets/javascripts/webshims/shims/form-validation.js +39 -27
  56. data/vendor/assets/javascripts/webshims/shims/forms-picker.js +173 -128
  57. data/vendor/assets/javascripts/webshims/shims/i18n/{formcfg-ch-ZN.js → formcfg-ch-CN.js} +0 -0
  58. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-en.js +0 -2
  59. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-zh-CN.js +65 -0
  60. data/vendor/assets/javascripts/webshims/shims/plugins/jquery.ui.position.js +1 -1
  61. data/vendor/assets/javascripts/webshims/shims/range-ui.js +18 -11
  62. data/vendor/assets/javascripts/webshims/shims/styles/forms-ext.css +221 -153
  63. data/vendor/assets/javascripts/webshims/shims/styles/progress.gif +0 -0
  64. data/vendor/assets/javascripts/webshims/shims/styles/progress.png +0 -0
  65. data/vendor/assets/javascripts/webshims/shims/styles/scss/_extends.scss +5 -0
  66. data/vendor/assets/javascripts/webshims/shims/styles/scss/forms-ext.scss +273 -177
  67. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +113 -98
  68. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +114 -88
  69. data/vendor/assets/javascripts/webshims/shims/track-ui.js +2 -2
  70. metadata +10 -7
  71. data/vendor/assets/javascripts/webshims/extras/mousepress.js +0 -60
  72. data/vendor/assets/javascripts/webshims/shims/jpicker/images/Thumbs.db +0 -0
  73. data/vendor/assets/javascripts/webshims/shims/json-storage.js +0 -316
  74. data/vendor/assets/javascripts/webshims/shims/mediagroup.js +0 -29
@@ -40,34 +40,6 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
40
40
  webshims.ready('WINDOWLOAD', switch$);
41
41
 
42
42
  }
43
- // (function(){
44
- // var hostNames = {
45
- // 'afarkas.github.io': 1,
46
- // localhost: 1,
47
- // '127.0.0.1': 1
48
- // };
49
- //
50
- // if( webshims.cfg.debug && (hostNames[location.hostname] || location.protocol == 'file:') ){
51
- // var list = $('<ul class="webshims-debug-list" />');
52
- // webshims.errorLog.push = function(message){
53
- // list.appendTo('body');
54
- // $('<li style="display: none;">'+ message +'</li>')
55
- // .appendTo(list)
56
- // .slideDown()
57
- // .delay(3000)
58
- // .slideUp(function(){
59
- // $(this).remove();
60
- // if(!$('li', list).length){
61
- // list.detach();
62
- // }
63
- // })
64
- // ;
65
- // };
66
- // $.each(webshims.errorLog, function(i, message){
67
- // webshims.errorLog.push(message);
68
- // });
69
- // }
70
- // })();
71
43
 
72
44
  //shortcus
73
45
  var modules = webshims.modules;
@@ -509,11 +481,22 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
509
481
  });
510
482
  },
511
483
  getOptions: (function(){
484
+ var normalName = /\-([a-z])/g;
512
485
  var regs = {};
486
+ var nameRegs = {};
513
487
  var regFn = function(f, upper){
514
488
  return upper.toLowerCase();
515
489
  };
516
- return function(elem, name, bases){
490
+ var nameFn = function(f, dashed){
491
+ return dashed.toUpperCase();
492
+ };
493
+ return function(elem, name, bases, stringAllowed){
494
+ if(nameRegs[name]){
495
+ name = nameRegs[name];
496
+ } else {
497
+ nameRegs[name] = name.replace(normalName, nameFn);
498
+ name = nameRegs[name];
499
+ }
517
500
  var data = elementData(elem, 'cfg'+name);
518
501
  var dataName;
519
502
  var cfg = {};
@@ -522,7 +505,12 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
522
505
  return data;
523
506
  }
524
507
  data = $(elem).data();
525
-
508
+ if(data && typeof data[name] == 'string'){
509
+ if(stringAllowed){
510
+ return elementData(elem, 'cfg'+name, data[name]);
511
+ }
512
+ webshims.error('data-'+ name +' attribute has to be a valid JSON, was: '+ data[name]);
513
+ }
526
514
  if(!bases){
527
515
  bases = [true, {}];
528
516
  } else if(!Array.isArray(bases)){
@@ -531,12 +519,8 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
531
519
  bases.unshift(true, {});
532
520
  }
533
521
 
534
- if(data && data[name]){
535
- if(typeof data[name] == 'object'){
536
- bases.push(data[name]);
537
- } else {
538
- webshims.error('data-'+ name +' attribute has to be a valid JSON, was: '+ data[name]);
539
- }
522
+ if(data && typeof data[name] == 'object'){
523
+ bases.push(data[name]);
540
524
  }
541
525
 
542
526
  if(!regs[name]){
@@ -549,7 +533,6 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
549
533
  }
550
534
  }
551
535
  bases.push(cfg);
552
-
553
536
  return elementData(elem, 'cfg'+name, $.extend.apply($, bases));
554
537
  };
555
538
  })(),
@@ -579,7 +562,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
579
562
  var resizeTimer;
580
563
  var lastHeight;
581
564
  var lastWidth;
582
-
565
+ var $window = $(window);
583
566
  var docObserve = {
584
567
  init: false,
585
568
  runs: 0,
@@ -599,25 +582,36 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
599
582
  docObserve.runs = 0;
600
583
  }
601
584
  },
602
- handler: function(e){
603
- clearTimeout(resizeTimer);
604
- resizeTimer = setTimeout(function(){
605
- if(e.type == 'resize'){
606
- var width = $(window).width();
607
- var height = $(window).width();
608
- if(height == lastHeight && width == lastWidth){
609
- return;
585
+ handler: (function(){
586
+ var trigger = function(){
587
+ $(document).triggerHandler('updateshadowdom');
588
+ };
589
+ return function(e){
590
+ clearTimeout(resizeTimer);
591
+ resizeTimer = setTimeout(function(){
592
+ if(e.type == 'resize'){
593
+ var width = $window.width();
594
+ var height = $window.width();
595
+
596
+ if(height == lastHeight && width == lastWidth){
597
+ return;
598
+ }
599
+ lastHeight = height;
600
+ lastWidth = width;
601
+
602
+ docObserve.height = docObserve.getHeight();
603
+ docObserve.width = docObserve.getWidth();
604
+ }
605
+
606
+ if(window.requestAnimationFrame){
607
+ requestAnimationFrame(trigger);
608
+ } else {
609
+ setTimeout(trigger, 0);
610
610
  }
611
- lastHeight = height;
612
- lastWidth = width;
613
-
614
- docObserve.height = docObserve.getHeight();
615
- docObserve.width = docObserve.getWidth();
616
611
 
617
- }
618
- $(document).triggerHandler('updateshadowdom');
619
- }, (e.type == 'resize') ? 50 : 9);
620
- },
612
+ }, (e.type == 'resize' && !window.requestAnimationFrame) ? 50 : 0);
613
+ };
614
+ })(),
621
615
  _create: function(){
622
616
  $.each({ Height: "getHeight", Width: "getWidth" }, function(name, type){
623
617
  var body = document.body;
@@ -955,13 +949,17 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
955
949
  webshims.defineNodeNamesProperty(elementNames, prop, {
956
950
  attr: {
957
951
  set: function(val){
958
- this.setAttribute(prop, val);
952
+ if(descs.useContentAttribute){
953
+ webshims.contentAttr(this, prop, val);
954
+ } else {
955
+ this.setAttribute(prop, val);
956
+ }
959
957
  if(descs.set){
960
958
  descs.set.call(this, true);
961
959
  }
962
960
  },
963
961
  get: function(){
964
- var ret = this.getAttribute(prop);
962
+ var ret = (descs.useContentAttribute) ? webshims.contentAttr(this, prop) : this.getAttribute(prop);
965
963
  return (ret == null) ? undefined : prop;
966
964
  }
967
965
  },
@@ -1018,6 +1016,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1018
1016
  });
1019
1017
  }
1020
1018
  };
1019
+
1021
1020
  var select = function(obj){
1022
1021
  var oldLang = obj.__active;
1023
1022
  var selectLang = function(i, lang){
@@ -1025,6 +1024,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1025
1024
  if(obj[lang] || obj.availableLangs.indexOf(lang) != -1){
1026
1025
  if(obj[lang]){
1027
1026
  obj.__active = obj[lang];
1027
+ obj.__activeName = lang;
1028
1028
  } else {
1029
1029
  load(obj.langSrc+lang, obj, curLang.join());
1030
1030
  }
@@ -1034,6 +1034,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1034
1034
  $.each(curLang, selectLang);
1035
1035
  if(!obj.__active){
1036
1036
  obj.__active = obj[''];
1037
+ obj.__activeName = '';
1037
1038
  }
1038
1039
  if(oldLang != obj.__active){
1039
1040
  $(obj).trigger('change');
@@ -1138,7 +1139,7 @@ webshims.register('dom-extend', function($, webshims, window, document, undefine
1138
1139
  }
1139
1140
  });
1140
1141
 
1141
- })(webshims.$, document);
1142
+ })(webshims.$, document);;
1142
1143
  webshims.register('form-core', function($, webshims, window, document, undefined, options){
1143
1144
  "use strict";
1144
1145
 
@@ -1203,6 +1204,7 @@ webshims.register('form-core', function($, webshims, window, document, undefined
1203
1204
  };
1204
1205
 
1205
1206
  var extendSels = function(){
1207
+ var matches, matchesOverride;
1206
1208
  var exp = $.expr[":"];
1207
1209
  $.extend(exp, {
1208
1210
  "valid-element": function(elem){
@@ -1227,7 +1229,15 @@ webshims.register('form-core', function($, webshims, window, document, undefined
1227
1229
  });
1228
1230
 
1229
1231
  // sizzle/jQuery has a bug with :disabled/:enabled selectors
1230
- if(Modernizr.fieldsetdisabled && !$('<fieldset disabled=""><input /><fieldset>').find('input').is(':disabled')){
1232
+ if(Modernizr.fieldsetdisabled && !$('<fieldset disabled=""><input /><input /></fieldset>').find(':disabled').filter(':disabled').is(':disabled')){
1233
+ matches = $.find.matches;
1234
+ matchesOverride = {':disabled': 1, ':enabled': 1};
1235
+ $.find.matches = function(expr, elements){
1236
+ if(matchesOverride[expr]){
1237
+ return matches.call(this, '*'+expr, elements);
1238
+ }
1239
+ return matches.apply(this, arguments);
1240
+ };
1231
1241
  $.extend(exp, {
1232
1242
  "enabled": function( elem ) {
1233
1243
  return elem.disabled === false && !$(elem).is('fieldset[disabled] *');
@@ -1331,7 +1341,7 @@ webshims.register('form-core', function($, webshims, window, document, undefined
1331
1341
  if(webshims.errorbox && webshims.errorbox.initIvalContentMessage){
1332
1342
  webshims.errorbox.initIvalContentMessage(elem);
1333
1343
  }
1334
- var message = (webshims.getOptions && webshims.errorbox ? webshims.getOptions(elem, 'errormessage') : $(elem).data('errormessage')) || elem.getAttribute('x-moz-errormessage') || '';
1344
+ var message = (webshims.getOptions && webshims.errorbox ? webshims.getOptions(elem, 'errormessage', false, true) : $(elem).data('errormessage')) || elem.getAttribute('x-moz-errormessage') || '';
1335
1345
  if(key && message[key]){
1336
1346
  message = message[key];
1337
1347
  } else if(message) {
@@ -1382,10 +1392,8 @@ webshims.register('form-core', function($, webshims, window, document, undefined
1382
1392
  }
1383
1393
  });
1384
1394
  webshims.ready('WINDOWLOAD', lazyLoad);
1385
-
1386
1395
  });
1387
-
1388
- webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
1396
+ ;webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
1389
1397
  "use strict";
1390
1398
  var doc = document;
1391
1399
  var lazyLoad = function(name){
@@ -0,0 +1,2343 @@
1
+ // Copyright 2009-2012 by contributors, MIT License
2
+ // vim: ts=4 sts=4 sw=4 expandtab
3
+
4
+ (function () {
5
+
6
+ /**
7
+ * Brings an environment as close to ECMAScript 5 compliance
8
+ * as is possible with the facilities of erstwhile engines.
9
+ *
10
+ * Annotated ES5: http://es5.github.com/ (specific links below)
11
+ * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
12
+ * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
13
+ */
14
+
15
+ //
16
+ // Function
17
+ // ========
18
+ //
19
+
20
+ // ES-5 15.3.4.5
21
+ // http://es5.github.com/#x15.3.4.5
22
+
23
+ function Empty() {}
24
+
25
+ if (!Function.prototype.bind) {
26
+ Function.prototype.bind = function bind(that) { // .length is 1
27
+ // 1. Let Target be the this value.
28
+ var target = this;
29
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
30
+ if (typeof target != "function") {
31
+ throw new TypeError("Function.prototype.bind called on incompatible " + target);
32
+ }
33
+ // 3. Let A be a new (possibly empty) internal list of all of the
34
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
35
+ // XXX slicedArgs will stand in for "A" if used
36
+ var args = _Array_slice_.call(arguments, 1); // for normal call
37
+ // 4. Let F be a new native ECMAScript object.
38
+ // 11. Set the [[Prototype]] internal property of F to the standard
39
+ // built-in Function prototype object as specified in 15.3.3.1.
40
+ // 12. Set the [[Call]] internal property of F as described in
41
+ // 15.3.4.5.1.
42
+ // 13. Set the [[Construct]] internal property of F as described in
43
+ // 15.3.4.5.2.
44
+ // 14. Set the [[HasInstance]] internal property of F as described in
45
+ // 15.3.4.5.3.
46
+ var bound = function () {
47
+
48
+ if (this instanceof bound) {
49
+ // 15.3.4.5.2 [[Construct]]
50
+ // When the [[Construct]] internal method of a function object,
51
+ // F that was created using the bind function is called with a
52
+ // list of arguments ExtraArgs, the following steps are taken:
53
+ // 1. Let target be the value of F's [[TargetFunction]]
54
+ // internal property.
55
+ // 2. If target has no [[Construct]] internal method, a
56
+ // TypeError exception is thrown.
57
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
58
+ // property.
59
+ // 4. Let args be a new list containing the same values as the
60
+ // list boundArgs in the same order followed by the same
61
+ // values as the list ExtraArgs in the same order.
62
+ // 5. Return the result of calling the [[Construct]] internal
63
+ // method of target providing args as the arguments.
64
+
65
+ var result = target.apply(
66
+ this,
67
+ args.concat(_Array_slice_.call(arguments))
68
+ );
69
+ if (Object(result) === result) {
70
+ return result;
71
+ }
72
+ return this;
73
+
74
+ } else {
75
+ // 15.3.4.5.1 [[Call]]
76
+ // When the [[Call]] internal method of a function object, F,
77
+ // which was created using the bind function is called with a
78
+ // this value and a list of arguments ExtraArgs, the following
79
+ // steps are taken:
80
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
81
+ // property.
82
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
83
+ // property.
84
+ // 3. Let target be the value of F's [[TargetFunction]] internal
85
+ // property.
86
+ // 4. Let args be a new list containing the same values as the
87
+ // list boundArgs in the same order followed by the same
88
+ // values as the list ExtraArgs in the same order.
89
+ // 5. Return the result of calling the [[Call]] internal method
90
+ // of target providing boundThis as the this value and
91
+ // providing args as the arguments.
92
+
93
+ // equiv: target.call(this, ...boundArgs, ...args)
94
+ return target.apply(
95
+ that,
96
+ args.concat(_Array_slice_.call(arguments))
97
+ );
98
+
99
+ }
100
+
101
+ };
102
+ if(target.prototype) {
103
+ Empty.prototype = target.prototype;
104
+ bound.prototype = new Empty();
105
+ // Clean up dangling references.
106
+ Empty.prototype = null;
107
+ }
108
+ // XXX bound.length is never writable, so don't even try
109
+ //
110
+ // 15. If the [[Class]] internal property of Target is "Function", then
111
+ // a. Let L be the length property of Target minus the length of A.
112
+ // b. Set the length own property of F to either 0 or L, whichever is
113
+ // larger.
114
+ // 16. Else set the length own property of F to 0.
115
+ // 17. Set the attributes of the length own property of F to the values
116
+ // specified in 15.3.5.1.
117
+
118
+ // TODO
119
+ // 18. Set the [[Extensible]] internal property of F to true.
120
+
121
+ // TODO
122
+ // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
123
+ // 20. Call the [[DefineOwnProperty]] internal method of F with
124
+ // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
125
+ // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
126
+ // false.
127
+ // 21. Call the [[DefineOwnProperty]] internal method of F with
128
+ // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
129
+ // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
130
+ // and false.
131
+
132
+ // TODO
133
+ // NOTE Function objects created using Function.prototype.bind do not
134
+ // have a prototype property or the [[Code]], [[FormalParameters]], and
135
+ // [[Scope]] internal properties.
136
+ // XXX can't delete prototype in pure-js.
137
+
138
+ // 22. Return F.
139
+ return bound;
140
+ };
141
+ }
142
+
143
+ // Shortcut to an often accessed properties, in order to avoid multiple
144
+ // dereference that costs universally.
145
+ // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
146
+ // us it in defining shortcuts.
147
+ var call = Function.prototype.call;
148
+ var prototypeOfArray = Array.prototype;
149
+ var prototypeOfObject = Object.prototype;
150
+ var _Array_slice_ = prototypeOfArray.slice;
151
+ // Having a toString local variable name breaks in Opera so use _toString.
152
+ var _toString = call.bind(prototypeOfObject.toString);
153
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
154
+
155
+ // If JS engine supports accessors creating shortcuts.
156
+ var defineGetter;
157
+ var defineSetter;
158
+ var lookupGetter;
159
+ var lookupSetter;
160
+ var supportsAccessors;
161
+ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
162
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
163
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
164
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
165
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
166
+ }
167
+
168
+ //
169
+ // Array
170
+ // =====
171
+ //
172
+
173
+ // ES5 15.4.4.12
174
+ // http://es5.github.com/#x15.4.4.12
175
+ // Default value for second param
176
+ // [bugfix, ielt9, old browsers]
177
+ // IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12"
178
+ if ([1,2].splice(0).length != 2) {
179
+ var array_splice = Array.prototype.splice;
180
+
181
+ if(function() { // test IE < 9 to splice bug - see issue #138
182
+ function makeArray(l) {
183
+ var a = [];
184
+ while (l--) {
185
+ a.unshift(l)
186
+ }
187
+ return a
188
+ }
189
+
190
+ var array = []
191
+ , lengthBefore
192
+ ;
193
+
194
+ array.splice.bind(array, 0, 0).apply(null, makeArray(20));
195
+ array.splice.bind(array, 0, 0).apply(null, makeArray(26));
196
+
197
+ lengthBefore = array.length; //20
198
+ array.splice(5, 0, "XXX"); // add one element
199
+
200
+ if(lengthBefore + 1 == array.length) {
201
+ return true;// has right splice implementation without bugs
202
+ }
203
+ // else {
204
+ // IE8 bug
205
+ // }
206
+ }()) {//IE 6/7
207
+ Array.prototype.splice = function(start, deleteCount) {
208
+ if (!arguments.length) {
209
+ return [];
210
+ } else {
211
+ return array_splice.apply(this, [
212
+ start === void 0 ? 0 : start,
213
+ deleteCount === void 0 ? (this.length - start) : deleteCount
214
+ ].concat(_Array_slice_.call(arguments, 2)))
215
+ }
216
+ };
217
+ }
218
+ else {//IE8
219
+ Array.prototype.splice = function(start, deleteCount) {
220
+ var result
221
+ , args = _Array_slice_.call(arguments, 2)
222
+ , addElementsCount = args.length
223
+ ;
224
+
225
+ if(!arguments.length) {
226
+ return [];
227
+ }
228
+
229
+ if(start === void 0) { // default
230
+ start = 0;
231
+ }
232
+ if(deleteCount === void 0) { // default
233
+ deleteCount = this.length - start;
234
+ }
235
+
236
+ if(addElementsCount > 0) {
237
+ if(deleteCount <= 0) {
238
+ if(start == this.length) { // tiny optimisation #1
239
+ this.push.apply(this, args);
240
+ return [];
241
+ }
242
+
243
+ if(start == 0) { // tiny optimisation #2
244
+ this.unshift.apply(this, args);
245
+ return [];
246
+ }
247
+ }
248
+
249
+ // Array.prototype.splice implementation
250
+ result = _Array_slice_.call(this, start, start + deleteCount);// delete part
251
+ args.push.apply(args, _Array_slice_.call(this, start + deleteCount, this.length));// right part
252
+ args.unshift.apply(args, _Array_slice_.call(this, 0, start));// left part
253
+
254
+ // delete all items from this array and replace it to 'left part' + _Array_slice_.call(arguments, 2) + 'right part'
255
+ args.unshift(0, this.length);
256
+
257
+ array_splice.apply(this, args);
258
+
259
+ return result;
260
+ }
261
+
262
+ return array_splice.call(this, start, deleteCount);
263
+ }
264
+
265
+ }
266
+ }
267
+
268
+ // ES5 15.4.4.12
269
+ // http://es5.github.com/#x15.4.4.13
270
+ // Return len+argCount.
271
+ // [bugfix, ielt8]
272
+ // IE < 8 bug: [].unshift(0) == undefined but should be "1"
273
+ if ([].unshift(0) != 1) {
274
+ var array_unshift = Array.prototype.unshift;
275
+ Array.prototype.unshift = function() {
276
+ array_unshift.apply(this, arguments);
277
+ return this.length;
278
+ };
279
+ }
280
+
281
+ // ES5 15.4.3.2
282
+ // http://es5.github.com/#x15.4.3.2
283
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
284
+ if (!Array.isArray) {
285
+ Array.isArray = function isArray(obj) {
286
+ return _toString(obj) == "[object Array]";
287
+ };
288
+ }
289
+
290
+ // The IsCallable() check in the Array functions
291
+ // has been replaced with a strict check on the
292
+ // internal class of the object to trap cases where
293
+ // the provided function was actually a regular
294
+ // expression literal, which in V8 and
295
+ // JavaScriptCore is a typeof "function". Only in
296
+ // V8 are regular expression literals permitted as
297
+ // reduce parameters, so it is desirable in the
298
+ // general case for the shim to match the more
299
+ // strict and common behavior of rejecting regular
300
+ // expressions.
301
+
302
+ // ES5 15.4.4.18
303
+ // http://es5.github.com/#x15.4.4.18
304
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
305
+
306
+ // Check failure of by-index access of string characters (IE < 9)
307
+ // and failure of `0 in boxedString` (Rhino)
308
+ var boxedString = Object("a"),
309
+ splitString = boxedString[0] != "a" || !(0 in boxedString);
310
+
311
+ if (!Array.prototype.forEach) {
312
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
313
+ var object = toObject(this),
314
+ self = splitString && _toString(this) == "[object String]" ?
315
+ this.split("") :
316
+ object,
317
+ thisp = arguments[1],
318
+ i = -1,
319
+ length = self.length >>> 0;
320
+
321
+ // If no callback function or if callback is not a callable function
322
+ if (_toString(fun) != "[object Function]") {
323
+ throw new TypeError(); // TODO message
324
+ }
325
+
326
+ while (++i < length) {
327
+ if (i in self) {
328
+ // Invoke the callback function with call, passing arguments:
329
+ // context, property value, property key, thisArg object
330
+ // context
331
+ fun.call(thisp, self[i], i, object);
332
+ }
333
+ }
334
+ };
335
+ }
336
+
337
+ // ES5 15.4.4.19
338
+ // http://es5.github.com/#x15.4.4.19
339
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
340
+ if (!Array.prototype.map) {
341
+ Array.prototype.map = function map(fun /*, thisp*/) {
342
+ var object = toObject(this),
343
+ self = splitString && _toString(this) == "[object String]" ?
344
+ this.split("") :
345
+ object,
346
+ length = self.length >>> 0,
347
+ result = Array(length),
348
+ thisp = arguments[1];
349
+
350
+ // If no callback function or if callback is not a callable function
351
+ if (_toString(fun) != "[object Function]") {
352
+ throw new TypeError(fun + " is not a function");
353
+ }
354
+
355
+ for (var i = 0; i < length; i++) {
356
+ if (i in self)
357
+ result[i] = fun.call(thisp, self[i], i, object);
358
+ }
359
+ return result;
360
+ };
361
+ }
362
+
363
+ // ES5 15.4.4.20
364
+ // http://es5.github.com/#x15.4.4.20
365
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
366
+ if (!Array.prototype.filter) {
367
+ Array.prototype.filter = function filter(fun /*, thisp */) {
368
+ var object = toObject(this),
369
+ self = splitString && _toString(this) == "[object String]" ?
370
+ this.split("") :
371
+ object,
372
+ length = self.length >>> 0,
373
+ result = [],
374
+ value,
375
+ thisp = arguments[1];
376
+
377
+ // If no callback function or if callback is not a callable function
378
+ if (_toString(fun) != "[object Function]") {
379
+ throw new TypeError(fun + " is not a function");
380
+ }
381
+
382
+ for (var i = 0; i < length; i++) {
383
+ if (i in self) {
384
+ value = self[i];
385
+ if (fun.call(thisp, value, i, object)) {
386
+ result.push(value);
387
+ }
388
+ }
389
+ }
390
+ return result;
391
+ };
392
+ }
393
+
394
+ // ES5 15.4.4.16
395
+ // http://es5.github.com/#x15.4.4.16
396
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
397
+ if (!Array.prototype.every) {
398
+ Array.prototype.every = function every(fun /*, thisp */) {
399
+ var object = toObject(this),
400
+ self = splitString && _toString(this) == "[object String]" ?
401
+ this.split("") :
402
+ object,
403
+ length = self.length >>> 0,
404
+ thisp = arguments[1];
405
+
406
+ // If no callback function or if callback is not a callable function
407
+ if (_toString(fun) != "[object Function]") {
408
+ throw new TypeError(fun + " is not a function");
409
+ }
410
+
411
+ for (var i = 0; i < length; i++) {
412
+ if (i in self && !fun.call(thisp, self[i], i, object)) {
413
+ return false;
414
+ }
415
+ }
416
+ return true;
417
+ };
418
+ }
419
+
420
+ // ES5 15.4.4.17
421
+ // http://es5.github.com/#x15.4.4.17
422
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
423
+ if (!Array.prototype.some) {
424
+ Array.prototype.some = function some(fun /*, thisp */) {
425
+ var object = toObject(this),
426
+ self = splitString && _toString(this) == "[object String]" ?
427
+ this.split("") :
428
+ object,
429
+ length = self.length >>> 0,
430
+ thisp = arguments[1];
431
+
432
+ // If no callback function or if callback is not a callable function
433
+ if (_toString(fun) != "[object Function]") {
434
+ throw new TypeError(fun + " is not a function");
435
+ }
436
+
437
+ for (var i = 0; i < length; i++) {
438
+ if (i in self && fun.call(thisp, self[i], i, object)) {
439
+ return true;
440
+ }
441
+ }
442
+ return false;
443
+ };
444
+ }
445
+
446
+ // ES5 15.4.4.21
447
+ // http://es5.github.com/#x15.4.4.21
448
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
449
+ if (!Array.prototype.reduce) {
450
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
451
+ var object = toObject(this),
452
+ self = splitString && _toString(this) == "[object String]" ?
453
+ this.split("") :
454
+ object,
455
+ length = self.length >>> 0;
456
+
457
+ // If no callback function or if callback is not a callable function
458
+ if (_toString(fun) != "[object Function]") {
459
+ throw new TypeError(fun + " is not a function");
460
+ }
461
+
462
+ // no value to return if no initial value and an empty array
463
+ if (!length && arguments.length == 1) {
464
+ throw new TypeError("reduce of empty array with no initial value");
465
+ }
466
+
467
+ var i = 0;
468
+ var result;
469
+ if (arguments.length >= 2) {
470
+ result = arguments[1];
471
+ } else {
472
+ do {
473
+ if (i in self) {
474
+ result = self[i++];
475
+ break;
476
+ }
477
+
478
+ // if array contains no values, no initial value to return
479
+ if (++i >= length) {
480
+ throw new TypeError("reduce of empty array with no initial value");
481
+ }
482
+ } while (true);
483
+ }
484
+
485
+ for (; i < length; i++) {
486
+ if (i in self) {
487
+ result = fun.call(void 0, result, self[i], i, object);
488
+ }
489
+ }
490
+
491
+ return result;
492
+ };
493
+ }
494
+
495
+ // ES5 15.4.4.22
496
+ // http://es5.github.com/#x15.4.4.22
497
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
498
+ if (!Array.prototype.reduceRight) {
499
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
500
+ var object = toObject(this),
501
+ self = splitString && _toString(this) == "[object String]" ?
502
+ this.split("") :
503
+ object,
504
+ length = self.length >>> 0;
505
+
506
+ // If no callback function or if callback is not a callable function
507
+ if (_toString(fun) != "[object Function]") {
508
+ throw new TypeError(fun + " is not a function");
509
+ }
510
+
511
+ // no value to return if no initial value, empty array
512
+ if (!length && arguments.length == 1) {
513
+ throw new TypeError("reduceRight of empty array with no initial value");
514
+ }
515
+
516
+ var result, i = length - 1;
517
+ if (arguments.length >= 2) {
518
+ result = arguments[1];
519
+ } else {
520
+ do {
521
+ if (i in self) {
522
+ result = self[i--];
523
+ break;
524
+ }
525
+
526
+ // if array contains no values, no initial value to return
527
+ if (--i < 0) {
528
+ throw new TypeError("reduceRight of empty array with no initial value");
529
+ }
530
+ } while (true);
531
+ }
532
+
533
+ if (i < 0) {
534
+ return result;
535
+ }
536
+
537
+ do {
538
+ if (i in this) {
539
+ result = fun.call(void 0, result, self[i], i, object);
540
+ }
541
+ } while (i--);
542
+
543
+ return result;
544
+ };
545
+ }
546
+
547
+ // ES5 15.4.4.14
548
+ // http://es5.github.com/#x15.4.4.14
549
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
550
+ if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
551
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
552
+ var self = splitString && _toString(this) == "[object String]" ?
553
+ this.split("") :
554
+ toObject(this),
555
+ length = self.length >>> 0;
556
+
557
+ if (!length) {
558
+ return -1;
559
+ }
560
+
561
+ var i = 0;
562
+ if (arguments.length > 1) {
563
+ i = toInteger(arguments[1]);
564
+ }
565
+
566
+ // handle negative indices
567
+ i = i >= 0 ? i : Math.max(0, length + i);
568
+ for (; i < length; i++) {
569
+ if (i in self && self[i] === sought) {
570
+ return i;
571
+ }
572
+ }
573
+ return -1;
574
+ };
575
+ }
576
+
577
+ // ES5 15.4.4.15
578
+ // http://es5.github.com/#x15.4.4.15
579
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
580
+ if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
581
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
582
+ var self = splitString && _toString(this) == "[object String]" ?
583
+ this.split("") :
584
+ toObject(this),
585
+ length = self.length >>> 0;
586
+
587
+ if (!length) {
588
+ return -1;
589
+ }
590
+ var i = length - 1;
591
+ if (arguments.length > 1) {
592
+ i = Math.min(i, toInteger(arguments[1]));
593
+ }
594
+ // handle negative indices
595
+ i = i >= 0 ? i : length - Math.abs(i);
596
+ for (; i >= 0; i--) {
597
+ if (i in self && sought === self[i]) {
598
+ return i;
599
+ }
600
+ }
601
+ return -1;
602
+ };
603
+ }
604
+
605
+ //
606
+ // Object
607
+ // ======
608
+ //
609
+
610
+ // ES5 15.2.3.14
611
+ // http://es5.github.com/#x15.2.3.14
612
+ if (!Object.keys) {
613
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
614
+ var hasDontEnumBug = true,
615
+ dontEnums = [
616
+ "toString",
617
+ "toLocaleString",
618
+ "valueOf",
619
+ "hasOwnProperty",
620
+ "isPrototypeOf",
621
+ "propertyIsEnumerable",
622
+ "constructor"
623
+ ],
624
+ dontEnumsLength = dontEnums.length;
625
+
626
+ for (var key in {"toString": null}) {
627
+ hasDontEnumBug = false;
628
+ }
629
+
630
+ Object.keys = function keys(object) {
631
+
632
+ if (
633
+ (typeof object != "object" && typeof object != "function") ||
634
+ object === null
635
+ ) {
636
+ throw new TypeError("Object.keys called on a non-object");
637
+ }
638
+
639
+ var keys = [];
640
+ for (var name in object) {
641
+ if (owns(object, name)) {
642
+ keys.push(name);
643
+ }
644
+ }
645
+
646
+ if (hasDontEnumBug) {
647
+ for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
648
+ var dontEnum = dontEnums[i];
649
+ if (owns(object, dontEnum)) {
650
+ keys.push(dontEnum);
651
+ }
652
+ }
653
+ }
654
+ return keys;
655
+ };
656
+
657
+ }
658
+
659
+ //
660
+ // Date
661
+ // ====
662
+ //
663
+
664
+ // ES5 15.9.5.43
665
+ // http://es5.github.com/#x15.9.5.43
666
+ // This function returns a String value represent the instance in time
667
+ // represented by this Date object. The format of the String is the Date Time
668
+ // string format defined in 15.9.1.15. All fields are present in the String.
669
+ // The time zone is always UTC, denoted by the suffix Z. If the time value of
670
+ // this object is not a finite Number a RangeError exception is thrown.
671
+ var negativeDate = -62198755200000,
672
+ negativeYearString = "-000001";
673
+ if (
674
+ !Date.prototype.toISOString ||
675
+ (new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1)
676
+ ) {
677
+ Date.prototype.toISOString = function toISOString() {
678
+ var result, length, value, year, month;
679
+ if (!isFinite(this)) {
680
+ throw new RangeError("Date.prototype.toISOString called on non-finite value.");
681
+ }
682
+
683
+ year = this.getUTCFullYear();
684
+
685
+ month = this.getUTCMonth();
686
+ // see https://github.com/kriskowal/es5-shim/issues/111
687
+ year += Math.floor(month / 12);
688
+ month = (month % 12 + 12) % 12;
689
+
690
+ // the date time string format is specified in 15.9.1.15.
691
+ result = [month + 1, this.getUTCDate(),
692
+ this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
693
+ year = (
694
+ (year < 0 ? "-" : (year > 9999 ? "+" : "")) +
695
+ ("00000" + Math.abs(year))
696
+ .slice(0 <= year && year <= 9999 ? -4 : -6)
697
+ );
698
+
699
+ length = result.length;
700
+ while (length--) {
701
+ value = result[length];
702
+ // pad months, days, hours, minutes, and seconds to have two
703
+ // digits.
704
+ if (value < 10) {
705
+ result[length] = "0" + value;
706
+ }
707
+ }
708
+ // pad milliseconds to have three digits.
709
+ return (
710
+ year + "-" + result.slice(0, 2).join("-") +
711
+ "T" + result.slice(2).join(":") + "." +
712
+ ("000" + this.getUTCMilliseconds()).slice(-3) + "Z"
713
+ );
714
+ };
715
+ }
716
+
717
+
718
+ // ES5 15.9.5.44
719
+ // http://es5.github.com/#x15.9.5.44
720
+ // This function provides a String representation of a Date object for use by
721
+ // JSON.stringify (15.12.3).
722
+ var dateToJSONIsSupported = false;
723
+ try {
724
+ dateToJSONIsSupported = (
725
+ Date.prototype.toJSON &&
726
+ new Date(NaN).toJSON() === null &&
727
+ new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
728
+ Date.prototype.toJSON.call({ // generic
729
+ toISOString: function () {
730
+ return true;
731
+ }
732
+ })
733
+ );
734
+ } catch (e) {
735
+ }
736
+ if (!dateToJSONIsSupported) {
737
+ Date.prototype.toJSON = function toJSON(key) {
738
+ // When the toJSON method is called with argument key, the following
739
+ // steps are taken:
740
+
741
+ // 1. Let O be the result of calling ToObject, giving it the this
742
+ // value as its argument.
743
+ // 2. Let tv be toPrimitive(O, hint Number).
744
+ var o = Object(this),
745
+ tv = toPrimitive(o),
746
+ toISO;
747
+ // 3. If tv is a Number and is not finite, return null.
748
+ if (typeof tv === "number" && !isFinite(tv)) {
749
+ return null;
750
+ }
751
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
752
+ // O with argument "toISOString".
753
+ toISO = o.toISOString;
754
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
755
+ if (typeof toISO != "function") {
756
+ throw new TypeError("toISOString property is not callable");
757
+ }
758
+ // 6. Return the result of calling the [[Call]] internal method of
759
+ // toISO with O as the this value and an empty argument list.
760
+ return toISO.call(o);
761
+
762
+ // NOTE 1 The argument is ignored.
763
+
764
+ // NOTE 2 The toJSON function is intentionally generic; it does not
765
+ // require that its this value be a Date object. Therefore, it can be
766
+ // transferred to other kinds of objects for use as a method. However,
767
+ // it does require that any such object have a toISOString method. An
768
+ // object is free to use the argument key to filter its
769
+ // stringification.
770
+ };
771
+ }
772
+
773
+ // ES5 15.9.4.2
774
+ // http://es5.github.com/#x15.9.4.2
775
+ // based on work shared by Daniel Friesen (dantman)
776
+ // http://gist.github.com/303249
777
+ if (!Date.parse || "Date.parse is buggy") {
778
+ // XXX global assignment won't work in embeddings that use
779
+ // an alternate object for the context.
780
+ Date = (function(NativeDate) {
781
+
782
+ // Date.length === 7
783
+ function Date(Y, M, D, h, m, s, ms) {
784
+ var length = arguments.length;
785
+ if (this instanceof NativeDate) {
786
+ var date = length == 1 && String(Y) === Y ? // isString(Y)
787
+ // We explicitly pass it through parse:
788
+ new NativeDate(Date.parse(Y)) :
789
+ // We have to manually make calls depending on argument
790
+ // length here
791
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
792
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
793
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
794
+ length >= 4 ? new NativeDate(Y, M, D, h) :
795
+ length >= 3 ? new NativeDate(Y, M, D) :
796
+ length >= 2 ? new NativeDate(Y, M) :
797
+ length >= 1 ? new NativeDate(Y) :
798
+ new NativeDate();
799
+ // Prevent mixups with unfixed Date object
800
+ date.constructor = Date;
801
+ return date;
802
+ }
803
+ return NativeDate.apply(this, arguments);
804
+ };
805
+
806
+ // 15.9.1.15 Date Time String Format.
807
+ var isoDateExpression = new RegExp("^" +
808
+ "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign +
809
+ // 6-digit extended year
810
+ "(?:-(\\d{2})" + // optional month capture
811
+ "(?:-(\\d{2})" + // optional day capture
812
+ "(?:" + // capture hours:minutes:seconds.milliseconds
813
+ "T(\\d{2})" + // hours capture
814
+ ":(\\d{2})" + // minutes capture
815
+ "(?:" + // optional :seconds.milliseconds
816
+ ":(\\d{2})" + // seconds capture
817
+ "(?:(\\.\\d{1,}))?" + // milliseconds capture
818
+ ")?" +
819
+ "(" + // capture UTC offset component
820
+ "Z|" + // UTC capture
821
+ "(?:" + // offset specifier +/-hours:minutes
822
+ "([-+])" + // sign capture
823
+ "(\\d{2})" + // hours offset capture
824
+ ":(\\d{2})" + // minutes offset capture
825
+ ")" +
826
+ ")?)?)?)?" +
827
+ "$");
828
+
829
+ var months = [
830
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
831
+ ];
832
+
833
+ function dayFromMonth(year, month) {
834
+ var t = month > 1 ? 1 : 0;
835
+ return (
836
+ months[month] +
837
+ Math.floor((year - 1969 + t) / 4) -
838
+ Math.floor((year - 1901 + t) / 100) +
839
+ Math.floor((year - 1601 + t) / 400) +
840
+ 365 * (year - 1970)
841
+ );
842
+ }
843
+
844
+ // Copy any custom methods a 3rd party library may have added
845
+ for (var key in NativeDate) {
846
+ Date[key] = NativeDate[key];
847
+ }
848
+
849
+ // Copy "native" methods explicitly; they may be non-enumerable
850
+ Date.now = NativeDate.now;
851
+ Date.UTC = NativeDate.UTC;
852
+ Date.prototype = NativeDate.prototype;
853
+ Date.prototype.constructor = Date;
854
+
855
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
856
+ Date.parse = function parse(string) {
857
+ var match = isoDateExpression.exec(string);
858
+ if (match) {
859
+ // parse months, days, hours, minutes, seconds, and milliseconds
860
+ // provide default values if necessary
861
+ // parse the UTC offset component
862
+ var year = Number(match[1]),
863
+ month = Number(match[2] || 1) - 1,
864
+ day = Number(match[3] || 1) - 1,
865
+ hour = Number(match[4] || 0),
866
+ minute = Number(match[5] || 0),
867
+ second = Number(match[6] || 0),
868
+ millisecond = Math.floor(Number(match[7] || 0) * 1000),
869
+ // When time zone is missed, local offset should be used
870
+ // (ES 5.1 bug)
871
+ // see https://bugs.ecmascript.org/show_bug.cgi?id=112
872
+ offset = !match[4] || match[8] ?
873
+ 0 : Number(new NativeDate(1970, 0)),
874
+ signOffset = match[9] === "-" ? 1 : -1,
875
+ hourOffset = Number(match[10] || 0),
876
+ minuteOffset = Number(match[11] || 0),
877
+ result;
878
+ if (
879
+ hour < (
880
+ minute > 0 || second > 0 || millisecond > 0 ?
881
+ 24 : 25
882
+ ) &&
883
+ minute < 60 && second < 60 && millisecond < 1000 &&
884
+ month > -1 && month < 12 && hourOffset < 24 &&
885
+ minuteOffset < 60 && // detect invalid offsets
886
+ day > -1 &&
887
+ day < (
888
+ dayFromMonth(year, month + 1) -
889
+ dayFromMonth(year, month)
890
+ )
891
+ ) {
892
+ result = (
893
+ (dayFromMonth(year, month) + day) * 24 +
894
+ hour +
895
+ hourOffset * signOffset
896
+ ) * 60;
897
+ result = (
898
+ (result + minute + minuteOffset * signOffset) * 60 +
899
+ second
900
+ ) * 1000 + millisecond + offset;
901
+ if (-8.64e15 <= result && result <= 8.64e15) {
902
+ return result;
903
+ }
904
+ }
905
+ return NaN;
906
+ }
907
+ return NativeDate.parse.apply(this, arguments);
908
+ };
909
+
910
+ return Date;
911
+ })(Date);
912
+ }
913
+
914
+ // ES5 15.9.4.4
915
+ // http://es5.github.com/#x15.9.4.4
916
+ if (!Date.now) {
917
+ Date.now = function now() {
918
+ return new Date().getTime();
919
+ };
920
+ }
921
+
922
+
923
+ //
924
+ // Number
925
+ // ======
926
+ //
927
+
928
+ // ES5.1 15.7.4.5
929
+ // http://es5.github.com/#x15.7.4.5
930
+ if (!Number.prototype.toFixed || (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) === '0' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== "1000000000000000128") {
931
+ // Hide these variables and functions
932
+ (function () {
933
+ var base, size, data, i;
934
+
935
+ base = 1e7;
936
+ size = 6;
937
+ data = [0, 0, 0, 0, 0, 0];
938
+
939
+ function multiply(n, c) {
940
+ var i = -1;
941
+ while (++i < size) {
942
+ c += n * data[i];
943
+ data[i] = c % base;
944
+ c = Math.floor(c / base);
945
+ }
946
+ }
947
+
948
+ function divide(n) {
949
+ var i = size, c = 0;
950
+ while (--i >= 0) {
951
+ c += data[i];
952
+ data[i] = Math.floor(c / n);
953
+ c = (c % n) * base;
954
+ }
955
+ }
956
+
957
+ function toString() {
958
+ var i = size;
959
+ var s = '';
960
+ while (--i >= 0) {
961
+ if (s !== '' || i === 0 || data[i] !== 0) {
962
+ var t = String(data[i]);
963
+ if (s === '') {
964
+ s = t;
965
+ } else {
966
+ s += '0000000'.slice(0, 7 - t.length) + t;
967
+ }
968
+ }
969
+ }
970
+ return s;
971
+ }
972
+
973
+ function pow(x, n, acc) {
974
+ return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
975
+ }
976
+
977
+ function log(x) {
978
+ var n = 0;
979
+ while (x >= 4096) {
980
+ n += 12;
981
+ x /= 4096;
982
+ }
983
+ while (x >= 2) {
984
+ n += 1;
985
+ x /= 2;
986
+ }
987
+ return n;
988
+ }
989
+
990
+ Number.prototype.toFixed = function (fractionDigits) {
991
+ var f, x, s, m, e, z, j, k;
992
+
993
+ // Test for NaN and round fractionDigits down
994
+ f = Number(fractionDigits);
995
+ f = f !== f ? 0 : Math.floor(f);
996
+
997
+ if (f < 0 || f > 20) {
998
+ throw new RangeError("Number.toFixed called with invalid number of decimals");
999
+ }
1000
+
1001
+ x = Number(this);
1002
+
1003
+ // Test for NaN
1004
+ if (x !== x) {
1005
+ return "NaN";
1006
+ }
1007
+
1008
+ // If it is too big or small, return the string value of the number
1009
+ if (x <= -1e21 || x >= 1e21) {
1010
+ return String(x);
1011
+ }
1012
+
1013
+ s = "";
1014
+
1015
+ if (x < 0) {
1016
+ s = "-";
1017
+ x = -x;
1018
+ }
1019
+
1020
+ m = "0";
1021
+
1022
+ if (x > 1e-21) {
1023
+ // 1e-21 < x < 1e21
1024
+ // -70 < log2(x) < 70
1025
+ e = log(x * pow(2, 69, 1)) - 69;
1026
+ z = (e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1));
1027
+ z *= 0x10000000000000; // Math.pow(2, 52);
1028
+ e = 52 - e;
1029
+
1030
+ // -18 < e < 122
1031
+ // x = z / 2 ^ e
1032
+ if (e > 0) {
1033
+ multiply(0, z);
1034
+ j = f;
1035
+
1036
+ while (j >= 7) {
1037
+ multiply(1e7, 0);
1038
+ j -= 7;
1039
+ }
1040
+
1041
+ multiply(pow(10, j, 1), 0);
1042
+ j = e - 1;
1043
+
1044
+ while (j >= 23) {
1045
+ divide(1 << 23);
1046
+ j -= 23;
1047
+ }
1048
+
1049
+ divide(1 << j);
1050
+ multiply(1, 1);
1051
+ divide(2);
1052
+ m = toString();
1053
+ } else {
1054
+ multiply(0, z);
1055
+ multiply(1 << (-e), 0);
1056
+ m = toString() + '0.00000000000000000000'.slice(2, 2 + f);
1057
+ }
1058
+ }
1059
+
1060
+ if (f > 0) {
1061
+ k = m.length;
1062
+
1063
+ if (k <= f) {
1064
+ m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
1065
+ } else {
1066
+ m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
1067
+ }
1068
+ } else {
1069
+ m = s + m;
1070
+ }
1071
+
1072
+ return m;
1073
+ }
1074
+ }());
1075
+ }
1076
+
1077
+
1078
+ //
1079
+ // String
1080
+ // ======
1081
+ //
1082
+
1083
+
1084
+ // ES5 15.5.4.14
1085
+ // http://es5.github.com/#x15.5.4.14
1086
+
1087
+ // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
1088
+ // Many browsers do not split properly with regular expressions or they
1089
+ // do not perform the split correctly under obscure conditions.
1090
+ // See http://blog.stevenlevithan.com/archives/cross-browser-split
1091
+ // I've tested in many browsers and this seems to cover the deviant ones:
1092
+ // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
1093
+ // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
1094
+ // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
1095
+ // [undefined, "t", undefined, "e", ...]
1096
+ // ''.split(/.?/) should be [], not [""]
1097
+ // '.'.split(/()()/) should be ["."], not ["", "", "."]
1098
+
1099
+ var string_split = String.prototype.split;
1100
+ if (
1101
+ 'ab'.split(/(?:ab)*/).length !== 2 ||
1102
+ '.'.split(/(.?)(.?)/).length !== 4 ||
1103
+ 'tesst'.split(/(s)*/)[1] === "t" ||
1104
+ ''.split(/.?/).length === 0 ||
1105
+ '.'.split(/()()/).length > 1
1106
+ ) {
1107
+ (function () {
1108
+ var compliantExecNpcg = /()??/.exec("")[1] === void 0; // NPCG: nonparticipating capturing group
1109
+
1110
+ String.prototype.split = function (separator, limit) {
1111
+ var string = this;
1112
+ if (separator === void 0 && limit === 0)
1113
+ return [];
1114
+
1115
+ // If `separator` is not a regex, use native split
1116
+ if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
1117
+ return string_split.apply(this, arguments);
1118
+ }
1119
+
1120
+ var output = [],
1121
+ flags = (separator.ignoreCase ? "i" : "") +
1122
+ (separator.multiline ? "m" : "") +
1123
+ (separator.extended ? "x" : "") + // Proposed for ES6
1124
+ (separator.sticky ? "y" : ""), // Firefox 3+
1125
+ lastLastIndex = 0,
1126
+ // Make `global` and avoid `lastIndex` issues by working with a copy
1127
+ separator = new RegExp(separator.source, flags + "g"),
1128
+ separator2, match, lastIndex, lastLength;
1129
+ string += ""; // Type-convert
1130
+ if (!compliantExecNpcg) {
1131
+ // Doesn't need flags gy, but they don't hurt
1132
+ separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
1133
+ }
1134
+ /* Values for `limit`, per the spec:
1135
+ * If undefined: 4294967295 // Math.pow(2, 32) - 1
1136
+ * If 0, Infinity, or NaN: 0
1137
+ * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
1138
+ * If negative number: 4294967296 - Math.floor(Math.abs(limit))
1139
+ * If other: Type-convert, then use the above rules
1140
+ */
1141
+ limit = limit === void 0 ?
1142
+ -1 >>> 0 : // Math.pow(2, 32) - 1
1143
+ limit >>> 0; // ToUint32(limit)
1144
+ while (match = separator.exec(string)) {
1145
+ // `separator.lastIndex` is not reliable cross-browser
1146
+ lastIndex = match.index + match[0].length;
1147
+ if (lastIndex > lastLastIndex) {
1148
+ output.push(string.slice(lastLastIndex, match.index));
1149
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
1150
+ // nonparticipating capturing groups
1151
+ if (!compliantExecNpcg && match.length > 1) {
1152
+ match[0].replace(separator2, function () {
1153
+ for (var i = 1; i < arguments.length - 2; i++) {
1154
+ if (arguments[i] === void 0) {
1155
+ match[i] = void 0;
1156
+ }
1157
+ }
1158
+ });
1159
+ }
1160
+ if (match.length > 1 && match.index < string.length) {
1161
+ Array.prototype.push.apply(output, match.slice(1));
1162
+ }
1163
+ lastLength = match[0].length;
1164
+ lastLastIndex = lastIndex;
1165
+ if (output.length >= limit) {
1166
+ break;
1167
+ }
1168
+ }
1169
+ if (separator.lastIndex === match.index) {
1170
+ separator.lastIndex++; // Avoid an infinite loop
1171
+ }
1172
+ }
1173
+ if (lastLastIndex === string.length) {
1174
+ if (lastLength || !separator.test("")) {
1175
+ output.push("");
1176
+ }
1177
+ } else {
1178
+ output.push(string.slice(lastLastIndex));
1179
+ }
1180
+ return output.length > limit ? output.slice(0, limit) : output;
1181
+ };
1182
+ }());
1183
+
1184
+ // [bugfix, chrome]
1185
+ // If separator is undefined, then the result array contains just one String,
1186
+ // which is the this value (converted to a String). If limit is not undefined,
1187
+ // then the output array is truncated so that it contains no more than limit
1188
+ // elements.
1189
+ // "0".split(undefined, 0) -> []
1190
+ } else if ("0".split(void 0, 0).length) {
1191
+ String.prototype.split = function(separator, limit) {
1192
+ if (separator === void 0 && limit === 0) return [];
1193
+ return string_split.apply(this, arguments);
1194
+ }
1195
+ }
1196
+
1197
+
1198
+ // ECMA-262, 3rd B.2.3
1199
+ // Note an ECMAScript standart, although ECMAScript 3rd Edition has a
1200
+ // non-normative section suggesting uniform semantics and it should be
1201
+ // normalized across all browsers
1202
+ // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
1203
+ if("".substr && "0b".substr(-1) !== "b") {
1204
+ var string_substr = String.prototype.substr;
1205
+ /**
1206
+ * Get the substring of a string
1207
+ * @param {integer} start where to start the substring
1208
+ * @param {integer} length how many characters to return
1209
+ * @return {string}
1210
+ */
1211
+ String.prototype.substr = function(start, length) {
1212
+ return string_substr.call(
1213
+ this,
1214
+ start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
1215
+ length
1216
+ );
1217
+ }
1218
+ }
1219
+
1220
+ // ES5 15.5.4.20
1221
+ // http://es5.github.com/#x15.5.4.20
1222
+ var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
1223
+ "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
1224
+ "\u2029\uFEFF";
1225
+ if (!String.prototype.trim || ws.trim()) {
1226
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1227
+ // http://perfectionkills.com/whitespace-deviations/
1228
+ ws = "[" + ws + "]";
1229
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
1230
+ trimEndRegexp = new RegExp(ws + ws + "*$");
1231
+ String.prototype.trim = function trim() {
1232
+ if (this === void 0 || this === null) {
1233
+ throw new TypeError("can't convert "+this+" to object");
1234
+ }
1235
+ return String(this)
1236
+ .replace(trimBeginRegexp, "")
1237
+ .replace(trimEndRegexp, "");
1238
+ };
1239
+ }
1240
+
1241
+ //
1242
+ // Util
1243
+ // ======
1244
+ //
1245
+
1246
+ // ES5 9.4
1247
+ // http://es5.github.com/#x9.4
1248
+ // http://jsperf.com/to-integer
1249
+
1250
+ function toInteger(n) {
1251
+ n = +n;
1252
+ if (n !== n) { // isNaN
1253
+ n = 0;
1254
+ } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
1255
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
1256
+ }
1257
+ return n;
1258
+ }
1259
+
1260
+ function isPrimitive(input) {
1261
+ var type = typeof input;
1262
+ return (
1263
+ input === null ||
1264
+ type === "undefined" ||
1265
+ type === "boolean" ||
1266
+ type === "number" ||
1267
+ type === "string"
1268
+ );
1269
+ }
1270
+
1271
+ function toPrimitive(input) {
1272
+ var val, valueOf, toString;
1273
+ if (isPrimitive(input)) {
1274
+ return input;
1275
+ }
1276
+ valueOf = input.valueOf;
1277
+ if (typeof valueOf === "function") {
1278
+ val = valueOf.call(input);
1279
+ if (isPrimitive(val)) {
1280
+ return val;
1281
+ }
1282
+ }
1283
+ toString = input.toString;
1284
+ if (typeof toString === "function") {
1285
+ val = toString.call(input);
1286
+ if (isPrimitive(val)) {
1287
+ return val;
1288
+ }
1289
+ }
1290
+ throw new TypeError();
1291
+ }
1292
+
1293
+ // ES5 9.9
1294
+ // http://es5.github.com/#x9.9
1295
+ var toObject = function (o) {
1296
+ if (o == null) { // this matches both null and undefined
1297
+ throw new TypeError("can't convert "+o+" to object");
1298
+ }
1299
+ return Object(o);
1300
+ };
1301
+
1302
+ })();
1303
+
1304
+
1305
+
1306
+
1307
+ (function($, shims){
1308
+ var defineProperty = 'defineProperty';
1309
+ var advancedObjectProperties = !!(Object.create && Object.defineProperties && Object.getOwnPropertyDescriptor);
1310
+ //safari5 has defineProperty-interface, but it can't be used on dom-object
1311
+ //only do this test in non-IE browsers, because this hurts dhtml-behavior in some IE8 versions
1312
+ if (advancedObjectProperties && Object[defineProperty] && Object.prototype.__defineGetter__) {
1313
+ (function(){
1314
+ try {
1315
+ var foo = document.createElement('foo');
1316
+ Object[defineProperty](foo, 'bar', {
1317
+ get: function(){
1318
+ return true;
1319
+ }
1320
+ });
1321
+ advancedObjectProperties = !!foo.bar;
1322
+ }
1323
+ catch (e) {
1324
+ advancedObjectProperties = false;
1325
+ }
1326
+ foo = null;
1327
+ })();
1328
+ }
1329
+
1330
+ Modernizr.objectAccessor = !!((advancedObjectProperties || (Object.prototype.__defineGetter__ && Object.prototype.__lookupSetter__)));
1331
+ Modernizr.advancedObjectProperties = advancedObjectProperties;
1332
+
1333
+ if((!advancedObjectProperties || !Object.create || !Object.defineProperties || !Object.getOwnPropertyDescriptor || !Object.defineProperty)){
1334
+ var call = Function.prototype.call;
1335
+ var prototypeOfObject = Object.prototype;
1336
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
1337
+
1338
+ shims.objectCreate = function(proto, props, opts, no__proto__){
1339
+ var o;
1340
+ var f = function(){};
1341
+
1342
+ f.prototype = proto;
1343
+ o = new f();
1344
+
1345
+ if(!no__proto__ && !('__proto__' in o) && !Modernizr.objectAccessor){
1346
+ o.__proto__ = proto;
1347
+ }
1348
+
1349
+ if(props){
1350
+ shims.defineProperties(o, props);
1351
+ }
1352
+
1353
+ if(opts){
1354
+ o.options = $.extend(true, {}, o.options || {}, opts);
1355
+ opts = o.options;
1356
+ }
1357
+
1358
+ if(o._create && $.isFunction(o._create)){
1359
+ o._create(opts);
1360
+ }
1361
+ return o;
1362
+ };
1363
+
1364
+ shims.defineProperties = function(object, props){
1365
+ for (var name in props) {
1366
+ if (owns(props, name)) {
1367
+ shims.defineProperty(object, name, props[name]);
1368
+ }
1369
+ }
1370
+ return object;
1371
+ };
1372
+
1373
+ var descProps = ['configurable', 'enumerable', 'writable'];
1374
+ shims.defineProperty = function(proto, property, descriptor){
1375
+ if(typeof descriptor != "object" || descriptor === null){return proto;}
1376
+
1377
+ if(owns(descriptor, "value")){
1378
+ proto[property] = descriptor.value;
1379
+ return proto;
1380
+ }
1381
+
1382
+ if(proto.__defineGetter__){
1383
+ if (typeof descriptor.get == "function") {
1384
+ proto.__defineGetter__(property, descriptor.get);
1385
+ }
1386
+ if (typeof descriptor.set == "function"){
1387
+ proto.__defineSetter__(property, descriptor.set);
1388
+ }
1389
+ }
1390
+ return proto;
1391
+ };
1392
+
1393
+ shims.getPrototypeOf = function (object) {
1394
+ return Object.getPrototypeOf && Object.getPrototypeOf(object) || object.__proto__ || object.constructor && object.constructor.prototype;
1395
+ };
1396
+
1397
+ //based on http://www.refactory.org/s/object_getownpropertydescriptor/view/latest
1398
+ shims.getOwnPropertyDescriptor = function(obj, prop){
1399
+ if (typeof obj !== "object" && typeof obj !== "function" || obj === null){
1400
+ throw new TypeError("Object.getOwnPropertyDescriptor called on a non-object");
1401
+ }
1402
+ var descriptor;
1403
+ if(Object.defineProperty && Object.getOwnPropertyDescriptor){
1404
+ try{
1405
+ descriptor = Object.getOwnPropertyDescriptor(obj, prop);
1406
+ return descriptor;
1407
+ } catch(e){}
1408
+ }
1409
+ descriptor = {
1410
+ configurable: true,
1411
+ enumerable: true,
1412
+ writable: true,
1413
+ value: undefined
1414
+ };
1415
+ var getter = obj.__lookupGetter__ && obj.__lookupGetter__(prop),
1416
+ setter = obj.__lookupSetter__ && obj.__lookupSetter__(prop)
1417
+ ;
1418
+
1419
+ if (!getter && !setter) { // not an accessor so return prop
1420
+ if(!owns(obj, prop)){
1421
+ return;
1422
+ }
1423
+ descriptor.value = obj[prop];
1424
+ return descriptor;
1425
+ }
1426
+
1427
+ // there is an accessor, remove descriptor.writable; populate descriptor.get and descriptor.set
1428
+ delete descriptor.writable;
1429
+ delete descriptor.value;
1430
+ descriptor.get = descriptor.set = undefined;
1431
+
1432
+ if(getter){
1433
+ descriptor.get = getter;
1434
+ }
1435
+
1436
+ if(setter){
1437
+ descriptor.set = setter;
1438
+ }
1439
+
1440
+ return descriptor;
1441
+ };
1442
+
1443
+ }
1444
+ })(webshims.$, webshims);
1445
+
1446
+
1447
+ ;webshims.register('form-number-date-api', function($, webshims, window, document, undefined, options){
1448
+ "use strict";
1449
+ if(!webshims.addInputType){
1450
+ webshims.error("you can not call forms-ext feature after calling forms feature. call both at once instead: $.webshims.polyfill('forms forms-ext')");
1451
+ }
1452
+
1453
+ if(!webshims.getStep){
1454
+ webshims.getStep = function(elem, type){
1455
+ var step = $.attr(elem, 'step');
1456
+ if(step === 'any'){
1457
+ return step;
1458
+ }
1459
+ type = type || getType(elem);
1460
+ if(!typeModels[type] || !typeModels[type].step){
1461
+ return step;
1462
+ }
1463
+ step = typeProtos.number.asNumber(step);
1464
+ return ((!isNaN(step) && step > 0) ? step : typeModels[type].step) * (typeModels[type].stepScaleFactor || 1);
1465
+ };
1466
+ }
1467
+ if(!webshims.addMinMaxNumberToCache){
1468
+ webshims.addMinMaxNumberToCache = function(attr, elem, cache){
1469
+ if (!(attr+'AsNumber' in cache)) {
1470
+ cache[attr+'AsNumber'] = typeModels[cache.type].asNumber(elem.attr(attr));
1471
+ if(isNaN(cache[attr+'AsNumber']) && (attr+'Default' in typeModels[cache.type])){
1472
+ cache[attr+'AsNumber'] = typeModels[cache.type][attr+'Default'];
1473
+ }
1474
+ }
1475
+ };
1476
+ }
1477
+
1478
+ var nan = parseInt('NaN', 10),
1479
+ doc = document,
1480
+ typeModels = webshims.inputTypes,
1481
+ isNumber = function(string){
1482
+ return (typeof string == 'number' || (string && string == string * 1));
1483
+ },
1484
+ supportsType = function(type){
1485
+ return ($('<input type="'+type+'" />').prop('type') === type);
1486
+ },
1487
+ getType = function(elem){
1488
+ return (elem.getAttribute('type') || '').toLowerCase();
1489
+ },
1490
+ isDateTimePart = function(string){
1491
+ return (string && !(isNaN(string * 1)));
1492
+ },
1493
+ addMinMaxNumberToCache = webshims.addMinMaxNumberToCache,
1494
+ addleadingZero = function(val, len){
1495
+ val = ''+val;
1496
+ len = len - val.length;
1497
+ for(var i = 0; i < len; i++){
1498
+ val = '0'+val;
1499
+ }
1500
+ return val;
1501
+ },
1502
+ EPS = 1e-7,
1503
+ typeBugs = webshims.bugs.bustedValidity
1504
+ ;
1505
+
1506
+ webshims.addValidityRule('stepMismatch', function(input, val, cache, validityState){
1507
+ if(val === ''){return false;}
1508
+ if(!('type' in cache)){
1509
+ cache.type = getType(input[0]);
1510
+ }
1511
+ if(cache.type == 'week'){return false;}
1512
+ var base, attrVal;
1513
+ var ret = (validityState || {}).stepMismatch || false;
1514
+ if(typeModels[cache.type] && typeModels[cache.type].step){
1515
+ if( !('step' in cache) ){
1516
+ cache.step = webshims.getStep(input[0], cache.type);
1517
+ }
1518
+
1519
+ if(cache.step == 'any'){return false;}
1520
+
1521
+ if(!('valueAsNumber' in cache)){
1522
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
1523
+ }
1524
+ if(isNaN(cache.valueAsNumber)){return false;}
1525
+
1526
+ addMinMaxNumberToCache('min', input, cache);
1527
+ base = cache.minAsNumber;
1528
+
1529
+ if(isNaN(base) && (attrVal = input.prop('defaultValue'))){
1530
+ base = typeModels[cache.type].asNumber( attrVal );
1531
+ }
1532
+
1533
+ if(isNaN(base)){
1534
+ base = typeModels[cache.type].stepBase || 0;
1535
+ }
1536
+
1537
+ ret = Math.abs((cache.valueAsNumber - base) % cache.step);
1538
+
1539
+ ret = !( ret <= EPS || Math.abs(ret - cache.step) <= EPS );
1540
+ }
1541
+ return ret;
1542
+ });
1543
+
1544
+
1545
+
1546
+ [{name: 'rangeOverflow', attr: 'max', factor: 1}, {name: 'rangeUnderflow', attr: 'min', factor: -1}].forEach(function(data, i){
1547
+ webshims.addValidityRule(data.name, function(input, val, cache, validityState) {
1548
+ var ret = (validityState || {})[data.name] || false;
1549
+ if(val === ''){return ret;}
1550
+ if (!('type' in cache)) {
1551
+ cache.type = getType(input[0]);
1552
+ }
1553
+ if (typeModels[cache.type] && typeModels[cache.type].asNumber) {
1554
+ if(!('valueAsNumber' in cache)){
1555
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
1556
+ }
1557
+ if(isNaN(cache.valueAsNumber)){
1558
+ return false;
1559
+ }
1560
+
1561
+ addMinMaxNumberToCache(data.attr, input, cache);
1562
+
1563
+ if(isNaN(cache[data.attr+'AsNumber'])){
1564
+ return ret;
1565
+ }
1566
+ ret = ( cache[data.attr+'AsNumber'] * data.factor < cache.valueAsNumber * data.factor - EPS );
1567
+ }
1568
+ return ret;
1569
+ });
1570
+ });
1571
+
1572
+ webshims.reflectProperties(['input'], ['max', 'min', 'step']);
1573
+
1574
+
1575
+ //IDLs and methods, that aren't part of constrain validation, but strongly tight to it
1576
+ var valueAsNumberDescriptor = webshims.defineNodeNameProperty('input', 'valueAsNumber', {
1577
+ prop: {
1578
+ get: function(){
1579
+ var elem = this;
1580
+ var type = getType(elem);
1581
+ var ret = (typeModels[type] && typeModels[type].asNumber) ?
1582
+ typeModels[type].asNumber($.prop(elem, 'value')) :
1583
+ (valueAsNumberDescriptor.prop._supget && valueAsNumberDescriptor.prop._supget.apply(elem, arguments));
1584
+ if(ret == null){
1585
+ ret = nan;
1586
+ }
1587
+ return ret;
1588
+ },
1589
+ set: function(val){
1590
+ var elem = this;
1591
+ var type = getType(elem);
1592
+ if(typeModels[type] && typeModels[type].numberToString){
1593
+ //is NaN a number?
1594
+ if(isNaN(val)){
1595
+ $.prop(elem, 'value', '');
1596
+ return;
1597
+ }
1598
+ var set = typeModels[type].numberToString(val);
1599
+ if(set !== false){
1600
+ $.prop(elem, 'value', set);
1601
+ } else {
1602
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
1603
+ }
1604
+ } else if(valueAsNumberDescriptor.prop._supset) {
1605
+ valueAsNumberDescriptor.prop._supset.apply(elem, arguments);
1606
+ }
1607
+ }
1608
+ }
1609
+ });
1610
+
1611
+ var valueAsDateDescriptor = webshims.defineNodeNameProperty('input', 'valueAsDate', {
1612
+ prop: {
1613
+ get: function(){
1614
+ var elem = this;
1615
+ var type = getType(elem);
1616
+ return (typeModels[type] && typeModels[type].asDate && !typeModels[type].noAsDate) ?
1617
+ typeModels[type].asDate($.prop(elem, 'value')) :
1618
+ valueAsDateDescriptor.prop._supget && valueAsDateDescriptor.prop._supget.call(elem) || null;
1619
+ },
1620
+ set: function(value){
1621
+ var elem = this;
1622
+ var type = getType(elem);
1623
+ if(typeModels[type] && typeModels[type].dateToString && !typeModels[type].noAsDate){
1624
+
1625
+ if(value === null){
1626
+ $.prop(elem, 'value', '');
1627
+ return '';
1628
+ }
1629
+ var set = typeModels[type].dateToString(value);
1630
+ if(set !== false){
1631
+ $.prop(elem, 'value', set);
1632
+ return set;
1633
+ } else {
1634
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
1635
+ }
1636
+ } else {
1637
+ return valueAsDateDescriptor.prop._supset && valueAsDateDescriptor.prop._supset.apply(elem, arguments) || null;
1638
+ }
1639
+ }
1640
+ }
1641
+ });
1642
+
1643
+ $.each({stepUp: 1, stepDown: -1}, function(name, stepFactor){
1644
+ var stepDescriptor = webshims.defineNodeNameProperty('input', name, {
1645
+ prop: {
1646
+ value: function(factor){
1647
+ var step, val, dateVal, valModStep, alignValue, cache, base, attrVal;
1648
+ var type = getType(this);
1649
+ if(typeModels[type] && typeModels[type].asNumber){
1650
+ cache = {type: type};
1651
+ if(!factor){
1652
+ factor = 1;
1653
+ webshims.warn("you should always use a factor for stepUp/stepDown");
1654
+ }
1655
+ factor *= stepFactor;
1656
+
1657
+ val = $.prop(this, 'valueAsNumber');
1658
+
1659
+ if(isNaN(val)){
1660
+ webshims.info("valueAsNumber is NaN can't apply stepUp/stepDown ");
1661
+ throw('invalid state error');
1662
+ }
1663
+
1664
+ step = webshims.getStep(this, type);
1665
+
1666
+ if(step == 'any'){
1667
+ webshims.info("step is 'any' can't apply stepUp/stepDown");
1668
+ throw('invalid state error');
1669
+ }
1670
+
1671
+ webshims.addMinMaxNumberToCache('min', $(this), cache);
1672
+ webshims.addMinMaxNumberToCache('max', $(this), cache);
1673
+
1674
+ base = cache.minAsNumber;
1675
+
1676
+ if(isNaN(base) && (attrVal = $.prop(this, 'defaultValue'))){
1677
+ base = typeModels[type].asNumber( attrVal );
1678
+ }
1679
+
1680
+ if(!base){
1681
+ base = 0;
1682
+ }
1683
+
1684
+ step *= factor;
1685
+
1686
+ val = (val + step).toFixed(5) * 1;
1687
+
1688
+ valModStep = (val - base) % step;
1689
+
1690
+ if ( valModStep && (Math.abs(valModStep) > EPS) ) {
1691
+ alignValue = val - valModStep;
1692
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
1693
+ val = alignValue.toFixed(5) * 1;
1694
+ }
1695
+
1696
+ if( (!isNaN(cache.maxAsNumber) && val > cache.maxAsNumber) || (!isNaN(cache.minAsNumber) && val < cache.minAsNumber) ){
1697
+ webshims.info("max/min overflow can't apply stepUp/stepDown");
1698
+ throw('invalid state error');
1699
+ }
1700
+
1701
+ $.prop(this, 'valueAsNumber', val);
1702
+
1703
+ } else if(stepDescriptor.prop && stepDescriptor.prop._supvalue){
1704
+ return stepDescriptor.prop._supvalue.apply(this, arguments);
1705
+ } else {
1706
+ webshims.info("no step method for type: "+ type);
1707
+ throw('invalid state error');
1708
+ }
1709
+ }
1710
+ }
1711
+ });
1712
+ });
1713
+
1714
+ /*
1715
+ * ToDO: WEEK
1716
+ */
1717
+ // var getWeek = function(date){
1718
+ // var time;
1719
+ // var checkDate = new Date(date.getTime());
1720
+ //
1721
+ // checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
1722
+ //
1723
+ // time = checkDate.getTime();
1724
+ // checkDate.setMonth(0);
1725
+ // checkDate.setDate(1);
1726
+ // return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
1727
+ // };
1728
+ //
1729
+ // var setWeek = function(year, week){
1730
+ // var date = new Date(year, 0, 1);
1731
+ //
1732
+ // week = (week - 1) * 86400000 * 7;
1733
+ // date = new Date(date.getTime() + week);
1734
+ // date.setDate(date.getDate() + 1 - (date.getDay() || 7));
1735
+ // return date;
1736
+ // };
1737
+
1738
+ var typeProtos = {
1739
+
1740
+ number: {
1741
+ bad: function(val){
1742
+ return !(isNumber(val));
1743
+ },
1744
+ step: 1,
1745
+ //stepBase: 0, 0 = default
1746
+ stepScaleFactor: 1,
1747
+ asNumber: function(str){
1748
+ return (isNumber(str)) ? str * 1 : nan;
1749
+ },
1750
+ numberToString: function(num){
1751
+ return (isNumber(num)) ? num : false;
1752
+ }
1753
+ },
1754
+
1755
+ range: {
1756
+ minDefault: 0,
1757
+ maxDefault: 100
1758
+ },
1759
+ color: {
1760
+ bad: (function(){
1761
+ var cReg = /^\u0023[a-f0-9]{6}$/;
1762
+ return function(val){
1763
+ return (!val || val.length != 7 || !(cReg.test(val)));
1764
+ };
1765
+ })()
1766
+ },
1767
+ date: {
1768
+ bad: function(val){
1769
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
1770
+ var i;
1771
+ var valA = val.split(/\u002D/);
1772
+ if(valA.length !== 3){return true;}
1773
+ var ret = false;
1774
+
1775
+
1776
+ if(valA[0].length < 4 || valA[1].length != 2 || valA[1] > 12 || valA[2].length != 2 || valA[2] > 33){
1777
+ ret = true;
1778
+ } else {
1779
+ for(i = 0; i < 3; i++){
1780
+ if(!isDateTimePart(valA[i])){
1781
+ ret = true;
1782
+ break;
1783
+ }
1784
+ }
1785
+ }
1786
+
1787
+ return ret || (val !== this.dateToString( this.asDate(val, true) ) );
1788
+ },
1789
+ step: 1,
1790
+ //stepBase: 0, 0 = default
1791
+ stepScaleFactor: 86400000,
1792
+ asDate: function(val, _noMismatch){
1793
+ if(!_noMismatch && this.bad(val)){
1794
+ return null;
1795
+ }
1796
+ return new Date(this.asNumber(val, true));
1797
+ },
1798
+ asNumber: function(str, _noMismatch){
1799
+ var ret = nan;
1800
+ if(_noMismatch || !this.bad(str)){
1801
+ str = str.split(/\u002D/);
1802
+ ret = Date.UTC(str[0], str[1] - 1, str[2]);
1803
+ }
1804
+ return ret;
1805
+ },
1806
+ numberToString: function(num){
1807
+ return (isNumber(num)) ? this.dateToString(new Date( num * 1)) : false;
1808
+ },
1809
+ dateToString: function(date){
1810
+ return (date && date.getFullYear) ? addleadingZero(date.getUTCFullYear(), 4) +'-'+ addleadingZero(date.getUTCMonth()+1, 2) +'-'+ addleadingZero(date.getUTCDate(), 2) : false;
1811
+ }
1812
+ },
1813
+ /*
1814
+ * ToDO: WEEK
1815
+ */
1816
+ // week: {
1817
+ // bad: function(val){
1818
+ // if(!val || !val.split){return true;}
1819
+ // var valA = val.split('-W');
1820
+ // var ret = true;
1821
+ // if(valA.length == 2 && valA[0].length > 3 && valA.length == 2){
1822
+ // ret = this.dateToString(setWeek(valA[0], valA[1])) != val;
1823
+ // }
1824
+ // return ret;
1825
+ // },
1826
+ // step: 1,
1827
+ // stepScaleFactor: 604800000,
1828
+ // stepBase: -259200000,
1829
+ // asDate: function(str, _noMismatch){
1830
+ // var ret = null;
1831
+ // if(_noMismatch || !this.bad(str)){
1832
+ // ret = str.split('-W');
1833
+ // ret = setWeek(ret[0], ret[1]);
1834
+ // }
1835
+ // return ret;
1836
+ // },
1837
+ // asNumber: function(str, _noMismatch){
1838
+ // var ret = nan;
1839
+ // var date = this.asDate(str, _noMismatch);
1840
+ // if(date && date.getUTCFullYear){
1841
+ // ret = date.getTime();
1842
+ // }
1843
+ // return ret;
1844
+ // },
1845
+ // dateToString: function(date){
1846
+ // var week, checkDate;
1847
+ // var ret = false;
1848
+ // if(date && date.getFullYear){
1849
+ // week = getWeek(date);
1850
+ // if(week == 1){
1851
+ // checkDate = new Date(date.getTime());
1852
+ // checkDate.setDate(checkDate.getDate() + 7);
1853
+ // date.setUTCFullYear(checkDate.getUTCFullYear());
1854
+ // }
1855
+ // ret = addleadingZero(date.getUTCFullYear(), 4) +'-W'+addleadingZero(week, 2);
1856
+ // }
1857
+ // return ret;
1858
+ // },
1859
+ // numberToString: function(num){
1860
+ // return (isNumber(num)) ? this.dateToString(new Date( num * 1)) : false;
1861
+ // }
1862
+ // },
1863
+ time: {
1864
+ bad: function(val, _getParsed){
1865
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
1866
+ val = val.split(/\u003A/);
1867
+ if(val.length < 2 || val.length > 3){return true;}
1868
+ var ret = false,
1869
+ sFraction;
1870
+ if(val[2]){
1871
+ val[2] = val[2].split(/\u002E/);
1872
+ sFraction = parseInt(val[2][1], 10);
1873
+ val[2] = val[2][0];
1874
+ }
1875
+ $.each(val, function(i, part){
1876
+ if(!isDateTimePart(part) || part.length !== 2){
1877
+ ret = true;
1878
+ return false;
1879
+ }
1880
+ });
1881
+ if(ret){return true;}
1882
+ if(val[0] > 23 || val[0] < 0 || val[1] > 59 || val[1] < 0){
1883
+ return true;
1884
+ }
1885
+ if(val[2] && (val[2] > 59 || val[2] < 0 )){
1886
+ return true;
1887
+ }
1888
+ if(sFraction && isNaN(sFraction)){
1889
+ return true;
1890
+ }
1891
+ if(sFraction){
1892
+ if(sFraction < 100){
1893
+ sFraction *= 100;
1894
+ } else if(sFraction < 10){
1895
+ sFraction *= 10;
1896
+ }
1897
+ }
1898
+ return (_getParsed === true) ? [val, sFraction] : false;
1899
+ },
1900
+ step: 60,
1901
+ stepBase: 0,
1902
+ stepScaleFactor: 1000,
1903
+ asDate: function(val){
1904
+ val = new Date(this.asNumber(val));
1905
+ return (isNaN(val)) ? null : val;
1906
+ },
1907
+ asNumber: function(val){
1908
+ var ret = nan;
1909
+ val = this.bad(val, true);
1910
+ if(val !== true){
1911
+ ret = Date.UTC('1970', 0, 1, val[0][0], val[0][1], val[0][2] || 0);
1912
+ if(val[1]){
1913
+ ret += val[1];
1914
+ }
1915
+ }
1916
+ return ret;
1917
+ },
1918
+ dateToString: function(date){
1919
+ if(date && date.getUTCHours){
1920
+ var str = addleadingZero(date.getUTCHours(), 2) +':'+ addleadingZero(date.getUTCMinutes(), 2),
1921
+ tmp = date.getSeconds()
1922
+ ;
1923
+ if(tmp != "0"){
1924
+ str += ':'+ addleadingZero(tmp, 2);
1925
+ }
1926
+ tmp = date.getUTCMilliseconds();
1927
+ if(tmp != "0"){
1928
+ str += '.'+ addleadingZero(tmp, 3);
1929
+ }
1930
+ return str;
1931
+ } else {
1932
+ return false;
1933
+ }
1934
+ }
1935
+ },
1936
+ month: {
1937
+ bad: function(val){
1938
+ return typeProtos.date.bad(val+'-01');
1939
+ },
1940
+ step: 1,
1941
+ stepScaleFactor: false,
1942
+ //stepBase: 0, 0 = default
1943
+ asDate: function(val){
1944
+ return new Date(typeProtos.date.asNumber(val+'-01'));
1945
+ },
1946
+ asNumber: function(val){
1947
+ //1970-01
1948
+ var ret = nan;
1949
+ if(val && !this.bad(val)){
1950
+ val = val.split(/\u002D/);
1951
+ val[0] = (val[0] * 1) - 1970;
1952
+ val[1] = (val[1] * 1) - 1;
1953
+ ret = (val[0] * 12) + val[1];
1954
+ }
1955
+ return ret;
1956
+ },
1957
+ numberToString: function(num){
1958
+ var mod;
1959
+ var ret = false;
1960
+ if(isNumber(num)){
1961
+ mod = (num % 12);
1962
+ num = ((num - mod) / 12) + 1970;
1963
+ mod += 1;
1964
+ if(mod < 1){
1965
+ num -= 1;
1966
+ mod += 12;
1967
+ }
1968
+ ret = addleadingZero(num, 4)+'-'+addleadingZero(mod, 2);
1969
+
1970
+ }
1971
+
1972
+ return ret;
1973
+ },
1974
+ dateToString: function(date){
1975
+ if(date && date.getUTCHours){
1976
+ var str = typeProtos.date.dateToString(date);
1977
+ return (str.split && (str = str.split(/\u002D/))) ? str[0]+'-'+str[1] : false;
1978
+ } else {
1979
+ return false;
1980
+ }
1981
+ }
1982
+ }
1983
+ ,'datetime-local': {
1984
+ bad: function(val, _getParsed){
1985
+ if(!val || !val.split || (val+'special').split(/\u0054/).length !== 2){return true;}
1986
+ val = val.split(/\u0054/);
1987
+ return ( typeProtos.date.bad(val[0]) || typeProtos.time.bad(val[1], _getParsed) );
1988
+ },
1989
+ noAsDate: true,
1990
+ asDate: function(val){
1991
+ val = new Date(this.asNumber(val));
1992
+
1993
+ return (isNaN(val)) ? null : val;
1994
+ },
1995
+ asNumber: function(val){
1996
+ var ret = nan;
1997
+ var time = this.bad(val, true);
1998
+ if(time !== true){
1999
+ val = val.split(/\u0054/)[0].split(/\u002D/);
2000
+
2001
+ ret = Date.UTC(val[0], val[1] - 1, val[2], time[0][0], time[0][1], time[0][2] || 0);
2002
+ if(time[1]){
2003
+ ret += time[1];
2004
+ }
2005
+ }
2006
+ return ret;
2007
+ },
2008
+ dateToString: function(date, _getParsed){
2009
+ return typeProtos.date.dateToString(date) +'T'+ typeProtos.time.dateToString(date, _getParsed);
2010
+ }
2011
+ }
2012
+ };
2013
+
2014
+ if(typeBugs || !supportsType('range') || !supportsType('time') || !supportsType('month') || !supportsType('datetime-local')){
2015
+ typeProtos.range = $.extend({}, typeProtos.number, typeProtos.range);
2016
+ typeProtos.time = $.extend({}, typeProtos.date, typeProtos.time);
2017
+ typeProtos.month = $.extend({}, typeProtos.date, typeProtos.month);
2018
+ typeProtos['datetime-local'] = $.extend({}, typeProtos.date, typeProtos.time, typeProtos['datetime-local']);
2019
+ }
2020
+
2021
+ //
2022
+ ['number', 'month', 'range', 'date', 'time', 'color', 'datetime-local'].forEach(function(type){
2023
+ if(typeBugs || !supportsType(type)){
2024
+ webshims.addInputType(type, typeProtos[type]);
2025
+ }
2026
+ });
2027
+
2028
+ if($('<input />').prop('labels') == null){
2029
+ webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
2030
+ prop: {
2031
+ get: function(){
2032
+ if(this.type == 'hidden'){return null;}
2033
+ var id = this.id;
2034
+ var labels = $(this)
2035
+ .closest('label')
2036
+ .filter(function(){
2037
+ var hFor = (this.attributes['for'] || {});
2038
+ return (!hFor.specified || hFor.value == id);
2039
+ })
2040
+ ;
2041
+
2042
+ if(id) {
2043
+ labels = labels.add('label[for="'+ id +'"]');
2044
+ }
2045
+ return labels.get();
2046
+ },
2047
+ writeable: false
2048
+ }
2049
+ });
2050
+ }
2051
+
2052
+ });;webshims.register('form-datalist', function($, webshims, window, document, undefined, options){
2053
+ "use strict";
2054
+ var doc = document;
2055
+ var lazyLoad = function(name){
2056
+ if(!name || typeof name != 'string'){
2057
+ name = 'DOM';
2058
+ }
2059
+ if(!lazyLoad[name+'Loaded']){
2060
+ lazyLoad[name+'Loaded'] = true;
2061
+ webshims.ready(name, function(){
2062
+ webshims.loader.loadList(['form-datalist-lazy']);
2063
+ });
2064
+ }
2065
+ };
2066
+ var noDatalistSupport = {
2067
+ submit: 1,
2068
+ button: 1,
2069
+ reset: 1,
2070
+ hidden: 1,
2071
+
2072
+ range: 1,
2073
+ date: 1,
2074
+ month: 1
2075
+ };
2076
+ if(webshims.modules["form-number-date-ui"].loaded){
2077
+ $.extend(noDatalistSupport, {
2078
+ number: 1,
2079
+ time: 1
2080
+ });
2081
+ }
2082
+
2083
+
2084
+ /*
2085
+ * implement propType "element" currently only used for list-attribute (will be moved to dom-extend, if needed)
2086
+ */
2087
+ webshims.propTypes.element = function(descs, name){
2088
+ webshims.createPropDefault(descs, 'attr');
2089
+ if(descs.prop){return;}
2090
+ descs.prop = {
2091
+ get: function(){
2092
+ var elem = $.attr(this, name);
2093
+ if(elem){
2094
+ elem = document.getElementById(elem);
2095
+ if(elem && descs.propNodeName && !$.nodeName(elem, descs.propNodeName)){
2096
+ elem = null;
2097
+ }
2098
+ }
2099
+ return elem || null;
2100
+ },
2101
+ writeable: false
2102
+ };
2103
+ };
2104
+
2105
+
2106
+ /*
2107
+ * Implements datalist element and list attribute
2108
+ */
2109
+
2110
+ (function(){
2111
+ var formsCFG = $.webshims.cfg.forms;
2112
+ var listSupport = Modernizr.input.list;
2113
+ if(listSupport && !formsCFG.customDatalist){return;}
2114
+
2115
+ var initializeDatalist = function(){
2116
+
2117
+ var updateDatlistAndOptions = function(){
2118
+ var id;
2119
+ if(!$.data(this, 'datalistWidgetData') && (id = $.prop(this, 'id'))){
2120
+ $('input[list="'+ id +'"], input[data-wslist="'+ id +'"]').eq(0).attr('list', id);
2121
+ } else {
2122
+ $(this).triggerHandler('updateDatalist');
2123
+ }
2124
+ };
2125
+
2126
+ var inputListProto = {
2127
+ //override autocomplete
2128
+ autocomplete: {
2129
+ attr: {
2130
+ get: function(){
2131
+ var elem = this;
2132
+ var data = $.data(elem, 'datalistWidget');
2133
+ if(data){
2134
+ return data._autocomplete;
2135
+ }
2136
+ return ('autocomplete' in elem) ? elem.autocomplete : elem.getAttribute('autocomplete');
2137
+ },
2138
+ set: function(value){
2139
+ var elem = this;
2140
+ var data = $.data(elem, 'datalistWidget');
2141
+ if(data){
2142
+ data._autocomplete = value;
2143
+ if(value == 'off'){
2144
+ data.hideList();
2145
+ }
2146
+ } else {
2147
+ if('autocomplete' in elem){
2148
+ elem.autocomplete = value;
2149
+ } else {
2150
+ elem.setAttribute('autocomplete', value);
2151
+ }
2152
+ }
2153
+ }
2154
+ }
2155
+ }
2156
+ };
2157
+
2158
+ if(listSupport){
2159
+ //options only return options, if option-elements are rooted: but this makes this part of HTML5 less backwards compatible
2160
+ if(!($('<datalist><select><option></option></select></datalist>').prop('options') || []).length ){
2161
+ webshims.defineNodeNameProperty('datalist', 'options', {
2162
+ prop: {
2163
+ writeable: false,
2164
+ get: function(){
2165
+ var options = this.options || [];
2166
+ if(!options.length){
2167
+ var elem = this;
2168
+ var select = $('select', elem);
2169
+ if(select[0] && select[0].options && select[0].options.length){
2170
+ options = select[0].options;
2171
+ }
2172
+ }
2173
+ return options;
2174
+ }
2175
+ }
2176
+ });
2177
+ }
2178
+ inputListProto.list = {
2179
+ attr: {
2180
+ get: function(){
2181
+ var val = webshims.contentAttr(this, 'list');
2182
+ if(val != null){
2183
+ $.data(this, 'datalistListAttr', val);
2184
+ if(!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]){
2185
+ this.removeAttribute('list');
2186
+ }
2187
+ } else {
2188
+ val = $.data(this, 'datalistListAttr');
2189
+ }
2190
+
2191
+ return (val == null) ? undefined : val;
2192
+ },
2193
+ set: function(value){
2194
+ var elem = this;
2195
+ $.data(elem, 'datalistListAttr', value);
2196
+ if (!noDatalistSupport[$.prop(this, 'type')] && !noDatalistSupport[$.attr(this, 'type')]) {
2197
+ webshims.objectCreate(shadowListProto, undefined, {
2198
+ input: elem,
2199
+ id: value,
2200
+ datalist: $.prop(elem, 'list')
2201
+ });
2202
+ elem.setAttribute('data-wslist', value);
2203
+ } else {
2204
+ elem.setAttribute('list', value);
2205
+ }
2206
+ $(elem).triggerHandler('listdatalistchange');
2207
+ }
2208
+ },
2209
+ initAttr: true,
2210
+ reflect: true,
2211
+ propType: 'element',
2212
+ propNodeName: 'datalist'
2213
+ };
2214
+ } else {
2215
+ webshims.defineNodeNameProperties('input', {
2216
+ list: {
2217
+ attr: {
2218
+ get: function(){
2219
+ var val = webshims.contentAttr(this, 'list');
2220
+ return (val == null) ? undefined : val;
2221
+ },
2222
+ set: function(value){
2223
+ var elem = this;
2224
+ webshims.contentAttr(elem, 'list', value);
2225
+ webshims.objectCreate(options.shadowListProto, undefined, {input: elem, id: value, datalist: $.prop(elem, 'list')});
2226
+ $(elem).triggerHandler('listdatalistchange');
2227
+ }
2228
+ },
2229
+ initAttr: true,
2230
+ reflect: true,
2231
+ propType: 'element',
2232
+ propNodeName: 'datalist'
2233
+ }
2234
+ });
2235
+ }
2236
+
2237
+ webshims.defineNodeNameProperties('input', inputListProto);
2238
+
2239
+ webshims.addReady(function(context, contextElem){
2240
+ contextElem
2241
+ .filter('datalist > select, datalist, datalist > option, datalist > select > option')
2242
+ .closest('datalist')
2243
+ .each(updateDatlistAndOptions)
2244
+ ;
2245
+ });
2246
+ };
2247
+
2248
+
2249
+ /*
2250
+ * ShadowList
2251
+ */
2252
+
2253
+ var shadowListProto = {
2254
+ _create: function(opts){
2255
+
2256
+ if(noDatalistSupport[$.prop(opts.input, 'type')] || noDatalistSupport[$.attr(opts.input, 'type')]){return;}
2257
+ var datalist = opts.datalist;
2258
+ var data = $.data(opts.input, 'datalistWidget');
2259
+ var that = this;
2260
+ if(datalist && data && data.datalist !== datalist){
2261
+ data.datalist = datalist;
2262
+ data.id = opts.id;
2263
+
2264
+
2265
+ $(data.datalist)
2266
+ .off('updateDatalist.datalistWidget')
2267
+ .on('updateDatalist.datalistWidget', $.proxy(data, '_resetListCached'))
2268
+ ;
2269
+
2270
+ data._resetListCached();
2271
+ return;
2272
+ } else if(!datalist){
2273
+ if(data){
2274
+ data.destroy();
2275
+ }
2276
+ return;
2277
+ } else if(data && data.datalist === datalist){
2278
+ return;
2279
+ }
2280
+
2281
+
2282
+
2283
+ this.datalist = datalist;
2284
+ this.id = opts.id;
2285
+ this.hasViewableData = true;
2286
+ this._autocomplete = $.attr(opts.input, 'autocomplete');
2287
+ $.data(opts.input, 'datalistWidget', this);
2288
+ $.data(datalist, 'datalistWidgetData', this);
2289
+
2290
+ lazyLoad('WINDOWLOAD');
2291
+
2292
+ if(webshims.isReady('form-datalist-lazy')){
2293
+ this._lazyCreate(opts);
2294
+ } else {
2295
+ $(opts.input).one('focus', lazyLoad);
2296
+ webshims.ready('form-datalist-lazy', function(){
2297
+ if(!that._destroyed){
2298
+ that._lazyCreate(opts);
2299
+ }
2300
+ });
2301
+ }
2302
+ },
2303
+ destroy: function(e){
2304
+ var input;
2305
+ var autocomplete = $.attr(this.input, 'autocomplete');
2306
+ $(this.input)
2307
+ .off('.datalistWidget')
2308
+ .removeData('datalistWidget')
2309
+ ;
2310
+ this.shadowList.remove();
2311
+ $(document).off('.datalist'+this.id);
2312
+ $(window).off('.datalist'+this.id);
2313
+ if(this.input.form && this.input.id){
2314
+ $(this.input.form).off('submit.datalistWidget'+this.input.id);
2315
+ }
2316
+ this.input.removeAttribute('aria-haspopup');
2317
+ if(autocomplete === undefined){
2318
+ this.input.removeAttribute('autocomplete');
2319
+ } else {
2320
+ $(this.input).attr('autocomplete', autocomplete);
2321
+ }
2322
+ if(e && e.type == 'beforeunload'){
2323
+ input = this.input;
2324
+ setTimeout(function(){
2325
+ $.attr(input, 'list', $.attr(input, 'list'));
2326
+ }, 9);
2327
+ }
2328
+ this._destroyed = true;
2329
+ }
2330
+ };
2331
+
2332
+ webshims.loader.addModule('form-datalist-lazy', {
2333
+ noAutoCallback: true,
2334
+ options: $.extend(options, {shadowListProto: shadowListProto})
2335
+ });
2336
+ if(!options.list){
2337
+ options.list = {};
2338
+ }
2339
+ //init datalist update
2340
+ initializeDatalist();
2341
+ })();
2342
+
2343
+ });