diff options
Diffstat (limited to 'layout/generic/test/test_movement_by_words.html')
-rw-r--r-- | layout/generic/test/test_movement_by_words.html | 781 |
1 files changed, 781 insertions, 0 deletions
diff --git a/layout/generic/test/test_movement_by_words.html b/layout/generic/test/test_movement_by_words.html new file mode 100644 index 0000000000..a6639f39ca --- /dev/null +++ b/layout/generic/test/test_movement_by_words.html @@ -0,0 +1,781 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test Word Movement (including nsTextFrame::PeekOffsetWord)</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: block"> +<div contentEditable id="editor"></div> +</div> +<p id="catch">Catch-all +<pre id="test"><script class="testbody" type="text/javascript"> + +/** Tests for bugs 384147, 981281, 1066756, 1820290 **/ + +const kIsMac = navigator.platform.includes("Mac"); + +SimpleTest.waitForExplicitFinish(); + +SimpleTest.waitForFocus(async () => { + const editor = document.getElementById("editor"); + const waitForFocusEditor = new Promise(resolve => + editor.addEventListener("focus", resolve, {once: true}) + ); + editor.focus(); + // This seems to be necessary because the selection is not set up properly otherwise + await waitForFocusEditor; + + await test1(); + await test2(); + await test3(); + await test4(); + + SimpleTest.finish(); +}); + +var eatSpace; +var stopAtPunctuation; +var sel = window.getSelection(); +var editor = document.getElementById("editor"); + +function setPrefs(eat_space, stop_at_punctuation) { + eatSpace = eat_space; + stopAtPunctuation = stop_at_punctuation; + return SpecialPowers.pushPrefEnv({ + "set": [["layout.word_select.eat_space_to_next_word", eat_space], + ["layout.word_select.stop_at_punctuation", stop_at_punctuation], + ["intl.icu4x.segmenter.enabled", true]] + }); +} + +function currentStateDescription() { + return `eatSpace=${eatSpace}, stopAtPunctuation=${stopAtPunctuation}, testing="${editor.outerHTML}"`; +} + +function getNodeDescription(aNode) { + if (aNode === undefined) { + return "undefined"; + } + if (aNode === null) { + return "null"; + } + switch (aNode.nodeType) { + case Node.TEXT_NODE: + return `"${ + aNode.data.replace(/\n/g, "\\n") + }" in ${getNodeDescription(aNode.parentNode)}`; + case Node.ELEMENT_NODE: + return `<${aNode.tagName.toLowerCase()}${ + aNode.getAttribute("id") !== null + ? ` id="${aNode.getAttribute("id")}"` + : "" + }${ + aNode.getAttribute("dir") !== null + ? ` dir="${aNode.getAttribute("dir")}"` + : "" + }>`; + } + return aNode.nodeName; +} + +function testRight(node, offset, knownFailure) { + if (!kIsMac) { + synthesizeKey("KEY_ArrowRight", { ctrlKey: true }); + } else { + // macOS does not have default shortcut key to move caret per word. + SpecialPowers.doCommand(window, "cmd_wordNext"); + } + (knownFailure ? todo_is : is)( + `{${getNodeDescription(sel.anchorNode)} - ${sel.anchorOffset}}`, + `{${getNodeDescription(node)} - ${offset}}`, + `testRight(${currentStateDescription()})` + ); + if (knownFailure) { + getSelection().collapse(node, offset); + } +} + +function testLeft(node, offset, knownFailure) { + if (!kIsMac) { + synthesizeKey("KEY_ArrowLeft", { ctrlKey: true }); + } else { + // macOS does not have default shortcut key to move caret per word. + SpecialPowers.doCommand(window, "cmd_wordPrevious"); + } + (knownFailure ? todo_is : is)( + `{${getNodeDescription(sel.anchorNode)} - ${sel.anchorOffset}}`, + `{${getNodeDescription(node)} - ${offset}}`, + `testLeft(${currentStateDescription()})` + ); + if (knownFailure) { + getSelection().collapse(node, offset); + } +} + +const afterEditorNode = document.getElementById("catch").firstChild; + +const ChineseChars = "漢字"; +const HiraganaChars = "ひらがな"; +const KatakanaChars = "カタカナ"; +const JapaneseFullStop = "。"; +const JapaneseComma = "、"; +const ModifierColon = "꞉"; +const Symbol = "⛅"; // "sun behind cloud" (weather symbol) +const Emoji = "🐀"; // rat emoji +const DeseretChars = "𐑀𐑁"; +const ChineseCharsPlane2 = "𠀋𠀿"; +const ArabicOne = "\u0648\u0627\u062D\u062F"; +const ArabicTwo = "\u0627\u062B\u0646\u064A\u0646"; +const ArabicThree = "\u062B\u0644\u0627\u062B\u0629"; + +async function test1() { + await setPrefs(false, true); + + editor.innerHTML = "Hello Kitty"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 11); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "<b>Hello</b> Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.nextSibling, 0); + testRight(editor.firstChild.nextSibling, 6); + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Hello </b>Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.firstChild, 5); + testRight(editor.firstChild.nextSibling, 5); + testLeft(editor.firstChild.firstChild, 6); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Log out</b> roc"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.firstChild, 3); + testRight(editor.firstChild.nextSibling, 0); + testRight(editor.firstChild.nextSibling, 5); + // In the next test, we expect to be at the end of the + // space that is not collapsed away + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 4); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "http://www.mozilla.org"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 11); + testRight(editor.firstChild, 19); + testLeft(editor.firstChild, 11); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "Set .rc to <b>'</b>quiz'"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 10); + testRight(editor.firstChild.nextSibling.nextSibling, 5); + testLeft(editor.firstChild.nextSibling.firstChild, 1); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "layout.word_select.stop_at_punctuation"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 19); + testRight(editor.firstChild, 38); + testLeft(editor.firstChild, 19); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + HiraganaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + KatakanaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + HiraganaChars + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 12); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + editor.innerHTML = HiraganaChars + JapaneseComma + HiraganaChars + JapaneseFullStop + HiraganaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 10); + testRight(editor.firstChild, 13); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 13); + testLeft(editor.firstChild, 10); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 3); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + JapaneseComma + KatakanaChars + JapaneseFullStop + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 10); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 10); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + JapaneseComma + ChineseChars + JapaneseFullStop + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 3); + testLeft(editor.firstChild, 0); + + // test for bug 1066756 + editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 13); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); + + // test word selection in Deseret (alphabet in Plane 1) + editor.innerHTML = DeseretChars + " " + DeseretChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 9); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + // Latin words separated by a pictographic symbol + editor.innerHTML = "hello" + Symbol + "world"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 11); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 0); + + // Latin words separated by an emoji symbol + editor.innerHTML = "hello" + Emoji + "world"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 12); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + // Emoji and Chinese + editor.innerHTML = Emoji + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 4); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + // test that word selection stops at Latin/Chinese boundary + editor.innerHTML = "hello" + ChineseChars + "world"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 12); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + // similar, but with Deseret (alphabet in Plane 1) in place of Latin + editor.innerHTML = DeseretChars + ChineseChars + DeseretChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 10); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + // with Plane 2 Chinese characters + editor.innerHTML = "hello" + ChineseCharsPlane2 + "world"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 9); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 9); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + // Plane 1 Deseret and Plane 2 Chinese characters + editor.innerHTML = DeseretChars + ChineseCharsPlane2 + DeseretChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 12); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + // Out-of-flow frames around line edges should be treated as independent lines. + for (const floatValue of ["left", "right"]) { + editor.innerHTML = `<b>One</b> <i>Two</i><span style=float:${floatValue}>Three</span>`; + sel.collapse(editor.querySelector("i").firstChild, 0); + testRight(editor.querySelector("i").firstChild, "Two".length); + testRight(editor.querySelector("span").firstChild, "Three".length); + testLeft(editor.querySelector("span").firstChild, 0); + testLeft(editor.querySelector("i").previousSibling, " ".length); // FIXME: Should stop at start of "Two" + editor.innerHTML = `<span style=float:${floatValue}>One</span><b>Two</b> <i>Three</i>`; + sel.collapse(editor.querySelector("b").firstChild, "Two".length); + testLeft(editor.querySelector("b").firstChild, 0); + testLeft(editor.querySelector("span").firstChild, 0); + testRight(editor.querySelector("span").firstChild, "One".length); + testRight(editor.querySelector("b").nextSibling, 0); // FIXME: Should stop at end of "Two" + } + + // And also visually connected words which are split by an out-of-flow content + // shouldn't be treated as a word. + editor.innerHTML = 'One<span style=float:right>Two</span>Three'; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, "One".length); + testRight(editor.querySelector("span").firstChild, "Two".length); + testRight(editor.lastChild, "Three".length); + testLeft(editor.lastChild, 0); + testLeft(editor.querySelector("span").firstChild, 0); + testLeft(editor.firstChild, 0); + + // Simple RTL cases of above. + editor.setAttribute("dir", "rtl"); + for (const floatValue of ["left", "right"]) { + editor.innerHTML = `<b>${ArabicOne}</b> <i>${ArabicTwo}</i><span style=float:${floatValue}>${ArabicThree}</span>`; + sel.collapse(editor.querySelector("i").firstChild, 0); + testLeft(editor.querySelector("i").firstChild, ArabicTwo.length); + testLeft(editor.querySelector("span").firstChild, ArabicThree.length); + testRight(editor.querySelector("span").firstChild, 0); + testRight(editor.querySelector("i").previousSibling, " ".length); // FIXME: Should stop at start of ArabicTwo. + editor.innerHTML = `<span style=float:${floatValue}>${ArabicOne}</span><b>${ArabicTwo}</b> <i>${ArabicThree}</i>`; + sel.collapse(editor.querySelector("b").firstChild, ArabicTwo.length); + testRight(editor.querySelector("b").firstChild, 0); + testRight(editor.querySelector("span").firstChild, 0); + testLeft(editor.querySelector("span").firstChild, ArabicOne.length); + testLeft(editor.querySelector("b").nextSibling, 0); // FIXME: Should stop at end of ArabicTwo. + } + + // And also the bidi cases which LRT frames are at line edge if ignoring the + // out-of-flow things. + // XXX Although these tests are behave as expected if I test them manually. + // I don't know the reason why the behavior changes in this test file. + for (const floatValue of ["left", "right"]) { + editor.innerHTML = `<div><b>${ArabicOne}</b> <i dir="ltr">Two</i><span style=float:${floatValue}>${ArabicThree}</span></div>`; + sel.collapse(editor.querySelector("i").firstChild, "Two".length); + testLeft(editor.querySelector("i").firstChild, 0, true); + testLeft(editor.querySelector("span").firstChild, 0, true); + testLeft(editor.querySelector("span").firstChild, ArabicThree.length); + testRight(editor.querySelector("span").firstChild, 0); + testRight(editor.querySelector("i").previousSibling, " ".length); // FIXME: Should stop at end of "Two" + editor.innerHTML = `<div><span style=float:${floatValue}>${ArabicOne}</span><b dir="ltr">Two</b> <i>${ArabicThree}</i></div>`; + sel.collapse(editor.querySelector("b").firstChild, 0); + testRight(editor.querySelector("b").firstChild, "Two".length, true); + testRight(editor.querySelector("span").firstChild, ArabicOne.length, true); + testRight(editor.querySelector("span").firstChild, 0); + testLeft(editor.querySelector("span").firstChild, ArabicOne.length); + testLeft(editor.querySelector("b").nextSibling, 0); // FIXME: Should stop at start of "Two". + } + + editor.removeAttribute("dir"); +} + +async function test2() { + // test basic word movement with eat_space_next_to_word true. + await setPrefs(true, true); + + editor.innerHTML = "Hello Kitty"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 11); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "<b>Hello</b> Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.nextSibling, 1); + testRight(editor.firstChild.nextSibling, 6); + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Hello </b>Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.nextSibling, 0); + testRight(editor.firstChild.nextSibling, 5); + testLeft(editor.firstChild.firstChild, 6); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Log out</b> roc"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.firstChild, 4); + testRight(editor.firstChild.nextSibling, 2); + testRight(editor.firstChild.nextSibling, 5); + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 4); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "http://www.mozilla.org"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 11); + testRight(editor.firstChild, 19); + testLeft(editor.firstChild, 11); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "Set .rc to <b>'</b>quiz'"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 8); + testRight(editor.firstChild.nextSibling.firstChild, 0); + testRight(editor.firstChild.nextSibling.nextSibling, 5); + testLeft(editor.firstChild.nextSibling.firstChild, 1); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "layout.word_select.stop_at_punctuation"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 19); + testRight(editor.firstChild, 38); + testLeft(editor.firstChild, 19); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + HiraganaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + KatakanaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + HiraganaChars + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 12); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + editor.innerHTML = HiraganaChars + JapaneseComma + HiraganaChars + JapaneseFullStop + HiraganaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 10); + testRight(editor.firstChild, 13); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 13); + testLeft(editor.firstChild, 10); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 3); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + JapaneseComma + KatakanaChars + JapaneseFullStop + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 10); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 10); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + JapaneseComma + ChineseChars + JapaneseFullStop + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 3); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 13); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); +} + +async function test3() { + // Test basic word movement with stop_at_punctuation false (bug 981281). + await setPrefs(false, false); + + editor.innerHTML = "Hello Kitty"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 11); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "<b>Hello</b> Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.nextSibling, 0); + testRight(editor.firstChild.nextSibling, 6); + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Hello </b>Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.firstChild, 5); + testRight(editor.firstChild.nextSibling, 5); + testLeft(editor.firstChild.firstChild, 6); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Log out</b> roc"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.firstChild, 3); + testRight(editor.firstChild.nextSibling, 0); + testRight(editor.firstChild.nextSibling, 5); + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 4); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "http://www.mozilla.org"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 22); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "Set .rc to <b>'</b>quiz'"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 10); + testRight(editor.firstChild.nextSibling.nextSibling, 5); + testLeft(editor.firstChild, 11); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "layout.word_select.stop_at_punctuation"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 38); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + HiraganaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + KatakanaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + HiraganaChars + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 12); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + editor.innerHTML = HiraganaChars + JapaneseComma + HiraganaChars + JapaneseFullStop + HiraganaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 13); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 13); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 3); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + JapaneseComma + KatakanaChars + JapaneseFullStop + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + JapaneseComma + ChineseChars + JapaneseFullStop + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 13); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); +} + +async function test4() { + // And again with eat_space_next_to_word true. + await setPrefs(true, false); + + editor.innerHTML = "Hello Kitty"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 11); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "<b>Hello</b> Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.nextSibling, 1); + testRight(editor.firstChild.nextSibling, 6); + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Hello </b>Kitty"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.nextSibling, 0); + testRight(editor.firstChild.nextSibling, 5); + testLeft(editor.firstChild.firstChild, 6); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "<b>Log out</b> roc"; + sel.collapse(editor.firstChild.firstChild, 0); + testRight(editor.firstChild.firstChild, 4); + testRight(editor.firstChild.nextSibling, 2); + testRight(editor.firstChild.nextSibling, 5); + testLeft(editor.firstChild.nextSibling, 1); + testLeft(editor.firstChild.firstChild, 4); + testLeft(editor.firstChild.firstChild, 0); + + editor.innerHTML = "http://www.mozilla.org"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 22); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "Set .rc to <b>'</b>quiz'"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 8); + testRight(editor.firstChild.nextSibling.firstChild, 0); + testRight(editor.firstChild.nextSibling.nextSibling, 5); + testLeft(editor.firstChild, 11); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "layout.word_select.stop_at_punctuation"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 38); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + HiraganaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 5); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 5); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + KatakanaChars + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 2); + testRight(editor.firstChild, 6); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 6); + testLeft(editor.firstChild, 2); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + HiraganaChars + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 4); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 12); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 4); + testLeft(editor.firstChild, 0); + + editor.innerHTML = HiraganaChars + JapaneseComma + HiraganaChars + JapaneseFullStop + HiraganaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 3); + testRight(editor.firstChild, 8); + testRight(editor.firstChild, 13); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 13); + testLeft(editor.firstChild, 8); + testLeft(editor.firstChild, 3); + testLeft(editor.firstChild, 0); + + editor.innerHTML = KatakanaChars + JapaneseComma + KatakanaChars + JapaneseFullStop + KatakanaChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 14); + testLeft(editor.firstChild, 0); + + editor.innerHTML = ChineseChars + JapaneseComma + ChineseChars + JapaneseFullStop + ChineseChars; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 8); + testLeft(editor.firstChild, 0); + + editor.innerHTML = "hello" + ModifierColon + " wo" + ModifierColon + "rld"; + sel.collapse(editor.firstChild, 0); + testRight(editor.firstChild, 7); + testRight(editor.firstChild, 13); + testLeft(editor.firstChild, 7); + testLeft(editor.firstChild, 0); +} + + +</script></pre> +</body> +</html> |