summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/selection/textcontrols
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/selection/textcontrols')
-rw-r--r--testing/web-platform/tests/selection/textcontrols/focus.html43
-rw-r--r--testing/web-platform/tests/selection/textcontrols/onselectionchange-content-attribute.html29
-rw-r--r--testing/web-platform/tests/selection/textcontrols/selectionchange-bubble.html33
-rw-r--r--testing/web-platform/tests/selection/textcontrols/selectionchange.html212
4 files changed, 317 insertions, 0 deletions
diff --git a/testing/web-platform/tests/selection/textcontrols/focus.html b/testing/web-platform/tests/selection/textcontrols/focus.html
new file mode 100644
index 0000000000..8c2e0b5591
--- /dev/null
+++ b/testing/web-platform/tests/selection/textcontrols/focus.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Stop selection extension when focus changes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+#p {
+ font: 16px/1 Ahem;
+}
+</style>
+<p id="p">
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+ occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+</p>
+<textarea id="textarea">Hello</textarea>
+<script>
+ const selection = getSelection();
+ const { p, textarea } = document.all;
+ document.addEventListener("selectionchange", ev => {
+ if (p.contains(selection.focusNode)) {
+ textarea.focus();
+ }
+ });
+
+ promise_test(async () => {
+ await new test_driver.Actions()
+ .pointerMove(5, 5, {origin: p})
+ .pointerDown()
+ .pointerMove(50, 50)
+ .pointerUp()
+ .send();
+ assert_equals(selection.focusNode, document.body);
+ assert_equals(selection.focusOffset, 2);
+ assert_equals(selection.anchorNode, document.body);
+ assert_equals(selection.focusOffset, 2);
+ }, "focus() should cancel selection extension by pointer device");
+</script>
diff --git a/testing/web-platform/tests/selection/textcontrols/onselectionchange-content-attribute.html b/testing/web-platform/tests/selection/textcontrols/onselectionchange-content-attribute.html
new file mode 100644
index 0000000000..3120b3bff5
--- /dev/null
+++ b/testing/web-platform/tests/selection/textcontrols/onselectionchange-content-attribute.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test that setting "onselectionchange" content attribute adds an event listener</title>
+<link rel="help" href="https://w3c.github.io/selection-api/#extensions-to-globaleventhandlers-interface">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<div id="testElement" onselectionchange="window.handlerSetFromParserWasFired()"></div>
+<script>
+ promise_test(() => {
+ return new Promise(resolve => {
+ window.handlerSetFromParserWasFired = resolve;
+ testElement.dispatchEvent(new Event("selectionchange"));
+ });
+ }, "handler set from parser");
+
+ promise_test(() => {
+ const el = document.createElement("div");
+ el.setAttribute("onselectionchange", "window.handlerSetViaSetAttributeWasFired()");
+ document.body.append(el);
+
+ return new Promise(resolve => {
+ window.handlerSetViaSetAttributeWasFired = resolve;
+ el.dispatchEvent(new Event("selectionchange"));
+ });
+ }, "handler set via setAttribute()");
+</script>
diff --git a/testing/web-platform/tests/selection/textcontrols/selectionchange-bubble.html b/testing/web-platform/tests/selection/textcontrols/selectionchange-bubble.html
new file mode 100644
index 0000000000..834b32bdd3
--- /dev/null
+++ b/testing/web-platform/tests/selection/textcontrols/selectionchange-bubble.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test selectionchange events bubbling from text controls</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<input id="input" width="200" value="foo"><br>
+<textarea id="textarea" width="200">foo</textarea>
+
+<script>
+ function untilEvent(element, eventName) {
+ return new Promise(resolve => {
+ element.addEventListener(eventName, resolve, { once: true });
+ });
+ }
+
+ for (const element of [input, textarea]) {
+ const name = element.localName;
+ for (const focus of [false, true]) {
+ let focused = focus ? " when focused" : "";
+ let offset = focus ? 2 : 1;
+ promise_test(async () => {
+ if (focus) {
+ element.focus();
+ }
+
+ element.setSelectionRange(offset, offset);
+ const ev = await untilEvent(element, "selectionchange");
+ assert_equals(ev.bubbles, true);
+ }, `selectionchange bubbles from ${name}${focused}`);
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/selection/textcontrols/selectionchange.html b/testing/web-platform/tests/selection/textcontrols/selectionchange.html
new file mode 100644
index 0000000000..2b43cfe44b
--- /dev/null
+++ b/testing/web-platform/tests/selection/textcontrols/selectionchange.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test selectionchange events from text controls</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ input,
+ textarea {
+ font: 16px/1 Ahem;
+ }
+</style>
+
+<input id="input" width="200"><br>
+<textarea id="textarea" width="200"></textarea>
+
+<script>
+ class SelectionChangeCollector {
+ /**
+ * @param {HTMLElement} target
+ */
+ constructor(target) {
+ this.target = target;
+ this.events = [];
+ target.addEventListener("selectionchange", ev => {
+ this.events.push(ev);
+ });
+ }
+ clear() {
+ this.events.length = 0;
+ }
+ }
+
+ const data = {
+ collectors: [
+ new SelectionChangeCollector(input),
+ new SelectionChangeCollector(input.cloneNode()),
+ new SelectionChangeCollector(textarea),
+ new SelectionChangeCollector(textarea.cloneNode(true)),
+ ],
+ async initialize() {
+ for (const collector of this.collectors) {
+ collector.target.value = "XXXXXXXXXXXXXXXXXXX";
+ collector.target.blur();
+ collector.target.setSelectionRange(0, 0);
+ }
+ await this.spin();
+ for (const collector of this.collectors) {
+ collector.clear();
+ }
+ },
+ spin() {
+ return new Promise(setTimeout);
+ },
+ async assert_empty_spin() {
+ // firing selectionchange must be asynchronous
+ for (const collector of this.collectors) {
+ assert_equals(collector.events.length, 0);
+ }
+ await this.spin();
+ }
+ };
+
+ for (const collector of data.collectors) {
+ const target = collector.target;
+ const name = `the ${!target.parentNode ? "disconnected " : ""}${target.localName} element`;
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.selectionStart = 1;
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Modifying selectionStart value of ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.selectionEnd = 1;
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Modifying selectionEnd value of ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.setSelectionRange(0, 4);
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Calling setSelectionRange() on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.select();
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Calling select() on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.setRangeText("newmiddle", 2, 3, "select");
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Calling setRangeText() on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.selectionStart = 0;
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 0);
+ }, `Setting initial zero selectionStart value on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.selectionStart = 2;
+ target.selectionStart = 2;
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Setting the same selectionStart value twice on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.selectionEnd = 0;
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 0);
+ }, `Setting initial zero selectionEnd value on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.selectionEnd = 2;
+ target.selectionEnd = 2;
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Setting the same selectionEnd value twice on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.setSelectionRange(0, 0);
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 0);
+ }, `Setting initial zero selection range on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.setSelectionRange(3, 3);
+ target.setSelectionRange(3, 3);
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Setting the same selection range twice on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.select();
+ target.select();
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 1);
+ }, `Calling select() twice on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.select();
+ target.setRangeText("foo", 2, 6);
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 2);
+ }, `Calling setRangeText() after select() on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.select();
+ target.setRangeText("", 10, 12);
+ target.setRangeText("", 10, 12);
+ target.setRangeText("", 10, 12);
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 4);
+ }, `Calling setRangeText() repeatedly on ${name}`);
+
+ promise_test(async () => {
+ await data.initialize();
+
+ target.value = "";
+ target.setRangeText("foo");
+
+ await data.assert_empty_spin();
+ assert_equals(collector.events.length, 0);
+ }, `Calling setRangeText() on empty ${name}`);
+ }
+</script>