test_bug430351.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. <!DOCTYPE HTML>
  2. <html>
  3. <!--
  4. https://bugzilla.mozilla.org/show_bug.cgi?id=430351
  5. -->
  6. <head>
  7. <title>Test for Bug 430351</title>
  8. <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
  9. <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  10. <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
  11. <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
  12. </head>
  13. <body>
  14. <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=430351">Mozilla Bug 430351</a>
  15. <p id="display"></p>
  16. <div id="content">
  17. <div id="parent"></div>
  18. <div id="editableParent" contenteditable="true"></div>
  19. <iframe id="frame"></iframe>
  20. <map name="map"><area></map>
  21. </div>
  22. <pre id="test">
  23. <script class="testbody" type="text/javascript">
  24. /** Test for Bug 430351 **/
  25. var focusableElements = [
  26. "<a tabindex=\"-1\"></a>",
  27. "<a tabindex=\"0\"></a>",
  28. "<a tabindex=\"0\" disabled></a>",
  29. "<a tabindex=\"1\"></a>",
  30. "<a contenteditable=\"true\"></a>",
  31. "<a href=\"#\"></a>",
  32. "<a href=\"#\" tabindex=\"-1\"></a>",
  33. "<a href=\"#\" tabindex=\"0\"></a>",
  34. "<a href=\"#\" tabindex=\"0\" disabled></a>",
  35. "<a href=\"#\" tabindex=\"1\"></a>",
  36. "<a href=\"#\" contenteditable=\"true\"></a>",
  37. "<a href=\"#\" disabled></a>",
  38. "<button></button>",
  39. "<button tabindex=\"-1\"></button>",
  40. "<button tabindex=\"0\"></button>",
  41. "<button tabindex=\"1\"></button>",
  42. "<button contenteditable=\"true\"></button>",
  43. "<button type=\"reset\"></button>",
  44. "<button type=\"reset\" tabindex=\"-1\"></button>",
  45. "<button type=\"reset\" tabindex=\"0\"></button>",
  46. "<button type=\"reset\" tabindex=\"1\"></button>",
  47. "<button type=\"reset\" contenteditable=\"true\"></button>",
  48. "<button type=\"submit\"></button>",
  49. "<button type=\"submit\" tabindex=\"-1\"></button>",
  50. "<button type=\"submit\" tabindex=\"0\"></button>",
  51. "<button type=\"submit\" tabindex=\"1\"></button>",
  52. "<button type=\"submit\" contenteditable=\"true\"></button>",
  53. "<div tabindex=\"-1\"></div>",
  54. "<div tabindex=\"0\"></div>",
  55. "<div tabindex=\"1\"></div>",
  56. "<div contenteditable=\"true\"></div>",
  57. "<div tabindex=\"0\" disabled></div>",
  58. "<embed>",
  59. "<embed tabindex=\"-1\">",
  60. "<embed tabindex=\"0\">",
  61. "<embed tabindex=\"0\" disabled>",
  62. "<embed tabindex=\"1\">",
  63. "<embed disabled>",
  64. "<embed contenteditable=\"true\">",
  65. "<iframe contenteditable=\"true\"></iframe>",
  66. "<iframe src=\"about:blank\"></iframe>",
  67. "<iframe src=\"about:blank\" disabled></iframe>",
  68. "<iframe src=\"about:blank\" tabindex=\"-1\"></iframe>",
  69. "<iframe src=\"about:blank\" tabindex=\"0\"></iframe>",
  70. "<iframe src=\"about:blank\" tabindex=\"0\" disabled></iframe>",
  71. "<iframe src=\"about:blank\" tabindex=\"1\"></iframe>",
  72. "<iframe src=\"about:blank\" contenteditable=\"true\"></iframe>",
  73. "<iframe></iframe>",
  74. "<iframe tabindex=\"-1\"></iframe>",
  75. "<iframe tabindex=\"0\"></iframe>",
  76. "<iframe tabindex=\"0\" disabled></iframe>",
  77. "<iframe tabindex=\"1\"></iframe>",
  78. "<iframe disabled></iframe>",
  79. "<img tabindex=\"-1\">",
  80. "<img tabindex=\"0\">",
  81. "<img tabindex=\"0\" disabled>",
  82. "<img tabindex=\"1\">",
  83. "<input>",
  84. "<input tabindex=\"-1\">",
  85. "<input tabindex=\"0\">",
  86. "<input tabindex=\"1\">",
  87. "<input contenteditable=\"true\">",
  88. "<input type=\"button\">",
  89. "<input type=\"button\" tabindex=\"-1\">",
  90. "<input type=\"button\" tabindex=\"0\">",
  91. "<input type=\"button\" tabindex=\"1\">",
  92. "<input type=\"button\" contenteditable=\"true\">",
  93. "<input type=\"checkbox\">",
  94. "<input type=\"checkbox\" tabindex=\"-1\">",
  95. "<input type=\"checkbox\" tabindex=\"0\">",
  96. "<input type=\"checkbox\" tabindex=\"1\">",
  97. "<input type=\"checkbox\" contenteditable=\"true\">",
  98. "<input type=\"image\">",
  99. "<input type=\"image\" tabindex=\"-1\">",
  100. "<input type=\"image\" tabindex=\"0\">",
  101. "<input type=\"image\" tabindex=\"1\">",
  102. "<input type=\"image\" contenteditable=\"true\">",
  103. "<input type=\"password\">",
  104. "<input type=\"password\" tabindex=\"-1\">",
  105. "<input type=\"password\" tabindex=\"0\">",
  106. "<input type=\"password\" tabindex=\"1\">",
  107. "<input type=\"password\" contenteditable=\"true\">",
  108. "<input type=\"radio\">",
  109. "<input type=\"radio\" tabindex=\"-1\">",
  110. "<input type=\"radio\" tabindex=\"0\">",
  111. "<input type=\"radio\" tabindex=\"1\">",
  112. "<input type=\"radio\" contenteditable=\"true\">",
  113. "<input type=\"radio\" checked>",
  114. "<form><input type=\"radio\" name=\"foo\"></form>",
  115. "<input type=\"reset\">",
  116. "<input type=\"reset\" tabindex=\"-1\">",
  117. "<input type=\"reset\" tabindex=\"0\">",
  118. "<input type=\"reset\" tabindex=\"1\">",
  119. "<input type=\"reset\" contenteditable=\"true\">",
  120. "<input type=\"submit\">",
  121. "<input type=\"submit\" tabindex=\"-1\">",
  122. "<input type=\"submit\" tabindex=\"0\">",
  123. "<input type=\"submit\" tabindex=\"1\">",
  124. "<input type=\"submit\" contenteditable=\"true\">",
  125. "<input type=\"text\">",
  126. "<input type=\"text\" tabindex=\"-1\">",
  127. "<input type=\"text\" tabindex=\"0\">",
  128. "<input type=\"text\" tabindex=\"1\">",
  129. "<input type=\"text\" contenteditable=\"true\">",
  130. "<input type=\"number\">",
  131. "<input type=\"number\" tabindex=\"-1\">",
  132. "<input type=\"number\" tabindex=\"0\">",
  133. "<input type=\"number\" tabindex=\"1\">",
  134. "<input type=\"number\" contenteditable=\"true\">",
  135. "<object tabindex=\"-1\"></object>",
  136. "<object tabindex=\"0\"></object>",
  137. "<object tabindex=\"1\"></object>",
  138. "<object contenteditable=\"true\"></object>",
  139. "<object classid=\"java:a\"></object>",
  140. "<object classid=\"java:a\" tabindex=\"-1\"></object>",
  141. "<object classid=\"java:a\" tabindex=\"0\"></object>",
  142. "<object classid=\"java:a\" tabindex=\"0\" disabled></object>",
  143. "<object classid=\"java:a\" tabindex=\"1\"></object>",
  144. "<object classid=\"java:a\" disabled></object>",
  145. "<object classid=\"java:a\" contenteditable=\"true\"></object>",
  146. "<select></select>",
  147. "<select tabindex=\"-1\"></select>",
  148. "<select tabindex=\"0\"></select>",
  149. "<select tabindex=\"1\"></select>",
  150. "<select contenteditable=\"true\"></select>",
  151. "<option tabindex='-1'></option>",
  152. "<option tabindex='0'></option>",
  153. "<option tabindex='1'></option>",
  154. "<option contenteditable></option>",
  155. "<optgroup tabindex='-1'></optgroup>",
  156. "<optgroup tabindex='0'></optgroup>",
  157. "<optgroup tabindex='1'></optgroup>",
  158. "<optgroup contenteditable></optgroup>"
  159. ];
  160. var nonFocusableElements = [
  161. "<a></a>",
  162. "<a disabled></a>",
  163. "<button tabindex=\"0\" disabled></button>",
  164. "<button disabled></button>",
  165. "<button type=\"reset\" tabindex=\"0\" disabled></button>",
  166. "<button type=\"reset\" disabled></button>",
  167. "<button type=\"submit\" tabindex=\"0\" disabled></button>",
  168. "<button type=\"submit\" disabled></button>",
  169. "<div></div>",
  170. "<div disabled></div>",
  171. "<img>",
  172. "<img disabled>",
  173. "<img contenteditable=\"true\">",
  174. "<img usemap=\"#map\">",
  175. "<img usemap=\"#map\" tabindex=\"-1\">",
  176. "<img usemap=\"#map\" tabindex=\"0\">",
  177. "<img usemap=\"#map\" tabindex=\"0\" disabled>",
  178. "<img usemap=\"#map\" tabindex=\"1\">",
  179. "<img usemap=\"#map\" disabled>",
  180. "<img usemap=\"#map\" contenteditable=\"true\">",
  181. "<input tabindex=\"0\" disabled>",
  182. "<input disabled>",
  183. "<input type=\"button\" tabindex=\"0\" disabled>",
  184. "<input type=\"button\" disabled>",
  185. "<input type=\"checkbox\" tabindex=\"0\" disabled>",
  186. "<input type=\"checkbox\" disabled>",
  187. "<input type=\"file\" tabindex=\"0\" disabled>",
  188. "<input type=\"file\" disabled>",
  189. "<input type=\"hidden\">",
  190. "<input type=\"hidden\" tabindex=\"-1\">",
  191. "<input type=\"hidden\" tabindex=\"0\">",
  192. "<input type=\"hidden\" tabindex=\"0\" disabled>",
  193. "<input type=\"hidden\" tabindex=\"1\">",
  194. "<input type=\"hidden\" disabled>",
  195. "<input type=\"hidden\" contenteditable=\"true\">",
  196. "<input type=\"image\" tabindex=\"0\" disabled>",
  197. "<input type=\"image\" disabled>",
  198. "<input type=\"password\" tabindex=\"0\" disabled>",
  199. "<input type=\"password\" disabled>",
  200. "<input type=\"radio\" tabindex=\"0\" disabled>",
  201. "<input type=\"radio\" disabled>",
  202. "<input type=\"reset\" tabindex=\"0\" disabled>",
  203. "<input type=\"reset\" disabled>",
  204. "<input type=\"submit\" tabindex=\"0\" disabled>",
  205. "<input type=\"submit\" disabled>",
  206. "<input type=\"text\" tabindex=\"0\" disabled>",
  207. "<input type=\"text\" disabled>",
  208. "<object></object>",
  209. "<select tabindex=\"0\" disabled></select>",
  210. "<select disabled></select>",
  211. "<option></option>",
  212. "<option tabindex='1' disabled></option>",
  213. "<optgroup></optgroup>",
  214. "<optgroup tabindex='1' disabled></optgroup>"
  215. ];
  216. var focusableInContentEditable = [
  217. "<button></button>",
  218. "<button tabindex=\"-1\"></button>",
  219. "<button tabindex=\"0\"></button>",
  220. "<button tabindex=\"1\"></button>",
  221. "<button contenteditable=\"true\"></button>",
  222. "<button type=\"reset\"></button>",
  223. "<button type=\"reset\" tabindex=\"-1\"></button>",
  224. "<button type=\"reset\" tabindex=\"0\"></button>",
  225. "<button type=\"reset\" tabindex=\"1\"></button>",
  226. "<button type=\"reset\" contenteditable=\"true\"></button>",
  227. "<button type=\"submit\"></button>",
  228. "<button type=\"submit\" tabindex=\"-1\"></button>",
  229. "<button type=\"submit\" tabindex=\"0\"></button>",
  230. "<button type=\"submit\" tabindex=\"1\"></button>",
  231. "<button type=\"submit\" contenteditable=\"true\"></button>",
  232. "<div tabindex=\"-1\"></div>",
  233. "<div tabindex=\"0\"></div>",
  234. "<div tabindex=\"1\"></div>",
  235. "<div tabindex=\"0\" disabled></div>",
  236. "<embed>",
  237. "<embed tabindex=\"-1\">",
  238. "<embed tabindex=\"0\">",
  239. "<embed tabindex=\"0\" disabled>",
  240. "<embed tabindex=\"1\">",
  241. "<embed disabled>",
  242. "<embed contenteditable=\"true\">",
  243. "<iframe src=\"about:blank\"></iframe>",
  244. "<iframe></iframe>",
  245. "<iframe src=\"about:blank\" disabled></iframe>",
  246. "<iframe disabled></iframe>",
  247. "<iframe src=\"about:blank\" tabindex=\"-1\"></iframe>",
  248. "<iframe tabindex=\"-1\"></iframe>",
  249. "<iframe src=\"about:blank\" tabindex=\"0\"></iframe>",
  250. "<iframe tabindex=\"0\"></iframe>",
  251. "<iframe src=\"about:blank\" tabindex=\"0\" disabled></iframe>",
  252. "<iframe tabindex=\"0\" disabled></iframe>",
  253. "<iframe src=\"about:blank\" tabindex=\"1\"></iframe>",
  254. "<iframe tabindex=\"1\"></iframe>",
  255. "<iframe src=\"about:blank\" contenteditable=\"true\"></iframe>",
  256. "<iframe contenteditable=\"true\"></iframe>",
  257. "<img tabindex=\"-1\">",
  258. "<img tabindex=\"0\">",
  259. "<img tabindex=\"0\" disabled>",
  260. "<img tabindex=\"1\">",
  261. "<input>",
  262. "<input tabindex=\"-1\">",
  263. "<input tabindex=\"0\">",
  264. "<input tabindex=\"1\">",
  265. "<input contenteditable=\"true\">",
  266. "<input type=\"button\">",
  267. "<input type=\"button\" tabindex=\"-1\">",
  268. "<input type=\"button\" tabindex=\"0\">",
  269. "<input type=\"button\" tabindex=\"1\">",
  270. "<input type=\"button\" contenteditable=\"true\">",
  271. "<input type=\"file\">",
  272. "<input type=\"file\" tabindex=\"-1\">",
  273. "<input type=\"file\" tabindex=\"0\">",
  274. "<input type=\"file\" tabindex=\"1\">",
  275. "<input type=\"file\" contenteditable=\"true\">",
  276. "<input type=\"checkbox\">",
  277. "<input type=\"checkbox\" tabindex=\"-1\">",
  278. "<input type=\"checkbox\" tabindex=\"0\">",
  279. "<input type=\"checkbox\" tabindex=\"1\">",
  280. "<input type=\"checkbox\" contenteditable=\"true\">",
  281. "<input type=\"image\">",
  282. "<input type=\"image\" tabindex=\"-1\">",
  283. "<input type=\"image\" tabindex=\"0\">",
  284. "<input type=\"image\" tabindex=\"1\">",
  285. "<input type=\"image\" contenteditable=\"true\">",
  286. "<input type=\"password\">",
  287. "<input type=\"password\" tabindex=\"-1\">",
  288. "<input type=\"password\" tabindex=\"0\">",
  289. "<input type=\"password\" tabindex=\"1\">",
  290. "<input type=\"password\" contenteditable=\"true\">",
  291. "<input type=\"radio\">",
  292. "<input type=\"radio\" tabindex=\"-1\">",
  293. "<input type=\"radio\" tabindex=\"0\">",
  294. "<input type=\"radio\" tabindex=\"1\">",
  295. "<input type=\"radio\" contenteditable=\"true\">",
  296. "<input type=\"radio\" checked>",
  297. "<form><input type=\"radio\" name=\"foo\"></form>",
  298. "<input type=\"reset\">",
  299. "<input type=\"reset\" tabindex=\"-1\">",
  300. "<input type=\"reset\" tabindex=\"0\">",
  301. "<input type=\"reset\" tabindex=\"1\">",
  302. "<input type=\"reset\" contenteditable=\"true\">",
  303. "<input type=\"submit\">",
  304. "<input type=\"submit\" tabindex=\"-1\">",
  305. "<input type=\"submit\" tabindex=\"0\">",
  306. "<input type=\"submit\" tabindex=\"1\">",
  307. "<input type=\"submit\" contenteditable=\"true\">",
  308. "<input type=\"text\">",
  309. "<input type=\"text\" tabindex=\"-1\">",
  310. "<input type=\"text\" tabindex=\"0\">",
  311. "<input type=\"text\" tabindex=\"1\">",
  312. "<input type=\"text\" contenteditable=\"true\">",
  313. "<input type=\"number\">",
  314. "<input type=\"number\" tabindex=\"-1\">",
  315. "<input type=\"number\" tabindex=\"0\">",
  316. "<input type=\"number\" tabindex=\"1\">",
  317. "<input type=\"number\" contenteditable=\"true\">",
  318. "<object tabindex=\"-1\"></object>",
  319. "<object tabindex=\"0\"></object>",
  320. "<object tabindex=\"1\"></object>",
  321. // Disabled doesn't work for <object>.
  322. "<object tabindex=\"0\" disabled></object>",
  323. "<object disabled></object>",
  324. "<select></select>",
  325. "<select tabindex=\"-1\"></select>",
  326. "<select tabindex=\"0\"></select>",
  327. "<select tabindex=\"1\"></select>",
  328. "<select contenteditable=\"true\"></select>",
  329. "<option tabindex='-1'></option>",
  330. "<option tabindex='0'></option>",
  331. "<option tabindex='1'></option>",
  332. "<optgroup tabindex='-1'></optgroup>",
  333. "<optgroup tabindex='0'></optgroup>",
  334. "<optgroup tabindex='1'></optgroup>"
  335. ];
  336. var focusableInDesignMode = [
  337. "<embed>",
  338. "<embed tabindex=\"-1\">",
  339. "<embed tabindex=\"0\">",
  340. "<embed tabindex=\"0\" disabled>",
  341. "<embed tabindex=\"1\">",
  342. "<embed disabled>",
  343. "<embed contenteditable=\"true\">",
  344. "<img tabindex=\"-1\">",
  345. "<img tabindex=\"0\">",
  346. "<img tabindex=\"0\" disabled>",
  347. "<img tabindex=\"1\">",
  348. ];
  349. // Can't currently test these, need a plugin.
  350. var focusableElementsTODO = [
  351. "<object classid=\"java:a\"></object>",
  352. "<object classid=\"java:a\" tabindex=\"-1\"></object>",
  353. "<object classid=\"java:a\" tabindex=\"0\"></object>",
  354. "<object classid=\"java:a\" tabindex=\"0\" disabled></object>",
  355. "<object classid=\"java:a\" tabindex=\"1\"></object>",
  356. "<object classid=\"java:a\" disabled></object>",
  357. "<object classid=\"java:a\" contenteditable=\"true\"></object>",
  358. ];
  359. var serializer = new XMLSerializer();
  360. function testElements(parent, tags, shouldBeFocusable)
  361. {
  362. var focusable, errorSuffix = "";
  363. if (parent.ownerDocument.designMode == "on") {
  364. focusable = focusableInDesignMode;
  365. errorSuffix = " in a document with designMode=on";
  366. }
  367. else if (parent.contentEditable == "true") {
  368. focusable = focusableInContentEditable;
  369. }
  370. for (var tag of tags) {
  371. parent.ownerDocument.body.focus();
  372. if (focusableElementsTODO.indexOf(tag) > -1) {
  373. todo_is(parent.ownerDocument.activeElement, parent.firstChild,
  374. tag + " should be focusable" + errorSuffix);
  375. continue;
  376. }
  377. parent.innerHTML = tag;
  378. // Focus the deepest descendant.
  379. var descendant = parent;
  380. while ((descendant = descendant.firstChild))
  381. element = descendant;
  382. if (element.nodeName == "IFRAME" && element.hasAttribute("src"))
  383. var foo = element.contentDocument;
  384. element.focus();
  385. var errorPrefix = serializer.serializeToString(element) + " in " +
  386. serializer.serializeToString(parent);
  387. try {
  388. // Make sure activeElement doesn't point to a
  389. // native anonymous element.
  390. parent.ownerDocument.activeElement.localName;
  391. } catch (ex) {
  392. ok(false, ex + errorPrefix + errorSuffix);
  393. }
  394. if (focusable ? focusable.indexOf(tag) > -1 : shouldBeFocusable) {
  395. is(parent.ownerDocument.activeElement, element,
  396. errorPrefix + " should be focusable" + errorSuffix);
  397. }
  398. else {
  399. isnot(parent.ownerDocument.activeElement, element,
  400. errorPrefix + " should not be focusable" + errorSuffix);
  401. }
  402. parent.innerHTML = "";
  403. }
  404. }
  405. function test()
  406. {
  407. var parent = document.getElementById("parent");
  408. var editableParent = document.getElementById("editableParent");
  409. testElements(parent, focusableElements, true);
  410. testElements(parent, nonFocusableElements, false);
  411. testElements(editableParent, focusableElements, true);
  412. testElements(editableParent, nonFocusableElements, false);
  413. var frame = document.getElementById("frame");
  414. frame.contentDocument.body.innerHTML = document.getElementById("content").innerHTML;
  415. frame.contentDocument.designMode = "on";
  416. parent = frame.contentDocument.getElementById("parent");
  417. editableParent = frame.contentDocument.getElementById("editableParent");
  418. testElements(parent, focusableElements, false);
  419. testElements(parent, nonFocusableElements, false);
  420. testElements(editableParent, focusableElements, false);
  421. testElements(editableParent, nonFocusableElements, false);
  422. }
  423. SimpleTest.waitForExplicitFinish();
  424. addLoadEvent(test);
  425. addLoadEvent(SimpleTest.finish);
  426. </script>
  427. </pre>
  428. </body>
  429. </html>