Bug 1329639 - Don't duplicate custom element by merging nodes. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Wed, 25 Jan 2017 14:07:53 +0900
changeset 466717 4b37d8ac2303c9c8f0510f80049cc812dc7dc587
parent 466606 fbdfcecf0c774d2221f11aed5a504d5591c774e0
child 543496 7b10ad01f19d8e032ac19c1f8b4aa1c565655748
push id42975
push userbmo:m_kato@ga2.so-net.ne.jp
push dateThu, 26 Jan 2017 11:31:25 +0000
reviewersmasayuki
bugs1329639
milestone54.0a1
Bug 1329639 - Don't duplicate custom element by merging nodes. r?masayuki When using custom element, nsIParserService doesn't detect as block element. So when merging node into another node via HTMLEditRuleS::TryToJoinBlocks, BustUpInlinesAtRangeEndpoints will duplicate the node since it detects inline node. MozReview-Commit-ID: 64gUI90Xd4z
editor/libeditor/HTMLEditor.cpp
editor/libeditor/tests/mochitest.ini
editor/libeditor/tests/test_bug1329639.html
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -763,25 +763,31 @@ HTMLEditor::NodeIsBlockStatic(const nsIN
                                     nsGkAtoms::td,
                                     nsGkAtoms::li,
                                     nsGkAtoms::dt,
                                     nsGkAtoms::dd,
                                     nsGkAtoms::pre)) {
     return true;
   }
 
+  // Custom element is as block even if parser says not block.
+  nsIParserService* parserService = nsContentUtils::GetParserService();
+  nsIAtom* name = aElement->NodeInfo()->NameAtom();
+  int32_t tag = parserService->HTMLCaseSensitiveAtomTagToId(name);
+  if (tag == eHTMLTag_userdefined &&
+      nsContentUtils::IsCustomElementName(name)) {
+    return true;
+  }
+
   bool isBlock;
 #ifdef DEBUG
   // XXX we can't use DebugOnly here because VC++ is stupid (bug 802884)
   nsresult rv =
 #endif
-    nsContentUtils::GetParserService()->
-    IsBlock(nsContentUtils::GetParserService()->HTMLAtomTagToId(
-              aElement->NodeInfo()->NameAtom()),
-            isBlock);
+    parserService->IsBlock(parserService->HTMLAtomTagToId(name), isBlock);
   MOZ_ASSERT(rv == NS_OK);
 
   AssertParserServiceIsCorrect(aElement->NodeInfo()->NameAtom(), isBlock);
 
   return isBlock;
 }
 
 nsresult
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -214,16 +214,17 @@ skip-if = toolkit == 'android'
 [test_bug1306532.html]
 subsuite = clipboard
 skip-if = toolkit == 'android'
 [test_bug1310912.html]
 skip-if = toolkit == 'android' # bug 1315898
 [test_bug1314790.html]
 [test_bug1315065.html]
 [test_bug1316302.html]
+[test_bug1329639.html]
 [test_bug1330796.html]
 
 [test_CF_HTML_clipboard.html]
 subsuite = clipboard
 [test_composition_event_created_in_chrome.html]
 [test_contenteditable_focus.html]
 [test_dom_input_event_on_htmleditor.html]
 skip-if = toolkit == 'android' # bug 1054087
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_bug1329639.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1329639
+-->
+<html>
+<head>
+  <title>Test for Bug 1329639</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1329639">Mozilla Bug 1329639</a>
+<p id="display"></p>
+<div id="content" style="display: none;">
+
+</div>
+
+<div id="editor1" contenteditable="true">
+<custom-element id="customelement1">
+  <p>First line</p>
+  <p>Second line</p>
+  <p>Third line</p>
+  <p><br></p>
+  <p><br></p>
+  <p><br></p>
+  <p id="lastblock">Fourth line</p>
+</custom-element>
+</div>
+<pre id="test">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+  var editor = document.getElementById("editor1");
+  editor.focus();
+  var selection = window.getSelection();
+  selection.collapse(document.getElementById("lastblock").firstChild, 0);
+  synthesizeKey('VK_BACK_SPACE', {});
+  synthesizeKey('VK_BACK_SPACE', {});
+
+  is(document.getElementsByTagName('custom-element').length, 1,
+     "<custom-element> element shouldn't be duplicated");
+
+  SimpleTest.finish();
+});
+</script>
+</pre>
+</body>
+</html>