60 lines
2.7 KiB
HTML
60 lines
2.7 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8">
|
|
<title>Selection.modify() inside contenteditable</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<div contenteditable id="host">Editable</div>
|
|
<div>Non-editable</div>
|
|
<div id="inlinehosts">
|
|
Prefix: <span contenteditable title="inline">Editable</span>: Suffix<br>
|
|
Prefix: <span contenteditable style="display:inline-block;" title="inline-block">Editable</span>: Suffix<br>
|
|
<span contenteditable title="suffix only">Editable</span>: Suffix<br>
|
|
Prefix: <span contenteditable title="prefix only">Editable</span><br>
|
|
<span contenteditable title="standalone">Editable</span><br>
|
|
Prefix: <span contenteditable title="inline linebreak">Edit<br>able</span>: Suffix<br>
|
|
Prefix: <span contenteditable style="display:inline-block;" title="inline-block linebreak">Edit<br>able</span>:
|
|
Suffix<br>
|
|
</div>
|
|
<script>
|
|
/** @param {Node} parent */
|
|
function* textNodeEntries(parent) {
|
|
for (const [i, node] of parent.childNodes.entries()) {
|
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
yield [i, node];
|
|
}
|
|
}
|
|
}
|
|
|
|
const selection = getSelection();
|
|
test(() => {
|
|
selection.collapse(host);
|
|
selection.modify('extend', 'forward', 'word');
|
|
selection.modify('extend', 'forward', 'word');
|
|
assert_equals(selection.focusNode.parentElement, host);
|
|
}, "Selection.modify() must not select outside of the host");
|
|
|
|
/** @type {NodeListOf<HTMLElement>} */
|
|
const hosts = inlinehosts.querySelectorAll("span[contenteditable]");
|
|
for (const host of hosts) {
|
|
test(() => {
|
|
for (const [i, text] of textNodeEntries(host)) {
|
|
selection.collapse(text, 1);
|
|
selection.modify("move", "forward", "lineboundary");
|
|
if (selection.focusNode === host) {
|
|
assert_equals(selection.focusOffset, i + 1, "focusOffset should be after the text node");
|
|
} else {
|
|
assert_equals(selection.focusNode, text, "focusNode should be the text node");
|
|
assert_equals(selection.focusOffset, text.textContent.length, "focusOffset should be the length of the text node");
|
|
}
|
|
}
|
|
}, `Selection.modify('move', 'forward', 'lineboundary') must be within the inline editing host: ${host.title}`);
|
|
test(() => {
|
|
for (const [i, text] of textNodeEntries(host)) {
|
|
selection.collapse(text, 1);
|
|
selection.modify("move", "backward", "lineboundary");
|
|
assert_equals(selection.focusNode, text, "focusNode should be the text node");
|
|
assert_equals(selection.focusOffset, 0, "focusOffset should be 0");
|
|
}
|
|
}, `Selection.modify('move', 'backward', 'lineboundary') must be within the inline editing host: ${host.title}`);
|
|
}
|
|
</script>
|