Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=935876
5 -->
6 <head>
7 <meta charset="utf-8">
8 <title>Test for Bug 935876</title>
9 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10 <script type="application/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=935876">Mozilla Bug 935876</a>
15 <p id="display"></p>
16 <div>
17 <select id="listbox" size="3">
18 <option selected>1</option>
19 <option>2</option>
20 <option>3</option>
21 <option>4</option>
22 <option>5</option>
23 <option>6</option>
24 <option>7</option>
25 </select>
26 <select id="multipleListbox" size="3" multiple>
27 <option selected>1</option>
28 <option>2</option>
29 <option>3</option>
30 <option>4</option>
31 <option>5</option>
32 <option>6</option>
33 <option>7</option>
34 </select>
35 <select id="combobox">
36 <option selected>1</option>
37 <option>2</option>
38 <option>3</option>
39 <option>4</option>
40 <option>5</option>
41 <option>6</option>
42 <option>7</option>
43 </select>
44 </div>
45 <pre id="test">
46 </pre>
47 <script type="application/javascript">
48 SimpleTest.waitForExplicitFinish();
50 const kIsWin = navigator.platform.indexOf("Win") == 0;
51 const kIsMac = navigator.platform.indexOf("Mac") == 0;
52 const kIsAndroid = navigator.appVersion.indexOf("Android") != 0;
54 function runTests()
55 {
56 var doPreventDefault = false;
57 function onKeydown(aEvent)
58 {
59 if (doPreventDefault) {
60 aEvent.preventDefault();
61 }
62 }
64 var keyPressEventFired = false;
65 function onKeypress(aEvent)
66 {
67 keyPressEventFired = true;
68 }
70 var keyDownEventConsumedByJS = false;
71 var keyDownEventConsumed = false;
72 function onkeydownInSystemEventGroup(aEvent)
73 {
74 keyDownEventConsumedByJS = aEvent.defaultPrevented;
75 keyDownEventConsumed = aEvent.getPreventDefault();
76 }
78 function reset()
79 {
80 keyPressEventFired = false;
81 keyDownEventConsumedByJS = false;
82 keyDownEventConsumed = false;
83 }
85 function check(aExpectingKeydownConsumed, aDescription)
86 {
87 if (doPreventDefault) {
88 ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription +
89 " if preventDefault() of keydown event was called");
90 ok(keyDownEventConsumedByJS, "keydown event of " + aDescription +
91 " should be consumed in content level if preventDefault() of keydown event is called");
92 ok(keyDownEventConsumed, "keydown event of " + aDescription +
93 " should be consumed in system level if preventDefault() of keydown event is called");
94 } else if (aExpectingKeydownConsumed) {
95 ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription);
96 ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
97 ok(keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
98 } else {
99 ok(keyPressEventFired, "keypress event should be fired for " + aDescription);
100 ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
101 ok(!keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
102 }
103 }
105 var listbox = document.getElementById("listbox");
106 listbox.addEventListener("keydown", onKeydown, false);
107 listbox.addEventListener("keypress", onKeypress, false);
108 SpecialPowers.addSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false);
110 listbox.focus();
112 [ false, true ].forEach(function (consume) {
113 doPreventDefault = consume;
114 for (var i = 0; i < listbox.options.length + 1; i++) {
115 reset()
116 synthesizeKey("VK_DOWN", {});
117 check(true, "DownArrow key on listbox #" + i);
118 }
120 for (var i = 0; i < listbox.options.length + 1; i++) {
121 reset()
122 synthesizeKey("VK_UP", {});
123 check(true, "UpArrow key on listbox #" + i);
124 }
126 for (var i = 0; i < listbox.options.length + 1; i++) {
127 reset()
128 synthesizeKey("VK_RIGHT", {});
129 check(true, "RightArrow key on listbox #" + i);
130 }
132 for (var i = 0; i < listbox.options.length + 1; i++) {
133 reset()
134 synthesizeKey("VK_LEFT", {});
135 check(true, "LeftArrow key on listbox #" + i);
136 }
138 for (var i = 0; i < 4; i++) {
139 reset()
140 synthesizeKey("VK_PAGE_DOWN", {});
141 check(true, "PageDown key on listbox #" + i);
142 }
144 for (var i = 0; i < 4; i++) {
145 reset()
146 synthesizeKey("VK_PAGE_UP", {});
147 check(true, "PageUp key on listbox #" + i);
148 }
150 for (var i = 0; i < 2; i++) {
151 reset()
152 synthesizeKey("VK_END", {});
153 check(true, "End key on listbox #" + i);
154 }
156 for (var i = 0; i < 2; i++) {
157 reset()
158 synthesizeKey("VK_HOME", {});
159 check(true, "Home key on listbox #" + i);
160 }
162 reset()
163 synthesizeKey("VK_RETURN", {});
164 check(false, "Enter key on listbox");
166 reset()
167 synthesizeKey("VK_ESCAPE", {});
168 check(false, "Esc key on listbox");
170 reset()
171 synthesizeKey("VK_F4", {});
172 check(false, "F4 key on listbox");
174 reset()
175 synthesizeKey("a", {});
176 check(false, "'A' key on listbox");
177 });
179 listbox.removeEventListener("keydown", onKeydown, false);
180 listbox.removeEventListener("keypress", onKeypress, false);
181 SpecialPowers.removeSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false);
185 var multipleListbox = document.getElementById("multipleListbox");
186 multipleListbox.addEventListener("keydown", onKeydown, false);
187 multipleListbox.addEventListener("keypress", onKeypress, false);
188 SpecialPowers.addSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false);
190 multipleListbox.focus();
192 [ false, true ].forEach(function (consume) {
193 doPreventDefault = consume;
194 for (var i = 0; i < multipleListbox.options.length + 1; i++) {
195 reset()
196 synthesizeKey("VK_DOWN", {});
197 check(true, "DownArrow key on multiple listbox #" + i);
198 }
200 for (var i = 0; i < multipleListbox.options.length + 1; i++) {
201 reset()
202 synthesizeKey("VK_UP", {});
203 check(true, "UpArrow key on multiple listbox #" + i);
204 }
206 for (var i = 0; i < multipleListbox.options.length + 1; i++) {
207 reset()
208 synthesizeKey("VK_RIGHT", {});
209 check(true, "RightArrow key on multiple listbox #" + i);
210 }
212 for (var i = 0; i < multipleListbox.options.length + 1; i++) {
213 reset()
214 synthesizeKey("VK_LEFT", {});
215 check(true, "LeftArrow key on multiple listbox #" + i);
216 }
218 for (var i = 0; i < 4; i++) {
219 reset()
220 synthesizeKey("VK_PAGE_DOWN", {});
221 check(true, "PageDown key on multiple listbox #" + i);
222 }
224 for (var i = 0; i < 4; i++) {
225 reset()
226 synthesizeKey("VK_PAGE_UP", {});
227 check(true, "PageUp key on multiple listbox #" + i);
228 }
230 for (var i = 0; i < 2; i++) {
231 reset()
232 synthesizeKey("VK_END", {});
233 check(true, "End key on multiple listbox #" + i);
234 }
236 for (var i = 0; i < 2; i++) {
237 reset()
238 synthesizeKey("VK_HOME", {});
239 check(true, "Home key on multiple listbox #" + i);
240 }
242 reset()
243 synthesizeKey("VK_RETURN", {});
244 check(true, "Enter key on multiple listbox");
246 reset()
247 synthesizeKey("VK_ESCAPE", {});
248 check(false, "Esc key on multiple listbox");
250 reset()
251 synthesizeKey("VK_F4", {});
252 check(false, "F4 key on multiple listbox");
254 reset()
255 synthesizeKey("a", {});
256 check(false, "'A' key on multiple listbox");
257 });
259 multipleListbox.removeEventListener("keydown", onKeydown, false);
260 multipleListbox.removeEventListener("keypress", onKeypress, false);
261 SpecialPowers.removeSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false);
265 var combobox = document.getElementById("combobox");
266 combobox.addEventListener("keydown", onKeydown, false);
267 combobox.addEventListener("keypress", onKeypress, false);
268 SpecialPowers.addSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false);
270 combobox.focus();
272 [ false, true ].forEach(function (consume) {
273 doPreventDefault = consume;
274 for (var i = 0; i < combobox.options.length + 1; i++) {
275 reset()
276 synthesizeKey("VK_DOWN", {});
277 check(true, "DownArrow key on combobox #" + i);
278 }
280 for (var i = 0; i < combobox.options.length + 1; i++) {
281 reset()
282 synthesizeKey("VK_UP", {});
283 check(true, "UpArrow key on combobox #" + i);
284 }
286 for (var i = 0; i < combobox.options.length + 1; i++) {
287 reset()
288 synthesizeKey("VK_RIGHT", {});
289 check(true, "RightArrow key on combobox #" + i);
290 }
292 for (var i = 0; i < combobox.options.length + 1; i++) {
293 reset()
294 synthesizeKey("VK_LEFT", {});
295 check(true, "LeftArrow key on combobox #" + i);
296 }
298 for (var i = 0; i < 4; i++) {
299 reset()
300 synthesizeKey("VK_PAGE_DOWN", {});
301 check(true, "PageDown key on combobox #" + i);
302 }
304 for (var i = 0; i < 4; i++) {
305 reset()
306 synthesizeKey("VK_PAGE_UP", {});
307 check(true, "PageUp key on combobox #" + i);
308 }
310 for (var i = 0; i < 2; i++) {
311 reset()
312 synthesizeKey("VK_END", {});
313 check(true, "End key on combobox #" + i);
314 }
316 for (var i = 0; i < 2; i++) {
317 reset()
318 synthesizeKey("VK_HOME", {});
319 check(true, "Home key on combobox #" + i);
320 }
322 reset()
323 synthesizeKey("VK_RETURN", {});
324 check(false, "Enter key on combobox");
326 reset()
327 synthesizeKey("VK_ESCAPE", {});
328 check(true, "Esc key on combobox");
330 if (!kIsWin) {
331 reset()
332 synthesizeKey("VK_F4", {});
333 check(false, "F4 key on combobox");
334 }
336 reset()
337 synthesizeKey("a", {});
338 check(false, "'A' key on combobox");
339 });
341 function finish()
342 {
343 combobox.removeEventListener("keydown", onKeydown, false);
344 combobox.removeEventListener("keypress", onKeypress, false);
345 SpecialPowers.removeSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false);
346 SimpleTest.finish();
347 }
349 // Mac uses native popup for dropdown. Let's skip the tests for popup
350 // since it's not handled in nsListControlFrame.
351 // Similarly, Android doesn't use popup for dropdown.
352 if (kIsMac || kIsAndroid) {
353 finish();
354 return;
355 }
357 function testDropDown(aCallback)
358 {
359 testOpenDropDown(function () {
360 reset()
361 synthesizeKey("VK_DOWN", { altKey: true });
362 }, function () {
363 check(true, "Alt + DownArrow key on combobox at opening dropdown");
365 for (var i = 0; i < combobox.options.length + 1; i++) {
366 reset()
367 synthesizeKey("VK_DOWN", {});
368 check(true, "DownArrow key on combobox during dropdown open #" + i);
369 }
371 for (var i = 0; i < combobox.options.length + 1; i++) {
372 reset()
373 synthesizeKey("VK_UP", {});
374 check(true, "UpArrow key on combobox during dropdown open #" + i);
375 }
377 for (var i = 0; i < combobox.options.length + 1; i++) {
378 reset()
379 synthesizeKey("VK_RIGHT", {});
380 check(true, "RightArrow key on combobox during dropdown open #" + i);
381 }
383 for (var i = 0; i < combobox.options.length + 1; i++) {
384 reset()
385 synthesizeKey("VK_LEFT", {});
386 check(true, "LeftArrow key on combobox during dropdown open #" + i);
387 }
389 for (var i = 0; i < 4; i++) {
390 reset()
391 synthesizeKey("VK_PAGE_DOWN", {});
392 check(true, "PageDown key on combobox during dropdown open #" + i);
393 }
395 for (var i = 0; i < 4; i++) {
396 reset()
397 synthesizeKey("VK_PAGE_UP", {});
398 check(true, "PageUp key on combobox during dropdown open #" + i);
399 }
401 for (var i = 0; i < 2; i++) {
402 reset()
403 synthesizeKey("VK_END", {});
404 check(true, "End key on combobox during dropdown open #" + i);
405 }
407 for (var i = 0; i < 2; i++) {
408 reset()
409 synthesizeKey("VK_HOME", {});
410 check(true, "Home key on combobox during dropdown open #" + i);
411 }
413 testCloseDropDown(function () {
414 reset()
415 synthesizeKey("VK_RETURN", {});
416 }, function () {
417 testOpenDropDown(function () {
418 check(true, "Enter key on combobox at closing dropdown");
420 synthesizeKey("VK_UP", { altKey: true });
421 }, function () {
422 check(true, "Alt + UpArrow key on combobox at opening dropdown");
424 testCloseDropDown(function () {
425 reset()
426 synthesizeKey("VK_ESCAPE", {});
427 }, function () {
428 check(true, "Esc key on combobox at closing dropdown");
430 // F4 key opens/closes dropdown only on Windows. So, other platforms
431 // don't need to do anymore.
432 if (!kIsWin) {
433 aCallback();
434 return;
435 }
437 testOpenDropDown(function () {
438 reset()
439 synthesizeKey("VK_F4", {});
440 }, function () {
441 check(true, "F4 key on combobox at opening dropdown on Windows");
443 testCloseDropDown(function () {
444 reset()
445 synthesizeKey("VK_F4", {});
446 }, function () {
447 check(true, "F4 key on combobox at closing dropdown on Windows");
449 aCallback();
450 return;
451 });
452 });
453 });
454 });
455 });
456 });
457 }
459 doPreventDefault = false;
460 testDropDown(function () {
461 // Even if keydown event is consumed by JS, opening/closing dropdown
462 // should work for a11y and security (e.g., cannot close dropdown causes
463 // staying top-most window on the screen). If it's blocked by JS, this
464 // test would cause permanent timeout.
465 doPreventDefault = true;
466 testDropDown(finish);
467 });
468 }
470 function testOpenDropDown(aTest, aOnOpenDropDown)
471 {
472 document.addEventListener("popupshowing", function (aEvent) {
473 document.removeEventListener(aEvent.type, arguments.callee, false);
474 setTimeout(aOnOpenDropDown, 0);
475 }, false);
476 aTest();
477 }
479 function testCloseDropDown(aTest, aOnCloseDropDown)
480 {
481 document.addEventListener("popuphiding", function (aEvent) {
482 document.removeEventListener(aEvent.type, arguments.callee, false);
483 setTimeout(aOnCloseDropDown, 0)
484 }, false);
485 aTest();
486 }
488 SimpleTest.waitForFocus(runTests);
489 </script>
490 </body>
491 </html>