summaryrefslogtreecommitdiffstats
path: root/layout/generic/test/test_movement_by_words.html
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 /layout/generic/test/test_movement_by_words.html
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 'layout/generic/test/test_movement_by_words.html')
-rw-r--r--layout/generic/test/test_movement_by_words.html781
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 = "&#x6F22;&#x5B57;";
+const HiraganaChars = "&#x3072;&#x3089;&#x304C;&#x306A;";
+const KatakanaChars = "&#x30AB;&#x30BF;&#x30AB;&#x30CA;";
+const JapaneseFullStop = "&#x3002;";
+const JapaneseComma = "&#x3001;";
+const ModifierColon = "&#xA789;";
+const Symbol = "&#x26C5;"; // "sun behind cloud" (weather symbol)
+const Emoji = "&#x1f400;"; // rat emoji
+const DeseretChars = "&#x10440;&#x10441;";
+const ChineseCharsPlane2 = "&#x2000B;&#x2003F;";
+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>