summaryrefslogtreecommitdiffstats
path: root/layout/forms/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /layout/forms/test
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/forms/test')
-rw-r--r--layout/forms/test/bug287446_subframe.html38
-rw-r--r--layout/forms/test/bug477700_subframe.html39
-rw-r--r--layout/forms/test/bug536567_iframe.html9
-rw-r--r--layout/forms/test/bug536567_subframe.html14
-rw-r--r--layout/forms/test/bug564115_window.html10
-rw-r--r--layout/forms/test/chrome.toml8
-rw-r--r--layout/forms/test/mochitest.toml121
-rw-r--r--layout/forms/test/test_bug1111995.html60
-rw-r--r--layout/forms/test/test_bug1301290.html49
-rw-r--r--layout/forms/test/test_bug1305282.html57
-rw-r--r--layout/forms/test/test_bug1327129.html385
-rw-r--r--layout/forms/test/test_bug1529036.html73
-rw-r--r--layout/forms/test/test_bug231389.html55
-rw-r--r--layout/forms/test/test_bug287446.html74
-rw-r--r--layout/forms/test/test_bug345267.html97
-rw-r--r--layout/forms/test/test_bug346043.html65
-rw-r--r--layout/forms/test/test_bug348236.html123
-rw-r--r--layout/forms/test/test_bug353539.html52
-rw-r--r--layout/forms/test/test_bug365410.html132
-rw-r--r--layout/forms/test/test_bug378670.html55
-rw-r--r--layout/forms/test/test_bug402198.html77
-rw-r--r--layout/forms/test/test_bug411236.html71
-rw-r--r--layout/forms/test/test_bug446663.html80
-rw-r--r--layout/forms/test/test_bug476308.html31
-rw-r--r--layout/forms/test/test_bug477531.html65
-rw-r--r--layout/forms/test/test_bug477700.html59
-rw-r--r--layout/forms/test/test_bug534785.html88
-rw-r--r--layout/forms/test/test_bug536567_perwindowpb.html215
-rw-r--r--layout/forms/test/test_bug542914.html115
-rw-r--r--layout/forms/test/test_bug549170.html77
-rw-r--r--layout/forms/test/test_bug562447.html62
-rw-r--r--layout/forms/test/test_bug563642.html82
-rw-r--r--layout/forms/test/test_bug564115.html57
-rw-r--r--layout/forms/test/test_bug571352.html86
-rw-r--r--layout/forms/test/test_bug572406.html48
-rw-r--r--layout/forms/test/test_bug572649.html63
-rw-r--r--layout/forms/test/test_bug595310.html64
-rw-r--r--layout/forms/test/test_bug620936.html35
-rw-r--r--layout/forms/test/test_bug644542.html63
-rw-r--r--layout/forms/test/test_bug672810.html120
-rw-r--r--layout/forms/test/test_bug704049.html50
-rw-r--r--layout/forms/test/test_bug717878_input_scroll.html107
-rw-r--r--layout/forms/test/test_bug869314.html55
-rw-r--r--layout/forms/test/test_bug903715.html81
-rw-r--r--layout/forms/test/test_bug935876.html502
-rw-r--r--layout/forms/test/test_bug957562.html43
-rw-r--r--layout/forms/test/test_bug960277.html29
-rw-r--r--layout/forms/test/test_listcontrol_search.html46
-rw-r--r--layout/forms/test/test_readonly.html58
-rw-r--r--layout/forms/test/test_select_collapsed_page_keys.html43
-rw-r--r--layout/forms/test/test_select_key_navigation_bug1498769.html123
-rw-r--r--layout/forms/test/test_select_key_navigation_bug961363.html131
-rw-r--r--layout/forms/test/test_select_prevent_default.html116
-rw-r--r--layout/forms/test/test_select_reframe.html52
-rw-r--r--layout/forms/test/test_select_vertical.html75
-rw-r--r--layout/forms/test/test_textarea_resize.html102
-rw-r--r--layout/forms/test/test_unstyled_control_height.html72
57 files changed, 4759 insertions, 0 deletions
diff --git a/layout/forms/test/bug287446_subframe.html b/layout/forms/test/bug287446_subframe.html
new file mode 100644
index 0000000000..51fd701e3b
--- /dev/null
+++ b/layout/forms/test/bug287446_subframe.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <script>
+ function doIs(arg1, arg2, arg3) {
+ window.parent.postMessage("t " + encodeURIComponent(arg1) + " " +
+ encodeURIComponent(arg2) + " " +
+ encodeURIComponent(arg3), "*");
+ }
+
+ function $(arg) { return document.getElementById(arg); }
+
+ window.addEventListener("message",
+ function(evt) {
+ var t = $("target");
+ if (evt.data == "start") {
+ doIs(t.value, "Test", "Shouldn't have lost our initial value");
+ t.focus();
+ sendString("Foo");
+ doIs(t.value, "FooTest", "Typing should work");
+ window.parent.postMessage("c", "*");
+ } else {
+ doIs(evt.data, "continue", "Unexpected message");
+ doIs(t.value, "FooTest", "Shouldn't have lost our typed value");
+ sendString("Bar");
+ doIs(t.value, "FooBarTest", "Typing should still work");
+ window.parent.postMessage("f", "*");
+ }
+ },
+ "false");
+
+ </script>
+ </head>
+ <body>
+ <input id="target" value="Test">
+ </body>
+</html>
diff --git a/layout/forms/test/bug477700_subframe.html b/layout/forms/test/bug477700_subframe.html
new file mode 100644
index 0000000000..c0398fb2ad
--- /dev/null
+++ b/layout/forms/test/bug477700_subframe.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <script>
+ function doIs(arg1, arg2, arg3) {
+ window.parent.postMessage("t " + encodeURIComponent(arg1) + " " +
+ encodeURIComponent(arg2) + " " +
+ encodeURIComponent(arg3), "*");
+ }
+
+ function $(arg) { return document.getElementById(arg); }
+
+ window.addEventListener("message",
+ function(evt) {
+ doIs(evt.data, "start", "Unexpected message");
+ $("target").focus();
+ sendString("Test");
+ var t = $("target");
+ doIs(t.value, "Test", "Typing should work");
+ (function() {
+ SpecialPowers.wrap(t).editor.undo();
+ })()
+ doIs(t.value, "", "Undo should work");
+ (function() {
+ SpecialPowers.wrap(t).editor.redo();
+ })()
+ doIs(t.value, "Test", "Redo should work");
+ window.parent.postMessage("f", "*");
+ },
+ "false");
+
+ </script>
+ </head>
+ <body>
+ <input id="target">
+ </body>
+</html>
+
diff --git a/layout/forms/test/bug536567_iframe.html b/layout/forms/test/bug536567_iframe.html
new file mode 100644
index 0000000000..b2b2ca60ac
--- /dev/null
+++ b/layout/forms/test/bug536567_iframe.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ </head>
+ <body>
+ <iframe id="content"></iframe>
+ </body>
+</html>
+
diff --git a/layout/forms/test/bug536567_subframe.html b/layout/forms/test/bug536567_subframe.html
new file mode 100644
index 0000000000..c1271becf0
--- /dev/null
+++ b/layout/forms/test/bug536567_subframe.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<body>
+<input id="target" type="file" />
+<script type="text/javascript">
+
+window.onload = function() {
+ var fileInput = document.getElementById("target");
+ fileInput.click();
+};
+
+</script>
+</body>
+</html>
diff --git a/layout/forms/test/bug564115_window.html b/layout/forms/test/bug564115_window.html
new file mode 100644
index 0000000000..b55cc0400d
--- /dev/null
+++ b/layout/forms/test/bug564115_window.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Window for Bug 564115</title>
+</head>
+<body>
+<input type="text">
+<div style="height: 10000px;"></div>
+</body>
+</html>
diff --git a/layout/forms/test/chrome.toml b/layout/forms/test/chrome.toml
new file mode 100644
index 0000000000..e37aa39571
--- /dev/null
+++ b/layout/forms/test/chrome.toml
@@ -0,0 +1,8 @@
+[DEFAULT]
+skip-if = ["os == 'android'"]
+support-files = [
+ "bug536567_iframe.html",
+ "bug536567_subframe.html",
+]
+
+["test_bug536567_perwindowpb.html"]
diff --git a/layout/forms/test/mochitest.toml b/layout/forms/test/mochitest.toml
new file mode 100644
index 0000000000..0748041524
--- /dev/null
+++ b/layout/forms/test/mochitest.toml
@@ -0,0 +1,121 @@
+[DEFAULT]
+support-files = [
+ "bug287446_subframe.html",
+ "bug477700_subframe.html",
+ "bug564115_window.html",
+]
+
+["test_bug231389.html"]
+
+["test_bug287446.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug345267.html"]
+
+["test_bug346043.html"]
+
+["test_bug348236.html"]
+skip-if = ["true"] # mac(select form control popup behavior is different)
+
+["test_bug353539.html"]
+
+["test_bug365410.html"]
+
+["test_bug378670.html"]
+
+["test_bug402198.html"]
+
+["test_bug411236.html"]
+
+["test_bug446663.html"]
+
+["test_bug476308.html"]
+
+["test_bug477531.html"]
+
+["test_bug477700.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_bug534785.html"]
+
+["test_bug542914.html"]
+
+["test_bug549170.html"]
+
+["test_bug562447.html"]
+
+["test_bug563642.html"]
+
+["test_bug564115.html"]
+skip-if = ["os == 'android'"] #TIMED_OUT
+
+["test_bug571352.html"]
+skip-if = ["os == 'android'"] #TIMED_OUT
+
+["test_bug572406.html"]
+
+["test_bug572649.html"]
+skip-if = ["os == 'android'"] # Bug 1635771
+
+["test_bug595310.html"]
+
+["test_bug620936.html"]
+
+["test_bug644542.html"]
+
+["test_bug672810.html"]
+
+["test_bug704049.html"]
+
+["test_bug717878_input_scroll.html"]
+
+["test_bug869314.html"]
+
+["test_bug903715.html"]
+skip-if = ["true"]
+
+["test_bug935876.html"]
+
+["test_bug957562.html"]
+
+["test_bug960277.html"]
+
+["test_bug1111995.html"]
+
+["test_bug1301290.html"]
+skip-if = ["os == 'android'"]
+
+["test_bug1305282.html"]
+
+["test_bug1327129.html"]
+
+["test_bug1529036.html"]
+
+["test_listcontrol_search.html"]
+
+["test_readonly.html"]
+
+["test_select_collapsed_page_keys.html"]
+skip-if = ["os == 'mac'"] # select control keyboard behavior is different
+
+["test_select_key_navigation_bug961363.html"]
+
+["test_select_key_navigation_bug1498769.html"]
+
+["test_select_prevent_default.html"]
+
+["test_select_reframe.html"]
+
+["test_select_vertical.html"]
+skip-if = ["true"] # Bug 1170129, # <select> elements don't use an in-page popup on Android
+
+["test_textarea_resize.html"]
+skip-if = ["os == 'android'"]
+
+["test_unstyled_control_height.html"]
diff --git a/layout/forms/test/test_bug1111995.html b/layout/forms/test/test_bug1111995.html
new file mode 100644
index 0000000000..c164dc23f7
--- /dev/null
+++ b/layout/forms/test/test_bug1111995.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1111995
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1111995</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"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1111995 **/
+
+ function doTest() {
+ SimpleTest.waitForExplicitFinish();
+
+ var clicks = 0;
+ var elms = document.querySelectorAll('.click');
+ for (var i = 0; i < elms.length; ++i) {
+ var e = elms[i];
+ e.addEventListener('click', function(event) {
+ ++clicks;
+ });
+ }
+
+ for (var i = 0; i < elms.length; ++i) {
+ var e = elms[i];
+ synthesizeMouse(e, 3, 3, {});
+ }
+ is(clicks, 0, "click events outside border with radius");
+
+ clicks = 0;
+ synthesizeMouse($("t3"), 17, 17, {});
+ synthesizeMouse($("t4"), 17, 17, {});
+ is(clicks, 2, "click events on border with radius");
+
+ SimpleTest.finish();
+ }
+ </script>
+</head>
+<body onload="SimpleTest.waitForFocus(doTest, window)">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1111995">Mozilla Bug 1111995</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+
+<input class="click" id="t1" type=button style="width:100px; height:100px; padding:20px; border-radius:50%" value="Round button">
+<button class="click" id="t2" style="width:100px; height:100px; padding:20px; border-radius:50%">Round button</button>
+<input class="click" id="t3" type=button style="width:100px; height:100px; border-width:20px; border-radius:50%" value="Round button">
+<button class="click" id="t4" style="width:100px; height:100px; border-width:20px; border-radius:50%">Round button</button>
+<input class="click" id="t5" type=button style="width:100px; height:100px; border-radius:50%;overflow:hidden" value="Round button">
+<button class="click" id="t6" style="width:100px; height:100px; border-radius:50%;overflow:hidden">Round button</button>
+
+</body>
+</html>
diff --git a/layout/forms/test/test_bug1301290.html b/layout/forms/test/test_bug1301290.html
new file mode 100644
index 0000000000..6b3fc0df14
--- /dev/null
+++ b/layout/forms/test/test_bug1301290.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test for Bug 1301290</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"/>
+ <style type="text/css">
+ .blue, .green {
+ border: none;
+ box-sizing: border-box;
+ display: block;
+ width: 200px;
+ height: 100px;
+ overflow: scroll;
+ resize: both;
+ }
+
+ .blue {
+ background: blue;
+ }
+
+ .green {
+ background: green;
+ margin-top: -100px;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="blue"></div>
+ <textarea class="green" id="textarea"></textarea>
+ <script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(() => SimpleTest.executeSoon(function() {
+ var textarea = $("textarea");
+ var rect = textarea.getBoundingClientRect();
+
+ synthesizeMouse(textarea, rect.width - 9, rect.height - 9, { type: "mousedown" });
+ synthesizeMouse(textarea, rect.width + 40, rect.height + 40, { type: "mousemove" });
+ synthesizeMouse(textarea, rect.width + 40, rect.height + 40, { type: "mouseup" });
+
+ var newrect = textarea.getBoundingClientRect();
+ ok(newrect.width > rect.width, "width did not increase");
+ ok(newrect.height > rect.height, "height did not increase");
+ SimpleTest.finish();
+ }));
+ </script>
+ </body>
+</html>
diff --git a/layout/forms/test/test_bug1305282.html b/layout/forms/test/test_bug1305282.html
new file mode 100644
index 0000000000..bd631f3444
--- /dev/null
+++ b/layout/forms/test/test_bug1305282.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=615697
+-->
+<head>
+ <title>Test for Bug 1305282</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=1305282">Mozilla Bug 1305282</a>
+<p id="display"></p>
+<div id="content">
+ <select>
+ <option>f o o</option>
+ <option>b a r</option>
+ <option>b o o</option>
+ </select>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1305282 **/
+
+var select = document.getElementsByTagName('select')[0];
+
+select.addEventListener("change", function(aEvent) {
+ is(select.selectedIndex, 1, "'b a r' option is selected");
+ SimpleTest.finish();
+}, {once: true});
+
+select.addEventListener("focus", function() {
+ SimpleTest.executeSoon(function () {
+ synthesizeKey("KEY_ArrowDown");
+ SimpleTest.executeSoon(function () {
+ sendString("b");
+ SimpleTest.executeSoon(function () {
+ sendString(" ");
+ SimpleTest.executeSoon(function () {
+ synthesizeKey("KEY_Enter");
+ });
+ });
+ });
+ });
+}, {once: true});
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ select.focus();
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug1327129.html b/layout/forms/test/test_bug1327129.html
new file mode 100644
index 0000000000..0e52f140b3
--- /dev/null
+++ b/layout/forms/test/test_bug1327129.html
@@ -0,0 +1,385 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=935876
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1327129</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=1327129">Mozilla Bug 1327129</a>
+<p id="display"></p>
+<div>
+<select size="3" firstNonDisabledIndex="0">
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" firstNonDisabledIndex="1">
+ <option disabled>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" firstNonDisabledIndex="0">
+ <optgroup><option>1</option></optgroup>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" firstNonDisabledIndex="1">
+ <option disabled>1</option>
+ <optgroup><option>2</option></optgroup>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" firstNonDisabledIndex="2">
+ <option disabled>1</option>
+ <optgroup><option disabled>2</option></optgroup>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" firstNonDisabledIndex="-1">
+ <option disabled>1</option>
+ <optgroup><option disabled>2</option></optgroup>
+ <option disabled>3</option>
+ <option disabled>4</option>
+ <option disabled>5</option>
+</select>
+<select size="3" multiple firstNonDisabledIndex="0">
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" multiple firstNonDisabledIndex="0">
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" multiple firstNonDisabledIndex="0">
+ <optgroup><option>1</option></optgroup>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" multiple firstNonDisabledIndex="1">
+ <option disabled>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" multiple firstNonDisabledIndex="3">
+ <option disabled>1</option>
+ <optgroup><option disabled>2</option></optgroup>
+ <option disabled>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="3" multiple firstNonDisabledIndex="-1">
+ <option disabled>1</option>
+ <optgroup><option disabled>2</option></optgroup>
+ <option disabled>3</option>
+ <option disabled>4</option>
+ <option disabled>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="0">
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="0">
+ <optgroup><option>1</option></optgroup>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="1">
+ <optgroup disabled><option>1</option></optgroup>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="1">
+ <option disabled>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="1">
+ <option disabled>1</option>
+ <optgroup><option>2</option></optgroup>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="2">
+ <option disabled>1</option>
+ <optgroup><option disabled>2</option></optgroup>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="3">
+ <option disabled>1</option>
+ <optgroup><option disabled>2</option></optgroup>
+ <option disabled>3</option>
+ <option>4</option>
+ <option>5</option>
+</select>
+<select size="1" firstNonDisabledIndex="-1">
+ <option disabled>1</option>
+ <optgroup><option disabled>2</option></optgroup>
+ <option disabled>3</option>
+ <option disabled>4</option>
+ <option disabled>5</option>
+</select>
+</div>
+<pre id="test">
+</pre>
+
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+const kIsMac = navigator.platform.indexOf("Mac") == 0;
+
+function runTests()
+{
+ const all = Array.from(document.querySelectorAll('select'));
+ let i = 0;
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ ++i;
+ if (!elem.id)
+ elem.id = "element " + i;
+ });
+
+ //
+ // Test DOWN key on a <select> with no selected options.
+ //
+ const listboxes = Array.from(document.querySelectorAll('select[size="3"]'));
+ listboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown");
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": DOWN selected first non-disabled option");
+ });
+
+ const comboboxes = Array.from(document.querySelectorAll('select[size="1"]'));
+ // Mac shows the drop-down menu for DOWN, so skip this test there.
+ if (!kIsMac) {
+ comboboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown");
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": DOWN selected first non-disabled option");
+ });
+ }
+
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ elem.blur();
+ });
+
+ //
+ // Test SHIFT+DOWN on a <select> with no selected options.
+ //
+ listboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown", {shiftKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": SHIFT+DOWN selected first non-disabled option");
+ });
+
+ // Mac shows the drop-down menu for SHIFT+DOWN, so skip this test there.
+ if (!kIsMac) {
+ comboboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown", {shiftKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": SHIFT+DOWN selected first non-disabled option");
+ });
+ }
+
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ elem.blur();
+ });
+
+ //
+ // Test CTRL+DOWN on a <select> with no selected options.
+ //
+ listboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown", {ctrlKey:true});
+ if (!elem.multiple)
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+DOWN selected first non-disabled option");
+ else
+ is(elem.selectedIndex, -1, elem.id + ": CTRL+DOWN did NOT select first any option");
+ });
+
+ // Mac shows the drop-down menu for CTRL+DOWN, so skip this test there.
+ if (!kIsMac) {
+ comboboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown", {ctrlKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+DOWN selected first non-disabled option");
+ });
+ }
+
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ elem.blur();
+ });
+
+ //
+ // Test SPACE on a <select> with no selected options.
+ //
+ listboxes.forEach((elem) => {
+ elem.focus();
+ sendString(" ");
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": SPACE selected first non-disabled option");
+ });
+
+ // All platforms shows the drop-down menu for SPACE so skip testing that
+ // on the comboboxes.
+
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ elem.blur();
+ });
+
+ //
+ // Test CTRL+SPACE on a <select> with no selected options.
+ //
+ listboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey(" ", {ctrlKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+SPACE selected first non-disabled option");
+ });
+
+ // non-Mac shows the drop-down menu for CTRL+SPACE, so skip this test there.
+ if (kIsMac) {
+ comboboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey(" ", {ctrlKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+SPACE selected first non-disabled option");
+ });
+ }
+
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ elem.blur();
+ });
+
+ //
+ // Test SHIFT+SPACE on a <select> with no selected options.
+ //
+ listboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey(" ", {shiftKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": SHIFT+SPACE selected first non-disabled option");
+ });
+
+ // All platforms shows the drop-down menu for SHIFT+SPACE so skip testing that
+ // on the comboboxes.
+
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ elem.blur();
+ });
+
+ //
+ // Test CTRL+SHIFT+DOWN on a <select> with no selected options.
+ //
+ listboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown", {ctrlKey:true, shiftKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+SHIFT+DOWN selected first non-disabled option");
+ });
+
+ // Mac shows the drop-down menu for CTRL+SHIFT+DOWN, so skip this test there.
+ if (!kIsMac) {
+ comboboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey("KEY_ArrowDown", {ctrlKey:true, shiftKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+SHIFT+DOWN selected first non-disabled option");
+ });
+ }
+
+ all.forEach((elem) => {
+ elem.selectedIndex = -1;
+ elem.blur();
+ });
+
+ //
+ // Test CTRL+SHIFT+SPACE on a <select> with no selected options.
+ //
+ listboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey(" ", {ctrlKey:true, shiftKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+SHIFT+SPACE selected first non-disabled option");
+ });
+
+ // non-Mac shows the drop-down menu for CTRL+SHIFT+SPACE, so skip this test there.
+ if (kIsMac) {
+ comboboxes.forEach((elem) => {
+ elem.focus();
+ synthesizeKey(" ", {ctrlKey:true, shiftKey:true});
+ is(""+elem.selectedIndex,
+ elem.getAttribute('firstNonDisabledIndex'),
+ elem.id + ": CTRL+SHIFT+SPACE selected first non-disabled option");
+ });
+ }
+
+ SimpleTest.finish();
+}
+
+
+SimpleTest.waitForFocus(runTests);
+</script>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug1529036.html b/layout/forms/test/test_bug1529036.html
new file mode 100644
index 0000000000..0d1c4fa207
--- /dev/null
+++ b/layout/forms/test/test_bug1529036.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1529036
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1529036</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"/>
+ <style>
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+ </style>
+ <script type="application/javascript">
+
+ /** Test for Bug 1529036 **/
+
+ function doTest() {
+ SimpleTest.waitForExplicitFinish();
+
+ var clicks = 0;
+ var elms = document.querySelectorAll('.click');
+ for (var i = 0; i < elms.length; ++i) {
+ var e = elms[i];
+ e.addEventListener('click', function(event) {
+ ++clicks;
+ });
+ }
+
+ var elms = document.querySelectorAll('.click.hit');
+ for (var i = 0; i < elms.length; ++i) {
+ var e = elms[i];
+ let r = e.getBoundingClientRect();
+ synthesizeMouse(e, 50, 50, {});
+ }
+ is(clicks, elms.length, "click events on overflow");
+
+ clicks = 0;
+ elms = document.querySelectorAll('.click.nohit');
+ for (var i = 0; i < elms.length; ++i) {
+ var e = elms[i];
+ let r = e.getBoundingClientRect();
+ synthesizeMouse(e, 50, 50, {});
+ }
+ is(clicks, 0, "click events on clipped overflow");
+
+ SimpleTest.finish();
+ }
+ </script>
+</head>
+<body onload="SimpleTest.waitForFocus(doTest, window)">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1529036">Mozilla Bug 1529036</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+
+<div style="border: 1px solid">
+<button class="click hit" id="t1" style="width:10px; height:10px; padding:20px; border-radius:50%"><div>button<br>button<br>button<br>button<br>button<br></div></button>
+<button class="click hit" id="t2" style="width:10px; height:10px; padding:20px; border:1px solid"><div>button<br>button<br>button<br>button<br>button<br></div></button>
+<button class="click hit" id="t3" style="width:10px; height:10px; border-width:20px; border-radius:50%"><div>button<br>button<br>button<br>button<br>button<br></div></button>
+<button class="click hit" id="t4" style="width:10px; height:10px; border:20px solid"><div>button<br>button<br>button<br>button<br>button<br></div></button>
+<button class="click nohit" id="t5" style="width:10px; height:10px; padding:20px; overflow:hidden; border-radius:50%"><div>button<br>button<br>button<br>button<br>button<br></div></button>
+<button class="click nohit" id="t6" style="width:10px; height:10px; padding:20px; overflow:hidden; border:1px solid"><div>button<br>button<br>button<br>button<br>button<br></div></button>
+</div>
+
+</body>
+</html>
diff --git a/layout/forms/test/test_bug231389.html b/layout/forms/test/test_bug231389.html
new file mode 100644
index 0000000000..9239839247
--- /dev/null
+++ b/layout/forms/test/test_bug231389.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=231389
+-->
+<head>
+ <title>Test for Bug 231389</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=231389">Mozilla Bug 231389</a>
+<p id="display">
+ <textarea id="area" rows="5">
+ Here
+ is
+ some
+ very
+ long
+ text
+ that
+ we're
+ using
+ for
+ testing
+ purposes
+ </textarea>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 231389 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+ var area = document.getElementById("area");
+ var val = area.value;
+ var pos = val.indexOf("purposes");
+
+ is(area.scrollTop, 0, "The textarea should not be scrolled initially");
+ area.selectionStart = pos;
+ area.selectionEnd = pos;
+ requestAnimationFrame(function() {
+ isnot(area.scrollTop, 0, "The textarea's insertion point should be scrolled into view");
+
+ SimpleTest.finish();
+ });
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug287446.html b/layout/forms/test/test_bug287446.html
new file mode 100644
index 0000000000..bb9e3bec39
--- /dev/null
+++ b/layout/forms/test/test_bug287446.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=287446
+-->
+<head>
+ <title>Test for Bug 287446</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=287446">Mozilla Bug 287446</a>
+<p id="display">
+ <iframe id="i"
+ src="http://example.com/tests/layout/forms/test/bug287446_subframe.html"></iframe>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 287446 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+ isnot(window.location.host, "example.com", "test is not testing cross-site");
+ var accessed = false;
+ try {
+ $("i").contentDocument.documentElement;
+ accessed = true;
+ } catch(e) {}
+ is(accessed, false, "Shouldn't be able to access cross-site");
+
+ $("i").style.display = "none";
+ document.body.offsetWidth;
+ is(document.defaultView.getComputedStyle($("i")).display, "none",
+ "toggling display failed");
+ $("i").style.display = "";
+ document.body.offsetWidth;
+ is(document.defaultView.getComputedStyle($("i")).display, "inline",
+ "toggling display back failed");
+
+ $("i").contentWindow.postMessage("start", "*");
+});
+
+function continueTest() {
+ $("i").style.display = "none";
+ document.body.offsetWidth;
+ is(document.defaultView.getComputedStyle($("i")).display, "none",
+ "toggling display second time failed");
+ $("i").style.display = "";
+ document.body.offsetWidth;
+ is(document.defaultView.getComputedStyle($("i")).display, "inline",
+ "toggling display back second time failed");
+
+$("i").contentWindow.postMessage("continue", "*");
+}
+
+window.addEventListener("message",
+ function(evt) {
+ var arr = evt.data.split(/ /).map(decodeURIComponent);
+ if (arr[0] == 't') {
+ is(arr[1], arr[2], arr[3]);
+ } else if (arr[0] == 'c') {
+ continueTest();
+ } else if (arr[0] == 'f') {
+ SimpleTest.finish();
+ }
+ });
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug345267.html b/layout/forms/test/test_bug345267.html
new file mode 100644
index 0000000000..ba9a3bd555
--- /dev/null
+++ b/layout/forms/test/test_bug345267.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=345267
+-->
+<head>
+ <title>Test for Bug 345267</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=345267">Mozilla Bug 345267</a>
+<p id="display">
+ <input id="d1" maxlength="3" value="abcde">
+ <input id="d2" maxlength="3">
+ <input id="d3" maxlength="3">
+ <input id="d4" value="abcdefghijk">
+ <input id="target" value="abcdefghijklm" maxlength="3">
+</p>
+<div id="content" style="display: none">
+ <input id="u1" maxlength="3" value="abcdef">
+ <input id="u2" maxlength="3">
+ <input id="u3" maxlength="3">
+ <input id="u4" value="abcdefghijkl">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 345267 **/
+SimpleTest.waitForExplicitFinish();
+runTest();
+
+function runTest() {
+ is($("d1").value, "abcde",
+ "Displayed initial value should not be truncated by maxlength");
+ is($("u1").value, "abcdef",
+ "Undisplayed initial value should not be truncated by maxlength");
+
+ $("d2").value = "abcdefg";
+ is($("d2").value, "abcdefg",
+ "Displayed set value should not be truncated by maxlength");
+
+ $("u2").value = "abcdefgh";
+ is($("u2").value, "abcdefgh",
+ "Undisplayed set value should not be truncated by maxlength");
+
+ $("d3").defaultValue = "abcdefghi";
+ is($("d3").value, "abcdefghi",
+ "Displayed set defaultValue should not be truncated by maxlength");
+
+ $("u3").defaultValue = "abcdefghij";
+ is($("u3").value, "abcdefghij",
+ "Undisplayed set defaultValue should not be truncated by maxlength");
+
+ $("d4").maxLength = "3";
+ is($("d4").value, "abcdefghijk",
+ "Displayed: setting maxLength should not truncate existing value");
+
+ $("u4").maxLength = "3";
+ is($("u4").value, "abcdefghijkl",
+ "Undisplayed: setting maxLength should not truncate existing value");
+
+ // Now start the editing tests
+ is($("target").value, "abcdefghijklm", "Test starting state incorrect");
+ $("target").focus();
+ $("target").selectionStart = $("target").selectionEnd = 13;
+ sendKey("back_space");
+ is($("target").value, "abcdefghijkl", "Should only delete one char");
+ sendKey("back_space");
+ is($("target").value, "abcdefghijk", "Should only delete one char again");
+ (function () {
+ SpecialPowers.wrap($("target")).controllers.getControllerForCommand('cmd_undo')
+ .doCommand('cmd_undo');
+ })();
+ is($("target").value, "abcdefghijklm",
+ "Should be able to undo deletion in the face of maxlength");
+ sendString("nopq");
+ is($("target").value, "abcdefghijklm",
+ "Typing should have no effect when already past maxlength");
+
+ $("target").value = "";
+ sendString("abcde");
+ is($("target").value, "abc", "Typing should be limited by maxlength");
+
+ $("target").value = "";
+ sendString("ad");
+ sendKey("left");
+ sendString("bc");
+ is($("target").value, "abd", "Typing should be limited by maxlength again");
+ SimpleTest.finish();
+}
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/layout/forms/test/test_bug346043.html b/layout/forms/test/test_bug346043.html
new file mode 100644
index 0000000000..e5db9bb8cf
--- /dev/null
+++ b/layout/forms/test/test_bug346043.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=346043
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 346043</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript">
+ /** Test for Bug 346043 **/
+ function test(select, index, useEscape) {
+ select.selectedIndex = index;
+ is(select.selectedIndex, index, "Selected index is broken");
+
+ // Open the select dropdown.
+ //
+ // Using Alt+Down (instead of a click) seems necessary to make subsequent
+ // mouse events work with the dropdown itself, instead of the window below
+ // it.
+ select.focus();
+ synthesizeKey("KEY_ArrowDown", {altKey: true});
+
+ var options = select.getElementsByTagName("option");
+ synthesizeMouseAtCenter(options[1],
+ {type: "mousemove", clickCount: 0});
+
+ // Close the select dropdown.
+ if (useEscape)
+ synthesizeKey("KEY_Escape"); // Tests a different code path.
+ select.blur();
+ is(select.selectedIndex, index, "Selected index shouldn't change");
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.waitForFocus(function() {
+ test(document.getElementById("test-unselected"), -1, true);
+ test(document.getElementById("test-unselected"), -1, false);
+ test(document.getElementById("test-disabled"), 0, true);
+ test(document.getElementById("test-disabled"), 0, false);
+ SimpleTest.finish();
+ });
+ </script>
+</head>
+<body>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=346043">Mozilla Bug 346043</a>
+ <p id="display"></p>
+ <div id="content">
+ <select id="test-unselected">
+ <option>A</option>
+ <option>B</option>
+ <option>C</option>
+ </select>
+
+ <select id="test-disabled">
+ <option disabled>A</option>
+ <option>B</option>
+ <option>C</option>
+ </select>
+ </div>
+ <pre id="test"></pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug348236.html b/layout/forms/test/test_bug348236.html
new file mode 100644
index 0000000000..f00f89efa7
--- /dev/null
+++ b/layout/forms/test/test_bug348236.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=348236
+-->
+<head>
+
+ <title>Test for Bug 348236</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" />
+ <style type="text/css">
+ #eSelect {
+ position: fixed; top:0; left: 350px; font-size: 24px; width: 100px
+ }
+ #eSelect option {
+ margin: 0; padding: 0; height: 24px
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=348236">Mozilla Bug 348236</a>
+<p id="display"></p>
+<div id="content">
+
+ <select id="eSelect" size="1" onchange="++this.onchangeCount">
+ <option selected>1</option>
+ <option>2</option>
+ <option id="option3">3</option>
+ </select>
+</div>
+<pre id="test">
+<script type="text/javascript">
+
+ /** Test for Bug 348236 **/
+
+SimpleTest.waitForExplicitFinish()
+addLoadEvent(function test() {
+
+ var
+ WinUtils = SpecialPowers.getDOMWindowUtils(window),
+ sec = netscape.security,
+ eSelect = $("eSelect"),
+ timeout = 0 // Choose a larger value like 500 ms if you want to see what's happening.
+
+ function keypressOnSelect(key) {
+ eSelect.focus();
+ synthesizeKey(key.key, {altKey: key.altKey});
+ }
+
+ function testKey(key, keyString, functionToContinue) {
+ var selectGotClick
+ function clickListener() { selectGotClick = true }
+ eSelect.selectedIndex = 0
+ eSelect.onchangeCount = 0
+
+ // Drop the SELECT down.
+ keypressOnSelect(key)
+ // This timeout and the following are necessary to let the sent events take effect.
+ setTimeout(cont1, timeout)
+ function cont1() {
+ // Move the mouse over option 3.
+ let option3 = document.getElementById("option3");
+ let rect = option3.getBoundingClientRect();
+ WinUtils.sendMouseEvent("mousemove", rect.left + 4, rect.top + 4, 0, 0, 0, true)
+ setTimeout(cont2, timeout)
+ }
+ function cont2() {
+ // Close the select.
+ keypressOnSelect(key)
+ setTimeout(cont3, timeout)
+ }
+ function cont3() {
+ is(eSelect.value, "3", "Select's value should be 3 after hovering over option 3 and pressing " + keyString + ".")
+ is(eSelect.onchangeCount, 1, "Onchange should have fired once.")
+
+ // Simulate click on area to the left of the select.
+ eSelect.addEventListener("click", clickListener, true)
+ selectGotClick = false
+ WinUtils.sendMouseEvent("mousedown", 320, 0, 0, 0, 0, true)
+ WinUtils.sendMouseEvent("mouseup", 320, 0, 0, 0, 0, true)
+ setTimeout(cont4, timeout)
+ }
+ function cont4() {
+ eSelect.removeEventListener("click", clickListener, true)
+ ok(!selectGotClick, "SELECT must not capture mouse events after closing it with " + keyString + ".")
+ functionToContinue()
+ }
+ }
+
+
+ // Quick sanity checks.
+ is(eSelect.value, "1", "SELECT value should be 1 after load.")
+ is(eSelect.selectedIndex, 0, "SELECT selectedIndex should be 0 after load.")
+
+ // Check if sending key events works.
+ keypressOnSelect({key: "KEY_ArrowDown"});
+ is(eSelect.value, "2", "SELECT value should be 2 after pressing Down.")
+
+ // Test ALT-Down.
+ testKey({key: "KEY_ArrowDown", altKey: true}, "ALT-Down", nextKey1)
+ function nextKey1() {
+ // Test ALT-Up.
+ testKey({key: "KEY_ArrowUp", altKey: true}, "ALT-Up", nextKey2)
+ }
+ function nextKey2() {
+ // Test the F4 key on Windows.
+ if (/Win/i.test(navigator.platform))
+ testKey({key: "KEY_F4"}, "F4", finished)
+ else
+ finished()
+ }
+ function finished() {
+ // Reset value to get the expected value if we reload the page.
+ eSelect.selectedIndex = 0
+ SimpleTest.finish()
+ }
+})
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug353539.html b/layout/forms/test/test_bug353539.html
new file mode 100644
index 0000000000..593250d207
--- /dev/null
+++ b/layout/forms/test/test_bug353539.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=353539
+-->
+<head>
+ <title>Test for Bug 353539</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=353539">Mozilla Bug 353539</a>
+<p id="display">
+ <textarea id="area" rows="5">
+ Here
+ is
+ some
+ very
+ long
+ text
+ that
+ we're
+ using
+ for
+ testing
+ purposes
+ </textarea>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 353539 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+ var area = document.getElementById("area");
+
+ is(area.scrollTop, 0, "The textarea should not be scrolled initially");
+ area.focus();
+ setTimeout(function() {
+ is(area.scrollTop, 0, "The textarea's insertion point should not be scrolled into view");
+
+ SimpleTest.finish();
+ }, 0);
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug365410.html b/layout/forms/test/test_bug365410.html
new file mode 100644
index 0000000000..94ba8abfa0
--- /dev/null
+++ b/layout/forms/test/test_bug365410.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=365410
+-->
+<title>Test for Bug 365410</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"/>
+<style>
+ select { box-sizing: content-box }
+</style>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=365410">Mozilla Bug 365410</a>
+<p id="display">
+<select id="test0" multiple="multiple">
+ <option id="option">Item 1</option>
+ <option>Item 2</option>
+ <option>Item 3</option>
+ <option>Item 4</option>
+ <option>Item 5</option>
+ <option>Item 6</option>
+ <option>Item 7</option>
+ <option>Item 8</option>
+ <option>Item 9</option>
+ <option>Item 10</option>
+ <option>Item 11</option>
+ <option>Item 12</option>
+ <option>Item 13</option>
+ <option>Item 14</option>
+ <option>Item 15</option>
+</select>
+<select id="test1" multiple="multiple" size="1">
+ <option>Item 1</option>
+ <option>Item 2</option>
+ <option>Item 3</option>
+ <option>Item 4</option>
+ <option>Item 5</option>
+ <option>Item 6</option>
+ <option>Item 7</option>
+ <option>Item 8</option>
+ <option>Item 9</option>
+ <option>Item 10</option>
+ <option>Item 11</option>
+ <option>Item 12</option>
+ <option>Item 13</option>
+ <option>Item 14</option>
+ <option>Item 15</option>
+</select>
+<select id="test2" multiple="multiple" size="1" style="height:0.9em">
+ <option>Item 1</option>
+ <option>Item 2</option>
+ <option>Item 3</option>
+ <option>Item 4</option>
+ <option>Item 5</option>
+ <option>Item 6</option>
+ <option>Item 7</option>
+ <option>Item 8</option>
+ <option>Item 9</option>
+ <option>Item 10</option>
+ <option>Item 11</option>
+ <option>Item 12</option>
+ <option>Item 13</option>
+ <option>Item 14</option>
+ <option>Item 15</option>
+</select>
+<select id="test3" multiple="multiple" size="1"></select>
+<select id="test4" multiple="multiple" size="1" style="height:0.9em"></select>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 365410 **/
+
+function pageUpDownTest(id,index) {
+ var elm = document.getElementById(id);
+ elm.focus();
+ elm.selectedIndex = 0;
+ sendKey("page_down");
+ sendKey("page_down");
+ sendKey("page_up");
+ sendKey("page_down");
+ is(elm.selectedIndex, index, "pageUpDownTest: selectedIndex for " + id + " is " + index);
+}
+
+function upDownTest(id,index) {
+ var elm = document.getElementById(id);
+ elm.focus();
+ elm.selectedIndex = 0;
+ sendKey("down");
+ sendKey("down");
+ sendKey("up");
+ sendKey("down");
+ is(elm.selectedIndex, index, "upDownTest: selectedIndex for " + id + " is " + index);
+}
+
+function setHeight(id, h) {
+ var elm = document.getElementById(id);
+ elm.style.height = h + 'px';
+}
+
+function runTest() {
+ var h = document.getElementById("option").clientHeight;
+ var list5itemsHeight = h * 5.5;
+ setHeight("test0", list5itemsHeight);
+ setHeight("test1", list5itemsHeight);
+ setHeight("test3", list5itemsHeight);
+
+ pageUpDownTest("test0",8);
+ pageUpDownTest("test1",8);
+ pageUpDownTest("test2",2);
+ pageUpDownTest("test3",-1);
+ pageUpDownTest("test4",-1);
+ upDownTest("test0",2);
+ upDownTest("test1",2);
+ upDownTest("test2",2);
+ upDownTest("test3",-1);
+ upDownTest("test4",-1);
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTest);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug378670.html b/layout/forms/test/test_bug378670.html
new file mode 100644
index 0000000000..f039cf35d6
--- /dev/null
+++ b/layout/forms/test/test_bug378670.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=378670
+-->
+<head>
+ <title>Test for Bug 378670</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=378670">Mozilla Bug 378670</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+Clicking on the select should not crash Mozilla
+<select id="select">
+<option>1</option>
+<option>2</option>
+</select>
+
+<pre id="test">
+<script>
+document.body.addEventListener('popupshowing', function(e) {e.target.remove() }, true);
+</script>
+<script type="application/javascript">
+
+/** Test for Bug 378670 **/
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+
+function clickit() {
+ var select = document.getElementById('select');
+
+ sendMouseEvent({type:'mousedown'}, select);
+ sendMouseEvent({type:'mouseup'}, select);
+ sendMouseEvent({type:'click'}, select);
+
+ setTimeout(finish, 200);
+}
+
+window.addEventListener('load', clickit);
+
+function finish()
+{
+ ok(true, "This is a mochikit version of a crash test. To complete is to pass.");
+ SimpleTest.finish();
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug402198.html b/layout/forms/test/test_bug402198.html
new file mode 100644
index 0000000000..f319a11976
--- /dev/null
+++ b/layout/forms/test/test_bug402198.html
@@ -0,0 +1,77 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=402198
+-->
+<head>
+ <title>Test for Bug 402198</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=402198">Mozilla Bug 402198</a>
+<p id="display">
+ <select></select>
+ <select><optgroup></optgroup></select>
+ <legend style="overflow: scroll;">
+ <select></select>
+ </legend>
+ <span></span>
+ <span style="display: -moz-box;">
+ <select></select>
+ </span>
+ <legend style=" ">
+ <label style="overflow: scroll; display: -moz-box;">
+ <select></select>
+ </label>
+ </legend>
+ <legend>
+ <label style=" display: table;">
+ <select id="a">
+ <option>High Grade</option>
+ <option>Medium Grade</option>
+ </select>
+ </label>
+ </legend>
+
+ <input>
+ <select multiple="multiple"></select>
+ <select style="overflow: scroll; display: -moz-box;">
+ <optgroup></optgroup>
+ <optgroup style="display: table-cell;"></optgroup>
+ </select>
+</p>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+function doe3() {
+ document.documentElement.style.display = 'none';
+ document.body.offsetHeight;
+ document.documentElement.style.display = '';
+ document.body.offsetHeight;
+
+ document.getElementById('a').focus();
+ document.body.style.display = 'none';
+
+ synthesizeKey('KEY_Tab', {shiftKey: true});
+
+ is(0, 0, "this is a crash/assertion test, so we're ok if we survived this far");
+ setTimeout(function() {document.body.style.display = ''; SimpleTest.finish();}, 0);
+}
+
+function do_test() {
+ setTimeout(doe3,300);
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+addLoadEvent(do_test);
+</script>
+</pre>
+
+<style>
+* {quotes: "quote" "quote" !important;}
+</style>
+
+</body>
+</html>
diff --git a/layout/forms/test/test_bug411236.html b/layout/forms/test/test_bug411236.html
new file mode 100644
index 0000000000..b2e2bee380
--- /dev/null
+++ b/layout/forms/test/test_bug411236.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=411236
+-->
+<head>
+ <title>Test for Bug 411236</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=411236">Mozilla Bug 411236</a>
+<p id="display"></p>
+<div id="content">
+ <input type="file" onfocus="window.oTarget = event.originalTarget;"
+ onclick="window.fileInputGotClick = true; return false;"
+ id="fileinput">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 411236 **/
+
+window.oTarget = null;
+window.fileInputGotClick = false;
+
+function test() {
+ // Try to find the '<input>' using tabbing.
+ var i = 0;
+ while (!window.oTarget && i < 100) {
+ ++i;
+ synthesizeKey("KEY_Tab");
+ }
+
+ if (i >= 100) {
+ ok(false, "Couldn't find an input element!");
+ SimpleTest.finish();
+ return;
+ }
+
+ ok(window.oTarget instanceof HTMLInputElement, "Should have focused the input element!");
+ var e = document.createEvent("mouseevents");
+ e.initMouseEvent("click", true, true, window, 0, 1, 1, 1, 1,
+ false, false, false, false, 0, null);
+ SpecialPowers.wrap(window.oTarget).dispatchEvent(e);
+ ok(window.fileInputGotClick,
+ "File input should have got a click event, but not open the file dialog.");
+ SimpleTest.finish();
+}
+
+function beginTest() {
+ // accessibility.tabfocus must be set to value 7 before running test also
+ // on a mac.
+ SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]}, do_test);
+}
+
+function do_test() {
+ window.focus();
+ document.getElementById('fileinput').focus();
+ setTimeout(test, 100);
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+addLoadEvent(beginTest);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug446663.html b/layout/forms/test/test_bug446663.html
new file mode 100644
index 0000000000..bdab0b20ef
--- /dev/null
+++ b/layout/forms/test/test_bug446663.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=446663
+-->
+<head>
+ <title>Test for Bug 446663</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=446663">Mozilla Bug 446663</a>
+<p id="display">
+<style>#bug446663_a:focus{overflow:hidden}</style>
+<input id="bug446663_a"><input id="bug446663_b"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 446663 **/
+
+function test_edit_cmds(id) {
+
+ var elm = document.getElementById(id);
+ elm.focus();
+ elm.select();
+ SpecialPowers.wrap(elm).controllers.getControllerForCommand('cmd_cut')
+ .doCommand('cmd_cut');
+ is(elm.value, '', id + " cut");
+
+ SpecialPowers.wrap(elm).controllers.getControllerForCommand('cmd_undo')
+ .doCommand('cmd_undo');
+ is(elm.value, '123', id + " undo");
+}
+
+var inputHappened = false;
+function inputListener() {
+ inputHappened = true;
+ $(id).removeEventListener("input", inputListener);
+}
+
+var id = 'bug446663_a'
+var elm = document.getElementById(id);
+elm.focus();
+var x = document.body.offsetHeight;
+$(id).addEventListener("input", inputListener);
+sendChar('1');
+is(inputHappened, true, "How come no input?");
+sendChar('3');
+sendKey('LEFT')
+sendChar('2');
+elm.blur();
+x = document.body.offsetHeight;
+is(elm.value, '123', id + " edit");
+test_edit_cmds(id)
+
+id = 'bug446663_b'
+elm = document.getElementById(id);
+elm.focus();
+sendChar('1');
+elm.style.display = 'none'
+var x = document.body.offsetHeight;
+elm.style.display = 'inline'
+x = document.body.offsetHeight;
+sendChar('3');
+sendKey('LEFT')
+sendChar('2');
+elm.blur();
+x = document.body.offsetHeight;
+is(elm.value, '123', id + " edit");
+test_edit_cmds(id)
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/layout/forms/test/test_bug476308.html b/layout/forms/test/test_bug476308.html
new file mode 100644
index 0000000000..41858d9eb8
--- /dev/null
+++ b/layout/forms/test/test_bug476308.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=476308
+-->
+<head>
+ <title>Test for Bug 345267</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>
+
+<button style="-moz-appearance: none; width: 100px; height: 60px; background-color: red; border: 2px solid green; box-shadow: 30px 0px 3.5px black; position: absolute; top: 300px; left: 20px;"
+ id="button1">1</button>
+
+<br />
+<div style="width: 100px; height: 100px; background-color: green; border: 3px dotted blue; box-shadow: -30px -20px 0px black; position: absolute; top: 500px; left: 70px;"
+ id="div1">2</div>
+
+<script type="text/javascript">
+ var elem = document.elementFromPoint(130, 310);
+ isnot(elem, document.getElementById("button1"), "button1's box-shadow is receiving events when it shouldn't");
+
+ elem = document.elementFromPoint(50, 500);
+ isnot(elem, document.getElementById("div1"), "div1's box-shadow is receiving events when it shouldn't");
+</script>
+
+</body>
+</html>
+
diff --git a/layout/forms/test/test_bug477531.html b/layout/forms/test/test_bug477531.html
new file mode 100644
index 0000000000..e0c7979af4
--- /dev/null
+++ b/layout/forms/test/test_bug477531.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=477531
+-->
+<head>
+ <title>Test for Bug 477531</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+ <style type="text/css">
+ #s {
+ margin-left: 10px;
+ }
+
+ #s:indeterminate {
+ margin-left: 30px;
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=477531">Mozilla Bug 477531</a>
+<p id="display"></p>
+<div id="content">
+
+<input type="checkbox" id="s" />
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 477531 **/
+is(document.defaultView.getComputedStyle($("s")).getPropertyValue("margin-left"),
+ "10px",
+ "Non-indeterminate checkbox should have a margin of 10px");
+
+$("s").indeterminate = true;
+
+is(document.defaultView.getComputedStyle($("s")).getPropertyValue("margin-left"),
+ "30px",
+ "Indeterminate checkbox should have a margin of 30px");
+
+$("s").setAttribute("type", "radio");
+
+is(document.defaultView.getComputedStyle($("s")).getPropertyValue("margin-left"),
+ "30px",
+ "Setting an indeterminate element to type radio should give it indeterminate styles");
+
+$("s").setAttribute("type", "checkbox");
+
+is(document.defaultView.getComputedStyle($("s")).getPropertyValue("margin-left"),
+ "30px",
+ "Setting an indeterminate element to type checkbox should give it indeterminate styles");
+
+$("s").indeterminate = false;
+
+is(document.defaultView.getComputedStyle($("s")).getPropertyValue("margin-left"),
+ "10px",
+ "Newly non-indeterminate checkbox should have a margin of 10px");
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/layout/forms/test/test_bug477700.html b/layout/forms/test/test_bug477700.html
new file mode 100644
index 0000000000..1ab8d88321
--- /dev/null
+++ b/layout/forms/test/test_bug477700.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=477700
+-->
+<head>
+ <title>Test for Bug 477700</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=477700">Mozilla Bug 477700</a>
+<p id="display">
+ <iframe id="i"
+ src="http://example.com/tests/layout/forms/test/bug477700_subframe.html"></iframe>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 477700 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+ isnot(window.location.host, "example.com", "test is not testing cross-site");
+ var accessed = false;
+ try {
+ $("i").contentDocument.documentElement;
+ accessed = true;
+ } catch(e) {}
+ is(accessed, false, "Shouldn't be able to access cross-site");
+
+ $("i").style.display = "none";
+ document.body.offsetWidth;
+ is(document.defaultView.getComputedStyle($("i")).display, "none",
+ "toggling display failed");
+ $("i").style.display = "";
+ document.body.offsetWidth;
+ is(document.defaultView.getComputedStyle($("i")).display, "inline",
+ "toggling display back failed");
+
+ $("i").contentWindow.postMessage("start", "*");
+});
+
+window.addEventListener("message",
+ function(evt) {
+ var arr = evt.data.split(/ /).map(decodeURIComponent);
+ if (arr[0] == 't') {
+ is(arr[1], arr[2], arr[3]);
+ } else if (arr[0] == 'f') {
+ SimpleTest.finish();
+ }
+ });
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug534785.html b/layout/forms/test/test_bug534785.html
new file mode 100644
index 0000000000..7e43838927
--- /dev/null
+++ b/layout/forms/test/test_bug534785.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=534785
+-->
+<head>
+ <title>Test for Bug 534785</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=534785">Mozilla Bug 534785</a>
+<p id="display"></p>
+<input type="text" value="test">
+<div id="reframe">
+<textarea></textarea>
+<textarea>test</textarea>
+<input type="text">
+<input type="text" value="test">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 534785 **/
+
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+ var i = document.querySelector("input");
+ i.addEventListener("focus", function() {
+ is(i.value, "test", "Sanity check");
+
+ is(document.activeElement, i, "Should be focused before frame reconstruction");
+ sendString("1");
+ is(i.value, "1test", "Can accept keyboard events before frame reconstruction");
+
+ // force frame reconstruction
+ i.style.display = "none";
+ document.offsetHeight;
+ i.style.display = "";
+ document.offsetHeight;
+
+ is(document.activeElement, i, "Should be focused after frame reconstruction");
+ sendString("2");
+ is(i.value, "12test", "Can accept keyboard events after frame reconstruction");
+
+ // Make sure reframing happens gracefully
+ var reframeDiv = document.getElementById("reframe");
+ var textAreaWithoutValue = reframeDiv.querySelectorAll("textarea")[0];
+ var textAreaWithValue = reframeDiv.querySelectorAll("textarea")[1];
+ var inputWithoutValue = reframeDiv.querySelectorAll("input")[0];
+ var inputWithValue = reframeDiv.querySelectorAll("input")[1];
+ reframeDiv.style.display = "none";
+ document.body.offsetWidth;
+ reframeDiv.style.display = "";
+ document.body.offsetWidth;
+ [textAreaWithoutValue, inputWithoutValue].forEach(function (elem) {
+ is(elem.value, "", "Value should persist correctly");
+ });
+ [textAreaWithValue, inputWithValue].forEach(function (elem) {
+ is(elem.value, "test", "Value should persist correctly");
+ });
+ [inputWithoutValue, inputWithValue].forEach(elem => elem.type = "submit");
+ document.body.offsetWidth;
+ is(inputWithoutValue.value, "", "Value should persist correctly");
+ is(inputWithValue.value, "test", "Value should persist correctly");
+ [inputWithoutValue, inputWithValue].forEach(elem => elem.type = "text");
+ document.body.offsetWidth;
+ is(inputWithoutValue.value, "", "Value should persist correctly");
+ is(inputWithValue.value, "test", "Value should persist correctly");
+ [inputWithoutValue, inputWithValue].forEach(elem => elem.focus()); // initialze the editor
+ reframeDiv.style.display = "none";
+ document.body.offsetWidth;
+ reframeDiv.style.display = "";
+ document.body.offsetWidth;
+ is(inputWithoutValue.value, "", "Value should persist correctly with editor");
+ is(inputWithValue.value, "test", "Value should persist correctly with editor");
+
+ SimpleTest.finish();
+ });
+ i.focus();
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug536567_perwindowpb.html b/layout/forms/test/test_bug536567_perwindowpb.html
new file mode 100644
index 0000000000..224b2c74a4
--- /dev/null
+++ b/layout/forms/test/test_bug536567_perwindowpb.html
@@ -0,0 +1,215 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=536567
+-->
+<head>
+ <title>Test for Bug 536567</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=536567">Mozilla Bug 536567</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 536567 **/
+
+const Cm = Components.manager;
+
+var MockFilePicker = SpecialPowers.MockFilePicker;
+MockFilePicker.init(window);
+
+var tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
+var homeDir = Services.dirsvc.get("Desk", Ci.nsIFile);
+
+function newDir() {
+ var dir = tmpDir.clone();
+ dir.append("testdir" + Math.floor(Math.random() * 10000));
+ dir.QueryInterface(Ci.nsIFile);
+ dir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o700);
+ return dir;
+}
+
+var dirs = [];
+for(let i = 0; i < 6; i++) {
+ dirs.push(newDir());
+}
+dirs.push(homeDir);
+var domains = ['http://mochi.test:8888', 'http://example.org:80', 'http://example.com:80'];
+/*
+ * These tests take 3 args each:
+ * - which domain to load
+ * - the filePicker displayDirectory we expect to be set
+ * - the file to pick (in most cases this will show up in the next test,
+ * as indicated by the comments)
+ */
+var tests = [
+ "clear history",
+ [0, 6, 0], // 0 -> 3
+ [1, 6, 1], // 1 -> 4
+ [2, 6, 2], // 2 -> 5
+ [0, 0, 3], // 3 -> 6
+ [1, 1, 1], // 4 -> 8
+ [2, 2, 2], // 5 -> 9
+ [0, 3, 1], // 6 -> 7
+ [0, 1, 0], // 7 -> x
+ [1, 1, 1], // 8 -> x
+ [2, 2, 2], // 9 -> x
+ "clear history",
+ [0, 6, 0], // 11 -> 15
+ [1, 6, 1], // 12 -> 16
+ [2, 6, 2], // 13 -> 17
+ "pb on",
+ [0, 0, 3], // 15 -> 18
+ [1, 1, 4], // 16 -> 19
+ [2, 2, 5], // 17 -> 20
+ [0, 3, 3], // 18 -> x
+ [1, 4, 4], // 19 -> x
+ [2, 5, 5], // 20 -> x
+ "pb off",
+ [0, 0, 5], // 22 -> 26
+ [1, 1, 4], // 23 -> 27
+ [2, 2, 3], // 24 -> 28
+ "pb on",
+ [0, 3, 5], // 26 -> x
+ [1, 4, 4], // 27 -> x
+ [2, 5, 3], // 28 -> x
+ "clear history",
+ // Not checking after clear history because browser.download.lastDir content
+ // pref is not being clear properly in private windows.
+ //[0, 6, 0], // 30 -> x
+ //[1, 6, 1], // 31 -> x
+ //[2, 6, 2], // 32 -> x
+ "pb off"
+];
+
+var testIndex = 0;
+var content;
+var normalWindow;
+var privateWindow;
+var normalWindowIframe;
+var privateWindowIframe;
+
+function runTest() {
+ var test = tests[testIndex];
+ if (test == undefined) {
+ endTest();
+ } else if (test == "pb on") {
+ content = privateWindowIframe;
+ testIndex++;
+ runTest();
+ } else if (test == "pb off") {
+ content = normalWindowIframe;
+ testIndex++;
+ runTest();
+ } else if (test == "clear history") {
+ Services.obs.notifyObservers(null, "browser:purge-session-history");
+ testIndex++;
+ runTest();
+ } else {
+ var file = dirs[test[2]].clone();
+ file.append("file.file");
+ MockFilePicker.setFiles([file]);
+ content.setAttribute('src', domains[test[0]] + '/chrome/layout/forms/test/bug536567_subframe.html');
+ }
+}
+
+function endTest() {
+ for(let i = 0; i < dirs.length - 1; i++) {
+ dirs[i].remove(true);
+ }
+
+ normalWindow.close();
+ privateWindow.close();
+ MockFilePicker.cleanup();
+ SimpleTest.finish();
+}
+
+var mainWindow = window.browsingContext.topChromeWindow;
+var contentPage = "http://mochi.test:8888/chrome/layout/forms/test/bug536567_iframe.html";
+
+function whenDelayedStartupFinished(aWindow, aCallback) {
+ Services.obs.addObserver(function observer(aSubject, aTopic) {
+ if (aWindow == aSubject) {
+ Services.obs.removeObserver(observer, aTopic);
+ setTimeout(aCallback, 0);
+ }
+ }, "browser-delayed-startup-finished");
+}
+
+function testOnWindow(aIsPrivate, aCallback) {
+ var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
+ whenDelayedStartupFinished(win, function() {
+ win.addEventListener("DOMContentLoaded", function onInnerLoad() {
+ if (win.content.location.href != contentPage) {
+ win.gBrowser.loadURI(Services.io.newURI(contentPage), {
+ triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+ });
+ return;
+ }
+ win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
+ win.gBrowser.selectedBrowser.focus();
+ SimpleTest.info("DOMContentLoaded's window: " + win.location + " vs. " + window.location);
+ win.setTimeout(function() { aCallback(win); }, 0);
+ }, true);
+ SimpleTest.info("load's window: " + win.location + " vs. " + window.location);
+ win.setTimeout(function() {
+ win.gBrowser.loadURI(Services.io.newURI(contentPage), {
+ triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
+ });
+ }, 0);
+ });
+}
+
+MockFilePicker.showCallback = function(filepicker) {
+ var test = tests[testIndex];
+ var returned = -1;
+ for (let i = 0; i < dirs.length; i++) {
+ var dir = MockFilePicker.displayDirectory
+ ? MockFilePicker.displayDirectory
+ : Services.dirsvc.get(MockFilePicker.displaySpecialDirectory, Ci.nsIFile);
+ if (dirs[i].path == dir.path) {
+ returned = i;
+ break;
+ }
+ }
+ if (test[1] == -1) {
+ ok(false, "We should never get an unknown directory back");
+ } else {
+ is(returned, test[1], 'test ' + testIndex);
+ }
+
+ filepicker.window.setTimeout(function() {
+ testIndex++;
+ runTest();
+ }, 0);
+};
+
+window.onload = function() {
+ SimpleTest.waitForExplicitFinish();
+ testOnWindow(false, function(aWin) {
+ var selectedBrowser = aWin.gBrowser.selectedBrowser;
+
+ normalWindow = aWin;
+ normalWindowIframe =
+ selectedBrowser.contentDocument.getElementById("content");
+
+ testOnWindow(true, function(aPrivateWin) {
+ selectedBrowser = aPrivateWin.gBrowser.selectedBrowser;
+
+ privateWindow = aPrivateWin;
+ privateWindowIframe =
+ selectedBrowser.contentDocument.getElementById("content");
+
+ content = normalWindowIframe;
+ selectedBrowser.contentWindow.setTimeout(runTest, 0);
+ });
+ });
+};
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug542914.html b/layout/forms/test/test_bug542914.html
new file mode 100644
index 0000000000..ff7a68acea
--- /dev/null
+++ b/layout/forms/test/test_bug542914.html
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=542914
+-->
+<head>
+ <title>Test for Bug 542914</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=542914">Mozilla Bug 542914</a>
+<p id="display">
+ <input type="text" id="a" value="test">
+ <input type="text" id="b">
+ <input type="text" id="c">
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 542914 **/
+SimpleTest.waitForExplicitFinish();
+function runTests(callback, type) {
+ var a = $("a");
+
+ // Test that the initial value of the control is available to script
+ // without initilization of the editor
+ is(a.value, "test", "The value is available before initialization");
+ // Initialize the editor
+ a.focus();
+ // Test that the value does not change after initialization
+ is(a.value, "test", "The value does not change after initializtion");
+
+ var b = $("b");
+
+ // Test that the initial value is empty before initialization.
+ is(b.value, "", "The value is empty before initialization");
+ // Make sure that the value can be changed before initialization
+ b.value ="some value";
+ is(b.value, "some value", "The value can be changed before initialization");
+ // Initialize the editor
+ b.focus();
+ // Make sure that the value does not change after initialization
+ is(b.value, "some value", "The value does not change after initialization");
+ // Make sure that the value does not change if the element is hidden
+ b.style.display = "none";
+ document.body.offsetHeight;
+ is(b.value, "some value", "The value does not change while hidden");
+ b.style.display = "";
+ document.body.offsetHeight;
+ b.focus();
+ is(b.value, "some value", "The value does not change after being shown");
+
+ var c = $("c");
+
+ // Make sure that the control accepts input events without explicit initialization
+ is(c.value, "", "Control is empty initially");
+ c.focus();
+ sendChar("a");
+ is(c.value, "a", "Control accepts input without explicit initialization");
+ // Make sure that the control retains its caret position
+ c.focus();
+ c.blur();
+ c.focus();
+ sendChar("b");
+ is(c.value, "ab", "Control retains caret position after being re-focused");
+
+ var d = document.createElement("input");
+ d.setAttribute("type", type);
+ $("display").appendChild(d);
+ document.body.offsetHeight;
+
+ // Make sure dynamically injected inputs work as expected
+ is(d.value, "", "Dynamic control's initial value should be empty");
+ d.value = "new";
+ d.focus();
+ is(d.value, "new", "Dynamic control's value can be set before initialization");
+ sendChar("x");
+ is(d.value, "newx", "Dynamic control accepts keyboard input without explicit initialization");
+ $("display").removeChild(d);
+ is(d.value, "newx", "Dynamic control retains value after being removed from the document");
+
+ callback();
+}
+
+var gPreviousType = "text";
+function setTypes(aType) {
+ var content = document.getElementById("display");
+ content.innerHTML = content.innerHTML.replace(gPreviousType, aType);
+ gPreviousType = aType;
+}
+
+addLoadEvent(function() {
+ ok(true, "Running tests on <input type=text>");
+ runTests(function() {
+ ok(true, "Running tests on <input type=password>");
+ setTypes("password");
+ runTests(function() {
+ ok(true, "Running tests on <input type=tel>");
+ setTypes("tel");
+ runTests(function() {
+ SimpleTest.finish();
+ }, "tel");
+ }, "password");
+ }, "text");
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug549170.html b/layout/forms/test/test_bug549170.html
new file mode 100644
index 0000000000..a8a3f6d508
--- /dev/null
+++ b/layout/forms/test/test_bug549170.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=549170
+-->
+<head>
+ <title>Test for Bug 549170</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 onload="window.setTimeout(runTests, 0);">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=549170">Mozilla Bug 549170</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<input id='i'
+ onmouseup="mouseHandler(event);"
+ onmousedown="mouseHandler(event);">
+<textarea id='t'
+ onmouseup="mouseHandler(event);"
+ onmousedown="mouseHandler(event);"></textarea><br>
+<input id='ip' placeholder='foo'
+ onmouseup="mouseHandler(event);"
+ onmousedown="mouseHandler(event);">
+<textarea id='tp' placeholder='foo'
+ onmouseup="mouseHandler(event);"
+ onmousedown="mouseHandler(event);"></textarea>
+<pre id="test">
+
+<script type="application/javascript">
+
+/** Test for Bug 549170 **/
+
+var gNumberOfMouseEventsCaught = 0;
+
+SimpleTest.waitForExplicitFinish();
+
+function mouseHandler(aEvent)
+{
+ gNumberOfMouseEventsCaught++;
+ is(SpecialPowers.wrap(aEvent).originalTarget.nodeName, "DIV", "An inner div should be the target of the event");
+ ok(SpecialPowers.wrap(aEvent).originalTarget.implementedPseudoElement == "::-moz-text-control-editing-root", "the target div should be the editor div");
+}
+
+function checkMouseEvents(element)
+{
+ gNumberOfMouseEventsCaught = 0;
+
+ let x = element.offsetWidth / 2;
+ let y = element.offsetHeight / 2;
+
+ synthesizeMouse(element, x, y, {type: "mousedown", button: 0});
+ synthesizeMouse(element, x, y, {type: "mouseup", button: 0});
+ synthesizeMouse(element, x, y, {type: "mousedown", button: 1});
+ // NOTE: this event is going to copy the buffer on linux, this should not be a problem
+ synthesizeMouse(element, x, y, {type: "mouseup", button: 1});
+ synthesizeMouse(element, x, y, {type: "mousedown", button: 2});
+ synthesizeMouse(element, x, y, {type: "mouseup", button: 2});
+
+ is(gNumberOfMouseEventsCaught, 6, "Some mouse events have not been caught");
+}
+
+function runTests()
+{
+ checkMouseEvents(document.getElementById('i'));
+ checkMouseEvents(document.getElementById('t'));
+ checkMouseEvents(document.getElementById('ip'));
+ checkMouseEvents(document.getElementById('tp'));
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug562447.html b/layout/forms/test/test_bug562447.html
new file mode 100644
index 0000000000..86042bb485
--- /dev/null
+++ b/layout/forms/test/test_bug562447.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=562447
+-->
+<head>
+ <title>Test for Bug 562447</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+</head>
+<body>
+<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug?id=562447">Mozilla Bug 562447</a>
+
+<input id="WhyDoYouFocusMe"
+ style="position: absolute; left: -50px; top: 10000px;">
+
+<pre id="test">
+<script>
+addLoadEvent(function() {
+ // Scroll down a bit
+ window.scrollTo(0, 5000);
+
+ setTimeout(function() {
+ // Make sure that we're scrolled by 5000px
+ is(Math.round(window.pageYOffset), 5000, "Make sure we're scrolled correctly");
+
+ // Scroll back up, and mess with the input box along the way
+ var input = document.getElementById("WhyDoYouFocusMe");
+ input.focus();
+ input.blur();
+ window.scrollTo(0, 0);
+
+ setTimeout(function() {
+ is(window.pageYOffset, 0, "Make sure we're scrolled back up correctly");
+
+ // Scroll back up
+ window.scrollTo(0, 5000);
+
+ setTimeout(function() {
+ is(Math.round(window.pageYOffset), 5000, "Sanity check");
+
+ window.scrollTo(0, 0);
+ input.focus();
+ input.blur();
+
+ setTimeout(function() {
+ isnot(Math.round(window.pageYOffset), 0, "This time we shouldn't be scrolled up");
+
+ SimpleTest.finish();
+ }, 0);
+ }, 0);
+ }, 0);
+ }, 0);
+});
+
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/layout/forms/test/test_bug563642.html b/layout/forms/test/test_bug563642.html
new file mode 100644
index 0000000000..72bb4c6858
--- /dev/null
+++ b/layout/forms/test/test_bug563642.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=563642
+-->
+<head>
+ <title>Test for Bug 563642</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=563642">Mozilla Bug 563642</a>
+<p id="display">
+<select id="test1" multiple="multiple" size="1">
+ <option>Item 1</option>
+ <option>Item 2</option>
+ <option>Item 3</option>
+ <option>Item 4</option>
+ <option>Item 5</option>
+</select>
+<select id="test2" multiple="multiple" size="1">
+ <option>Item 1</option>
+ <option disabled>Item 2</option>
+ <option>Item 3</option>
+ <option disabled>Item 4</option>
+ <option>Item 5</option>
+</select>
+<select id="test3" multiple="multiple"></select>
+<select id="test4" multiple="multiple" size="1"></select>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 563642 **/
+
+function pageUpDownTest(id,index) {
+ var elm = document.getElementById(id);
+ elm.focus();
+ elm.selectedIndex = 0;
+ sendKey("page_down");
+ sendKey("page_down");
+ sendKey("page_down");
+ sendKey("page_up");
+ sendKey("page_down");
+ is(elm.selectedIndex, index, "pageUpDownTest: selectedIndex for " + id + " is " + index);
+}
+
+function upDownTest(id,index) {
+ var elm = document.getElementById(id);
+ elm.focus();
+ elm.selectedIndex = 0;
+ sendKey("down");
+ sendKey("down");
+ sendKey("down");
+ sendKey("up");
+ sendKey("down");
+ is(elm.selectedIndex, index, "upDownTest: selectedIndex for " + id + " is " + index);
+}
+
+function runTest() {
+ pageUpDownTest("test1",3);
+ pageUpDownTest("test2",4);
+ pageUpDownTest("test3",-1);
+ pageUpDownTest("test4",-1);
+ upDownTest("test1",3);
+ upDownTest("test2",4);
+ upDownTest("test3",-1);
+ upDownTest("test4",-1);
+
+ SimpleTest.finish();
+}
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTest);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug564115.html b/layout/forms/test/test_bug564115.html
new file mode 100644
index 0000000000..16fb423341
--- /dev/null
+++ b/layout/forms/test/test_bug564115.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=564115
+-->
+<head>
+ <title>Test for Bug 564115</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+</head>
+<body>
+<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug?id=564115">Mozilla Bug 564115</a>
+
+<pre id="test">
+<script>
+
+const TEST_URL = "/tests/layout/forms/test/bug564115_window.html";
+
+addLoadEvent(function() {
+ var win = open(TEST_URL, "", "width=600,height=600");
+ SimpleTest.waitForFocus(function() {
+ var doc = win.document;
+ var input = doc.querySelector("input");
+
+ // Focus the input box, and wait for the focus to actually happen
+ input.focus();
+ win.requestAnimationFrame(function() {
+ win.requestAnimationFrame(function() {
+ // Scroll down a bit
+ win.scrollTo(0, 5000);
+
+ setTimeout(function() {
+ is(Math.round(win.pageYOffset), 5000, "Page should be scrolled correctly");
+
+ // Refocus the window
+ SimpleTest.waitForFocus(function() {
+ SimpleTest.waitForFocus(function() {
+ is(Math.round(win.pageYOffset), 5000,
+ "The page's scroll offset should not have been changed");
+
+ win.close();
+ SimpleTest.finish();
+ }, win);
+ });
+ }, 0);
+ });
+ });
+ }, win);
+});
+
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/layout/forms/test/test_bug571352.html b/layout/forms/test/test_bug571352.html
new file mode 100644
index 0000000000..73ad7454f3
--- /dev/null
+++ b/layout/forms/test/test_bug571352.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=571352
+-->
+<head>
+ <title>Test for Bug 571352</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=571352">Mozilla Bug 571352</a>
+<p id="display"><select multiple style="width:300px/*to avoid any overlay scrollbar messing with our mouse clicks*/"><option>0<option>1<option>2<option>3<option>4<option>5</select></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 571352 **/
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function test() {
+ function focusList() {
+ $('display').firstChild.focus();
+ }
+ function option(index) {
+ return $('display').firstChild.childNodes[index];
+ }
+ function remove(index) {
+ var sel = $('display').firstChild;
+ sel.removeChild(sel.childNodes[index]);
+ document.body.clientHeight;
+ }
+ function up() { synthesizeKey("KEY_ArrowUp"); }
+ function shiftUp() { synthesizeKey("KEY_ArrowUp", {shiftKey:true}); }
+ function down() { synthesizeKey("KEY_ArrowDown"); }
+ function shiftDown() { synthesizeKey("KEY_ArrowDown", {shiftKey:true}); }
+ function mouseEvent(index,event) {
+ synthesizeMouse(option(index), 5, 5, event);
+ }
+
+ const click = {};
+ const shiftClick = {shiftKey:true};
+ focusList();
+ mouseEvent(0,click)
+ is(document.activeElement,$('display').firstChild,"<select> is focused");
+ ok(option(0).selected,"first option is selected");
+ mouseEvent(2,shiftClick)
+ remove(0);
+ ok(option(0).selected && option(1).selected,"first two options are selected");
+ mouseEvent(2,shiftClick)
+ ok(option(0).selected && option(1).selected && option(2).selected,"first three options are selected");
+ shiftUp();
+ ok(option(0).selected && option(1).selected,"first two options are selected");
+ remove(1);
+ ok(option(0).selected,"first option is selected");
+ shiftDown();
+ ok(option(0).selected && option(1).selected,"first two options are selected");
+ down();
+ ok(option(2).selected,"third option is selected");
+ shiftDown();
+ ok(option(2).selected && option(3).selected,"third & fourth option are selected");
+ remove(2);
+ shiftUp();
+ ok(option(1).selected && option(2).selected,"2nd & third option are selected");
+ remove(0);
+ mouseEvent(0,shiftClick)
+ ok(option(0).selected && option(1).selected,"all remaining 2 options are selected");
+ shiftDown();
+ remove(1);
+ ok(!option(0).selected,"first option is unselected");
+ remove(0); // select is now empty
+ ok($('display').firstChild.firstChild==null,"all options were removed");
+
+ SimpleTest.finish();
+});
+
+
+
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug572406.html b/layout/forms/test/test_bug572406.html
new file mode 100644
index 0000000000..8b4d0b81ce
--- /dev/null
+++ b/layout/forms/test/test_bug572406.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=572406
+-->
+<head>
+ <title>Test for Bug 572406</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload='runTests();'>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=572406">Mozilla Bug 572406</a>
+<p id="display"></p>
+<div id='content'>
+ <textarea id='i'>foo</textarea>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 572406 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function runTests()
+{
+ var textarea = document.getElementById('i');
+
+ textarea.firstChild.nodeValue = "bar";
+ is(textarea.value, textarea.firstChild.nodeValue,
+ "textarea value should be firstChild.nodeValue");
+ is(textarea.defaultValue, textarea.firstChild.nodeValue,
+ "textarea defaultValue should be firstChild.nodeValue");
+
+ textarea.style.display = 'none';
+ SimpleTest.executeSoon(function() {
+ textarea.firstChild.nodeValue = "tulip";
+ is(textarea.value, textarea.firstChild.nodeValue,
+ "textarea value should be firstChild.nodeValue");
+ is(textarea.defaultValue, textarea.firstChild.nodeValue,
+ "textarea defaultValue should be firstChild.nodeValue");
+ SimpleTest.finish();
+ });
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug572649.html b/layout/forms/test/test_bug572649.html
new file mode 100644
index 0000000000..10fa6e63f7
--- /dev/null
+++ b/layout/forms/test/test_bug572649.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=572649
+-->
+<head>
+ <title>Test for Bug 572649</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=572649">Mozilla Bug 572649</a>
+<p id="display">
+ <textarea id="area" rows="5">
+ Here
+ is
+ some
+ very
+ long
+ text
+ that
+ we're
+ using
+ for
+ testing
+ purposes
+ </textarea>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 572649 **/
+SimpleTest.waitForExplicitFinish();
+
+// We intermittently trigger two "Wrong parent ComputedStyle" assertions
+// on B2G emulator builds (bug XXXXXXX). The two frames that get incorrect
+// ComputedStyle parents are scroll bar parts in the <textarea>.
+SimpleTest.expectAssertions(0, 2);
+
+addLoadEvent(function() {
+ var area = document.getElementById("area");
+
+ is(area.scrollTop, 0, "The textarea should not be scrolled initially");
+ area.addEventListener("focus", function() {
+ setTimeout(function() {
+ is(area.scrollTop, 0, "The textarea's insertion point should not be scrolled into view");
+
+ SimpleTest.finish();
+ }, 0);
+ }, {once: true});
+ setTimeout(function() {
+ var rect = area.getBoundingClientRect();
+ synthesizeMouse(area, rect.width - 5, 5, {});
+ }, 0);
+});
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug595310.html b/layout/forms/test/test_bug595310.html
new file mode 100644
index 0000000000..47db981167
--- /dev/null
+++ b/layout/forms/test/test_bug595310.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=595310
+-->
+<head>
+ <title>Test for Bug 595310</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.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=595310">Mozilla Bug 595310</a>
+<p id="display"></p>
+<div id="content">
+ <input id='i' value="bar">
+ <textarea id='t'>bar</textarea>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 595310 **/
+
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(function() {
+ // We want to compare to value="bar" and no placeholder shown.
+ // That is what is currently showed.
+ var s1 = snapshotWindow(window, false);
+
+ var content = document.getElementById('content');
+ var i = document.getElementById('i');
+ var t = SpecialPowers.wrap(document.getElementById('t'));
+ i.value = ""; i.placeholder = "foo";
+ t.value = ""; t.placeholder = "foo";
+
+ // Flushing.
+ // Note: one call would have been enough actually but I didn't want to favour
+ // one element... ;)
+ i.getBoundingClientRect();
+ t.getBoundingClientRect();
+
+ function synthesizeDropText(aElement, aText)
+ {
+ SpecialPowers.wrap(aElement).editor.insertText(aText);
+ }
+
+ // We insert "bar" and we should only see "bar" now.
+ synthesizeDropText(i, "bar");
+ synthesizeDropText(t, "bar");
+
+ var s2 = snapshotWindow(window, false);
+
+ ok(compareSnapshots(s1, s2, true)[0],
+ "When setting the value, the placeholder should disappear.");
+
+ SimpleTest.finish();
+});
+
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug620936.html b/layout/forms/test/test_bug620936.html
new file mode 100644
index 0000000000..aa1beed01a
--- /dev/null
+++ b/layout/forms/test/test_bug620936.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=620936
+-->
+<head>
+ <title>Test for Bug 620936</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=620936">Mozilla Bug 620936</a>
+<p id="display"></p>
+<div id="content">
+ <input value="foo">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 620936 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+ var i = document.querySelector("input");
+ i.focus();
+ i.setSelectionRange(100, 100);
+ is(i.selectionStart, 3, "The selection should be set to the end of the text");
+ is(i.selectionEnd, 3, "The selection should be set to the end of the text");
+ SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug644542.html b/layout/forms/test/test_bug644542.html
new file mode 100644
index 0000000000..6c33cbe958
--- /dev/null
+++ b/layout/forms/test/test_bug644542.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=644542
+-->
+<head>
+ <title>Test for Bug 644542</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"/>
+ <style type="text/css">
+ select:after {
+ content: ' appended string';
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=644542">Mozilla Bug 644542</a>
+<p id="display">
+ <form method="post" action="">
+ <select id="select">
+ <option value="1">1</option>
+ <option value="2">2</option>
+ </select>
+ </form>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 644542 **/
+
+var select = document.getElementById("select");
+
+var clicks = 0;
+
+function click() {
+ synthesizeMouseAtCenter(select, { });
+ ++clicks;
+
+ // At least two clicks were required for bug 644542, sometimes more;
+ // delay is long enough that this doesn't look like a double
+ // click, and also allows time for popup to show and for painting.
+ setTimeout(clicks < 4 ? click : done, 500);
+}
+
+function done() {
+ ok(true, "No crash on opening dropdown");
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+// waitForFocus is most likely not the right thing to wait for, but
+// without this the first click is ineffective (even with a reflow forced
+// before synthesizeMouse).
+SimpleTest.waitForFocus(click);
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug672810.html b/layout/forms/test/test_bug672810.html
new file mode 100644
index 0000000000..991fe57389
--- /dev/null
+++ b/layout/forms/test/test_bug672810.html
@@ -0,0 +1,120 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=672810
+-->
+<head>
+ <title>Test for Bug 672810</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=672810">Mozilla Bug 672810</a>
+<p id="display"></p>
+<div id="content">
+ <select id="s1" multiple size="10"><option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x</select>
+ <select id="s2" size="10"><option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x</select>
+ <select id="s3" size="1"><option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x<option>x</select>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 672810 **/
+
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+ var sel = document.getElementsByTagName('select');
+
+ sel[0].addEventListener('focus', function() {
+ s = sel[0];
+ s.removeEventListener('focus', arguments.callee);
+ synthesizeKey('KEY_ArrowDown');
+ is(s.selectedIndex,0, s.id + ": initial DOWN selects first option");
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true});
+ is(s.selectedIndex,0, s.id + ": first option is still selected");
+ ok(!s[1].selected,s.id + ": CTRL+DOWN did not select 2nd option");
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true});
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,0, s.id + ": first option is still selected");
+ ok(!s[1].selected,s.id + ": 2nd option is still unselected");
+ ok(s[2].selected,s.id + ": 3rd option is selected");
+ ok(s[3].selected,s.id + ": 4th option is selected");
+ ok(!s[4].selected,s.id + ": 5th option is unselected");
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,0, s.id + ": first option is still selected");
+ ok(!s[1].selected,s.id + ": 2nd option is still unselected");
+ ok(s[2].selected,s.id + ": 3rd option is still selected");
+ ok(s[3].selected,s.id + ": 4th option is still selected");
+ ok(s[4].selected,s.id + ": 5th option is selected");
+ ok(!s[5].selected,s.id + ": 6th option is unselected");
+ synthesizeKey('KEY_ArrowUp', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,0, s.id + ": first option is still selected");
+ ok(!s[1].selected,s.id + ": 2nd option is still unselected");
+ ok(s[2].selected,s.id + ": 3rd option is still selected");
+ ok(s[3].selected,s.id + ": 4th option is still selected");
+ ok(s[4].selected,s.id + ": 5th option is still selected");
+ ok(!s[5].selected,s.id + ": 6th option is still unselected");
+ synthesizeKey(' ', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,0, s.id + ": first option is still selected");
+ ok(!s[1].selected,s.id + ": 2nd option is still unselected");
+ ok(s[2].selected,s.id + ": 3rd option is still selected");
+ ok(!s[3].selected,s.id + ": 4th option is unselected");
+ ok(s[4].selected,s.id + ": 5th option is still selected");
+ ok(!s[5].selected,s.id + ": 6th option is still unselected");
+ synthesizeKey(' ', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,0, s.id + ": first option is still selected");
+ ok(!s[1].selected,s.id + ": 2nd option is still unselected");
+ ok(s[2].selected,s.id + ": 3rd option is still selected");
+ ok(s[3].selected,s.id + ": 4th option is selected");
+ ok(s[4].selected,s.id + ": 5th option is still selected");
+ ok(!s[5].selected,s.id + ": 6th option is still unselected");
+ setTimeout(function(){sel[1].focus()},0);
+ });
+ sel[1].addEventListener('focus', function() {
+ s = sel[1];
+ s.removeEventListener('focus', arguments.callee);
+ synthesizeKey('KEY_ArrowDown');
+ is(s.selectedIndex,0, s.id + ": initial DOWN selects first option");
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true});
+ is(s.selectedIndex,1, s.id + ": 2nd option is selected");
+ ok(!s[0].selected,s.id + ": CTRL+DOWN deselected first option");
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true});
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,3, s.id + ": 4th option is selected");
+ ok(!s[1].selected,s.id + ": CTRL+SHIFT+DOWN deselected 2nd option");
+ synthesizeKey(' ', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,3, s.id + ": 4th option is still selected");
+ synthesizeKey(' ', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,3, s.id + ": 4th option is still selected");
+ setTimeout(function(){sel[2].focus()},0);
+ });
+ sel[2].addEventListener('focus', function() {
+ if (!navigator.platform.includes("Mac")) {
+ s = sel[2];
+ s.removeEventListener('focus', arguments.callee);
+ synthesizeKey('KEY_ArrowDown');
+ is(s.selectedIndex,1, s.id + ": initial DOWN selects 2nd option");
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true});
+ is(s.selectedIndex,2, s.id + ": 3rd option is selected");
+ ok(!s[1].selected,s.id + ": CTRL+DOWN deselected 2nd option");
+ synthesizeKey('KEY_ArrowDown', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,3, s.id + ": 4th option is selected");
+ ok(!s[2].selected,s.id + ": CTRL+SHIFT+DOWN deselected 3rd option");
+ synthesizeKey(' ', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,3, s.id + ": 4th option is still selected");
+ synthesizeKey(' ', {ctrlKey: true, shiftKey: true});
+ is(s.selectedIndex,3, s.id + ": 4th option is still selected");
+ } else {
+ todo(false, "Make this test work on OSX");
+ }
+ setTimeout(function(){SimpleTest.finish()},0);
+ });
+ sel[0].focus();
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug704049.html b/layout/forms/test/test_bug704049.html
new file mode 100644
index 0000000000..1da2badea2
--- /dev/null
+++ b/layout/forms/test/test_bug704049.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=704049
+-->
+<head>
+ <title>Test for Bug 704049</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=704049">Mozilla Bug 704049</a>
+<p id="display"></p>
+<input type="radio" id="radio11" name="group1">
+<input type="radio" id="radio12" name="group1">
+<input type="radio" id="radio21" name="group2" checked>
+<input type="radio" id="radio22" name="group2">
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 704049 **/
+
+window.addEventListener("click", function (e) { e.preventDefault(); });
+
+function doTest()
+{
+ var target = document.getElementById("radio11");
+ synthesizeMouseAtCenter(target, {});
+ is(target.checked, false, "radio11 is checked");
+ target = document.getElementById("radio12");
+ synthesizeMouseAtCenter(target, {});
+ is(target.checked, false, "radio12 is checked");
+ target = document.getElementById("radio21");
+ synthesizeMouseAtCenter(target, {});
+ is(target.checked, true, "radio21 is not checked");
+ target = document.getElementById("radio22");
+ synthesizeMouseAtCenter(target, {});
+ is(target.checked, false, "radio22 is checked");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(doTest);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug717878_input_scroll.html b/layout/forms/test/test_bug717878_input_scroll.html
new file mode 100644
index 0000000000..6bd27ddacc
--- /dev/null
+++ b/layout/forms/test/test_bug717878_input_scroll.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717878
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 717878</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=717878">Mozilla Bug 717878</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<!-- size=10 and monospace font ensure there's no overflow in either direction -->
+<input id="no-overflow" type="text"
+ size="10"
+ style="
+ font-family: monospace;
+ font-size: 1em;"
+ value="Short">
+<!-- ditto, with appearance:none -->
+<input id="no-overflow2" type="text"
+ size="10"
+ style="
+ -webkit-appearance:none;
+ font-family: monospace;
+ font-size: 1em;"
+ value="Short">
+<!-- size=10, monospace font, and height=0.5em ensure overflow in both directions -->
+<input id="overflow" type="text"
+ size="10"
+ style="
+ font-family: monospace;
+ font-size: 3em;
+ height: 0.5em;"
+ value="This is a long string">
+<!-- ditto, with appearance:none -->
+<input id="overflow2" type="text"
+ size="10"
+ style="
+ -webkit-appearance:none;
+ font-family: monospace;
+ font-size: 3em;
+ height: 0.5em;"
+ value="This is a long string">
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 717878 **/
+
+/**
+ * Test an element's scroll properties for correctness
+ *
+ * @param element Element to test
+ * @param prop Specify the property to test,
+ * i.e. "scrollLeft" or "scrollTop"
+ * @param propMax Specify the scrollMax property to test,
+ * i.e. "scrollLeftMax" or "scrollTopMax"
+ * @param is_overflow Specify whether the element is
+ * scrollable in the above direction
+ */
+function test_scroll(element, scroll, scrollMax, is_overflow) {
+
+ is(element[scroll], 0, element.id + " initial " + scroll + " != 0");
+ if (is_overflow) {
+ isnot(element[scrollMax], 0, element.id + " " + scrollMax + " == 0");
+ } else {
+ is(element[scrollMax], 0, element.id + " " + scrollMax + " != 0");
+ }
+
+ element[scroll] = 10;
+ if (is_overflow) {
+ isnot(element[scroll], 0, element.id + " unable to scroll " + scroll);
+ } else {
+ is(element[scroll], 0, element.id + " able to scroll " + scroll);
+ }
+
+ element[scroll] = element[scrollMax];
+ is(element[scroll], element[scrollMax], element.id + " did not scroll to " + scrollMax);
+
+ element[scroll] = element[scrollMax] + 10;
+ is(element[scroll], element[scrollMax], element.id + " scrolled past " + scrollMax);
+}
+
+var no_overflow = document.getElementById("no-overflow");
+test_scroll(no_overflow, "scrollLeft", "scrollLeftMax", /* is_overflow */ false);
+test_scroll(no_overflow, "scrollTop", "scrollTopMax", /* is_overflow */ false);
+
+var no_overflow2 = document.getElementById("no-overflow2");
+test_scroll(no_overflow2, "scrollLeft", "scrollLeftMax", /* is_overflow */ false);
+test_scroll(no_overflow2, "scrollTop", "scrollTopMax", /* is_overflow */ false);
+
+var overflow = document.getElementById("overflow");
+test_scroll(overflow, "scrollLeft", "scrollLeftMax", /* is_overflow */ true);
+test_scroll(overflow, "scrollTop", "scrollTopMax", /* is_overflow */ true);
+
+var overflow2 = document.getElementById("overflow2");
+test_scroll(overflow2, "scrollLeft", "scrollLeftMax", /* is_overflow */ true);
+test_scroll(overflow2, "scrollTop", "scrollTopMax", /* is_overflow */ true);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug869314.html b/layout/forms/test/test_bug869314.html
new file mode 100644
index 0000000000..7c786fccfc
--- /dev/null
+++ b/layout/forms/test/test_bug869314.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=869314
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 869314</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+ <style type="text/css">
+ .selectbox {
+ background-color: #00FF00;
+ }
+ </style>
+
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=869314">Mozilla Bug 869314</a>
+<p id="display"></p>
+<div id="content">
+
+ <select id="selectbox1" name="non-native selectbox" class="selectbox">
+ <option value="item">test item</option>
+ </select>
+
+ <select id="selectbox2" name="native selectbox">
+ <option value="item">test item</option>
+ </select>
+
+ <script type="application/javascript">
+ let Cc = SpecialPowers.Cc;
+ let Ci = SpecialPowers.Ci;
+ let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
+ let osName = sysInfo.getProperty("name");
+ let isNNT = SpecialPowers.getBoolPref("widget.non-native-theme.enabled");
+ if (osName == "Darwin" && !isNNT) { // Native styled macOS form controls.
+ // This test is for macOS with native styled form controls only. See bug for more info.
+ ok(document.getElementById("selectbox1").clientWidth >
+ document.getElementById("selectbox2").clientWidth,
+ "Non-native styled combobox does not have enough space for a " +
+ "dropmarker!");
+ } else {
+ // We need to call at least one test function to make the test harness
+ // happy.
+ ok(true, "Test wasn't ignored but should have been.");
+ }
+ </script>
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug903715.html b/layout/forms/test/test_bug903715.html
new file mode 100644
index 0000000000..b887b2cd01
--- /dev/null
+++ b/layout/forms/test/test_bug903715.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=903715
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 903715</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=903715">Mozilla Bug 903715</a>
+<p id="display"></p>
+<div id="content">
+ <form id="form" action="/">
+ <select id="select" name="select">
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option>5</option>
+ <option>6</option>
+ <option>7</option>
+ <option>8</option>
+ <option>9</option>
+ </select>
+ <input id="input-text" name="text" value="some text">
+ <input id="input-submit" type="submit">
+ </form>
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+SimpleTest.waitForFocus(runTests, window);
+
+function runTests()
+{
+ var form = document.getElementById("form");
+ form.addEventListener("keypress", function (aEvent) {
+ ok(false, "keypress event shouldn't be fired when the preceding keydown event caused closing the dropdown of the select element");
+ }, true);
+ form.addEventListener("submit", function (aEvent) {
+ ok(false, "submit shouldn't be performed by the Enter key press on the select element");
+ aEvent.preventDefault();
+ }, true);
+ var select = document.getElementById("select");
+ select.addEventListener("change", function (aEvent) {
+ var input = document.getElementById("input-text");
+ input.focus();
+ input.select();
+ });
+
+ select.focus();
+
+ select.addEventListener("popupshowing", function (aEvent) {
+ setTimeout(function () {
+ synthesizeKey("KEY_ArrowDown");
+ select.addEventListener("popuphiding", function (aEventInner) {
+ setTimeout(function () {
+ // Enter key should cause closing the dropdown of the select element
+ // and keypress event shouldn't be fired on the input element because
+ // which shouldn't cause sumbmitting the form contents.
+ ok(true, "Test passes if there is no error");
+ SimpleTest.finish();
+ }, 100);
+ });
+ // Close dropdown.
+ synthesizeKey("KEY_Enter");
+ }, 100);
+ });
+
+ // Open dropdown.
+ synthesizeKey("KEY_ArrowDown", { altKey: true });
+}
+</script>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug935876.html b/layout/forms/test/test_bug935876.html
new file mode 100644
index 0000000000..4488fdf962
--- /dev/null
+++ b/layout/forms/test/test_bug935876.html
@@ -0,0 +1,502 @@
+<!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;
+
+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 {
+ ok(!keyPressEventFired, "keypress event shouldn't be fired 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>
diff --git a/layout/forms/test/test_bug957562.html b/layout/forms/test/test_bug957562.html
new file mode 100644
index 0000000000..52821d8757
--- /dev/null
+++ b/layout/forms/test/test_bug957562.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=957562
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 903715</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=957562">Mozilla Bug 957562</a>
+<p id="display"></p>
+<input id="n" onfocus="kill()" type="number" style="border:20px solid black">
+<pre id="test">
+</pre>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests, window);
+
+var killed = false;
+function kill() {
+ if (killed) {
+ return;
+ }
+ killed = true;
+ n.style.display = 'none';
+ r = n.getBoundingClientRect();
+ setTimeout(function() {
+ ok(true, "Didn't crash");
+ SimpleTest.finish();
+ }, 0);
+}
+
+function runTests()
+{
+ synthesizeMouse(n, 2, 2, {});
+}
+</script>
+</body>
+</html>
diff --git a/layout/forms/test/test_bug960277.html b/layout/forms/test/test_bug960277.html
new file mode 100644
index 0000000000..28981b121a
--- /dev/null
+++ b/layout/forms/test/test_bug960277.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=960277
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 903715</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=960277">Mozilla Bug 960277</a>
+<p id="display"></p>
+<fieldset style="position:relative; height:100px; margin:50px; background:blue;">
+<legend style="background:purple">
+ <div id="d" style="position:absolute; background:yellow; top:0; left:0; width:50px; height:50px;"></div>
+</legend>
+</fieldset>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+var rect = d.getBoundingClientRect();
+is(document.elementFromPoint(rect.left + 10, rect.top + 10), d,
+ "Hit testing yellow div");
+</script>
+</body>
+</html>
diff --git a/layout/forms/test/test_listcontrol_search.html b/layout/forms/test/test_listcontrol_search.html
new file mode 100644
index 0000000000..d696edae66
--- /dev/null
+++ b/layout/forms/test/test_listcontrol_search.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=849438
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for &lt;select&gt; list control search</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"/>
+ <script type="application/javascript">
+
+ /** This test will focus a select element and press a key that matches the
+ first non-space character of an entry. **/
+
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.waitForFocus(function() {
+ var select = document.getElementsByTagName('select')[0];
+ select.focus();
+ sendString('a');
+
+ is(select.options[0].selected, false, "the first option isn't selected");
+ is(select.options[1].selected, true, "the second option is selected");
+
+ select.blur();
+
+ SimpleTest.finish();
+ });
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=849438">Mozilla Bug 849438</a>
+<p id="display"></p>
+<div id="content">
+ <select>
+ <option>Please select an entry</option>
+ <option>&nbsp;a</option>
+ <option>&nbsp;b</option>
+ </select>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_readonly.html b/layout/forms/test/test_readonly.html
new file mode 100644
index 0000000000..3bfb768f9c
--- /dev/null
+++ b/layout/forms/test/test_readonly.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="should-apply">
+ <textarea></textarea>
+ <input type="text">
+ <input type="password">
+ <input type="search">
+ <input type="tel">
+ <input type="email">
+ <input type="url">
+ <input type="number">
+ <input type="date">
+ <input type="time">
+ <input type="month">
+ <input type="week">
+ <input type="datetime-local">
+</div>
+<div id="should-not-apply">
+ <input type="hidden">
+ <input type="button">
+ <input type="image">
+ <input type="reset">
+ <input type="submit">
+ <input type="radio">
+ <input type="file">
+ <input type="checkbox">
+ <input type="range">
+ <input type="color">
+</div>
+<script>
+for (const element of Array.from(document.querySelectorAll('#should-apply *'))) {
+ let elementDesc = element.tagName.toLowerCase();
+ if (elementDesc === "input")
+ elementDesc += ` type="${element.type}"`;
+ test(function() {
+ assert_false(element.matches(':read-only'), "Shouldn't be initially read-only");
+ assert_true(element.matches(':read-write'), "Thus should be read-write");
+ element.setAttribute("readonly", "readonly");
+ assert_true(element.matches(':read-only'), "Should become read-only");
+ assert_false(element.matches(':read-write'), "Thus should stop being read-write");
+ }, elementDesc);
+}
+
+for (const element of Array.from(document.querySelectorAll('#should-not-apply *'))) {
+ let elementDesc = element.tagName.toLowerCase();
+ if (elementDesc === "input")
+ elementDesc += ` type="${element.type}"`;
+ test(function() {
+ assert_true(element.matches(':read-only'), "Should match read-only");
+ assert_false(element.matches(':read-write'), "Should not be read-write");
+ element.setAttribute("readonly", "readonly");
+ assert_true(element.matches(':read-only'), "Should keep matching read-only");
+ assert_false(element.matches(':read-write'), "Should still not be read-write");
+ }, elementDesc);
+}
+</script>
diff --git a/layout/forms/test/test_select_collapsed_page_keys.html b/layout/forms/test/test_select_collapsed_page_keys.html
new file mode 100644
index 0000000000..08c1615152
--- /dev/null
+++ b/layout/forms/test/test_select_collapsed_page_keys.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test for page up/down in collapsed select (bug 1488828)</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"/>
+<script>
+ SimpleTest.waitForExplicitFinish();
+
+ function test() {
+ let select = document.getElementById("select");
+ select.focus();
+ is(select.selectedIndex, 0, "Option 0 initially selected");
+ synthesizeKey("KEY_PageDown", {});
+ ok(select.selectedIndex >= 2, "PageDown skips more than 1 option");
+ ok(select.selectedIndex < 49, "PageDown does not move to the last option");
+ synthesizeKey("KEY_PageUp", {});
+ is(select.selectedIndex, 0, "PageUp skips more than 1 option");
+ SimpleTest.finish();
+ }
+</script>
+</head>
+<body onload="test()">
+<div>
+ <select id="select" size="1">
+ <option selected>0</option>
+ </select>
+ <script>
+ // Add more options so we have 50 in total.
+ let select = document.getElementById("select");
+ for (let i = 1; i <= 49; ++i) {
+ let option = document.createElement("option");
+ option.textContent = i;
+ select.appendChild(option);
+ }
+ </script>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_select_key_navigation_bug1498769.html b/layout/forms/test/test_select_key_navigation_bug1498769.html
new file mode 100644
index 0000000000..3574761e66
--- /dev/null
+++ b/layout/forms/test/test_select_key_navigation_bug1498769.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1498769
+-->
+<head>
+<meta charset="utf-8">
+<title>Test for Bug 1498769</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"/>
+<script type="application/javascript">
+ /** Test for Bug 1498769 **/
+
+ SimpleTest.waitForExplicitFinish();
+
+ function test() {
+ const kIsMac = navigator.platform.indexOf("Mac") == 0;
+ SimpleTest.waitForFocus(function() {
+ [...document.querySelectorAll('select')].forEach(function(e) {
+ e.focus();
+ const description = ` (size ${e.size})`;
+ is(e.selectedIndex, 1, "the 'selected' attribute is respected" + description);
+ if (kIsMac && e.size == "1") {
+ // On OSX, UP/DOWN opens the dropdown menu rather than changing
+ // the value so we skip the rest of this test there in this case.
+ return;
+ }
+ synthesizeKey("VK_DOWN", {});
+ is(e.selectedIndex, 2, "VK_DOWN selected the first option below" + description);
+ synthesizeKey("VK_UP", {});
+ is(e.selectedIndex, 0, "VK_UP skips the display:none/contents option" + description);
+ synthesizeKey("VK_DOWN", {});
+ is(e.selectedIndex, 2, "VK_DOWN skips the display:none/contents option" + description);
+ });
+ SimpleTest.finish();
+ });
+ }
+</script>
+</head>
+<body onload="test()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1498769">Mozilla Bug 1498769</a>
+<div>
+ <select size="4">
+ <option>0</option>
+ <option selected style="display:none">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="4">
+ <option>0</option>
+ <option selected style="display:contents">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="4">
+ <option>0</option>
+ <optgroup label="group" style="display:none">
+ <option selected>1</option>
+ </optgroup>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="4">
+ <option>0</option>
+ <optgroup label="group" style="display:contents">
+ <option selected>1</option>
+ </optgroup>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="4">
+ <option>0</option>
+ <optgroup label="group" style="display:contents">
+ <option selected style="display:none">1</option>
+ </optgroup>
+ <option>2</option>
+ <option>3</option>
+ </select>
+
+<!-- Same as above but with size="1" -->
+
+ <select size="1">
+ <option>0</option>
+ <option selected style="display:none">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="1">
+ <option>0</option>
+ <option selected style="display:contents">1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="1">
+ <option>0</option>
+ <optgroup label="group" style="display:none">
+ <option selected>1</option>
+ </optgroup>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="1">
+ <option>0</option>
+ <optgroup label="group" style="display:contents">
+ <option selected>1</option>
+ </optgroup>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ <select size="1">
+ <option>0</option>
+ <optgroup label="group" style="display:contents">
+ <option selected style="display:none">1</option>
+ </optgroup>
+ <option>2</option>
+ <option>3</option>
+ </select>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_select_key_navigation_bug961363.html b/layout/forms/test/test_select_key_navigation_bug961363.html
new file mode 100644
index 0000000000..7815149778
--- /dev/null
+++ b/layout/forms/test/test_select_key_navigation_bug961363.html
@@ -0,0 +1,131 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=961363
+-->
+<head>
+<meta charset="utf-8">
+<title>Test for Bug 961363</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"/>
+<script type="application/javascript">
+ /** Test for Bug 961363 **/
+
+ SimpleTest.waitForExplicitFinish();
+
+ function test() {
+ SimpleTest.waitForFocus(function() {
+ const single_list = [
+ {key: "DOWN", change: true, state: [false, false, true, false]},
+ {key: "UP", change: true, state: [false, true, false, false]},
+ {key: "RIGHT", change: true, state: [false, false, true, false]},
+ {key: "LEFT", change: true, state: [false, true, false, false]},
+ {key: "END", change: true, state: [false, false, false, true ]},
+ {key: "HOME", change: true, state: [true, false, false, false]},
+ {key: "PAGE_DOWN", change: false, state: [true, false, false, false]},
+ {key: "PAGE_UP", change: false, state: [true, false, false, false]}
+ ];
+
+ const single_dropdown = [
+ {key: "DOWN", change: true, state: [false, false, true, false]},
+ {key: "UP", change: true, state: [false, true, false, false]},
+ {key: "RIGHT", change: true, state: [false, false, true, false]},
+ {key: "LEFT", change: true, state: [false, true, false, false]},
+ {key: "END", change: true, state: [false, false, false, true ]},
+ {key: "HOME", change: true, state: [true, false, false, false]},
+ {key: "PAGE_DOWN", change: false, state: [true, false, false, false]},
+ {key: "PAGE_UP", change: false, state: [true, false, false, false]}
+ ];
+
+ const multiple = [
+ {key: "DOWN", change: false, state: [false, true, true, false]},
+ {key: "UP", change: false, state: [false, false, true, false]},
+ {key: "RIGHT", change: false, state: [false, false, false, false]},
+ {key: "LEFT", change: false, state: [false, true, false, false]},
+ {key: "PAGE_DOWN", change: false, state: [false, true, false, true ]},
+ {key: "PAGE_UP", change: false, state: [false, false, false, true ]},
+ {key: "END", change: false, state: [false, false, false, false]},
+ {key: "HOME", change: false, state: [true, false, false, false]}
+ ];
+
+ function select_test(id, tests) {
+ let element = document.getElementById(id);
+ element.focus();
+ tests.forEach(data => {
+ let previousValue = element.value;
+ let key = data.k;
+ synthesizeKey("VK_" + data.key, {shiftKey: false, metaKey: false,
+ ctrlKey: true });
+ (data.change ? isnot : is)(
+ element.value, previousValue,
+ `value should ${data.change ? "": "not "} have changed while testing CTRL+${data.key} (id: ${id})`
+ );
+
+ // Hit ctrl+space, but only for <select multiple> elements; doing so
+ // for single <select> elements will just trigger the dropdown to
+ // open. This is especially important because e10s-backed dropdowns
+ // behave differently: their .value isn't updated until the dropdown
+ // is closed (and the change confirmed), e.g. by pressing Enter.
+ let action;
+ if (element.multiple) {
+ synthesizeKey(" ", {shiftKey: false, metaKey: false,
+ ctrlKey: true});
+ action = `CTRL+SPACE (after testing CTRL+${data.key})`;
+ } else {
+ action = `testing CTRL+${data.key}`;
+ }
+
+ let selected = [...element.options].map(o => o.selected);
+ is(selected.toString(), data.state.toString(),
+ `selected options match after ${action} (id: ${id})`);
+ });
+ }
+
+ select_test("single-list", single_list);
+ if (!navigator.platform.includes("Mac")) {
+ select_test("single-dropdown", single_dropdown);
+ } else {
+ todo(false, "Make these tests work on OSX");
+ }
+
+ select_test("multiple", multiple);
+ SimpleTest.finish();
+ });
+ }
+</script>
+</head>
+<body onload="test();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=961363">Mozilla Bug 961363</a>
+<div>
+ <ul>
+ <li>
+ <select id="single-list" size="3">
+ <option>0</option>
+ <option selected>1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ </li>
+ <li>
+ <select id="single-dropdown" size="1">
+ <option>0</option>
+ <option selected>1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ </li>
+ <li>
+ <select id="multiple" multiple size="3">
+ <option>0</option>
+ <option selected>1</option>
+ <option>2</option>
+ <option>3</option>
+ </select>
+ </li>
+ </ul>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_select_prevent_default.html b/layout/forms/test/test_select_prevent_default.html
new file mode 100644
index 0000000000..4ad9db0580
--- /dev/null
+++ b/layout/forms/test/test_select_prevent_default.html
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=291082
+-->
+<head>
+<meta charset="utf-8">
+<title>Test for Bug 291082</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"/>
+<script type="application/javascript">
+ /** Test for Bug 291082 **/
+
+
+ SimpleTest.waitForExplicitFinish();
+
+ function preventDefault(event) {
+ event.preventDefault();
+ }
+
+ function runTest() {
+ document.getElementById("keydown").addEventListener("keydown", preventDefault);
+ document.getElementById("keypress").addEventListener("keypress", preventDefault);
+
+ SimpleTest.waitForFocus(function() {
+ if (navigator.platform.indexOf("Mac") == 0) {
+ todo(false, "Make this test work on OSX");
+ SimpleTest.finish();
+ return;
+ }
+ var testData = [ "one", "two", "three", "four", "keydown", "keypress" ];
+
+ // The order of the keys in otherKeys is important for the test to function properly.
+ var otherKeys = [ "DOWN", "UP", "RIGHT", "LEFT", "PAGE_DOWN", "PAGE_UP",
+ "END", "HOME" ];
+
+ testData.forEach(function(id) {
+ var element = document.getElementById(id);
+ element.focus();
+ var previousValue = element.value;
+ sendChar('2');
+ is(element.value, previousValue, "value should not have changed (id: " + id + ")");
+ previousValue = element.value;
+ otherKeys.forEach(function(key) {
+ sendKey(key);
+ // All these preventDefault on key down in various ways.
+ let shouldchange = id != "keydown" && id != "one" && id != "three";
+ (shouldchange ? isnot : is)(element.value, previousValue, "value should " + (shouldchange ? "" : "not ") + "have changed while testing key " + key + " (id: " + id + ")");
+ previousValue = element.value;
+ });
+ });
+ SimpleTest.finish();
+ });
+ }
+</script>
+</head>
+<body onload="runTest();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=291082">Mozilla Bug 291082</a>
+<div>
+ <ul>
+ <li>
+ <select id="one" onkeydown="event.preventDefault();">
+ <option>0</option>
+ <option>1</option>
+ <option>2</option>
+ </select>
+ select onkeydown="event.preventDefault();"
+ </li>
+ <li>
+ <select id="two" onkeypress="event.preventDefault();">
+ <option>0</option>
+ <option>1</option>
+ <option>2</option>
+ </select>
+ select onkeypress="event.preventDefault();"
+ </li>
+ <li onkeydown="event.preventDefault();">
+ <select id="three">
+ <option>0</option>
+ <option>1</option>
+ <option>2</option>
+ </select>
+ li onkeydown="event.preventDefault();"
+ </li>
+ <li onkeypress="event.preventDefault();">
+ <select id="four">
+ <option>0</option>
+ <option>1</option>
+ <option>2</option>
+ </select>
+ li onkeypress="event.preventDefault();"
+ </li>
+ <li>
+ <select id="keydown">
+ <option>0</option>
+ <option>1</option>
+ <option>2</option>
+ </select>
+ select.addEventListener("keydown", function(event) { event.preventDefault(); });
+ </li>
+ <li>
+ <select id="keypress">
+ <option>0</option>
+ <option>1</option>
+ <option>2</option>
+ <option>9</option>
+ </select>
+ select.addEventListener("keypress", function(event) { event.preventDefault(); });
+ </li>
+ </ul>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_select_reframe.html b/layout/forms/test/test_select_reframe.html
new file mode 100644
index 0000000000..666d8074b8
--- /dev/null
+++ b/layout/forms/test/test_select_reframe.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Test for page up/down in collapsed select (bug 1488828)</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<style>
+.reframe {
+ display: flex;
+}
+</style>
+<div id="container">
+ <select>
+ <option>ABC</option>
+ <option>DEF</option>
+ </select>
+</div>
+<script>
+(async function() {
+ SimpleTest.waitForExplicitFinish();
+
+ const utils = SpecialPowers.DOMWindowUtils;
+ const select = document.querySelector("select");
+ await SimpleTest.promiseFocus(window);
+
+ ok(!select.openInParentProcess, "Should not be open")
+
+ select.focus();
+ synthesizeKey("VK_SPACE");
+
+ ok(SpecialPowers.wrap(select).openInParentProcess, "Should open");
+
+ const container = document.getElementById("container");
+ container.getBoundingClientRect(); // flush layout
+
+ const frameCountBeforeReframe = utils.framesConstructed;
+
+ container.classList.add("reframe");
+
+ container.getBoundingClientRect(); // flush layout
+
+ ok(utils.framesConstructed > frameCountBeforeReframe, "Should have reframed");
+ ok(SpecialPowers.wrap(select).openInParentProcess, "Should remain open");
+
+ select.remove();
+
+ container.getBoundingClientRect(); // flush layout
+ ok(!SpecialPowers.wrap(select).openInParentProcess, "Should close after removal");
+
+ SimpleTest.finish();
+}());
+</script>
diff --git a/layout/forms/test/test_select_vertical.html b/layout/forms/test/test_select_vertical.html
new file mode 100644
index 0000000000..51c6208bd3
--- /dev/null
+++ b/layout/forms/test/test_select_vertical.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for select popup in vertical writing mode</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script>
+SimpleTest.waitForExplicitFinish();
+
+function test() {
+ SimpleTest.waitForFocus(function() {
+ var vlr = document.getElementById("vlr");
+ var selWidth = vlr.offsetWidth;
+ var optWidth = vlr.children[0].offsetWidth;
+
+ // We should be able to choose options from the vertical-lr <select>
+ // at positions increasingly to the right of the element itself.
+ is(vlr.value, "1", "(vertical-lr) initial value should be 1");
+
+ synthesizeMouse(vlr, 5, 5, { type : "mousedown", button: 0 });
+ synthesizeMouse(vlr, selWidth + 1.5 * optWidth, 5, { type : "mouseup", button: 0 });
+
+ is(vlr.value, "2", "(vertical-lr) new value should be 2");
+
+ synthesizeMouse(vlr, 5, 5, { type : "mousedown", button: 0 });
+ synthesizeMouse(vlr, selWidth + 2.5 * optWidth, 5, { type : "mouseup", button: 0 });
+
+ is(vlr.value, "3", "(vertical-lr) new value should be 3");
+
+ synthesizeMouse(vlr, 5, 5, { type : "mousedown", button: 0 });
+ synthesizeMouse(vlr, selWidth + 0.5 * optWidth, 5, { type : "mouseup", button: 0 });
+
+ is(vlr.value, "1", "(vertical-lr) value should be back to 1");
+
+ var vrl = document.getElementById("vrl");
+
+ // We should be able to choose options from the vertical-rl <select>
+ // at positions increasingly to the left of the element itself.
+ is(vrl.value, "1", "(vertical-rl) initial value should be 1");
+
+ synthesizeMouse(vrl, 5, 5, { type : "mousedown", button: 0 });
+ synthesizeMouse(vrl, -1.5 * optWidth, 5, { type : "mouseup", button: 0 });
+
+ is(vrl.value, "2", "(vertical-rl) new value should be 2");
+
+ synthesizeMouse(vrl, 5, 5, { type : "mousedown", button: 0 });
+ synthesizeMouse(vrl, -2.5 * optWidth, 5, { type : "mouseup", button: 0 });
+
+ is(vrl.value, "3", "(vertical-rl) new value should be 3");
+
+ synthesizeMouse(vrl, 5, 5, { type : "mousedown", button: 0 });
+ synthesizeMouse(vrl, -0.5 * optWidth, 5, { type : "mouseup", button: 0 });
+
+ is(vrl.value, "1", "(vertical-rl) value should be back to 1");
+
+ SimpleTest.finish();
+ });
+}
+</script>
+
+<body onload="test();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1113206">Mozilla Bug 1113206</a>
+<div>
+ <select id="vlr" style="writing-mode: vertical-lr; margin: 80px;">
+ <option value="1">one
+ <option value="2">two
+ <option value="3">three
+ <option value="4">four
+ </select>
+ <select id="vrl" style="writing-mode: vertical-rl; margin: 80px;">
+ <option value="1">one
+ <option value="2">two
+ <option value="3">three
+ <option value="4">four
+ </select>
+</div>
diff --git a/layout/forms/test/test_textarea_resize.html b/layout/forms/test/test_textarea_resize.html
new file mode 100644
index 0000000000..93889a0d17
--- /dev/null
+++ b/layout/forms/test/test_textarea_resize.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Bug 477700</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>
+<div id="content" style="display: none">
+</div>
+
+<textarea id="textarea" style="-moz-appearance: none; border: 2px solid black; padding: 3px; box-sizing: border-box; min-width: 15px; min-height: 15px;">Text</textarea>
+
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for textbox resizing **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(() => SimpleTest.executeSoon(doTheTest));
+
+// -1 means use the default value which is 'both', then test explicitly
+// setting each possible value.
+var currentResize = -1;
+var currentBoxSizing = 0;
+var currentPointer = 0;
+var resizeTypes = [ "horizontal", "vertical", "none", "inherit", "both" ];
+var boxSizingTypes = [ "", "border-box" ];
+var pointerTypes = [ synthesizeMouse, synthesizeTouch]
+
+function doTheTest() {
+ runTest(pointerTypes[currentPointer]);
+}
+
+function runTest(aPointerFunc) {
+ var boxSizingText = " with box sizing " + (currentBoxSizing ? boxSizingTypes[currentBoxSizing] : "content-box");
+
+ var textarea = $("textarea");
+ var rect = textarea.getBoundingClientRect();
+ var touch = aPointerFunc.name.match(/Touch/);
+ // -1 means use the default value of resize, i.e. "both"
+ var type = (currentResize == -1) ? "both" : resizeTypes[currentResize];
+ // assume that the resizer is in the lower right corner
+
+ aPointerFunc(textarea, rect.width - 10, rect.height - 10, { type: touch ? "touchstart" : "mousedown" });
+ aPointerFunc(textarea, rect.width + 40, rect.height + 40, { type: touch ? "touchmove" : "mousemove" });
+
+ var newrect = textarea.getBoundingClientRect();
+ var hchange = (type == "both" || type == "horizontal");
+ var vchange = (type == "both" || type == "vertical");
+
+ is(Math.round(newrect.width), Math.round(rect.width + (hchange ? 50 : 0)),
+ type + " width has increased" + boxSizingText + " using " + aPointerFunc.name);
+ is(Math.round(newrect.height), Math.round(rect.height + (vchange ? 50 : 0)),
+ type + " height has increased" + boxSizingText + " using " + aPointerFunc.name);
+
+ aPointerFunc(textarea, rect.width - 20, rect.height - 20, { type: touch ? "touchmove" : "mousemove" });
+
+ newrect = textarea.getBoundingClientRect();
+
+ is(Math.round(newrect.width), Math.round(rect.width - (hchange ? 10 : 0)),
+ type + " width has decreased" + boxSizingText + " using " + aPointerFunc.name);
+ is(Math.round(newrect.height), Math.round(rect.height - (vchange ? 10 : 0)),
+ type + " height has decreased" + boxSizingText + " using " + aPointerFunc.name);
+
+ aPointerFunc(textarea, rect.width - 220, rect.height - 220, { type: touch ? "touchmove" : "mousemove" });
+
+ newrect = textarea.getBoundingClientRect();
+ ok(hchange ? newrect.width >= 15 : Math.round(newrect.width) == Math.round(rect.width),
+ type + " width decreased below minimum" + boxSizingText + " using " + newrect.width);
+ ok(vchange ? newrect.height >= 15 : Math.round(newrect.height) == Math.round(rect.height),
+ type + " height decreased below minimum" + boxSizingText + " using " + aPointerFunc.name);
+
+ aPointerFunc(textarea, rect.width - 8, rect.height - 8, { type: touch ? "touchend" : "mouseup" });
+
+ textarea.style.width = "auto";
+ textarea.style.height = "auto";
+
+ if (currentBoxSizing++ <= boxSizingTypes.length) {
+ textarea.style.MozBoxSizing = boxSizingTypes[currentBoxSizing];
+ SimpleTest.executeSoon(doTheTest);
+ } else {
+ currentBoxSizing = 0;
+ if (++currentResize < resizeTypes.length) {
+ textarea.style.resize = resizeTypes[currentResize];
+ SimpleTest.executeSoon(doTheTest);
+ } else {
+ currentResize = -1;
+ textarea.style.resize = "";
+ if (++currentPointer < pointerTypes.length) {
+ SimpleTest.executeSoon(doTheTest);
+ } else {
+ SimpleTest.finish();
+ }
+ }
+ }
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/layout/forms/test/test_unstyled_control_height.html b/layout/forms/test/test_unstyled_control_height.html
new file mode 100644
index 0000000000..ad5cd125d2
--- /dev/null
+++ b/layout/forms/test/test_unstyled_control_height.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<style>
+ #container *, #container2 * {
+ white-space: nowrap;
+ appearance: none;
+ }
+ input {
+ /* Reduce the width so that container can fit all its children in 600px viewport width. */
+ width: 100px;
+ }
+ /* date by default uses a monospace font, which might have different metrics */
+ input, button, select {
+ font: Menu;
+ }
+ .small-font * {
+ font-size: 8px !important; /* important to override rule above */
+ }
+ .no-padding * {
+ padding: 0;
+ }
+</style>
+
+<!-- Each container should fit all its children in the same line to verify every
+ child has the same |top|. -->
+<div id="container">
+ <input>
+ <!-- Putting the <input> containing Burmese characters here is just to verify
+ our current behavior. They are slightly clipped. So if we fix it by
+ making the <input> taller, it's OK to remove it from this test. -->
+ <input value="漢字 jpg မြန်မာစာ">
+ <input type=date>
+ <button>Foo</button>
+ <select><option>Foo</option></select>
+</div>
+
+<br>
+<div id="container2">
+ <button>漢字 Foo မြန်မာစာ</button>
+ <select><option>漢字 Foo မြန်မာစာ</option></select>
+</div>
+
+<script>
+function testHeightMatches(id, desc) {
+ let commonHeight = null;
+ let commonTop = null;
+ for (let element of document.querySelectorAll(`#${id} > *`)) {
+ let rect = element.getBoundingClientRect();
+ if (commonHeight === null) {
+ commonHeight = rect.height;
+ commonTop = rect.top;
+ }
+ is(rect.height, commonHeight, `Height of the controls should match for ${element.outerHTML}${desc}`);
+ is(rect.top, commonTop, `Top of the controls should match for ${element.outerHTML}${desc}`);
+ }
+}
+
+for (id of ["container", "container2"]) {
+ const container = document.getElementById(id);
+
+ testHeightMatches(id, "");
+
+ container.className = "no-padding";
+
+ testHeightMatches(id, " without padding");
+
+ container.className = "small-font";
+
+ testHeightMatches(id, " with an small font");
+}
+</script>