Bug 1877513 - Make HTMLEditor deletes only preceding lines of right child block if the range starts from start of a line r=m_kato

Currently, the editor of Gecko always unwraps first line of the right child
block after deleting selected range when the range starts in a parent block
and ends in a child block.  This behavior is almost same as the other browsers,
but the other browsers deletes only preceding lines of the right child block
(i.e., without unwrapping the first line of the right child block) if the range
starts from start of a preceding line, for example, when deleting
`<div>abc<br>[def<p>g]hi<br>jkl`, Gecko moves "hi" to the parent `<div>`,
but the other browsers keeps it in the child `<p>`.

For emulating this special handling, we need to touch 2 paths.

One is `Backspace` when selection is collapsed at start of the child block.  In
this case, only when the preceding line is empty, i.e., there are 2 line breaks
(either `<br>` or `\n` in `white-space: pre-*`), the following break should
be deleted, but the child block should not be touched.

The other is, deleting when selection is not collapsed or `Delete` when
selection is collapsed at immediately before the child block.  In the latter
case, `HTMLEditor::HandleDeleteSelection` extends `Selection` using
`nsFrameSelection`.  Then, handle it with same path as deleting non-collapsed
range.

The former is handled with `HandleDeleteLineBreak` and
`ComputeRangeToDeleteLineBreak`.  The latter is handled with
`HandleDeleteNonCollapsedRange` and `ComputeRangeToDeleteNonCollapsedRange`.
The new handlers use the `ComputeRangeToDelete*`.  Therefore, `beforeinput`
reports exactly same range from `getTargetRanges`.  However, existing paths
do not use same approach and this patch makes `HandleDeleteNonCollapsedRange`
fall it back to `HandleDeleteNonCollapsedRange`.  Therefore, some `if` checks
in `HandleDeleteNonCollapsedRange` are ugly, but I have no better idea to
implement this smarter.

Differential Revision: https://phabricator.services.mozilla.com/D207690
This commit is contained in:
Masayuki Nakano 2024-04-27 00:36:26 +00:00
parent ece3d5301d
commit 398b556e90
9 changed files with 1876 additions and 107 deletions

View file

@ -642,6 +642,7 @@ inline EditorInputType ToInputType(EditAction aEditAction) {
inline bool MayEditActionDeleteAroundCollapsedSelection( inline bool MayEditActionDeleteAroundCollapsedSelection(
const EditAction aEditAction) { const EditAction aEditAction) {
switch (aEditAction) { switch (aEditAction) {
case EditAction::eCut:
case EditAction::eDeleteSelection: case EditAction::eDeleteSelection:
case EditAction::eDeleteBackward: case EditAction::eDeleteBackward:
case EditAction::eDeleteForward: case EditAction::eDeleteForward:

File diff suppressed because it is too large Load diff

View file

@ -10,9 +10,6 @@
[[["delete",""\]\] "foo<script>bar</script>[\]baz" compare innerHTML] [[["delete",""\]\] "foo<script>bar</script>[\]baz" compare innerHTML]
expected: FAIL expected: FAIL
[[["delete",""\]\] "foo<br><br><p>[\]bar</p>" compare innerHTML]
expected: FAIL
[[["defaultparagraphseparator","div"\],["delete",""\]\] "foo<div><p>[\]bar</p></div>" compare innerHTML] [[["defaultparagraphseparator","div"\],["delete",""\]\] "foo<div><p>[\]bar</p></div>" compare innerHTML]
expected: FAIL expected: FAIL
@ -25,9 +22,6 @@
[[["delete",""\]\] "<p>foo</p><br><p>[\]bar</p>" compare innerHTML] [[["delete",""\]\] "<p>foo</p><br><p>[\]bar</p>" compare innerHTML]
expected: FAIL expected: FAIL
[[["delete",""\]\] "<p>foo</p><br><br><p>[\]bar</p>" compare innerHTML]
expected: FAIL
[[["delete",""\]\] "<a>foo</a>[\]bar" compare innerHTML] [[["delete",""\]\] "<a>foo</a>[\]bar" compare innerHTML]
expected: FAIL expected: FAIL

View file

@ -436,9 +436,6 @@
[[["forwarddelete",""\]\] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" compare innerHTML] [[["forwarddelete",""\]\] "<ol><li><p>foo</ol><p>{}<br></p><ol><li>bar</ol>" compare innerHTML]
expected: FAIL expected: FAIL
[[["forwarddelete",""\]\] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>": execCommand("forwarddelete", false, "") return value]
expected: FAIL
[[["forwarddelete",""\]\] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" compare innerHTML] [[["forwarddelete",""\]\] "<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>" compare innerHTML]
expected: FAIL expected: FAIL

View file

@ -7,9 +7,6 @@
[Backspace at "<ul><li>list-item1[</li></ul><ul><li>}list-item2<br>second line in list-item2</li></ul>" - comparing innerHTML] [Backspace at "<ul><li>list-item1[</li></ul><ul><li>}list-item2<br>second line in list-item2</li></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
[Backspace at "<ul><li>list-item1</li><li>[list-item2</li><ol><li>list-item3</li><li>}list-item4</li></ol></ul>" - comparing innerHTML]
expected: FAIL
[Backspace at "<ul><ol><li>list-item1</li><li>[list-item2</li></ol><li>}list-item3</li></ul>" - comparing innerHTML] [Backspace at "<ul><ol><li>list-item1</li><li>[list-item2</li></ol><li>}list-item3</li></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
@ -355,9 +352,6 @@
[Backspace at "<ul><li>list-item1</li><li><p>[\]list-item2</p></li></ul>" - comparing innerHTML] [Backspace at "<ul><li>list-item1</li><li><p>[\]list-item2</p></li></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
[Backspace at "<ul><li>list-item1</li><li>[list-item2</li><ul><li>list-item3</li><li>}list-item4</li></ul></ul>" - comparing innerHTML]
expected: FAIL
[Backspace at "<ul><ul><li>list-item1[</li></ul></ul><ol><li>list-item2\]</li></ol>"] [Backspace at "<ul><ul><li>list-item1[</li></ul></ul><ol><li>list-item2\]</li></ol>"]
expected: FAIL expected: FAIL
@ -875,15 +869,9 @@
[Delete at "<ul><ol><li>[list-item1</li></ol><li>list-item2\]</li></ul>" - comparing innerHTML] [Delete at "<ul><ol><li>[list-item1</li></ol><li>list-item2\]</li></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
[Delete at "<ul><li>list-item1</li><li>[list-item2</li><ul><li>list-item3</li><li>}list-item4</li></ul></ul>" - comparing innerHTML]
expected: FAIL
[Delete at "<ul><ul><li>[list-item1</li></ul><li>list-item2\]</li></ul>" - comparing innerHTML] [Delete at "<ul><ul><li>[list-item1</li></ul><li>list-item2\]</li></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
[Delete at "<ul><li>list-item1</li><li>[list-item2</li><ol><li>list-item3</li><li>}list-item4</li></ol></ul>" - comparing innerHTML]
expected: FAIL
[Delete at "<ul><li>[list-item1</li></ul><ul><li>list-item2\]</li></ul>" - comparing innerHTML] [Delete at "<ul><li>[list-item1</li></ul><ul><li>list-item2\]</li></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
@ -1128,9 +1116,6 @@
[Backspace at "<ol><ol><li>list-item1[</li></ol></ol><ul><li>list-item2\]</li></ul>"] [Backspace at "<ol><ol><li>list-item1[</li></ol></ol><ul><li>list-item2\]</li></ul>"]
expected: FAIL expected: FAIL
[Backspace at "<ol><li>list-item1</li><li>[list-item2</li><ol><li>list-item3</li><li>}list-item4</li></ol></ol>" - comparing innerHTML]
expected: FAIL
[Backspace at "<ol><ul><li>[list-item1</li></ul></ol><ul><li>}list-item2</li></ul>"] [Backspace at "<ol><ul><li>[list-item1</li></ul></ol><ul><li>}list-item2</li></ul>"]
expected: FAIL expected: FAIL
@ -1155,9 +1140,6 @@
[Backspace at "<ol><li>[list-item1</li></ol><ul><ol><li>}list-item2</li></ol></ul>" - comparing innerHTML] [Backspace at "<ol><li>[list-item1</li></ol><ul><ol><li>}list-item2</li></ol></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
[Backspace at "<ol><li>list-item1</li><li>[list-item2</li><ul><li>list-item3</li><li>}list-item4</li></ul></ol>" - comparing innerHTML]
expected: FAIL
[Backspace at "<ol><ul><li>list-item1</li><li>[list-item2</li></ul><li>}list-item3</li></ol>" - comparing innerHTML] [Backspace at "<ol><ul><li>list-item1</li><li>[list-item2</li></ul><li>}list-item3</li></ol>" - comparing innerHTML]
expected: FAIL expected: FAIL
@ -1718,9 +1700,6 @@
[Delete at "<ol><ol><li>[list-item1</li></ol><li>list-item2\]</li></ol>" - comparing innerHTML] [Delete at "<ol><ol><li>[list-item1</li></ol><li>list-item2\]</li></ol>" - comparing innerHTML]
expected: FAIL expected: FAIL
[Delete at "<ol><li>list-item1</li><li>[list-item2</li><ul><li>list-item3</li><li>}list-item4</li></ul></ol>" - comparing innerHTML]
expected: FAIL
[Delete at "<ol><li><ul><li>[list-item1</li></ul><li>}list-item2</li></ol>" - comparing innerHTML] [Delete at "<ol><li><ul><li>[list-item1</li></ul><li>}list-item2</li></ol>" - comparing innerHTML]
expected: FAIL expected: FAIL
@ -1847,9 +1826,6 @@
[Delete at "<ol><li>[list-item1</li></ol><ul><li><ol><li>list-item2\]</li></ol></li></ul>" - comparing innerHTML] [Delete at "<ol><li>[list-item1</li></ol><ul><li><ol><li>list-item2\]</li></ol></li></ul>" - comparing innerHTML]
expected: FAIL expected: FAIL
[Delete at "<ol><li>list-item1</li><li>[list-item2</li><ol><li>list-item3</li><li>}list-item4</li></ol></ol>" - comparing innerHTML]
expected: FAIL
[Delete at "<ol><ul><li>[list-item1</li></ul></ol><ol><li>}list-item2</li></ol>"] [Delete at "<ol><ul><li>[list-item1</li></ul></ol><ol><li>}list-item2</li></ol>"]
expected: FAIL expected: FAIL

View file

@ -2044,12 +2044,12 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}],
["foo<br><br>{<p>]bar</p>", ["foo<br><br>{<p>]bar</p>",
[["defaultparagraphseparator","div"],["delete",""]], [["defaultparagraphseparator","div"],["delete",""]],
"foo<br>{}bar", "foo<br><p>bar</p>",
[true,true], [true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"delete":[false,false,"",false,false,""]}],
["foo<br><br>{<p>]bar</p>", ["foo<br><br>{<p>]bar</p>",
[["defaultparagraphseparator","p"],["delete",""]], [["defaultparagraphseparator","p"],["delete",""]],
"foo<br>{}bar", "foo<br><p>bar</p>",
[true,true], [true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}],
["<p>foo<br>{</p><p>}bar</p>", ["<p>foo<br>{</p><p>}bar</p>",
@ -2359,7 +2359,7 @@ var browserTests = [
{"delete":[false,false,"",false,false,""]}], {"delete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol>[bar<ol><li>]baz</ol>", ["<ol><li>foo</ol>[bar<ol><li>]baz</ol>",
[["delete",""]], [["delete",""]],
"<ol><li>foo</li></ol>{}baz", "<ol><li>foo</li></ol><ol><li>baz</li></ol>",
[true], [true],
{"delete":[false,false,"",false,false,""]}], {"delete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>", ["<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>",

View file

@ -2009,12 +2009,12 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}],
["foo<br><br>{<p>]bar</p>", ["foo<br><br>{<p>]bar</p>",
[["defaultparagraphseparator","div"],["forwarddelete",""]], [["defaultparagraphseparator","div"],["forwarddelete",""]],
"foo<br>{}bar", "foo<br><p>bar</p>",
[true,true], [true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}],
["foo<br><br>{<p>]bar</p>", ["foo<br><br>{<p>]bar</p>",
[["defaultparagraphseparator","p"],["forwarddelete",""]], [["defaultparagraphseparator","p"],["forwarddelete",""]],
"foo<br>{}bar", "foo<br><p>bar</p>",
[true,true], [true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}],
["<p>foo<br>{</p><p>}bar</p>", ["<p>foo<br>{</p><p>}bar</p>",
@ -2184,7 +2184,7 @@ var browserTests = [
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol>{}<br><ol><li>bar</ol>", ["<ol><li>foo</ol>{}<br><ol><li>bar</ol>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ol><li>foo</li></ol>{}bar", "<ol><li>foo</li></ol><ol><li>bar</li></ol>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>", ["<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>",
@ -2199,22 +2199,22 @@ var browserTests = [
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>", ["<ol id=a><li>foo</ol>{}<br><ol><li>bar</ol>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ol id=\"a\"><li>foo</li></ol>{}bar", "<ol id=\"a\"><li>foo</li></ol><ol><li>bar</li></ol>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>", ["<ol><li>foo</ol>{}<br><ol id=b><li>bar</ol>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ol><li>foo</li></ol>{}bar", "<ol><li>foo</li></ol><ol id=\"b\"><li>bar</li></ol>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>", ["<ol id=a><li>foo</ol>{}<br><ol id=b><li>bar</ol>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ol id=\"a\"><li>foo</li></ol>{}bar", "<ol id=\"a\"><li>foo</li></ol><ol id=\"b\"><li>bar</li></ol>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>", ["<ol class=a><li>foo</ol>{}<br><ol class=b><li>bar</ol>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ol class=\"a\"><li>foo</li></ol>{}bar", "<ol class=\"a\"><li>foo</li></ol><ol class=\"b\"><li>bar</li></ol>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>", ["<ol><ol><li>foo</ol><li>{}<br><ol><li>bar</ol></ol>",
@ -2259,7 +2259,7 @@ var browserTests = [
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol>[bar<ol><li>]baz</ol>", ["<ol><li>foo</ol>[bar<ol><li>]baz</ol>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ol><li>foo</li></ol>{}baz", "<ol><li>foo</li></ol><ol><li>baz</li></ol>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>", ["<ol><li>foo</ol><p>[bar<ol><li>]baz</ol>",
@ -2269,12 +2269,12 @@ var browserTests = [
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>", ["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>",
[["defaultparagraphseparator","div"],["forwarddelete",""]], [["defaultparagraphseparator","div"],["forwarddelete",""]],
"<ol><li>foo</li></ol><p>{}baz</p>", "<ol><li>foo</li></ol><ol><li><p>{}baz</p></li></ol>",
[true,true], [true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>", ["<ol><li>foo</ol><p>[bar<ol><li><p>]baz</ol>",
[["defaultparagraphseparator","p"],["forwarddelete",""]], [["defaultparagraphseparator","p"],["forwarddelete",""]],
"<ol><li>foo</li></ol><p>{}baz</p>", "<ol><li>foo</li></ol><ol><li><p>{}baz</p></li></ol>",
[true,true], [true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}], {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol><ol><li>[]bar</ol>", ["<ol><li>foo</ol><ol><li>[]bar</ol>",
@ -2289,7 +2289,7 @@ var browserTests = [
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ul><li>foo</ul>{}<br><ul><li>bar</ul>", ["<ul><li>foo</ul>{}<br><ul><li>bar</ul>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ul><li>foo</li></ul>{}bar", "<ul><li>foo</li></ul><ul><li>bar</li></ul>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>", ["<ul><li>foo</ul><p>{}<br></p><ul><li>bar</ul>",
@ -2304,7 +2304,7 @@ var browserTests = [
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol>{}<br><ul><li>bar</ul>", ["<ol><li>foo</ol>{}<br><ul><li>bar</ul>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ol><li>foo</li></ol>{}bar", "<ol><li>foo</li></ol><ul><li>bar</li></ul>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>", ["<ol><li>foo</ol><p>{}<br></p><ul><li>bar</ul>",
@ -2314,7 +2314,7 @@ var browserTests = [
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ul><li>foo</ul>{}<br><ol><li>bar</ol>", ["<ul><li>foo</ul>{}<br><ol><li>bar</ol>",
[["forwarddelete",""]], [["forwarddelete",""]],
"<ul><li>foo</li></ul>{}bar", "<ul><li>foo</li></ul><ol><li>bar</li></ol>",
[true], [true],
{"forwarddelete":[false,false,"",false,false,""]}], {"forwarddelete":[false,false,"",false,false,""]}],
["<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>", ["<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>",

View file

@ -424,4 +424,79 @@ class EditorTestUtils {
); );
} }
} }
static getRangeArrayDescription(arrayOfRanges) {
if (arrayOfRanges === null) {
return "null";
}
if (arrayOfRanges === undefined) {
return "undefined";
}
if (!Array.isArray(arrayOfRanges)) {
return "Unknown Object";
}
if (arrayOfRanges.length === 0) {
return "[]";
}
let result = "";
for (let range of arrayOfRanges) {
if (result === "") {
result = "[";
} else {
result += ",";
}
result += `{${EditorTestUtils.getRangeDescription(range)}}`;
}
result += "]";
return result;
}
static 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.replaceAll("\n", "\\\\n")}"`;
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")}"`
: ""
}${
node.inert ? ` inert` : ""
}${
node.hidden ? ` hidden` : ""
}${
node.readonly ? ` readonly` : ""
}${
node.disabled ? ` disabled` : ""
}>`;
default:
return `${node.nodeName}`;
}
}
static getRangeDescription(range) {
if (range === null) {
return "null";
}
if (range === undefined) {
return "undefined";
}
return range.startContainer == range.endContainer &&
range.startOffset == range.endOffset
? `(${EditorTestUtils.getNodeDescription(range.startContainer)}, ${range.startOffset})`
: `(${EditorTestUtils.getNodeDescription(range.startContainer)}, ${
range.startOffset
}) - (${EditorTestUtils.getNodeDescription(range.endContainer)}, ${range.endOffset})`;
}
} }