webshims-rails 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/lib/webshims-rails/version.rb +2 -2
  2. data/vendor/assets/javascripts/webshims/extras/custom-validity.js +253 -261
  3. data/vendor/assets/javascripts/webshims/extras/modernizr-custom.js +534 -534
  4. data/vendor/assets/javascripts/webshims/extras/mousepress.js +60 -60
  5. data/vendor/assets/javascripts/webshims/minified/extras/custom-validity.js +1 -10
  6. data/vendor/assets/javascripts/webshims/minified/extras/modernizr-custom.js +1 -20
  7. data/vendor/assets/javascripts/webshims/minified/extras/mousepress.js +1 -2
  8. data/vendor/assets/javascripts/webshims/minified/polyfiller.js +1 -30
  9. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/canvas2png.js +1 -42
  10. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/flashcanvas.js +1 -28
  11. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/flashcanvas.swf +0 -0
  12. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/proxy.php +0 -0
  13. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvas/save.php +0 -0
  14. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/canvas2png.js +1 -42
  15. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  16. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  17. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/flashcanvas.js +1 -31
  18. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/proxy.php +0 -0
  19. data/vendor/assets/javascripts/webshims/minified/shims/FlashCanvasPro/save.php +0 -0
  20. data/vendor/assets/javascripts/webshims/minified/shims/combos/1.js +1 -38
  21. data/vendor/assets/javascripts/webshims/minified/shims/combos/10.js +1 -80
  22. data/vendor/assets/javascripts/webshims/minified/shims/combos/11.js +1 -45
  23. data/vendor/assets/javascripts/webshims/minified/shims/combos/12.js +1 -44
  24. data/vendor/assets/javascripts/webshims/minified/shims/combos/13.js +1 -28
  25. data/vendor/assets/javascripts/webshims/minified/shims/combos/14.js +1 -19
  26. data/vendor/assets/javascripts/webshims/minified/shims/combos/15.js +1 -10
  27. data/vendor/assets/javascripts/webshims/minified/shims/combos/16.js +1 -58
  28. data/vendor/assets/javascripts/webshims/minified/shims/combos/17.js +1 -66
  29. data/vendor/assets/javascripts/webshims/minified/shims/combos/18.js +1 -62
  30. data/vendor/assets/javascripts/webshims/minified/shims/combos/19.js +1 -64
  31. data/vendor/assets/javascripts/webshims/minified/shims/combos/2.js +1 -73
  32. data/vendor/assets/javascripts/webshims/minified/shims/combos/20.js +1 -42
  33. data/vendor/assets/javascripts/webshims/minified/shims/combos/21.js +1 -54
  34. data/vendor/assets/javascripts/webshims/minified/shims/combos/22.js +1 -57
  35. data/vendor/assets/javascripts/webshims/minified/shims/combos/23.js +1 -70
  36. data/vendor/assets/javascripts/webshims/minified/shims/combos/24.js +1 -80
  37. data/vendor/assets/javascripts/webshims/minified/shims/combos/25.js +1 -60
  38. data/vendor/assets/javascripts/webshims/minified/shims/combos/26.js +1 -79
  39. data/vendor/assets/javascripts/webshims/minified/shims/combos/27.js +1 -101
  40. data/vendor/assets/javascripts/webshims/minified/shims/combos/3.js +1 -95
  41. data/vendor/assets/javascripts/webshims/minified/shims/combos/4.js +1 -27
  42. data/vendor/assets/javascripts/webshims/minified/shims/combos/5.js +1 -34
  43. data/vendor/assets/javascripts/webshims/minified/shims/combos/59.js +1 -56
  44. data/vendor/assets/javascripts/webshims/minified/shims/combos/6.js +1 -33
  45. data/vendor/assets/javascripts/webshims/minified/shims/combos/7.js +1 -40
  46. data/vendor/assets/javascripts/webshims/minified/shims/combos/8.js +1 -39
  47. data/vendor/assets/javascripts/webshims/minified/shims/combos/9.js +1 -65
  48. data/vendor/assets/javascripts/webshims/minified/shims/details.js +1 -5
  49. data/vendor/assets/javascripts/webshims/minified/shims/dom-extend.js +1 -23
  50. data/vendor/assets/javascripts/webshims/minified/shims/es5.js +1 -15
  51. data/vendor/assets/javascripts/webshims/minified/shims/excanvas.js +1 -21
  52. data/vendor/assets/javascripts/webshims/minified/shims/form-core.js +1 -19
  53. data/vendor/assets/javascripts/webshims/minified/shims/form-datalist.js +1 -22
  54. data/vendor/assets/javascripts/webshims/minified/shims/form-message.js +1 -8
  55. data/vendor/assets/javascripts/webshims/minified/shims/form-native-extend.js +1 -7
  56. data/vendor/assets/javascripts/webshims/minified/shims/form-number-date-api.js +1 -10
  57. data/vendor/assets/javascripts/webshims/minified/shims/form-number-date-ui.js +1 -23
  58. data/vendor/assets/javascripts/webshims/minified/shims/form-shim-extend.js +1 -46
  59. data/vendor/assets/javascripts/webshims/minified/shims/geolocation.js +1 -5
  60. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ar.js +1 -7
  61. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ch-ZN.js +1 -3
  62. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-de.txt +33 -33
  63. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-el.js +1 -7
  64. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-en.txt +34 -34
  65. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-es.js +1 -3
  66. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-fr.js +1 -3
  67. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-he.js +1 -6
  68. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-hi.js +1 -6
  69. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-hu.js +1 -3
  70. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-it.js +1 -3
  71. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ja.js +1 -4
  72. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-nl.js +1 -3
  73. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-pt-PT.js +1 -3
  74. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-ru.js +1 -8
  75. data/vendor/assets/javascripts/webshims/minified/shims/i18n/errormessages-sv.js +1 -3
  76. data/vendor/assets/javascripts/webshims/minified/shims/json-storage.js +1 -14
  77. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/license.txt +0 -0
  78. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/player.swf +0 -0
  79. data/vendor/assets/javascripts/webshims/minified/shims/jwplayer/readme.html +0 -0
  80. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-core.js +1 -16
  81. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-jaris.js +1 -23
  82. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-native-fix.js +1 -3
  83. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-swf.js +1 -26
  84. data/vendor/assets/javascripts/webshims/minified/shims/mediaelement-yt.js +1 -14
  85. data/vendor/assets/javascripts/webshims/minified/shims/range-ui.js +1 -0
  86. data/vendor/assets/javascripts/webshims/minified/shims/styles/details-arrows.png +0 -0
  87. data/vendor/assets/javascripts/webshims/minified/shims/styles/forms.png +0 -0
  88. data/vendor/assets/javascripts/webshims/minified/shims/styles/polyfill-loader.gif +0 -0
  89. data/vendor/assets/javascripts/webshims/minified/shims/styles/shim.css +1 -689
  90. data/vendor/assets/javascripts/webshims/minified/shims/swf/JarisFLVPlayer.swf +0 -0
  91. data/vendor/assets/javascripts/webshims/minified/shims/swf/jwwebshims.swf +0 -0
  92. data/vendor/assets/javascripts/webshims/minified/shims/swf/localStorage.swf +0 -0
  93. data/vendor/assets/javascripts/webshims/minified/shims/track-ui.js +1 -9
  94. data/vendor/assets/javascripts/webshims/minified/shims/track.js +1 -21
  95. data/vendor/assets/javascripts/webshims/polyfiller.js +1188 -1191
  96. data/vendor/assets/javascripts/webshims/{minified/shims → shims}/FlashCanvas/README +0 -0
  97. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/canvas2png.js +0 -0
  98. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.js +0 -0
  99. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/flashcanvas.swf +0 -0
  100. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/proxy.php +0 -0
  101. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/save.php +0 -0
  102. data/vendor/assets/javascripts/webshims/{minified/shims → shims}/FlashCanvasPro/README +82 -82
  103. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/canvas2png.js +0 -0
  104. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  105. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  106. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/flashcanvas.js +0 -0
  107. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/proxy.php +0 -0
  108. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/save.php +0 -0
  109. data/vendor/assets/javascripts/webshims/shims/combos/1.js +1752 -1754
  110. data/vendor/assets/javascripts/webshims/shims/combos/10.js +3311 -3247
  111. data/vendor/assets/javascripts/webshims/shims/combos/11.js +1631 -1633
  112. data/vendor/assets/javascripts/webshims/shims/combos/12.js +1697 -1636
  113. data/vendor/assets/javascripts/webshims/shims/combos/13.js +1098 -1100
  114. data/vendor/assets/javascripts/webshims/shims/combos/14.js +477 -476
  115. data/vendor/assets/javascripts/webshims/shims/combos/15.js +317 -316
  116. data/vendor/assets/javascripts/webshims/shims/combos/16.js +2155 -2095
  117. data/vendor/assets/javascripts/webshims/shims/combos/17.js +2320 -2259
  118. data/vendor/assets/javascripts/webshims/shims/combos/18.js +1326 -1322
  119. data/vendor/assets/javascripts/webshims/shims/combos/19.js +2238 -2239
  120. data/vendor/assets/javascripts/webshims/shims/combos/2.js +2341 -2339
  121. data/vendor/assets/javascripts/webshims/shims/combos/20.js +1558 -1493
  122. data/vendor/assets/javascripts/webshims/shims/combos/21.js +1734 -1733
  123. data/vendor/assets/javascripts/webshims/shims/combos/22.js +2361 -2295
  124. data/vendor/assets/javascripts/webshims/shims/combos/23.js +2332 -2269
  125. data/vendor/assets/javascripts/webshims/shims/combos/24.js +2836 -2775
  126. data/vendor/assets/javascripts/webshims/shims/combos/25.js +1549 -1489
  127. data/vendor/assets/javascripts/webshims/shims/combos/26.js +2156 -2095
  128. data/vendor/assets/javascripts/webshims/shims/combos/27.js +3313 -3248
  129. data/vendor/assets/javascripts/webshims/shims/combos/3.js +3022 -3020
  130. data/vendor/assets/javascripts/webshims/shims/combos/4.js +771 -770
  131. data/vendor/assets/javascripts/webshims/shims/combos/5.js +1027 -1025
  132. data/vendor/assets/javascripts/webshims/shims/combos/59.js +1709 -1706
  133. data/vendor/assets/javascripts/webshims/shims/combos/6.js +387 -386
  134. data/vendor/assets/javascripts/webshims/shims/combos/7.js +643 -641
  135. data/vendor/assets/javascripts/webshims/shims/combos/8.js +1547 -1488
  136. data/vendor/assets/javascripts/webshims/shims/combos/9.js +2508 -2445
  137. data/vendor/assets/javascripts/webshims/shims/details.js +148 -148
  138. data/vendor/assets/javascripts/webshims/shims/dom-extend.js +949 -952
  139. data/vendor/assets/javascripts/webshims/shims/es5.js +802 -802
  140. data/vendor/assets/javascripts/webshims/shims/excanvas.js +924 -924
  141. data/vendor/assets/javascripts/webshims/shims/form-core.js +606 -606
  142. data/vendor/assets/javascripts/webshims/shims/form-datalist.js +681 -681
  143. data/vendor/assets/javascripts/webshims/shims/form-message.js +164 -164
  144. data/vendor/assets/javascripts/webshims/shims/form-native-extend.js +255 -255
  145. data/vendor/assets/javascripts/webshims/shims/form-number-date-api.js +383 -383
  146. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +2 -2
  147. data/vendor/assets/javascripts/webshims/shims/form-shim-extend.js +1568 -1569
  148. data/vendor/assets/javascripts/webshims/shims/geolocation.js +168 -168
  149. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ar.js +32 -32
  150. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ch-ZN.js +32 -32
  151. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-de.txt +33 -33
  152. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-el.js +32 -32
  153. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-en.txt +34 -34
  154. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-es.js +31 -31
  155. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-fr.js +32 -32
  156. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-he.js +32 -32
  157. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-hi.js +32 -32
  158. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-hu.js +32 -32
  159. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-it.js +32 -32
  160. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ja.js +32 -32
  161. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-nl.js +32 -32
  162. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-pt-PT.js +32 -32
  163. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-ru.js +31 -31
  164. data/vendor/assets/javascripts/webshims/shims/i18n/errormessages-sv.js +32 -32
  165. data/vendor/assets/javascripts/webshims/shims/json-storage.js +308 -308
  166. data/vendor/assets/javascripts/webshims/shims/jwplayer/license.txt +0 -0
  167. data/vendor/assets/javascripts/webshims/shims/jwplayer/player.swf +0 -0
  168. data/vendor/assets/javascripts/webshims/shims/jwplayer/readme.html +0 -0
  169. data/vendor/assets/javascripts/webshims/shims/mediaelement-core.js +597 -536
  170. data/vendor/assets/javascripts/webshims/shims/mediaelement-jaris.js +891 -860
  171. data/vendor/assets/javascripts/webshims/shims/mediaelement-native-fix.js +98 -98
  172. data/vendor/assets/javascripts/webshims/shims/mediaelement-swf.js +960 -957
  173. data/vendor/assets/javascripts/webshims/shims/mediaelement-yt.js +543 -543
  174. data/vendor/assets/javascripts/webshims/shims/range-ui.js +66 -0
  175. data/vendor/assets/javascripts/webshims/shims/styles/details-arrows.png +0 -0
  176. data/vendor/assets/javascripts/webshims/shims/styles/forms.png +0 -0
  177. data/vendor/assets/javascripts/webshims/shims/styles/polyfill-loader.gif +0 -0
  178. data/vendor/assets/javascripts/webshims/shims/styles/shim.css +697 -689
  179. data/vendor/assets/javascripts/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
  180. data/vendor/assets/javascripts/webshims/shims/swf/jwwebshims.swf +0 -0
  181. data/vendor/assets/javascripts/webshims/shims/swf/localStorage.swf +0 -0
  182. data/vendor/assets/javascripts/webshims/shims/track-ui.js +0 -0
  183. data/vendor/assets/javascripts/webshims/shims/track.js +0 -0
  184. metadata +6 -4
@@ -1,2339 +1,2341 @@
1
- //additional tests for partial implementation of forms features
2
- (function($){
3
- "use strict";
4
- var Modernizr = window.Modernizr;
5
- var webshims = $.webshims;
6
- var bugs = webshims.bugs;
7
- var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input required="" name="a" /></form>');
8
- var testRequiredFind = function(){
9
- if(form[0].querySelector){
10
- try {
11
- bugs.findRequired = !(form[0].querySelector('select:required'));
12
- } catch(er){
13
- bugs.findRequired = false;
14
- }
15
- }
16
- };
17
- var inputElem = $('input', form).eq(0);
18
- var onDomextend = function(fn){
19
- webshims.loader.loadList(['dom-extend']);
20
- webshims.ready('dom-extend', fn);
21
- };
22
-
23
- bugs.findRequired = false;
24
- bugs.validationMessage = false;
25
-
26
- webshims.capturingEventPrevented = function(e){
27
- if(!e._isPolyfilled){
28
- var isDefaultPrevented = e.isDefaultPrevented;
29
- var preventDefault = e.preventDefault;
30
- e.preventDefault = function(){
31
- clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
32
- $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
33
- $.removeData(e.target, e.type + 'DefaultPrevented');
34
- }, 30));
35
- return preventDefault.apply(this, arguments);
36
- };
37
- e.isDefaultPrevented = function(){
38
- return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
39
- };
40
- e._isPolyfilled = true;
41
- }
42
- };
43
-
44
- if(!Modernizr.formvalidation || bugs.bustedValidity){
45
- testRequiredFind();
46
- return;
47
- }
48
-
49
- //create delegatable events
50
- webshims.capturingEvents(['input']);
51
- webshims.capturingEvents(['invalid'], true);
52
-
53
- if(window.opera || window.testGoodWithFix){
54
-
55
- form.appendTo('head');
56
-
57
- testRequiredFind();
58
- bugs.validationMessage = !(inputElem.prop('validationMessage'));
59
-
60
- webshims.reTest(['form-extend', 'form-message']);
61
-
62
- form.remove();
63
-
64
- $(function(){
65
- onDomextend(function(){
66
-
67
- //Opera shows native validation bubbles in case of input.checkValidity()
68
- // Opera 11.6/12 hasn't fixed this issue right, it's buggy
69
- var preventDefault = function(e){
70
- e.preventDefault();
71
- };
72
-
73
- ['form', 'input', 'textarea', 'select'].forEach(function(name){
74
- var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
75
- prop: {
76
- value: function(){
77
- if (!webshims.fromSubmit) {
78
- $(this).on('invalid.checkvalidity', preventDefault);
79
- }
80
-
81
- webshims.fromCheckValidity = true;
82
- var ret = desc.prop._supvalue.apply(this, arguments);
83
- if (!webshims.fromSubmit) {
84
- $(this).unbind('invalid.checkvalidity', preventDefault);
85
- }
86
- webshims.fromCheckValidity = false;
87
- return ret;
88
- }
89
- }
90
- });
91
- });
92
-
93
- });
94
- });
95
- }
96
-
97
- if($.browser.webkit && !webshims.bugs.bustedValidity){
98
- (function(){
99
- var elems = /^(?:textarea|input)$/i;
100
- var form = false;
101
-
102
- document.addEventListener('contextmenu', function(e){
103
- if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
104
- setTimeout(function(){
105
- form = false;
106
- }, 1);
107
- }
108
- }, false);
109
-
110
- $(window).on('invalid', function(e){
111
- if(e.originalEvent && form && form == e.target.form){
112
- e.wrongWebkitInvalid = true;
113
- e.stopImmediatePropagation();
114
- }
115
- });
116
- })();
117
- }
118
- })(jQuery);
119
-
120
- jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
121
- "use strict";
122
-
123
- var groupTypes = {radio: 1};
124
- var checkTypes = {checkbox: 1, radio: 1};
125
- var emptyJ = $([]);
126
- var bugs = webshims.bugs;
127
- var getGroupElements = function(elem){
128
- elem = $(elem);
129
- var name;
130
- var form;
131
- var ret = emptyJ;
132
- if(groupTypes[elem[0].type]){
133
- form = elem.prop('form');
134
- name = elem[0].name;
135
- if(!name){
136
- ret = elem;
137
- } else if(form){
138
- ret = $(form[name]);
139
- } else {
140
- ret = $(document.getElementsByName(name)).filter(function(){
141
- return !$.prop(this, 'form');
142
- });
143
- }
144
- ret = ret.filter('[type="radio"]');
145
- }
146
- return ret;
147
- };
148
-
149
- var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
150
- var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
151
- if(key && message[key]){
152
- message = message[key];
153
- }
154
- if(typeof message == 'object'){
155
- validity = validity || $.prop(elem, 'validity') || {valid: 1};
156
- if(!validity.valid){
157
- $.each(validity, function(name, prop){
158
- if(prop && name != 'valid' && message[name]){
159
- message = message[name];
160
- return false;
161
- }
162
- });
163
- }
164
- }
165
-
166
- if(typeof message == 'object'){
167
- message = message.defaultMessage;
168
- }
169
- return message || '';
170
- };
171
-
172
- /*
173
- * Selectors for all browsers
174
- */
175
- var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
176
- var hasInvalid = function(elem){
177
- var ret = false;
178
- $($.prop(elem, 'elements')).each(function(){
179
- ret = $(this).is(':invalid');
180
- if(ret){
181
- return false;
182
- }
183
- });
184
- return ret;
185
- };
186
- $.extend($.expr[":"], {
187
- "valid-element": function(elem){
188
- return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
189
- },
190
- "invalid-element": function(elem){
191
- return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
192
- },
193
- "required-element": function(elem){
194
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
195
- },
196
- "user-error": function(elem){
197
- return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
198
- },
199
- "optional-element": function(elem){
200
- return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
201
- },
202
- "in-range": function(elem){
203
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
204
- return false;
205
- }
206
- var val = $.prop(elem, 'validity');
207
- return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
208
- },
209
- "out-of-range": function(elem){
210
- if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
211
- return false;
212
- }
213
- var val = $.prop(elem, 'validity');
214
- return !!(val && (val.rangeOverflow || val.rangeUnderflow));
215
- }
216
-
217
- });
218
-
219
- ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
220
- $.expr[":"][name] = $.expr.filters[name+"-element"];
221
- });
222
-
223
-
224
- $.expr[":"].focus = function( elem ) {
225
- try {
226
- var doc = elem.ownerDocument;
227
- return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
228
- } catch(e){}
229
- return false;
230
- };
231
-
232
- var customEvents = $.event.customEvent || {};
233
- var isValid = function(elem){
234
- return ($.prop(elem, 'validity') || {valid: 1}).valid;
235
- };
236
-
237
- if (bugs.bustedValidity || bugs.findRequired) {
238
- (function(){
239
- var find = $.find;
240
- var matchesSelector = $.find.matchesSelector;
241
-
242
- var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
243
- var regFn = function(sel){
244
- return sel + '-element';
245
- };
246
-
247
- $.find = (function(){
248
- var slice = Array.prototype.slice;
249
- var fn = function(sel){
250
- var ar = arguments;
251
- ar = slice.call(ar, 1, ar.length);
252
- ar.unshift(sel.replace(regExp, regFn));
253
- return find.apply(this, ar);
254
- };
255
- for (var i in find) {
256
- if(find.hasOwnProperty(i)){
257
- fn[i] = find[i];
258
- }
259
- }
260
- return fn;
261
- })();
262
- if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
263
- $.find.matchesSelector = function(node, expr){
264
- expr = expr.replace(regExp, regFn);
265
- return matchesSelector.call(this, node, expr);
266
- };
267
- }
268
-
269
- })();
270
- }
271
-
272
- //ToDo needs testing
273
- var oldAttr = $.prop;
274
- var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
275
- $.prop = function(elem, name, val){
276
- var ret = oldAttr.apply(this, arguments);
277
- if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
278
- if(isValid(elem)){
279
- $(elem).getShadowElement().removeClass(invalidClasses);
280
- if(name == 'checked' && val) {
281
- getGroupElements(elem).not(elem).removeClass(invalidClasses).removeAttr('aria-invalid');
282
- }
283
- }
284
- }
285
- return ret;
286
- };
287
-
288
- var returnValidityCause = function(validity, elem){
289
- var ret;
290
- $.each(validity, function(name, value){
291
- if(value){
292
- ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
293
- return false;
294
- }
295
- });
296
- return ret;
297
- };
298
-
299
- var isInGroup = function(name){
300
- var ret;
301
- try {
302
- ret = document.activeElement.name === name;
303
- } catch(e){}
304
- return ret;
305
- };
306
- /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-succes instead */
307
- var invalidClass = 'user-error';
308
- var invalidClasses = 'user-error form-ui-invalid';
309
- var validClass = 'user-success';
310
- var validClasses = 'user-success form-ui-valid';
311
- var switchValidityClass = function(e){
312
- var elem, timer;
313
- if(!e.target){return;}
314
- elem = $(e.target).getNativeElement()[0];
315
- if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
316
- timer = $.data(elem, 'webshimsswitchvalidityclass');
317
- var switchClass = function(){
318
- if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
319
- var validity = $.prop(elem, 'validity');
320
- var shadowElem = $(elem).getShadowElement();
321
- var addClass, removeClass, trigger, generaltrigger, validityCause;
322
-
323
- $(elem).trigger('refreshCustomValidityRules');
324
- if(validity.valid){
325
- if(!shadowElem.hasClass(validClass)){
326
- addClass = validClasses;
327
- removeClass = invalidClasses;
328
- generaltrigger = 'changedvaliditystate';
329
- trigger = 'changedvalid';
330
- if(checkTypes[elem.type] && elem.checked){
331
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
332
- }
333
- $.removeData(elem, 'webshimsinvalidcause');
334
- }
335
- } else {
336
- validityCause = returnValidityCause(validity, elem);
337
- if($.data(elem, 'webshimsinvalidcause') != validityCause){
338
- $.data(elem, 'webshimsinvalidcause', validityCause);
339
- generaltrigger = 'changedvaliditystate';
340
- }
341
- if(!shadowElem.hasClass(invalidClass)){
342
- addClass = invalidClasses;
343
- removeClass = validClasses;
344
- if (checkTypes[elem.type] && !elem.checked) {
345
- getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
346
- }
347
- trigger = 'changedinvalid';
348
- }
349
- }
350
- if(addClass){
351
- shadowElem.addClass(addClass).removeClass(removeClass);
352
- //jQuery 1.6.1 IE9 bug (doubble trigger bug)
353
- setTimeout(function(){
354
- $(elem).trigger(trigger);
355
- }, 0);
356
- }
357
- if(generaltrigger){
358
- setTimeout(function(){
359
- $(elem).trigger(generaltrigger);
360
- }, 0);
361
- }
362
- $.removeData(e.target, 'webshimsswitchvalidityclass');
363
- };
364
-
365
- if(timer){
366
- clearTimeout(timer);
367
- }
368
- if(e.type == 'refreshvalidityui'){
369
- switchClass();
370
- } else {
371
- $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
372
- }
373
- };
374
-
375
- $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
376
- customEvents.changedvaliditystate = true;
377
- customEvents.refreshCustomValidityRules = true;
378
- customEvents.changedvalid = true;
379
- customEvents.changedinvalid = true;
380
- customEvents.refreshvalidityui = true;
381
-
382
-
383
- webshims.triggerInlineForm = function(elem, event){
384
- $(elem).trigger(event);
385
- };
386
-
387
- webshims.modules["form-core"].getGroupElements = getGroupElements;
388
-
389
-
390
- var setRoot = function(){
391
- webshims.scrollRoot = ($.browser.webkit || document.compatMode == 'BackCompat') ?
392
- $(document.body) :
393
- $(document.documentElement)
394
- ;
395
- };
396
- setRoot();
397
- webshims.ready('DOM', setRoot);
398
-
399
- webshims.getRelOffset = function(posElem, relElem){
400
- posElem = $(posElem);
401
- var offset = $(relElem).offset();
402
- var bodyOffset;
403
- $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
404
- bodyOffset = posElem.offset();
405
- });
406
- offset.top -= bodyOffset.top;
407
- offset.left -= bodyOffset.left;
408
- return offset;
409
- };
410
-
411
- /* some extra validation UI */
412
- webshims.validityAlert = (function(){
413
- var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label';
414
- var errorBubble;
415
- var hideTimer = false;
416
- var focusTimer = false;
417
- var resizeTimer = false;
418
- var boundHide;
419
-
420
- var api = {
421
- hideDelay: 5000,
422
-
423
- showFor: function(elem, message, noFocusElem, noBubble){
424
- api._create();
425
- elem = $(elem);
426
- var visual = $(elem).getShadowElement();
427
- var offset = api.getOffsetFromBody(visual);
428
- api.clear();
429
- if(noBubble){
430
- this.hide();
431
- } else {
432
- this.getMessage(elem, message);
433
- this.position(visual, offset);
434
-
435
- this.show();
436
- if(this.hideDelay){
437
- hideTimer = setTimeout(boundHide, this.hideDelay);
438
- }
439
- $(window)
440
- .on('resize.validityalert', function(){
441
- clearTimeout(resizeTimer);
442
- resizeTimer = setTimeout(function(){
443
- api.position(visual);
444
- }, 9);
445
- })
446
- ;
447
- }
448
-
449
- if(!noFocusElem){
450
- this.setFocus(visual, offset);
451
- }
452
- },
453
- getOffsetFromBody: function(elem){
454
- return webshims.getRelOffset(errorBubble, elem);
455
- },
456
- setFocus: function(visual, offset){
457
- var focusElem = $(visual).getShadowFocusElement();
458
- var scrollTop = webshims.scrollRoot.scrollTop();
459
- var elemTop = ((offset || focusElem.offset()).top) - 30;
460
- var smooth;
461
-
462
- if(webshims.getID && alertElem == 'label'){
463
- errorBubble.attr('for', webshims.getID(focusElem));
464
- }
465
-
466
- if(scrollTop > elemTop){
467
- webshims.scrollRoot.animate(
468
- {scrollTop: elemTop - 5},
469
- {
470
- queue: false,
471
- duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
472
- }
473
- );
474
- smooth = true;
475
- }
476
- try {
477
- focusElem[0].focus();
478
- } catch(e){}
479
- if(smooth){
480
- webshims.scrollRoot.scrollTop(scrollTop);
481
- setTimeout(function(){
482
- webshims.scrollRoot.scrollTop(scrollTop);
483
- }, 0);
484
- }
485
- setTimeout(function(){
486
- $(document).on('focusout.validityalert', boundHide);
487
- }, 10);
488
- },
489
- getMessage: function(elem, message){
490
- if (!message) {
491
- message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage');
492
- }
493
- if (message) {
494
- $('span.va-box', errorBubble).text(message);
495
- }
496
- else {
497
- this.hide();
498
- }
499
- },
500
- position: function(elem, offset){
501
- offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
502
- offset.top += elem.outerHeight();
503
- errorBubble.css(offset);
504
- },
505
- show: function(){
506
- if(errorBubble.css('display') === 'none'){
507
- errorBubble.css({opacity: 0}).show();
508
- }
509
- errorBubble.addClass('va-visible').fadeTo(400, 1);
510
- },
511
- hide: function(){
512
- errorBubble.removeClass('va-visible').fadeOut();
513
- },
514
- clear: function(){
515
- clearTimeout(focusTimer);
516
- clearTimeout(hideTimer);
517
- $(document).unbind('.validityalert');
518
- $(window).unbind('.validityalert');
519
- errorBubble.stop().removeAttr('for');
520
- },
521
- _create: function(){
522
- if(errorBubble){return;}
523
- 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'});
524
- webshims.ready('DOM', function(){
525
- errorBubble.appendTo('body');
526
- if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){
527
- errorBubble.bgIframe();
528
- }
529
- });
530
- }
531
- };
532
-
533
-
534
- boundHide = $.proxy(api, 'hide');
535
-
536
- return api;
537
- })();
538
-
539
-
540
- /* extension, but also used to fix native implementation workaround/bugfixes */
541
- (function(){
542
- var firstEvent,
543
- invalids = [],
544
- stopSubmitTimer,
545
- form
546
- ;
547
-
548
- $(document).on('invalid', function(e){
549
- if(e.wrongWebkitInvalid){return;}
550
- var jElm = $(e.target);
551
- var shadowElem = jElm.getShadowElement();
552
- if(!shadowElem.hasClass(invalidClass)){
553
- shadowElem.addClass(invalidClasses).removeClass(validClasses);
554
- setTimeout(function(){
555
- $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
556
- }, 0);
557
- }
558
-
559
- if(!firstEvent){
560
- //trigger firstinvalid
561
- firstEvent = $.Event('firstinvalid');
562
- firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
563
- var firstSystemInvalid = $.Event('firstinvalidsystem');
564
- $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
565
- jElm.trigger(firstEvent);
566
- }
567
-
568
- //if firstinvalid was prevented all invalids will be also prevented
569
- if( firstEvent && firstEvent.isDefaultPrevented() ){
570
- e.preventDefault();
571
- }
572
- invalids.push(e.target);
573
- e.extraData = 'fix';
574
- clearTimeout(stopSubmitTimer);
575
- stopSubmitTimer = setTimeout(function(){
576
- var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
577
- //reset firstinvalid
578
- firstEvent = false;
579
- invalids = [];
580
- $(e.target).trigger(lastEvent, lastEvent);
581
- }, 9);
582
- jElm = null;
583
- shadowElem = null;
584
- });
585
- })();
586
-
587
- $.fn.getErrorMessage = function(){
588
- var message = '';
589
- var elem = this[0];
590
- if(elem){
591
- message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
592
- }
593
- return message;
594
- };
595
-
596
- if(options.replaceValidationUI){
597
- webshims.ready('DOM forms', function(){
598
- $(document).on('firstinvalid', function(e){
599
- if(!e.isInvalidUIPrevented()){
600
- e.preventDefault();
601
- $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') );
602
- }
603
- });
604
- });
605
- }
606
-
607
- });jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
608
- "use strict";
609
- var validityMessages = webshims.validityMessages;
610
-
611
- var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
612
-
613
- validityMessages['en'] = $.extend(true, {
614
- typeMismatch: {
615
- email: 'Please enter an email address.',
616
- url: 'Please enter a URL.',
617
- number: 'Please enter a number.',
618
- date: 'Please enter a date.',
619
- time: 'Please enter a time.',
620
- range: 'Invalid input.',
621
- "datetime-local": 'Please enter a datetime.'
622
- },
623
- rangeUnderflow: {
624
- defaultMessage: 'Value must be greater than or equal to {%min}.'
625
- },
626
- rangeOverflow: {
627
- defaultMessage: 'Value must be less than or equal to {%max}.'
628
- },
629
- stepMismatch: 'Invalid input.',
630
- tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
631
-
632
- patternMismatch: 'Invalid input. {%title}',
633
- valueMissing: {
634
- defaultMessage: 'Please fill out this field.',
635
- checkbox: 'Please check this box if you want to proceed.'
636
- }
637
- }, (validityMessages['en'] || validityMessages['en-US'] || {}));
638
-
639
-
640
- ['select', 'radio'].forEach(function(type){
641
- validityMessages['en'].valueMissing[type] = 'Please select an option.';
642
- });
643
-
644
- ['date', 'time', 'datetime-local'].forEach(function(type){
645
- validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
646
- });
647
- ['date', 'time', 'datetime-local'].forEach(function(type){
648
- validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
649
- });
650
-
651
- validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
652
- validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
653
-
654
- validityMessages['de'] = $.extend(true, {
655
- typeMismatch: {
656
- email: '{%value} ist keine zulässige E-Mail-Adresse',
657
- url: '{%value} ist keine zulässige Webadresse',
658
- number: '{%value} ist keine Nummer!',
659
- date: '{%value} ist kein Datum',
660
- time: '{%value} ist keine Uhrzeit',
661
- range: '{%value} ist keine Nummer!',
662
- "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
663
- },
664
- rangeUnderflow: {
665
- defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
666
- },
667
- rangeOverflow: {
668
- defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
669
- },
670
- stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
671
- tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
672
- patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
673
- valueMissing: {
674
- defaultMessage: 'Bitte geben Sie einen Wert ein',
675
- checkbox: 'Bitte aktivieren Sie das Kästchen'
676
- }
677
- }, (validityMessages['de'] || {}));
678
-
679
- ['select', 'radio'].forEach(function(type){
680
- validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
681
- });
682
-
683
- ['date', 'time', 'datetime-local'].forEach(function(type){
684
- validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
685
- });
686
- ['date', 'time', 'datetime-local'].forEach(function(type){
687
- validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
688
- });
689
-
690
- var currentValidationMessage = validityMessages[''];
691
-
692
-
693
- webshims.createValidationMessage = function(elem, name){
694
- var message = currentValidationMessage[name];
695
- if(message && typeof message !== 'string'){
696
- message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
697
- }
698
- if(message){
699
- ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
700
- if(message.indexOf('{%'+attr) === -1){return;}
701
- var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
702
- if(name == 'patternMismatch' && attr == 'title' && !val){
703
- webshims.error('no title for patternMismatch provided. Always add a title attribute.');
704
- }
705
- message = message.replace('{%'+ attr +'}', val);
706
- if('value' == attr){
707
- message = message.replace('{%valueLen}', val.length);
708
- }
709
- });
710
- }
711
- return message || '';
712
- };
713
-
714
-
715
- if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
716
- implementProperties.push('validationMessage');
717
- }
718
-
719
- webshims.activeLang({
720
- langObj: validityMessages,
721
- module: 'form-core',
722
- callback: function(langObj){
723
- currentValidationMessage = langObj;
724
- }
725
- });
726
-
727
- implementProperties.forEach(function(messageProp){
728
- webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
729
- prop: {
730
- value: '',
731
- writeable: false
732
- }
733
- });
734
- ['input', 'select', 'textarea'].forEach(function(nodeName){
735
- var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
736
- prop: {
737
- get: function(){
738
- var elem = this;
739
- var message = '';
740
- if(!$.prop(elem, 'willValidate')){
741
- return message;
742
- }
743
-
744
- var validity = $.prop(elem, 'validity') || {valid: 1};
745
-
746
- if(validity.valid){return message;}
747
- message = webshims.getContentValidationMessage(elem, validity);
748
-
749
- if(message){return message;}
750
-
751
- if(validity.customError && elem.nodeName){
752
- message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
753
- if(message){return message;}
754
- }
755
- $.each(validity, function(name, prop){
756
- if(name == 'valid' || !prop){return;}
757
-
758
- message = webshims.createValidationMessage(elem, name);
759
- if(message){
760
- return false;
761
- }
762
- });
763
- return message || '';
764
- },
765
- writeable: false
766
- }
767
- });
768
- });
769
-
770
- });
771
- });if(!Modernizr.formvalidation || jQuery.webshims.bugs.bustedValidity){
772
- jQuery.webshims.register('form-extend', function($, webshims, window, document){
773
- "use strict";
774
- webshims.inputTypes = webshims.inputTypes || {};
775
- //some helper-functions
776
- var cfg = webshims.cfg.forms;
777
- var isSubmit;
778
-
779
- var isNumber = function(string){
780
- return (typeof string == 'number' || (string && string == string * 1));
781
- },
782
- typeModels = webshims.inputTypes,
783
- checkTypes = {
784
- radio: 1,
785
- checkbox: 1
786
- },
787
- getType = function(elem){
788
- return (elem.getAttribute('type') || elem.type || '').toLowerCase();
789
- }
790
- ;
791
-
792
- //API to add new input types
793
- webshims.addInputType = function(type, obj){
794
- typeModels[type] = obj;
795
- };
796
-
797
- //contsrain-validation-api
798
- var validityPrototype = {
799
- customError: false,
800
-
801
- typeMismatch: false,
802
- rangeUnderflow: false,
803
- rangeOverflow: false,
804
- stepMismatch: false,
805
- tooLong: false,
806
- patternMismatch: false,
807
- valueMissing: false,
808
-
809
- valid: true
810
- };
811
-
812
- var isPlaceholderOptionSelected = function(select){
813
- if(select.type == 'select-one' && select.size < 2){
814
- var option = $('> option:first-child', select);
815
- return !!option.prop('selected');
816
- }
817
- return false;
818
- };
819
-
820
- var validityRules = {
821
- valueMissing: function(input, val, cache){
822
- if(!input.prop('required')){return false;}
823
- var ret = false;
824
- if(!('type' in cache)){
825
- cache.type = getType(input[0]);
826
- }
827
- if(cache.nodeName == 'select'){
828
- ret = (!val && (input[0].selectedIndex < 0 || isPlaceholderOptionSelected(input[0]) ));
829
- } else if(checkTypes[cache.type]){
830
- ret = (cache.type == 'checkbox') ? !input.is(':checked') : !webshims.modules["form-core"].getGroupElements(input).filter(':checked')[0];
831
- } else {
832
- ret = !(val);
833
- }
834
- return ret;
835
- },
836
- tooLong: function(){
837
- return false;
838
- },
839
- typeMismatch: function (input, val, cache){
840
- if(val === '' || cache.nodeName == 'select'){return false;}
841
- var ret = false;
842
- if(!('type' in cache)){
843
- cache.type = getType(input[0]);
844
- }
845
-
846
- if(typeModels[cache.type] && typeModels[cache.type].mismatch){
847
- ret = typeModels[cache.type].mismatch(val, input);
848
- } else if('validity' in input[0]){
849
- ret = input[0].validity.typeMismatch;
850
- }
851
- return ret;
852
- },
853
- patternMismatch: function(input, val, cache) {
854
- if(val === '' || cache.nodeName == 'select'){return false;}
855
- var pattern = input.attr('pattern');
856
- if(!pattern){return false;}
857
- try {
858
- pattern = new RegExp('^(?:' + pattern + ')$');
859
- } catch(er){
860
- webshims.error('invalid pattern value: "'+ pattern +'" | '+ er);
861
- pattern = false;
862
- }
863
- if(!pattern){return false;}
864
- return !(pattern.test(val));
865
- }
866
- }
867
- ;
868
-
869
- webshims.addValidityRule = function(type, fn){
870
- validityRules[type] = fn;
871
- };
872
-
873
- $.event.special.invalid = {
874
- add: function(){
875
- $.event.special.invalid.setup.call(this.form || this);
876
- },
877
- setup: function(){
878
- var form = this.form || this;
879
- if( $.data(form, 'invalidEventShim') ){
880
- form = null;
881
- return;
882
- }
883
- $(form)
884
- .data('invalidEventShim', true)
885
- .on('submit', $.event.special.invalid.handler)
886
- ;
887
- webshims.moveToFirstEvent(form, 'submit');
888
- if(webshims.bugs.bustedValidity && $.nodeName(form, 'form')){
889
- (function(){
890
- var noValidate = form.getAttribute('novalidate');
891
- form.setAttribute('novalidate', 'novalidate');
892
- webshims.data(form, 'bustedNoValidate', (noValidate == null) ? null : noValidate);
893
- })();
894
- }
895
- form = null;
896
- },
897
- teardown: $.noop,
898
- handler: function(e, d){
899
-
900
- if( e.type != 'submit' || e.testedValidity || !e.originalEvent || !$.nodeName(e.target, 'form') || $.prop(e.target, 'noValidate') ){return;}
901
-
902
- isSubmit = true;
903
- e.testedValidity = true;
904
- var notValid = !($(e.target).checkValidity());
905
- if(notValid){
906
- e.stopImmediatePropagation();
907
- isSubmit = false;
908
- return false;
909
- }
910
- isSubmit = false;
911
- }
912
- };
913
-
914
- var addSubmitBubbles = function(form){
915
- if (!$.support.submitBubbles && form && typeof form == 'object' && !form._submit_attached ) {
916
-
917
- $.event.add( form, 'submit._submit', function( event ) {
918
- event._submit_bubble = true;
919
- });
920
-
921
- form._submit_attached = true;
922
- }
923
- };
924
- if(!$.support.submitBubbles && $.event.special.submit){
925
- $.event.special.submit.setup = function() {
926
- // Only need this for delegated form submit events
927
- if ( $.nodeName( this, "form" ) ) {
928
- return false;
929
- }
930
-
931
- // Lazy-add a submit handler when a descendant form may potentially be submitted
932
- $.event.add( this, "click._submit keypress._submit", function( e ) {
933
- // Node name check avoids a VML-related crash in IE (#9807)
934
- var elem = e.target,
935
- form = $.nodeName( elem, 'input' ) || $.nodeName( elem, 'button' ) ? $.prop(elem, 'form') : undefined;
936
- addSubmitBubbles(form);
937
-
938
- });
939
- // return undefined since we don't need an event listener
940
- };
941
- }
942
-
943
- $.event.special.submit = $.event.special.submit || {setup: function(){return false;}};
944
- var submitSetup = $.event.special.submit.setup;
945
- $.extend($.event.special.submit, {
946
- setup: function(){
947
- if($.nodeName(this, 'form')){
948
- $(this).on('invalid', $.noop);
949
- } else {
950
- $('form', this).on('invalid', $.noop);
951
- }
952
- return submitSetup.apply(this, arguments);
953
- }
954
- });
955
-
956
- $(window).on('invalid', $.noop);
957
-
958
-
959
- webshims.addInputType('email', {
960
- mismatch: (function(){
961
- //taken from http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
962
- var test = cfg.emailReg || /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
963
- return function(val){
964
- return !test.test(val);
965
- };
966
- })()
967
- });
968
-
969
- webshims.addInputType('url', {
970
- mismatch: (function(){
971
- //taken from scott gonzales
972
- var test = cfg.urlReg || /^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
973
- return function(val){
974
- return !test.test(val);
975
- };
976
- })()
977
- });
978
-
979
- webshims.defineNodeNameProperty('input', 'type', {
980
- prop: {
981
- get: function(){
982
- var elem = this;
983
- var type = (elem.getAttribute('type') || '').toLowerCase();
984
- return (webshims.inputTypes[type]) ? type : elem.type;
985
- }
986
- }
987
- });
988
-
989
- // IDLs for constrain validation API
990
- //ToDo: add object to this list
991
- webshims.defineNodeNamesProperties(['button', 'fieldset', 'output'], {
992
- checkValidity: {
993
- value: function(){return true;}
994
- },
995
- willValidate: {
996
- value: false
997
- },
998
- setCustomValidity: {
999
- value: $.noop
1000
- },
1001
- validity: {
1002
- writeable: false,
1003
- get: function(){
1004
- return $.extend({}, validityPrototype);
1005
- }
1006
- }
1007
- }, 'prop');
1008
-
1009
- var baseCheckValidity = function(elem){
1010
- var e,
1011
- v = $.prop(elem, 'validity')
1012
- ;
1013
- if(v){
1014
- $.data(elem, 'cachedValidity', v);
1015
- } else {
1016
- return true;
1017
- }
1018
- if( !v.valid ){
1019
- e = $.Event('invalid');
1020
- var jElm = $(elem).trigger(e);
1021
- if(isSubmit && !baseCheckValidity.unhandledInvalids && !e.isDefaultPrevented()){
1022
- webshims.validityAlert.showFor(jElm);
1023
- baseCheckValidity.unhandledInvalids = true;
1024
- }
1025
- }
1026
- $.removeData(elem, 'cachedValidity');
1027
- return v.valid;
1028
- };
1029
- var rsubmittable = /^(?:select|textarea|input)/i;
1030
- webshims.defineNodeNameProperty('form', 'checkValidity', {
1031
- prop: {
1032
- value: function(){
1033
-
1034
- var ret = true,
1035
- elems = $($.prop(this, 'elements')).filter(function(){
1036
- if(!rsubmittable.test(this.nodeName)){return false;}
1037
- var shadowData = webshims.data(this, 'shadowData');
1038
- return !shadowData || !shadowData.nativeElement || shadowData.nativeElement === this;
1039
- })
1040
- ;
1041
-
1042
- baseCheckValidity.unhandledInvalids = false;
1043
- for(var i = 0, len = elems.length; i < len; i++){
1044
- if( !baseCheckValidity(elems[i]) ){
1045
- ret = false;
1046
- }
1047
- }
1048
- return ret;
1049
- }
1050
- }
1051
- });
1052
-
1053
- webshims.defineNodeNamesProperties(['input', 'textarea', 'select'], {
1054
- checkValidity: {
1055
- value: function(){
1056
- baseCheckValidity.unhandledInvalids = false;
1057
- return baseCheckValidity($(this).getNativeElement()[0]);
1058
- }
1059
- },
1060
- setCustomValidity: {
1061
- value: function(error){
1062
- $.removeData(this, 'cachedValidity');
1063
- webshims.data(this, 'customvalidationMessage', ''+error);
1064
- }
1065
- },
1066
- willValidate: {
1067
- writeable: false,
1068
- get: (function(){
1069
- var types = {
1070
- button: 1,
1071
- reset: 1,
1072
- hidden: 1,
1073
- image: 1
1074
- }
1075
- ;
1076
- return function(){
1077
- var elem = $(this).getNativeElement()[0];
1078
- //elem.name && <- we don't use to make it easier for developers
1079
- return !!(!elem.disabled && !elem.readOnly && !types[elem.type] );
1080
- };
1081
- })()
1082
- },
1083
- validity: {
1084
- writeable: false,
1085
- get: function(){
1086
- var jElm = $(this).getNativeElement();
1087
- var elem = jElm[0];
1088
- var validityState = $.data(elem, 'cachedValidity');
1089
- if(validityState){
1090
- return validityState;
1091
- }
1092
- validityState = $.extend({}, validityPrototype);
1093
-
1094
- if( !$.prop(elem, 'willValidate') || elem.type == 'submit' ){
1095
- return validityState;
1096
- }
1097
- var val = jElm.val(),
1098
- cache = {nodeName: elem.nodeName.toLowerCase()}
1099
- ;
1100
-
1101
- validityState.customError = !!(webshims.data(elem, 'customvalidationMessage'));
1102
- if( validityState.customError ){
1103
- validityState.valid = false;
1104
- }
1105
-
1106
- $.each(validityRules, function(rule, fn){
1107
- if (fn(jElm, val, cache)) {
1108
- validityState[rule] = true;
1109
- validityState.valid = false;
1110
- }
1111
- });
1112
- $(this).getShadowFocusElement().attr('aria-invalid', validityState.valid ? 'false' : 'true');
1113
- jElm = null;
1114
- elem = null;
1115
- return validityState;
1116
- }
1117
- }
1118
- }, 'prop');
1119
-
1120
- webshims.defineNodeNamesBooleanProperty(['input', 'textarea', 'select'], 'required', {
1121
- set: function(value){
1122
- $(this).getShadowFocusElement().attr('aria-required', !!(value)+'');
1123
- },
1124
- initAttr: (!$.browser.msie || webshims.browserVersion > 7)//only if we have aria-support
1125
- });
1126
-
1127
- webshims.reflectProperties(['input'], ['pattern']);
1128
-
1129
-
1130
- if( !('maxLength' in document.createElement('textarea')) ){
1131
- var constrainMaxLength = (function(){
1132
- var timer;
1133
- var curLength = 0;
1134
- var lastElement = $([]);
1135
- var max = 1e9;
1136
- var constrainLength = function(){
1137
- var nowValue = lastElement.prop('value');
1138
- var nowLen = nowValue.length;
1139
- if(nowLen > curLength && nowLen > max){
1140
- nowLen = Math.max(curLength, max);
1141
- lastElement.prop('value', nowValue.substr(0, nowLen ));
1142
- }
1143
- curLength = nowLen;
1144
- };
1145
- var remove = function(){
1146
- clearTimeout(timer);
1147
- lastElement.unbind('.maxlengthconstraint');
1148
- };
1149
- return function(element, maxLength){
1150
- remove();
1151
- if(maxLength > -1){
1152
- max = maxLength;
1153
- curLength = $.prop(element, 'value').length;
1154
- lastElement = $(element);
1155
- lastElement.on({
1156
- 'keydown.maxlengthconstraint keypress.maxlengthconstraint paste.maxlengthconstraint cut.maxlengthconstraint': function(e){
1157
- setTimeout(constrainLength, 0);
1158
- },
1159
- 'keyup.maxlengthconstraint': constrainLength,
1160
- 'blur.maxlengthconstraint': remove
1161
- });
1162
- timer = setInterval(constrainLength, 200);
1163
- }
1164
- };
1165
- })();
1166
-
1167
- constrainMaxLength.update = function(element, maxLength){
1168
- if($(element).is(':focus')){
1169
- if(!maxLength){
1170
- maxLength = $.prop(element, 'maxlength');
1171
- }
1172
- constrainMaxLength(element, maxLength);
1173
- }
1174
- };
1175
-
1176
- $(document).on('focusin', function(e){
1177
- var maxLength;
1178
- if(e.target.nodeName == "TEXTAREA" && (maxLength = $.prop(e.target, 'maxlength')) > -1){
1179
- constrainMaxLength(e.target, maxLength);
1180
- }
1181
- });
1182
-
1183
- webshims.defineNodeNameProperty('textarea', 'maxlength', {
1184
- attr: {
1185
- set: function(val){
1186
- this.setAttribute('maxlength', ''+val);
1187
- constrainMaxLength.update(this);
1188
- },
1189
- get: function(){
1190
- var ret = this.getAttribute('maxlength');
1191
- return ret == null ? undefined : ret;
1192
- }
1193
- },
1194
- prop: {
1195
- set: function(val){
1196
- if(isNumber(val)){
1197
- if(val < 0){
1198
- throw('INDEX_SIZE_ERR');
1199
- }
1200
- val = parseInt(val, 10);
1201
- this.setAttribute('maxlength', val);
1202
- constrainMaxLength.update(this, val);
1203
- return;
1204
- }
1205
- this.setAttribute('maxlength', '0');
1206
- constrainMaxLength.update(this, 0);
1207
- },
1208
- get: function(){
1209
- var val = this.getAttribute('maxlength');
1210
- return (isNumber(val) && val >= 0) ? parseInt(val, 10) : -1;
1211
-
1212
- }
1213
- }
1214
- });
1215
- webshims.defineNodeNameProperty('textarea', 'maxLength', {
1216
- prop: {
1217
- set: function(val){
1218
- $.prop(this, 'maxlength', val);
1219
- },
1220
- get: function(){
1221
- return $.prop(this, 'maxlength');
1222
- }
1223
- }
1224
- });
1225
- }
1226
-
1227
-
1228
-
1229
- var submitterTypes = {submit: 1, button: 1, image: 1};
1230
- var formSubmitterDescriptors = {};
1231
- [
1232
- {
1233
- name: "enctype",
1234
- limitedTo: {
1235
- "application/x-www-form-urlencoded": 1,
1236
- "multipart/form-data": 1,
1237
- "text/plain": 1
1238
- },
1239
- defaultProp: "application/x-www-form-urlencoded",
1240
- proptype: "enum"
1241
- },
1242
- {
1243
- name: "method",
1244
- limitedTo: {
1245
- "get": 1,
1246
- "post": 1
1247
- },
1248
- defaultProp: "get",
1249
- proptype: "enum"
1250
- },
1251
- {
1252
- name: "action",
1253
- proptype: "url"
1254
- },
1255
- {
1256
- name: "target"
1257
- },
1258
- {
1259
- name: "novalidate",
1260
- propName: "noValidate",
1261
- proptype: "boolean"
1262
- }
1263
- ].forEach(function(desc){
1264
- var propName = 'form'+ (desc.propName || desc.name).replace(/^[a-z]/, function(f){
1265
- return f.toUpperCase();
1266
- });
1267
- var attrName = 'form'+ desc.name;
1268
- var formName = desc.name;
1269
- var eventName = 'click.webshimssubmittermutate'+formName;
1270
-
1271
- var changeSubmitter = function(){
1272
- var elem = this;
1273
- if( !('form' in elem) || !submitterTypes[elem.type] ){return;}
1274
- var form = $.prop(elem, 'form');
1275
- if(!form){return;}
1276
- var attr = $.attr(elem, attrName);
1277
- if(attr != null && ( !desc.limitedTo || attr.toLowerCase() === $.prop(elem, propName))){
1278
-
1279
- var oldAttr = $.attr(form, formName);
1280
-
1281
- $.attr(form, formName, attr);
1282
- setTimeout(function(){
1283
- if(oldAttr != null){
1284
- $.attr(form, formName, oldAttr);
1285
- } else {
1286
- try {
1287
- $(form).removeAttr(formName);
1288
- } catch(er){
1289
- form.removeAttribute(formName);
1290
- }
1291
- }
1292
- }, 9);
1293
- }
1294
- };
1295
-
1296
-
1297
-
1298
- switch(desc.proptype) {
1299
- case "url":
1300
- var urlForm = document.createElement('form');
1301
- formSubmitterDescriptors[propName] = {
1302
- prop: {
1303
- set: function(value){
1304
- $.attr(this, attrName, value);
1305
- },
1306
- get: function(){
1307
- var value = $.attr(this, attrName);
1308
- if(value == null){return '';}
1309
- urlForm.setAttribute('action', value);
1310
- return urlForm.action;
1311
- }
1312
- }
1313
- };
1314
- break;
1315
- case "boolean":
1316
- formSubmitterDescriptors[propName] = {
1317
- prop: {
1318
- set: function(val){
1319
- val = !!val;
1320
- if(val){
1321
- $.attr(this, 'formnovalidate', 'formnovalidate');
1322
- } else {
1323
- $(this).removeAttr('formnovalidate');
1324
- }
1325
- },
1326
- get: function(){
1327
- return $.attr(this, 'formnovalidate') != null;
1328
- }
1329
- }
1330
- };
1331
- break;
1332
- case "enum":
1333
- formSubmitterDescriptors[propName] = {
1334
- prop: {
1335
- set: function(value){
1336
- $.attr(this, attrName, value);
1337
- },
1338
- get: function(){
1339
- var value = $.attr(this, attrName);
1340
- return (!value || ( (value = value.toLowerCase()) && !desc.limitedTo[value] )) ? desc.defaultProp : value;
1341
- }
1342
- }
1343
- };
1344
- break;
1345
- default:
1346
- formSubmitterDescriptors[propName] = {
1347
- prop: {
1348
- set: function(value){
1349
- $.attr(this, attrName, value);
1350
- },
1351
- get: function(){
1352
- var value = $.attr(this, attrName);
1353
- return (value != null) ? value : "";
1354
- }
1355
- }
1356
- };
1357
- }
1358
-
1359
-
1360
- if(!formSubmitterDescriptors[attrName]){
1361
- formSubmitterDescriptors[attrName] = {};
1362
- }
1363
- formSubmitterDescriptors[attrName].attr = {
1364
- set: function(value){
1365
- formSubmitterDescriptors[attrName].attr._supset.call(this, value);
1366
- $(this).unbind(eventName).on(eventName, changeSubmitter);
1367
- },
1368
- get: function(){
1369
- return formSubmitterDescriptors[attrName].attr._supget.call(this);
1370
- }
1371
- };
1372
- formSubmitterDescriptors[attrName].initAttr = true;
1373
- formSubmitterDescriptors[attrName].removeAttr = {
1374
- value: function(){
1375
- $(this).unbind(eventName);
1376
- formSubmitterDescriptors[attrName].removeAttr._supvalue.call(this);
1377
- }
1378
- };
1379
- });
1380
-
1381
- webshims.defineNodeNamesProperties(['input', 'button'], formSubmitterDescriptors);
1382
-
1383
-
1384
- if(!$.support.getSetAttribute && $('<form novalidate></form>').attr('novalidate') == null){
1385
- webshims.defineNodeNameProperty('form', 'novalidate', {
1386
- attr: {
1387
- set: function(val){
1388
- this.setAttribute('novalidate', ''+val);
1389
- },
1390
- get: function(){
1391
- var ret = this.getAttribute('novalidate');
1392
- return ret == null ? undefined : ret;
1393
- }
1394
- }
1395
- });
1396
- } else if(webshims.bugs.bustedValidity){
1397
-
1398
- webshims.defineNodeNameProperty('form', 'novalidate', {
1399
- attr: {
1400
- set: function(val){
1401
- webshims.data(this, 'bustedNoValidate', ''+val);
1402
- },
1403
- get: function(){
1404
- var ret = webshims.data(this, 'bustedNoValidate');
1405
- return ret == null ? undefined : ret;
1406
- }
1407
- },
1408
- removeAttr: {
1409
- value: function(){
1410
- webshims.data(this, 'bustedNoValidate', null);
1411
- }
1412
- }
1413
- });
1414
-
1415
- $.each(['rangeUnderflow', 'rangeOverflow', 'stepMismatch'], function(i, name){
1416
- validityRules[name] = function(elem){
1417
- return (elem[0].validity || {})[name] || false;
1418
- };
1419
- });
1420
-
1421
- }
1422
-
1423
- webshims.defineNodeNameProperty('form', 'noValidate', {
1424
- prop: {
1425
- set: function(val){
1426
- val = !!val;
1427
- if(val){
1428
- $.attr(this, 'novalidate', 'novalidate');
1429
- } else {
1430
- $(this).removeAttr('novalidate');
1431
- }
1432
- },
1433
- get: function(){
1434
- return $.attr(this, 'novalidate') != null;
1435
- }
1436
- }
1437
- });
1438
-
1439
- if($.browser.webkit && Modernizr.inputtypes.date){
1440
- (function(){
1441
-
1442
- var noInputTriggerEvts = {updateInput: 1, input: 1},
1443
- fixInputTypes = {
1444
- date: 1,
1445
- time: 1,
1446
- "datetime-local": 1
1447
- },
1448
- noFocusEvents = {
1449
- focusout: 1,
1450
- blur: 1
1451
- },
1452
- changeEvts = {
1453
- updateInput: 1,
1454
- change: 1
1455
- },
1456
- observe = function(input){
1457
- var timer,
1458
- focusedin = true,
1459
- lastInputVal = input.prop('value'),
1460
- lastChangeVal = lastInputVal,
1461
- trigger = function(e){
1462
- //input === null
1463
- if(!input){return;}
1464
- var newVal = input.prop('value');
1465
-
1466
- if(newVal !== lastInputVal){
1467
- lastInputVal = newVal;
1468
- if(!e || !noInputTriggerEvts[e.type]){
1469
- input.trigger('input');
1470
- }
1471
- }
1472
- if(e && changeEvts[e.type]){
1473
- lastChangeVal = newVal;
1474
- }
1475
- if(!focusedin && newVal !== lastChangeVal){
1476
- input.trigger('change');
1477
- }
1478
- },
1479
- extraTimer,
1480
- extraTest = function(){
1481
- clearTimeout(extraTimer);
1482
- extraTimer = setTimeout(trigger, 9);
1483
- },
1484
- unbind = function(e){
1485
- clearInterval(timer);
1486
- setTimeout(function(){
1487
- if(e && noFocusEvents[e.type]){
1488
- focusedin = false;
1489
- }
1490
- if(input){
1491
- input.unbind('focusout blur', unbind).unbind('input change updateInput', trigger);
1492
- trigger();
1493
- }
1494
- input = null;
1495
- }, 1);
1496
-
1497
- }
1498
- ;
1499
-
1500
- clearInterval(timer);
1501
- timer = setInterval(trigger, 160);
1502
- extraTest();
1503
- input
1504
- .off({
1505
- 'focusout blur': unbind,
1506
- 'input change updateInput': trigger
1507
- })
1508
- .on({
1509
- 'focusout blur': unbind,
1510
- 'input updateInput change': trigger
1511
- })
1512
- ;
1513
- }
1514
- ;
1515
- if($.event.customEvent){
1516
- $.event.customEvent.updateInput = true;
1517
- }
1518
-
1519
- (function(){
1520
-
1521
- var correctValue = function(elem){
1522
- var i = 1;
1523
- var len = 3;
1524
- var abort, val;
1525
- if(elem.type == 'date' && (isSubmit || !$(elem).is(':focus'))){
1526
- val = elem.value;
1527
- if(val && val.length < 10 && (val = val.split('-')) && val.length == len){
1528
- for(; i < len; i++){
1529
- if(val[i].length == 1){
1530
- val[i] = '0'+val[i];
1531
- } else if(val[i].length != 2){
1532
- abort = true;
1533
- break;
1534
- }
1535
- }
1536
- if(!abort){
1537
- val = val.join('-');
1538
- $.prop(elem, 'value', val);
1539
- return val;
1540
- }
1541
- }
1542
- }
1543
- };
1544
- var inputCheckValidityDesc, formCheckValidityDesc, inputValueDesc, inputValidityDesc;
1545
-
1546
- inputCheckValidityDesc = webshims.defineNodeNameProperty('input', 'checkValidity', {
1547
- prop: {
1548
- value: function(){
1549
- correctValue(this);
1550
- return inputCheckValidityDesc.prop._supvalue.apply(this, arguments);
1551
- }
1552
- }
1553
- });
1554
-
1555
- formCheckValidityDesc = webshims.defineNodeNameProperty('form', 'checkValidity', {
1556
- prop: {
1557
- value: function(){
1558
- $('input', this).each(function(){
1559
- correctValue(this);
1560
- });
1561
- return formCheckValidityDesc.prop._supvalue.apply(this, arguments);
1562
- }
1563
- }
1564
- });
1565
-
1566
- inputValueDesc = webshims.defineNodeNameProperty('input', 'value', {
1567
- prop: {
1568
- set: function(){
1569
- return inputValueDesc.prop._supset.apply(this, arguments);
1570
- },
1571
- get: function(){
1572
- return correctValue(this) || inputValueDesc.prop._supget.apply(this, arguments);
1573
- }
1574
- }
1575
- });
1576
-
1577
- inputValidityDesc = webshims.defineNodeNameProperty('input', 'validity', {
1578
- prop: {
1579
- writeable: false,
1580
- get: function(){
1581
- correctValue(this);
1582
- return inputValidityDesc.prop._supget.apply(this, arguments);
1583
- }
1584
- }
1585
- });
1586
-
1587
- $(document).on('change', function(e){
1588
- isChangeSubmit = true;
1589
- correctValue(e.target);
1590
- isChangeSubmit = false;
1591
- });
1592
-
1593
- })();
1594
-
1595
- $(document)
1596
- .on('focusin', function(e){
1597
- if( e.target && fixInputTypes[e.target.type] && !e.target.readOnly && !e.target.disabled ){
1598
- observe($(e.target));
1599
- }
1600
- })
1601
- ;
1602
-
1603
-
1604
- })();
1605
- }
1606
-
1607
- webshims.addReady(function(context, contextElem){
1608
- //start constrain-validation
1609
- var focusElem;
1610
- $('form', context)
1611
- .add(contextElem.filter('form'))
1612
- .bind('invalid', $.noop)
1613
- ;
1614
-
1615
- try {
1616
- if(context == document && !('form' in (document.activeElement || {}))) {
1617
- focusElem = $('input[autofocus], select[autofocus], textarea[autofocus]', context).eq(0).getShadowFocusElement()[0];
1618
- if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) {
1619
- focusElem.focus();
1620
- }
1621
- }
1622
- }
1623
- catch (er) {}
1624
-
1625
- });
1626
-
1627
- if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled){
1628
- (function(){
1629
- (function(prop, undefined){
1630
- $.prop = function(elem, name, value){
1631
- var ret;
1632
- if(elem && elem.nodeType == 1 && value === undefined && $.nodeName(elem, 'form') && elem.id){
1633
- ret = document.getElementsByName(name);
1634
- if(!ret || !ret.length){
1635
- ret = document.getElementById(name);
1636
- }
1637
- if(ret){
1638
- ret = $(ret).filter(function(){
1639
- return $.prop(this, 'form') == elem;
1640
- }).get();
1641
- if(ret.length){
1642
- return ret.length == 1 ? ret[0] : ret;
1643
- }
1644
- }
1645
- }
1646
- return prop.apply(this, arguments);
1647
- };
1648
- })($.prop, undefined);
1649
- var removeAddedElements = function(form){
1650
- var elements = $.data(form, 'webshimsAddedElements');
1651
- if(elements){
1652
- elements.remove();
1653
- $.removeData(form, 'webshimsAddedElements');
1654
- }
1655
- };
1656
- var rCRLF = /\r?\n/g,
1657
- rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
1658
- rselectTextarea = /^(?:select|textarea)/i;
1659
-
1660
- if(!Modernizr.formattribute){
1661
- webshims.defineNodeNamesProperty(['input', 'textarea', 'select', 'button', 'fieldset'], 'form', {
1662
- prop: {
1663
- get: function(){
1664
- var form = webshims.contentAttr(this, 'form');
1665
- if(form){
1666
- form = document.getElementById(form);
1667
- if(form && !$.nodeName(form, 'form')){
1668
- form = null;
1669
- }
1670
- }
1671
- return form || this.form;
1672
- },
1673
- writeable: false
1674
- }
1675
- });
1676
-
1677
-
1678
- webshims.defineNodeNamesProperty(['form'], 'elements', {
1679
- prop: {
1680
- get: function(){
1681
- var id = this.id;
1682
- var elements = $.makeArray(this.elements);
1683
- if(id){
1684
- elements = $(elements).add('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"], button[form="'+ id +'"], fieldset[form="'+ id +'"]').not('.webshims-visual-hide > *').get();
1685
- }
1686
- return elements;
1687
- },
1688
- writeable: false
1689
- }
1690
- });
1691
-
1692
-
1693
-
1694
- $(function(){
1695
- var stopPropagation = function(e){
1696
- e.stopPropagation();
1697
- };
1698
- $(document).on('submit', function(e){
1699
-
1700
- if(!e.isDefaultPrevented()){
1701
- var form = e.target;
1702
- var id = form.id;
1703
- var elements;
1704
-
1705
-
1706
- if(id){
1707
- removeAddedElements(form);
1708
-
1709
- elements = $('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"]')
1710
- .filter(function(){
1711
- return !this.disabled && this.name && this.form != form;
1712
- })
1713
- .clone()
1714
- ;
1715
- if(elements.length){
1716
- $.data(form, 'webshimsAddedElements', $('<div class="webshims-visual-hide" />').append(elements).appendTo(form));
1717
- setTimeout(function(){
1718
- removeAddedElements(form);
1719
- }, 9);
1720
- }
1721
- elements = null;
1722
- }
1723
- }
1724
- });
1725
-
1726
- $(document).on('click', function(e){
1727
- if(!e.isDefaultPrevented() && $(e.target).is('input[type="submit"][form], button[form], input[type="button"][form], input[type="image"][form], input[type="reset"][form]')){
1728
- var trueForm = $.prop(e.target, 'form');
1729
- var formIn = e.target.form;
1730
- var clone;
1731
- if(trueForm && trueForm != formIn){
1732
- clone = $(e.target)
1733
- .clone()
1734
- .removeAttr('form')
1735
- .addClass('webshims-visual-hide')
1736
- .on('click', stopPropagation)
1737
- .appendTo(trueForm)
1738
- ;
1739
- if(formIn){
1740
- e.preventDefault();
1741
- }
1742
- addSubmitBubbles(trueForm);
1743
- clone.trigger('click');
1744
- setTimeout(function(){
1745
- clone.remove();
1746
- clone = null;
1747
- }, 9);
1748
- }
1749
- }
1750
- });
1751
- });
1752
- }
1753
-
1754
- if(!Modernizr.fieldsetdisabled){
1755
- webshims.defineNodeNamesProperty(['fieldset'], 'elements', {
1756
- prop: {
1757
- get: function(){
1758
- //add listed elements without keygen, object, output
1759
- return $('input, select, textarea, button, fieldset', this).get() || [];
1760
- },
1761
- writeable: false
1762
- }
1763
- });
1764
- }
1765
-
1766
- $.fn.serializeArray = function() {
1767
- return this.map(function(){
1768
- var elements = $.prop(this, 'elements');
1769
- return elements ? $.makeArray( elements ) : this;
1770
- })
1771
- .filter(function(){
1772
- return this.name && !this.disabled &&
1773
- ( this.checked || rselectTextarea.test( this.nodeName ) ||
1774
- rinput.test( this.type ) );
1775
- })
1776
- .map(function( i, elem ){
1777
- var val = $( this ).val();
1778
-
1779
- return val == null ?
1780
- null :
1781
- $.isArray( val ) ?
1782
- $.map( val, function( val, i ){
1783
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1784
- }) :
1785
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1786
- }).get();
1787
- };
1788
-
1789
- })();
1790
- }
1791
-
1792
- try {
1793
- document.querySelector(':checked');
1794
- } catch(er){
1795
- (function(){
1796
- var checkInputs = {
1797
- radio: 1,
1798
- checkbox: 1
1799
- };
1800
- var selectChange = function(){
1801
- var options = this.options || [];
1802
- var i, len, option;
1803
- for(i = 0, len = options.length; i < len; i++){
1804
- option = $(options[i]);
1805
- option[$.prop(options[i], 'selected') ? 'addClass' : 'removeClass']('prop-checked');
1806
- }
1807
- };
1808
- var checkChange = function(){
1809
- var fn = $.prop(this, 'checked') ? 'addClass' : 'removeClass';
1810
- var className = this.className || '';
1811
- var parent;
1812
-
1813
- //IE8- has problems to update styles, we help
1814
- if( (className.indexOf('prop-checked') == -1) == (fn == 'addClass')){
1815
- $(this)[fn]('prop-checked');
1816
- if((parent = this.parentNode)){
1817
- parent.className = parent.className;
1818
- }
1819
- }
1820
- };
1821
-
1822
-
1823
- webshims.onNodeNamesPropertyModify('select', 'value', selectChange);
1824
- webshims.onNodeNamesPropertyModify('select', 'selectedIndex', selectChange);
1825
- webshims.onNodeNamesPropertyModify('option', 'selected', function(){
1826
- $(this).closest('select').each(selectChange);
1827
- });
1828
- webshims.onNodeNamesPropertyModify('input', 'checked', function(value, boolVal){
1829
- var type = this.type;
1830
- if(type == 'radio' && boolVal){
1831
- webshims.modules["form-core"].getGroupElements(this).each(checkChange);
1832
- } else if(checkInputs[type]) {
1833
- $(this).each(checkChange);
1834
- }
1835
- });
1836
-
1837
- $(document).on('change', function(e){
1838
-
1839
- if(checkInputs[e.target.type]){
1840
- if(e.target.type == 'radio'){
1841
- webshims.modules["form-core"].getGroupElements(e.target).each(checkChange);
1842
- } else {
1843
- $(e.target)[$.prop(e.target, 'checked') ? 'addClass' : 'removeClass']('prop-checked');
1844
- }
1845
- } else if(e.target.nodeName.toLowerCase() == 'select'){
1846
- $(e.target).each(selectChange);
1847
- }
1848
- });
1849
-
1850
- webshims.addReady(function(context, contextElem){
1851
- $('option, input', context)
1852
- .add(contextElem.filter('option, input'))
1853
- .each(function(){
1854
- var prop;
1855
- if(checkInputs[this.type]){
1856
- prop = 'checked';
1857
- } else if(this.nodeName.toLowerCase() == 'option'){
1858
- prop = 'selected';
1859
- }
1860
- if(prop){
1861
- $(this)[$.prop(this, prop) ? 'addClass' : 'removeClass']('prop-checked');
1862
- }
1863
-
1864
- })
1865
- ;
1866
- });
1867
- })();
1868
- }
1869
-
1870
- (function(){
1871
- Modernizr.textareaPlaceholder = !!('placeholder' in $('<textarea />')[0]);
1872
- var bustedTextarea = $.browser.webkit && Modernizr.textareaPlaceholder && webshims.browserVersion < 535;
1873
- if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder && !bustedTextarea){return;}
1874
-
1875
- var isOver = (webshims.cfg.forms.placeholderType == 'over');
1876
- var isResponsive = (webshims.cfg.forms.responsivePlaceholder);
1877
- var polyfillElements = ['textarea'];
1878
- if(!Modernizr.input.placeholder){
1879
- polyfillElements.push('input');
1880
- }
1881
-
1882
- var setSelection = function(elem){
1883
- try {
1884
- if(elem.setSelectionRange){
1885
- elem.setSelectionRange(0, 0);
1886
- return true;
1887
- } else if(elem.createTextRange){
1888
- var range = elem.createTextRange();
1889
- range.collapse(true);
1890
- range.moveEnd('character', 0);
1891
- range.moveStart('character', 0);
1892
- range.select();
1893
- return true;
1894
- }
1895
- } catch(er){}
1896
- };
1897
-
1898
- var hidePlaceholder = function(elem, data, value, _onFocus){
1899
- if(value === false){
1900
- value = $.prop(elem, 'value');
1901
- }
1902
- if(!isOver && elem.type != 'password'){
1903
- if(!value && _onFocus && setSelection(elem)){
1904
- var selectTimer = setTimeout(function(){
1905
- setSelection(elem);
1906
- }, 9);
1907
- $(elem)
1908
- .off('.placeholderremove')
1909
- .on({
1910
- 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
1911
- if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1912
- elem.value = $.prop(elem, 'value');
1913
- data.box.removeClass('placeholder-visible');
1914
- clearTimeout(selectTimer);
1915
- $(elem).unbind('.placeholderremove');
1916
- },
1917
- 'mousedown.placeholderremove drag.placeholderremove select.placeholderremove': function(e){
1918
- setSelection(elem);
1919
- clearTimeout(selectTimer);
1920
- selectTimer = setTimeout(function(){
1921
- setSelection(elem);
1922
- }, 9);
1923
- },
1924
- 'blur.placeholderremove': function(){
1925
- clearTimeout(selectTimer);
1926
- $(elem).unbind('.placeholderremove');
1927
- }
1928
- })
1929
- ;
1930
- return;
1931
- }
1932
- elem.value = value;
1933
- } else if(!value && _onFocus){
1934
- $(elem)
1935
- .off('.placeholderremove')
1936
- .on({
1937
- 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
1938
- if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1939
- data.box.removeClass('placeholder-visible');
1940
- $(elem).unbind('.placeholderremove');
1941
- },
1942
- 'blur.placeholderremove': function(){
1943
- $(elem).unbind('.placeholderremove');
1944
- }
1945
- })
1946
- ;
1947
- return;
1948
- }
1949
- data.box.removeClass('placeholder-visible');
1950
- },
1951
- showPlaceholder = function(elem, data, placeholderTxt){
1952
- if(placeholderTxt === false){
1953
- placeholderTxt = $.prop(elem, 'placeholder');
1954
- }
1955
-
1956
- if(!isOver && elem.type != 'password'){
1957
- elem.value = placeholderTxt;
1958
- }
1959
- data.box.addClass('placeholder-visible');
1960
- },
1961
- changePlaceholderVisibility = function(elem, value, placeholderTxt, data, type){
1962
- if(!data){
1963
- data = $.data(elem, 'placeHolder');
1964
- if(!data){return;}
1965
- }
1966
- $(elem).unbind('.placeholderremove');
1967
- if(type == 'focus' || (!type && $(elem).is(':focus'))){
1968
- if(elem.type == 'password' || isOver || $(elem).hasClass('placeholder-visible')){
1969
- hidePlaceholder(elem, data, '', true);
1970
- }
1971
- return;
1972
- }
1973
- if(value === false){
1974
- value = $.prop(elem, 'value');
1975
- }
1976
- if(value){
1977
- hidePlaceholder(elem, data, value);
1978
- return;
1979
- }
1980
- if(placeholderTxt === false){
1981
- placeholderTxt = $.attr(elem, 'placeholder') || '';
1982
- }
1983
- if(placeholderTxt && !value){
1984
- showPlaceholder(elem, data, placeholderTxt);
1985
- } else {
1986
- hidePlaceholder(elem, data, value);
1987
- }
1988
- },
1989
- createPlaceholder = function(elem){
1990
- elem = $(elem);
1991
- var id = elem.prop('id'),
1992
- hasLabel = !!(elem.prop('title') || elem.attr('aria-labelledby'))
1993
- ;
1994
- if(!hasLabel && id){
1995
- hasLabel = !!( $('label[for="'+ id +'"]', elem[0].form)[0] );
1996
- }
1997
- if(!hasLabel){
1998
- if(!id){
1999
- id = $.webshims.getID(elem);
2000
- }
2001
- hasLabel = !!($('label #'+ id)[0]);
2002
- }
2003
- return $( hasLabel ? '<span class="placeholder-text"></span>' : '<label for="'+ id +'" class="placeholder-text"></label>');
2004
- },
2005
- pHolder = (function(){
2006
- var delReg = /\n|\r|\f|\t/g,
2007
- allowedPlaceholder = {
2008
- text: 1,
2009
- search: 1,
2010
- url: 1,
2011
- email: 1,
2012
- password: 1,
2013
- tel: 1
2014
- }
2015
- ;
2016
-
2017
- return {
2018
- create: function(elem){
2019
- var data = $.data(elem, 'placeHolder');
2020
- var form;
2021
- var responsiveElem;
2022
- if(data){return data;}
2023
- data = $.data(elem, 'placeHolder', {});
2024
-
2025
- $(elem).on('focus.placeholder blur.placeholder', function(e){
2026
- changePlaceholderVisibility(this, false, false, data, e.type );
2027
- data.box[e.type == 'focus' ? 'addClass' : 'removeClass']('placeholder-focused');
2028
- });
2029
-
2030
- if((form = $.prop(elem, 'form'))){
2031
- $(form).on('reset.placeholder', function(e){
2032
- setTimeout(function(){
2033
- changePlaceholderVisibility(elem, false, false, data, e.type );
2034
- }, 0);
2035
- });
2036
- }
2037
-
2038
- if(elem.type == 'password' || isOver){
2039
- data.text = createPlaceholder(elem);
2040
- if(isResponsive || $(elem).is('.responsive-width') || (elem.currentStyle || {width: ''}).width.indexOf('%') != -1){
2041
- responsiveElem = true;
2042
- data.box = data.text;
2043
- } else {
2044
- data.box = $(elem)
2045
- .wrap('<span class="placeholder-box placeholder-box-'+ (elem.nodeName || '').toLowerCase() +' placeholder-box-'+$.css(elem, 'float')+'" />')
2046
- .parent()
2047
- ;
2048
- }
2049
- data.text
2050
- .insertAfter(elem)
2051
- .on('mousedown.placeholder', function(){
2052
- changePlaceholderVisibility(this, false, false, data, 'focus');
2053
- try {
2054
- setTimeout(function(){
2055
- elem.focus();
2056
- }, 0);
2057
- } catch(e){}
2058
- return false;
2059
- })
2060
- ;
2061
-
2062
-
2063
- $.each(['lineHeight', 'fontSize', 'fontFamily', 'fontWeight'], function(i, style){
2064
- var prop = $.css(elem, style);
2065
- if(data.text.css(style) != prop){
2066
- data.text.css(style, prop);
2067
- }
2068
- });
2069
- $.each(['Left', 'Top'], function(i, side){
2070
- var size = (parseInt($.css(elem, 'padding'+ side), 10) || 0) + Math.max((parseInt($.css(elem, 'margin'+ side), 10) || 0), 0) + (parseInt($.css(elem, 'border'+ side +'Width'), 10) || 0);
2071
- data.text.css('padding'+ side, size);
2072
- });
2073
-
2074
- $(elem)
2075
- .on('updateshadowdom', function(){
2076
- var height, width;
2077
- if((width = elem.offsetWidth) || (height = elem.offsetHeight)){
2078
- data.text
2079
- .css({
2080
- width: width,
2081
- height: height
2082
- })
2083
- .css($(elem).position())
2084
- ;
2085
- }
2086
- })
2087
- .triggerHandler('updateshadowdom')
2088
- ;
2089
-
2090
- } else {
2091
- var reset = function(e){
2092
- if($(elem).hasClass('placeholder-visible')){
2093
- hidePlaceholder(elem, data, '');
2094
- if(e && e.type == 'submit'){
2095
- setTimeout(function(){
2096
- if(e.isDefaultPrevented()){
2097
- changePlaceholderVisibility(elem, false, false, data );
2098
- }
2099
- }, 9);
2100
- }
2101
- }
2102
- };
2103
-
2104
- $(window).on('beforeunload', reset);
2105
- data.box = $(elem);
2106
- if(form){
2107
- $(form).submit(reset);
2108
- }
2109
- }
2110
-
2111
- return data;
2112
- },
2113
- update: function(elem, val){
2114
- var type = ($.attr(elem, 'type') || $.prop(elem, 'type') || '').toLowerCase();
2115
- if(!allowedPlaceholder[type] && !$.nodeName(elem, 'textarea')){
2116
- webshims.error('placeholder not allowed on input[type="'+type+'"]');
2117
- if(type == 'date'){
2118
- webshims.error('but you can use data-placeholder for input[type="date"]');
2119
- }
2120
- return;
2121
- }
2122
-
2123
-
2124
- var data = pHolder.create(elem);
2125
- if(data.text){
2126
- data.text.text(val);
2127
- }
2128
-
2129
- changePlaceholderVisibility(elem, false, val, data);
2130
- }
2131
- };
2132
- })()
2133
- ;
2134
-
2135
- $.webshims.publicMethods = {
2136
- pHolder: pHolder
2137
- };
2138
- polyfillElements.forEach(function(nodeName){
2139
- var desc = webshims.defineNodeNameProperty(nodeName, 'placeholder', {
2140
- attr: {
2141
- set: function(val){
2142
- var elem = this;
2143
- if(bustedTextarea){
2144
- webshims.data(elem, 'textareaPlaceholder', val);
2145
- elem.placeholder = '';
2146
- } else {
2147
- webshims.contentAttr(elem, 'placeholder', val);
2148
- }
2149
- pHolder.update(elem, val);
2150
- },
2151
- get: function(){
2152
- var ret = (bustedTextarea) ? webshims.data(this, 'textareaPlaceholder') : '';
2153
- return ret || webshims.contentAttr(this, 'placeholder');
2154
- }
2155
- },
2156
- reflect: true,
2157
- initAttr: true
2158
- });
2159
- });
2160
-
2161
-
2162
- polyfillElements.forEach(function(name){
2163
- var placeholderValueDesc = {};
2164
- var desc;
2165
- ['attr', 'prop'].forEach(function(propType){
2166
- placeholderValueDesc[propType] = {
2167
- set: function(val){
2168
- var elem = this;
2169
- var placeholder;
2170
- if(bustedTextarea){
2171
- placeholder = webshims.data(elem, 'textareaPlaceholder');
2172
- }
2173
- if(!placeholder){
2174
- placeholder = webshims.contentAttr(elem, 'placeholder');
2175
- }
2176
- $.removeData(elem, 'cachedValidity');
2177
- var ret = desc[propType]._supset.call(elem, val);
2178
- if(placeholder && 'value' in elem){
2179
- changePlaceholderVisibility(elem, val, placeholder);
2180
- }
2181
- return ret;
2182
- },
2183
- get: function(){
2184
- var elem = this;
2185
- return $(elem).hasClass('placeholder-visible') ? '' : desc[propType]._supget.call(elem);
2186
- }
2187
- };
2188
- });
2189
- desc = webshims.defineNodeNameProperty(name, 'value', placeholderValueDesc);
2190
- });
2191
-
2192
- })();
2193
-
2194
- (function(){
2195
- var doc = document;
2196
- if( 'value' in document.createElement('output') ){return;}
2197
-
2198
- webshims.defineNodeNameProperty('output', 'value', {
2199
- prop: {
2200
- set: function(value){
2201
- var setVal = $.data(this, 'outputShim');
2202
- if(!setVal){
2203
- setVal = outputCreate(this);
2204
- }
2205
- setVal(value);
2206
- },
2207
- get: function(){
2208
- return webshims.contentAttr(this, 'value') || $(this).text() || '';
2209
- }
2210
- }
2211
- });
2212
-
2213
-
2214
- webshims.onNodeNamesPropertyModify('input', 'value', function(value, boolVal, type){
2215
- if(type == 'removeAttr'){return;}
2216
- var setVal = $.data(this, 'outputShim');
2217
- if(setVal){
2218
- setVal(value);
2219
- }
2220
- });
2221
-
2222
- var outputCreate = function(elem){
2223
- if(elem.getAttribute('aria-live')){return;}
2224
- elem = $(elem);
2225
- var value = (elem.text() || '').trim();
2226
- var id = elem.attr('id');
2227
- var htmlFor = elem.attr('for');
2228
- var shim = $('<input class="output-shim" type="text" disabled name="'+ (elem.attr('name') || '')+'" value="'+value+'" style="display: none !important;" />').insertAfter(elem);
2229
- var form = shim[0].form || doc;
2230
- var setValue = function(val){
2231
- shim[0].value = val;
2232
- val = shim[0].value;
2233
- elem.text(val);
2234
- webshims.contentAttr(elem[0], 'value', val);
2235
- };
2236
-
2237
- elem[0].defaultValue = value;
2238
- webshims.contentAttr(elem[0], 'value', value);
2239
-
2240
- elem.attr({'aria-live': 'polite'});
2241
- if(id){
2242
- shim.attr('id', id);
2243
- elem.attr('aria-labelledby', webshims.getID($('label[for="'+id+'"]', form)));
2244
- }
2245
- if(htmlFor){
2246
- id = webshims.getID(elem);
2247
- htmlFor.split(' ').forEach(function(control){
2248
- control = document.getElementById(control);
2249
- if(control){
2250
- control.setAttribute('aria-controls', id);
2251
- }
2252
- });
2253
- }
2254
- elem.data('outputShim', setValue );
2255
- shim.data('outputShim', setValue );
2256
- return setValue;
2257
- };
2258
-
2259
- webshims.addReady(function(context, contextElem){
2260
- $('output', context).add(contextElem.filter('output')).each(function(){
2261
- outputCreate(this);
2262
- });
2263
- });
2264
-
2265
- /*
2266
- * Implements input event in all browsers
2267
- */
2268
- (function(){
2269
- var noInputTriggerEvts = {updateInput: 1, input: 1},
2270
- noInputTypes = {
2271
- radio: 1,
2272
- checkbox: 1,
2273
- submit: 1,
2274
- button: 1,
2275
- image: 1,
2276
- reset: 1,
2277
- file: 1
2278
-
2279
- //pro forma
2280
- ,color: 1
2281
- //,range: 1
2282
- },
2283
- observe = function(input){
2284
- var timer,
2285
- lastVal = input.prop('value'),
2286
- trigger = function(e){
2287
- //input === null
2288
- if(!input){return;}
2289
- var newVal = input.prop('value');
2290
-
2291
- if(newVal !== lastVal){
2292
- lastVal = newVal;
2293
- if(!e || !noInputTriggerEvts[e.type]){
2294
- webshims.triggerInlineForm && webshims.triggerInlineForm(input[0], 'input');
2295
- }
2296
- }
2297
- },
2298
- extraTimer,
2299
- extraTest = function(){
2300
- clearTimeout(extraTimer);
2301
- extraTimer = setTimeout(trigger, 9);
2302
- },
2303
- unbind = function(){
2304
- input.unbind('focusout', unbind).unbind('keyup keypress keydown paste cut', extraTest).unbind('input change updateInput', trigger);
2305
- clearInterval(timer);
2306
- setTimeout(function(){
2307
- trigger();
2308
- input = null;
2309
- }, 1);
2310
-
2311
- }
2312
- ;
2313
-
2314
- clearInterval(timer);
2315
- timer = setInterval(trigger, 99);
2316
- extraTest();
2317
- input.on({
2318
- 'keyup keypress keydown paste cut': extraTest,
2319
- focusout: unbind,
2320
- 'input updateInput change': trigger
2321
- });
2322
- }
2323
- ;
2324
- if($.event.customEvent){
2325
- $.event.customEvent.updateInput = true;
2326
- }
2327
-
2328
- $(doc)
2329
- .on('focusin', function(e){
2330
- if( e.target && e.target.type && !e.target.readOnly && !e.target.disabled && (e.target.nodeName || '').toLowerCase() == 'input' && !noInputTypes[e.target.type] ){
2331
- observe($(e.target));
2332
- }
2333
- })
2334
- ;
2335
- })();
2336
- })();
2337
-
2338
- }); //webshims.ready end
2339
- }//end formvalidation
1
+ //additional tests for partial implementation of forms features
2
+ (function($){
3
+ "use strict";
4
+ var Modernizr = window.Modernizr;
5
+ var webshims = $.webshims;
6
+ var bugs = webshims.bugs;
7
+ var form = $('<form action="#" style="width: 1px; height: 1px; overflow: hidden;"><select name="b" required="" /><input required="" name="a" /></form>');
8
+ var testRequiredFind = function(){
9
+ if(form[0].querySelector){
10
+ try {
11
+ bugs.findRequired = !(form[0].querySelector('select:required'));
12
+ } catch(er){
13
+ bugs.findRequired = false;
14
+ }
15
+ }
16
+ };
17
+ var inputElem = $('input', form).eq(0);
18
+ var onDomextend = function(fn){
19
+ webshims.loader.loadList(['dom-extend']);
20
+ webshims.ready('dom-extend', fn);
21
+ };
22
+
23
+ bugs.findRequired = false;
24
+ bugs.validationMessage = false;
25
+
26
+ webshims.capturingEventPrevented = function(e){
27
+ if(!e._isPolyfilled){
28
+ var isDefaultPrevented = e.isDefaultPrevented;
29
+ var preventDefault = e.preventDefault;
30
+ e.preventDefault = function(){
31
+ clearTimeout($.data(e.target, e.type + 'DefaultPrevented'));
32
+ $.data(e.target, e.type + 'DefaultPrevented', setTimeout(function(){
33
+ $.removeData(e.target, e.type + 'DefaultPrevented');
34
+ }, 30));
35
+ return preventDefault.apply(this, arguments);
36
+ };
37
+ e.isDefaultPrevented = function(){
38
+ return !!(isDefaultPrevented.apply(this, arguments) || $.data(e.target, e.type + 'DefaultPrevented') || false);
39
+ };
40
+ e._isPolyfilled = true;
41
+ }
42
+ };
43
+
44
+ if(!Modernizr.formvalidation || bugs.bustedValidity){
45
+ testRequiredFind();
46
+ return;
47
+ }
48
+
49
+ //create delegatable events
50
+ webshims.capturingEvents(['input']);
51
+ webshims.capturingEvents(['invalid'], true);
52
+
53
+ if(window.opera || window.testGoodWithFix){
54
+
55
+ form.appendTo('head');
56
+
57
+ testRequiredFind();
58
+ bugs.validationMessage = !(inputElem.prop('validationMessage'));
59
+
60
+ webshims.reTest(['form-native-extend', 'form-message']);
61
+
62
+ form.remove();
63
+
64
+ $(function(){
65
+ onDomextend(function(){
66
+
67
+ //Opera shows native validation bubbles in case of input.checkValidity()
68
+ // Opera 11.6/12 hasn't fixed this issue right, it's buggy
69
+ var preventDefault = function(e){
70
+ e.preventDefault();
71
+ };
72
+
73
+ ['form', 'input', 'textarea', 'select'].forEach(function(name){
74
+ var desc = webshims.defineNodeNameProperty(name, 'checkValidity', {
75
+ prop: {
76
+ value: function(){
77
+ if (!webshims.fromSubmit) {
78
+ $(this).on('invalid.checkvalidity', preventDefault);
79
+ }
80
+
81
+ webshims.fromCheckValidity = true;
82
+ var ret = desc.prop._supvalue.apply(this, arguments);
83
+ if (!webshims.fromSubmit) {
84
+ $(this).unbind('invalid.checkvalidity', preventDefault);
85
+ }
86
+ webshims.fromCheckValidity = false;
87
+ return ret;
88
+ }
89
+ }
90
+ });
91
+ });
92
+
93
+ });
94
+ });
95
+ }
96
+
97
+ if($.browser.webkit && !webshims.bugs.bustedValidity){
98
+ (function(){
99
+ var elems = /^(?:textarea|input)$/i;
100
+ var form = false;
101
+
102
+ document.addEventListener('contextmenu', function(e){
103
+ if(elems.test( e.target.nodeName || '') && (form = e.target.form)){
104
+ setTimeout(function(){
105
+ form = false;
106
+ }, 1);
107
+ }
108
+ }, false);
109
+
110
+ $(window).on('invalid', function(e){
111
+ if(e.originalEvent && form && form == e.target.form){
112
+ e.wrongWebkitInvalid = true;
113
+ e.stopImmediatePropagation();
114
+ }
115
+ });
116
+ })();
117
+ }
118
+ })(jQuery);
119
+
120
+ jQuery.webshims.register('form-core', function($, webshims, window, document, undefined, options){
121
+ "use strict";
122
+
123
+ var groupTypes = {radio: 1};
124
+ var checkTypes = {checkbox: 1, radio: 1};
125
+ var emptyJ = $([]);
126
+ var bugs = webshims.bugs;
127
+ var getGroupElements = function(elem){
128
+ elem = $(elem);
129
+ var name;
130
+ var form;
131
+ var ret = emptyJ;
132
+ if(groupTypes[elem[0].type]){
133
+ form = elem.prop('form');
134
+ name = elem[0].name;
135
+ if(!name){
136
+ ret = elem;
137
+ } else if(form){
138
+ ret = $(form[name]);
139
+ } else {
140
+ ret = $(document.getElementsByName(name)).filter(function(){
141
+ return !$.prop(this, 'form');
142
+ });
143
+ }
144
+ ret = ret.filter('[type="radio"]');
145
+ }
146
+ return ret;
147
+ };
148
+
149
+ var getContentValidationMessage = webshims.getContentValidationMessage = function(elem, validity, key){
150
+ var message = $(elem).data('errormessage') || elem.getAttribute('x-moz-errormessage') || '';
151
+ if(key && message[key]){
152
+ message = message[key];
153
+ }
154
+ if(typeof message == 'object'){
155
+ validity = validity || $.prop(elem, 'validity') || {valid: 1};
156
+ if(!validity.valid){
157
+ $.each(validity, function(name, prop){
158
+ if(prop && name != 'valid' && message[name]){
159
+ message = message[name];
160
+ return false;
161
+ }
162
+ });
163
+ }
164
+ }
165
+
166
+ if(typeof message == 'object'){
167
+ message = message.defaultMessage;
168
+ }
169
+ return message || '';
170
+ };
171
+
172
+ /*
173
+ * Selectors for all browsers
174
+ */
175
+ var rangeTypes = {number: 1, range: 1, date: 1/*, time: 1, 'datetime-local': 1, datetime: 1, month: 1, week: 1*/};
176
+ var hasInvalid = function(elem){
177
+ var ret = false;
178
+ $($.prop(elem, 'elements')).each(function(){
179
+ ret = $(this).is(':invalid');
180
+ if(ret){
181
+ return false;
182
+ }
183
+ });
184
+ return ret;
185
+ };
186
+ $.extend($.expr[":"], {
187
+ "valid-element": function(elem){
188
+ return $.nodeName(elem, 'form') ? !hasInvalid(elem) :!!($.prop(elem, 'willValidate') && isValid(elem));
189
+ },
190
+ "invalid-element": function(elem){
191
+ return $.nodeName(elem, 'form') ? hasInvalid(elem) : !!($.prop(elem, 'willValidate') && !isValid(elem));
192
+ },
193
+ "required-element": function(elem){
194
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required'));
195
+ },
196
+ "user-error": function(elem){
197
+ return ($.prop(elem, 'willValidate') && $(elem).hasClass('user-error'));
198
+ },
199
+ "optional-element": function(elem){
200
+ return !!($.prop(elem, 'willValidate') && $.prop(elem, 'required') === false);
201
+ },
202
+ "in-range": function(elem){
203
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
204
+ return false;
205
+ }
206
+ var val = $.prop(elem, 'validity');
207
+ return !!(val && !val.rangeOverflow && !val.rangeUnderflow);
208
+ },
209
+ "out-of-range": function(elem){
210
+ if(!rangeTypes[$.prop(elem, 'type')] || !$.prop(elem, 'willValidate')){
211
+ return false;
212
+ }
213
+ var val = $.prop(elem, 'validity');
214
+ return !!(val && (val.rangeOverflow || val.rangeUnderflow));
215
+ }
216
+
217
+ });
218
+
219
+ ['valid', 'invalid', 'required', 'optional'].forEach(function(name){
220
+ $.expr[":"][name] = $.expr.filters[name+"-element"];
221
+ });
222
+
223
+
224
+ $.expr[":"].focus = function( elem ) {
225
+ try {
226
+ var doc = elem.ownerDocument;
227
+ return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus());
228
+ } catch(e){}
229
+ return false;
230
+ };
231
+
232
+ var customEvents = $.event.customEvent || {};
233
+ var isValid = function(elem){
234
+ return ($.prop(elem, 'validity') || {valid: 1}).valid;
235
+ };
236
+
237
+ if (bugs.bustedValidity || bugs.findRequired) {
238
+ (function(){
239
+ var find = $.find;
240
+ var matchesSelector = $.find.matchesSelector;
241
+
242
+ var regExp = /(\:valid|\:invalid|\:optional|\:required|\:in-range|\:out-of-range)(?=[\s\[\~\.\+\>\:\#*]|$)/ig;
243
+ var regFn = function(sel){
244
+ return sel + '-element';
245
+ };
246
+
247
+ $.find = (function(){
248
+ var slice = Array.prototype.slice;
249
+ var fn = function(sel){
250
+ var ar = arguments;
251
+ ar = slice.call(ar, 1, ar.length);
252
+ ar.unshift(sel.replace(regExp, regFn));
253
+ return find.apply(this, ar);
254
+ };
255
+ for (var i in find) {
256
+ if(find.hasOwnProperty(i)){
257
+ fn[i] = find[i];
258
+ }
259
+ }
260
+ return fn;
261
+ })();
262
+ if(!Modernizr.prefixed || Modernizr.prefixed("matchesSelector", document.documentElement)){
263
+ $.find.matchesSelector = function(node, expr){
264
+ expr = expr.replace(regExp, regFn);
265
+ return matchesSelector.call(this, node, expr);
266
+ };
267
+ }
268
+
269
+ })();
270
+ }
271
+
272
+ //ToDo needs testing
273
+ var oldAttr = $.prop;
274
+ var changeVals = {selectedIndex: 1, value: 1, checked: 1, disabled: 1, readonly: 1};
275
+ $.prop = function(elem, name, val){
276
+ var ret = oldAttr.apply(this, arguments);
277
+ if(elem && 'form' in elem && changeVals[name] && val !== undefined && $(elem).hasClass(invalidClass)){
278
+ if(isValid(elem)){
279
+ $(elem).getShadowElement().removeClass(invalidClasses);
280
+ if(name == 'checked' && val) {
281
+ getGroupElements(elem).not(elem).removeClass(invalidClasses).removeAttr('aria-invalid');
282
+ }
283
+ }
284
+ }
285
+ return ret;
286
+ };
287
+
288
+ var returnValidityCause = function(validity, elem){
289
+ var ret;
290
+ $.each(validity, function(name, value){
291
+ if(value){
292
+ ret = (name == 'customError') ? $.prop(elem, 'validationMessage') : name;
293
+ return false;
294
+ }
295
+ });
296
+ return ret;
297
+ };
298
+
299
+ var isInGroup = function(name){
300
+ var ret;
301
+ try {
302
+ ret = document.activeElement.name === name;
303
+ } catch(e){}
304
+ return ret;
305
+ };
306
+ /* form-ui-invalid/form-ui-valid are deprecated. use user-error/user-succes instead */
307
+ var invalidClass = 'user-error';
308
+ var invalidClasses = 'user-error form-ui-invalid';
309
+ var validClass = 'user-success';
310
+ var validClasses = 'user-success form-ui-valid';
311
+ var switchValidityClass = function(e){
312
+ var elem, timer;
313
+ if(!e.target){return;}
314
+ elem = $(e.target).getNativeElement()[0];
315
+ if(elem.type == 'submit' || !$.prop(elem, 'willValidate')){return;}
316
+ timer = $.data(elem, 'webshimsswitchvalidityclass');
317
+ var switchClass = function(){
318
+ if(e.type == 'focusout' && elem.type == 'radio' && isInGroup(elem.name)){return;}
319
+ var validity = $.prop(elem, 'validity');
320
+ var shadowElem = $(elem).getShadowElement();
321
+ var addClass, removeClass, trigger, generaltrigger, validityCause;
322
+
323
+ $(elem).trigger('refreshCustomValidityRules');
324
+ if(validity.valid){
325
+ if(!shadowElem.hasClass(validClass)){
326
+ addClass = validClasses;
327
+ removeClass = invalidClasses;
328
+ generaltrigger = 'changedvaliditystate';
329
+ trigger = 'changedvalid';
330
+ if(checkTypes[elem.type] && elem.checked){
331
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass).removeAttr('aria-invalid');
332
+ }
333
+ $.removeData(elem, 'webshimsinvalidcause');
334
+ }
335
+ } else {
336
+ validityCause = returnValidityCause(validity, elem);
337
+ if($.data(elem, 'webshimsinvalidcause') != validityCause){
338
+ $.data(elem, 'webshimsinvalidcause', validityCause);
339
+ generaltrigger = 'changedvaliditystate';
340
+ }
341
+ if(!shadowElem.hasClass(invalidClass)){
342
+ addClass = invalidClasses;
343
+ removeClass = validClasses;
344
+ if (checkTypes[elem.type] && !elem.checked) {
345
+ getGroupElements(elem).not(elem).removeClass(removeClass).addClass(addClass);
346
+ }
347
+ trigger = 'changedinvalid';
348
+ }
349
+ }
350
+ if(addClass){
351
+ shadowElem.addClass(addClass).removeClass(removeClass);
352
+ //jQuery 1.6.1 IE9 bug (doubble trigger bug)
353
+ setTimeout(function(){
354
+ $(elem).trigger(trigger);
355
+ }, 0);
356
+ }
357
+ if(generaltrigger){
358
+ setTimeout(function(){
359
+ $(elem).trigger(generaltrigger);
360
+ }, 0);
361
+ }
362
+ $.removeData(e.target, 'webshimsswitchvalidityclass');
363
+ };
364
+
365
+ if(timer){
366
+ clearTimeout(timer);
367
+ }
368
+ if(e.type == 'refreshvalidityui'){
369
+ switchClass();
370
+ } else {
371
+ $.data(elem, 'webshimsswitchvalidityclass', setTimeout(switchClass, 9));
372
+ }
373
+ };
374
+
375
+ $(document).on(options.validityUIEvents || 'focusout change refreshvalidityui', switchValidityClass);
376
+ customEvents.changedvaliditystate = true;
377
+ customEvents.refreshCustomValidityRules = true;
378
+ customEvents.changedvalid = true;
379
+ customEvents.changedinvalid = true;
380
+ customEvents.refreshvalidityui = true;
381
+
382
+
383
+ webshims.triggerInlineForm = function(elem, event){
384
+ $(elem).trigger(event);
385
+ };
386
+
387
+ webshims.modules["form-core"].getGroupElements = getGroupElements;
388
+
389
+
390
+ var setRoot = function(){
391
+ webshims.scrollRoot = ($.browser.webkit || document.compatMode == 'BackCompat') ?
392
+ $(document.body) :
393
+ $(document.documentElement)
394
+ ;
395
+ };
396
+ setRoot();
397
+ webshims.ready('DOM', setRoot);
398
+
399
+ webshims.getRelOffset = function(posElem, relElem){
400
+ posElem = $(posElem);
401
+ var offset = $(relElem).offset();
402
+ var bodyOffset;
403
+ $.swap($(posElem)[0], {visibility: 'hidden', display: 'inline-block', left: 0, top: 0}, function(){
404
+ bodyOffset = posElem.offset();
405
+ });
406
+ offset.top -= bodyOffset.top;
407
+ offset.left -= bodyOffset.left;
408
+ return offset;
409
+ };
410
+
411
+ /* some extra validation UI */
412
+ webshims.validityAlert = (function(){
413
+ var alertElem = (!$.browser.msie || parseInt($.browser.version, 10) > 7) ? 'span' : 'label';
414
+ var errorBubble;
415
+ var hideTimer = false;
416
+ var focusTimer = false;
417
+ var resizeTimer = false;
418
+ var boundHide;
419
+
420
+ var api = {
421
+ hideDelay: 5000,
422
+
423
+ showFor: function(elem, message, noFocusElem, noBubble){
424
+ api._create();
425
+ elem = $(elem);
426
+ var visual = $(elem).getShadowElement();
427
+ var offset = api.getOffsetFromBody(visual);
428
+ api.clear();
429
+ if(noBubble){
430
+ this.hide();
431
+ } else {
432
+ this.getMessage(elem, message);
433
+ this.position(visual, offset);
434
+
435
+ this.show();
436
+ if(this.hideDelay){
437
+ hideTimer = setTimeout(boundHide, this.hideDelay);
438
+ }
439
+ $(window)
440
+ .on('resize.validityalert', function(){
441
+ clearTimeout(resizeTimer);
442
+ resizeTimer = setTimeout(function(){
443
+ api.position(visual);
444
+ }, 9);
445
+ })
446
+ ;
447
+ }
448
+
449
+ if(!noFocusElem){
450
+ this.setFocus(visual, offset);
451
+ }
452
+ },
453
+ getOffsetFromBody: function(elem){
454
+ return webshims.getRelOffset(errorBubble, elem);
455
+ },
456
+ setFocus: function(visual, offset){
457
+ var focusElem = $(visual).getShadowFocusElement();
458
+ var scrollTop = webshims.scrollRoot.scrollTop();
459
+ var elemTop = ((offset || focusElem.offset()).top) - 30;
460
+ var smooth;
461
+
462
+ if(webshims.getID && alertElem == 'label'){
463
+ errorBubble.attr('for', webshims.getID(focusElem));
464
+ }
465
+
466
+ if(scrollTop > elemTop){
467
+ webshims.scrollRoot.animate(
468
+ {scrollTop: elemTop - 5},
469
+ {
470
+ queue: false,
471
+ duration: Math.max( Math.min( 600, (scrollTop - elemTop) * 1.5 ), 80 )
472
+ }
473
+ );
474
+ smooth = true;
475
+ }
476
+ try {
477
+ focusElem[0].focus();
478
+ } catch(e){}
479
+ if(smooth){
480
+ webshims.scrollRoot.scrollTop(scrollTop);
481
+ setTimeout(function(){
482
+ webshims.scrollRoot.scrollTop(scrollTop);
483
+ }, 0);
484
+ }
485
+ setTimeout(function(){
486
+ $(document).on('focusout.validityalert', boundHide);
487
+ }, 10);
488
+ },
489
+ getMessage: function(elem, message){
490
+ if (!message) {
491
+ message = getContentValidationMessage(elem[0]) || elem.prop('validationMessage');
492
+ }
493
+ if (message) {
494
+ $('span.va-box', errorBubble).text(message);
495
+ }
496
+ else {
497
+ this.hide();
498
+ }
499
+ },
500
+ position: function(elem, offset){
501
+ offset = offset ? $.extend({}, offset) : api.getOffsetFromBody(elem);
502
+ offset.top += elem.outerHeight();
503
+ errorBubble.css(offset);
504
+ },
505
+ show: function(){
506
+ if(errorBubble.css('display') === 'none'){
507
+ errorBubble.css({opacity: 0}).show();
508
+ }
509
+ errorBubble.addClass('va-visible').fadeTo(400, 1);
510
+ },
511
+ hide: function(){
512
+ errorBubble.removeClass('va-visible').fadeOut();
513
+ },
514
+ clear: function(){
515
+ clearTimeout(focusTimer);
516
+ clearTimeout(hideTimer);
517
+ $(document).unbind('.validityalert');
518
+ $(window).unbind('.validityalert');
519
+ errorBubble.stop().removeAttr('for');
520
+ },
521
+ _create: function(){
522
+ if(errorBubble){return;}
523
+ 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'});
524
+ webshims.ready('DOM', function(){
525
+ errorBubble.appendTo('body');
526
+ if($.fn.bgIframe && $.browser.msie && parseInt($.browser.version, 10) < 7){
527
+ errorBubble.bgIframe();
528
+ }
529
+ });
530
+ }
531
+ };
532
+
533
+
534
+ boundHide = $.proxy(api, 'hide');
535
+
536
+ return api;
537
+ })();
538
+
539
+
540
+ /* extension, but also used to fix native implementation workaround/bugfixes */
541
+ (function(){
542
+ var firstEvent,
543
+ invalids = [],
544
+ stopSubmitTimer,
545
+ form
546
+ ;
547
+
548
+ $(document).on('invalid', function(e){
549
+ if(e.wrongWebkitInvalid){return;}
550
+ var jElm = $(e.target);
551
+ var shadowElem = jElm.getShadowElement();
552
+ if(!shadowElem.hasClass(invalidClass)){
553
+ shadowElem.addClass(invalidClasses).removeClass(validClasses);
554
+ setTimeout(function(){
555
+ $(e.target).trigger('changedinvalid').trigger('changedvaliditystate');
556
+ }, 0);
557
+ }
558
+
559
+ if(!firstEvent){
560
+ //trigger firstinvalid
561
+ firstEvent = $.Event('firstinvalid');
562
+ firstEvent.isInvalidUIPrevented = e.isDefaultPrevented;
563
+ var firstSystemInvalid = $.Event('firstinvalidsystem');
564
+ $(document).triggerHandler(firstSystemInvalid, {element: e.target, form: e.target.form, isInvalidUIPrevented: e.isDefaultPrevented});
565
+ jElm.trigger(firstEvent);
566
+ }
567
+
568
+ //if firstinvalid was prevented all invalids will be also prevented
569
+ if( firstEvent && firstEvent.isDefaultPrevented() ){
570
+ e.preventDefault();
571
+ }
572
+ invalids.push(e.target);
573
+ e.extraData = 'fix';
574
+ clearTimeout(stopSubmitTimer);
575
+ stopSubmitTimer = setTimeout(function(){
576
+ var lastEvent = {type: 'lastinvalid', cancelable: false, invalidlist: $(invalids)};
577
+ //reset firstinvalid
578
+ firstEvent = false;
579
+ invalids = [];
580
+ $(e.target).trigger(lastEvent, lastEvent);
581
+ }, 9);
582
+ jElm = null;
583
+ shadowElem = null;
584
+ });
585
+ })();
586
+
587
+ $.fn.getErrorMessage = function(){
588
+ var message = '';
589
+ var elem = this[0];
590
+ if(elem){
591
+ message = getContentValidationMessage(elem) || $.prop(elem, 'customValidationMessage') || $.prop(elem, 'validationMessage');
592
+ }
593
+ return message;
594
+ };
595
+
596
+ if(options.replaceValidationUI){
597
+ webshims.ready('DOM forms', function(){
598
+ $(document).on('firstinvalid', function(e){
599
+ if(!e.isInvalidUIPrevented()){
600
+ e.preventDefault();
601
+ $.webshims.validityAlert.showFor( e.target, $(e.target).prop('customValidationMessage') );
602
+ }
603
+ });
604
+ });
605
+ }
606
+
607
+ });
608
+ if(!Modernizr.formvalidation || jQuery.webshims.bugs.bustedValidity){
609
+ jQuery.webshims.register('form-shim-extend', function($, webshims, window, document){
610
+ "use strict";
611
+ webshims.inputTypes = webshims.inputTypes || {};
612
+ //some helper-functions
613
+ var cfg = webshims.cfg.forms;
614
+ var isSubmit;
615
+
616
+ var isNumber = function(string){
617
+ return (typeof string == 'number' || (string && string == string * 1));
618
+ },
619
+ typeModels = webshims.inputTypes,
620
+ checkTypes = {
621
+ radio: 1,
622
+ checkbox: 1
623
+ },
624
+ getType = function(elem){
625
+ return (elem.getAttribute('type') || elem.type || '').toLowerCase();
626
+ }
627
+ ;
628
+
629
+ //API to add new input types
630
+ webshims.addInputType = function(type, obj){
631
+ typeModels[type] = obj;
632
+ };
633
+
634
+ //contsrain-validation-api
635
+ var validityPrototype = {
636
+ customError: false,
637
+
638
+ typeMismatch: false,
639
+ rangeUnderflow: false,
640
+ rangeOverflow: false,
641
+ stepMismatch: false,
642
+ tooLong: false,
643
+ patternMismatch: false,
644
+ valueMissing: false,
645
+
646
+ valid: true
647
+ };
648
+
649
+ var isPlaceholderOptionSelected = function(select){
650
+ if(select.type == 'select-one' && select.size < 2){
651
+ var option = $('> option:first-child', select);
652
+ return !!option.prop('selected');
653
+ }
654
+ return false;
655
+ };
656
+
657
+ var validityRules = {
658
+ valueMissing: function(input, val, cache){
659
+ if(!input.prop('required')){return false;}
660
+ var ret = false;
661
+ if(!('type' in cache)){
662
+ cache.type = getType(input[0]);
663
+ }
664
+ if(cache.nodeName == 'select'){
665
+ ret = (!val && (input[0].selectedIndex < 0 || isPlaceholderOptionSelected(input[0]) ));
666
+ } else if(checkTypes[cache.type]){
667
+ ret = (cache.type == 'checkbox') ? !input.is(':checked') : !webshims.modules["form-core"].getGroupElements(input).filter(':checked')[0];
668
+ } else {
669
+ ret = !(val);
670
+ }
671
+ return ret;
672
+ },
673
+ tooLong: function(){
674
+ return false;
675
+ },
676
+ typeMismatch: function (input, val, cache){
677
+ if(val === '' || cache.nodeName == 'select'){return false;}
678
+ var ret = false;
679
+ if(!('type' in cache)){
680
+ cache.type = getType(input[0]);
681
+ }
682
+
683
+ if(typeModels[cache.type] && typeModels[cache.type].mismatch){
684
+ ret = typeModels[cache.type].mismatch(val, input);
685
+ } else if('validity' in input[0]){
686
+ ret = input[0].validity.typeMismatch;
687
+ }
688
+ return ret;
689
+ },
690
+ patternMismatch: function(input, val, cache) {
691
+ if(val === '' || cache.nodeName == 'select'){return false;}
692
+ var pattern = input.attr('pattern');
693
+ if(!pattern){return false;}
694
+ try {
695
+ pattern = new RegExp('^(?:' + pattern + ')$');
696
+ } catch(er){
697
+ webshims.error('invalid pattern value: "'+ pattern +'" | '+ er);
698
+ pattern = false;
699
+ }
700
+ if(!pattern){return false;}
701
+ return !(pattern.test(val));
702
+ }
703
+ }
704
+ ;
705
+
706
+ webshims.addValidityRule = function(type, fn){
707
+ validityRules[type] = fn;
708
+ };
709
+
710
+ $.event.special.invalid = {
711
+ add: function(){
712
+ $.event.special.invalid.setup.call(this.form || this);
713
+ },
714
+ setup: function(){
715
+ var form = this.form || this;
716
+ if( $.data(form, 'invalidEventShim') ){
717
+ form = null;
718
+ return;
719
+ }
720
+ $(form)
721
+ .data('invalidEventShim', true)
722
+ .on('submit', $.event.special.invalid.handler)
723
+ ;
724
+ webshims.moveToFirstEvent(form, 'submit');
725
+ if(webshims.bugs.bustedValidity && $.nodeName(form, 'form')){
726
+ (function(){
727
+ var noValidate = form.getAttribute('novalidate');
728
+ form.setAttribute('novalidate', 'novalidate');
729
+ webshims.data(form, 'bustedNoValidate', (noValidate == null) ? null : noValidate);
730
+ })();
731
+ }
732
+ form = null;
733
+ },
734
+ teardown: $.noop,
735
+ handler: function(e, d){
736
+
737
+ if( e.type != 'submit' || e.testedValidity || !e.originalEvent || !$.nodeName(e.target, 'form') || $.prop(e.target, 'noValidate') ){return;}
738
+
739
+ isSubmit = true;
740
+ e.testedValidity = true;
741
+ var notValid = !($(e.target).checkValidity());
742
+ if(notValid){
743
+ e.stopImmediatePropagation();
744
+ isSubmit = false;
745
+ return false;
746
+ }
747
+ isSubmit = false;
748
+ }
749
+ };
750
+
751
+ var addSubmitBubbles = function(form){
752
+ if (!$.support.submitBubbles && form && typeof form == 'object' && !form._submit_attached ) {
753
+
754
+ $.event.add( form, 'submit._submit', function( event ) {
755
+ event._submit_bubble = true;
756
+ });
757
+
758
+ form._submit_attached = true;
759
+ }
760
+ };
761
+ if(!$.support.submitBubbles && $.event.special.submit){
762
+ $.event.special.submit.setup = function() {
763
+ // Only need this for delegated form submit events
764
+ if ( $.nodeName( this, "form" ) ) {
765
+ return false;
766
+ }
767
+
768
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
769
+ $.event.add( this, "click._submit keypress._submit", function( e ) {
770
+ // Node name check avoids a VML-related crash in IE (#9807)
771
+ var elem = e.target,
772
+ form = $.nodeName( elem, 'input' ) || $.nodeName( elem, 'button' ) ? $.prop(elem, 'form') : undefined;
773
+ addSubmitBubbles(form);
774
+
775
+ });
776
+ // return undefined since we don't need an event listener
777
+ };
778
+ }
779
+
780
+ $.event.special.submit = $.event.special.submit || {setup: function(){return false;}};
781
+ var submitSetup = $.event.special.submit.setup;
782
+ $.extend($.event.special.submit, {
783
+ setup: function(){
784
+ if($.nodeName(this, 'form')){
785
+ $(this).on('invalid', $.noop);
786
+ } else {
787
+ $('form', this).on('invalid', $.noop);
788
+ }
789
+ return submitSetup.apply(this, arguments);
790
+ }
791
+ });
792
+
793
+ $(window).on('invalid', $.noop);
794
+
795
+
796
+ webshims.addInputType('email', {
797
+ mismatch: (function(){
798
+ //taken from http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
799
+ var test = cfg.emailReg || /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
800
+ return function(val){
801
+ return !test.test(val);
802
+ };
803
+ })()
804
+ });
805
+
806
+ webshims.addInputType('url', {
807
+ mismatch: (function(){
808
+ //taken from scott gonzales
809
+ var test = cfg.urlReg || /^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
810
+ return function(val){
811
+ return !test.test(val);
812
+ };
813
+ })()
814
+ });
815
+
816
+ webshims.defineNodeNameProperty('input', 'type', {
817
+ prop: {
818
+ get: function(){
819
+ var elem = this;
820
+ var type = (elem.getAttribute('type') || '').toLowerCase();
821
+ return (webshims.inputTypes[type]) ? type : elem.type;
822
+ }
823
+ }
824
+ });
825
+
826
+ // IDLs for constrain validation API
827
+ //ToDo: add object to this list
828
+ webshims.defineNodeNamesProperties(['button', 'fieldset', 'output'], {
829
+ checkValidity: {
830
+ value: function(){return true;}
831
+ },
832
+ willValidate: {
833
+ value: false
834
+ },
835
+ setCustomValidity: {
836
+ value: $.noop
837
+ },
838
+ validity: {
839
+ writeable: false,
840
+ get: function(){
841
+ return $.extend({}, validityPrototype);
842
+ }
843
+ }
844
+ }, 'prop');
845
+
846
+ var baseCheckValidity = function(elem){
847
+ var e,
848
+ v = $.prop(elem, 'validity')
849
+ ;
850
+ if(v){
851
+ $.data(elem, 'cachedValidity', v);
852
+ } else {
853
+ return true;
854
+ }
855
+ if( !v.valid ){
856
+ e = $.Event('invalid');
857
+ var jElm = $(elem).trigger(e);
858
+ if(isSubmit && !baseCheckValidity.unhandledInvalids && !e.isDefaultPrevented()){
859
+ webshims.validityAlert.showFor(jElm);
860
+ baseCheckValidity.unhandledInvalids = true;
861
+ }
862
+ }
863
+ $.removeData(elem, 'cachedValidity');
864
+ return v.valid;
865
+ };
866
+ var rsubmittable = /^(?:select|textarea|input)/i;
867
+ webshims.defineNodeNameProperty('form', 'checkValidity', {
868
+ prop: {
869
+ value: function(){
870
+
871
+ var ret = true,
872
+ elems = $($.prop(this, 'elements')).filter(function(){
873
+ if(!rsubmittable.test(this.nodeName)){return false;}
874
+ var shadowData = webshims.data(this, 'shadowData');
875
+ return !shadowData || !shadowData.nativeElement || shadowData.nativeElement === this;
876
+ })
877
+ ;
878
+
879
+ baseCheckValidity.unhandledInvalids = false;
880
+ for(var i = 0, len = elems.length; i < len; i++){
881
+ if( !baseCheckValidity(elems[i]) ){
882
+ ret = false;
883
+ }
884
+ }
885
+ return ret;
886
+ }
887
+ }
888
+ });
889
+
890
+ webshims.defineNodeNamesProperties(['input', 'textarea', 'select'], {
891
+ checkValidity: {
892
+ value: function(){
893
+ baseCheckValidity.unhandledInvalids = false;
894
+ return baseCheckValidity($(this).getNativeElement()[0]);
895
+ }
896
+ },
897
+ setCustomValidity: {
898
+ value: function(error){
899
+ $.removeData(this, 'cachedValidity');
900
+ webshims.data(this, 'customvalidationMessage', ''+error);
901
+ }
902
+ },
903
+ willValidate: {
904
+ writeable: false,
905
+ get: (function(){
906
+ var types = {
907
+ button: 1,
908
+ reset: 1,
909
+ hidden: 1,
910
+ image: 1
911
+ }
912
+ ;
913
+ return function(){
914
+ var elem = $(this).getNativeElement()[0];
915
+ //elem.name && <- we don't use to make it easier for developers
916
+ return !!(!elem.disabled && !elem.readOnly && !types[elem.type] );
917
+ };
918
+ })()
919
+ },
920
+ validity: {
921
+ writeable: false,
922
+ get: function(){
923
+ var jElm = $(this).getNativeElement();
924
+ var elem = jElm[0];
925
+ var validityState = $.data(elem, 'cachedValidity');
926
+ if(validityState){
927
+ return validityState;
928
+ }
929
+ validityState = $.extend({}, validityPrototype);
930
+
931
+ if( !$.prop(elem, 'willValidate') || elem.type == 'submit' ){
932
+ return validityState;
933
+ }
934
+ var val = jElm.val(),
935
+ cache = {nodeName: elem.nodeName.toLowerCase()}
936
+ ;
937
+
938
+ validityState.customError = !!(webshims.data(elem, 'customvalidationMessage'));
939
+ if( validityState.customError ){
940
+ validityState.valid = false;
941
+ }
942
+
943
+ $.each(validityRules, function(rule, fn){
944
+ if (fn(jElm, val, cache)) {
945
+ validityState[rule] = true;
946
+ validityState.valid = false;
947
+ }
948
+ });
949
+ $(this).getShadowFocusElement().attr('aria-invalid', validityState.valid ? 'false' : 'true');
950
+ jElm = null;
951
+ elem = null;
952
+ return validityState;
953
+ }
954
+ }
955
+ }, 'prop');
956
+
957
+ webshims.defineNodeNamesBooleanProperty(['input', 'textarea', 'select'], 'required', {
958
+ set: function(value){
959
+ $(this).getShadowFocusElement().attr('aria-required', !!(value)+'');
960
+ },
961
+ initAttr: (!$.browser.msie || webshims.browserVersion > 7)//only if we have aria-support
962
+ });
963
+
964
+ webshims.reflectProperties(['input'], ['pattern']);
965
+
966
+
967
+ if( !('maxLength' in document.createElement('textarea')) ){
968
+ var constrainMaxLength = (function(){
969
+ var timer;
970
+ var curLength = 0;
971
+ var lastElement = $([]);
972
+ var max = 1e9;
973
+ var constrainLength = function(){
974
+ var nowValue = lastElement.prop('value');
975
+ var nowLen = nowValue.length;
976
+ if(nowLen > curLength && nowLen > max){
977
+ nowLen = Math.max(curLength, max);
978
+ lastElement.prop('value', nowValue.substr(0, nowLen ));
979
+ }
980
+ curLength = nowLen;
981
+ };
982
+ var remove = function(){
983
+ clearTimeout(timer);
984
+ lastElement.unbind('.maxlengthconstraint');
985
+ };
986
+ return function(element, maxLength){
987
+ remove();
988
+ if(maxLength > -1){
989
+ max = maxLength;
990
+ curLength = $.prop(element, 'value').length;
991
+ lastElement = $(element);
992
+ lastElement.on({
993
+ 'keydown.maxlengthconstraint keypress.maxlengthconstraint paste.maxlengthconstraint cut.maxlengthconstraint': function(e){
994
+ setTimeout(constrainLength, 0);
995
+ },
996
+ 'keyup.maxlengthconstraint': constrainLength,
997
+ 'blur.maxlengthconstraint': remove
998
+ });
999
+ timer = setInterval(constrainLength, 200);
1000
+ }
1001
+ };
1002
+ })();
1003
+
1004
+ constrainMaxLength.update = function(element, maxLength){
1005
+ if($(element).is(':focus')){
1006
+ if(!maxLength){
1007
+ maxLength = $.prop(element, 'maxlength');
1008
+ }
1009
+ constrainMaxLength(element, maxLength);
1010
+ }
1011
+ };
1012
+
1013
+ $(document).on('focusin', function(e){
1014
+ var maxLength;
1015
+ if(e.target.nodeName == "TEXTAREA" && (maxLength = $.prop(e.target, 'maxlength')) > -1){
1016
+ constrainMaxLength(e.target, maxLength);
1017
+ }
1018
+ });
1019
+
1020
+ webshims.defineNodeNameProperty('textarea', 'maxlength', {
1021
+ attr: {
1022
+ set: function(val){
1023
+ this.setAttribute('maxlength', ''+val);
1024
+ constrainMaxLength.update(this);
1025
+ },
1026
+ get: function(){
1027
+ var ret = this.getAttribute('maxlength');
1028
+ return ret == null ? undefined : ret;
1029
+ }
1030
+ },
1031
+ prop: {
1032
+ set: function(val){
1033
+ if(isNumber(val)){
1034
+ if(val < 0){
1035
+ throw('INDEX_SIZE_ERR');
1036
+ }
1037
+ val = parseInt(val, 10);
1038
+ this.setAttribute('maxlength', val);
1039
+ constrainMaxLength.update(this, val);
1040
+ return;
1041
+ }
1042
+ this.setAttribute('maxlength', '0');
1043
+ constrainMaxLength.update(this, 0);
1044
+ },
1045
+ get: function(){
1046
+ var val = this.getAttribute('maxlength');
1047
+ return (isNumber(val) && val >= 0) ? parseInt(val, 10) : -1;
1048
+
1049
+ }
1050
+ }
1051
+ });
1052
+ webshims.defineNodeNameProperty('textarea', 'maxLength', {
1053
+ prop: {
1054
+ set: function(val){
1055
+ $.prop(this, 'maxlength', val);
1056
+ },
1057
+ get: function(){
1058
+ return $.prop(this, 'maxlength');
1059
+ }
1060
+ }
1061
+ });
1062
+ }
1063
+
1064
+
1065
+
1066
+ var submitterTypes = {submit: 1, button: 1, image: 1};
1067
+ var formSubmitterDescriptors = {};
1068
+ [
1069
+ {
1070
+ name: "enctype",
1071
+ limitedTo: {
1072
+ "application/x-www-form-urlencoded": 1,
1073
+ "multipart/form-data": 1,
1074
+ "text/plain": 1
1075
+ },
1076
+ defaultProp: "application/x-www-form-urlencoded",
1077
+ proptype: "enum"
1078
+ },
1079
+ {
1080
+ name: "method",
1081
+ limitedTo: {
1082
+ "get": 1,
1083
+ "post": 1
1084
+ },
1085
+ defaultProp: "get",
1086
+ proptype: "enum"
1087
+ },
1088
+ {
1089
+ name: "action",
1090
+ proptype: "url"
1091
+ },
1092
+ {
1093
+ name: "target"
1094
+ },
1095
+ {
1096
+ name: "novalidate",
1097
+ propName: "noValidate",
1098
+ proptype: "boolean"
1099
+ }
1100
+ ].forEach(function(desc){
1101
+ var propName = 'form'+ (desc.propName || desc.name).replace(/^[a-z]/, function(f){
1102
+ return f.toUpperCase();
1103
+ });
1104
+ var attrName = 'form'+ desc.name;
1105
+ var formName = desc.name;
1106
+ var eventName = 'click.webshimssubmittermutate'+formName;
1107
+
1108
+ var changeSubmitter = function(){
1109
+ var elem = this;
1110
+ if( !('form' in elem) || !submitterTypes[elem.type] ){return;}
1111
+ var form = $.prop(elem, 'form');
1112
+ if(!form){return;}
1113
+ var attr = $.attr(elem, attrName);
1114
+ if(attr != null && ( !desc.limitedTo || attr.toLowerCase() === $.prop(elem, propName))){
1115
+
1116
+ var oldAttr = $.attr(form, formName);
1117
+
1118
+ $.attr(form, formName, attr);
1119
+ setTimeout(function(){
1120
+ if(oldAttr != null){
1121
+ $.attr(form, formName, oldAttr);
1122
+ } else {
1123
+ try {
1124
+ $(form).removeAttr(formName);
1125
+ } catch(er){
1126
+ form.removeAttribute(formName);
1127
+ }
1128
+ }
1129
+ }, 9);
1130
+ }
1131
+ };
1132
+
1133
+
1134
+
1135
+ switch(desc.proptype) {
1136
+ case "url":
1137
+ var urlForm = document.createElement('form');
1138
+ formSubmitterDescriptors[propName] = {
1139
+ prop: {
1140
+ set: function(value){
1141
+ $.attr(this, attrName, value);
1142
+ },
1143
+ get: function(){
1144
+ var value = $.attr(this, attrName);
1145
+ if(value == null){return '';}
1146
+ urlForm.setAttribute('action', value);
1147
+ return urlForm.action;
1148
+ }
1149
+ }
1150
+ };
1151
+ break;
1152
+ case "boolean":
1153
+ formSubmitterDescriptors[propName] = {
1154
+ prop: {
1155
+ set: function(val){
1156
+ val = !!val;
1157
+ if(val){
1158
+ $.attr(this, 'formnovalidate', 'formnovalidate');
1159
+ } else {
1160
+ $(this).removeAttr('formnovalidate');
1161
+ }
1162
+ },
1163
+ get: function(){
1164
+ return $.attr(this, 'formnovalidate') != null;
1165
+ }
1166
+ }
1167
+ };
1168
+ break;
1169
+ case "enum":
1170
+ formSubmitterDescriptors[propName] = {
1171
+ prop: {
1172
+ set: function(value){
1173
+ $.attr(this, attrName, value);
1174
+ },
1175
+ get: function(){
1176
+ var value = $.attr(this, attrName);
1177
+ return (!value || ( (value = value.toLowerCase()) && !desc.limitedTo[value] )) ? desc.defaultProp : value;
1178
+ }
1179
+ }
1180
+ };
1181
+ break;
1182
+ default:
1183
+ formSubmitterDescriptors[propName] = {
1184
+ prop: {
1185
+ set: function(value){
1186
+ $.attr(this, attrName, value);
1187
+ },
1188
+ get: function(){
1189
+ var value = $.attr(this, attrName);
1190
+ return (value != null) ? value : "";
1191
+ }
1192
+ }
1193
+ };
1194
+ }
1195
+
1196
+
1197
+ if(!formSubmitterDescriptors[attrName]){
1198
+ formSubmitterDescriptors[attrName] = {};
1199
+ }
1200
+ formSubmitterDescriptors[attrName].attr = {
1201
+ set: function(value){
1202
+ formSubmitterDescriptors[attrName].attr._supset.call(this, value);
1203
+ $(this).unbind(eventName).on(eventName, changeSubmitter);
1204
+ },
1205
+ get: function(){
1206
+ return formSubmitterDescriptors[attrName].attr._supget.call(this);
1207
+ }
1208
+ };
1209
+ formSubmitterDescriptors[attrName].initAttr = true;
1210
+ formSubmitterDescriptors[attrName].removeAttr = {
1211
+ value: function(){
1212
+ $(this).unbind(eventName);
1213
+ formSubmitterDescriptors[attrName].removeAttr._supvalue.call(this);
1214
+ }
1215
+ };
1216
+ });
1217
+
1218
+ webshims.defineNodeNamesProperties(['input', 'button'], formSubmitterDescriptors);
1219
+
1220
+
1221
+ if(!$.support.getSetAttribute && $('<form novalidate></form>').attr('novalidate') == null){
1222
+ webshims.defineNodeNameProperty('form', 'novalidate', {
1223
+ attr: {
1224
+ set: function(val){
1225
+ this.setAttribute('novalidate', ''+val);
1226
+ },
1227
+ get: function(){
1228
+ var ret = this.getAttribute('novalidate');
1229
+ return ret == null ? undefined : ret;
1230
+ }
1231
+ }
1232
+ });
1233
+ } else if(webshims.bugs.bustedValidity){
1234
+
1235
+ webshims.defineNodeNameProperty('form', 'novalidate', {
1236
+ attr: {
1237
+ set: function(val){
1238
+ webshims.data(this, 'bustedNoValidate', ''+val);
1239
+ },
1240
+ get: function(){
1241
+ var ret = webshims.data(this, 'bustedNoValidate');
1242
+ return ret == null ? undefined : ret;
1243
+ }
1244
+ },
1245
+ removeAttr: {
1246
+ value: function(){
1247
+ webshims.data(this, 'bustedNoValidate', null);
1248
+ }
1249
+ }
1250
+ });
1251
+
1252
+ $.each(['rangeUnderflow', 'rangeOverflow', 'stepMismatch'], function(i, name){
1253
+ validityRules[name] = function(elem){
1254
+ return (elem[0].validity || {})[name] || false;
1255
+ };
1256
+ });
1257
+
1258
+ }
1259
+
1260
+ webshims.defineNodeNameProperty('form', 'noValidate', {
1261
+ prop: {
1262
+ set: function(val){
1263
+ val = !!val;
1264
+ if(val){
1265
+ $.attr(this, 'novalidate', 'novalidate');
1266
+ } else {
1267
+ $(this).removeAttr('novalidate');
1268
+ }
1269
+ },
1270
+ get: function(){
1271
+ return $.attr(this, 'novalidate') != null;
1272
+ }
1273
+ }
1274
+ });
1275
+
1276
+ if($.browser.webkit && Modernizr.inputtypes.date){
1277
+ (function(){
1278
+
1279
+ var noInputTriggerEvts = {updateInput: 1, input: 1},
1280
+ fixInputTypes = {
1281
+ date: 1,
1282
+ time: 1,
1283
+ "datetime-local": 1
1284
+ },
1285
+ noFocusEvents = {
1286
+ focusout: 1,
1287
+ blur: 1
1288
+ },
1289
+ changeEvts = {
1290
+ updateInput: 1,
1291
+ change: 1
1292
+ },
1293
+ observe = function(input){
1294
+ var timer,
1295
+ focusedin = true,
1296
+ lastInputVal = input.prop('value'),
1297
+ lastChangeVal = lastInputVal,
1298
+ trigger = function(e){
1299
+ //input === null
1300
+ if(!input){return;}
1301
+ var newVal = input.prop('value');
1302
+
1303
+ if(newVal !== lastInputVal){
1304
+ lastInputVal = newVal;
1305
+ if(!e || !noInputTriggerEvts[e.type]){
1306
+ input.trigger('input');
1307
+ }
1308
+ }
1309
+ if(e && changeEvts[e.type]){
1310
+ lastChangeVal = newVal;
1311
+ }
1312
+ if(!focusedin && newVal !== lastChangeVal){
1313
+ input.trigger('change');
1314
+ }
1315
+ },
1316
+ extraTimer,
1317
+ extraTest = function(){
1318
+ clearTimeout(extraTimer);
1319
+ extraTimer = setTimeout(trigger, 9);
1320
+ },
1321
+ unbind = function(e){
1322
+ clearInterval(timer);
1323
+ setTimeout(function(){
1324
+ if(e && noFocusEvents[e.type]){
1325
+ focusedin = false;
1326
+ }
1327
+ if(input){
1328
+ input.unbind('focusout blur', unbind).unbind('input change updateInput', trigger);
1329
+ trigger();
1330
+ }
1331
+ input = null;
1332
+ }, 1);
1333
+
1334
+ }
1335
+ ;
1336
+
1337
+ clearInterval(timer);
1338
+ timer = setInterval(trigger, 160);
1339
+ extraTest();
1340
+ input
1341
+ .off({
1342
+ 'focusout blur': unbind,
1343
+ 'input change updateInput': trigger
1344
+ })
1345
+ .on({
1346
+ 'focusout blur': unbind,
1347
+ 'input updateInput change': trigger
1348
+ })
1349
+ ;
1350
+ }
1351
+ ;
1352
+ if($.event.customEvent){
1353
+ $.event.customEvent.updateInput = true;
1354
+ }
1355
+
1356
+ (function(){
1357
+
1358
+ var correctValue = function(elem){
1359
+ var i = 1;
1360
+ var len = 3;
1361
+ var abort, val;
1362
+ if(elem.type == 'date' && (isSubmit || !$(elem).is(':focus'))){
1363
+ val = elem.value;
1364
+ if(val && val.length < 10 && (val = val.split('-')) && val.length == len){
1365
+ for(; i < len; i++){
1366
+ if(val[i].length == 1){
1367
+ val[i] = '0'+val[i];
1368
+ } else if(val[i].length != 2){
1369
+ abort = true;
1370
+ break;
1371
+ }
1372
+ }
1373
+ if(!abort){
1374
+ val = val.join('-');
1375
+ $.prop(elem, 'value', val);
1376
+ return val;
1377
+ }
1378
+ }
1379
+ }
1380
+ };
1381
+ var inputCheckValidityDesc, formCheckValidityDesc, inputValueDesc, inputValidityDesc;
1382
+
1383
+ inputCheckValidityDesc = webshims.defineNodeNameProperty('input', 'checkValidity', {
1384
+ prop: {
1385
+ value: function(){
1386
+ correctValue(this);
1387
+ return inputCheckValidityDesc.prop._supvalue.apply(this, arguments);
1388
+ }
1389
+ }
1390
+ });
1391
+
1392
+ formCheckValidityDesc = webshims.defineNodeNameProperty('form', 'checkValidity', {
1393
+ prop: {
1394
+ value: function(){
1395
+ $('input', this).each(function(){
1396
+ correctValue(this);
1397
+ });
1398
+ return formCheckValidityDesc.prop._supvalue.apply(this, arguments);
1399
+ }
1400
+ }
1401
+ });
1402
+
1403
+ inputValueDesc = webshims.defineNodeNameProperty('input', 'value', {
1404
+ prop: {
1405
+ set: function(){
1406
+ return inputValueDesc.prop._supset.apply(this, arguments);
1407
+ },
1408
+ get: function(){
1409
+ return correctValue(this) || inputValueDesc.prop._supget.apply(this, arguments);
1410
+ }
1411
+ }
1412
+ });
1413
+
1414
+ inputValidityDesc = webshims.defineNodeNameProperty('input', 'validity', {
1415
+ prop: {
1416
+ writeable: false,
1417
+ get: function(){
1418
+ correctValue(this);
1419
+ return inputValidityDesc.prop._supget.apply(this, arguments);
1420
+ }
1421
+ }
1422
+ });
1423
+
1424
+ $(document).on('change', function(e){
1425
+ correctValue(e.target);
1426
+ });
1427
+
1428
+ })();
1429
+
1430
+ $(document)
1431
+ .on('focusin', function(e){
1432
+ if( e.target && fixInputTypes[e.target.type] && !e.target.readOnly && !e.target.disabled ){
1433
+ observe($(e.target));
1434
+ }
1435
+ })
1436
+ ;
1437
+
1438
+
1439
+ })();
1440
+ }
1441
+
1442
+ webshims.addReady(function(context, contextElem){
1443
+ //start constrain-validation
1444
+ var focusElem;
1445
+ $('form', context)
1446
+ .add(contextElem.filter('form'))
1447
+ .bind('invalid', $.noop)
1448
+ ;
1449
+
1450
+ try {
1451
+ if(context == document && !('form' in (document.activeElement || {}))) {
1452
+ focusElem = $('input[autofocus], select[autofocus], textarea[autofocus]', context).eq(0).getShadowFocusElement()[0];
1453
+ if (focusElem && focusElem.offsetHeight && focusElem.offsetWidth) {
1454
+ focusElem.focus();
1455
+ }
1456
+ }
1457
+ }
1458
+ catch (er) {}
1459
+
1460
+ });
1461
+
1462
+ if(!Modernizr.formattribute || !Modernizr.fieldsetdisabled){
1463
+ (function(){
1464
+ (function(prop, undefined){
1465
+ $.prop = function(elem, name, value){
1466
+ var ret;
1467
+ if(elem && elem.nodeType == 1 && value === undefined && $.nodeName(elem, 'form') && elem.id){
1468
+ ret = document.getElementsByName(name);
1469
+ if(!ret || !ret.length){
1470
+ ret = document.getElementById(name);
1471
+ }
1472
+ if(ret){
1473
+ ret = $(ret).filter(function(){
1474
+ return $.prop(this, 'form') == elem;
1475
+ }).get();
1476
+ if(ret.length){
1477
+ return ret.length == 1 ? ret[0] : ret;
1478
+ }
1479
+ }
1480
+ }
1481
+ return prop.apply(this, arguments);
1482
+ };
1483
+ })($.prop, undefined);
1484
+ var removeAddedElements = function(form){
1485
+ var elements = $.data(form, 'webshimsAddedElements');
1486
+ if(elements){
1487
+ elements.remove();
1488
+ $.removeData(form, 'webshimsAddedElements');
1489
+ }
1490
+ };
1491
+ var rCRLF = /\r?\n/g,
1492
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
1493
+ rselectTextarea = /^(?:select|textarea)/i;
1494
+
1495
+ if(!Modernizr.formattribute){
1496
+ webshims.defineNodeNamesProperty(['input', 'textarea', 'select', 'button', 'fieldset'], 'form', {
1497
+ prop: {
1498
+ get: function(){
1499
+ var form = webshims.contentAttr(this, 'form');
1500
+ if(form){
1501
+ form = document.getElementById(form);
1502
+ if(form && !$.nodeName(form, 'form')){
1503
+ form = null;
1504
+ }
1505
+ }
1506
+ return form || this.form;
1507
+ },
1508
+ writeable: false
1509
+ }
1510
+ });
1511
+
1512
+
1513
+ webshims.defineNodeNamesProperty(['form'], 'elements', {
1514
+ prop: {
1515
+ get: function(){
1516
+ var id = this.id;
1517
+ var elements = $.makeArray(this.elements);
1518
+ if(id){
1519
+ elements = $(elements).add('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"], button[form="'+ id +'"], fieldset[form="'+ id +'"]').not('.webshims-visual-hide > *').get();
1520
+ }
1521
+ return elements;
1522
+ },
1523
+ writeable: false
1524
+ }
1525
+ });
1526
+
1527
+
1528
+
1529
+ $(function(){
1530
+ var stopPropagation = function(e){
1531
+ e.stopPropagation();
1532
+ };
1533
+ $(document).on('submit', function(e){
1534
+
1535
+ if(!e.isDefaultPrevented()){
1536
+ var form = e.target;
1537
+ var id = form.id;
1538
+ var elements;
1539
+
1540
+
1541
+ if(id){
1542
+ removeAddedElements(form);
1543
+
1544
+ elements = $('input[form="'+ id +'"], select[form="'+ id +'"], textarea[form="'+ id +'"]')
1545
+ .filter(function(){
1546
+ return !this.disabled && this.name && this.form != form;
1547
+ })
1548
+ .clone()
1549
+ ;
1550
+ if(elements.length){
1551
+ $.data(form, 'webshimsAddedElements', $('<div class="webshims-visual-hide" />').append(elements).appendTo(form));
1552
+ setTimeout(function(){
1553
+ removeAddedElements(form);
1554
+ }, 9);
1555
+ }
1556
+ elements = null;
1557
+ }
1558
+ }
1559
+ });
1560
+
1561
+ $(document).on('click', function(e){
1562
+ if(!e.isDefaultPrevented() && $(e.target).is('input[type="submit"][form], button[form], input[type="button"][form], input[type="image"][form], input[type="reset"][form]')){
1563
+ var trueForm = $.prop(e.target, 'form');
1564
+ var formIn = e.target.form;
1565
+ var clone;
1566
+ if(trueForm && trueForm != formIn){
1567
+ clone = $(e.target)
1568
+ .clone()
1569
+ .removeAttr('form')
1570
+ .addClass('webshims-visual-hide')
1571
+ .on('click', stopPropagation)
1572
+ .appendTo(trueForm)
1573
+ ;
1574
+ if(formIn){
1575
+ e.preventDefault();
1576
+ }
1577
+ addSubmitBubbles(trueForm);
1578
+ clone.trigger('click');
1579
+ setTimeout(function(){
1580
+ clone.remove();
1581
+ clone = null;
1582
+ }, 9);
1583
+ }
1584
+ }
1585
+ });
1586
+ });
1587
+ }
1588
+
1589
+ if(!Modernizr.fieldsetdisabled){
1590
+ webshims.defineNodeNamesProperty(['fieldset'], 'elements', {
1591
+ prop: {
1592
+ get: function(){
1593
+ //add listed elements without keygen, object, output
1594
+ return $('input, select, textarea, button, fieldset', this).get() || [];
1595
+ },
1596
+ writeable: false
1597
+ }
1598
+ });
1599
+ }
1600
+
1601
+ $.fn.serializeArray = function() {
1602
+ return this.map(function(){
1603
+ var elements = $.prop(this, 'elements');
1604
+ return elements ? $.makeArray( elements ) : this;
1605
+ })
1606
+ .filter(function(){
1607
+ return this.name && !this.disabled &&
1608
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
1609
+ rinput.test( this.type ) );
1610
+ })
1611
+ .map(function( i, elem ){
1612
+ var val = $( this ).val();
1613
+
1614
+ return val == null ?
1615
+ null :
1616
+ $.isArray( val ) ?
1617
+ $.map( val, function( val, i ){
1618
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1619
+ }) :
1620
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
1621
+ }).get();
1622
+ };
1623
+
1624
+ })();
1625
+ }
1626
+
1627
+ try {
1628
+ document.querySelector(':checked');
1629
+ } catch(er){
1630
+ (function(){
1631
+ var checkInputs = {
1632
+ radio: 1,
1633
+ checkbox: 1
1634
+ };
1635
+ var selectChange = function(){
1636
+ var options = this.options || [];
1637
+ var i, len, option;
1638
+ for(i = 0, len = options.length; i < len; i++){
1639
+ option = $(options[i]);
1640
+ option[$.prop(options[i], 'selected') ? 'addClass' : 'removeClass']('prop-checked');
1641
+ }
1642
+ };
1643
+ var checkChange = function(){
1644
+ var fn = $.prop(this, 'checked') ? 'addClass' : 'removeClass';
1645
+ var className = this.className || '';
1646
+ var parent;
1647
+
1648
+ //IE8- has problems to update styles, we help
1649
+ if( (className.indexOf('prop-checked') == -1) == (fn == 'addClass')){
1650
+ $(this)[fn]('prop-checked');
1651
+ if((parent = this.parentNode)){
1652
+ parent.className = parent.className;
1653
+ }
1654
+ }
1655
+ };
1656
+
1657
+
1658
+ webshims.onNodeNamesPropertyModify('select', 'value', selectChange);
1659
+ webshims.onNodeNamesPropertyModify('select', 'selectedIndex', selectChange);
1660
+ webshims.onNodeNamesPropertyModify('option', 'selected', function(){
1661
+ $(this).closest('select').each(selectChange);
1662
+ });
1663
+ webshims.onNodeNamesPropertyModify('input', 'checked', function(value, boolVal){
1664
+ var type = this.type;
1665
+ if(type == 'radio' && boolVal){
1666
+ webshims.modules["form-core"].getGroupElements(this).each(checkChange);
1667
+ } else if(checkInputs[type]) {
1668
+ $(this).each(checkChange);
1669
+ }
1670
+ });
1671
+
1672
+ $(document).on('change', function(e){
1673
+
1674
+ if(checkInputs[e.target.type]){
1675
+ if(e.target.type == 'radio'){
1676
+ webshims.modules["form-core"].getGroupElements(e.target).each(checkChange);
1677
+ } else {
1678
+ $(e.target)[$.prop(e.target, 'checked') ? 'addClass' : 'removeClass']('prop-checked');
1679
+ }
1680
+ } else if(e.target.nodeName.toLowerCase() == 'select'){
1681
+ $(e.target).each(selectChange);
1682
+ }
1683
+ });
1684
+
1685
+ webshims.addReady(function(context, contextElem){
1686
+ $('option, input', context)
1687
+ .add(contextElem.filter('option, input'))
1688
+ .each(function(){
1689
+ var prop;
1690
+ if(checkInputs[this.type]){
1691
+ prop = 'checked';
1692
+ } else if(this.nodeName.toLowerCase() == 'option'){
1693
+ prop = 'selected';
1694
+ }
1695
+ if(prop){
1696
+ $(this)[$.prop(this, prop) ? 'addClass' : 'removeClass']('prop-checked');
1697
+ }
1698
+
1699
+ })
1700
+ ;
1701
+ });
1702
+ })();
1703
+ }
1704
+
1705
+ (function(){
1706
+ Modernizr.textareaPlaceholder = !!('placeholder' in $('<textarea />')[0]);
1707
+ var bustedTextarea = $.browser.webkit && Modernizr.textareaPlaceholder && webshims.browserVersion < 535;
1708
+ if(Modernizr.input.placeholder && Modernizr.textareaPlaceholder && !bustedTextarea){return;}
1709
+
1710
+ var isOver = (webshims.cfg.forms.placeholderType == 'over');
1711
+ var isResponsive = (webshims.cfg.forms.responsivePlaceholder);
1712
+ var polyfillElements = ['textarea'];
1713
+ if(!Modernizr.input.placeholder){
1714
+ polyfillElements.push('input');
1715
+ }
1716
+
1717
+ var setSelection = function(elem){
1718
+ try {
1719
+ if(elem.setSelectionRange){
1720
+ elem.setSelectionRange(0, 0);
1721
+ return true;
1722
+ } else if(elem.createTextRange){
1723
+ var range = elem.createTextRange();
1724
+ range.collapse(true);
1725
+ range.moveEnd('character', 0);
1726
+ range.moveStart('character', 0);
1727
+ range.select();
1728
+ return true;
1729
+ }
1730
+ } catch(er){}
1731
+ };
1732
+
1733
+ var hidePlaceholder = function(elem, data, value, _onFocus){
1734
+ if(value === false){
1735
+ value = $.prop(elem, 'value');
1736
+ }
1737
+ if(!isOver && elem.type != 'password'){
1738
+ if(!value && _onFocus && setSelection(elem)){
1739
+ var selectTimer = setTimeout(function(){
1740
+ setSelection(elem);
1741
+ }, 9);
1742
+ $(elem)
1743
+ .off('.placeholderremove')
1744
+ .on({
1745
+ 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
1746
+ if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1747
+ elem.value = $.prop(elem, 'value');
1748
+ data.box.removeClass('placeholder-visible');
1749
+ clearTimeout(selectTimer);
1750
+ $(elem).unbind('.placeholderremove');
1751
+ },
1752
+ 'mousedown.placeholderremove drag.placeholderremove select.placeholderremove': function(e){
1753
+ setSelection(elem);
1754
+ clearTimeout(selectTimer);
1755
+ selectTimer = setTimeout(function(){
1756
+ setSelection(elem);
1757
+ }, 9);
1758
+ },
1759
+ 'blur.placeholderremove': function(){
1760
+ clearTimeout(selectTimer);
1761
+ $(elem).unbind('.placeholderremove');
1762
+ }
1763
+ })
1764
+ ;
1765
+ return;
1766
+ }
1767
+ elem.value = value;
1768
+ } else if(!value && _onFocus){
1769
+ $(elem)
1770
+ .off('.placeholderremove')
1771
+ .on({
1772
+ 'keydown.placeholderremove keypress.placeholderremove paste.placeholderremove input.placeholderremove': function(e){
1773
+ if(e && (e.keyCode == 17 || e.keyCode == 16)){return;}
1774
+ data.box.removeClass('placeholder-visible');
1775
+ $(elem).unbind('.placeholderremove');
1776
+ },
1777
+ 'blur.placeholderremove': function(){
1778
+ $(elem).unbind('.placeholderremove');
1779
+ }
1780
+ })
1781
+ ;
1782
+ return;
1783
+ }
1784
+ data.box.removeClass('placeholder-visible');
1785
+ },
1786
+ showPlaceholder = function(elem, data, placeholderTxt){
1787
+ if(placeholderTxt === false){
1788
+ placeholderTxt = $.prop(elem, 'placeholder');
1789
+ }
1790
+
1791
+ if(!isOver && elem.type != 'password'){
1792
+ elem.value = placeholderTxt;
1793
+ }
1794
+ data.box.addClass('placeholder-visible');
1795
+ },
1796
+ changePlaceholderVisibility = function(elem, value, placeholderTxt, data, type){
1797
+ if(!data){
1798
+ data = $.data(elem, 'placeHolder');
1799
+ if(!data){return;}
1800
+ }
1801
+ $(elem).unbind('.placeholderremove');
1802
+ if(type == 'focus' || (!type && $(elem).is(':focus'))){
1803
+ if(elem.type == 'password' || isOver || $(elem).hasClass('placeholder-visible')){
1804
+ hidePlaceholder(elem, data, '', true);
1805
+ }
1806
+ return;
1807
+ }
1808
+ if(value === false){
1809
+ value = $.prop(elem, 'value');
1810
+ }
1811
+ if(value){
1812
+ hidePlaceholder(elem, data, value);
1813
+ return;
1814
+ }
1815
+ if(placeholderTxt === false){
1816
+ placeholderTxt = $.attr(elem, 'placeholder') || '';
1817
+ }
1818
+ if(placeholderTxt && !value){
1819
+ showPlaceholder(elem, data, placeholderTxt);
1820
+ } else {
1821
+ hidePlaceholder(elem, data, value);
1822
+ }
1823
+ },
1824
+ createPlaceholder = function(elem){
1825
+ elem = $(elem);
1826
+ var id = elem.prop('id'),
1827
+ hasLabel = !!(elem.prop('title') || elem.attr('aria-labelledby'))
1828
+ ;
1829
+ if(!hasLabel && id){
1830
+ hasLabel = !!( $('label[for="'+ id +'"]', elem[0].form)[0] );
1831
+ }
1832
+ if(!hasLabel){
1833
+ if(!id){
1834
+ id = $.webshims.getID(elem);
1835
+ }
1836
+ hasLabel = !!($('label #'+ id)[0]);
1837
+ }
1838
+ return $( hasLabel ? '<span class="placeholder-text"></span>' : '<label for="'+ id +'" class="placeholder-text"></label>');
1839
+ },
1840
+ pHolder = (function(){
1841
+ var delReg = /\n|\r|\f|\t/g,
1842
+ allowedPlaceholder = {
1843
+ text: 1,
1844
+ search: 1,
1845
+ url: 1,
1846
+ email: 1,
1847
+ password: 1,
1848
+ tel: 1,
1849
+ number: 1
1850
+ }
1851
+ ;
1852
+
1853
+ return {
1854
+ create: function(elem){
1855
+ var data = $.data(elem, 'placeHolder');
1856
+ var form;
1857
+ var responsiveElem;
1858
+ if(data){return data;}
1859
+ data = $.data(elem, 'placeHolder', {});
1860
+
1861
+ $(elem).on('focus.placeholder blur.placeholder', function(e){
1862
+ changePlaceholderVisibility(this, false, false, data, e.type );
1863
+ data.box[e.type == 'focus' ? 'addClass' : 'removeClass']('placeholder-focused');
1864
+ });
1865
+
1866
+ if((form = $.prop(elem, 'form'))){
1867
+ $(form).on('reset.placeholder', function(e){
1868
+ setTimeout(function(){
1869
+ changePlaceholderVisibility(elem, false, false, data, e.type );
1870
+ }, 0);
1871
+ });
1872
+ }
1873
+
1874
+ if(elem.type == 'password' || isOver){
1875
+ data.text = createPlaceholder(elem);
1876
+ if(isResponsive || $(elem).is('.responsive-width') || (elem.currentStyle || {width: ''}).width.indexOf('%') != -1){
1877
+ responsiveElem = true;
1878
+ data.box = data.text;
1879
+ } else {
1880
+ data.box = $(elem)
1881
+ .wrap('<span class="placeholder-box placeholder-box-'+ (elem.nodeName || '').toLowerCase() +' placeholder-box-'+$.css(elem, 'float')+'" />')
1882
+ .parent()
1883
+ ;
1884
+ }
1885
+ data.text
1886
+ .insertAfter(elem)
1887
+ .on('mousedown.placeholder', function(){
1888
+ changePlaceholderVisibility(this, false, false, data, 'focus');
1889
+ try {
1890
+ setTimeout(function(){
1891
+ elem.focus();
1892
+ }, 0);
1893
+ } catch(e){}
1894
+ return false;
1895
+ })
1896
+ ;
1897
+
1898
+
1899
+ $.each(['lineHeight', 'fontSize', 'fontFamily', 'fontWeight'], function(i, style){
1900
+ var prop = $.css(elem, style);
1901
+ if(data.text.css(style) != prop){
1902
+ data.text.css(style, prop);
1903
+ }
1904
+ });
1905
+ $.each(['Left', 'Top'], function(i, side){
1906
+ var size = (parseInt($.css(elem, 'padding'+ side), 10) || 0) + Math.max((parseInt($.css(elem, 'margin'+ side), 10) || 0), 0) + (parseInt($.css(elem, 'border'+ side +'Width'), 10) || 0);
1907
+ data.text.css('padding'+ side, size);
1908
+ });
1909
+
1910
+ $(elem)
1911
+ .on('updateshadowdom', function(){
1912
+ var height, width;
1913
+ if((width = elem.offsetWidth) || (height = elem.offsetHeight)){
1914
+ data.text
1915
+ .css({
1916
+ width: width,
1917
+ height: height
1918
+ })
1919
+ .css($(elem).position())
1920
+ ;
1921
+ }
1922
+ })
1923
+ .triggerHandler('updateshadowdom')
1924
+ ;
1925
+
1926
+ } else {
1927
+ var reset = function(e){
1928
+ if($(elem).hasClass('placeholder-visible')){
1929
+ hidePlaceholder(elem, data, '');
1930
+ if(e && e.type == 'submit'){
1931
+ setTimeout(function(){
1932
+ if(e.isDefaultPrevented()){
1933
+ changePlaceholderVisibility(elem, false, false, data );
1934
+ }
1935
+ }, 9);
1936
+ }
1937
+ }
1938
+ };
1939
+
1940
+ $(window).on('beforeunload', reset);
1941
+ data.box = $(elem);
1942
+ if(form){
1943
+ $(form).submit(reset);
1944
+ }
1945
+ }
1946
+
1947
+ return data;
1948
+ },
1949
+ update: function(elem, val){
1950
+ var type = ($.attr(elem, 'type') || $.prop(elem, 'type') || '').toLowerCase();
1951
+ if(!allowedPlaceholder[type] && !$.nodeName(elem, 'textarea')){
1952
+ webshims.error('placeholder not allowed on input[type="'+type+'"]');
1953
+ if(type == 'date'){
1954
+ webshims.error('but you can use data-placeholder for input[type="date"]');
1955
+ }
1956
+ return;
1957
+ }
1958
+
1959
+
1960
+ var data = pHolder.create(elem);
1961
+ if(data.text){
1962
+ data.text.text(val);
1963
+ }
1964
+
1965
+ changePlaceholderVisibility(elem, false, val, data);
1966
+ }
1967
+ };
1968
+ })()
1969
+ ;
1970
+
1971
+ $.webshims.publicMethods = {
1972
+ pHolder: pHolder
1973
+ };
1974
+ polyfillElements.forEach(function(nodeName){
1975
+ var desc = webshims.defineNodeNameProperty(nodeName, 'placeholder', {
1976
+ attr: {
1977
+ set: function(val){
1978
+ var elem = this;
1979
+ if(bustedTextarea){
1980
+ webshims.data(elem, 'textareaPlaceholder', val);
1981
+ elem.placeholder = '';
1982
+ } else {
1983
+ webshims.contentAttr(elem, 'placeholder', val);
1984
+ }
1985
+ pHolder.update(elem, val);
1986
+ },
1987
+ get: function(){
1988
+ var ret = (bustedTextarea) ? webshims.data(this, 'textareaPlaceholder') : '';
1989
+ return ret || webshims.contentAttr(this, 'placeholder');
1990
+ }
1991
+ },
1992
+ reflect: true,
1993
+ initAttr: true
1994
+ });
1995
+ });
1996
+
1997
+
1998
+ polyfillElements.forEach(function(name){
1999
+ var placeholderValueDesc = {};
2000
+ var desc;
2001
+ ['attr', 'prop'].forEach(function(propType){
2002
+ placeholderValueDesc[propType] = {
2003
+ set: function(val){
2004
+ var elem = this;
2005
+ var placeholder;
2006
+ if(bustedTextarea){
2007
+ placeholder = webshims.data(elem, 'textareaPlaceholder');
2008
+ }
2009
+ if(!placeholder){
2010
+ placeholder = webshims.contentAttr(elem, 'placeholder');
2011
+ }
2012
+ $.removeData(elem, 'cachedValidity');
2013
+ var ret = desc[propType]._supset.call(elem, val);
2014
+ if(placeholder && 'value' in elem){
2015
+ changePlaceholderVisibility(elem, val, placeholder);
2016
+ }
2017
+ return ret;
2018
+ },
2019
+ get: function(){
2020
+ var elem = this;
2021
+ return $(elem).hasClass('placeholder-visible') ? '' : desc[propType]._supget.call(elem);
2022
+ }
2023
+ };
2024
+ });
2025
+ desc = webshims.defineNodeNameProperty(name, 'value', placeholderValueDesc);
2026
+ });
2027
+
2028
+ })();
2029
+
2030
+ (function(){
2031
+ var doc = document;
2032
+ if( 'value' in document.createElement('output') ){return;}
2033
+
2034
+ webshims.defineNodeNameProperty('output', 'value', {
2035
+ prop: {
2036
+ set: function(value){
2037
+ var setVal = $.data(this, 'outputShim');
2038
+ if(!setVal){
2039
+ setVal = outputCreate(this);
2040
+ }
2041
+ setVal(value);
2042
+ },
2043
+ get: function(){
2044
+ return webshims.contentAttr(this, 'value') || $(this).text() || '';
2045
+ }
2046
+ }
2047
+ });
2048
+
2049
+
2050
+ webshims.onNodeNamesPropertyModify('input', 'value', function(value, boolVal, type){
2051
+ if(type == 'removeAttr'){return;}
2052
+ var setVal = $.data(this, 'outputShim');
2053
+ if(setVal){
2054
+ setVal(value);
2055
+ }
2056
+ });
2057
+
2058
+ var outputCreate = function(elem){
2059
+ if(elem.getAttribute('aria-live')){return;}
2060
+ elem = $(elem);
2061
+ var value = (elem.text() || '').trim();
2062
+ var id = elem.attr('id');
2063
+ var htmlFor = elem.attr('for');
2064
+ var shim = $('<input class="output-shim" type="text" disabled name="'+ (elem.attr('name') || '')+'" value="'+value+'" style="display: none !important;" />').insertAfter(elem);
2065
+ var form = shim[0].form || doc;
2066
+ var setValue = function(val){
2067
+ shim[0].value = val;
2068
+ val = shim[0].value;
2069
+ elem.text(val);
2070
+ webshims.contentAttr(elem[0], 'value', val);
2071
+ };
2072
+
2073
+ elem[0].defaultValue = value;
2074
+ webshims.contentAttr(elem[0], 'value', value);
2075
+
2076
+ elem.attr({'aria-live': 'polite'});
2077
+ if(id){
2078
+ shim.attr('id', id);
2079
+ elem.attr('aria-labelledby', webshims.getID($('label[for="'+id+'"]', form)));
2080
+ }
2081
+ if(htmlFor){
2082
+ id = webshims.getID(elem);
2083
+ htmlFor.split(' ').forEach(function(control){
2084
+ control = document.getElementById(control);
2085
+ if(control){
2086
+ control.setAttribute('aria-controls', id);
2087
+ }
2088
+ });
2089
+ }
2090
+ elem.data('outputShim', setValue );
2091
+ shim.data('outputShim', setValue );
2092
+ return setValue;
2093
+ };
2094
+
2095
+ webshims.addReady(function(context, contextElem){
2096
+ $('output', context).add(contextElem.filter('output')).each(function(){
2097
+ outputCreate(this);
2098
+ });
2099
+ });
2100
+
2101
+ /*
2102
+ * Implements input event in all browsers
2103
+ */
2104
+ (function(){
2105
+ var noInputTriggerEvts = {updateInput: 1, input: 1},
2106
+ noInputTypes = {
2107
+ radio: 1,
2108
+ checkbox: 1,
2109
+ submit: 1,
2110
+ button: 1,
2111
+ image: 1,
2112
+ reset: 1,
2113
+ file: 1
2114
+
2115
+ //pro forma
2116
+ ,color: 1
2117
+ //,range: 1
2118
+ },
2119
+ observe = function(input){
2120
+ var timer,
2121
+ lastVal = input.prop('value'),
2122
+ trigger = function(e){
2123
+ //input === null
2124
+ if(!input){return;}
2125
+ var newVal = input.prop('value');
2126
+
2127
+ if(newVal !== lastVal){
2128
+ lastVal = newVal;
2129
+ if(!e || !noInputTriggerEvts[e.type]){
2130
+ webshims.triggerInlineForm && webshims.triggerInlineForm(input[0], 'input');
2131
+ }
2132
+ }
2133
+ },
2134
+ extraTimer,
2135
+ extraTest = function(){
2136
+ clearTimeout(extraTimer);
2137
+ extraTimer = setTimeout(trigger, 9);
2138
+ },
2139
+ unbind = function(){
2140
+ input.unbind('focusout', unbind).unbind('keyup keypress keydown paste cut', extraTest).unbind('input change updateInput', trigger);
2141
+ clearInterval(timer);
2142
+ setTimeout(function(){
2143
+ trigger();
2144
+ input = null;
2145
+ }, 1);
2146
+
2147
+ }
2148
+ ;
2149
+
2150
+ clearInterval(timer);
2151
+ timer = setInterval(trigger, 99);
2152
+ extraTest();
2153
+ input.on({
2154
+ 'keyup keypress keydown paste cut': extraTest,
2155
+ focusout: unbind,
2156
+ 'input updateInput change': trigger
2157
+ });
2158
+ }
2159
+ ;
2160
+ if($.event.customEvent){
2161
+ $.event.customEvent.updateInput = true;
2162
+ }
2163
+
2164
+ $(doc)
2165
+ .on('focusin', function(e){
2166
+ if( e.target && e.target.type && !e.target.readOnly && !e.target.disabled && (e.target.nodeName || '').toLowerCase() == 'input' && !noInputTypes[e.target.type] ){
2167
+ observe($(e.target));
2168
+ }
2169
+ })
2170
+ ;
2171
+ })();
2172
+ })();
2173
+
2174
+ }); //webshims.ready end
2175
+ }//end formvalidation
2176
+
2177
+ jQuery.webshims.register('form-message', function($, webshims, window, document, undefined, options){
2178
+ "use strict";
2179
+ var validityMessages = webshims.validityMessages;
2180
+
2181
+ var implementProperties = (options.overrideMessages || options.customMessages) ? ['customValidationMessage'] : [];
2182
+
2183
+ validityMessages['en'] = $.extend(true, {
2184
+ typeMismatch: {
2185
+ email: 'Please enter an email address.',
2186
+ url: 'Please enter a URL.',
2187
+ number: 'Please enter a number.',
2188
+ date: 'Please enter a date.',
2189
+ time: 'Please enter a time.',
2190
+ range: 'Invalid input.',
2191
+ "datetime-local": 'Please enter a datetime.'
2192
+ },
2193
+ rangeUnderflow: {
2194
+ defaultMessage: 'Value must be greater than or equal to {%min}.'
2195
+ },
2196
+ rangeOverflow: {
2197
+ defaultMessage: 'Value must be less than or equal to {%max}.'
2198
+ },
2199
+ stepMismatch: 'Invalid input.',
2200
+ tooLong: 'Please enter at most {%maxlength} character(s). You entered {%valueLen}.',
2201
+
2202
+ patternMismatch: 'Invalid input. {%title}',
2203
+ valueMissing: {
2204
+ defaultMessage: 'Please fill out this field.',
2205
+ checkbox: 'Please check this box if you want to proceed.'
2206
+ }
2207
+ }, (validityMessages['en'] || validityMessages['en-US'] || {}));
2208
+
2209
+
2210
+ ['select', 'radio'].forEach(function(type){
2211
+ validityMessages['en'].valueMissing[type] = 'Please select an option.';
2212
+ });
2213
+
2214
+ ['date', 'time', 'datetime-local'].forEach(function(type){
2215
+ validityMessages.en.rangeUnderflow[type] = 'Value must be at or after {%min}.';
2216
+ });
2217
+ ['date', 'time', 'datetime-local'].forEach(function(type){
2218
+ validityMessages.en.rangeOverflow[type] = 'Value must be at or before {%max}.';
2219
+ });
2220
+
2221
+ validityMessages['en-US'] = validityMessages['en-US'] || validityMessages['en'];
2222
+ validityMessages[''] = validityMessages[''] || validityMessages['en-US'];
2223
+
2224
+ validityMessages['de'] = $.extend(true, {
2225
+ typeMismatch: {
2226
+ email: '{%value} ist keine zulässige E-Mail-Adresse',
2227
+ url: '{%value} ist keine zulässige Webadresse',
2228
+ number: '{%value} ist keine Nummer!',
2229
+ date: '{%value} ist kein Datum',
2230
+ time: '{%value} ist keine Uhrzeit',
2231
+ range: '{%value} ist keine Nummer!',
2232
+ "datetime-local": '{%value} ist kein Datum-Uhrzeit Format.'
2233
+ },
2234
+ rangeUnderflow: {
2235
+ defaultMessage: '{%value} ist zu niedrig. {%min} ist der unterste Wert, den Sie benutzen können.'
2236
+ },
2237
+ rangeOverflow: {
2238
+ defaultMessage: '{%value} ist zu hoch. {%max} ist der oberste Wert, den Sie benutzen können.'
2239
+ },
2240
+ stepMismatch: 'Der Wert {%value} ist in diesem Feld nicht zulässig. Hier sind nur bestimmte Werte zulässig. {%title}',
2241
+ tooLong: 'Der eingegebene Text ist zu lang! Sie haben {%valueLen} Zeichen eingegeben, dabei sind {%maxlength} das Maximum.',
2242
+ patternMismatch: '{%value} hat für dieses Eingabefeld ein falsches Format! {%title}',
2243
+ valueMissing: {
2244
+ defaultMessage: 'Bitte geben Sie einen Wert ein',
2245
+ checkbox: 'Bitte aktivieren Sie das Kästchen'
2246
+ }
2247
+ }, (validityMessages['de'] || {}));
2248
+
2249
+ ['select', 'radio'].forEach(function(type){
2250
+ validityMessages['de'].valueMissing[type] = 'Bitte wählen Sie eine Option aus';
2251
+ });
2252
+
2253
+ ['date', 'time', 'datetime-local'].forEach(function(type){
2254
+ validityMessages.de.rangeUnderflow[type] = '{%value} ist zu früh. {%min} ist die früheste Zeit, die Sie benutzen können.';
2255
+ });
2256
+ ['date', 'time', 'datetime-local'].forEach(function(type){
2257
+ validityMessages.de.rangeOverflow[type] = '{%value} ist zu spät. {%max} ist die späteste Zeit, die Sie benutzen können.';
2258
+ });
2259
+
2260
+ var currentValidationMessage = validityMessages[''];
2261
+
2262
+
2263
+ webshims.createValidationMessage = function(elem, name){
2264
+ var message = currentValidationMessage[name];
2265
+ if(message && typeof message !== 'string'){
2266
+ message = message[ $.prop(elem, 'type') ] || message[ (elem.nodeName || '').toLowerCase() ] || message[ 'defaultMessage' ];
2267
+ }
2268
+ if(message){
2269
+ ['value', 'min', 'max', 'title', 'maxlength', 'label'].forEach(function(attr){
2270
+ if(message.indexOf('{%'+attr) === -1){return;}
2271
+ var val = ((attr == 'label') ? $.trim($('label[for="'+ elem.id +'"]', elem.form).text()).replace(/\*$|:$/, '') : $.attr(elem, attr)) || '';
2272
+ if(name == 'patternMismatch' && attr == 'title' && !val){
2273
+ webshims.error('no title for patternMismatch provided. Always add a title attribute.');
2274
+ }
2275
+ message = message.replace('{%'+ attr +'}', val);
2276
+ if('value' == attr){
2277
+ message = message.replace('{%valueLen}', val.length);
2278
+ }
2279
+ });
2280
+ }
2281
+ return message || '';
2282
+ };
2283
+
2284
+
2285
+ if(webshims.bugs.validationMessage || !Modernizr.formvalidation || webshims.bugs.bustedValidity){
2286
+ implementProperties.push('validationMessage');
2287
+ }
2288
+
2289
+ webshims.activeLang({
2290
+ langObj: validityMessages,
2291
+ module: 'form-core',
2292
+ callback: function(langObj){
2293
+ currentValidationMessage = langObj;
2294
+ }
2295
+ });
2296
+
2297
+ implementProperties.forEach(function(messageProp){
2298
+ webshims.defineNodeNamesProperty(['fieldset', 'output', 'button'], messageProp, {
2299
+ prop: {
2300
+ value: '',
2301
+ writeable: false
2302
+ }
2303
+ });
2304
+ ['input', 'select', 'textarea'].forEach(function(nodeName){
2305
+ var desc = webshims.defineNodeNameProperty(nodeName, messageProp, {
2306
+ prop: {
2307
+ get: function(){
2308
+ var elem = this;
2309
+ var message = '';
2310
+ if(!$.prop(elem, 'willValidate')){
2311
+ return message;
2312
+ }
2313
+
2314
+ var validity = $.prop(elem, 'validity') || {valid: 1};
2315
+
2316
+ if(validity.valid){return message;}
2317
+ message = webshims.getContentValidationMessage(elem, validity);
2318
+
2319
+ if(message){return message;}
2320
+
2321
+ if(validity.customError && elem.nodeName){
2322
+ message = (Modernizr.formvalidation && !webshims.bugs.bustedValidity && desc.prop._supget) ? desc.prop._supget.call(elem) : webshims.data(elem, 'customvalidationMessage');
2323
+ if(message){return message;}
2324
+ }
2325
+ $.each(validity, function(name, prop){
2326
+ if(name == 'valid' || !prop){return;}
2327
+
2328
+ message = webshims.createValidationMessage(elem, name);
2329
+ if(message){
2330
+ return false;
2331
+ }
2332
+ });
2333
+ return message || '';
2334
+ },
2335
+ writeable: false
2336
+ }
2337
+ });
2338
+ });
2339
+
2340
+ });
2341
+ });