modify.tentative.html (2742B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>Selection.modify() inside contenteditable</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <div contenteditable id="host">Editable</div> 7 <div>Non-editable</div> 8 <div id="inlinehosts"> 9 Prefix: <span contenteditable title="inline">Editable</span>: Suffix<br> 10 Prefix: <span contenteditable style="display:inline-block;" title="inline-block">Editable</span>: Suffix<br> 11 <span contenteditable title="suffix only">Editable</span>: Suffix<br> 12 Prefix: <span contenteditable title="prefix only">Editable</span><br> 13 <span contenteditable title="standalone">Editable</span><br> 14 Prefix: <span contenteditable title="inline linebreak">Edit<br>able</span>: Suffix<br> 15 Prefix: <span contenteditable style="display:inline-block;" title="inline-block linebreak">Edit<br>able</span>: 16 Suffix<br> 17 </div> 18 <script> 19 /** @param {Node} parent */ 20 function* textNodeEntries(parent) { 21 for (const [i, node] of parent.childNodes.entries()) { 22 if (node.nodeType === Node.TEXT_NODE) { 23 yield [i, node]; 24 } 25 } 26 } 27 28 const selection = getSelection(); 29 test(() => { 30 selection.collapse(host); 31 selection.modify('extend', 'forward', 'word'); 32 selection.modify('extend', 'forward', 'word'); 33 assert_equals(selection.focusNode.parentElement, host); 34 }, "Selection.modify() must not select outside of the host"); 35 36 /** @type {NodeListOf<HTMLElement>} */ 37 const hosts = inlinehosts.querySelectorAll("span[contenteditable]"); 38 for (const host of hosts) { 39 test(() => { 40 for (const [i, text] of textNodeEntries(host)) { 41 selection.collapse(text, 1); 42 selection.modify("move", "forward", "lineboundary"); 43 if (selection.focusNode === host) { 44 assert_equals(selection.focusOffset, i + 1, "focusOffset should be after the text node"); 45 } else { 46 assert_equals(selection.focusNode, text, "focusNode should be the text node"); 47 assert_equals(selection.focusOffset, text.textContent.length, "focusOffset should be the length of the text node"); 48 } 49 } 50 }, `Selection.modify('move', 'forward', 'lineboundary') must be within the inline editing host: ${host.title}`); 51 test(() => { 52 for (const [i, text] of textNodeEntries(host)) { 53 selection.collapse(text, 1); 54 selection.modify("move", "backward", "lineboundary"); 55 assert_equals(selection.focusNode, text, "focusNode should be the text node"); 56 assert_equals(selection.focusOffset, 0, "focusOffset should be 0"); 57 } 58 }, `Selection.modify('move', 'backward', 'lineboundary') must be within the inline editing host: ${host.title}`); 59 } 60 </script>