summaryrefslogtreecommitdiffstats
path: root/layout/forms/test/test_bug935876.html
diff options
context:
space:
mode:
Diffstat (limited to 'layout/forms/test/test_bug935876.html')
-rw-r--r--layout/forms/test/test_bug935876.html509
1 files changed, 509 insertions, 0 deletions
diff --git a/layout/forms/test/test_bug935876.html b/layout/forms/test/test_bug935876.html
new file mode 100644
index 0000000000..e6563a117f
--- /dev/null
+++ b/layout/forms/test/test_bug935876.html
@@ -0,0 +1,509 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=935876
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 935876</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=935876">Mozilla Bug 935876</a>
+<p id="display"></p>
+<div>
+<select id="listbox" size="3">
+ <option selected>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+ <option>6</option>
+ <option>7</option>
+</select>
+<select id="multipleListbox" size="3" multiple>
+ <option selected>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+ <option>6</option>
+ <option>7</option>
+</select>
+<select id="combobox">
+ <option selected>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+ <option>6</option>
+ <option>7</option>
+</select>
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+const kIsWin = navigator.platform.indexOf("Win") == 0;
+const kIsMac = navigator.platform.indexOf("Mac") == 0;
+const kIsAndroid = navigator.appVersion.indexOf("Android") != 0;
+
+const kStrictKeyPressEvents =
+ SpecialPowers.getBoolPref("dom.keyboardevent.keypress.dispatch_non_printable_keys_only_system_group_in_content");
+
+function runTests()
+{
+ var doPreventDefault = false;
+ function onKeydown(aEvent)
+ {
+ if (doPreventDefault) {
+ aEvent.preventDefault();
+ }
+ }
+
+ var keyPressEventFired = false;
+ function onKeypress(aEvent)
+ {
+ keyPressEventFired = true;
+ }
+
+ var keyDownEventConsumedByJS = false;
+ var keyDownEventConsumed = false;
+ function onkeydownInSystemEventGroup(aEvent)
+ {
+ keyDownEventConsumedByJS = aEvent.defaultPrevented;
+ // If defaultPrevented is true via SpecialPowers, that means default was
+ // prevented, possibly in a non-content-visible way (e.g. by a system
+ // group handler).
+ keyDownEventConsumed = SpecialPowers.wrap(aEvent).defaultPrevented;
+ }
+
+ function reset()
+ {
+ keyPressEventFired = false;
+ keyDownEventConsumedByJS = false;
+ keyDownEventConsumed = false;
+ }
+
+ function check(aExpectingKeydownConsumed, aIsPrintableKey, aDescription)
+ {
+ if (doPreventDefault) {
+ ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription +
+ " if preventDefault() of keydown event was called");
+ ok(keyDownEventConsumedByJS, "keydown event of " + aDescription +
+ " should be consumed in content level if preventDefault() of keydown event is called");
+ ok(keyDownEventConsumed, "keydown event of " + aDescription +
+ " should be consumed in system level if preventDefault() of keydown event is called");
+ } else if (aExpectingKeydownConsumed) {
+ ok(!keyPressEventFired, "keypress event shouldn't be fired for " + aDescription);
+ ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
+ ok(keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
+ } else {
+ if (aIsPrintableKey) {
+ ok(keyPressEventFired, "keypress event should be fired for printable key, " + aDescription);
+ } else {
+ if (kStrictKeyPressEvents) {
+ ok(!keyPressEventFired, "keypress event shouldn't be fired for non-printable key, " + aDescription);
+ } else {
+ ok(keyPressEventFired, "keypress event should be fired even for non-printable key, " + aDescription);
+ }
+ }
+ ok(!keyDownEventConsumedByJS, "keydown event of " + aDescription + " shouldn't be consumed in content level");
+ ok(!keyDownEventConsumed, "keydown event of " + aDescription + " should be consumed in system level");
+ }
+ }
+
+ var listbox = document.getElementById("listbox");
+ listbox.addEventListener("keydown", onKeydown);
+ listbox.addEventListener("keypress", onKeypress);
+ SpecialPowers.addSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false);
+
+ listbox.focus();
+
+ [ false, true ].forEach(function (consume) {
+ doPreventDefault = consume;
+ for (var i = 0; i < listbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowDown");
+ check(true, false, "DownArrow key on listbox #" + i);
+ }
+
+ for (var i = 0; i < listbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowUp");
+ check(true, false, "'ArrowUp' key on listbox #" + i);
+ }
+
+ for (var i = 0; i < listbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowRight");
+ check(true, false, "'ArrowRight' key on listbox #" + i);
+ }
+
+ for (var i = 0; i < listbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowLeft");
+ check(true, false, "'ArrowLeft' key on listbox #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageDown");
+ check(true, false, "'PageDown' key on listbox #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageUp");
+ check(true, false, "'PageUp' key on listbox #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_End");
+ check(true, false, "'End' key on listbox #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_Home");
+ check(true, false, "'Home' key on listbox #" + i);
+ }
+
+ reset()
+ synthesizeKey("KEY_Enter");
+ check(false, true, "'Enter' key on listbox");
+
+ reset()
+ synthesizeKey("KEY_Escape");
+ check(false, false, "'Escape' key on listbox");
+
+ reset()
+ synthesizeKey("KEY_F4");
+ check(false, false, "F4 key on listbox");
+
+ reset()
+ sendString("a");
+ check(false, true, "'A' key on listbox");
+ });
+
+ listbox.removeEventListener("keydown", onKeydown);
+ listbox.removeEventListener("keypress", onKeypress);
+ SpecialPowers.removeSystemEventListener(listbox, "keydown", onkeydownInSystemEventGroup, false);
+
+
+
+ var multipleListbox = document.getElementById("multipleListbox");
+ multipleListbox.addEventListener("keydown", onKeydown);
+ multipleListbox.addEventListener("keypress", onKeypress);
+ SpecialPowers.addSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false);
+
+ multipleListbox.focus();
+
+ [ false, true ].forEach(function (consume) {
+ doPreventDefault = consume;
+ for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowDown");
+ check(true, false, "'ArrowDown' key on multiple listbox #" + i);
+ }
+
+ for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowUp");
+ check(true, false, "'ArrowUp' key on multiple listbox #" + i);
+ }
+
+ for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowRight");
+ check(true, false, "'ArrowRight' key on multiple listbox #" + i);
+ }
+
+ for (var i = 0; i < multipleListbox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowLeft");
+ check(true, false, "'ArrowLeft' key on multiple listbox #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageDown");
+ check(true, false, "'PageDown' key on multiple listbox #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageUp");
+ check(true, false, "'PageUp' key on multiple listbox #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_End");
+ check(true, false, "'End' key on multiple listbox #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_Home");
+ check(true, false, "'Home' key on multiple listbox #" + i);
+ }
+
+ reset()
+ synthesizeKey("KEY_Enter");
+ check(true, true, "'Enter' key on multiple listbox");
+
+ reset()
+ synthesizeKey("KEY_Escape");
+ check(false, false, "'Escape' key on multiple listbox");
+
+ reset()
+ synthesizeKey("KEY_F4");
+ check(false, false, "'F4' key on multiple listbox");
+
+ reset()
+ sendString("a");
+ check(false, true, "'A' key on multiple listbox");
+ });
+
+ multipleListbox.removeEventListener("keydown", onKeydown);
+ multipleListbox.removeEventListener("keypress", onKeypress);
+ SpecialPowers.removeSystemEventListener(multipleListbox, "keydown", onkeydownInSystemEventGroup, false);
+
+
+
+ var combobox = document.getElementById("combobox");
+ combobox.addEventListener("keydown", onKeydown);
+ combobox.addEventListener("keypress", onKeypress);
+ SpecialPowers.addSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false);
+
+ combobox.focus();
+
+ [ false, true ].forEach(function (consume) {
+ doPreventDefault = consume;
+ if (!kIsMac) {
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowDown");
+ check(true, false, "'ArrowDown' key on combobox #" + i);
+ }
+
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowUp");
+ check(true, false, "'ArrowUp' key on combobox #" + i);
+ }
+ } else {
+ todo(false, "Make this test work on OSX");
+ }
+
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowRight");
+ check(true, false, "'ArrowRight' key on combobox #" + i);
+ }
+
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowLeft");
+ check(true, false, "'ArrowLeft' key on combobox #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageDown");
+ check(true, false, "'PageDown' key on combobox #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageUp");
+ check(true, false, "'PageUp' key on combobox #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_End");
+ check(true, false, "'End' key on combobox #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_Home");
+ check(true, false, "'Home' key on combobox #" + i);
+ }
+
+ reset()
+ synthesizeKey("KEY_Enter");
+ check(false, true, "'Enter' key on combobox");
+
+ reset()
+ synthesizeKey("KEY_Escape");
+ check(false, false, "'Escape' key on combobox");
+
+ if (!kIsWin) {
+ reset()
+ synthesizeKey("KEY_F4");
+ check(false, false, "'F4' key on combobox");
+ }
+
+ reset()
+ sendString("a");
+ check(false, true, "'A' key on combobox");
+ });
+
+ function finish()
+ {
+ combobox.removeEventListener("keydown", onKeydown);
+ combobox.removeEventListener("keypress", onKeypress);
+ SpecialPowers.removeSystemEventListener(combobox, "keydown", onkeydownInSystemEventGroup, false);
+ SimpleTest.finish();
+ }
+
+ // Mac uses native popup for dropdown. Let's skip the tests for popup
+ // since it's not handled in nsListControlFrame.
+ // Similarly, Android doesn't use popup for dropdown.
+ if (kIsMac || kIsAndroid) {
+ finish();
+ return;
+ }
+
+ function testDropDown(aCallback)
+ {
+ testOpenDropDown(function () {
+ reset()
+ synthesizeKey("KEY_ArrowDown", {altKey: true});
+ }, function () {
+ check(true, false, "Alt + DownArrow key on combobox at opening dropdown");
+
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowDown");
+ check(true, false, "'ArrowDown' key on combobox during dropdown open #" + i);
+ }
+
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowUp");
+ check(true, false, "'ArrowUp' key on combobox during dropdown open #" + i);
+ }
+
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowRight");
+ check(true, false, "'ArrowRight' key on combobox during dropdown open #" + i);
+ }
+
+ for (var i = 0; i < combobox.options.length + 1; i++) {
+ reset()
+ synthesizeKey("KEY_ArrowLeft");
+ check(true, false, "'ArrowLeft' key on combobox during dropdown open #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageDown");
+ check(true, false, "'PageDown' key on combobox during dropdown open #" + i);
+ }
+
+ for (var i = 0; i < 4; i++) {
+ reset()
+ synthesizeKey("KEY_PageUp");
+ check(true, false, "'PageUp' key on combobox during dropdown open #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_End");
+ check(true, false, "'End' key on combobox during dropdown open #" + i);
+ }
+
+ for (var i = 0; i < 2; i++) {
+ reset()
+ synthesizeKey("KEY_Home");
+ check(true, false, "'Home' key on combobox during dropdown open #" + i);
+ }
+
+ testCloseDropDown(function () {
+ reset()
+ synthesizeKey("KEY_Enter");
+ }, function () {
+ testOpenDropDown(function () {
+ check(true, true, "'Enter' key on combobox at closing dropdown");
+
+ synthesizeKey("KEY_ArrowUp", {altKey: true});
+ }, function () {
+ check(true, false, "'Alt' + 'ArrowUp' key on combobox at opening dropdown");
+
+ testCloseDropDown(function () {
+ reset()
+ synthesizeKey("KEY_Escape");
+ }, function () {
+ check(true, false, "'Escape' key on combobox at closing dropdown");
+
+ // F4 key opens/closes dropdown only on Windows. So, other platforms
+ // don't need to do anymore.
+ if (!kIsWin) {
+ aCallback();
+ return;
+ }
+
+ testOpenDropDown(function () {
+ reset()
+ synthesizeKey("KEY_F4");
+ }, function () {
+ check(true, false, "'F4' key on combobox at opening dropdown on Windows");
+
+ testCloseDropDown(function () {
+ reset()
+ synthesizeKey("KEY_F4");
+ }, function () {
+ check(true, false, "'F4' key on combobox at closing dropdown on Windows");
+
+ aCallback();
+ return;
+ });
+ });
+ });
+ });
+ });
+ });
+ }
+
+ doPreventDefault = false;
+ testDropDown(function () {
+ // Even if keydown event is consumed by JS, opening/closing dropdown
+ // should work for a11y and security (e.g., cannot close dropdown causes
+ // staying top-most window on the screen). If it's blocked by JS, this
+ // test would cause permanent timeout.
+ doPreventDefault = true;
+ testDropDown(finish);
+ });
+}
+
+function testOpenDropDown(aTest, aOnOpenDropDown)
+{
+ document.addEventListener("popupshowing", function (aEvent) {
+ document.removeEventListener(aEvent.type, arguments.callee);
+ setTimeout(aOnOpenDropDown, 0);
+ });
+ aTest();
+}
+
+function testCloseDropDown(aTest, aOnCloseDropDown)
+{
+ document.addEventListener("popuphiding", function (aEvent) {
+ document.removeEventListener(aEvent.type, arguments.callee);
+ setTimeout(aOnCloseDropDown, 0)
+ });
+ aTest();
+}
+
+SimpleTest.waitForFocus(runTests);
+</script>
+</body>
+</html>