test_min_attribute.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. <!DOCTYPE HTML>
  2. <html>
  3. <!--
  4. https://bugzilla.mozilla.org/show_bug.cgi?id=635553
  5. -->
  6. <head>
  7. <title>Test for Bug 635553</title>
  8. <script type="application/javascript" src="/MochiKit/packed.js"></script>
  9. <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  10. <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
  11. </head>
  12. <body>
  13. <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=635499">Mozilla Bug 635499</a>
  14. <p id="display"></p>
  15. <div id="content" style="display: none">
  16. </div>
  17. <pre id="test">
  18. <script type="application/javascript">
  19. /** Test for Bug 635553 **/
  20. var data = [
  21. { type: 'hidden', apply: false },
  22. { type: 'text', apply: false },
  23. { type: 'search', apply: false },
  24. { type: 'tel', apply: false },
  25. { type: 'url', apply: false },
  26. { type: 'email', apply: false },
  27. { type: 'password', apply: false },
  28. { type: 'date', apply: true },
  29. { type: 'month', apply: true },
  30. { type: 'week', apply: true },
  31. { type: 'time', apply: true },
  32. { type: 'datetime-local', apply: true },
  33. { type: 'number', apply: true },
  34. { type: 'range', apply: true },
  35. { type: 'color', apply: false },
  36. { type: 'checkbox', apply: false },
  37. { type: 'radio', apply: false },
  38. { type: 'file', apply: false },
  39. { type: 'submit', apply: false },
  40. { type: 'image', apply: false },
  41. { type: 'reset', apply: false },
  42. { type: 'button', apply: false },
  43. ];
  44. var input = document.createElement("input");
  45. document.getElementById('content').appendChild(input);
  46. /**
  47. * @aValidity - boolean indicating whether the element is expected to be valid
  48. * (aElement.validity.valid is true) or not. The value passed is ignored and
  49. * overridden with true if aApply is false.
  50. * @aApply - boolean indicating whether the min/max attributes apply to this
  51. * element type.
  52. * @aRangeApply - A boolean that's set to true if the current input type is a
  53. * "[candidate] for constraint validation" and it "[has] range limitations"
  54. * per http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html#selector-in-range
  55. * (in other words, one of the pseudo classes :in-range and :out-of-range
  56. * should apply (which, depends on aValidity)).
  57. * Else (neither :in-range or :out-of-range should match) set to false.
  58. */
  59. function checkValidity(aElement, aValidity, aApply, aRangeApply)
  60. {
  61. aValidity = aApply ? aValidity : true;
  62. is(aElement.validity.valid, aValidity,
  63. "element validity should be " + aValidity);
  64. is(aElement.validity.rangeUnderflow, !aValidity,
  65. "element underflow status should be " + !aValidity);
  66. var underflowMsg =
  67. (aElement.type == "date" || aElement.type == "time" ||
  68. aElement.type == "month" || aElement.type == "week" ||
  69. aElement.type == "datetime-local") ?
  70. ("Please select a value that is no earlier than " + aElement.min + ".") :
  71. ("Please select a value that is no less than " + aElement.min + ".");
  72. is(aElement.validationMessage,
  73. aValidity ? "" : underflowMsg, "Checking range underflow validation message");
  74. is(aElement.matches(":valid"), aElement.willValidate && aValidity,
  75. (aElement.willValidate && aValidity) ? ":valid should apply" : "valid shouldn't apply");
  76. is(aElement.matches(":invalid"), aElement.willValidate && !aValidity,
  77. (aElement.wil && aValidity) ? ":invalid shouldn't apply" : "valid should apply");
  78. if (!aRangeApply) {
  79. ok(!aElement.matches(":in-range"), ":in-range should not match");
  80. ok(!aElement.matches(":out-of-range"),
  81. ":out-of-range should not match");
  82. } else {
  83. is(aElement.matches(":in-range"), aValidity,
  84. ":in-range matches status should be " + aValidity);
  85. is(aElement.matches(":out-of-range"), !aValidity,
  86. ":out-of-range matches status should be " + !aValidity);
  87. }
  88. }
  89. for (var test of data) {
  90. input.type = test.type;
  91. var apply = test.apply;
  92. if (test.todo) {
  93. todo_is(input.type, test.type, test.type + " isn't implemented yet");
  94. continue;
  95. }
  96. // The element should be valid. Range should not apply when @min and @max are
  97. // undefined, except if the input type is 'range' (since that type has a
  98. // default minimum and maximum).
  99. if (input.type == 'range') {
  100. checkValidity(input, true, apply, true);
  101. } else {
  102. checkValidity(input, true, apply, false);
  103. }
  104. switch (input.type) {
  105. case 'hidden':
  106. case 'text':
  107. case 'search':
  108. case 'password':
  109. case 'url':
  110. case 'tel':
  111. case 'email':
  112. case 'number':
  113. case 'checkbox':
  114. case 'radio':
  115. case 'file':
  116. case 'submit':
  117. case 'reset':
  118. case 'button':
  119. case 'image':
  120. case 'color':
  121. input.min = '999';
  122. break;
  123. case 'date':
  124. input.min = '2012-06-27';
  125. break;
  126. case 'time':
  127. input.min = '20:20';
  128. break;
  129. case 'range':
  130. // range is special, since setting min to 999 will make it invalid since
  131. // it's default maximum is 100, its value would be 999, and it would
  132. // suffer from overflow.
  133. break;
  134. case 'month':
  135. input.min = '2016-06';
  136. break;
  137. case 'week':
  138. input.min = '2016-W39';
  139. break;
  140. case 'datetime-local':
  141. input.min = '2017-01-01T00:00';
  142. break;
  143. default:
  144. ok(false, 'please, add a case for this new type (' + input.type + ')');
  145. }
  146. // The element should still be valid and range should apply if it can.
  147. checkValidity(input, true, apply, apply);
  148. switch (input.type) {
  149. case 'text':
  150. case 'hidden':
  151. case 'search':
  152. case 'password':
  153. case 'tel':
  154. case 'radio':
  155. case 'checkbox':
  156. case 'reset':
  157. case 'button':
  158. case 'submit':
  159. case 'image':
  160. case 'color':
  161. input.value = '0';
  162. checkValidity(input, true, apply, apply);
  163. break;
  164. case 'url':
  165. input.value = 'http://mozilla.org';
  166. checkValidity(input, true, apply, apply);
  167. break;
  168. case 'email':
  169. input.value = 'foo@bar.com';
  170. checkValidity(input, true, apply, apply);
  171. break;
  172. case 'file':
  173. var file = new File([''], '635499_file');
  174. SpecialPowers.wrap(input).mozSetFileArray([file]);
  175. checkValidity(input, true, apply, apply);
  176. break;
  177. case 'date':
  178. input.value = '2012-06-28';
  179. checkValidity(input, true, apply, apply);
  180. input.value = '2012-06-27';
  181. checkValidity(input, true, apply, apply);
  182. input.value = 'foo';
  183. checkValidity(input, true, apply, apply);
  184. input.value = '2012-06-26';
  185. checkValidity(input, false, apply, apply);
  186. input.min = '2012-02-29';
  187. checkValidity(input, true, apply, apply);
  188. input.value = '2012-02-28';
  189. checkValidity(input, false, apply, apply);
  190. input.value = '1000-01-01';
  191. checkValidity(input, false, apply, apply);
  192. input.value = '20120-01-01';
  193. checkValidity(input, true, apply, apply);
  194. input.min = '0050-01-01';
  195. checkValidity(input, true, apply, apply);
  196. input.value = '0049-01-01';
  197. checkValidity(input, false, apply, apply);
  198. input.min = '';
  199. checkValidity(input, true, apply, false);
  200. input.min = 'foo';
  201. checkValidity(input, true, apply, false);
  202. break;
  203. case 'number':
  204. input.min = '0';
  205. input.value = '1';
  206. checkValidity(input, true, apply, apply);
  207. input.value = '0';
  208. checkValidity(input, true, apply, apply);
  209. input.value = 'foo';
  210. checkValidity(input, true, apply, apply);
  211. input.value = '-1';
  212. checkValidity(input, false, apply, apply);
  213. input.min = '-1';
  214. checkValidity(input, true, apply, apply);
  215. input.value = '-42';
  216. checkValidity(input, false, apply, apply);
  217. input.min = '';
  218. checkValidity(input, true, apply, false);
  219. input.min = 'foo';
  220. checkValidity(input, true, apply, false);
  221. // Check that we correctly convert input.min to a double in
  222. // validationMessage.
  223. input.min = "4.333333333333333333333333333333333331";
  224. input.value = "2";
  225. is(input.validationMessage,
  226. "Please select a value that is no less than 4.33333333333333.",
  227. "validation message");
  228. break;
  229. case 'range':
  230. input.min = '0';
  231. input.value = '1';
  232. checkValidity(input, true, apply, apply);
  233. input.value = '0';
  234. checkValidity(input, true, apply, apply);
  235. input.value = 'foo';
  236. checkValidity(input, true, apply, apply);
  237. input.value = '-1';
  238. checkValidity(input, true, apply, apply);
  239. is(input.value, input.min, "the value should have been set to min");
  240. input.min = '-1';
  241. checkValidity(input, true, apply, apply);
  242. input.value = '-42';
  243. checkValidity(input, true, apply, apply);
  244. is(input.value, input.min, "the value should have been set to min");
  245. input.min = '';
  246. checkValidity(input, true, apply, true);
  247. input.min = 'foo';
  248. checkValidity(input, true, apply, true);
  249. // We don't check the conversion of input.min to a double in
  250. // validationMessage for 'range' since range will always clamp the value
  251. // up to at least the minimum (so we will never see the min in a
  252. // validationMessage).
  253. break;
  254. case 'time':
  255. // Don't worry about that.
  256. input.step = 'any';
  257. input.min = '20:20';
  258. input.value = '20:20:01';
  259. checkValidity(input, true, apply, apply);
  260. input.value = '20:20:00';
  261. checkValidity(input, true, apply, apply);
  262. input.value = 'foo';
  263. checkValidity(input, true, apply, apply);
  264. input.value = '10:00';
  265. checkValidity(input, false, apply, apply);
  266. input.min = '20:20:00.001';
  267. input.value = '20:20';
  268. checkValidity(input, false, apply, apply);
  269. input.value = '00:00';
  270. checkValidity(input, false, apply, apply);
  271. input.value = '23:59';
  272. checkValidity(input, true, apply, apply);
  273. input.value = '20:20:01';
  274. checkValidity(input, true, apply, apply);
  275. input.value = '20:20:00.01';
  276. checkValidity(input, true, apply, apply);
  277. input.value = '20:20:00.1';
  278. checkValidity(input, true, apply, apply);
  279. input.min = '00:00:00';
  280. input.value = '01:00';
  281. checkValidity(input, true, apply, apply);
  282. input.value = '00:00:00.000';
  283. checkValidity(input, true, apply, apply);
  284. input.min = '';
  285. checkValidity(input, true, apply, false);
  286. input.min = 'foo';
  287. checkValidity(input, true, apply, false);
  288. break;
  289. case 'month':
  290. input.value = '2016-07';
  291. checkValidity(input, true, apply, apply);
  292. input.value = '2016-06';
  293. checkValidity(input, true, apply, apply);
  294. input.value = 'foo';
  295. checkValidity(input, true, apply, apply);
  296. input.value = '2016-05';
  297. checkValidity(input, false, apply, apply);
  298. input.min = '2016-01';
  299. checkValidity(input, true, apply, apply);
  300. input.value = '2015-12';
  301. checkValidity(input, false, apply, apply);
  302. input.value = '1000-01';
  303. checkValidity(input, false, apply, apply);
  304. input.value = '10000-01';
  305. checkValidity(input, true, apply, apply);
  306. input.min = '0010-01';
  307. checkValidity(input, true, apply, apply);
  308. input.value = '0001-01';
  309. checkValidity(input, false, apply, apply);
  310. input.min = '';
  311. checkValidity(input, true, apply, false);
  312. input.min = 'foo';
  313. checkValidity(input, true, apply, false);
  314. break;
  315. case 'week':
  316. input.value = '2016-W40';
  317. checkValidity(input, true, apply, apply);
  318. input.value = '2016-W39';
  319. checkValidity(input, true, apply, apply);
  320. input.value = 'foo';
  321. checkValidity(input, true, apply, apply);
  322. input.value = '2016-W38';
  323. checkValidity(input, false, apply, apply);
  324. input.min = '2016-W01';
  325. checkValidity(input, true, apply, apply);
  326. input.value = '2015-W53';
  327. checkValidity(input, false, apply, apply);
  328. input.value = '1000-W01';
  329. checkValidity(input, false, apply, apply);
  330. input.value = '10000-01';
  331. checkValidity(input, true, apply, apply);
  332. input.min = '0010-W01';
  333. checkValidity(input, true, apply, apply);
  334. input.value = '0001-W01';
  335. checkValidity(input, false, apply, apply);
  336. input.min = '';
  337. checkValidity(input, true, apply, false);
  338. input.min = 'foo';
  339. checkValidity(input, true, apply, false);
  340. break;
  341. case 'datetime-local':
  342. input.value = '2017-12-31T23:59';
  343. checkValidity(input, true, apply, apply);
  344. input.value = '2017-01-01T00:00';
  345. checkValidity(input, true, apply, apply);
  346. input.value = '2017-01-01T00:00:00.123';
  347. checkValidity(input, true, apply, apply);
  348. input.value = 'foo';
  349. checkValidity(input, true, apply, apply);
  350. input.value = '2016-12-31T23:59';
  351. checkValidity(input, false, apply, apply);
  352. input.min = '2016-01-01T00:00';
  353. checkValidity(input, true, apply, apply);
  354. input.value = '2015-12-31T23:59';
  355. checkValidity(input, false, apply, apply);
  356. input.value = '1000-01-01T00:00';
  357. checkValidity(input, false, apply, apply);
  358. input.value = '10000-01-01T00:00';
  359. checkValidity(input, true, apply, apply);
  360. input.min = '0010-01-01T12:00';
  361. checkValidity(input, true, apply, apply);
  362. input.value = '0010-01-01T10:00';
  363. checkValidity(input, false, apply, apply);
  364. input.min = '';
  365. checkValidity(input, true, apply, false);
  366. input.min = 'foo';
  367. checkValidity(input, true, apply, false);
  368. break;
  369. default:
  370. ok(false, 'write tests for ' + input.type);
  371. }
  372. // Cleaning up,
  373. input.removeAttribute('min');
  374. input.value = '';
  375. }
  376. </script>
  377. </pre>
  378. </body>
  379. </html>