Bug 1250010 - Fix nsHTMLEditRules::ReturnInParagraph(). r=ehsan
authorJorg K
Wed, 24 Feb 2016 13:43:00 +0100
changeset 322784 f859932803e86f449793e3f99d905cf43bac0771
parent 322783 a19efafe26aceb4feef4ec6e57757d77f868b690
child 322785 5e0e7a6b6f10e4435569d33e92326b9c8d530da7
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1250010
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1250010 - Fix nsHTMLEditRules::ReturnInParagraph(). r=ehsan
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/tests/chrome.ini
editor/libeditor/tests/test_bug1250010.html
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -6470,17 +6470,20 @@ nsHTMLEditRules::ReturnInParagraph(Selec
 
   int32_t offset;
   nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(aNode, &offset);
 
   NS_ENSURE_STATE(mHTMLEditor);
   bool doesCRCreateNewP = mHTMLEditor->GetReturnInParagraphCreatesNewParagraph();
 
   bool newBRneeded = false;
+  bool newSelNode = false;
   nsCOMPtr<nsIDOMNode> sibling;
+  nsCOMPtr<nsIDOMNode> selNode = aNode;
+  int32_t selOffset = aOffset;
 
   NS_ENSURE_STATE(mHTMLEditor);
   if (aNode == aPara && doesCRCreateNewP) {
     // we are at the edges of the block, newBRneeded not needed!
     sibling = aNode;
   } else if (mHTMLEditor->IsTextNode(aNode)) {
     nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(aNode);
     uint32_t strLength;
@@ -6508,58 +6511,65 @@ nsHTMLEditRules::ReturnInParagraph(Selec
         newBRneeded = true;
         offset++;
       }
     } else {
       if (doesCRCreateNewP) {
         nsCOMPtr<nsIDOMNode> tmp;
         res = mEditor->SplitNode(aNode, aOffset, getter_AddRefs(tmp));
         NS_ENSURE_SUCCESS(res, res);
-        aNode = tmp;
+        selNode = tmp;
       }
 
       newBRneeded = true;
       offset++;
     }
   } else {
     // not in a text node.
     // is there a BR prior to it?
-    nsCOMPtr<nsIDOMNode> nearNode, selNode = aNode;
+    nsCOMPtr<nsIDOMNode> nearNode;
     NS_ENSURE_STATE(mHTMLEditor);
     res = mHTMLEditor->GetPriorHTMLNode(aNode, aOffset, address_of(nearNode));
     NS_ENSURE_SUCCESS(res, res);
     NS_ENSURE_STATE(mHTMLEditor);
     if (!nearNode || !mHTMLEditor->IsVisBreak(nearNode) ||
         nsTextEditUtils::HasMozAttr(nearNode)) {
       // is there a BR after it?
       NS_ENSURE_STATE(mHTMLEditor);
       res = mHTMLEditor->GetNextHTMLNode(aNode, aOffset, address_of(nearNode));
       NS_ENSURE_SUCCESS(res, res);
       NS_ENSURE_STATE(mHTMLEditor);
       if (!nearNode || !mHTMLEditor->IsVisBreak(nearNode) ||
           nsTextEditUtils::HasMozAttr(nearNode)) {
         newBRneeded = true;
+        parent = aNode;
+        offset = 0;
+        newSelNode = true;
       }
     }
     if (!newBRneeded) {
       sibling = nearNode;
     }
   }
   if (newBRneeded) {
     // if CR does not create a new P, default to BR creation
     NS_ENSURE_TRUE(doesCRCreateNewP, NS_OK);
 
     nsCOMPtr<nsIDOMNode> brNode;
     NS_ENSURE_STATE(mHTMLEditor);
     res =  mHTMLEditor->CreateBR(parent, offset, address_of(brNode));
     sibling = brNode;
-  }
-  nsCOMPtr<nsIDOMNode> selNode = aNode;
+    if (newSelNode) {
+      // We split the parent after the br we've just inserted.
+      selNode = parent;
+      selOffset = 1;
+    }
+  }
   *aHandled = true;
-  return SplitParagraph(aPara, sibling, aSelection, address_of(selNode), &aOffset);
+  return SplitParagraph(aPara, sibling, aSelection, address_of(selNode), &selOffset);
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // SplitParagraph: split a paragraph at selection point, possibly deleting a br
 //
 nsresult
 nsHTMLEditRules::SplitParagraph(nsIDOMNode *aPara,
                                 nsIDOMNode *aBRNode,
--- a/editor/libeditor/tests/chrome.ini
+++ b/editor/libeditor/tests/chrome.ini
@@ -25,16 +25,17 @@ skip-if = buildapp == 'mulet'
 [test_bug1102906.html]
 [test_bug1101392.html]
 [test_bug1140105.html]
 [test_bug1140617.xul]
 [test_bug1153237.html]
 [test_bug1154791.html]
 [test_bug1248128.html]
 [test_bug1248185.html]
+[test_bug1250010.html]
 [test_composition_event_created_in_chrome.html]
 [test_contenteditable_text_input_handling.html]
 [test_dragdrop.html]
 skip-if = buildapp == 'mulet'
 [test_htmleditor_keyevent_handling.html]
 [test_selection_move_commands.xul]
 [test_texteditor_keyevent_handling.html]
 skip-if = (debug && os=='win') || (os == 'linux') # Bug 1116205, leaks on windows debug, fails delete key on linux
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_bug1250010.html
@@ -0,0 +1,53 @@
+<!DOCTYPE>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1250010
+-->
+<head>
+  <title>Test for Bug 1250010</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+</head>
+<body>
+<div id="display">
+</div>
+
+<div id="content" contenteditable><p><b><font color="red">1234567890</font></b></p></div>
+
+<pre id="test">
+</pre>
+
+<script class="testbody" type="application/javascript">
+
+/** Test for Bug 1250010 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+  var div = document.getElementById("content");
+  div.focus();
+  synthesizeMouseAtCenter(div, {});
+
+  var sel = window.getSelection();
+  var selRange = sel.getRangeAt(0);
+  is(selRange.endContainer.nodeName, "#text", "selection should be at the end of text node");
+  is(selRange.endOffset, 10, "offset should be 10");
+
+  synthesizeKey("VK_RETURN", {});
+  synthesizeKey("VK_RETURN", {});
+  synthesizeKey("b", {});
+  synthesizeKey("VK_UP", {});
+  synthesizeKey("a", {});
+
+  is(div.innerHTML, "<p><b><font color=\"red\">1234567890</font></b></p>" +
+                    "<p><b><font color=\"red\">a<br></font></b></p>" +
+                    "<p><b><font color=\"red\">b<br></font></b></p>",
+                    "unexpected HTML");
+
+  SimpleTest.finish();
+
+});
+
+</script>
+</body>
+
+</html>