Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 8 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /selection/contenteditable/modify-around-non-editable-span.html - WPT Dashboard Interop Dashboard
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Selection.modify() shouldn't move caret into non-editable nodes</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../editing/include/editor-test-utils.js"></script>
<script>
"use strict";
addEventListener("load", () => {
const editingHost = document.querySelector("div[contenteditable]");
editingHost.focus();
const precedingWhiteSpaces = editingHost.firstChild;
const middleText = editingHost.querySelector("span").nextSibling;
const trailingWhiteSpaces = editingHost.lastChild;
for (const callSelectAllChildren of [false, true]) {
for (const direction of ["forward", "right"]) {
test(() => {
if (callSelectAllChildren) {
getSelection().selectAllChildren(editingHost);
}
getSelection().collapse(precedingWhiteSpaces, precedingWhiteSpaces.length);
getSelection().modify("move", direction, "character");
assert_in_array(
EditorTestUtils.getRangeDescription(getSelection().getRangeAt(0)),
[
// start of editable region at middle of the line
EditorTestUtils.getRangeDescription(
{ startContainer: editingHost, startOffset: 2, endContainer: editingHost, endOffset: 2 }),
EditorTestUtils.getRangeDescription(
{ startContainer: middleText, startOffset: 0, endContainer: middleText, endOffset: 0 }),
]
);
}, `getSelection().modify("move", "${direction}", "character") ${
callSelectAllChildren ? "after getSelection().selectAllChildren(editingHost) " : ""
}when " []<span contenteditable=false>"`);
test(() => {
if (callSelectAllChildren) {
getSelection().selectAllChildren(editingHost);
}
getSelection().collapse(middleText, middleText.length);
getSelection().modify("move", direction, "character");
assert_in_array(
EditorTestUtils.getRangeDescription(getSelection().getRangeAt(0)),
[
// At start of trailing invisible white spaces
EditorTestUtils.getRangeDescription(
{ startContainer: editingHost, startOffset: 4, endContainer: editingHost, endOffset: 4 }),
EditorTestUtils.getRangeDescription(
{ startContainer: trailingWhiteSpaces, startOffset: 0, endContainer: trailingWhiteSpaces, endOffset: 0 }),
// or at end of trailing invisible white spaces
EditorTestUtils.getRangeDescription(
{ startContainer: editingHost, startOffset: 5, endContainer: editingHost, endOffset: 5 }),
EditorTestUtils.getRangeDescription(
{ startContainer: trailingWhiteSpaces, startOffset: trailingWhiteSpaces.length, endContainer: trailingWhiteSpaces, endOffset: trailingWhiteSpaces.length }),
]
);
}, `getSelection().modify("move", "${direction}", "character") ${
callSelectAllChildren ? "after getSelection().selectAllChildren(editingHost) " : ""
}when "editable[]<span contenteditable=false>"`);
}
for (const direction of ["backward", "left"]) {
test(() => {
if (callSelectAllChildren) {
getSelection().selectAllChildren(editingHost);
}
getSelection().collapse(middleText, 0);
getSelection().modify("move", direction, "character");
assert_in_array(
EditorTestUtils.getRangeDescription(getSelection().getRangeAt(0)),
[
// At end of preceding invisible white spaces
EditorTestUtils.getRangeDescription(
{ startContainer: editingHost, startOffset: 1, endContainer: editingHost, endOffset: 1 }),
EditorTestUtils.getRangeDescription(
{ startContainer: precedingWhiteSpaces, startOffset: 1, endContainer: precedingWhiteSpaces, endOffset: 1 }),
// or start of preceding invisible whites spaces
EditorTestUtils.getRangeDescription(
{ startContainer: editingHost, startOffset: 0, endContainer: editingHost, endOffset: 0 }),
EditorTestUtils.getRangeDescription(
{ startContainer: precedingWhiteSpaces, startOffset: 0, endContainer: precedingWhiteSpaces, endOffset: 0 }),
]
);
}, `getSelection().modify("move", "${direction}", "character") ${
callSelectAllChildren ? "after getSelection().selectAllChildren(editingHost) " : ""
}when " <span contenteditable=false>...</span>[]editable"`);
test(() => {
if (callSelectAllChildren) {
getSelection().selectAllChildren(editingHost);
}
getSelection().collapse(trailingWhiteSpaces, 0);
getSelection().modify("move", direction, "character");
assert_in_array(
EditorTestUtils.getRangeDescription(getSelection().getRangeAt(0)),
[
// end of editable region at middle of the line
EditorTestUtils.getRangeDescription(
{ startContainer: editingHost, startOffset: 3, endContainer: editingHost, endOffset: 3 }),
EditorTestUtils.getRangeDescription(
{ startContainer: middleText, startOffset: middleText.length, endContainer: middleText, endOffset: middleText.length }),
]
);
}, `getSelection().modify("move", "${direction}", "character") ${
callSelectAllChildren ? "after getSelection().selectAllChildren(editingHost) " : ""
}when "editable<span contenteditable=false>...</span>[] "`);
}
}
}, {once: true});
</script>
</head>
<body>
<div contenteditable> <span contenteditable="false">non-editable</span>editable<span contenteditable="false">non-editable</span> </div>
</body>
</html>