Bug 1416099 - part 7: Make HTMLEditRules::ReturnInParagraph() use start of selection to split parent block instead of receiving the point from arguments r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 10 Nov 2017 16:51:24 +0900
changeset 696350 077e6ce55ee26d1335493a119acea14911e0552c
parent 696349 6833cc15b6ef1a09d4d714cc3c895c7e165a5b3f
child 739832 26a9d5b33494db5cf9fe0ade5c8cfaa425c40430
push id88684
push usermasayuki@d-toybox.com
push dateFri, 10 Nov 2017 13:42:43 +0000
reviewersm_kato
bugs1416099
milestone58.0a1
Bug 1416099 - part 7: Make HTMLEditRules::ReturnInParagraph() use start of selection to split parent block instead of receiving the point from arguments r?m_kato Now, we know HTMLEditRules::ReturnInParagraph() always splits the parent block at start of selection. So, it doesn't need to receive the position from the caller because the cost to get start of selection from first range of Selection is really cheap. MozReview-Commit-ID: EvNb6lUBLdt
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1797,21 +1797,17 @@ HTMLEditRules::WillInsertBreak(Selection
   //     Gmail.  So, let's use traditional odd behavior only when the default
   //     paragraph separator is <br>.  Otherwise, take consistent behavior
   //     between <p> container and <div> container.
   if ((separator == ParagraphSeparator::br &&
        blockParent->IsHTMLElement(nsGkAtoms::p)) ||
       (separator != ParagraphSeparator::br &&
        blockParent->IsAnyOfHTMLElements(nsGkAtoms::p, nsGkAtoms::div))) {
     // Paragraphs: special rules to look for <br>s
-    EditActionResult result =
-      ReturnInParagraph(aSelection, *blockParent,
-                        atStartOfSelection.Container(),
-                        atStartOfSelection.Offset(),
-                        atStartOfSelection.GetChildAtOffset());
+    EditActionResult result = ReturnInParagraph(aSelection, *blockParent);
     if (NS_WARN_IF(result.Failed())) {
       return result.Rv();
     }
     *aHandled = result.Handled();
     *aCancel = result.Canceled();
     // Fall through, we may not have handled it in ReturnInParagraph()
   }
 
@@ -6729,72 +6725,77 @@ HTMLEditRules::ReturnInHeader(Selection&
     rv = aSelection.Collapse(&aHeader, 0);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return NS_OK;
 }
 
 EditActionResult
 HTMLEditRules::ReturnInParagraph(Selection& aSelection,
-                                 nsINode& aParentDivOrP,
-                                 nsINode* aNode,
-                                 int32_t aOffset,
-                                 nsIContent* aChildAtOffset)
+                                 nsINode& aParentDivOrP)
 {
   if (NS_WARN_IF(!mHTMLEditor)) {
     return EditActionResult(NS_ERROR_NOT_AVAILABLE);
   }
 
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  if (!node) {
-    return EditActionResult(NS_ERROR_NULL_POINTER);
-  }
-
   RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
 
+  nsRange* firstRange = aSelection.GetRangeAt(0);
+  if (NS_WARN_IF(!firstRange)) {
+    return EditActionResult(NS_ERROR_FAILURE);
+  }
+
+  EditorDOMPoint atStartOfSelection(firstRange->StartRef());
+  if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
+    return EditActionResult(NS_ERROR_FAILURE);
+  }
+  MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
+
   bool doesCRCreateNewP = htmlEditor->GetReturnInParagraphCreatesNewParagraph();
 
   bool splitAfterNewBR = false;
   nsCOMPtr<nsIContent> brNode;
 
   // Point to split aParentDivOrP.
   // XXX If we don't need to use nsIDOMNode here, we should use EditorDOMPoint.
-  nsCOMPtr<nsIDOMNode> containerAtSplitPoint = GetAsDOMNode(aNode);
-  int32_t offsetAtSplitPoint = aOffset;
+  nsCOMPtr<nsIDOMNode> containerAtSplitPoint =
+    GetAsDOMNode(atStartOfSelection.Container());
+  int32_t offsetAtSplitPoint = atStartOfSelection.Offset();
 
   EditorRawDOMPoint pointToInsertBR;
-  if (aNode == &aParentDivOrP && doesCRCreateNewP) {
-    // We are at the edges of the block, we don't need to create new <br>.
+  if (doesCRCreateNewP &&
+      atStartOfSelection.Container() == &aParentDivOrP) {
+    // We are at the edges of the block, so, we don't need to create new <br>.
     brNode = nullptr;
-  } else if (EditorBase::IsTextNode(aNode)) {
+  } else if (EditorBase::IsTextNode(atStartOfSelection.Container())) {
     // at beginning of text node?
-    if (!aOffset) {
+    if (atStartOfSelection.IsStartOfContainer()) {
       // is there a BR prior to it?
-      brNode = htmlEditor->GetPriorHTMLSibling(node);
+      brNode = htmlEditor->GetPriorHTMLSibling(atStartOfSelection.Container());
       if (!brNode ||
           !htmlEditor->IsVisibleBRElement(brNode) ||
           TextEditUtils::HasMozAttr(GetAsDOMNode(brNode))) {
-        pointToInsertBR.Set(node);
+        pointToInsertBR.Set(atStartOfSelection.Container());
         brNode = nullptr;
       }
-    } else if (aOffset == static_cast<int32_t>(node->Length())) {
+    } else if (atStartOfSelection.IsEndOfContainer()) {
       // we're at the end of text node...
       // is there a BR after to it?
-      brNode = htmlEditor->GetNextHTMLSibling(node);
+      brNode = htmlEditor->GetNextHTMLSibling(atStartOfSelection.Container());
       if (!brNode ||
           !htmlEditor->IsVisibleBRElement(brNode) ||
           TextEditUtils::HasMozAttr(GetAsDOMNode(brNode))) {
-        pointToInsertBR.Set(node);
+        pointToInsertBR.Set(atStartOfSelection.Container());
         DebugOnly<bool> advanced = pointToInsertBR.AdvanceOffset();
         NS_WARNING_ASSERTION(advanced,
-          "Failed to advance offset to after the container");
+          "Failed to advance offset to after the container of selection start");
         brNode = nullptr;
       }
     } else {
-      nsCOMPtr<nsINode> leftNode = node;
+      nsCOMPtr<nsINode> leftNode = atStartOfSelection.Container();
 
       if (doesCRCreateNewP) {
         nsCOMPtr<nsIDOMNode> leftDOMNode;
         nsresult rv =
           htmlEditor->SplitNode(containerAtSplitPoint, offsetAtSplitPoint,
                                 getter_AddRefs(leftDOMNode));
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return EditActionResult(rv);
@@ -6803,35 +6804,32 @@ HTMLEditRules::ReturnInParagraph(Selecti
         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");
+        "Failed to advance offset to after the container of selection start");
     }
   } else {
     // not in a text node.
     // is there a BR prior to it?
     nsCOMPtr<nsIContent> nearNode;
-    nearNode = htmlEditor->GetPreviousEditableHTMLNode(
-                             EditorRawDOMPoint(node, aChildAtOffset, aOffset));
+    nearNode =
+      htmlEditor->GetPreviousEditableHTMLNode(atStartOfSelection.AsRaw());
     if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
         TextEditUtils::HasMozAttr(GetAsDOMNode(nearNode))) {
       // is there a BR after it?
       nearNode =
-        htmlEditor->GetNextEditableHTMLNode(
-                      EditorRawDOMPoint(node, aChildAtOffset, aOffset));
+        htmlEditor->GetNextEditableHTMLNode(atStartOfSelection.AsRaw());
       if (!nearNode || !htmlEditor->IsVisibleBRElement(nearNode) ||
           TextEditUtils::HasMozAttr(GetAsDOMNode(nearNode))) {
-        pointToInsertBR.Set(node, aOffset);
-        NS_WARNING_ASSERTION(pointToInsertBR.IsSetAndValid(),
-          "Failed to set point to insert <br> to given node");
+        pointToInsertBR = atStartOfSelection;
         splitAfterNewBR = true;
       }
     }
     if (!pointToInsertBR.IsSet() && TextEditUtils::IsBreak(nearNode)) {
       brNode = nearNode;
     }
   }
   if (pointToInsertBR.IsSet()) {
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -292,32 +292,29 @@ protected:
                        Tables aTables = Tables::yes);
   Element* IsInListItem(nsINode* aNode);
   nsAtom& DefaultParagraphSeparator();
   nsresult ReturnInHeader(Selection& aSelection, Element& aHeader,
                           nsINode& aNode, int32_t aOffset);
 
   /**
    * ReturnInParagraph() does the right thing for Enter key press or
-   * 'insertParagraph' command in aParentDivOrP.
+   * 'insertParagraph' command in aParentDivOrP.  aParentDivOrP will be
+   * split at start of first selection range.
    *
-   * @param aSelection      The selection
+   * @param aSelection      The selection.  aParentDivOrP will be split at
+   *                        start of the first selection range.
    * @param aParentDivOrP   The parent block.  This must be <p> or <div>
    *                        element.
-   * @param aTextNode
-   * @param aOffset
-   * @param aChildAtOffset
    * @return                Returns with NS_OK if this doesn't meat any
    *                        unexpected situation.  If this method tries to
    *                        split the paragraph, marked as handled.
    */
   EditActionResult ReturnInParagraph(Selection& aSelection,
-                                     nsINode& aParentDivOrP,
-                                     nsINode* aTextNode, int32_t aOffset,
-                                     nsIContent* aChildAtOffset);
+                                     nsINode& aParentDivOrP);
 
   /**
    * SplitParagraph() splits the parent block, aPara, at aSelNode - aOffset.
    *
    * @param aPara       The parent block to be split.
    * @param aBRNode     Next <br> node if there is.  Otherwise, nullptr.
    *                    If this is not nullptr, the <br> node may be removed.
    * @param aSelection  The selection.