Bug 1416099 - part 4: Make HTMLEditRules::ReturnInParagraph() use EditorRawDOMPoint to store point to insert new <br> element before splitting the parent block r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 10 Nov 2017 17:24:39 +0900
changeset 696347 ae662cdef973787d17907c4eafd6d431ceeb170d
parent 696346 277a25c64a93c8e1191f3e7225538e955d94d0d1
child 696348 2ebb0c26cf54f6f00942ba1b3f12b1a1e7f501ed
push id88684
push usermasayuki@d-toybox.com
push dateFri, 10 Nov 2017 13:42:43 +0000
reviewersm_kato
bugs1416099
milestone58.0a1
Bug 1416099 - part 4: Make HTMLEditRules::ReturnInParagraph() use EditorRawDOMPoint to store point to insert new <br> element before splitting the parent block r?m_kato HTMLEditRules::ReturnInParagraph() stores point to insert new <br> element with a set of |parent|, |node| and |offset|. Their names are really unclear and they're really messy. So, let's use new local variable, |EditorRawDOMPoint pointToInsertBR|. This is set only when new <br> element is necessary. So, we can get rid of |newBRneeded| too. MozReview-Commit-ID: EdnhnlokurN
editor/libeditor/HTMLEditRules.cpp
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -6727,106 +6727,113 @@ HTMLEditRules::ReturnInParagraph(Selecti
 
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   if (!node) {
     return EditActionResult(NS_ERROR_NULL_POINTER);
   }
 
   RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
 
-  int32_t offset;
-  nsCOMPtr<nsINode> parent = EditorBase::GetNodeLocation(node, &offset);
-
   bool doesCRCreateNewP = htmlEditor->GetReturnInParagraphCreatesNewParagraph();
 
-  bool newBRneeded = false;
   bool newSelNode = false;
   nsCOMPtr<nsIContent> brNode;
   nsCOMPtr<nsIDOMNode> selNode = GetAsDOMNode(aNode);
   int32_t selOffset = aOffset;
 
+  EditorRawDOMPoint pointToInsertBR;
   if (aNode == &aParentDivOrP && doesCRCreateNewP) {
-    // we are at the edges of the block, newBRneeded not needed!
+    // We are at the edges of the block, we don't need to create new <br>.
     brNode = nullptr;
   } else if (EditorBase::IsTextNode(aNode)) {
     // at beginning of text node?
     if (!aOffset) {
       // is there a BR prior to it?
       brNode = htmlEditor->GetPriorHTMLSibling(node);
       if (!brNode ||
           !htmlEditor->IsVisibleBRElement(brNode) ||
           TextEditUtils::HasMozAttr(GetAsDOMNode(brNode))) {
-        newBRneeded = true;
+        pointToInsertBR.Set(node);
         brNode = nullptr;
       }
     } else if (aOffset == static_cast<int32_t>(node->Length())) {
       // we're at the end of text node...
       // is there a BR after to it?
       brNode = htmlEditor->GetNextHTMLSibling(node);
       if (!brNode ||
           !htmlEditor->IsVisibleBRElement(brNode) ||
           TextEditUtils::HasMozAttr(GetAsDOMNode(brNode))) {
-        newBRneeded = true;
+        pointToInsertBR.Set(node);
+        DebugOnly<bool> advanced = pointToInsertBR.AdvanceOffset();
+        NS_WARNING_ASSERTION(advanced,
+          "Failed to advance offset to after the container");
         brNode = nullptr;
-        offset++;
       }
     } else {
+      nsCOMPtr<nsINode> leftNode = node;
+
       if (doesCRCreateNewP) {
-        nsCOMPtr<nsIDOMNode> tmp;
+        nsCOMPtr<nsIDOMNode> leftDOMNode;
         nsresult rv =
-          htmlEditor->SplitNode(selNode, aOffset, getter_AddRefs(tmp));
+          htmlEditor->SplitNode(selNode, aOffset, getter_AddRefs(leftDOMNode));
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return EditActionResult(rv);
         }
-        selNode = tmp;
-      }
-
-      newBRneeded = true;
-      offset++;
+        selNode = leftDOMNode;
+        leftNode = do_QueryInterface(leftDOMNode);
+      }
+
+      // We need to put new <br> after the left node if given node was split
+      // above.
+      pointToInsertBR.Set(leftNode);
+      DebugOnly<bool> advanced = pointToInsertBR.AdvanceOffset();
+      NS_WARNING_ASSERTION(advanced,
+        "Failed to advance offset to after the container");
     }
   } else {
     // not in a text node.
     // is there a BR prior to it?
     nsCOMPtr<nsIContent> nearNode;
     nearNode = htmlEditor->GetPreviousEditableHTMLNode(
                              EditorRawDOMPoint(node, aChildAtOffset, aOffset));
     if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
         TextEditUtils::HasMozAttr(GetAsDOMNode(nearNode))) {
       // is there a BR after it?
       nearNode =
         htmlEditor->GetNextEditableHTMLNode(
                       EditorRawDOMPoint(node, aChildAtOffset, aOffset));
       if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
           TextEditUtils::HasMozAttr(GetAsDOMNode(nearNode))) {
-        newBRneeded = true;
-        parent = node;
-        offset = aOffset;
+        pointToInsertBR.Set(node, aOffset);
+        NS_WARNING_ASSERTION(pointToInsertBR.IsSetAndValid(),
+          "Failed to set point to insert <br> to given node");
         newSelNode = true;
       }
     }
-    if (!newBRneeded && TextEditUtils::IsBreak(nearNode)) {
+    if (!pointToInsertBR.IsSet() && TextEditUtils::IsBreak(nearNode)) {
       brNode = nearNode;
     }
   }
-  if (newBRneeded) {
+  if (pointToInsertBR.IsSet()) {
     // Don't modify the DOM tree if mHTMLEditor disappeared.
     if (NS_WARN_IF(!mHTMLEditor)) {
       return EditActionResult(NS_ERROR_NOT_AVAILABLE);
     }
 
     // if CR does not create a new P, default to BR creation
     if (NS_WARN_IF(!doesCRCreateNewP)) {
       return EditActionResult(NS_OK);
     }
 
-    brNode = htmlEditor->CreateBR(parent, offset);
+    brNode = htmlEditor->CreateBR(pointToInsertBR.Container(),
+                                  pointToInsertBR.Offset());
     if (newSelNode) {
       // We split the parent after the br we've just inserted.
-      selNode = GetAsDOMNode(parent);
-      selOffset = offset + 1;
+      selNode = GetAsDOMNode(pointToInsertBR.Container());
+      selOffset = pointToInsertBR.Offset() + 1;
     }
   }
   EditActionResult result(
     SplitParagraph(GetAsDOMNode(&aParentDivOrP), brNode, &aSelection,
                    address_of(selNode), &selOffset));
   result.MarkAsHandled();
   if (NS_WARN_IF(result.Failed())) {
     return result;