|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=238987 |
|
5 --> |
|
6 <head> |
|
7 <title>Test for Bug 238987</title> |
|
8 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
10 </head> |
|
11 <body> |
|
12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=238987">Mozilla Bug 238987</a> |
|
13 <p id="display"></p> |
|
14 <div id="content" style="display: none"> |
|
15 |
|
16 </div> |
|
17 <pre id="test"> |
|
18 <script class="testbody" type="text/javascript"> |
|
19 |
|
20 /** Test for Bug 238987 **/ |
|
21 |
|
22 var shouldStop = false; |
|
23 var modifier = 0; |
|
24 var expectedResult = "i1,i2,i3,i4,i5,i6,i7,i8,number,i9,i10,i11,i12"; |
|
25 var forwardFocusArray = expectedResult.split(","); |
|
26 var backwardFocusArray = expectedResult.split(","); |
|
27 var forwardBlurArray = expectedResult.split(","); |
|
28 var backwardBlurArray = expectedResult.split(","); |
|
29 // Adding 3 for "begin", "end", "begin" and one for the <a> in the Mochitest template, |
|
30 var expectedWindowFocusCount = forwardFocusArray.length + backwardFocusArray.length + 4; |
|
31 // but the last blur event goes to i1, not "begin". |
|
32 var expectedWindowBlurCount = forwardFocusArray.length + backwardFocusArray.length + 3; |
|
33 |
|
34 // accessibility.tabfocus must be set to value 7 before running test also |
|
35 // on a mac. |
|
36 function setOrRestoreTabFocus(newValue) { |
|
37 if (!newValue) { |
|
38 SpecialPowers.clearUserPref("accessibility.tabfocus"); |
|
39 } else { |
|
40 SpecialPowers.setIntPref("accessibility.tabfocus", newValue); |
|
41 } |
|
42 } |
|
43 |
|
44 function handleFocus(e) { |
|
45 if (e.target.id == "begin") { |
|
46 // if the modifier is set, the test is coming back from the end. |
|
47 if (modifier) { |
|
48 shouldStop = true; |
|
49 } |
|
50 } else if (e.target.id == "end") { |
|
51 modifier = Components.interfaces.nsIDOMEvent.SHIFT_MASK; |
|
52 } else if (modifier) { |
|
53 var expected = backwardFocusArray.pop(); |
|
54 ok(expected == e.target.id, |
|
55 "(focus) Backward tabbing, expected [" + |
|
56 expected + "], got [" + e.target.id + "]"); |
|
57 } else { |
|
58 var expected = forwardFocusArray.shift(); |
|
59 is(e.target, document.activeElement, "Wrong activeElement!"); |
|
60 ok(expected == e.target.id, |
|
61 "(focus) Forward tabbing, expected [" + |
|
62 expected + "], got [" + e.target.id + "]"); |
|
63 } |
|
64 } |
|
65 |
|
66 function handleWindowFocus(e) { |
|
67 --expectedWindowFocusCount; |
|
68 var s = "target " + e.target; |
|
69 if ("id" in e.target) { |
|
70 s = s + ", id=\"" + e.target.id + "\""; |
|
71 } |
|
72 ok(e.eventPhase == Components.interfaces.nsIDOMEvent.CAPTURING_PHASE, |
|
73 "|window| should not have got a focus event, " + s); |
|
74 } |
|
75 |
|
76 function handleBlur(e) { |
|
77 if (e.target.id == "begin" || e.target.id == "end") { |
|
78 return; |
|
79 } else if (modifier) { |
|
80 var expected = backwardBlurArray.pop(); |
|
81 ok(expected == e.target.id, |
|
82 "(blur) backward tabbing, expected [" + |
|
83 expected + "], got [" + e.target.id + "]"); |
|
84 } else { |
|
85 var expected = forwardBlurArray.shift(); |
|
86 ok(expected == e.target.id, |
|
87 "(blur) forward tabbing, expected [" + |
|
88 expected + "], got [" + e.target.id + "]"); |
|
89 } |
|
90 } |
|
91 |
|
92 function handleWindowBlur(e) { |
|
93 --expectedWindowBlurCount; |
|
94 var s = "target " + e.target; |
|
95 if ("id" in e.target) { |
|
96 s = s + ", id=\"" + e.target.id + "\""; |
|
97 } |
|
98 ok(e.eventPhase == Components.interfaces.nsIDOMEvent.CAPTURING_PHASE, |
|
99 "|window| should not have got a blur event, " + s); |
|
100 } |
|
101 |
|
102 function tab() { |
|
103 var utils = SpecialPowers.DOMWindowUtils; |
|
104 // Send tab key events. |
|
105 var key = Components.interfaces.nsIDOMKeyEvent.DOM_VK_TAB; |
|
106 utils.sendKeyEvent("keydown", key, 0, modifier); |
|
107 utils.sendKeyEvent("keypress", key, 0, modifier); |
|
108 utils.sendKeyEvent("keyup", key, 0, modifier); |
|
109 if (shouldStop) { |
|
110 // Did focus handling succeed |
|
111 is(forwardFocusArray.length, 0, |
|
112 "Not all forward tabbing focus tests were run, " + |
|
113 forwardFocusArray.toString()); |
|
114 is(backwardFocusArray.length, 0, |
|
115 "Not all backward tabbing focus tests were run, " + |
|
116 backwardFocusArray.toString()); |
|
117 is(expectedWindowFocusCount, 0, |
|
118 "|window| didn't get the right amount of focus events"); |
|
119 |
|
120 // and blur. |
|
121 is(forwardBlurArray.length, 0, |
|
122 "Not all forward tabbing blur tests were run, " + |
|
123 forwardBlurArray.toString()); |
|
124 is(backwardBlurArray.length, 0, |
|
125 "Not all backward tabbing blur tests were run, " + |
|
126 backwardBlurArray.toString()); |
|
127 is(expectedWindowBlurCount, 0, |
|
128 "|window| didn't get the right amount of blur events"); |
|
129 |
|
130 // Cleanup |
|
131 setOrRestoreTabFocus(0); |
|
132 window.removeEventListener("focus", handleWindowFocus, true); |
|
133 window.removeEventListener("focus", handleWindowFocus, false); |
|
134 window.removeEventListener("blur", handleWindowBlur, true); |
|
135 window.removeEventListener("blur", handleWindowBlur, false); |
|
136 var elements = document.getElementsByTagName("*"); |
|
137 for (var i = 0; i < elements.length; ++i) { |
|
138 if (elements[i].hasAttribute("id")) { |
|
139 elements[i].removeEventListener("focus", handleFocus, false); |
|
140 elements[i].removeEventListener("blur", handleBlur, false); |
|
141 } |
|
142 } |
|
143 |
|
144 SimpleTest.finish(); |
|
145 } else { |
|
146 setTimeout(tab, 0); |
|
147 } |
|
148 } |
|
149 |
|
150 function start() { |
|
151 window.focus(); |
|
152 window.addEventListener("focus", handleWindowFocus, true); |
|
153 window.addEventListener("focus", handleWindowFocus, false); |
|
154 window.addEventListener("blur", handleWindowBlur, true); |
|
155 window.addEventListener("blur", handleWindowBlur, false); |
|
156 var elements = document.getElementsByTagName("*"); |
|
157 for (var i = 0; i < elements.length; ++i) { |
|
158 if (elements[i].hasAttribute("id")) { |
|
159 elements[i].addEventListener("focus", handleFocus, false); |
|
160 elements[i].addEventListener("blur", handleBlur, false); |
|
161 } |
|
162 if (elements[i].getAttribute("tabindex") == "1") { |
|
163 elements[i].setAttribute("tabindex", "-1"); |
|
164 } |
|
165 } |
|
166 tab(); |
|
167 } |
|
168 |
|
169 function doTest() { |
|
170 setOrRestoreTabFocus(7); |
|
171 setTimeout(start, 0); |
|
172 } |
|
173 |
|
174 SimpleTest.waitForExplicitFinish(); |
|
175 addLoadEvent(doTest); |
|
176 |
|
177 </script> |
|
178 </pre> |
|
179 <h4 tabindex="0" id="begin">Test:</h4> |
|
180 <table> |
|
181 <tbody> |
|
182 <tr> |
|
183 <td>type="text"</td><td><input type="text" id="i1" value=""></td> |
|
184 </tr> |
|
185 <tr> |
|
186 <td>type="button"</td><td><input type="button" id="i2" value="type='button'"></td> |
|
187 </tr> |
|
188 <tr> |
|
189 <td>type="checkbox"</td><td><input type="checkbox" id="i3" ></td> |
|
190 </tr> |
|
191 <tr> |
|
192 <td>type="radio" checked</td><td><input type="radio" id="i4" name="radio" checked> |
|
193 <input type="radio" id="i4b" name="radio"></td> |
|
194 </tr> |
|
195 <tr> |
|
196 <td>type="radio"</td><td><input type="radio" id="i5" name="radio2"> |
|
197 <input type="radio" id="i6" name="radio2"></td> |
|
198 </tr> |
|
199 <tr> |
|
200 <td>type="password"</td><td><input type="password" id="i7"></td> |
|
201 </tr> |
|
202 <tr> |
|
203 <td>type="file"</td><td><input type="file" id="i8"></td> |
|
204 </tr> |
|
205 <tr> |
|
206 <td>type="number"</td><td><input type="number" id="number"></td> |
|
207 </tr> |
|
208 <tr> |
|
209 <td>button</td><td><button id="i9">button</button></td> |
|
210 </tr> |
|
211 <tr> |
|
212 <td>select</td><td><select id="i10"><option>select</option></select></td> |
|
213 </tr> |
|
214 <tr> |
|
215 <td>a</td><td><a href="#radio" id="i11">a link</a></td> |
|
216 </tr> |
|
217 <tr> |
|
218 <td>tabindex="0"</td><td><span tabindex="0" id="i12">span</span></td> |
|
219 </tr> |
|
220 |
|
221 <tr> |
|
222 <td><h3>Form elements with tabindex="-1"</h3></td> |
|
223 </tr> |
|
224 <tr> |
|
225 <td>type="text"</td><td><input type="text" tabindex="-1" value=""></td> |
|
226 </tr> |
|
227 <tr> |
|
228 <td>type="button"</td><td><input type="button" tabindex="-1" value="type='button'"></td> |
|
229 </tr> |
|
230 <tr> |
|
231 <td>type="checkbox"</td><td><input type="checkbox" tabindex="-1"></td> |
|
232 </tr> |
|
233 <tr> |
|
234 <td>type="radio" checked</td><td><input type="radio" tabindex="-1" name="radio3" checked> |
|
235 <input type="radio" tabindex="-1" name="radio3"></td> |
|
236 </tr> |
|
237 <tr> |
|
238 <td>type="radio"</td><td><input type="radio" tabindex="-1" name="radio4"> |
|
239 <input type="radio" tabindex="-1" name="radio4"></td> |
|
240 </tr> |
|
241 <tr> |
|
242 <td>type="password"</td><td><input type="password" tabindex="-1"></td> |
|
243 </tr> |
|
244 <tr> |
|
245 <td>type="file"</td><td><input type="file" tabindex="-1"></td> |
|
246 </tr> |
|
247 <tr> |
|
248 <td>button</td><td><button tabindex="-1">button</button></td> |
|
249 </tr> |
|
250 <tr> |
|
251 <td>select</td><td><select tabindex="-1"><option>select</option></select></td> |
|
252 </tr> |
|
253 |
|
254 <tr> |
|
255 <td><h3>Form elements with .setAttribute("tabindex", "-1")</h3></td> |
|
256 </tr> |
|
257 <tr> |
|
258 <td>type="text"</td><td><input type="text" tabindex="1" value=""></td> |
|
259 </tr> |
|
260 <tr> |
|
261 <td>type="button"</td><td><input type="button" tabindex="1" value="type='button'"></td> |
|
262 </tr> |
|
263 <tr> |
|
264 <td>type="checkbox"</td><td><input type="checkbox" tabindex="1"></td> |
|
265 </tr> |
|
266 <tr> |
|
267 <td>type="radio" checked</td><td><input type="radio" tabindex="1" name="radio5" checked> |
|
268 <input type="radio" tabindex="1" name="radio5"></td> |
|
269 </tr> |
|
270 <tr> |
|
271 <td>type="radio"</td><td><input type="radio" tabindex="1" name="radio6"> |
|
272 <input type="radio" tabindex="1" name="radio6"></td> |
|
273 </tr> |
|
274 <tr> |
|
275 <td>type="password"</td><td><input type="password" tabindex="1"></td> |
|
276 </tr> |
|
277 <tr> |
|
278 <td>type="file"</td><td><input type="file" tabindex="1"></td> |
|
279 </tr> |
|
280 <tr> |
|
281 <td>button</td><td><button tabindex="1">button</button></td> |
|
282 </tr> |
|
283 <tr> |
|
284 <td>select</td><td><select tabindex="1"><option>select</option></select></td> |
|
285 </tr> |
|
286 |
|
287 </tbody> |
|
288 </table> |
|
289 <h4 tabindex="0" id="end">done.</h4> |
|
290 </body> |
|
291 </html> |
|
292 |