summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/selection/caret
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 /testing/web-platform/tests/selection/caret
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 'testing/web-platform/tests/selection/caret')
-rw-r--r--testing/web-platform/tests/selection/caret/collapse-pre-linestart-1.html13
-rw-r--r--testing/web-platform/tests/selection/caret/collapse-pre-linestart-2.html14
-rw-r--r--testing/web-platform/tests/selection/caret/collapse-pre-linestart-ref.html8
-rw-r--r--testing/web-platform/tests/selection/caret/empty-elements.html25
-rw-r--r--testing/web-platform/tests/selection/caret/move-around-contenteditable-false.html189
5 files changed, 249 insertions, 0 deletions
diff --git a/testing/web-platform/tests/selection/caret/collapse-pre-linestart-1.html b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-1.html
new file mode 100644
index 0000000000..e8bd262868
--- /dev/null
+++ b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-1.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>selection.collapse() to line start</title>
+<link rel="author" title="Kagami Sascha Rosylight" href="mailto:krosylight@mozilla.com">
+<link rel="help" href="https://w3c.github.io/selection-api/#dom-selection-collapse">
+<link rel="match" href="collapse-pre-linestart-ref.html">
+<meta name="assert" content="The caret must appear at the start of the second line.">
+<pre id=target contenteditable>ABC
+<br></pre>
+<script>
+ target.focus();
+ getSelection().collapse(target.childNodes[0], 4);
+</script>
diff --git a/testing/web-platform/tests/selection/caret/collapse-pre-linestart-2.html b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-2.html
new file mode 100644
index 0000000000..0feee464c9
--- /dev/null
+++ b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-2.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>selection.collapse() to line start</title>
+<link rel="author" title="Kagami Sascha Rosylight" href="mailto:krosylight@mozilla.com">
+<link rel="help" href="https://w3c.github.io/selection-api/#dom-selection-collapse">
+<link rel="match" href="collapse-pre-linestart-ref.html">
+<meta name="assert" content="The caret must appear at the start of the second line.">
+<pre id=target contenteditable>ABC
+
+</pre>
+<script>
+ target.focus();
+ getSelection().collapse(target.childNodes[0], 4);
+</script>
diff --git a/testing/web-platform/tests/selection/caret/collapse-pre-linestart-ref.html b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-ref.html
new file mode 100644
index 0000000000..2b25941ded
--- /dev/null
+++ b/testing/web-platform/tests/selection/caret/collapse-pre-linestart-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>selection.collapse() to line start</title>
+<pre id=target contenteditable>ABC<br><br></pre>
+<script>
+ target.focus();
+ getSelection().collapse(target, 3);
+</script>
diff --git a/testing/web-platform/tests/selection/caret/empty-elements.html b/testing/web-platform/tests/selection/caret/empty-elements.html
new file mode 100644
index 0000000000..328188c957
--- /dev/null
+++ b/testing/web-platform/tests/selection/caret/empty-elements.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Placing selection inside empty elements</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div contenteditable id="host">
+ <p><strong id="strong"></strong></p>
+</div>
+<script>
+test( () => {
+ const range = document.createRange();
+
+ range.setStart( strong, 0 );
+ range.collapse()
+ getSelection().removeAllRanges();
+ getSelection().addRange( range );
+
+ const selectedRange = getSelection().getRangeAt( 0 );
+
+ assert_equals( selectedRange.startContainer, strong );
+ assert_equals( selectedRange.startOffset, 0 );
+ assert_equals( selectedRange.endContainer, strong );
+ assert_equals( selectedRange.endOffset, 0 );
+}, 'Selection can be placed inside the empty element' );
+</script>
diff --git a/testing/web-platform/tests/selection/caret/move-around-contenteditable-false.html b/testing/web-platform/tests/selection/caret/move-around-contenteditable-false.html
new file mode 100644
index 0000000000..256804f17a
--- /dev/null
+++ b/testing/web-platform/tests/selection/caret/move-around-contenteditable-false.html
@@ -0,0 +1,189 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Don't move caret to non-editable node from a editable node</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script>
+"use strict";
+
+function getRangeDescription(range) {
+ function getNodeDescription(node) {
+ if (!node) {
+ return "null";
+ }
+ switch (node.nodeType) {
+ case Node.TEXT_NODE:
+ return `${node.nodeName} "${node.data}"`;
+ case Node.ELEMENT_NODE:
+ return `<${node.nodeName.toLowerCase()}>`;
+ default:
+ return `${node.nodeName}`;
+ }
+ }
+ if (range === null) {
+ return "null";
+ }
+ if (range === undefined) {
+ return "undefined";
+ }
+ return range.startContainer == range.endContainer &&
+ range.startOffset == range.endOffset
+ ? `(${getNodeDescription(range.startContainer)}, ${range.startOffset})`
+ : `(${getNodeDescription(range.startContainer)}, ${
+ range.startOffset
+ }) - (${getNodeDescription(range.endContainer)}, ${range.endOffset})`;
+}
+
+function sendArrowRightKey() {
+ const kArrowRight = "\uE014";
+ return new test_driver.Actions()
+ .keyDown(kArrowRight)
+ .keyUp(kArrowRight)
+ .send();
+}
+
+function sendArrowLeftKey() {
+ const kArrowLeft = "\uE012";
+ return new test_driver.Actions()
+ .keyDown(kArrowLeft)
+ .keyUp(kArrowLeft)
+ .send();
+}
+
+promise_test(async () => {
+ await new Promise(resolve => {
+ addEventListener("load", resolve, {once: true});
+ });
+}, "Initializing tests");
+
+promise_test(async t => {
+ const editingHost = document.querySelector("div[contenteditable]");
+ editingHost.focus();
+ const p = editingHost.querySelector("p");
+ getSelection().collapse(p.firstChild, "abc".length);
+ await sendArrowRightKey();
+ test(() => {
+ assert_equals(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: p.nextSibling,
+ startOffset: 0,
+ endContainer: p.nextSibling,
+ endOffset: 0,
+ }),
+ );
+ }, `${t.name}: first arrow-right should move caret before non-editable text`);
+ await sendArrowRightKey();
+ test(() => {
+ assert_equals(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: p.nextSibling,
+ startOffset: 1,
+ endContainer: p.nextSibling,
+ endOffset: 1,
+ }),
+ );
+ }, `${t.name}: second arrow-right should move caret after non-editable text`);
+}, "Move caret from end of editable text node to <br> following non-editable text in next paragraph");
+
+promise_test(async t => {
+ const editingHost = document.querySelector("div[contenteditable]");
+ editingHost.focus();
+ const p = editingHost.querySelector("p");
+ getSelection().collapse(p.nextSibling, 1);
+ await sendArrowLeftKey();
+ assert_false(
+ editingHost.querySelector("[contenteditable=false]").contains(getSelection().focusNode),
+ "focus node should not be the non-editable nodes"
+ );
+ assert_false(
+ editingHost.querySelector("[contenteditable=false]").contains(getSelection().anchorNode),
+ "anchor node should not be the non-editable nodes"
+ );
+ test(() => {
+ assert_equals(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: p.nextSibling,
+ startOffset: 0,
+ endContainer: p.nextSibling,
+ endOffset: 0,
+ }),
+ );
+ }, `${t.name}: first arrow-left should move caret before non-editable text`);
+}, "Move caret from <br> following non-editable text to end of preceding editable text in next paragraph");
+
+promise_test(async t => {
+ const editingHost = document.querySelector("div[contenteditable] + div[contenteditable]");
+ editingHost.focus();
+ const p = editingHost.querySelector("p");
+ getSelection().collapse(p.firstChild, 0);
+ await sendArrowRightKey();
+ test(() => {
+ assert_equals(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: p.nextSibling,
+ startOffset: 0,
+ endContainer: p.nextSibling,
+ endOffset: 0,
+ }),
+ );
+ }, `${t.name}: first arrow-right should move caret before non-editable text`);
+ await sendArrowRightKey();
+ test(() => {
+ assert_equals(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: editingHost.querySelector("[contenteditable=false]").nextSibling,
+ startOffset: 0,
+ endContainer: editingHost.querySelector("[contenteditable=false]").nextSibling,
+ endOffset: 0,
+ }),
+ );
+ }, `${t.name}: second arrow-right should move caret after non-editable text`);
+}, "Move caret from empty editable paragraph to editable text following non-editable text in next paragraph");
+
+promise_test(async t => {
+ const editingHost = document.querySelector("div[contenteditable] + div[contenteditable]");
+ editingHost.focus();
+ const p = editingHost.querySelector("p");
+ getSelection().collapse(editingHost.querySelector("[contenteditable=false]").nextSibling, 0);
+ await sendArrowLeftKey();
+ assert_false(
+ editingHost.querySelector("[contenteditable=false]").contains(getSelection().focusNode),
+ "focus node should not be the non-editable nodes"
+ );
+ assert_false(
+ editingHost.querySelector("[contenteditable=false]").contains(getSelection().anchorNode),
+ "anchor node should not be the non-editable nodes"
+ );
+ test(() => {
+ assert_equals(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: p.nextSibling,
+ startOffset: 0,
+ endContainer: p.nextSibling,
+ endOffset: 0,
+ }),
+ );
+ }, `${t.name}: first arrow-left should move caret before non-editable text`);
+}, "Move caret from start of text following non-editable text to empty preceding editable paragraph");
+</script>
+</head>
+<body>
+<div contenteditable>
+<p>abc</p><p><span contenteditable="false">def</span><br></p>
+</div>
+<div contenteditable>
+<p><br></p><p><span contenteditable="false">abc</span>def</p>
+</div>
+</body>
+</html>