summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/mozilla/tests/editor
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 /testing/web-platform/mozilla/tests/editor
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 'testing/web-platform/mozilla/tests/editor')
-rw-r--r--testing/web-platform/mozilla/tests/editor/delete-space-after-double-click-selection.html278
-rw-r--r--testing/web-platform/mozilla/tests/editor/input-setRangeText-during-noframe-crash.html18
-rw-r--r--testing/web-platform/mozilla/tests/editor/white-space-handling-in-mail-editor.html371
3 files changed, 667 insertions, 0 deletions
diff --git a/testing/web-platform/mozilla/tests/editor/delete-space-after-double-click-selection.html b/testing/web-platform/mozilla/tests/editor/delete-space-after-double-click-selection.html
new file mode 100644
index 0000000000..6c065cbc12
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/editor/delete-space-after-double-click-selection.html
@@ -0,0 +1,278 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="timeout" content="long">
+ <title>Test for Bug 1783641</title>
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-actions.js"></script>
+ <style>
+ .testStyle {
+ font-family: 'Courier New', Courier, monospace;
+ font-size: 12px;
+ padding: 0px;
+ width: 200px;
+ }
+ </style>
+</head>
+<body>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1783641">Mozilla Bug 1783641</a><br />
+ <span class="testStyle" id="placeholder"></span>
+ <input class="testStyle" type="text" />
+ <div class="testStyle" contenteditable></div>
+ <textarea class="testStyle"></textarea>
+ <script>
+
+ promise_test(async t => {
+ await new Promise(resolve => { window.onload = resolve; });
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["editor.word_select.delete_space_after_doubleclick_selection", true],
+ ["layout.word_select.eat_space_to_next_word", false]
+ ]
+ });
+ }, "Test setup");
+ const placeHolder = document.getElementById("placeholder");
+ const deleteKey = "\uE017";
+
+ function waitForRender() {
+ return new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
+ };
+
+ for (const selector of ["input", "div[contenteditable]", "textarea"]) {
+ const editableElement = document.querySelector(selector);
+ editableElement.focus();
+
+ /**
+ * Helper functions to set or get the value and the current selection of `editableElement`,
+ * regardless of its actual type.
+ */
+ const setValue = (aValue) => {
+ editableElement.tagName.toLowerCase() == "div"
+ ? editableElement.innerHTML = aValue
+ : editableElement.value = aValue;
+ }
+ const getValue = () => {
+ return editableElement.tagName.toLowerCase() == "div"
+ ? editableElement.innerHTML
+ : editableElement.value;
+ };
+ const getSelection = () => {
+ return editableElement.tagName.toLowerCase() == "div"
+ ? document.getSelection().toString()
+ : editableElement.value.substring(
+ editableElement.selectionStart,
+ editableElement.selectionEnd
+ );
+ };
+
+ /**
+ * Places a double click in `editableElement` at exactly the end of `aPlaceHolderText` and press delete.
+ * `aPlaceholderText` therefore should contain the same text as the value of the `editableElement`
+ * up to the point where the doubleclick should happen.
+ *
+ * If `aSelectionValue` is defined, the selection created by the double click is compared to `aSelectionValue`.
+ */
+ const doubleClickAndDelete = async (aPlaceHolderText, aSelectionValue = undefined) => {
+ placeHolder.innerHTML = aPlaceHolderText;
+ editableElement.focus();
+ await waitForRender();
+ const absInputPos = editableElement.getBoundingClientRect();
+ selectionOffset = {
+ x: placeHolder.getBoundingClientRect().width,
+ y: Math.floor(placeHolder.getBoundingClientRect().height / 2)
+ };
+ await (new test_driver.Actions()
+ // for some reason this still doesn't work:
+ // .pointerMove(Math.floor(selectionOffset.x), Math.floor(selectionOffset.y), { origin: editableElement })
+ // but this does:
+ .pointerMove(
+ Math.floor(absInputPos.x + selectionOffset.x),
+ Math.floor(absInputPos.y + selectionOffset.y),
+ { origin: "viewport" }
+ )
+ .pointerDown()
+ .pointerUp()
+ .pointerDown()
+ .pointerUp())
+ .send()
+ await waitForRender();
+ if (aSelectionValue !== undefined) {
+ assert_equals(getSelection(), aSelectionValue, "Wrong selection value!");
+ }
+ return test_driver.send_keys(editableElement, deleteKey);
+ };
+ if (editableElement.tagName.toLowerCase() == "div") {
+ promise_test(async t => {
+ setValue("<p>abc def<span></span></p>");
+ await doubleClickAndDelete("abc de", "def");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "<p>abc</p>",
+ "The <span> at the end of the string must be removed, as well as the whitespace in between words.");
+ }, `${editableElement.tagName}: An empty span at the end of the selection should be considered end of selection!`);
+ }
+ promise_test(async t => {
+ setValue("one two");
+ await doubleClickAndDelete("on", "one");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "two",
+ "The whitespace between words must be removed when a word at the beginning is selected and deleted!"
+ );
+ }, `${editableElement.tagName}: Remove word at the beginning of string should remove the whitespace in between.`);
+
+ promise_test(async t => {
+ setValue("one two");
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one",
+ "The whitespace between words must be removed when a word is selected at the end of the string and deleted!"
+ );
+ }, `${editableElement.tagName}: Remove word at the end of a string should remove the whitespace in between.`);
+
+ promise_test(async t => {
+ setValue("one two three");
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one three",
+ "One whitespace between words must be removed when a word is selected and deleted!"
+ );
+ await waitForRender();
+ if (editableElement.tagName.toLowerCase() == "div") {
+ document.getSelection().setBaseAndExtent(
+ editableElement.firstChild,
+ 0,
+ editableElement.firstChild,
+ 3
+ );
+ }
+ else {
+ editableElement.setSelectionRange(0, 3);
+ }
+ await test_driver.send_keys(editableElement, deleteKey);
+ // div[contenteditable] returns '&nbsp;three' here.
+ assert_equals(
+ getValue().replace(/&nbsp;/g, " "),
+ " three",
+ "The whitespace must not be removed when selecting a word without doubleclicking it!"
+ );
+
+ }, `${editableElement.tagName}: Remove word in the middle of a string should remove one whitespace ` +
+ "only if selection is created by double click.");
+
+ promise_test(async t => {
+ setValue("one two three");
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one three",
+ "One whitespace between words must be removed when a word is selected and deleted!"
+ );
+ }, `${editableElement.tagName}: Only one whitespace character should be removed when there are multiple.`);
+
+ promise_test(async t => {
+ setValue("one two");
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one ",
+ "One whitespace character between words must be removed when a word is selected and deleted!"
+ );
+ }, `${editableElement.tagName}: Only one whitespace character should be removed when ` +
+ "there are multiple whitespaces and the deleted range is the end of the string.");
+
+ promise_test(async t => {
+ setValue("one two, three");
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one, three",
+ "The whitespace in front of the selected word must be removed when punctuation follows selection!"
+ );
+ }, `${editableElement.tagName}: Removing a word before punctuation should remove the whitespace.`);
+
+ promise_test(async t => {
+ setValue("one, two");
+ await doubleClickAndDelete("one, tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one,",
+ "The whitespace in front of the selected word must be removed!"
+ );
+ }, `${editableElement.tagName}: Remove a word after punctuation should remove the whitespace.`);
+
+ promise_test(async t => {
+ setValue("one\u00A0two, three"); // adds a &nbsp;
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one, three",
+ "The whitespace between words must be removed when a word is selected and deleted!"
+ );
+ }, `${editableElement.tagName}: Removing a word between a &nbsp; and punctuation should remove the nbsp character.`);
+
+ if (editableElement.tagName.toLowerCase() == "div") {
+ promise_test(async t => {
+ setValue("one two<br>");
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one<br>",
+ "The line break must be preserved!"
+ );
+ }, `${editableElement.tagName}: Removing a word in front of a line break should preserve the line break.`);
+ }
+ if (editableElement.tagName.toLowerCase() == "textarea") {
+ promise_test(async t => {
+ setValue("one two\n");
+ await doubleClickAndDelete("one tw", "two");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "one\n",
+ "The line break must be preserved!"
+ );
+ }, `${editableElement.tagName}: RRemoving a word in front of a line break should preserve the line break.`);
+ }
+ promise_test(async t => {
+ setValue("one two");
+ await doubleClickAndDelete("on", "one");
+ await waitForRender();
+ assert_equals(
+ getValue(),
+ "two",
+ "The whitespace between words must be removed when a word at the beginning is selected and deleted!"
+ );
+ document.execCommand("undo", false, null);
+ assert_equals(
+ getValue(),
+ "one two",
+ "Undo action must restore the original state!"
+ );
+ document.execCommand("redo", false, null);
+ assert_equals(
+ getValue(),
+ "two",
+ "Redo action must remove the word and whitespace again!"
+ );
+ }, `${editableElement.tagName}: Undo and Redo actions should take the removed whitespace into account.`);
+ }
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/mozilla/tests/editor/input-setRangeText-during-noframe-crash.html b/testing/web-platform/mozilla/tests/editor/input-setRangeText-during-noframe-crash.html
new file mode 100644
index 0000000000..815ec994e8
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/editor/input-setRangeText-during-noframe-crash.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ const input = document.querySelector("input");
+ input.select();
+ input.type = "text/x-ecmascript";
+ input.setRangeText("foo", 1, 1);
+ document.execCommand("enableObjectResizing");
+});
+</script>
+</head>
+<body>
+<input type="number" value="a">
+</body>
+</html>
diff --git a/testing/web-platform/mozilla/tests/editor/white-space-handling-in-mail-editor.html b/testing/web-platform/mozilla/tests/editor/white-space-handling-in-mail-editor.html
new file mode 100644
index 0000000000..06fe0acf6e
--- /dev/null
+++ b/testing/web-platform/mozilla/tests/editor/white-space-handling-in-mail-editor.html
@@ -0,0 +1,371 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<meta name="variant" content="?plaintext=true">
+<meta name="variant" content="?plaintext=false">
+<title>Testing white-space handling in mail editor mode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div contenteditable></div>
+<script>
+"use strict";
+
+const params = new URLSearchParams(location.search);
+const inPlaintextMode = params.get("plaintext") === "true";
+
+const editingHost = document.querySelector("div[contenteditable]");
+// To show white-spaces as-is, editing host should have "pre-wrap" style.
+// Then, editor does not need to convert white-spaces.
+editingHost.style.whiteSpace = "pre-wrap";
+
+const editor = SpecialPowers.wrap(window).docShell.editingSession.getEditorForWindow(window);
+editor.flags |= SpecialPowers.Ci.nsIEditor.eEditorMailMask;
+if (inPlaintextMode) {
+ editor.flags |= SpecialPowers.Ci.nsIEditor.eEditorPlaintextMask;
+}
+
+test(() => {
+ editingHost.innerHTML = "<p><br></p>";
+ getSelection().collapse(editingHost.querySelector("p"), 0);
+ document.execCommand("insertText", false, " ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Inserting first white-space into empty paragraph shouldn't convert the inserting white-space to an NBSP");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertText", false, " ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Inserting second white-space next to a white-space shouldn't convert the inserting white-space nor the existing white-space to NBSP");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertText", false, " ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Inserting 3rd white-space into middle of white-spaces shouldn't convert the inserting white-space nor the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("insertText", false, "a");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> a </p>",
+ "<p> a <br></p>",
+ ]
+ );
+}, "Inserting a character into middle of white-spaces shouldn't convert the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p> a </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 3);
+ document.execCommand("delete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Deleting a character at middle of white-spaces shouldn't convert the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 3);
+ document.execCommand("delete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Deleting a white-space at middle of white-spaces shouldn't convert the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p> a </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("forwardDelete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Forward deleting a character at middle of white-spaces shouldn't convert the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("forwardDelete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Forward deleting at middle of white-spaces shouldn't convert the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p><br></p>";
+ getSelection().collapse(editingHost.querySelector("p"), 0);
+ document.execCommand("insertText", false, "\xA0");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;</p>",
+ "<p>&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting first NBSP into empty paragraph shouldn't convert the inserting NBSP to a white-space");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertText", false, "\xA0");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting second NBSP next to an NBSP shouldn't convert the inserting NBSP nor the existing NBSP to white-space");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertText", false, "\xA0");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting 3rd NBSP into middle of NBSPs shouldn't convert the inserting NBSP nor the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("insertText", false, "a");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;a&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;a&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting a character into middle of NBSPs shouldn't convert the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0a\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 3);
+ document.execCommand("delete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Deleting a character at middle of NBSPs shouldn't convert the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0\xA0\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 3);
+ document.execCommand("delete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Deleting an NBSP at middle of NBSPs shouldn't convert the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0a\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("forwardDelete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Forward deleting a character at middle of NBSPs shouldn't convert the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0\xA0\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("forwardDelete");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Forward deleting at middle of NBSPs shouldn't convert the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p><br></p>";
+ getSelection().collapse(editingHost.querySelector("p"), 0);
+ document.execCommand("insertHTML", false, " ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Inserting first white-space with insertHTML command into empty paragraph shouldn't convert the inserting white-space to an NBSP");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertHTML", false, " ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Inserting second white-space with insertHTML command next to a white-space shouldn't convert the inserting white-space nor the existing white-space to NBSP");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertHTML", false, " ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> </p>",
+ "<p> <br></p>",
+ ]
+ );
+}, "Inserting 3rd white-space with insertHTML command into middle of white-spaces shouldn't convert the inserting white-space nor the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p> </p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("insertHTML", false, "a");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p> a </p>",
+ "<p> a <br></p>",
+ ]
+ );
+}, "Inserting a character with insertHTML command into middle of white-spaces shouldn't convert the existing white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p><br></p>";
+ getSelection().collapse(editingHost.querySelector("p"), 0);
+ document.execCommand("insertHTML", false, "\xA0");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;</p>",
+ "<p>&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting first NBSP with insertHTML command into empty paragraph shouldn't convert the inserting NBSP to a white-space");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertHTML", false, "\xA0");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting second NBSP with insertHTML command next to an NBSP shouldn't convert the inserting NBSP nor the existing NBSP to white-space");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 1);
+ document.execCommand("insertHTML", false, "\xA0");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting 3rd NBSP with insertHTML command into middle of NBSPs shouldn't convert the inserting NBSP nor the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p>\xA0\xA0\xA0\xA0</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, 2);
+ document.execCommand("insertHTML", false, "a");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>&nbsp;&nbsp;a&nbsp;&nbsp;</p>",
+ "<p>&nbsp;&nbsp;a&nbsp;&nbsp;<br></p>",
+ ]
+ );
+}, "Inserting a character with insertHTML command into middle of NBSPs shouldn't convert the existing NBSPs to white-spaces");
+
+test(() => {
+ editingHost.innerHTML = "<p>abc</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, "abc".length);
+ document.execCommand("insertHTML", false, "def ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>abcdef </p>",
+ "<p>abcdef <br></p>",
+ ]
+ );
+}, "Inserting multiple white-spaces with insertHTML command shouldn't convert the white-spaces to NBSPs");
+
+test(() => {
+ editingHost.innerHTML = "<p>abc</p>";
+ getSelection().collapse(editingHost.querySelector("p").firstChild, "abc".length);
+ document.execCommand("insertHTML", false, "def ");
+ assert_in_array(
+ editingHost.innerHTML,
+ [
+ "<p>abcdef </p>",
+ "<p>abcdef <br></p>",
+ ]
+ );
+}, "Inserting multiple NBSPs with insertHTML command shouldn't convert the NBSPs to white-spaces");
+
+</script>
+</body>
+</html>