webshims-rails 0.4.7 → 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +15 -0
  2. data/lib/webshims-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/webshims/extras/custom-validity.js +1 -1
  4. data/vendor/assets/javascripts/webshims/extras/mousepress.js +1 -1
  5. data/vendor/assets/javascripts/webshims/polyfiller.js +197 -166
  6. data/vendor/assets/javascripts/webshims/shims/combos/1.js +1711 -1609
  7. data/vendor/assets/javascripts/webshims/shims/combos/10.js +2575 -2253
  8. data/vendor/assets/javascripts/webshims/shims/combos/11.js +2452 -1476
  9. data/vendor/assets/javascripts/webshims/shims/combos/12.js +1405 -1159
  10. data/vendor/assets/javascripts/webshims/shims/combos/13.js +1316 -963
  11. data/vendor/assets/javascripts/webshims/shims/combos/14.js +1862 -179
  12. data/vendor/assets/javascripts/webshims/shims/combos/15.js +4327 -287
  13. data/vendor/assets/javascripts/webshims/shims/combos/16.js +3887 -586
  14. data/vendor/assets/javascripts/webshims/shims/combos/17.js +2911 -2159
  15. data/vendor/assets/javascripts/webshims/shims/combos/18.js +3425 -1730
  16. data/vendor/assets/javascripts/webshims/shims/combos/19.js +2854 -1203
  17. data/vendor/assets/javascripts/webshims/shims/combos/2.js +3351 -2130
  18. data/vendor/assets/javascripts/webshims/shims/combos/20.js +2426 -581
  19. data/vendor/assets/javascripts/webshims/shims/combos/21.js +1915 -1574
  20. data/vendor/assets/javascripts/webshims/shims/combos/22.js +864 -2275
  21. data/vendor/assets/javascripts/webshims/shims/combos/23.js +609 -1811
  22. data/vendor/assets/javascripts/webshims/shims/combos/3.js +1655 -2736
  23. data/vendor/assets/javascripts/webshims/shims/combos/4.js +1037 -603
  24. data/vendor/assets/javascripts/webshims/shims/combos/5.js +3100 -773
  25. data/vendor/assets/javascripts/webshims/shims/combos/6.js +3631 -840
  26. data/vendor/assets/javascripts/webshims/shims/combos/7.js +3596 -1354
  27. data/vendor/assets/javascripts/webshims/shims/combos/8.js +1731 -188
  28. data/vendor/assets/javascripts/webshims/shims/combos/9.js +3243 -1431
  29. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +107 -18
  30. data/vendor/assets/javascripts/webshims/shims/es5.js +1 -0
  31. data/vendor/assets/javascripts/webshims/shims/form-core.js +553 -464
  32. data/vendor/assets/javascripts/webshims/shims/form-datalist.js +160 -154
  33. data/vendor/assets/javascripts/webshims/shims/form-message.js +73 -49
  34. data/vendor/assets/javascripts/webshims/shims/form-native-extend.js +18 -1
  35. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +161 -36
  36. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +2130 -813
  37. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +206 -58
  38. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-ar.js → formcfg-ar.js} +30 -0
  39. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-ch-ZN.js → formcfg-ch-ZN.js} +31 -0
  40. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-de.txt → formcfg-de.txt} +50 -11
  41. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-el.js → formcfg-el.js} +31 -0
  42. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-en.txt → formcfg-en.txt} +44 -11
  43. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-es.js → formcfg-es.js} +31 -0
  44. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-fr.js → formcfg-fr.js} +31 -0
  45. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-he.js → formcfg-he.js} +31 -0
  46. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-hi.js → formcfg-hi.js} +31 -0
  47. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-hu.js → formcfg-hu.js} +31 -0
  48. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-it.js → formcfg-it.js} +31 -0
  49. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-ja.js → formcfg-ja.js} +31 -0
  50. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-nl.js → formcfg-nl.js} +31 -0
  51. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-pt-PT.js → formcfg-pt-PT.js} +31 -0
  52. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-ru.js → formcfg-ru.js} +31 -0
  53. data/vendor/assets/javascripts/webshims/shims/i18n/{errormessages-sv.js → formcfg-sv.js} +32 -0
  54. data/vendor/assets/javascripts/webshims/shims/json-storage.js +16 -10
  55. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +155 -122
  56. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +76 -41
  57. data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +8 -16
  58. data/vendor/assets/javascripts/webshims/shims/range-ui.js +388 -0
  59. data/vendor/assets/javascripts/webshims/shims/styles/config.rb +12 -0
  60. data/vendor/assets/javascripts/webshims/shims/styles/forms.png +0 -0
  61. data/vendor/assets/javascripts/webshims/shims/styles/scss/shim.scss +1186 -0
  62. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +868 -548
  63. data/vendor/assets/javascripts/webshims/shims/styles/vertical-range.png +0 -0
  64. data/vendor/assets/javascripts/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
  65. data/vendor/assets/javascripts/webshims/shims/swfmini.js +497 -0
  66. data/vendor/assets/javascripts/webshims/shims/track-ui.js +3 -0
  67. data/vendor/assets/javascripts/webshims/shims/track.js +29 -29
  68. metadata +26 -125
  69. data/vendor/assets/javascripts/webshims/minified/extras/custom-validity.js +0 -1
  70. data/vendor/assets/javascripts/webshims/minified/extras/modernizr-custom.js +0 -1
  71. data/vendor/assets/javascripts/webshims/minified/extras/mousepress.js +0 -1
  72. data/vendor/assets/javascripts/webshims/minified/polyfiller.js +0 -1
  73. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/canvas2png.js +0 -1
  74. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/flashcanvas.js +0 -1
  75. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/flashcanvas.swf +0 -0
  76. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/proxy.php +0 -73
  77. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/save.php +0 -49
  78. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/canvas2png.js +0 -1
  79. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  80. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  81. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/flashcanvas.js +0 -1
  82. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/proxy.php +0 -73
  83. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/save.php +0 -49
  84. data/vendor/assets/javascripts/webshims/minified/shims/combos/1.js +0 -1
  85. data/vendor/assets/javascripts/webshims/minified/shims/combos/10.js +0 -1
  86. data/vendor/assets/javascripts/webshims/minified/shims/combos/11.js +0 -1
  87. data/vendor/assets/javascripts/webshims/minified/shims/combos/12.js +0 -1
  88. data/vendor/assets/javascripts/webshims/minified/shims/combos/13.js +0 -1
  89. data/vendor/assets/javascripts/webshims/minified/shims/combos/14.js +0 -1
  90. data/vendor/assets/javascripts/webshims/minified/shims/combos/15.js +0 -1
  91. data/vendor/assets/javascripts/webshims/minified/shims/combos/16.js +0 -1
  92. data/vendor/assets/javascripts/webshims/minified/shims/combos/17.js +0 -1
  93. data/vendor/assets/javascripts/webshims/minified/shims/combos/18.js +0 -1
  94. data/vendor/assets/javascripts/webshims/minified/shims/combos/19.js +0 -1
  95. data/vendor/assets/javascripts/webshims/minified/shims/combos/2.js +0 -1
  96. data/vendor/assets/javascripts/webshims/minified/shims/combos/20.js +0 -1
  97. data/vendor/assets/javascripts/webshims/minified/shims/combos/21.js +0 -1
  98. data/vendor/assets/javascripts/webshims/minified/shims/combos/22.js +0 -1
  99. data/vendor/assets/javascripts/webshims/minified/shims/combos/23.js +0 -1
  100. data/vendor/assets/javascripts/webshims/minified/shims/combos/24.js +0 -1
  101. data/vendor/assets/javascripts/webshims/minified/shims/combos/25.js +0 -1
  102. data/vendor/assets/javascripts/webshims/minified/shims/combos/26.js +0 -1
  103. data/vendor/assets/javascripts/webshims/minified/shims/combos/27.js +0 -1
  104. data/vendor/assets/javascripts/webshims/minified/shims/combos/3.js +0 -1
  105. data/vendor/assets/javascripts/webshims/minified/shims/combos/4.js +0 -1
  106. data/vendor/assets/javascripts/webshims/minified/shims/combos/5.js +0 -1
  107. data/vendor/assets/javascripts/webshims/minified/shims/combos/59.js +0 -1
  108. data/vendor/assets/javascripts/webshims/minified/shims/combos/6.js +0 -1
  109. data/vendor/assets/javascripts/webshims/minified/shims/combos/7.js +0 -1
  110. data/vendor/assets/javascripts/webshims/minified/shims/combos/8.js +0 -1
  111. data/vendor/assets/javascripts/webshims/minified/shims/combos/9.js +0 -1
  112. data/vendor/assets/javascripts/webshims/minified/shims/details.js +0 -1
  113. data/vendor/assets/javascripts/webshims/minified/shims/dom-extend.js +0 -1
  114. data/vendor/assets/javascripts/webshims/minified/shims/es5.js +0 -1
  115. data/vendor/assets/javascripts/webshims/minified/shims/excanvas.js +0 -1
  116. data/vendor/assets/javascripts/webshims/minified/shims/form-core.js +0 -1
  117. data/vendor/assets/javascripts/webshims/minified/shims/form-datalist.js +0 -1
  118. data/vendor/assets/javascripts/webshims/minified/shims/form-message.js +0 -1
  119. data/vendor/assets/javascripts/webshims/minified/shims/form-native-extend.js +0 -1
  120. data/vendor/assets/javascripts/webshims/minified/shims/form-number-date-api.js +0 -1
  121. data/vendor/assets/javascripts/webshims/minified/shims/form-number-date-ui.js +0 -1
  122. data/vendor/assets/javascripts/webshims/minified/shims/form-shim-extend.js +0 -1
  123. data/vendor/assets/javascripts/webshims/minified/shims/geolocation.js +0 -1
  124. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ar.js +0 -1
  125. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ch-ZN.js +0 -1
  126. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-de.txt +0 -33
  127. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-el.js +0 -1
  128. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-en.txt +0 -34
  129. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-es.js +0 -1
  130. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-fr.js +0 -1
  131. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-he.js +0 -1
  132. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-hi.js +0 -1
  133. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-hu.js +0 -1
  134. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-it.js +0 -1
  135. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ja.js +0 -1
  136. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-nl.js +0 -1
  137. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-pt-PT.js +0 -1
  138. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ru.js +0 -1
  139. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-sv.js +0 -1
  140. data/vendor/assets/javascripts/webshims/minified/shims/json-storage.js +0 -1
  141. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/license.txt +0 -1
  142. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/player.swf +0 -0
  143. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/readme.html +0 -87
  144. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-core.js +0 -1
  145. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-jaris.js +0 -1
  146. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-native-fix.js +0 -1
  147. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-swf.js +0 -1
  148. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-yt.js +0 -1
  149. data/vendor/assets/javascripts/webshims/minified/shims/styles/details-arrows.png +0 -0
  150. data/vendor/assets/javascripts/webshims/minified/shims/styles/forms.png +0 -0
  151. data/vendor/assets/javascripts/webshims/minified/shims/styles/polyfill-loader.gif +0 -0
  152. data/vendor/assets/javascripts/webshims/minified/shims/styles/shim.css +0 -1
  153. data/vendor/assets/javascripts/webshims/minified/shims/swf/JarisFLVPlayer.swf +0 -0
  154. data/vendor/assets/javascripts/webshims/minified/shims/swf/jwwebshims.swf +0 -0
  155. data/vendor/assets/javascripts/webshims/minified/shims/swf/localStorage.swf +0 -0
  156. data/vendor/assets/javascripts/webshims/minified/shims/track-ui.js +0 -1
  157. data/vendor/assets/javascripts/webshims/minified/shims/track.js +0 -1
  158. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/README +0 -62
  159. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/README +0 -82
  160. data/vendor/assets/javascripts/webshims/shims/combos/24.js +0 -2872
  161. data/vendor/assets/javascripts/webshims/shims/combos/25.js +0 -2376
  162. data/vendor/assets/javascripts/webshims/shims/combos/26.js +0 -3009
  163. data/vendor/assets/javascripts/webshims/shims/combos/27.js +0 -4150
  164. data/vendor/assets/javascripts/webshims/shims/combos/59.js +0 -1747
  165. data/vendor/assets/javascripts/webshims/shims/jwplayer/license.txt +0 -1
  166. data/vendor/assets/javascripts/webshims/shims/jwplayer/player.swf +0 -0
  167. data/vendor/assets/javascripts/webshims/shims/jwplayer/readme.html +0 -87
  168. data/vendor/assets/javascripts/webshims/shims/mediaelement-swf.js +0 -972
@@ -1,636 +1,3 @@
1
- //additional tests for partial implementation of forms features
2
- (function($){
3
- "use strict";
4
- var isWebkit = /webkit/i.test(navigator.userAgent);
5
- var Modernizr = window.Modernizr;
6
- var webshims = $.webshims;
7
- var bugs = webshims.bugs;
8
- var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input required="" name="a" /></form>');
9
- var testRequiredFind = function(){
10
- if(form[0].querySelector){
11
- try {
12
- bugs.findRequired = !(form[0].querySelector('select:required'));
13
- } catch(er){
14
- bugs.findRequired = false;
15
- }
16
- }
17
- };
18
- var inputElem = $('input', form).eq(0);
19
- var onDomextend = function(fn){
20
- webshims.loader.loadList(['dom-extend']);
21
- webshims.ready('dom-extend', fn);
22
- };
23
-
24
- bugs.findRequired = false;
25
- bugs.validationMessage = false;
26
-
27
- webshims.capturingEventPrevented = function(e){
28
- if(!e._isPolyfilled){
29
- var isDefaultPrevented = e.isDefaultPrevented;
30
- var preventDefault = e.preventDefault;
31
- e.preventDefault = function(){
32
- clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
33
- $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
34
- $.removeData(e.target, e.type + 'DefaultPrevented');
35
- }, 30));
36
- return preventDefault.apply(this, arguments);
37
- };
38
- e.isDefaultPrevented = function(){
39
- return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
40
- };
41
- e._isPolyfilled = true;
42
- }
43
- };
44
-
45
- if(!Modernizr.formvalidation || bugs.bustedValidity){
46
- testRequiredFind();
47
- } else {
48
- //create delegatable events
49
- webshims.capturingEvents(['input']);
50
- webshims.capturingEvents(['invalid'], true);
51
-
52
- if(window.opera || window.testGoodWithFix){
53
-
54
- form.appendTo('head');
55
-
56
- testRequiredFind();
57
- bugs.validationMessage = !(inputElem.prop('validationMessage'));
58
-
59
- webshims.reTest(['form-native-extend', 'form-message']);
60
-
61
- form.remove();
62
-
63
- $(function(){
64
- onDomextend(function(){
65
-
66
- //Opera shows native validation bubbles in case of input.checkValidity()
67
- // Opera 11.6/12 hasn't fixed this issue right, it's buggy
68
- var preventDefault = function(e){
69
- e.preventDefault();
70
- };
71
-
72
- ['form', 'input', 'textarea', 'select'].forEach(function(name){
73
- var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
74
- prop: {
75
- value: function(){
76
- if (!webshims.fromSubmit) {
77
- $(this).on('invalid.checkvalidity', preventDefault);
78
- }
79
-
80
- webshims.fromCheckValidity = true;
81
- var ret = desc.prop._supvalue.apply(this, arguments);
82
- if (!webshims.fromSubmit) {
83
- $(this).unbind('invalid.checkvalidity', preventDefault);
84
- }
85
- webshims.fromCheckValidity = false;
86
- return ret;
87
- }
88
- }
89
- });
90
- });
91
-
92
- });
93
- });
94
- }
95
-
96
- if(isWebkit && !webshims.bugs.bustedValidity){
97
- (function(){
98
- var elems = /^(?:textarea|input)$/i;
99
- var form = false;
100
-
101
- document.addEventListener('contextmenu', function(e){
102
- if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
103
- setTimeout(function(){
104
- form = false;
105
- }, 1);
106
- }
107
- }, false);
108
-
109
- $(window).on('invalid', function(e){
110
- if(e.originalEvent && form && form == e.target.form){
111
- e.wrongWebkitInvalid = true;
112
- e.stopImmediatePropagation();
113
- }
114
- });
115
-
116
- })();
117
- }
118
- }
119
-
120
-
121
-
122
- jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
123
- "use strict";
124
-
125
-
126
- var checkTypes = {checkbox: 1, radio: 1};
127
- var emptyJ = $([]);
128
- var bugs = webshims.bugs;
129
- var groupTypes = {radio: 1};
130
- var getGroupElements = function(elem){
131
- elem = $(elem);
132
- var name;
133
- var form;
134
- var ret = emptyJ;
135
- if(groupTypes[elem[0].type]){
136
- form = elem.prop('form');
137
- name = elem[0].name;
138
- if(!name){
139
- ret = elem;
140
- } else if(form){
141
- ret = $(form[name]);
142
- } else {
143
- ret = $(document.getElementsByName(name)).filter(function(){
144
- return !$.prop(this, 'form');
145
- });
146
- }
147
- ret = ret.filter('[type="radio"]');
148
- }
149
- return ret;
150
- };
151
-
152
- var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
153
- var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
154
- if(key && message[key]){
155
- message = message[key];
156
- }
157
- if(typeof message == 'object'){
158
- validity = validity || $.prop(elem, 'validity') || {valid: 1};
159
- if(!validity.valid){
160
- $.each(validity, function(name, prop){
161
- if(prop && name != 'valid' && message[name]){
162
- message = message[name];
163
- return false;
164
- }
165
- });
166
- }
167
- }
168
-
169
- if(typeof message == 'object'){
170
- message = message.defaultMessage;
171
- }
172
- return message || '';
173
- };
174
-
175
- /*
176
- * Selectors for all browsers
177
- */
178
- var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
179
- var hasInvalid = function(elem){
180
- var ret = false;
181
- $($.prop(elem, 'elements')).each(function(){
182
- ret = $(this).is(':invalid');
183
- if(ret){
184
- return false;
185
- }
186
- });
187
- return ret;
188
- };
189
- $.extend($.expr[":"], {
190
- "valid-element": function(elem){
191
- return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
192
- },
193
- "invalid-element": function(elem){
194
- return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
195
- },
196
- "required-element": function(elem){
197
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
198
- },
199
- "user-error": function(elem){
200
- return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
201
- },
202
- "optional-element": function(elem){
203
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
204
- },
205
- "in-range": function(elem){
206
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
207
- return false;
208
- }
209
- var val = $.prop(elem, 'validity');
210
- return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
211
- },
212
- "out-of-range": function(elem){
213
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
214
- return false;
215
- }
216
- var val = $.prop(elem, 'validity');
217
- return !!(val && (val.rangeOverflow || val.rangeUnderflow));
218
- }
219
-
220
- });
221
-
222
- ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
223
- $.expr[":"][name] = $.expr.filters[name+"-element"];
224
- });
225
-
226
-
227
- $.expr[":"].focus = function( elem ) {
228
- try {
229
- var doc = elem.ownerDocument;
230
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
231
- } catch(e){}
232
- return false;
233
- };
234
-
235
- if(Modernizr.formvalidation && isWebkit && !webshims.bugs.bustedValidity){
236
- (function(){
237
- var retriggerRadioValidity = function(){
238
- var validity;
239
- if((validity = this.validity) && !validity.customError){
240
- this.setCustomValidity('');
241
- }
242
- };
243
-
244
- webshims.addReady(function(context, insertedElement){
245
- if(context !== document){
246
- $('input[type="radio"]:invalid', context)
247
- .add(insertedElement.filter('input[type="radio"]:invalid'))
248
- .each(retriggerRadioValidity)
249
- ;
250
- }
251
- });
252
- })();
253
- }
254
-
255
- var customEvents = $.event.customEvent || {};
256
- var isValid = function(elem){
257
- return ($.prop(elem, 'validity') || {valid: 1}).valid;
258
- };
259
-
260
- if (bugs.bustedValidity || bugs.findRequired) {
261
- (function(){
262
- var find = $.find;
263
- var matchesSelector = $.find.matchesSelector;
264
-
265
- var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
266
- var regFn = function(sel){
267
- return sel + '-element';
268
- };
269
-
270
- $.find = (function(){
271
- var slice = Array.prototype.slice;
272
- var fn = function(sel){
273
- var ar = arguments;
274
- ar = slice.call(ar, 1, ar.length);
275
- ar.unshift(sel.replace(regExp, regFn));
276
- return find.apply(this, ar);
277
- };
278
- for (var i in find) {
279
- if(find.hasOwnProperty(i)){
280
- fn[i] = find[i];
281
- }
282
- }
283
- return fn;
284
- })();
285
- if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
286
- $.find.matchesSelector = function(node, expr){
287
- expr = expr.replace(regExp, regFn);
288
- return matchesSelector.call(this, node, expr);
289
- };
290
- }
291
-
292
- })();
293
- }
294
-
295
- //ToDo needs testing
296
- var oldAttr = $.prop;
297
- var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
298
- $.prop = function(elem, name, val){
299
- var ret = oldAttr.apply(this, arguments);
300
- if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
301
- if(isValid(elem)){
302
- $(elem).getShadowElement().removeClass(invalidClasses);
303
- if(name == 'checked' && val) {
304
- getGroupElements(elem).not(elem).removeClass(invalidClasses).removeAttr('aria-invalid');
305
- }
306
- }
307
- }
308
- return ret;
309
- };
310
-
311
- var returnValidityCause = function(validity, elem){
312
- var ret;
313
- $.each(validity, function(name, value){
314
- if(value){
315
- ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
316
- return false;
317
- }
318
- });
319
- return ret;
320
- };
321
-
322
- var isInGroup = function(name){
323
- var ret;
324
- try {
325
- ret = document.activeElement.name === name;
326
- } catch(e){}
327
- return ret;
328
- };
329
- /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-success instead */
330
- var invalidClass = 'user-error';
331
- var invalidClasses = 'user-error form-ui-invalid';
332
- var validClass = 'user-success';
333
- var validClasses = 'user-success form-ui-valid';
334
- var switchValidityClass = function(e){
335
- var elem, timer;
336
- if(!e.target){return;}
337
- elem = $(e.target).getNativeElement()[0];
338
- if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
339
- timer = $.data(elem, 'webshimsswitchvalidityclass');
340
- var switchClass = function(){
341
- if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
342
- var validity = $.prop(elem, 'validity');
343
- var shadowElem = $(elem).getShadowElement();
344
- var addClass, removeClass, trigger, generaltrigger, validityCause;
345
-
346
- $(elem).trigger('refreshCustomValidityRules');
347
- if(validity.valid){
348
- if(!shadowElem.hasClass(validClass)){
349
- addClass = validClasses;
350
- removeClass = invalidClasses;
351
- generaltrigger = 'changedvaliditystate';
352
- trigger = 'changedvalid';
353
- if(checkTypes[elem.type] && elem.checked){
354
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
355
- }
356
- $.removeData(elem, 'webshimsinvalidcause');
357
- }
358
- } else {
359
- validityCause = returnValidityCause(validity, elem);
360
- if($.data(elem, 'webshimsinvalidcause') != validityCause){
361
- $.data(elem, 'webshimsinvalidcause', validityCause);
362
- generaltrigger = 'changedvaliditystate';
363
- }
364
- if(!shadowElem.hasClass(invalidClass)){
365
- addClass = invalidClasses;
366
- removeClass = validClasses;
367
- if (checkTypes[elem.type] && !elem.checked) {
368
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
369
- }
370
- trigger = 'changedinvalid';
371
- }
372
- }
373
- if(addClass){
374
- shadowElem.addClass(addClass).removeClass(removeClass);
375
- //jQuery 1.6.1 IE9 bug (doubble trigger bug)
376
- setTimeout(function(){
377
- $(elem).trigger(trigger);
378
- }, 0);
379
- }
380
- if(generaltrigger){
381
- setTimeout(function(){
382
- $(elem).trigger(generaltrigger);
383
- }, 0);
384
- }
385
- $.removeData(e.target, 'webshimsswitchvalidityclass');
386
- };
387
-
388
- if(timer){
389
- clearTimeout(timer);
390
- }
391
- if(e.type == 'refreshvalidityui'){
392
- switchClass();
393
- } else {
394
- $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
395
- }
396
- };
397
-
398
- $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
399
- customEvents.changedvaliditystate = true;
400
- customEvents.refreshCustomValidityRules = true;
401
- customEvents.changedvalid = true;
402
- customEvents.changedinvalid = true;
403
- customEvents.refreshvalidityui = true;
404
-
405
-
406
- webshims.triggerInlineForm = function(elem, event){
407
- $(elem).trigger(event);
408
- };
409
-
410
- webshims.modules["form-core"].getGroupElements = getGroupElements;
411
-
412
-
413
- var setRoot = function(){
414
- webshims.scrollRoot = (isWebkit || document.compatMode == 'BackCompat') ?
415
- $(document.body) :
416
- $(document.documentElement)
417
- ;
418
- };
419
- setRoot();
420
- webshims.ready('DOM', setRoot);
421
-
422
- webshims.getRelOffset = function(posElem, relElem){
423
- posElem = $(posElem);
424
- var offset = $(relElem).offset();
425
- var bodyOffset;
426
- $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
427
- bodyOffset = posElem.offset();
428
- });
429
- offset.top -= bodyOffset.top;
430
- offset.left -= bodyOffset.left;
431
- return offset;
432
- };
433
-
434
- /* some extra validation UI */
435
- webshims.validityAlert = (function(){
436
- var alertElem = 'span';
437
- var errorBubble;
438
- var hideTimer = false;
439
- var focusTimer = false;
440
- var resizeTimer = false;
441
- var boundHide;
442
-
443
- var api = {
444
- hideDelay: 5000,
445
-
446
- showFor: function(elem, message, noFocusElem, noBubble){
447
- api._create();
448
- elem = $(elem);
449
- var visual = $(elem).getShadowElement();
450
- var offset = api.getOffsetFromBody(visual);
451
- api.clear();
452
- if(noBubble){
453
- this.hide();
454
- } else {
455
-
456
- this.getMessage(elem, message);
457
- this.position(visual, offset);
458
-
459
- this.show();
460
- if(this.hideDelay){
461
- hideTimer = setTimeout(boundHide, this.hideDelay);
462
- }
463
- $(window)
464
- .on('resize.validityalert reposoverlay.validityalert', function(){
465
- clearTimeout(resizeTimer);
466
- resizeTimer = setTimeout(function(){
467
- api.position(visual);
468
- }, 9);
469
- })
470
- ;
471
- }
472
-
473
- if(!noFocusElem){
474
- this.setFocus(visual, offset);
475
- }
476
- },
477
- getOffsetFromBody: function(elem){
478
- return webshims.getRelOffset(errorBubble, elem);
479
- },
480
- setFocus: function(visual, offset){
481
- var focusElem = $(visual).getShadowFocusElement();
482
- var scrollTop = webshims.scrollRoot.scrollTop();
483
- var elemTop = ((offset || focusElem.offset()).top) - 30;
484
- var smooth;
485
-
486
- if(webshims.getID && alertElem == 'label'){
487
- errorBubble.attr('for', webshims.getID(focusElem));
488
- }
489
-
490
- if(scrollTop > elemTop){
491
- webshims.scrollRoot.animate(
492
- {scrollTop: elemTop - 5},
493
- {
494
- queue: false,
495
- duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
496
- }
497
- );
498
- smooth = true;
499
- }
500
- try {
501
- focusElem[0].focus();
502
- } catch(e){}
503
- if(smooth){
504
- webshims.scrollRoot.scrollTop(scrollTop);
505
- setTimeout(function(){
506
- webshims.scrollRoot.scrollTop(scrollTop);
507
- }, 0);
508
- }
509
- setTimeout(function(){
510
- $(document).on('focusout.validityalert', boundHide);
511
- }, 10);
512
- $(window).triggerHandler('reposoverlay');
513
- },
514
- getMessage: function(elem, message){
515
- if (!message) {
516
- message = getContentValidationMessage(elem[0]) || elem.prop('customValidationMessage') || elem.prop('validationMessage');
517
- }
518
- if (message) {
519
- $('span.va-box', errorBubble).text(message);
520
- }
521
- else {
522
- this.hide();
523
- }
524
- },
525
- position: function(elem, offset){
526
- offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
527
- offset.top += elem.outerHeight();
528
- errorBubble.css(offset);
529
- },
530
- show: function(){
531
- if(errorBubble.css('display') === 'none'){
532
- errorBubble.css({opacity: 0}).show();
533
- }
534
- errorBubble.addClass('va-visible').fadeTo(400, 1);
535
- },
536
- hide: function(){
537
- errorBubble.removeClass('va-visible').fadeOut();
538
- },
539
- clear: function(){
540
- clearTimeout(focusTimer);
541
- clearTimeout(hideTimer);
542
- $(document).unbind('.validityalert');
543
- $(window).unbind('.validityalert');
544
- errorBubble.stop().removeAttr('for');
545
- },
546
- _create: function(){
547
- if(errorBubble){return;}
548
- errorBubble = api.errorBubble = $('<'+alertElem+' class="validity-alert-wrapper" role="alert"><span class="validity-alert"><span class="va-arrow"><span class="va-arrow-box"></span></span><span class="va-box"></span></span></'+alertElem+'>').css({position: 'absolute', display: 'none'});
549
- webshims.ready('DOM', function(){
550
- errorBubble.appendTo('body');
551
- if($.fn.bgIframe){
552
- errorBubble.bgIframe();
553
- }
554
- });
555
- }
556
- };
557
-
558
-
559
- boundHide = $.proxy(api, 'hide');
560
-
561
- return api;
562
- })();
563
-
564
-
565
- /* extension, but also used to fix native implementation workaround/bugfixes */
566
- (function(){
567
- var firstEvent,
568
- invalids = [],
569
- stopSubmitTimer,
570
- form
571
- ;
572
-
573
- $(document).on('invalid', function(e){
574
- if(e.wrongWebkitInvalid){return;}
575
- var jElm = $(e.target);
576
- var shadowElem = jElm.getShadowElement();
577
- if(!shadowElem.hasClass(invalidClass)){
578
- shadowElem.addClass(invalidClasses).removeClass(validClasses);
579
- setTimeout(function(){
580
- $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
581
- }, 0);
582
- }
583
-
584
- if(!firstEvent){
585
- //trigger firstinvalid
586
- firstEvent = $.Event('firstinvalid');
587
- firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
588
- var firstSystemInvalid = $.Event('firstinvalidsystem');
589
- $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
590
- jElm.trigger(firstEvent);
591
- }
592
-
593
- //if firstinvalid was prevented all invalids will be also prevented
594
- if( firstEvent && firstEvent.isDefaultPrevented() ){
595
- e.preventDefault();
596
- }
597
- invalids.push(e.target);
598
- e.extraData = 'fix';
599
- clearTimeout(stopSubmitTimer);
600
- stopSubmitTimer = setTimeout(function(){
601
- var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
602
- //reset firstinvalid
603
- firstEvent = false;
604
- invalids = [];
605
- $(e.target).trigger(lastEvent, lastEvent);
606
- }, 9);
607
- jElm = null;
608
- shadowElem = null;
609
- });
610
- })();
611
-
612
- $.fn.getErrorMessage = function(){
613
- var message = '';
614
- var elem = this[0];
615
- if(elem){
616
- message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
617
- }
618
- return message;
619
- };
620
-
621
- if(options.replaceValidationUI){
622
- webshims.ready('DOM forms', function(){
623
- $(document).on('firstinvalid', function(e){
624
- if(!e.isInvalidUIPrevented()){
625
- e.preventDefault();
626
- $.webshims.validityAlert.showFor( e.target );
627
- }
628
- });
629
- });
630
- }
631
- });
632
-
633
- })(jQuery);
634
1
  jQuery.webshims.register('form-native-extend', function($, webshims, window, doc, undefined, options){
635
2
  "use strict";
636
3
  var Modernizr = window.Modernizr;
@@ -639,15 +6,32 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
639
6
  var typeModels = webshims.inputTypes;
640
7
  var validityRules = {};
641
8
 
9
+ var updateValidity = (function(){
10
+ var timer;
11
+ var getValidity = function(){
12
+ $(this).prop('validity');
13
+ };
14
+ var update = function(){
15
+ $('input').each(getValidity);
16
+ };
17
+ return function(fast){
18
+ clearTimeout(timer);
19
+ timer = setTimeout(update, 9);
20
+ };
21
+ })();
642
22
  webshims.addInputType = function(type, obj){
643
23
  typeModels[type] = obj;
24
+ //update validity of all implemented input types
25
+ if($.isDOMReady && Modernizr.formvalidation && !webshims.bugs.bustedValidity){
26
+ updateValidity();
27
+ }
644
28
  };
645
29
 
646
30
  webshims.addValidityRule = function(type, fn){
647
31
  validityRules[type] = fn;
648
32
  };
649
33
 
650
- webshims.addValidityRule('typeMismatch',function (input, val, cache, validityState){
34
+ webshims.addValidityRule('typeMismatch', function (input, val, cache, validityState){
651
35
  if(val === ''){return false;}
652
36
  var ret = validityState.typeMismatch;
653
37
  if(!('type' in cache)){
@@ -887,180 +271,3123 @@ jQuery.webshims.register('form-native-extend', function($, webshims, window, doc
887
271
 
888
272
 
889
273
  });
890
- jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
274
+ jQuery.webshims.register('form-number-date-api', function($, webshims, window, document, undefined){
891
275
  "use strict";
892
- var validityMessages = webshims.validityMessages;
893
276
 
894
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
895
277
 
896
- validityMessages['en'] = $.extend(true, {
897
- typeMismatch: {
898
- email: 'Please enter an email address.',
899
- url: 'Please enter a URL.',
900
- number: 'Please enter a number.',
901
- date: 'Please enter a date.',
902
- time: 'Please enter a time.',
903
- range: 'Invalid input.',
904
- "datetime-local": 'Please enter a datetime.'
905
- },
906
- rangeUnderflow: {
907
- defaultMessage: 'Value must be greater than or equal to {%min}.'
278
+ if(!webshims.getStep){
279
+ webshims.getStep = function(elem, type){
280
+ var step = $.attr(elem, 'step');
281
+ if(step === 'any'){
282
+ return step;
283
+ }
284
+ type = type || getType(elem);
285
+ if(!typeModels[type] || !typeModels[type].step){
286
+ return step;
287
+ }
288
+ step = typeProtos.number.asNumber(step);
289
+ return ((!isNaN(step) && step > 0) ? step : typeModels[type].step) * (typeModels[type].stepScaleFactor || 1);
290
+ };
291
+ }
292
+ if(!webshims.addMinMaxNumberToCache){
293
+ webshims.addMinMaxNumberToCache = function(attr, elem, cache){
294
+ if (!(attr+'AsNumber' in cache)) {
295
+ cache[attr+'AsNumber'] = typeModels[cache.type].asNumber(elem.attr(attr));
296
+ if(isNaN(cache[attr+'AsNumber']) && (attr+'Default' in typeModels[cache.type])){
297
+ cache[attr+'AsNumber'] = typeModels[cache.type][attr+'Default'];
298
+ }
299
+ }
300
+ };
301
+ }
302
+
303
+ var nan = parseInt('NaN', 10),
304
+ doc = document,
305
+ typeModels = webshims.inputTypes,
306
+ isNumber = function(string){
307
+ return (typeof string == 'number' || (string && string == string * 1));
908
308
  },
909
- rangeOverflow: {
910
- defaultMessage: 'Value must be less than or equal to {%max}.'
309
+ supportsType = function(type){
310
+ return ($('<input type="'+type+'" />').prop('type') === type);
911
311
  },
912
- stepMismatch: 'Invalid input.',
913
- tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
914
-
915
- patternMismatch: 'Invalid input. {%title}',
916
- valueMissing: {
917
- defaultMessage: 'Please fill out this field.',
918
- checkbox: 'Please check this box if you want to proceed.'
919
- }
920
- }, (validityMessages['en'] || validityMessages['en-US'] || {}));
921
-
922
-
923
- ['select', 'radio'].forEach(function(type){
924
- if(typeof validityMessages['en'].valueMissing == 'object'){
925
- validityMessages['en'].valueMissing[type] = 'Please select an option.';
926
- }
927
- });
928
-
929
- ['date', 'time', 'datetime-local'].forEach(function(type){
930
- if(typeof validityMessages['en'].rangeUnderflow == 'object'){
931
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
932
- }
933
- });
934
- ['date', 'time', 'datetime-local'].forEach(function(type){
935
- if(typeof validityMessages['en'].rangeOverflow == 'object'){
936
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
937
- }
938
- });
939
-
940
- validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
941
- validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
942
-
943
- validityMessages['de'] = $.extend(true, {
944
- typeMismatch: {
945
- email: '{%value} ist keine zulässige E-Mail-Adresse',
946
- url: '{%value} ist keine zulässige Webadresse',
947
- number: '{%value} ist keine Nummer!',
948
- date: '{%value} ist kein Datum',
949
- time: '{%value} ist keine Uhrzeit',
950
- range: '{%value} ist keine Nummer!',
951
- "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
312
+ getType = function(elem){
313
+ return (elem.getAttribute('type') || '').toLowerCase();
952
314
  },
953
- rangeUnderflow: {
954
- defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
315
+ isDateTimePart = function(string){
316
+ return (string && !(isNaN(string * 1)));
955
317
  },
956
- rangeOverflow: {
957
- defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
318
+ addMinMaxNumberToCache = webshims.addMinMaxNumberToCache,
319
+ addleadingZero = function(val, len){
320
+ val = ''+val;
321
+ len = len - val.length;
322
+ for(var i = 0; i < len; i++){
323
+ val = '0'+val;
324
+ }
325
+ return val;
958
326
  },
959
- stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
960
- tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
961
- patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
962
- valueMissing: {
963
- defaultMessage: 'Bitte geben Sie einen Wert ein',
964
- checkbox: 'Bitte aktivieren Sie das Kästchen'
965
- }
966
- }, (validityMessages['de'] || {}));
327
+ EPS = 1e-7,
328
+ typeBugs = webshims.bugs.bustedValidity
329
+ ;
967
330
 
968
- ['select', 'radio'].forEach(function(type){
969
- if(typeof validityMessages['de'].valueMissing == 'object'){
970
- validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
331
+ webshims.addValidityRule('stepMismatch', function(input, val, cache, validityState){
332
+ if(val === ''){return false;}
333
+ if(!('type' in cache)){
334
+ cache.type = getType(input[0]);
971
335
  }
336
+
337
+ var ret = (validityState || {}).stepMismatch || false, base;
338
+ if(typeModels[cache.type] && typeModels[cache.type].step){
339
+ if( !('step' in cache) ){
340
+ cache.step = webshims.getStep(input[0], cache.type);
341
+ }
342
+
343
+ if(cache.step == 'any'){return false;}
344
+
345
+ if(!('valueAsNumber' in cache)){
346
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
347
+ }
348
+ if(isNaN(cache.valueAsNumber)){return false;}
349
+
350
+ addMinMaxNumberToCache('min', input, cache);
351
+ base = cache.minAsNumber;
352
+ if(isNaN(base)){
353
+ base = typeModels[cache.type].stepBase || 0;
354
+ }
355
+
356
+ ret = Math.abs((cache.valueAsNumber - base) % cache.step);
357
+
358
+ ret = !( ret <= EPS || Math.abs(ret - cache.step) <= EPS );
359
+ }
360
+ return ret;
361
+ });
362
+
363
+
364
+
365
+ [{name: 'rangeOverflow', attr: 'max', factor: 1}, {name: 'rangeUnderflow', attr: 'min', factor: -1}].forEach(function(data, i){
366
+ webshims.addValidityRule(data.name, function(input, val, cache, validityState) {
367
+ var ret = (validityState || {})[data.name] || false;
368
+ if(val === ''){return ret;}
369
+ if (!('type' in cache)) {
370
+ cache.type = getType(input[0]);
371
+ }
372
+ if (typeModels[cache.type] && typeModels[cache.type].asNumber) {
373
+ if(!('valueAsNumber' in cache)){
374
+ cache.valueAsNumber = typeModels[cache.type].asNumber( val );
375
+ }
376
+ if(isNaN(cache.valueAsNumber)){
377
+ return false;
378
+ }
379
+
380
+ addMinMaxNumberToCache(data.attr, input, cache);
381
+
382
+ if(isNaN(cache[data.attr+'AsNumber'])){
383
+ return ret;
384
+ }
385
+ ret = ( cache[data.attr+'AsNumber'] * data.factor < cache.valueAsNumber * data.factor - EPS );
386
+ }
387
+ return ret;
388
+ });
972
389
  });
973
390
 
974
- ['date', 'time', 'datetime-local'].forEach(function(type){
975
- if(typeof validityMessages['de'].rangeUnderflow == 'object'){
976
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
391
+ webshims.reflectProperties(['input'], ['max', 'min', 'step']);
392
+
393
+
394
+ //IDLs and methods, that aren't part of constrain validation, but strongly tight to it
395
+ var valueAsNumberDescriptor = webshims.defineNodeNameProperty('input', 'valueAsNumber', {
396
+ prop: {
397
+ get: function(){
398
+ var elem = this;
399
+ var type = getType(elem);
400
+ var ret = (typeModels[type] && typeModels[type].asNumber) ?
401
+ typeModels[type].asNumber($.prop(elem, 'value')) :
402
+ (valueAsNumberDescriptor.prop._supget && valueAsNumberDescriptor.prop._supget.apply(elem, arguments));
403
+ if(ret == null){
404
+ ret = nan;
405
+ }
406
+ return ret;
407
+ },
408
+ set: function(val){
409
+ var elem = this;
410
+ var type = getType(elem);
411
+ if(typeModels[type] && typeModels[type].numberToString){
412
+ //is NaN a number?
413
+ if(isNaN(val)){
414
+ $.prop(elem, 'value', '');
415
+ return;
416
+ }
417
+ var set = typeModels[type].numberToString(val);
418
+ if(set !== false){
419
+ $.prop(elem, 'value', set);
420
+ } else {
421
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
422
+ }
423
+ } else {
424
+ valueAsNumberDescriptor.prop._supset && valueAsNumberDescriptor.prop._supset.apply(elem, arguments);
425
+ }
426
+ }
977
427
  }
978
428
  });
979
- ['date', 'time', 'datetime-local'].forEach(function(type){
980
- if(typeof validityMessages['de'].rangeOverflow == 'object'){
981
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
429
+
430
+ var valueAsDateDescriptor = webshims.defineNodeNameProperty('input', 'valueAsDate', {
431
+ prop: {
432
+ get: function(){
433
+ var elem = this;
434
+ var type = getType(elem);
435
+ return (typeModels[type] && typeModels[type].asDate && !typeModels[type].noAsDate) ?
436
+ typeModels[type].asDate($.prop(elem, 'value')) :
437
+ valueAsDateDescriptor.prop._supget && valueAsDateDescriptor.prop._supget.call(elem) || null;
438
+ },
439
+ set: function(value){
440
+ var elem = this;
441
+ var type = getType(elem);
442
+ if(typeModels[type] && typeModels[type].dateToString && !typeModels[type].noAsDate){
443
+
444
+ if(value === null){
445
+ $.prop(elem, 'value', '');
446
+ return '';
447
+ }
448
+ var set = typeModels[type].dateToString(value);
449
+ if(set !== false){
450
+ $.prop(elem, 'value', set);
451
+ return set;
452
+ } else {
453
+ webshims.error('INVALID_STATE_ERR: DOM Exception 11');
454
+ }
455
+ } else {
456
+ return valueAsDateDescriptor.prop._supset && valueAsDateDescriptor.prop._supset.apply(elem, arguments) || null;
457
+ }
458
+ }
982
459
  }
983
460
  });
984
461
 
985
- var currentValidationMessage = validityMessages[''];
462
+ $.each({stepUp: 1, stepDown: -1}, function(name, stepFactor){
463
+ var stepDescriptor = webshims.defineNodeNameProperty('input', name, {
464
+ prop: {
465
+ value: function(factor){
466
+ var step, val, dateVal, valModStep, alignValue, cache;
467
+ var type = getType(this);
468
+ if(typeModels[type] && typeModels[type].asNumber){
469
+ cache = {type: type};
470
+ if(!factor){
471
+ factor = 1;
472
+ webshims.info("you should always use a factor for stepUp/stepDown");
473
+ }
474
+ factor *= stepFactor;
475
+
476
+ val = $.prop(this, 'valueAsNumber');
477
+
478
+ if(isNaN(val)){
479
+ webshims.info("valueAsNumber is NaN can't apply stepUp/stepDown ");
480
+ throw('invalid state error');
481
+ }
482
+
483
+ step = webshims.getStep(this, type);
484
+
485
+ if(step == 'any'){
486
+ webshims.info("step is 'any' can't apply stepUp/stepDown");
487
+ throw('invalid state error');
488
+ }
489
+
490
+ webshims.addMinMaxNumberToCache('min', $(this), cache);
491
+ webshims.addMinMaxNumberToCache('max', $(this), cache);
492
+
493
+ step *= factor;
494
+
495
+ val = (val + step).toFixed(5) * 1;
496
+ valModStep = (val - (cache.minAsNumber || 0)) % step;
497
+
498
+ if ( valModStep && (Math.abs(valModStep) > EPS) ) {
499
+ alignValue = val - valModStep;
500
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
501
+ val = alignValue.toFixed(5) * 1;
502
+ }
503
+
504
+ if( (!isNaN(cache.maxAsNumber) && val > cache.maxAsNumber) || (!isNaN(cache.minAsNumber) && val < cache.minAsNumber) ){
505
+ webshims.info("max/min overflow can't apply stepUp/stepDown");
506
+ throw('invalid state error');
507
+ }
508
+ if(dateVal){
509
+ $.prop(this, 'valueAsDate', dateVal);
510
+ } else {
511
+ $.prop(this, 'valueAsNumber', val);
512
+ }
513
+ } else if(stepDescriptor.prop && stepDescriptor.prop.value){
514
+ return stepDescriptor.prop.value.apply(this, arguments);
515
+ } else {
516
+ webshims.info("no step method for type: "+ type);
517
+ throw('invalid state error');
518
+ }
519
+ }
520
+ }
521
+ });
522
+ });
986
523
 
987
524
 
988
- webshims.createValidationMessage = function(elem, name){
989
- var message = currentValidationMessage[name];
990
- if(message && typeof message !== 'string'){
991
- message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
992
- }
993
- if(message){
994
- ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
995
- if(message.indexOf('{%'+attr) === -1){return;}
996
- var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
997
- if(name == 'patternMismatch' && attr == 'title' && !val){
998
- webshims.error('no title for patternMismatch provided. Always add a title attribute.');
525
+ var typeProtos = {
526
+
527
+ number: {
528
+ mismatch: function(val){
529
+ return !(isNumber(val));
530
+ },
531
+ step: 1,
532
+ //stepBase: 0, 0 = default
533
+ stepScaleFactor: 1,
534
+ asNumber: function(str){
535
+ return (isNumber(str)) ? str * 1 : nan;
536
+ },
537
+ numberToString: function(num){
538
+ return (isNumber(num)) ? num : false;
539
+ }
540
+ },
541
+
542
+ range: {
543
+ minDefault: 0,
544
+ maxDefault: 100
545
+ },
546
+
547
+ date: {
548
+ mismatch: function(val){
549
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
550
+ var i;
551
+ var valA = val.split(/\u002D/);
552
+ if(valA.length !== 3){return true;}
553
+ var ret = false;
554
+
555
+
556
+ if(valA[0].length < 4 || valA[1].length != 2 || valA[1] > 12 || valA[2].length != 2 || valA[2] > 33){
557
+ ret = true;
558
+ } else {
559
+ for(i = 0; i < 3; i++){
560
+ if(!isDateTimePart(valA[i])){
561
+ ret = true;
562
+ break;
563
+ }
564
+ }
565
+ }
566
+
567
+ return ret || (val !== this.dateToString( this.asDate(val, true) ) );
568
+ },
569
+ step: 1,
570
+ //stepBase: 0, 0 = default
571
+ stepScaleFactor: 86400000,
572
+ asDate: function(val, _noMismatch){
573
+ if(!_noMismatch && this.mismatch(val)){
574
+ return null;
999
575
  }
1000
- message = message.replace('{%'+ attr +'}', val);
1001
- if('value' == attr){
1002
- message = message.replace('{%valueLen}', val.length);
576
+ return new Date(this.asNumber(val, true));
577
+ },
578
+ asNumber: function(str, _noMismatch){
579
+ var ret = nan;
580
+ if(_noMismatch || !this.mismatch(str)){
581
+ str = str.split(/\u002D/);
582
+ ret = Date.UTC(str[0], str[1] - 1, str[2]);
1003
583
  }
1004
- });
584
+ return ret;
585
+ },
586
+ numberToString: function(num){
587
+ return (isNumber(num)) ? this.dateToString(new Date( num * 1)) : false;
588
+ },
589
+ dateToString: function(date){
590
+ return (date && date.getFullYear) ? addleadingZero(date.getUTCFullYear(), 4) +'-'+ addleadingZero(date.getUTCMonth()+1, 2) +'-'+ addleadingZero(date.getUTCDate(), 2) : false;
591
+ }
592
+ },
593
+ time: {
594
+ mismatch: function(val, _getParsed){
595
+ if(!val || !val.split || !(/\d$/.test(val))){return true;}
596
+ val = val.split(/\u003A/);
597
+ if(val.length < 2 || val.length > 3){return true;}
598
+ var ret = false,
599
+ sFraction;
600
+ if(val[2]){
601
+ val[2] = val[2].split(/\u002E/);
602
+ sFraction = parseInt(val[2][1], 10);
603
+ val[2] = val[2][0];
604
+ }
605
+ $.each(val, function(i, part){
606
+ if(!isDateTimePart(part) || part.length !== 2){
607
+ ret = true;
608
+ return false;
609
+ }
610
+ });
611
+ if(ret){return true;}
612
+ if(val[0] > 23 || val[0] < 0 || val[1] > 59 || val[1] < 0){
613
+ return true;
614
+ }
615
+ if(val[2] && (val[2] > 59 || val[2] < 0 )){
616
+ return true;
617
+ }
618
+ if(sFraction && isNaN(sFraction)){
619
+ return true;
620
+ }
621
+ if(sFraction){
622
+ if(sFraction < 100){
623
+ sFraction *= 100;
624
+ } else if(sFraction < 10){
625
+ sFraction *= 10;
626
+ }
627
+ }
628
+ return (_getParsed === true) ? [val, sFraction] : false;
629
+ },
630
+ step: 60,
631
+ stepBase: 0,
632
+ stepScaleFactor: 1000,
633
+ asDate: function(val){
634
+ val = new Date(this.asNumber(val));
635
+ return (isNaN(val)) ? null : val;
636
+ },
637
+ asNumber: function(val){
638
+ var ret = nan;
639
+ val = this.mismatch(val, true);
640
+ if(val !== true){
641
+ ret = Date.UTC('1970', 0, 1, val[0][0], val[0][1], val[0][2] || 0);
642
+ if(val[1]){
643
+ ret += val[1];
644
+ }
645
+ }
646
+ return ret;
647
+ },
648
+ dateToString: function(date){
649
+ if(date && date.getUTCHours){
650
+ var str = addleadingZero(date.getUTCHours(), 2) +':'+ addleadingZero(date.getUTCMinutes(), 2),
651
+ tmp = date.getSeconds()
652
+ ;
653
+ if(tmp != "0"){
654
+ str += ':'+ addleadingZero(tmp, 2);
655
+ }
656
+ tmp = date.getUTCMilliseconds();
657
+ if(tmp != "0"){
658
+ str += '.'+ addleadingZero(tmp, 3);
659
+ }
660
+ return str;
661
+ } else {
662
+ return false;
663
+ }
664
+ }
665
+ },
666
+ month: {
667
+ mismatch: function(val){
668
+ return typeProtos.date.mismatch(val+'-01');
669
+ },
670
+ step: 1,
671
+ stepScaleFactor: false,
672
+ //stepBase: 0, 0 = default
673
+ asDate: function(val){
674
+ return new Date(typeProtos.date.asNumber(val+'-01'));
675
+ },
676
+ asNumber: function(val){
677
+ //1970-01
678
+ var ret = nan;
679
+ if(val && !this.mismatch(val)){
680
+ val = val.split(/\u002D/);
681
+ val[0] = (val[0] * 1) - 1970;
682
+ val[1] = (val[1] * 1) - 1;
683
+ ret = (val[0] * 12) + val[1];
684
+ }
685
+ return ret;
686
+ },
687
+ numberToString: function(num){
688
+ var mod;
689
+ var ret = false;
690
+ if(isNumber(num)){
691
+ mod = (num % 12);
692
+ num = ((num - mod) / 12) + 1970;
693
+ mod += 1;
694
+ if(mod < 1){
695
+ num -= 1;
696
+ mod += 12;
697
+ }
698
+ ret = addleadingZero(num, 4)+'-'+addleadingZero(mod, 2);
699
+
700
+ }
701
+
702
+ return ret;
703
+ },
704
+ dateToString: function(date){
705
+ if(date && date.getUTCHours){
706
+ var str = typeProtos.date.dateToString(date);
707
+ return (str.split && (str = str.split(/\u002D/))) ? str[0]+'-'+str[1] : false;
708
+ } else {
709
+ return false;
710
+ }
711
+ }
1005
712
  }
1006
- return message || '';
713
+ // ,'datetime-local': {
714
+ // mismatch: function(val, _getParsed){
715
+ // if(!val || !val.split || (val+'special').split(/\u0054/).length !== 2){return true;}
716
+ // val = val.split(/\u0054/);
717
+ // return ( typeProtos.date.mismatch(val[0]) || typeProtos.time.mismatch(val[1], _getParsed) );
718
+ // },
719
+ // noAsDate: true,
720
+ // asDate: function(val){
721
+ // val = new Date(this.asNumber(val));
722
+ //
723
+ // return (isNaN(val)) ? null : val;
724
+ // },
725
+ // asNumber: function(val){
726
+ // var ret = nan;
727
+ // var time = this.mismatch(val, true);
728
+ // if(time !== true){
729
+ // val = val.split(/\u0054/)[0].split(/\u002D/);
730
+ //
731
+ // ret = Date.UTC(val[0], val[1] - 1, val[2], time[0][0], time[0][1], time[0][2] || 0);
732
+ // if(time[1]){
733
+ // ret += time[1];
734
+ // }
735
+ // }
736
+ // return ret;
737
+ // },
738
+ // dateToString: function(date, _getParsed){
739
+ // return typeProtos.date.dateToString(date) +'T'+ typeProtos.time.dateToString(date, _getParsed);
740
+ // }
741
+ // }
1007
742
  };
1008
743
 
1009
-
1010
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
1011
- implementProperties.push('validationMessage');
744
+ if(typeBugs || !supportsType('range') || !supportsType('time')){
745
+ typeProtos.range = $.extend({}, typeProtos.number, typeProtos.range);
746
+ typeProtos.time = $.extend({}, typeProtos.date, typeProtos.time);
747
+ typeProtos.month = $.extend({}, typeProtos.date, typeProtos.month);
748
+ // typeProtos['datetime-local'] = $.extend({}, typeProtos.date, typeProtos.time, typeProtos['datetime-local']);
1012
749
  }
1013
750
 
1014
- webshims.activeLang({
1015
- langObj: validityMessages,
1016
- module: 'form-core',
1017
- callback: function(langObj){
1018
- currentValidationMessage = langObj;
751
+ //'datetime-local'
752
+ ['number', 'month', 'range', 'date', 'time'].forEach(function(type){
753
+ if(typeBugs || !supportsType(type)){
754
+ webshims.addInputType(type, typeProtos[type]);
1019
755
  }
1020
756
  });
1021
-
1022
- implementProperties.forEach(function(messageProp){
1023
- webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
757
+
758
+ if($('<input />').prop('labels') == null){
759
+ webshims.defineNodeNamesProperty('button, input, keygen, meter, output, progress, select, textarea', 'labels', {
1024
760
  prop: {
1025
- value: '',
761
+ get: function(){
762
+ if(this.type == 'hidden'){return null;}
763
+ var id = this.id;
764
+ var labels = $(this)
765
+ .closest('label')
766
+ .filter(function(){
767
+ var hFor = (this.attributes['for'] || {});
768
+ return (!hFor.specified || hFor.value == id);
769
+ })
770
+ ;
771
+
772
+ if(id) {
773
+ labels = labels.add('label[for="'+ id +'"]');
774
+ }
775
+ return labels.get();
776
+ },
1026
777
  writeable: false
1027
778
  }
1028
779
  });
1029
- ['input', 'select', 'textarea'].forEach(function(nodeName){
1030
- var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
1031
- prop: {
1032
- get: function(){
1033
- var elem = this;
1034
- var message = '';
1035
- if(!$.prop(elem, 'willValidate')){
1036
- return message;
1037
- }
1038
-
1039
- var validity = $.prop(elem, 'validity') || {valid: 1};
1040
-
1041
- if(validity.valid){return message;}
1042
- message = webshims.getContentValidationMessage(elem, validity);
1043
-
1044
- if(message){return message;}
1045
-
1046
- if(validity.customError && elem.nodeName){
1047
- message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
1048
- if(message){return message;}
780
+ }
781
+
782
+ });
783
+ (function($){
784
+
785
+ var id = 0;
786
+ var isNumber = function(string){
787
+ return (typeof string == 'number' || (string && string == string * 1));
788
+ };
789
+ var retDefault = function(val, def){
790
+ if(!(typeof val == 'number' || (val && val == val * 1))){
791
+ return def;
792
+ }
793
+ return val * 1;
794
+ };
795
+ var createOpts = ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex'];
796
+ var rangeProto = {
797
+ _create: function(){
798
+ var i;
799
+
800
+
801
+ this.element.addClass('ws-range').attr({role: 'slider'}).append('<span class="ws-range-min" /><span class="ws-range-rail"><span class="ws-range-thumb" /></span>');
802
+ this.trail = $('.ws-range-rail', this.element);
803
+ this.range = $('.ws-range-min', this.element);
804
+ this.thumb = $('.ws-range-thumb', this.trail);
805
+
806
+ this.updateMetrics();
807
+
808
+ this.orig = this.options.orig;
809
+
810
+ for(i = 0; i < createOpts.length; i++){
811
+ this[createOpts[i]](this.options[createOpts[i]]);
812
+ }
813
+ this.value = this._value;
814
+ this.value(this.options.value);
815
+ this.initDataList();
816
+ this.element.data('rangeUi', this);
817
+ this.addBindings();
818
+ this._init = true;
819
+ },
820
+ value: $.noop,
821
+ _value: function(val, _noNormalize, animate){
822
+ var left, posDif;
823
+ var o = this.options;
824
+ var oVal = val;
825
+ var thumbStyle = {};
826
+ var rangeStyle = {};
827
+ if(!_noNormalize && parseFloat(val, 10) != val){
828
+ val = o.min + ((o.max - o.min) / 2);
829
+ }
830
+
831
+ if(!_noNormalize){
832
+ val = this.normalizeVal(val);
833
+ }
834
+ left = 100 * ((val - o.min) / (o.max - o.min));
835
+
836
+ this.options.value = val;
837
+ this.thumb.stop();
838
+ this.range.stop();
839
+
840
+ rangeStyle[this.dirs.width] = left+'%';
841
+ if(this.vertical){
842
+ left = Math.abs(left - 100);
843
+ }
844
+ thumbStyle[this.dirs.left] = left+'%';
845
+
846
+
847
+ if(!animate){
848
+ this.thumb.css(thumbStyle);
849
+ this.range.css(rangeStyle);
850
+ } else {
851
+ if(typeof animate != 'object'){
852
+ animate = {};
853
+ } else {
854
+ animate = $.extend({}, animate);
855
+ }
856
+ if(!animate.duration){
857
+ posDif = Math.abs(left - parseInt(this.thumb[0].style[this.dirs.left] || 50, 10));
858
+ animate.duration = Math.max(Math.min(999, posDif * 5), 99);
859
+ }
860
+ this.thumb.animate(thumbStyle, animate);
861
+ this.range.animate(rangeStyle, animate);
862
+ }
863
+ if(this.orig && (oVal != val || (!this._init && this.orig.value != val)) ){
864
+ this.options._change(val);
865
+ }
866
+ this.element.attr({
867
+ 'aria-valuenow': this.options.value,
868
+ 'aria-valuetext': this.options.textValue ? this.options.textValue(this.options.value) : this.options.options[this.options.value] || this.options.value
869
+ });
870
+ },
871
+ initDataList: function(){
872
+ if(this.orig){
873
+ var listTimer;
874
+ var that = this;
875
+ var updateList = function(){
876
+ $(that.orig)
877
+ .jProp('list')
878
+ .off('updateDatalist', updateList)
879
+ .on('updateDatalist', updateList)
880
+ ;
881
+ clearTimeout(listTimer);
882
+ listTimer = setTimeout(function(){
883
+ if(that.list){
884
+ that.list();
1049
885
  }
1050
- $.each(validity, function(name, prop){
1051
- if(name == 'valid' || !prop){return;}
1052
-
1053
- message = webshims.createValidationMessage(elem, name);
1054
- if(message){
1055
- return false;
886
+ }, 9);
887
+
888
+ };
889
+
890
+ $(this.orig).on('listdatalistchange', updateList);
891
+ this.list();
892
+ }
893
+ },
894
+ list: function(opts){
895
+ var o = this.options;
896
+ var min = o.min;
897
+ var max = o.max;
898
+ var trail = this.trail;
899
+ var that = this;
900
+
901
+ this.element.attr({'aria-valuetext': o.options[o.value] || o.value});
902
+ $('.ws-range-ticks', trail).remove();
903
+
904
+
905
+ $(this.orig).jProp('list').find('option').each(function(){
906
+ o.options[$.prop(this, 'value')] = $.prop(this, 'label');
907
+ });
908
+
909
+ $.each(o.options, function(val, label){
910
+ if(!isNumber(val) || val < min || val > max){return;}
911
+ var left = 100 * ((val - min) / (max - min));
912
+ var title = o.showLabels ? ' title="'+ label +'"' : '';
913
+ if(that.vertical){
914
+ left = Math.abs(left - 100);
915
+ }
916
+ trail.append('<span class="ws-range-ticks"'+ title +' style="'+(that.dirs.left)+': '+left+'%;" />');
917
+ });
918
+ },
919
+ readonly: function(val){
920
+ val = !!val;
921
+ this.options.readonly = val;
922
+ this.element.attr('aria-readonly', ''+val);
923
+ },
924
+ disabled: function(val){
925
+ val = !!val;
926
+ this.options.disabled = val;
927
+ if(val){
928
+ this.element.attr({tabindex: -1, 'aria-disabled': 'true'});
929
+ } else {
930
+ this.element.attr({tabindex: this.options.tabindex, 'aria-disabled': 'false'});
931
+ }
932
+ },
933
+ tabindex: function(val){
934
+ this.options.tabindex = val;
935
+ if(!this.options.disabled){
936
+ this.element.attr({tabindex: val});
937
+ }
938
+ },
939
+ title: function(val){
940
+ this.element.prop('title', val);
941
+ },
942
+ min: function(val){
943
+ this.options.min = retDefault(val, 0);
944
+ this.value(this.options.value, true);
945
+ },
946
+ max: function(val){
947
+ this.options.max = retDefault(val, 100);
948
+ this.value(this.options.value, true);
949
+ },
950
+ step: function(val){
951
+ this.options.step = val == 'any' ? 'any' : retDefault(val, 1);
952
+ this.value(this.options.value);
953
+ },
954
+
955
+ normalizeVal: function(val){
956
+ var valModStep, alignValue, step;
957
+ var o = this.options;
958
+
959
+ if(val <= o.min){
960
+ val = o.min;
961
+ } else if(val >= o.max) {
962
+ val = o.max;
963
+ } else if(o.step != 'any'){
964
+ step = o.step;
965
+ valModStep = (val - o.min) % step;
966
+ alignValue = val - valModStep;
967
+
968
+ if ( Math.abs(valModStep) * 2 >= step ) {
969
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
970
+ }
971
+ val = alignValue.toFixed(5) * 1;
972
+ }
973
+ return val;
974
+ },
975
+ doStep: function(factor, animate){
976
+ var step = retDefault(this.options.step, 1);
977
+ if(this.options.step == 'any'){
978
+ step = Math.min(step, (this.options.max - this.options.min) / 10);
979
+ }
980
+ this.value( this.options.value + (step * factor), false, animate );
981
+
982
+ },
983
+
984
+ getStepedValueFromPos: function(pos){
985
+ var val, valModStep, alignValue, step;
986
+
987
+ if(pos <= 0){
988
+ val = this.options[this.dirs.min];
989
+ } else if(pos > 100) {
990
+ val = this.options[this.dirs.max];
991
+ } else {
992
+ if(this.vertical){
993
+ pos = Math.abs(pos - 100);
994
+ }
995
+ val = ((this.options.max - this.options.min) * (pos / 100)) + this.options.min;
996
+ step = this.options.step;
997
+ if(step != 'any'){
998
+ valModStep = (val - this.options.min) % step;
999
+ alignValue = val - valModStep;
1000
+
1001
+ if ( Math.abs(valModStep) * 2 >= step ) {
1002
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
1003
+ }
1004
+ val = ((alignValue).toFixed(5)) * 1;
1005
+
1006
+ }
1007
+ }
1008
+
1009
+ return val;
1010
+ },
1011
+ addBindings: function(){
1012
+ var leftOffset, widgetUnits, hasFocus;
1013
+ var that = this;
1014
+ var o = this.options;
1015
+
1016
+ var eventTimer = (function(){
1017
+ var events = {};
1018
+ return {
1019
+ init: function(name, curVal, fn){
1020
+ if(!events[name]){
1021
+ events[name] = {fn: fn};
1022
+ if(that.orig){
1023
+ $(that.orig).on(name, function(){
1024
+ events[name].val = $.prop(that.orig, 'value');
1025
+ });
1056
1026
  }
1057
- });
1058
- return message || '';
1027
+
1028
+ }
1029
+ events[name].val = curVal;
1059
1030
  },
1060
- writeable: false
1031
+ call: function(name, val){
1032
+ if(events[name].val != val){
1033
+ clearTimeout(events[name].timer);
1034
+ events[name].val = val;
1035
+ events[name].timer = setTimeout(function(){
1036
+ events[name].fn(val, that);
1037
+ }, 0);
1038
+ }
1039
+ }
1040
+ };
1041
+ })();
1042
+
1043
+ var setValueFromPos = function(e, animate){
1044
+
1045
+ var val = that.getStepedValueFromPos((e[that.dirs.mouse] - leftOffset) * widgetUnits);
1046
+ if(val != o.value){
1047
+ that.value(val, false, animate);
1048
+ eventTimer.call('input', val);
1049
+ }
1050
+ };
1051
+
1052
+ var remove = function(e){
1053
+ if(e && e.type == 'mouseup'){
1054
+ eventTimer.call('input', o.value);
1055
+ eventTimer.call('change', o.value);
1056
+ }
1057
+ that.element.removeClass('ws-active');
1058
+ $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1059
+ };
1060
+ var add = function(e){
1061
+ e.preventDefault();
1062
+ $(document).off('mousemove', setValueFromPos).off('mouseup', remove);
1063
+ if(!o.readonly && !o.disabled){
1064
+ leftOffset = that.element.focus().addClass('ws-active').offset();
1065
+ widgetUnits = that.element[that.dirs.width]();
1066
+ if(!widgetUnits || !leftOffset){return;}
1067
+ leftOffset = leftOffset[that.dirs.pos];
1068
+ widgetUnits = 100 / (widgetUnits - ((that.thumb[that.dirs.outerWidth]() || 2) / 2));
1069
+ setValueFromPos(e, o.animate);
1070
+ $(document)
1071
+ .on({
1072
+ mouseup: remove,
1073
+ mousemove: setValueFromPos
1074
+ })
1075
+ ;
1076
+ e.stopPropagation();
1077
+ }
1078
+ };
1079
+ var elementEvts = {
1080
+ mousedown: add,
1081
+ focus: function(e){
1082
+ if(!o.disabled){
1083
+ eventTimer.init('input', o.value);
1084
+ eventTimer.init('change', o.value);
1085
+ that.element.addClass('ws-focus');
1086
+ }
1087
+ hasFocus = true;
1088
+ },
1089
+ blur: function(e){
1090
+ that.element.removeClass('ws-focus ws-active');
1091
+ hasFocus = false;
1092
+ eventTimer.init('input', o.value);
1093
+ eventTimer.call('change', o.value);
1094
+ },
1095
+ keyup: function(){
1096
+ that.element.removeClass('ws-active');
1097
+ eventTimer.call('input', o.value);
1098
+ eventTimer.call('change', o.value);
1099
+ },
1100
+
1101
+ keydown: function(e){
1102
+ var step = true;
1103
+ var code = e.keyCode;
1104
+ if(!o.readonly && !o.disabled){
1105
+ if (code == 39 || code == 38) {
1106
+ that.doStep(1);
1107
+ } else if (code == 37 || code == 40) {
1108
+ that.doStep(-1);
1109
+ } else if (code == 33) {
1110
+ that.doStep(10, o.animate);
1111
+ } else if (code == 34) {
1112
+ that.doStep(-10, o.animate);
1113
+ } else if (code == 36) {
1114
+ that.value(that.options.max, false, o.animate);
1115
+ } else if (code == 35) {
1116
+ that.value(that.options.min, false, o.animate);
1117
+ } else {
1118
+ step = false;
1119
+ }
1120
+ if (step) {
1121
+ that.element.addClass('ws-active');
1122
+ eventTimer.call('input', o.value);
1123
+ e.preventDefault();
1124
+ }
1125
+ }
1126
+ }
1127
+ };
1128
+
1129
+ eventTimer.init('input', o.value, this.options.input);
1130
+ eventTimer.init('change', o.value, this.options.change);
1131
+
1132
+ elementEvts[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
1133
+ if(delta && hasFocus && !o.readonly && !o.disabled){
1134
+ that.doStep(delta);
1135
+ e.preventDefault();
1136
+ eventTimer.call('input', o.value);
1061
1137
  }
1138
+ };
1139
+ this.element.on(elementEvts);
1140
+ this.thumb.on({
1141
+ mousedown: add
1062
1142
  });
1143
+ },
1144
+ updateMetrics: function(){
1145
+ var width = this.element.innerWidth();
1146
+ this.vertical = (width && this.element.innerHeight() - width > 10);
1147
+
1148
+ this.dirs = this.vertical ?
1149
+ {mouse: 'pageY', pos: 'top', min: 'max', max: 'min', left: 'top', width: 'height', outerWidth: 'outerHeight'} :
1150
+ {mouse: 'pageX', pos: 'left', min: 'min', max: 'max', left: 'left', width: 'width', outerWidth: 'outerWidth'}
1151
+ ;
1152
+ this.element
1153
+ [this.vertical ? 'addClass' : 'removeClass']('vertical-range')
1154
+ [this.vertical ? 'addClass' : 'removeClass']('horizontal-range')
1155
+ ;
1156
+ }
1157
+ };
1158
+
1159
+ $.fn.rangeUI = function(opts){
1160
+ 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);
1161
+ return this.each(function(){
1162
+ $.webshims.objectCreate(rangeProto, {
1163
+ element: {
1164
+ value: $(this)
1165
+ }
1166
+ }, opts);
1063
1167
  });
1064
-
1065
- });
1066
- });
1168
+ };
1169
+ jQuery.webshims.isReady('range-ui', true);
1170
+ })(jQuery);
1171
+ jQuery.webshims.register('form-number-date-ui', function($, webshims, window, document, undefined, options){
1172
+ "use strict";
1173
+ var curCfg;
1174
+ var formcfg = $.webshims.formcfg;
1175
+
1176
+ var stopPropagation = function(e){
1177
+ e.stopImmediatePropagation(e);
1178
+ };
1179
+ var createFormat = function(name){
1180
+ if(!curCfg.patterns[name+'Obj']){
1181
+ var obj = {};
1182
+ $.each(curCfg.patterns[name].split(curCfg[name+'Format']), function(i, name){
1183
+ obj[name] = i;
1184
+ });
1185
+ curCfg.patterns[name+'Obj'] = obj;
1186
+ }
1187
+ };
1188
+ var splitInputs = {
1189
+ date: {
1190
+ _create: function(){
1191
+ var obj = {
1192
+ 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]]
1193
+ };
1194
+ obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1], $('<span class="ws-input-seperator" />')[0], obj.splits[2]];
1195
+ return obj;
1196
+ },
1197
+ sort: function(element){
1198
+ createFormat('d');
1199
+ var i = 0;
1200
+ var seperators = $('.ws-input-seperator', element).html(curCfg.dFormat);
1201
+ var inputs = $('input', element);
1202
+ $.each(curCfg.patterns.dObj, function(name, value){
1203
+ var input = inputs.filter('.'+ name);
1204
+ if(input[0]){
1205
+
1206
+ input.appendTo(element);
1207
+ if(i < seperators.length){
1208
+ seperators.eq(i).insertAfter(input);
1209
+ }
1210
+ i++;
1211
+ }
1212
+ });
1213
+ }
1214
+ },
1215
+ month: {
1216
+ _create: function(){
1217
+ var obj = {
1218
+ splits: [$('<input type="text" class="yy" size="4" />')[0], $('<input type="text" class="mm ws-spin" />')[0]]
1219
+ };
1220
+ obj.elements = [obj.splits[0], $('<span class="ws-input-seperator" />')[0], obj.splits[1]];
1221
+ return obj;
1222
+ },
1223
+ sort: function(element){
1224
+ var seperator = $('.ws-input-seperator', element).html(curCfg.dFormat);
1225
+ var mm = $('input.mm', element);
1226
+ var action;
1227
+ if(curCfg.date.showMonthAfterYear){
1228
+ mm.appendTo(element);
1229
+ action = 'insertBefore';
1230
+ } else {
1231
+ mm.prependTo(element);
1232
+ action = 'insertAfter';
1233
+ }
1234
+ seperator[action](mm);
1235
+ }
1236
+ }
1237
+ };
1238
+ var labelWidth = (function(){
1239
+ var getId = function(){
1240
+ return webshims.getID(this);
1241
+ };
1242
+ return function(element, labels, noFocus){
1243
+ $(element).attr({'aria-labelledby': labels.map(getId).get().join(' ')});
1244
+ if(!noFocus){
1245
+ labels.on('click', function(e){
1246
+ element.getShadowFocusElement().focus();
1247
+ e.preventDefault();
1248
+ return false;
1249
+ });
1250
+ }
1251
+ };
1252
+ })();
1253
+ var addZero = function(val){
1254
+ if(!val){return "";}
1255
+ val = val+'';
1256
+ return val.length == 1 ? '0'+val : val;
1257
+ };
1258
+
1259
+
1260
+ (function(){
1261
+ var monthDigits = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
1262
+ formcfg.de = {
1263
+ numberFormat: {
1264
+ ",": ".",
1265
+ ".": ","
1266
+ },
1267
+ timeSigns: ":. ",
1268
+ numberSigns: ',',
1269
+ dateSigns: '.',
1270
+ dFormat: ".",
1271
+ patterns: {
1272
+ d: "dd.mm.yy"
1273
+ },
1274
+ month: {
1275
+ currentText: 'Aktueller Monat'
1276
+ },
1277
+ date: {
1278
+ close: 'schließen',
1279
+ clear: 'Löschen',
1280
+ prevText: 'Zurück',
1281
+ nextText: 'Vor',
1282
+ currentText: 'Heute',
1283
+ monthNames: ['Januar','Februar','März','April','Mai','Juni',
1284
+ 'Juli','August','September','Oktober','November','Dezember'],
1285
+ monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
1286
+ 'Jul','Aug','Sep','Okt','Nov','Dez'],
1287
+ dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
1288
+ dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
1289
+ dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
1290
+ weekHeader: 'KW',
1291
+ firstDay: 1,
1292
+ isRTL: false,
1293
+ showMonthAfterYear: false,
1294
+ yearSuffix: ''
1295
+ }
1296
+ };
1297
+
1298
+ formcfg.en = {
1299
+ numberFormat: {
1300
+ ".": ".",
1301
+ ",": ","
1302
+ },
1303
+ numberSigns: '.',
1304
+ dateSigns: '/',
1305
+ timeSigns: ":. ",
1306
+ dFormat: "/",
1307
+ patterns: {
1308
+ d: "mm/dd/yy"
1309
+ },
1310
+ month: {
1311
+ currentText: 'This month'
1312
+ },
1313
+ date: {
1314
+ "closeText": "Done",
1315
+ clear: 'Clear',
1316
+ "prevText": "Prev",
1317
+ "nextText": "Next",
1318
+ "currentText": "Today",
1319
+ "monthNames": ["January","February","March","April","May","June","July","August","September","October","November","December"],
1320
+ "monthNamesShort": ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
1321
+ "dayNames": ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
1322
+ "dayNamesShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
1323
+ "dayNamesMin": ["Su","Mo","Tu","We","Th","Fr","Sa"],
1324
+ "weekHeader": "Wk",
1325
+ "firstDay": 0,
1326
+ "isRTL": false,
1327
+ "showMonthAfterYear": false,
1328
+ "yearSuffix": ""
1329
+ }
1330
+ };
1331
+
1332
+ formcfg['en-US'] = formcfg['en-US'] || formcfg['en'];
1333
+ formcfg[''] = formcfg[''] || formcfg['en-US'];
1334
+ curCfg = formcfg[''];
1335
+
1336
+ var createMonthKeys = function(langCfg){
1337
+ if(!langCfg.date.monthkeys){
1338
+ var create = function(i, name){
1339
+ var strNum;
1340
+ var num = i + 1;
1341
+ strNum = (num < 10) ? '0'+num : ''+num;
1342
+ langCfg.date.monthkeys[num] = strNum;
1343
+ langCfg.date.monthkeys[name] = strNum;
1344
+ langCfg.date.monthkeys[name.toLowerCase()] = strNum;
1345
+ };
1346
+ langCfg.date.monthkeys = {};
1347
+ langCfg.date.monthDigits = monthDigits;
1348
+ langCfg.numberSigns += '-';
1349
+ $.each(langCfg.date.monthNames, create);
1350
+ $.each(langCfg.date.monthNamesShort, create);
1351
+ }
1352
+ };
1353
+
1354
+ createMonthKeys(curCfg);
1355
+
1356
+ $.webshims.ready('dom-extend', function(){
1357
+ $.webshims.activeLang({
1358
+ register: 'form-core',
1359
+ callback: function(){
1360
+ $.each(arguments, function(i, val){
1361
+ if(formcfg[val]){
1362
+ curCfg = formcfg[val];
1363
+ createMonthKeys(curCfg);
1364
+ $(document).triggerHandler('wslocalechange');
1365
+ return false;
1366
+ }
1367
+ });
1368
+ }
1369
+ });
1370
+ });
1371
+ })();
1372
+
1373
+
1374
+
1375
+ (function(){
1376
+
1377
+
1378
+ var mousePress = function(e){
1379
+ $(this)[e.type == 'mousepressstart' ? 'addClass' : 'removeClass']('mousepress-ui');
1380
+ };
1381
+
1382
+ var retDefault = function(val, def){
1383
+ if(!(typeof val == 'number' || (val && val == val * 1))){
1384
+ return def;
1385
+ }
1386
+ return val * 1;
1387
+ };
1388
+
1389
+ var createOpts = ['step', 'min', 'max', 'readonly', 'title', 'disabled', 'tabindex', 'placeholder', 'value'];
1390
+
1391
+
1392
+ var formatVal = {
1393
+ number: function(val){
1394
+ return (val+'').replace(/\,/g, '').replace(/\./, curCfg.numberFormat['.']);
1395
+ },
1396
+ time: function(val){
1397
+ return val;
1398
+ },
1399
+ //todo empty val for month/split
1400
+ month: function(val, options){
1401
+ var names;
1402
+ var p = val.split('-');
1403
+ if(p[0] && p[1]){
1404
+ names = curCfg.date[options.formatMonthNames] || curCfg.date[options.monthNames] || curCfg.date.monthNames;
1405
+ p[1] = names[(p[1] * 1) - 1];
1406
+ if(options && options.splitInput){
1407
+ val = [p[0] || '', p[1] || ''];
1408
+ } else if(p[1]){
1409
+ val = curCfg.date.showMonthAfterYear ? p.join(' ') : p[1]+' '+p[0];
1410
+ }
1411
+ }
1412
+ return val;
1413
+ },
1414
+ date: function(val, opts){
1415
+ var p = (val+'').split('-');
1416
+ if(p[2] && p[1] && p[0]){
1417
+ if(opts && opts.splitInput){
1418
+ val = p;
1419
+ } else {
1420
+ val = curCfg.patterns.d.replace('yy', p[0] || '');
1421
+ val = val.replace('mm', p[1] || '');
1422
+ val = val.replace('dd', p[2] || '');
1423
+ }
1424
+ } else if(opts && opts.splitInput){
1425
+ val = [p[0] || '', p[1] || '', p[2] || ''];
1426
+ }
1427
+
1428
+ return val;
1429
+ }
1430
+ };
1431
+
1432
+ var parseVal = {
1433
+ number: function(val){
1434
+ return (val+'').replace(curCfg.numberFormat[','], '').replace(curCfg.numberFormat['.'], '.');
1435
+ },
1436
+ time: function(val){
1437
+ return val;
1438
+ },
1439
+ month: function(val, opts){
1440
+
1441
+ var p = (!opts.splitInput) ? val.trim().split(/[\.\s-\/\\]+/) : val;
1442
+
1443
+ if(p.length == 2){
1444
+ p[0] = curCfg.date.monthkeys[p[0]] || p[0];
1445
+ p[1] = curCfg.date.monthkeys[p[1]] || p[1];
1446
+ if(p[1].length == 2){
1447
+ val = p[0]+'-'+p[1];
1448
+ } else if(p[0].length == 2){
1449
+ val = p[1]+'-'+p[0];
1450
+ } else {
1451
+ val = '';
1452
+ }
1453
+ } else if(opts.splitInput) {
1454
+ val = '';
1455
+ }
1456
+ return val;
1457
+ },
1458
+ date: function(val, opts){
1459
+ createFormat('d');
1460
+ var i;
1461
+ var obj;
1462
+ if(opts.splitInput){
1463
+ obj = {yy: 0, mm: 1, dd: 2};
1464
+ } else {
1465
+ obj = curCfg.patterns.dObj;
1466
+ val = val.split(curCfg.dFormat);
1467
+ }
1468
+
1469
+ return (val.length == 3 && val[0] && val[1] && val[2]) ?
1470
+ ([addZero(val[obj.yy]), addZero(val[obj.mm]), addZero(val[obj.dd])]).join('-') :
1471
+ ''
1472
+ ;
1473
+ }
1474
+ };
1475
+
1476
+ var steps = {
1477
+ number: {
1478
+ step: 1
1479
+ },
1480
+ time: {
1481
+ step: 60
1482
+ },
1483
+ month: {
1484
+ step: 1,
1485
+ start: new Date()
1486
+ },
1487
+ date: {
1488
+ step: 1,
1489
+ start: new Date()
1490
+ }
1491
+ };
1492
+
1493
+
1494
+ var placeholderFormat = {
1495
+ date: function(val, opts){
1496
+ var hintValue = (val || '').split('-');
1497
+ if(hintValue.length == 3){
1498
+ hintValue = opts.splitInput ?
1499
+ hintValue :
1500
+ curCfg.patterns.d.replace('yy', hintValue[0]).replace('mm', hintValue[1]).replace('dd', hintValue[2]);
1501
+ } else {
1502
+ hintValue = opts.splitInput ?
1503
+ [val, val, val] :
1504
+ val;
1505
+ }
1506
+ return hintValue;
1507
+ },
1508
+ month: function(val, opts){
1509
+ var hintValue = (val || '').split('-');
1510
+
1511
+ if(hintValue.length == 2){
1512
+ hintValue = opts.splitInput ?
1513
+ hintValue :
1514
+ curCfg.patterns.d.replace('yy', hintValue[0]).replace('mm', hintValue[1]);
1515
+ } else {
1516
+ hintValue = opts.splitInput ?
1517
+ [val, val] :
1518
+ val;
1519
+ }
1520
+ return hintValue;
1521
+ }
1522
+ };
1523
+
1524
+ var createHelper = (function(){
1525
+ var types = {};
1526
+ return function(type){
1527
+ var input;
1528
+ if(!types[type]){
1529
+ input = $('<input type="'+type+'" />');
1530
+ types[type] = {
1531
+ asNumber: function(val){
1532
+ var type = (typeof val == 'object') ? 'valueAsDate' : 'value';
1533
+ return input.prop(type, val).prop('valueAsNumber');
1534
+ },
1535
+ asValue: function(val){
1536
+ var type = (typeof val == 'object') ? 'valueAsDate' : 'valueAsNumber';
1537
+ return input.prop(type, val).prop('value');
1538
+ }
1539
+ };
1540
+ }
1541
+ return types[type];
1542
+ };
1543
+ })();
1544
+
1545
+ steps.range = steps.number;
1546
+
1547
+
1548
+ var spinBtnProto = {
1549
+ _create: function(){
1550
+ var i;
1551
+ var o = this.options;
1552
+ var helper = createHelper(o.type);
1553
+ this.type = o.type;
1554
+ this.orig = o.orig;
1555
+
1556
+ this.elemHelper = $('<input type="'+ this.type+'" />');
1557
+ this.asNumber = helper.asNumber;
1558
+ this.asValue = helper.asValue;
1559
+
1560
+ 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>')
1561
+ .insertAfter(this.element)
1562
+ ;
1563
+
1564
+ if(o.splitInput){
1565
+ this._addSplitInputs();
1566
+ } else {
1567
+ this.inputElements = this.element;
1568
+ }
1569
+
1570
+ this.options.containerElements.push(this.buttonWrapper[0]);
1571
+
1572
+ if(typeof steps[this.type].start == 'object'){
1573
+ steps[this.type].start = this.asNumber(steps[this.type].start);
1574
+ }
1575
+
1576
+
1577
+
1578
+ for(i = 0; i < createOpts.length; i++){
1579
+ this[createOpts[i]](o[createOpts[i]]);
1580
+ }
1581
+
1582
+ this.element.data('wsspinner', this);
1583
+
1584
+ this.addBindings();
1585
+
1586
+ if(!o.min && typeof o.relMin == 'number'){
1587
+ o.min = this.asValue(this.getRelNumber(o.relMin));
1588
+ $.prop(this.orig, 'min', o.min);
1589
+ }
1590
+
1591
+ if(!o.max && typeof o.relMax == 'number'){
1592
+ o.max = this.asValue(this.getRelNumber(o.relMax));
1593
+ $.prop(this.orig, 'max', o.max);
1594
+ }
1595
+
1596
+ this._init = true;
1597
+ },
1598
+ _addSplitInputs: function(){
1599
+ if(!this.inputElements){
1600
+ var create = splitInputs[this.type]._create();
1601
+ this.splits = create.splits;
1602
+ this.inputElements = $(create.elements).prependTo(this.element).filter('input');
1603
+ }
1604
+ },
1605
+ parseValue: function(){
1606
+ var value = this.inputElements.map(function(){
1607
+ return $.prop(this, 'value');
1608
+ }).get();
1609
+ if(!this.options.splitInput){
1610
+ value = value[0];
1611
+ }
1612
+ return parseVal[this.type](value, this.options);
1613
+ },
1614
+ formatValue: function(val, noSplit){
1615
+ return formatVal[this.type](val, noSplit === false ? false : this.options);
1616
+ },
1617
+ placeholder: function(val){
1618
+ var options = this.options;
1619
+ options.placeholder = val;
1620
+ var placeholder = val;
1621
+ if(placeholderFormat[this.type]){
1622
+ placeholder = placeholderFormat[this.type](val, this.options);
1623
+ }
1624
+ if(options.splitInput && typeof placeholder == 'object'){
1625
+ $.each(this.splits, function(i, elem){
1626
+ $.prop(elem, 'placeholder', placeholder[i]);
1627
+ });
1628
+ } else {
1629
+ this.element.prop('placeholder', placeholder);
1630
+ }
1631
+ },
1632
+ getRelNumber: function(rel){
1633
+ var start = steps[this.type].start || 0;
1634
+ if(rel){
1635
+ start += rel;
1636
+ }
1637
+ return start;
1638
+ },
1639
+ addZero: addZero,
1640
+ _setStartInRange: function(){
1641
+ var start = this.getRelNumber(this.options.relDefaultValue);
1642
+ if(!isNaN(this.minAsNumber) && start < this.minAsNumber){
1643
+ start = this.minAsNumber;
1644
+ } else if(!isNaN(this.maxAsNumber) && start > this.maxAsNumber){
1645
+ start = this.maxAsNumber;
1646
+ }
1647
+ this.elemHelper.prop('valueAsNumber', start);
1648
+ this.options.defValue = this.elemHelper.prop('value');
1649
+
1650
+ },
1651
+ reorderInputs: function(){
1652
+ if(splitInputs[this.type]){
1653
+ var element = this.element;
1654
+ splitInputs[this.type].sort(element);
1655
+ setTimeout(function(){
1656
+ var data = webshims.data(element);
1657
+ if(data && data.shadowData){
1658
+ data.shadowData.shadowFocusElement = element.find('input')[0] || element[0];
1659
+ }
1660
+ }, 9);
1661
+ }
1662
+ },
1663
+ value: function(val){
1664
+ this.valueAsNumber = this.asNumber(val);
1665
+ this.options.value = val;
1666
+ if(isNaN(this.valueAsNumber) || (!isNaN(this.minAsNumber) && this.valueAsNumber < this.minAsNumber) || (!isNaN(this.maxAsNumber) && this.valueAsNumber > this.maxAsNumber)){
1667
+ this._setStartInRange();
1668
+ } else {
1669
+ this.elemHelper.prop('value', val);
1670
+ this.options.defValue = "";
1671
+ }
1672
+
1673
+ val = formatVal[this.type](val, this.options);
1674
+ if(this.options.splitInput){
1675
+
1676
+ $.each(this.splits, function(i, elem){
1677
+ $.prop(elem, 'value', val[i]);
1678
+ });
1679
+ } else {
1680
+ this.element.prop('value', val);
1681
+ }
1682
+
1683
+ this._propertyChange('value');
1684
+ },
1685
+ initDataList: function(){
1686
+ var listTimer;
1687
+ var that = this;
1688
+ var updateList = function(){
1689
+ $(that.orig)
1690
+ .jProp('list')
1691
+ .off('updateDatalist', updateList)
1692
+ .on('updateDatalist', updateList)
1693
+ ;
1694
+ clearTimeout(listTimer);
1695
+ listTimer = setTimeout(function(){
1696
+ if(that.list){
1697
+ that.list();
1698
+ }
1699
+ }, 9);
1700
+
1701
+ };
1702
+
1703
+ $(this.orig).onTrigger('listdatalistchange', updateList);
1704
+ },
1705
+ getOptions: function(){
1706
+ var options = {};
1707
+ var datalist = $(this.orig).jProp('list');
1708
+ datalist.find('option').each(function(){
1709
+ options[$.prop(this, 'value')] = $.prop(this, 'label');
1710
+ });
1711
+ return [options, datalist.data('label')];
1712
+ },
1713
+ list: function(val){
1714
+ if(this.type == 'number' || this.type == 'time'){
1715
+ this.element.attr('list', $.attr(this.orig, 'list'));
1716
+ }
1717
+ this.options.list = val;
1718
+ this._propertyChange('list');
1719
+ },
1720
+ _propertyChange: $.noop,
1721
+ tabindex: function(val){
1722
+ this.options.tabindex = val;
1723
+ this.inputElements.prop('tabindex', this.options.tabindex);
1724
+ },
1725
+ title: function(val){
1726
+ this.options.title = val;
1727
+ this.element.prop('title', this.options.title);
1728
+ },
1729
+
1730
+ min: function(val){
1731
+ this.elemHelper.prop('min', val);
1732
+ this.minAsNumber = this.asNumber(val);
1733
+ if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
1734
+ this._setStartInRange();
1735
+ }
1736
+ this.options.min = val;
1737
+ this._propertyChange('min');
1738
+ },
1739
+ max: function(val){
1740
+ this.elemHelper.prop('max', val);
1741
+ this.maxAsNumber = this.asNumber(val);
1742
+ if(this.valueAsNumber != null && isNaN(this.valueAsNumber)){
1743
+ this._setStartInRange();
1744
+ }
1745
+ this.options.max = val;
1746
+ this._propertyChange('max');
1747
+ },
1748
+ step: function(val){
1749
+ var defStep = steps[this.type];
1750
+ this.options.step = val;
1751
+ this.elemHelper.prop('step', retDefault(val, defStep.step));
1752
+ },
1753
+ addBindings: function(){
1754
+ var isFocused;
1755
+
1756
+ var that = this;
1757
+ var o = this.options;
1758
+
1759
+ var eventTimer = (function(){
1760
+ var events = {};
1761
+ return {
1762
+ init: function(name, curVal, fn){
1763
+ if(!events[name]){
1764
+ events[name] = {fn: fn};
1765
+ $(that.orig).on(name, function(){
1766
+ events[name].val = $.prop(that.orig, 'value');
1767
+ });
1768
+ }
1769
+ events[name].val = curVal;
1770
+ },
1771
+ call: function(name, val){
1772
+ if(events[name] && events[name].val != val){
1773
+ clearTimeout(events[name].timer);
1774
+ events[name].val = val;
1775
+ events[name].timer = setTimeout(function(){
1776
+ events[name].fn(val, that);
1777
+ }, 9);
1778
+ }
1779
+ }
1780
+ };
1781
+ })();
1782
+ var initChangeEvents = function(){
1783
+ eventTimer.init('input', $.prop(that.orig, 'value'), that.options.input);
1784
+ eventTimer.init('change', $.prop(that.orig, 'value'), that.options.change);
1785
+ };
1786
+
1787
+ var step = {};
1788
+
1789
+ var preventBlur = function(e){
1790
+ if(preventBlur.prevent){
1791
+ e.preventDefault();
1792
+ (isFocused || that.element.getShadowFocusElement()).focus();
1793
+ e.stopImmediatePropagation();
1794
+ return true;
1795
+ }
1796
+ };
1797
+ var callSplitChange = (function(){
1798
+ var timer;
1799
+
1800
+ var call = function(e){
1801
+ var val;
1802
+ clearTimeout(timer);
1803
+ val = that.parseValue();
1804
+ $.prop(that.orig, 'value', val);
1805
+ eventTimer.call('input', val);
1806
+ if(!e || e.type != 'wsupdatevalue'){
1807
+ eventTimer.call('change', val);
1808
+ }
1809
+ };
1810
+
1811
+ var onFocus = function(){
1812
+ clearTimeout(timer);
1813
+ };
1814
+ var onBlur = function(e){
1815
+ clearTimeout(timer);
1816
+ timer = setTimeout(call, 0);
1817
+
1818
+ if(e.type == 'change'){
1819
+ stopPropagation(e);
1820
+ if(!o.splitInput){
1821
+ call();
1822
+ }
1823
+ }
1824
+ };
1825
+
1826
+ that.element.on('wsupdatevalue', call);
1827
+
1828
+ that.inputElements
1829
+ .add(that.buttonWrapper)
1830
+ .add(that.element)
1831
+ .on(
1832
+ {
1833
+ 'focus focusin': onFocus,
1834
+ 'blur focusout change': onBlur
1835
+ }
1836
+ )
1837
+ ;
1838
+ setTimeout(function(){
1839
+ if(that.popover){
1840
+ $('> *', that.popover.element)
1841
+ .on({
1842
+ 'focusin': onFocus,
1843
+ 'focusout': onBlur
1844
+ })
1845
+ ;
1846
+ }
1847
+ }, 0);
1848
+ })();
1849
+
1850
+ var spinEvents = {};
1851
+ var spinElement = o.splitInput ? this.inputElements.filter('.ws-spin') : this.inputElements.eq(0);
1852
+ var elementEvts = {
1853
+ blur: function(e){
1854
+ if(!preventBlur(e) && !o.disabled && !o.readonly){
1855
+ if(!preventBlur.prevent){
1856
+ isFocused = false;
1857
+ }
1858
+ }
1859
+ stopPropagation(e);
1860
+ },
1861
+ focus: function(e){
1862
+ if(!isFocused){
1863
+ initChangeEvents();
1864
+ isFocused = this;
1865
+ }
1866
+ },
1867
+ keypress: function(e){
1868
+ if(e.isDefaultPrevented()){return;}
1869
+ var chr;
1870
+ var stepped = true;
1871
+ var code = e.keyCode;
1872
+ if(!e.ctrlKey && !e.metaKey && curCfg[that.type+'Signs']){
1873
+ chr = String.fromCharCode(e.charCode == null ? code : e.charCode);
1874
+ stepped = !(chr < " " || (curCfg[that.type+'Signs']+'0123456789').indexOf(chr) > -1);
1875
+ } else {
1876
+ stepped = false;
1877
+ }
1878
+ if(stepped){
1879
+ e.preventDefault();
1880
+ }
1881
+ },
1882
+ 'input keydown keypress': (function(){
1883
+ var timer;
1884
+ var isStopped = false;
1885
+ var releaseTab = function(){
1886
+ if(isStopped === true){
1887
+ isStopped = 'semi';
1888
+ timer = setTimeout(releaseTab, 250);
1889
+ } else {
1890
+ isStopped = false;
1891
+ }
1892
+ };
1893
+ var stopTab = function(){
1894
+ isStopped = true;
1895
+ clearTimeout(timer);
1896
+ timer = setTimeout(releaseTab, 300);
1897
+ };
1898
+ var select = function(){
1899
+ this.focus();
1900
+ this.select();
1901
+ stopTab();
1902
+ };
1903
+
1904
+ return function(e){
1905
+ if(o.splitInput && o.jumpInputs){
1906
+ if(e.type == 'input'){
1907
+ if($.prop(this, 'value').length === $.prop(this, 'maxLength')){
1908
+ try {
1909
+ $(this)
1910
+ .next()
1911
+ .next('input')
1912
+ .each(select)
1913
+ ;
1914
+ } catch(er){}
1915
+ }
1916
+ } else if(!e.shiftKey && !e.crtlKey && e.keyCode == 9 && (isStopped === true || (isStopped && !$.prop(this, 'value')))){
1917
+ e.preventDefault();
1918
+ }
1919
+ }
1920
+ }
1921
+ })()
1922
+ };
1923
+ var mouseDownInit = function(){
1924
+ if(!o.disabled && !isFocused){
1925
+ that.element.getShadowFocusElement().focus();
1926
+ }
1927
+ preventBlur.set();
1928
+
1929
+ return false;
1930
+ };
1931
+
1932
+ preventBlur.set = (function(){
1933
+ var timer;
1934
+ var reset = function(){
1935
+ preventBlur.prevent = false;
1936
+ };
1937
+ return function(){
1938
+ clearTimeout(timer);
1939
+ preventBlur.prevent = true;
1940
+ setTimeout(reset, 9);
1941
+ };
1942
+ })();
1943
+
1944
+ ['stepUp', 'stepDown'].forEach(function(name){
1945
+ step[name] = function(factor){
1946
+ if(!o.disabled && !o.readonly){
1947
+ if(!isFocused){
1948
+ mouseDownInit();
1949
+ }
1950
+ var ret = false;
1951
+ if (!factor) {
1952
+ factor = 1;
1953
+ }
1954
+ try {
1955
+ that.elemHelper[name](factor);
1956
+ ret = that.elemHelper.prop('value');
1957
+ that.value(ret);
1958
+ eventTimer.call('input', ret);
1959
+ } catch (er) {}
1960
+ return ret;
1961
+ }
1962
+ };
1963
+ });
1964
+
1965
+
1966
+
1967
+ this.buttonWrapper.on('mousedown', mouseDownInit);
1968
+
1969
+ this.setInput = function(value){
1970
+ that.value(value);
1971
+ eventTimer.call('input', value);
1972
+ };
1973
+ this.setChange = function(value){
1974
+ that.setInput(value);
1975
+ eventTimer.call('change', value);
1976
+ };
1977
+
1978
+
1979
+
1980
+ this.inputElements.on(elementEvts);
1981
+
1982
+ if(!o.noSpinbtn){
1983
+ spinEvents[$.fn.mwheelIntent ? 'mwheelIntent' : 'mousewheel'] = function(e, delta){
1984
+ if(delta && isFocused && !o.disabled){
1985
+ step[delta > 0 ? 'stepUp' : 'stepDown']();
1986
+ e.preventDefault();
1987
+ }
1988
+ };
1989
+ spinEvents.keydown = function(e){
1990
+ if(o.list || e.isDefaultPrevented() || $.attr(this, 'list')){return;}
1991
+ var stepped = true;
1992
+ var code = e.keyCode;
1993
+ if (code == 38) {
1994
+ step.stepUp();
1995
+ } else if (code == 40) {
1996
+ step.stepDown();
1997
+ } else {
1998
+ stepped = false;
1999
+ }
2000
+ if(stepped){
2001
+ e.preventDefault();
2002
+ }
2003
+ };
2004
+
2005
+ spinElement.attr({'autocomplete': 'off', role: 'spinbutton'}).on(spinEvents);
2006
+ }
2007
+
2008
+
2009
+ if(!o.splitInput){
2010
+ $(document).on('wslocalechange',function(){
2011
+ if(o.value){
2012
+ that.value(o.value);
2013
+ }
2014
+
2015
+ if(placeholderFormat[that.type] && o.placeholder){
2016
+ that.placeholder(o.placeholder);
2017
+ }
2018
+ });
2019
+ } else {
2020
+ $(document).onTrigger('wslocalechange',function(){
2021
+ that.reorderInputs();
2022
+ });
2023
+ }
2024
+
2025
+ $('.step-up', this.buttonWrapper)
2026
+ .on({
2027
+ 'mousepressstart mousepressend': mousePress,
2028
+ 'mousedown mousepress': function(e){
2029
+ step.stepUp();
2030
+ }
2031
+ })
2032
+ ;
2033
+ $('.step-down', this.buttonWrapper)
2034
+ .on({
2035
+ 'mousepressstart mousepressend': mousePress,
2036
+ 'mousedown mousepress': function(e){
2037
+ step.stepDown();
2038
+ }
2039
+ })
2040
+ ;
2041
+ initChangeEvents();
2042
+ }
2043
+ };
2044
+
2045
+ ['readonly', 'disabled'].forEach(function(name){
2046
+ spinBtnProto[name] = function(val){
2047
+ if(this.options[name] != val || !this._init){
2048
+ this.options[name] = !!val;
2049
+ if(name == 'readonly' && this.options.noInput){
2050
+ this.element
2051
+ .prop(name, true)
2052
+ .attr({'aria-readonly': this.options[name]})
2053
+ ;
2054
+ } else {
2055
+ this.element.prop(name, this.options[name]);
2056
+ }
2057
+ this.buttonWrapper[this.options[name] ? 'addClass' : 'removeClass']('ws-'+name);
2058
+ }
2059
+ };
2060
+ });
2061
+
2062
+
2063
+ $.fn.spinbtnUI = function(opts){
2064
+ opts = $.extend({
2065
+ monthNames: 'monthNames',
2066
+ size: 1,
2067
+ startView: 0
2068
+ }, opts);
2069
+ return this.each(function(){
2070
+ $.webshims.objectCreate(spinBtnProto, {
2071
+ element: {
2072
+ value: $(this)
2073
+ }
2074
+ }, opts);
2075
+ });
2076
+ };
2077
+ })();
2078
+
2079
+ (function(){
2080
+ var picker = {};
2081
+ var disable = {
2082
+
2083
+ };
2084
+
2085
+ var getDateArray = function(date){
2086
+ var ret = [date.getFullYear(), addZero(date.getMonth() + 1), addZero(date.getDate())];
2087
+ ret.month = ret[0]+'-'+ret[1];
2088
+ ret.date = ret[0]+'-'+ret[1]+'-'+ret[2];
2089
+ return ret;
2090
+ };
2091
+ var today = getDateArray(new Date());
2092
+
2093
+ var _setFocus = function(element, _noFocus){
2094
+ var setFocus, that;
2095
+ element = $(element || this.activeButton);
2096
+ this.activeButton.attr({tabindex: '-1', 'aria-selected': 'false'});
2097
+ this.activeButton = element.attr({tabindex: '0', 'aria-selected': 'true'});
2098
+ this.index = this.buttons.index(this.activeButton[0]);
2099
+
2100
+ clearTimeout(this.timer);
2101
+
2102
+ if(!this.popover.openedByFocus && !_noFocus){
2103
+ that = this;
2104
+ setFocus = function(noTrigger){
2105
+ clearTimeout(that.timer);
2106
+ that.timer = setTimeout(function(){
2107
+ if(element[0]){
2108
+ element[0].focus();
2109
+ if(noTrigger !== true && !element.is(':focus')){
2110
+ setFocus(true);
2111
+ }
2112
+ }
2113
+ }, that.popover.isVisible ? 99 : 360);
2114
+ };
2115
+ this.popover.activateElement(element);
2116
+ setFocus();
2117
+ }
2118
+
2119
+ };
2120
+
2121
+ var _initialFocus = function(){
2122
+ var sel;
2123
+ if(this.popover.navedInitFocus){
2124
+ sel = this.popover.navedInitFocus.sel || this.popover.navedInitFocus;
2125
+ if((!this.activeButton || !this.activeButton[0]) && this.buttons[sel]){
2126
+ this.activeButton = this.buttons[sel]();
2127
+ } else if(sel){
2128
+ this.activeButton = $(sel, this.element);
2129
+ }
2130
+
2131
+ if(!this.activeButton[0] && this.popover.navedInitFocus.alt){
2132
+ this.activeButton = this.buttons[this.popover.navedInitFocus.alt]();
2133
+ }
2134
+ }
2135
+
2136
+ if(!this.activeButton || !this.activeButton[0]){
2137
+ this.activeButton = this.buttons.filter('.checked-value');
2138
+ }
2139
+
2140
+ if(!this.activeButton[0]){
2141
+ this.activeButton = this.buttons.filter('.this-value');
2142
+ }
2143
+ if(!this.activeButton[0]){
2144
+ this.activeButton = this.buttons.eq(0);
2145
+ }
2146
+
2147
+ this.setFocus(this.activeButton, this.opts.noFocus);
2148
+ };
2149
+
2150
+
2151
+ webshims.ListBox = function (element, popover, opts){
2152
+ this.element = $('ul', element);
2153
+ this.popover = popover;
2154
+ this.opts = opts || {};
2155
+ this.buttons = $('button:not(:disabled)', this.element);
2156
+
2157
+
2158
+ this.ons(this);
2159
+ this._initialFocus();
2160
+ };
2161
+
2162
+ webshims.ListBox.prototype = {
2163
+ setFocus: _setFocus,
2164
+ _initialFocus: _initialFocus,
2165
+ prev: function(){
2166
+ var index = this.index - 1;
2167
+ if(index < 0){
2168
+ if(this.opts.prev){
2169
+ this.popover.navedInitFocus = 'last';
2170
+ this.popover.actionFn(this.opts.prev);
2171
+ this.popover.navedInitFocus = false;
2172
+ }
2173
+ } else {
2174
+ this.setFocus(this.buttons.eq(index));
2175
+ }
2176
+ },
2177
+ next: function(){
2178
+ var index = this.index + 1;
2179
+ if(index >= this.buttons.length){
2180
+ if(this.opts.next){
2181
+ this.popover.navedInitFocus = 'first';
2182
+ this.popover.actionFn(this.opts.next);
2183
+ this.popover.navedInitFocus = false;
2184
+ }
2185
+ } else {
2186
+ this.setFocus(this.buttons.eq(index));
2187
+ }
2188
+ },
2189
+ ons: function(that){
2190
+ this.element
2191
+ .on({
2192
+ 'keydown': function(e){
2193
+ var handled;
2194
+ var key = e.keyCode;
2195
+ if(e.ctrlKey){return;}
2196
+ if(key == 36 || key == 33){
2197
+ that.setFocus(that.buttons.eq(0));
2198
+ handled = true;
2199
+ } else if(key == 34 || key == 35){
2200
+ that.setFocus(that.buttons.eq(that.buttons.length - 1));
2201
+ handled = true;
2202
+ } else if(key == 38 || key == 37){
2203
+ that.prev();
2204
+ handled = true;
2205
+ } else if(key == 40 || key == 39){
2206
+ that.next();
2207
+ handled = true;
2208
+ }
2209
+ if(handled){
2210
+ return false;
2211
+ }
2212
+ }
2213
+ })
2214
+ ;
2215
+ }
2216
+ };
2217
+
2218
+ webshims.Grid = function (element, popover, opts){
2219
+ this.element = $('tbody', element);
2220
+ this.popover = popover;
2221
+ this.opts = opts || {};
2222
+ this.buttons = $('button:not(:disabled,.othermonth)', this.element);
2223
+
2224
+ this.ons(this);
2225
+
2226
+ this._initialFocus();
2227
+ if(this.popover.openedByFocus){
2228
+ this.popover.activeElement = this.activeButton;
2229
+ }
2230
+ };
2231
+
2232
+
2233
+
2234
+ webshims.Grid.prototype = {
2235
+ setFocus: _setFocus,
2236
+ _initialFocus: _initialFocus,
2237
+
2238
+ first: function(){
2239
+ this.setFocus(this.buttons.eq(0));
2240
+ },
2241
+ last: function(){
2242
+ this.setFocus(this.buttons.eq(this.buttons.length - 1));
2243
+ },
2244
+ upPage: function(){
2245
+ $('.ws-picker-header > button:not(:disabled)', this.popover.element).trigger('click');
2246
+ },
2247
+ downPage: function(){
2248
+ this.activeButton.filter(':not([data-action="changeInput"])').trigger('click');
2249
+ },
2250
+ ons: function(that){
2251
+ this.element
2252
+ .on({
2253
+ 'keydown': function(e){
2254
+ var handled;
2255
+ var key = e.keyCode;
2256
+
2257
+ if(e.shiftKey){return;}
2258
+
2259
+ if((e.ctrlKey && key == 40)){
2260
+ handled = 'downPage';
2261
+ } else if((e.ctrlKey && key == 38)){
2262
+ handled = 'upPage';
2263
+ } else if(key == 33 || (e.ctrlKey && key == 37)){
2264
+ handled = 'prevPage';
2265
+ } else if(key == 34 || (e.ctrlKey && key == 39)){
2266
+ handled = 'nextPage';
2267
+ } else if(e.keyCode == 36 || e.keyCode == 33){
2268
+ handled = 'first';
2269
+ } else if(e.keyCode == 35){
2270
+ handled = 'last';
2271
+ } else if(e.keyCode == 38){
2272
+ handled = 'up';
2273
+ } else if(e.keyCode == 37){
2274
+ handled = 'prev';
2275
+ } else if(e.keyCode == 40){
2276
+ handled = 'down';
2277
+ } else if(e.keyCode == 39){
2278
+ handled = 'next';
2279
+ }
2280
+ if(handled){
2281
+ that[handled]();
2282
+ return false;
2283
+ }
2284
+ }
2285
+ })
2286
+ ;
2287
+ }
2288
+ };
2289
+ $.each({
2290
+ prevPage: {get: 'last', action: 'prev'},
2291
+ nextPage: {get: 'first', action: 'next'}
2292
+ }, function(name, val){
2293
+ webshims.Grid.prototype[name] = function(){
2294
+ if(this.opts[val.action]){
2295
+ this.popover.navedInitFocus = {
2296
+ sel: 'button[data-id="'+ this.activeButton.attr('data-id') +'"]:not(:disabled,.othermonth)',
2297
+ alt: val.get
2298
+ };
2299
+ this.popover.actionFn(this.opts[val.action]);
2300
+ this.popover.navedInitFocus = false;
2301
+ }
2302
+ };
2303
+ });
2304
+
2305
+ $.each({
2306
+ up: {traverse: 'prevAll', get: 'last', action: 'prev', reverse: true},
2307
+ down: {traverse: 'nextAll', get: 'first', action: 'next'}
2308
+ }, function(name, val){
2309
+ webshims.Grid.prototype[name] = function(){
2310
+ var cellIndex = this.activeButton.closest('td').prop('cellIndex');
2311
+ var sel = 'td:nth-child('+(cellIndex + 1)+') button:not(:disabled,.othermonth)';
2312
+ var button = this.activeButton.closest('tr')[val.traverse]();
2313
+
2314
+ if(val.reverse){
2315
+ button = $(button.get().reverse());
2316
+ }
2317
+ button = button.find(sel)[val.get]();
2318
+
2319
+ if(!button[0]){
2320
+ if(this.opts[val.action]){
2321
+ this.popover.navedInitFocus = sel+':'+val.get;
2322
+ this.popover.actionFn(this.opts[val.action]);
2323
+ this.popover.navedInitFocus = false;
2324
+ }
2325
+ } else {
2326
+ this.setFocus(button.eq(0));
2327
+ }
2328
+ };
2329
+ });
2330
+
2331
+ $.each({
2332
+ prev: {traverse: 'prevAll',get: 'last', reverse: true},
2333
+ next: {traverse: 'nextAll', get: 'first'}
2334
+ }, function(name, val){
2335
+ webshims.Grid.prototype[name] = function(){
2336
+ var sel = 'button:not(:disabled,.othermonth)';
2337
+ var button = this.activeButton.closest('td')[val.traverse]('td');
2338
+ if(val.reverse){
2339
+ button = $(button.get().reverse());
2340
+ }
2341
+ button = button.find(sel)[val.get]();
2342
+ if(!button[0]){
2343
+ button = this.activeButton.closest('tr')[val.traverse]('tr');
2344
+ if(val.reverse){
2345
+ button = $(button.get().reverse());
2346
+ }
2347
+ button = button.find(sel)[val.get]();
2348
+ }
2349
+
2350
+ if(!button[0]){
2351
+ if(this.opts[name]){
2352
+ this.popover.navedInitFocus = val.get;
2353
+ this.popover.actionFn(this.opts[name]);
2354
+ this.popover.navedInitFocus = false;
2355
+ }
2356
+ } else {
2357
+ this.setFocus(button.eq(0));
2358
+ }
2359
+ };
2360
+ });
2361
+
2362
+ picker.getWeek = function(date){
2363
+ var onejan = new Date(date.getFullYear(),0,1);
2364
+ return Math.ceil((((date - onejan) / 86400000) + onejan.getDay()+1)/7);
2365
+ };
2366
+ picker.getYearList = function(value, data){
2367
+ var j, i, val, disabled, lis, prevDisabled, nextDisabled, classStr, classArray, start;
2368
+
2369
+
2370
+ var size = data.options.size;
2371
+ var max = data.options.max.split('-');
2372
+ var min = data.options.min.split('-');
2373
+ var currentValue = data.options.value.split('-');
2374
+ var xthCorrect = 0;
2375
+ var enabled = 0;
2376
+ var str = '';
2377
+ var rowNum = 0;
2378
+
2379
+ if(data.options.useDecadeBase == 'max' && max[0]){
2380
+ xthCorrect = 11 - (max[0] % 12);
2381
+ } else if(data.options.useDecadeBase == 'min' && min[0]){
2382
+ xthCorrect = 11 - (min[0] % 12);
2383
+ }
2384
+
2385
+ value = value[0] * 1;
2386
+ start = value - ((value + xthCorrect) % (12 * size));
2387
+
2388
+
2389
+
2390
+ for(j = 0; j < size; j++){
2391
+ if(j){
2392
+ start += 12;
2393
+ } else {
2394
+ prevDisabled = picker.isInRange([start-1], max, min) ? {'data-action': 'setYearList','value': start-1} : false;
2395
+ }
2396
+
2397
+ str += '<div class="year-list picker-list ws-index-'+ j +'"><div class="ws-picker-header"><button disabled="disabled">'+ start +' – '+(start + 11)+'</button></div>';
2398
+ lis = [];
2399
+ for(i = 0; i < 12; i++){
2400
+ val = start + i ;
2401
+ classArray = [];
2402
+ if( !picker.isInRange([val], max, min) ){
2403
+ disabled = ' disabled=""';
2404
+ } else {
2405
+ disabled = '';
2406
+ enabled++;
2407
+ }
2408
+
2409
+ if(val == today[0]){
2410
+ classArray.push('this-value');
2411
+ }
2412
+
2413
+ if(currentValue[0] == val){
2414
+ classArray.push('checked-value');
2415
+ }
2416
+
2417
+ classStr = classArray.length ? ' class="'+ (classArray.join(' ')) +'"' : '';
2418
+
2419
+ if(i && !(i % 3)){
2420
+ rowNum++;
2421
+ lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2422
+ }
2423
+ 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>');
2424
+ }
2425
+ if(j == size - 1){
2426
+ nextDisabled = picker.isInRange([val+1], max, min) ? {'data-action': 'setYearList','value': val+1} : false;
2427
+ }
2428
+ 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>';
2429
+ }
2430
+
2431
+ return {
2432
+ enabled: enabled,
2433
+ main: str,
2434
+ next: nextDisabled,
2435
+ prev: prevDisabled,
2436
+ type: 'Grid'
2437
+ };
2438
+ };
2439
+
2440
+
2441
+ picker.getMonthList = function(value, data){
2442
+
2443
+ var j, i, name, val, disabled, lis, fullyDisabled, prevDisabled, nextDisabled, classStr, classArray;
2444
+ var o = data.options;
2445
+ var size = o.size;
2446
+ var max = o.max.split('-');
2447
+ var min = o.min.split('-');
2448
+ var currentValue = o.value.split('-');
2449
+ var enabled = 0;
2450
+ var rowNum = 0;
2451
+ var str = '';
2452
+
2453
+ value = value[0] - Math.floor((size - 1) / 2);
2454
+ for(j = 0; j < size; j++){
2455
+ if(j){
2456
+ value++;
2457
+ } else {
2458
+ prevDisabled = picker.isInRange([value-1], max, min) ? {'data-action': 'setMonthList','value': value-1} : false;
2459
+ }
2460
+ if(j == size - 1){
2461
+ nextDisabled = picker.isInRange([value+1], max, min) ? {'data-action': 'setMonthList','value': value+1} : false;
2462
+ }
2463
+ lis = [];
2464
+
2465
+ if( !picker.isInRange([value, '01'], max, min) && !picker.isInRange([value, '12'], max, min)){
2466
+ disabled = ' disabled=""';
2467
+ fullyDisabled = true;
2468
+ } else {
2469
+ fullyDisabled = false;
2470
+ disabled = '';
2471
+ }
2472
+
2473
+ if(o.minView >= 1){
2474
+ disabled = ' disabled=""';
2475
+ }
2476
+
2477
+ str += '<div class="month-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">';
2478
+
2479
+ str += o.selectNav ?
2480
+ '<select data-action="setMonthList" class="year-select">'+ picker.createYearSelect(value, max, min).join('') +'</select>' :
2481
+ '<button data-action="setYearList"'+disabled+' value="'+ value +'" tabindex="-1">'+ value +'</button>';
2482
+ str += '</div>';
2483
+
2484
+ for(i = 0; i < 12; i++){
2485
+ val = curCfg.date.monthkeys[i+1];
2486
+ name = (curCfg.date[o.monthNames] || curCfg.date.monthNames)[i];
2487
+ classArray = [];
2488
+ if(fullyDisabled || !picker.isInRange([value, val], max, min) ){
2489
+ disabled = ' disabled=""';
2490
+ } else {
2491
+ disabled = '';
2492
+ enabled++;
2493
+ }
2494
+
2495
+ if(value == today[0] && today[1] == val){
2496
+ classArray.push('this-value');
2497
+ }
2498
+
2499
+ if(currentValue[0] == value && currentValue[1] == val){
2500
+ classArray.push('checked-value');
2501
+ }
2502
+
2503
+ classStr = (classArray.length) ? ' class="'+ (classArray.join(' ')) +'"' : '';
2504
+ if(i && !(i % 3)){
2505
+ rowNum++;
2506
+ lis.push('</tr><tr class="ws-row-'+ rowNum +'">');
2507
+ }
2508
+
2509
+ 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>');
2510
+
2511
+ }
2512
+
2513
+ str += '<div class="picker-grid"><table role="grid" aria-label="'+value+'"><tbody><tr class="ws-row-0">'+ (lis.join(''))+ '</tr></tbody></table></div></div>';
2514
+ }
2515
+
2516
+ return {
2517
+ enabled: enabled,
2518
+ main: str,
2519
+ prev: prevDisabled,
2520
+ next: nextDisabled,
2521
+ type: 'Grid'
2522
+ };
2523
+ };
2524
+
2525
+
2526
+ picker.getDayList = function(value, data){
2527
+
2528
+ var j, i, k, day, nDay, name, val, disabled, lis, prevDisabled, nextDisabled, addTr, week, rowNum;
2529
+
2530
+ var lastMotnh, curMonth, otherMonth, dateArray, monthName, fullMonthName, buttonStr, date2, classArray;
2531
+ var o = data.options;
2532
+ var size = o.size;
2533
+ var max = o.max.split('-');
2534
+ var min = o.min.split('-');
2535
+ var currentValue = o.value.split('-');
2536
+ var monthNames = curCfg.date[o.monthNamesHead] || curCfg.date[o.monthNames] || curCfg.date.monthNames;
2537
+ var enabled = 0;
2538
+ var str = [];
2539
+ var date = new Date(value[0], value[1] - 1, 1);
2540
+
2541
+ date.setMonth(date.getMonth() - Math.floor((size - 1) / 2));
2542
+
2543
+ for(j = 0; j < size; j++){
2544
+ date.setDate(1);
2545
+ lastMotnh = date.getMonth();
2546
+ rowNum = 0;
2547
+ if(!j){
2548
+ date2 = new Date(date.getTime());
2549
+ date2.setDate(-1);
2550
+ dateArray = getDateArray(date2);
2551
+ prevDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray[0]+'-'+dateArray[1]} : false;
2552
+ }
2553
+
2554
+ dateArray = getDateArray(date);
2555
+
2556
+ str.push('<div class="day-list picker-list ws-index-'+ j +'"><div class="ws-picker-header">');
2557
+ if( o.selectNav ){
2558
+ 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>'];
2559
+ if(curCfg.date.showMonthAfterYear){
2560
+ monthName.reverse();
2561
+ }
2562
+ str.push( monthName.join(' ') );
2563
+ }
2564
+
2565
+ fullMonthName = [curCfg.date.monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
2566
+ monthName = [monthNames[(dateArray[1] * 1) - 1], dateArray[0]];
2567
+ if(curCfg.date.showMonthAfterYear){
2568
+ monthName.reverse();
2569
+ fullMonthName.reverse();
2570
+ }
2571
+
2572
+ if(!data.options.selectNav) {
2573
+ str.push(
2574
+ '<button data-action="setMonthList"'+ (o.minView >= 2 ? ' disabled="" ' : '') +' value="'+ dateArray.date +'" tabindex="-1">'+ monthName.join(' ') +'</button>'
2575
+ );
2576
+ }
2577
+
2578
+
2579
+ str.push('</div><div class="picker-grid"><table role="grid" aria-label="'+ fullMonthName.join(' ') +'"><thead><tr>');
2580
+
2581
+ if(data.options.showWeek){
2582
+ str.push('<th class="week-header">'+ curCfg.date.weekHeader +'</th>');
2583
+ }
2584
+ for(k = curCfg.date.firstDay; k < curCfg.date.dayNamesShort.length; k++){
2585
+ str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2586
+ }
2587
+ k = curCfg.date.firstDay;
2588
+ while(k--){
2589
+ str.push('<th class="day-'+ k +'"><abbr title="'+ curCfg.date.dayNames[k] +'">'+ curCfg.date.dayNamesShort[k] +'</abbr></th>');
2590
+ }
2591
+ str.push('</tr></thead><tbody><tr class="ws-row-0">');
2592
+
2593
+ if(data.options.showWeek) {
2594
+ week = picker.getWeek(date);
2595
+ str.push('<td class="week-cell">'+ week +'</td>');
2596
+ }
2597
+
2598
+ for (i = 0; i < 99; i++) {
2599
+ addTr = (i && !(i % 7));
2600
+ curMonth = date.getMonth();
2601
+ otherMonth = lastMotnh != curMonth;
2602
+ day = date.getDay();
2603
+ classArray = [];
2604
+
2605
+ if(addTr && otherMonth ){
2606
+ str.push('</tr>');
2607
+ break;
2608
+ }
2609
+ if(addTr){
2610
+ rowNum++;
2611
+ str.push('</tr><tr class="ws-row-'+ rowNum +'">');
2612
+ if(data.options.showWeek) {
2613
+ week++;
2614
+ str.push('<td class="week-cell">'+ week +'</td>');
2615
+ }
2616
+ }
2617
+
2618
+ if(!i){
2619
+
2620
+ if(day != curCfg.date.firstDay){
2621
+ nDay = day - curCfg.date.firstDay;
2622
+ if(nDay < 0){
2623
+ nDay += 7;
2624
+ }
2625
+ date.setDate(date.getDate() - nDay);
2626
+ day = date.getDay();
2627
+ curMonth = date.getMonth();
2628
+ otherMonth = lastMotnh != curMonth;
2629
+ }
2630
+ }
2631
+
2632
+ dateArray = getDateArray(date);
2633
+ buttonStr = '<td role="presentation" class="day-'+ day +'"><button data-id="day-'+ date.getDate() +'" role="gridcell" data-action="changeInput" value="'+ (dateArray.join('-')) +'"';
2634
+
2635
+ if(otherMonth){
2636
+ classArray.push('othermonth');
2637
+ } else {
2638
+ classArray.push('day-'+date.getDate());
2639
+ }
2640
+
2641
+ if(dateArray[0] == today[0] && today[1] == dateArray[1] && today[2] == dateArray[2]){
2642
+ classArray.push('this-value');
2643
+ }
2644
+
2645
+ if(currentValue[0] == dateArray[0] && dateArray[1] == currentValue[1] && dateArray[2] == currentValue[2]){
2646
+ classArray.push('checked-value');
2647
+ }
2648
+
2649
+ if(classArray.length){
2650
+ buttonStr += ' class="'+ classArray.join(' ') +'"';
2651
+ }
2652
+
2653
+ if(!picker.isInRange(dateArray, max, min) || (data.options.disableDays && $.inArray(day, data.options.disableDays) != -1)){
2654
+ buttonStr += ' disabled=""';
2655
+ }
2656
+
2657
+ str.push(buttonStr+' tabindex="-1">'+ date.getDate() +'</button></td>');
2658
+
2659
+ date.setDate(date.getDate() + 1);
2660
+ }
2661
+ str.push('</tbody></table></div></div>');
2662
+ if(j == size - 1){
2663
+ dateArray = getDateArray(date);
2664
+ dateArray[2] = 1;
2665
+ nextDisabled = picker.isInRange(dateArray, max, min) ? {'data-action': 'setDayList','value': dateArray.date} : false;
2666
+ }
2667
+ }
2668
+
2669
+
2670
+ return {
2671
+ enabled: 9,
2672
+ main: str.join(''),
2673
+ prev: prevDisabled,
2674
+ next: nextDisabled,
2675
+ type: 'Grid'
2676
+ };
2677
+ };
2678
+
2679
+ picker.isInRange = function(values, max, min){
2680
+ var i;
2681
+ var ret = true;
2682
+ for(i = 0; i < values.length; i++){
2683
+
2684
+ if(min[i] && min[i] > values[i]){
2685
+ ret = false;
2686
+ break;
2687
+ } else if( !(min[i] && min[i] == values[i]) ){
2688
+ break;
2689
+ }
2690
+ }
2691
+ if(ret){
2692
+ for(i = 0; i < values.length; i++){
2693
+
2694
+ if((max[i] && max[i] < values[i])){
2695
+ ret = false;
2696
+ break;
2697
+ } else if( !(max[i] && max[i] == values[i]) ){
2698
+ break;
2699
+ }
2700
+ }
2701
+ }
2702
+ return ret;
2703
+ };
2704
+
2705
+ picker.createMonthSelect = function(value, max, min, monthNames){
2706
+ if(!monthNames){
2707
+ monthNames = curCfg.date.monthNames;
2708
+ }
2709
+
2710
+ var selected;
2711
+ var i = 0;
2712
+ var options = [];
2713
+ var tempVal = value[1]-1;
2714
+ for(; i < monthNames.length; i++){
2715
+ selected = tempVal == i ? ' selected=""' : '';
2716
+ if(selected || picker.isInRange([value[0], i+1], max, min)){
2717
+ options.push('<option value="'+ value[0]+'-'+addZero(i+1) + '"'+selected+'>'+ monthNames[i] +'</option>');
2718
+ }
2719
+ }
2720
+ return options;
2721
+ };
2722
+
2723
+ picker.createYearSelect = function(value, max, min, valueAdd){
2724
+
2725
+ var temp;
2726
+ var goUp = true;
2727
+ var goDown = true;
2728
+ var options = ['<option selected="">'+ value + '</option>'];
2729
+ var i = 0;
2730
+ if(!valueAdd){
2731
+ valueAdd = '';
2732
+ }
2733
+ while(i < 8 && (goUp || goDown)){
2734
+ i++;
2735
+ temp = value-i;
2736
+ if(goUp && picker.isInRange([temp], max, min)){
2737
+ options.unshift('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
2738
+ } else {
2739
+ goUp = false;
2740
+ }
2741
+ temp = value + i;
2742
+ if(goDown && picker.isInRange([temp], max, min)){
2743
+ options.push('<option value="'+ (temp+valueAdd) +'">'+ temp +'</option>');
2744
+ } else {
2745
+ goDown = false;
2746
+ }
2747
+ }
2748
+ return options;
2749
+ };
2750
+
2751
+ var actions = {
2752
+ changeInput: function(val, popover, data){
2753
+ popover.stopOpen = true;
2754
+ data.element.getShadowFocusElement().focus();
2755
+ setTimeout(function(){
2756
+ popover.stopOpen = false;
2757
+ }, 9);
2758
+ popover.hide();
2759
+ data.setChange(val);
2760
+ }
2761
+ };
2762
+
2763
+ (function(){
2764
+ var retNames = function(name){
2765
+ return 'get'+name+'List';
2766
+ };
2767
+ var retSetNames = function(name){
2768
+ return 'set'+name+'List';
2769
+ };
2770
+ var stops = {
2771
+ date: 'Day',
2772
+ week: 'Day',
2773
+ month: 'Month'
2774
+ };
2775
+
2776
+ $.each({'setYearList' : ['Year', 'Month', 'Day'], 'setMonthList': ['Month', 'Day'], 'setDayList': ['Day']}, function(setName, names){
2777
+ var getNames = names.map(retNames);
2778
+ var setNames = names.map(retSetNames);
2779
+ actions[setName] = function(val, popover, data, startAt){
2780
+ val = ''+val;
2781
+ var o = data.options;
2782
+ var values = val.split('-');
2783
+ if(!startAt){
2784
+ startAt = 0;
2785
+ }
2786
+ $.each(getNames, function(i, item){
2787
+ if(i >= startAt){
2788
+ var content = picker[item](values, data);
2789
+
2790
+ if( values.length < 2 || content.enabled > 1 || stops[data.type] === names[i]){
2791
+ popover.element
2792
+ .attr({'data-currentview': setNames[i]})
2793
+ .addClass('ws-size-'+o.size)
2794
+ .data('pickercontent', {
2795
+ data: data,
2796
+ content: content,
2797
+ values: values
2798
+ })
2799
+ ;
2800
+ popover.bodyElement.html(content.main);
2801
+ if(content.prev){
2802
+ popover.prevElement
2803
+ .attr(content.prev)
2804
+ .prop({disabled: false})
2805
+ ;
2806
+ } else {
2807
+ popover.prevElement
2808
+ .removeAttr('data-action')
2809
+ .prop({disabled: true})
2810
+ ;
2811
+ }
2812
+ if(content.next){
2813
+ popover.nextElement
2814
+ .attr(content.next)
2815
+ .prop({disabled: false})
2816
+ ;
2817
+ } else {
2818
+ popover.nextElement
2819
+ .removeAttr('data-action')
2820
+ .prop({disabled: true})
2821
+ ;
2822
+ }
2823
+ if(webshims[content.type]){
2824
+ new webshims[content.type](popover.bodyElement.children(), popover, content);
2825
+ }
2826
+ popover.element.trigger('pickerchange');
2827
+ return false;
2828
+ }
2829
+ }
2830
+ });
2831
+ };
2832
+ });
2833
+ })();
2834
+
2835
+ picker.commonInit = function(data, popover){
2836
+ var actionfn = function(e){
2837
+ if(!$(this).is('.othermonth') || $(this).css('cursor') == 'pointer'){
2838
+ popover.actionFn({
2839
+ 'data-action': $.attr(this, 'data-action'),
2840
+ value: $(this).val() || $.attr(this, 'value')
2841
+ });
2842
+ }
2843
+ return false;
2844
+ };
2845
+ var id = new Date().getTime();
2846
+ var generateList = function(o, max, min){
2847
+ var options = [];
2848
+ var label = '';
2849
+ var labelId = '';
2850
+ o.options = data.getOptions() || {};
2851
+ $('div.ws-options', popover.contentElement).remove();
2852
+ $.each(o.options[0], function(val, label){
2853
+ var disabled = picker.isInRange(val.split('-'), o.maxS, o.minS) ?
2854
+ '' :
2855
+ ' disabled="" '
2856
+ ;
2857
+ options.push('<li role="presentation"><button value="'+ val +'" '+disabled+' data-action="changeInput" tabindex="-1" role="option">'+ (label || data.formatValue(val, false)) +'</button></li>');
2858
+ });
2859
+ if(options.length){
2860
+ id++;
2861
+ if(o.options[1]){
2862
+ labelId = 'datalist-'+id;
2863
+ label = '<h5 id="'+labelId+'">'+ o.options[1] +'</h5>';
2864
+ labelId = ' aria-labelledbyid="'+ labelId +'" ';
2865
+ }
2866
+ new webshims.ListBox($('<div class="ws-options">'+label+'<ul role="listbox" '+ labelId +'>'+ options.join('') +'</div>').insertAfter(popover.bodyElement)[0], popover, {noFocus: true});
2867
+ }
2868
+ };
2869
+ var updateContent = function(){
2870
+ if(popover.isDirty){
2871
+ var o = data.options;
2872
+ o.maxS = o.max.split('-');
2873
+ o.minS = o.min.split('-');
2874
+
2875
+ $('button', popover.buttonRow).each(function(){
2876
+ var text;
2877
+ if($(this).is('.ws-empty')){
2878
+ text = curCfg.date.clear;
2879
+ if(!text){
2880
+ text = formcfg[''].date.clear || 'clear';
2881
+ webshims.warn("could not get clear text from form cfg");
2882
+ }
2883
+ } else if($(this).is('.ws-current')){
2884
+ text = (curCfg[data.type] || {}).currentText;
2885
+ if(!text){
2886
+ text = (formcfg[''][[data.type]] || {}).currentText || 'current';
2887
+ webshims.warn("could not get currentText from form cfg");
2888
+ }
2889
+ $.prop(this, 'disabled', !picker.isInRange(today[data.type].split('-'), o.maxS, o.minS));
2890
+ }
2891
+ if(text){
2892
+ $(this).text(text).attr({'aria-label': text});
2893
+ if(webshims.assumeARIA){
2894
+ $.attr(this, 'aria-label', text);
2895
+ }
2896
+ }
2897
+
2898
+ });
2899
+ popover.nextElement.attr({'aria-label': curCfg.date.nextText});
2900
+ $('> span', popover.nextElement).html(curCfg.date.nextText);
2901
+ popover.prevElement.attr({'aria-label': curCfg.date.prevText});
2902
+ $('> span', popover.prevElement).html(curCfg.date.prevText);
2903
+
2904
+ generateList(o, o.maxS, o.minS);
2905
+
2906
+ }
2907
+ $('button.ws-empty', popover.buttonRow).prop('disabled', $.prop(data.orig, 'required'));
2908
+ popover.isDirty = false;
2909
+ };
2910
+
2911
+ popover.actionFn = function(obj){
2912
+ if(actions[obj['data-action']]){
2913
+ actions[obj['data-action']](obj.value, popover, data, 0);
2914
+ } else {
2915
+ webshims.warn('no action for '+ obj['data-action']);
2916
+ }
2917
+ };
2918
+
2919
+ 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>');
2920
+ popover.nextElement = $('button.ws-next', popover.contentElement);
2921
+ popover.prevElement = $('button.ws-prev', popover.contentElement);
2922
+ popover.bodyElement = $('div.ws-picker-body', popover.contentElement);
2923
+ popover.buttonRow = $('div.ws-button-row', popover.contentElement);
2924
+
2925
+ popover.isDirty = true;
2926
+
2927
+ popover.contentElement
2928
+ .on('click', 'button[data-action]', actionfn)
2929
+ .on('change', 'select[data-action]', actionfn)
2930
+ ;
2931
+
2932
+ popover.contentElement.on({
2933
+ keydown: function(e){
2934
+ if(e.keyCode == 9){
2935
+ var tabbable = $('[tabindex="0"]:not(:disabled)', this).filter(':visible');
2936
+ var index = tabbable.index(e.target);
2937
+ if(e.shiftKey && index <= 0){
2938
+ tabbable.last().focus();
2939
+ return false;
2940
+ }
2941
+ if(!e.shiftKey && index >= tabbable.length - 1){
2942
+ tabbable.first().focus();
2943
+ return false;
2944
+ }
2945
+ } else if(e.keyCode == 27){
2946
+ data.element.getShadowFocusElement().focus();
2947
+ popover.hide();
2948
+ return false;
2949
+ }
2950
+ }
2951
+ });
2952
+
2953
+ $(data.options.orig).on('input', function(){
2954
+ var currentView;
2955
+ if(data.options.updateOnInput && popover.isVisible && data.options.value && (currentView = popover.element.attr('data-currentview'))){
2956
+ actions[currentView]( data.options.value , popover, data, 0);
2957
+ }
2958
+ });
2959
+
2960
+ data._propertyChange = (function(){
2961
+ var timer;
2962
+ var update = function(){
2963
+ if(popover.isVisible){
2964
+ updateContent();
2965
+ }
2966
+ };
2967
+ return function(prop){
2968
+ if(prop == 'value'){return;}
2969
+ popover.isDirty = true;
2970
+ if(popover.isVisible){
2971
+ clearTimeout(timer);
2972
+ timer = setTimeout(update, 9);
2973
+ }
2974
+ };
2975
+ })();
2976
+
2977
+ popover.activeElement = $([]);
2978
+
2979
+ popover.activateElement = function(element){
2980
+ element = $(element);
2981
+ if(element[0] != popover.activeElement[0]){
2982
+ popover.activeElement.removeClass('ws-focus');
2983
+ element.addClass('ws-focus');
2984
+ }
2985
+ popover.activeElement = element;
2986
+ };
2987
+ popover.element.on({
2988
+ wspopoverbeforeshow: function(){
2989
+ data.element.triggerHandler('wsupdatevalue');
2990
+ updateContent();
2991
+ }
2992
+ });
2993
+
2994
+ $(document).onTrigger('wslocalechange', data._propertyChange);
2995
+ };
2996
+
2997
+ picker._common = function(data){
2998
+ var popover = webshims.objectCreate(webshims.wsPopover, {}, {prepareFor: data.element});
2999
+ var opener = $('<button type="button" class="ws-popover-opener"><span /></button>').appendTo(data.buttonWrapper);
3000
+ var options = data.options;
3001
+ var init = false;
3002
+
3003
+ var show = function(){
3004
+ if(!options.disabled && !options.readonly && !popover.isVisible){
3005
+ if(!init){
3006
+ picker.commonInit(data, popover);
3007
+ }
3008
+
3009
+ if(!init || data.options.restartView) {
3010
+ actions.setYearList( options.defValue || options.value, popover, data, data.options.startView);
3011
+ } else {
3012
+ actions[popover.element.attr('data-currentview') || 'setYearList']( options.defValue || options.value, popover, data, 0);
3013
+ }
3014
+
3015
+ init = true;
3016
+ popover.show(data.element);
3017
+ }
3018
+ };
3019
+
3020
+ options.containerElements.push(popover.element[0]);
3021
+
3022
+ if(!options.startView){
3023
+ options.startView = 0;
3024
+ }
3025
+ if(!options.minView){
3026
+ options.minView = 0;
3027
+ }
3028
+ if(options.startView < options.minView){
3029
+ options.minView = options.startView;
3030
+ webshims.warn("wrong config for minView/startView.");
3031
+ }
3032
+ if(!options.size){
3033
+ options.size = 1;
3034
+ }
3035
+
3036
+ popover.element
3037
+ .addClass(data.type+'-popover input-picker')
3038
+ .attr({role: 'application'})
3039
+ .on({
3040
+ wspopoverhide: function(){
3041
+ popover.openedByFocus = false;
3042
+ },
3043
+ focusin: function(e){
3044
+ if(popover.activateElement){
3045
+ popover.openedByFocus = false;
3046
+ popover.activateElement(e.target);
3047
+ }
3048
+ },
3049
+ focusout: function(){
3050
+ if(popover.activeElement){
3051
+ popover.activeElement.removeClass('ws-focus');
3052
+ }
3053
+ }
3054
+ })
3055
+ ;
3056
+
3057
+ labelWidth(popover.element.children('div.ws-po-outerbox').attr({role: 'group'}), options.labels, true);
3058
+ labelWidth(opener, options.labels, true);
3059
+
3060
+ opener
3061
+ .attr({
3062
+ 'tabindex': options.labels.length ? 0 : '-1'
3063
+ })
3064
+ .on({
3065
+ mousedown: function(){
3066
+ stopPropagation.apply(this, arguments);
3067
+ popover.preventBlur();
3068
+ },
3069
+ click: function(){
3070
+ if(popover.isVisible && popover.activeElement){
3071
+ popover.openedByFocus = false;
3072
+ popover.activeElement.focus();
3073
+ }
3074
+ show();
3075
+ },
3076
+ focus: function(){
3077
+ popover.preventBlur();
3078
+ }
3079
+ })
3080
+ ;
3081
+
3082
+ (function(){
3083
+ var mouseFocus = false;
3084
+ var resetMouseFocus = function(){
3085
+ mouseFocus = false;
3086
+ };
3087
+ data.inputElements.on({
3088
+ focus: function(){
3089
+ if(!popover.stopOpen && (data.options.openOnFocus || (mouseFocus && options.openOnMouseFocus))){
3090
+ popover.openedByFocus = !options.noInput;
3091
+ show();
3092
+ } else {
3093
+ popover.preventBlur();
3094
+ }
3095
+ },
3096
+ mousedown: function(){
3097
+ mouseFocus = true;
3098
+ setTimeout(resetMouseFocus, 9);
3099
+ if(data.element.is(':focus')){
3100
+ popover.openedByFocus = !options.noInput;
3101
+ show();
3102
+ }
3103
+ popover.preventBlur();
3104
+ }
3105
+ });
3106
+ })();
3107
+ data.popover = popover;
3108
+ };
3109
+
3110
+ picker.month = picker._common;
3111
+ picker.date = picker.month;
3112
+
3113
+ webshims.picker = picker;
3114
+ })();
3115
+
3116
+ (function(){
3117
+
3118
+ var stopCircular, isCheckValidity;
3119
+
3120
+ var modernizrInputTypes = Modernizr.inputtypes;
3121
+ var inputTypes = {
3122
+
3123
+ };
3124
+ var copyProps = [
3125
+ 'disabled',
3126
+ 'readonly',
3127
+ 'value',
3128
+ 'min',
3129
+ 'max',
3130
+ 'step',
3131
+ 'title',
3132
+ 'placeholder'
3133
+ ];
3134
+
3135
+ //
3136
+ var copyAttrs = ['data-placeholder', 'tabindex'];
3137
+
3138
+ $.each(copyProps.concat(copyAttrs), function(i, name){
3139
+ var fnName = name.replace(/^data\-/, '');
3140
+ webshims.onNodeNamesPropertyModify('input', name, function(val){
3141
+ if(!stopCircular){
3142
+ var shadowData = webshims.data(this, 'shadowData');
3143
+ if(shadowData && shadowData.data && shadowData.nativeElement === this && shadowData.data[fnName]){
3144
+ shadowData.data[fnName](val);
3145
+ }
3146
+ }
3147
+ });
3148
+ });
3149
+
3150
+ if(options.replaceUI && 'valueAsNumber' in document.createElement('input')){
3151
+ var reflectFn = function(val){
3152
+ if(webshims.data(this, 'hasShadow')){
3153
+ $.prop(this, 'value', $.prop(this, 'value'));
3154
+ }
3155
+ };
3156
+
3157
+ webshims.onNodeNamesPropertyModify('input', 'valueAsNumber', reflectFn);
3158
+ webshims.onNodeNamesPropertyModify('input', 'valueAsDate', reflectFn);
3159
+ }
3160
+
3161
+ var extendType = (function(){
3162
+ return function(name, data){
3163
+ inputTypes[name] = data;
3164
+ data.attrs = $.merge([], copyAttrs, data.attrs);
3165
+ data.props = $.merge([], copyProps, data.props);
3166
+ };
3167
+ })();
3168
+
3169
+ var isVisible = function(){
3170
+ return $.css(this, 'display') != 'none';
3171
+ };
3172
+ var sizeInput = function(data){
3173
+ var init;
3174
+ var updateStyles = function(){
3175
+ $.style( data.orig, 'display', '' );
3176
+ var hasButtons, marginR, marginL;
3177
+ var correctWidth = 0.6;
3178
+ if(!init || data.orig.offsetWidth){
3179
+ hasButtons = data.buttonWrapper && data.buttonWrapper.filter(isVisible).length;
3180
+ marginR = $.css( data.orig, 'marginRight');
3181
+ data.element.css({
3182
+ marginLeft: $.css( data.orig, 'marginLeft'),
3183
+ marginRight: hasButtons ? 0 : marginR
3184
+ });
3185
+
3186
+ if(hasButtons){
3187
+ marginL = (parseInt(data.buttonWrapper.css('marginLeft'), 10) || 0);
3188
+ data.element.css({paddingRight: ''});
3189
+
3190
+ if(marginL < 0){
3191
+ marginR = (parseInt(marginR, 10) || 0) + ((data.buttonWrapper.outerWidth() + marginL) * -1);
3192
+ data.buttonWrapper.css('marginRight', marginR);
3193
+ data.element
3194
+ .css({paddingRight: ''})
3195
+ .css({
3196
+ paddingRight: (parseInt( data.element.css('paddingRight'), 10) || 0) + data.buttonWrapper.outerWidth()
3197
+ })
3198
+ ;
3199
+ } else {
3200
+ data.buttonWrapper.css('marginRight', marginR);
3201
+ correctWidth = data.buttonWrapper.outerWidth(true) + 0.6;
3202
+ }
3203
+ }
3204
+
3205
+ data.element.outerWidth( $(data.orig).outerWidth() - correctWidth );
3206
+ }
3207
+ init = true;
3208
+ $.style( data.orig, 'display', 'none' );
3209
+ };
3210
+ $(document).onTrigger('updateshadowdom', updateStyles);
3211
+ };
3212
+
3213
+
3214
+ var implementType = function(){
3215
+ var type = $.prop(this, 'type');
3216
+
3217
+ var i, opts, data, optsName, labels;
3218
+ if(inputTypes[type] && webshims.implement(this, 'inputwidgets')){
3219
+ data = {};
3220
+ optsName = type;
3221
+
3222
+ //todo: do we need deep extend?
3223
+
3224
+ labels = $(this).jProp('labels');
3225
+
3226
+ opts = $.extend({}, options.widgets, options[type], $($.prop(this, 'form')).data(type) || {}, $(this).data(type) || {}, {
3227
+ orig: this,
3228
+ type: type,
3229
+ labels: labels,
3230
+ options: {},
3231
+ input: function(val){
3232
+ opts._change(val, 'input');
3233
+ },
3234
+ change: function(val){
3235
+ opts._change(val, 'change');
3236
+ },
3237
+ _change: function(val, trigger){
3238
+ stopCircular = true;
3239
+ $.prop(opts.orig, 'value', val);
3240
+ stopCircular = false;
3241
+ if(trigger){
3242
+ $(opts.orig).trigger(trigger);
3243
+ }
3244
+ },
3245
+ containerElements: []
3246
+ });
3247
+
3248
+
3249
+ for(i = 0; i < copyProps.length; i++){
3250
+ opts[copyProps[i]] = $.prop(this, copyProps[i]);
3251
+ }
3252
+
3253
+ for(i = 0; i < copyAttrs.length; i++){
3254
+ optsName = copyAttrs[i].replace(/^data\-/, '');
3255
+ if(optsName == 'placeholder' || !opts[optsName]){
3256
+ opts[optsName] = $.attr(this, copyAttrs[i]) || opts[optsName];
3257
+ }
3258
+ }
3259
+
3260
+ data.shim = inputTypes[type]._create(opts);
3261
+
3262
+ webshims.addShadowDom(this, data.shim.element, {
3263
+ data: data.shim || {}
3264
+ });
3265
+
3266
+ data.shim.options.containerElements.push(data.shim.element[0]);
3267
+
3268
+ labelWidth($(this).getShadowFocusElement(), labels);
3269
+ $.attr(this, 'required', $.attr(this, 'required'));
3270
+ $(this).on('change', function(e){
3271
+ if(!stopCircular){
3272
+ data.shim.value($.prop(this, 'value'));
3273
+ }
3274
+ });
3275
+
3276
+ (function(){
3277
+ var has = {
3278
+ focusin: true,
3279
+ focus: true
3280
+ };
3281
+ var timer;
3282
+ var hasFocusTriggered = false;
3283
+ var hasFocus = false;
3284
+
3285
+ $(data.shim.options.containerElements)
3286
+ .on({
3287
+ 'focusin focus focusout blur': function(e){
3288
+ e.stopImmediatePropagation();
3289
+ hasFocus = has[e.type];
3290
+ clearTimeout(timer);
3291
+ timer = setTimeout(function(){
3292
+ if(hasFocus != hasFocusTriggered){
3293
+ hasFocusTriggered = hasFocus;
3294
+ $(opts.orig).triggerHandler(hasFocus ? 'focus' : 'blur');
3295
+ $(opts.orig).trigger(hasFocus ? 'focusin' : 'focusout');
3296
+ }
3297
+ hasFocusTriggered = hasFocus;
3298
+ }, 0);
3299
+ }
3300
+ })
3301
+ ;
3302
+ })();
3303
+
3304
+
3305
+ data.shim.element.on('change input', stopPropagation);
3306
+
3307
+ if(Modernizr.formvalidation){
3308
+ $(opts.orig).on('firstinvalid', function(e){
3309
+ if(!webshims.fromSubmit && isCheckValidity){return;}
3310
+ $(opts.orig).off('invalid.replacedwidgetbubble').on('invalid.replacedwidgetbubble', function(evt){
3311
+ if(!e.isInvalidUIPrevented() && !evt.isDefaultPrevented()){
3312
+ webshims.validityAlert.showFor( e.target );
3313
+ e.preventDefault();
3314
+ evt.preventDefault();
3315
+ }
3316
+ $(opts.orig).off('invalid.replacedwidgetbubble');
3317
+ });
3318
+ });
3319
+ }
3320
+
3321
+
3322
+ if(data.shim.buttonWrapper && data.shim.buttonWrapper.filter(isVisible).length){
3323
+ data.shim.element.addClass('has-input-buttons');
3324
+ }
3325
+
3326
+ if(opts.calculateWidth){
3327
+ sizeInput(data.shim);
3328
+ }
3329
+ $(this).css({display: 'none'});
3330
+ }
3331
+ };
3332
+
3333
+ if(!modernizrInputTypes.range || options.replaceUI){
3334
+ extendType('range', {
3335
+ _create: function(opts, set){
3336
+ return $('<span />').insertAfter(opts.orig).rangeUI(opts).data('rangeUi');
3337
+ }
3338
+ });
3339
+ }
3340
+
3341
+ if(Modernizr.formvalidation){
3342
+ ['input', 'form'].forEach(function(name){
3343
+ var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
3344
+ prop: {
3345
+ value: function(){
3346
+ isCheckValidity = true;
3347
+ var ret = desc.prop._supvalue.apply(this, arguments);
3348
+ isCheckValidity = false;
3349
+ return ret;
3350
+ }
3351
+ }
3352
+ });
3353
+ });
3354
+ }
3355
+
3356
+
3357
+ ['number', 'time', 'month', 'date'].forEach(function(name){
3358
+ if(!modernizrInputTypes[name] || options.replaceUI){
3359
+ extendType(name, {
3360
+ _create: function(opts, set){
3361
+
3362
+ if(opts.splitInput && !splitInputs[name]){
3363
+ webshims.warn('splitInput not supported for '+ name);
3364
+ opts.splitInput = false;
3365
+ }
3366
+ var markup = opts.splitInput ?
3367
+ '<span class="ws-'+name+' ws-input" role="group"></span>' :
3368
+ '<input class="ws-'+name+'" type="text" />';
3369
+ var data = $(markup) //role="spinbutton"???
3370
+ .insertAfter(opts.orig)
3371
+ .spinbtnUI(opts)
3372
+ .data('wsspinner')
3373
+ ;
3374
+ if(webshims.picker && webshims.picker[name]){
3375
+ webshims.picker[name](data);
3376
+ }
3377
+ data.buttonWrapper.addClass('input-button-size-'+(data.buttonWrapper.children().filter(isVisible).length));
3378
+ return data;
3379
+ }
3380
+ });
3381
+ }
3382
+ });
3383
+
3384
+
3385
+ webshims.addReady(function(context, contextElem){
3386
+ $('input', context)
3387
+ .add(contextElem.filter('input'))
3388
+ .each(implementType)
3389
+ ;
3390
+ });
3391
+ })();
3392
+ });
3393
+