summaryrefslogtreecommitdiffstats
path: root/editor/libeditor/tests/test_nsIHTMLEditor_insertElementAtSelection.html
diff options
context:
space:
mode:
Diffstat (limited to 'editor/libeditor/tests/test_nsIHTMLEditor_insertElementAtSelection.html')
-rw-r--r--editor/libeditor/tests/test_nsIHTMLEditor_insertElementAtSelection.html185
1 files changed, 185 insertions, 0 deletions
diff --git a/editor/libeditor/tests/test_nsIHTMLEditor_insertElementAtSelection.html b/editor/libeditor/tests/test_nsIHTMLEditor_insertElementAtSelection.html
new file mode 100644
index 0000000000..9a0b7450eb
--- /dev/null
+++ b/editor/libeditor/tests/test_nsIHTMLEditor_insertElementAtSelection.html
@@ -0,0 +1,185 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Testing `nsIHTMLEditor.insertElementAtSelection()`</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<script>
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests);
+
+function getRangeDescription(range) {
+ function getNodeDescription(node) {
+ if (!node) {
+ return "null";
+ }
+ switch (node.nodeType) {
+ case Node.TEXT_NODE:
+ case Node.COMMENT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ return `${node.nodeName} "${node.data}"`;
+ case Node.ELEMENT_NODE:
+ return `<${node.nodeName.toLowerCase()}${
+ node.hasAttribute("id")
+ ? ` id="${node.getAttribute("id")}"`
+ : ""
+ }${
+ node.hasAttribute("class")
+ ? ` class="${node.getAttribute("class")}"`
+ : ""
+ }${
+ node.hasAttribute("contenteditable")
+ ? ` contenteditable="${node.getAttribute("contenteditable")}"`
+ : ""
+ }>`;
+ default:
+ return `${node.nodeName}`;
+ }
+ }
+ if (range === null) {
+ return "null";
+ }
+ if (range === undefined) {
+ return "undefined";
+ }
+ return range.startContainer == range.endContainer &&
+ range.startOffset == range.endOffset
+ ? `(${getNodeDescription(range.startContainer)}, ${range.startOffset})`
+ : `(${getNodeDescription(range.startContainer)}, ${
+ range.startOffset
+ }) - (${getNodeDescription(range.endContainer)}, ${range.endOffset})`;
+}
+
+function doTest(aEditingHost, aHTMLEditor, aDeleteSelection) {
+ const description = `aDeleteSelection=${aDeleteSelection}:`;
+ (() => {
+ aEditingHost.innerHTML = "abc";
+ aEditingHost.focus();
+ getSelection().collapse(aEditingHost.firstChild, 0);
+ const p = document.createElement("p");
+ p.appendChild(document.createElement("br"));
+ aHTMLEditor.insertElementAtSelection(p, aDeleteSelection);
+ is(
+ aEditingHost.innerHTML,
+ "<p><br></p>abc",
+ `${description} The <p> element should be inserted before the text node when selection is collapsed at start of the text node`
+ );
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ '(<div contenteditable="">, 1)',
+ `${description} The selection should be collapsed after the inserted <p> element`
+ );
+ })();
+ (() => {
+ aEditingHost.innerHTML = "abc";
+ aEditingHost.focus();
+ getSelection().collapse(aEditingHost.firstChild, 1);
+ const p = document.createElement("p");
+ p.appendChild(document.createElement("br"));
+ aHTMLEditor.insertElementAtSelection(p, aDeleteSelection);
+ is(
+ aEditingHost.innerHTML,
+ "a<p><br></p>bc",
+ `${description} The <p> element should be inserted middle of the text node when selection is collapsed at middle of the text node`
+ );
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ '(<div contenteditable="">, 2)',
+ `${description} The selection should be collapsed after the inserted <p> element (i.e., at right text node)`
+ );
+ })();
+ (() => {
+ aEditingHost.innerHTML = "abc";
+ aEditingHost.focus();
+ getSelection().collapse(aEditingHost.firstChild, 3);
+ const p = document.createElement("p");
+ p.appendChild(document.createElement("br"));
+ aHTMLEditor.insertElementAtSelection(p, aDeleteSelection);
+ is(
+ aEditingHost.innerHTML,
+ "abc<p><br></p>",
+ `${description} The <p> element should be inserted after the text node when selection is collapsed at end of the text node`
+ );
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ '(<div contenteditable="">, 2)',
+ `${description} The selection should be collapsed at end of the editing host`
+ );
+ })();
+ (() => {
+ aEditingHost.innerHTML = "abc";
+ aEditingHost.focus();
+ getSelection().setBaseAndExtent(aEditingHost.firstChild, 0, aEditingHost.firstChild, 1);
+ const p = document.createElement("p");
+ p.appendChild(document.createElement("br"));
+ aHTMLEditor.insertElementAtSelection(p, aDeleteSelection);
+ is(
+ aEditingHost.innerHTML,
+ aDeleteSelection ? "<p><br></p>bc" : "a<p><br></p>bc",
+ `${description} The <p> element should be inserted after selected character when selection selects the first character of the text node`
+ );
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ `(<div contenteditable="">, ${aDeleteSelection ? "1" : "2"})`,
+ `${description} The selection should be collapsed after the inserted <p> element (when selection selected the first character)`
+ );
+ })();
+ (() => {
+ aEditingHost.innerHTML = "abc";
+ aEditingHost.focus();
+ getSelection().setBaseAndExtent(aEditingHost.firstChild, 1, aEditingHost.firstChild, 2);
+ const p = document.createElement("p");
+ p.appendChild(document.createElement("br"));
+ aHTMLEditor.insertElementAtSelection(p, aDeleteSelection);
+ is(
+ aEditingHost.innerHTML,
+ aDeleteSelection ? "a<p><br></p>c" : "ab<p><br></p>c",
+ `${description} The <p> element should be inserted after selected character when selection selects a middle character of the text node`
+ );
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ '(<div contenteditable="">, 2)',
+ `${description} The selection should be collapsed after the inserted <p> element (i.e., at right text node, when selection selected the middle character)`
+ );
+ })();
+ (() => {
+ aEditingHost.innerHTML = "abc";
+ aEditingHost.focus();
+ getSelection().setBaseAndExtent(aEditingHost.firstChild, 2, aEditingHost.firstChild, 3);
+ const p = document.createElement("p");
+ p.appendChild(document.createElement("br"));
+ aHTMLEditor.insertElementAtSelection(p, aDeleteSelection);
+ is(
+ aEditingHost.innerHTML,
+ aDeleteSelection ? "ab<p><br></p>" : "abc<p><br></p>",
+ `${description} The <p> element should be inserted after selected character when selection selects the last character of the text node`
+ );
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ '(<div contenteditable="">, 2)',
+ `${description} The selection should be collapsed at end of the editing host (when selection selected the last character)`
+ );
+ })();
+}
+
+async function runTests() {
+ const editingHost = document.createElement("div");
+ editingHost.setAttribute("contenteditable", "");
+ document.body.appendChild(editingHost);
+ const editor =
+ SpecialPowers.
+ wrap(window).
+ docShell.
+ editingSession.
+ getEditorForWindow(window).
+ QueryInterface(SpecialPowers.Ci.nsIHTMLEditor);
+ doTest(editingHost, editor, true);
+ doTest(editingHost, editor, false);
+ SimpleTest.finish();
+}
+</script>
+</body>
+</html>