Bug 1435123 - HTMLEditor::GetBlock() has to specify given ancestor limit node to HTMLEditor::GetBlockNodeParent() r?m_kato
This is a simple bug of internal API of HTMLEditor. HTMLEditor::GetBlock()
tries to retrieve nearest ancestor block node (including itself) of a node.
HTMLEditor::GetBlock() may have ancestor limiter typically it's active
editing host to prevent to modify editing host or its ancestor accidentally.
However, it forgets to call HTMLEditor::GetBlockNodeParent() with the given
ancestor limit node. Therefore, if editing host is an inline element and
its parent is a block element, the editing host is split accidentally.
MozReview-Commit-ID: Ermmxdnk4KB
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -894,17 +894,17 @@ HTMLEditor::GetBlock(nsINode& aNode,
MOZ_ASSERT(!aAncestorLimiter ||
&aNode == aAncestorLimiter ||
EditorUtils::IsDescendantOf(aNode, *aAncestorLimiter),
"aNode isn't in aAncestorLimiter");
if (NodeIsBlockStatic(&aNode)) {
return aNode.AsElement();
}
- return GetBlockNodeParent(&aNode);
+ return GetBlockNodeParent(&aNode, aAncestorLimiter);
}
/**
* IsNextCharInNodeWhitespace() checks the adjacent content in the same node to
* see if following selection is whitespace or nbsp.
*/
void
HTMLEditor::IsNextCharInNodeWhitespace(nsIContent* aContent,
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -266,16 +266,17 @@ subsuite = clipboard
[test_documentCharacterSet.html]
[test_dom_input_event_on_htmleditor.html]
skip-if = toolkit == 'android' # bug 1054087
[test_dom_input_event_on_texteditor.html]
[test_dragdrop.html]
skip-if = os == 'android'
[test_inline_style_cache.html]
[test_inlineTableEditing.html]
+[test_insertParagraph_in_inline_editing_host.html]
[test_keypress_untrusted_event.html]
[test_objectResizing.html]
[test_root_element_replacement.html]
[test_select_all_without_body.html]
[test_spellcheck_pref.html]
skip-if = toolkit == 'android'
[test_backspace_vs.html]
[test_css_chrome_load_access.html]
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_insertParagraph_in_inline_editing_host.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Test "insertParagraph" command in inline editing host</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+
+<span contenteditable>foobar</span>
+<hr>
+<p><span contenteditable>foobar</span></p>
+<hr>
+<div><span contenteditable>foobar</span></div>
+<hr>
+<div contenteditable><p contenteditable="false"><span contenteditable>foobar</span></p></div>
+
+<p id="display">
+</p>
+<div id="content" style="display: none">
+</div>
+
+<pre id="test">
+</pre>
+
+<script class="testbody" type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(() => {
+ var selection = document.getSelection();
+ var editors = document.querySelectorAll("span[contenteditable]");
+
+ var editor = editors.item(0);
+ editor.focus();
+ selection.collapse(editor.firstChild, 3);
+ document.execCommand("insertParagraph", false);
+ is(editor.innerHTML, "foo<br>bar",
+ "insertParagraph should insert <br> element (inline editing host is in <body>)");
+
+ editor = editors.item(1);
+ editor.focus();
+ selection.collapse(editor.firstChild, 3);
+ document.execCommand("insertParagraph", false);
+ is(editor.parentNode.innerHTML, "<span contenteditable=\"\">foo<br>bar</span>",
+ "insertParagraph should insert <br> element (inline editing host is in <p>)");
+
+ editor = editors.item(2);
+ editor.focus();
+ selection.collapse(editor.firstChild, 3);
+ document.execCommand("insertParagraph", false);
+ is(editor.parentNode.innerHTML, "<span contenteditable=\"\">foo<br>bar</span>",
+ "insertParagraph should insert <br> element (inline editing host is in <div>)");
+
+ editor = editors.item(3);
+ editor.focus();
+ selection.collapse(editor.firstChild, 3);
+ document.execCommand("insertParagraph", false);
+ is(editor.parentNode.parentNode.innerHTML, "<p contenteditable=\"false\"><span contenteditable=\"\">foo<br>bar</span></p>",
+ "insertParagraph should insert <br> element (inline editing host is in <p contenteditable=\"false\"> in <div contenteditable>)");
+
+ SimpleTest.finish();
+});
+
+</script>
+</body>
+
+</html>