Bug 1190172 part 9 - Clean up nsHTMLEditor::ReturnInHeader; r=ehsan
authorAryeh Gregor <ayg@aryeh.name>
Tue, 19 Apr 2016 06:55:00 +0200
changeset 333767 f0c671a3cf1d22e3aa40c2bca92d382a1a16d89e
parent 333766 f349334cc957a4187d53a0c30d848574d3c978a3
child 333768 19fbefce0e94796010c00a7525a23cab40c7bcf0
push id1146
push userCallek@gmail.com
push dateMon, 25 Jul 2016 16:35:44 +0000
treeherdermozilla-release@a55778f9cd5a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1190172
milestone48.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 1190172 part 9 - Clean up nsHTMLEditor::ReturnInHeader; r=ehsan
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -1566,18 +1566,17 @@ nsHTMLEditRules::WillInsertBreak(Selecti
   nsCOMPtr<Element> listItem = IsInListItem(blockParent);
   if (listItem && listItem != host) {
     ReturnInListItem(&aSelection, GetAsDOMNode(listItem), GetAsDOMNode(node),
                      offset);
     *aHandled = true;
     return NS_OK;
   } else if (nsHTMLEditUtils::IsHeader(*blockParent)) {
     // Headers: close (or split) header
-    ReturnInHeader(&aSelection, GetAsDOMNode(blockParent), GetAsDOMNode(node),
-                   offset);
+    ReturnInHeader(aSelection, *blockParent, node, offset);
     *aHandled = true;
     return NS_OK;
   } else if (blockParent->IsHTMLElement(nsGkAtoms::p)) {
     // Paragraphs: special rules to look for <br>s
     res = ReturnInParagraph(&aSelection, GetAsDOMNode(blockParent),
                             GetAsDOMNode(node), offset, aCancel, aHandled);
     NS_ENSURE_SUCCESS(res, res);
     // Fall through, we may not have handled it in ReturnInParagraph()
@@ -6245,111 +6244,95 @@ nsHTMLEditRules::IsInListItem(nsINode* a
       return parent;
     }
     parent = parent->GetParentElement();
   }
   return nullptr;
 }
 
 
-///////////////////////////////////////////////////////////////////////////
-// ReturnInHeader: do the right thing for returns pressed in headers
-//
+/**
+ * ReturnInHeader: do the right thing for returns pressed in headers
+ */
 nsresult
-nsHTMLEditRules::ReturnInHeader(Selection* aSelection,
-                                nsIDOMNode *aHeader,
-                                nsIDOMNode *aNode,
+nsHTMLEditRules::ReturnInHeader(Selection& aSelection,
+                                Element& aHeader,
+                                nsINode& aNode,
                                 int32_t aOffset)
 {
-  nsCOMPtr<Element> header = do_QueryInterface(aHeader);
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  NS_ENSURE_TRUE(aSelection && header && node, NS_ERROR_NULL_POINTER);
-
-  // remeber where the header is
-  int32_t offset;
-  nsCOMPtr<nsIDOMNode> headerParent = nsEditor::GetNodeLocation(aHeader, &offset);
-
-  // get ws code to adjust any ws
   NS_ENSURE_STATE(mHTMLEditor);
+  nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
+
+  // Remember where the header is
+  nsCOMPtr<nsINode> headerParent = aHeader.GetParentNode();
+  int32_t offset = headerParent ? headerParent->IndexOf(&aHeader) : -1;
+
+  // Get ws code to adjust any ws
+  nsCOMPtr<nsINode> node = &aNode;
   nsresult res = nsWSRunObject::PrepareToSplitAcrossBlocks(mHTMLEditor,
                                                            address_of(node),
                                                            &aOffset);
   NS_ENSURE_SUCCESS(res, res);
 
-  // split the header
+  // Split the header
   NS_ENSURE_STATE(node->IsContent());
-  NS_ENSURE_STATE(mHTMLEditor);
-  mHTMLEditor->SplitNodeDeep(*header, *node->AsContent(), aOffset);
-
-  // if the leftand heading is empty, put a mozbr in it
-  nsCOMPtr<nsIDOMNode> prevItem;
-  NS_ENSURE_STATE(mHTMLEditor);
-  mHTMLEditor->GetPriorHTMLSibling(aHeader, address_of(prevItem));
-  if (prevItem && nsHTMLEditUtils::IsHeader(prevItem))
-  {
-    bool bIsEmptyNode;
-    NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->IsEmptyNode(prevItem, &bIsEmptyNode);
+  mHTMLEditor->SplitNodeDeep(aHeader, *node->AsContent(), aOffset);
+
+  // If the left-hand heading is empty, put a mozbr in it
+  nsCOMPtr<nsIContent> prevItem = mHTMLEditor->GetPriorHTMLSibling(&aHeader);
+  if (prevItem && nsHTMLEditUtils::IsHeader(*prevItem)) {
+    bool isEmptyNode;
+    res = mHTMLEditor->IsEmptyNode(prevItem, &isEmptyNode);
     NS_ENSURE_SUCCESS(res, res);
-    if (bIsEmptyNode) {
-      res = CreateMozBR(prevItem, 0);
+    if (isEmptyNode) {
+      res = CreateMozBR(prevItem->AsDOMNode(), 0);
       NS_ENSURE_SUCCESS(res, res);
     }
   }
 
-  // if the new (righthand) header node is empty, delete it
+  // If the new (righthand) header node is empty, delete it
   bool isEmpty;
-  res = IsEmptyBlock(aHeader, &isEmpty, true);
+  res = IsEmptyBlock(aHeader.AsDOMNode(), &isEmpty, true);
   NS_ENSURE_SUCCESS(res, res);
-  if (isEmpty)
-  {
-    NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->DeleteNode(aHeader);
-    NS_ENSURE_SUCCESS(res, res);
-    // layout tells the caret to blink in a weird place
-    // if we don't place a break after the header.
-    nsCOMPtr<nsIDOMNode> sibling;
-    NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->GetNextHTMLSibling(headerParent, offset+1, address_of(sibling));
+  if (isEmpty) {
+    res = mHTMLEditor->DeleteNode(&aHeader);
     NS_ENSURE_SUCCESS(res, res);
-    if (!sibling || !nsTextEditUtils::IsBreak(sibling))
-    {
+    // Layout tells the caret to blink in a weird place if we don't place a
+    // break after the header.
+    nsCOMPtr<nsIContent> sibling =
+      mHTMLEditor->GetNextHTMLSibling(headerParent, offset + 1);
+    if (!sibling || !sibling->IsHTMLElement(nsGkAtoms::br)) {
       ClearCachedStyles();
-      NS_ENSURE_STATE(mHTMLEditor);
       mHTMLEditor->mTypeInState->ClearAllProps();
 
-      // create a paragraph
-      NS_NAMED_LITERAL_STRING(pType, "p");
-      nsCOMPtr<nsIDOMNode> pNode;
-      NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->CreateNode(pType, headerParent, offset+1, getter_AddRefs(pNode));
-      NS_ENSURE_SUCCESS(res, res);
-
-      // append a <br> to it
-      nsCOMPtr<nsIDOMNode> brNode;
-      NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->CreateBR(pNode, 0, address_of(brNode));
+      // Create a paragraph
+      nsCOMPtr<Element> pNode =
+        mHTMLEditor->CreateNode(nsGkAtoms::p, headerParent, offset + 1);
+      NS_ENSURE_STATE(pNode);
+
+      // Append a <br> to it
+      nsCOMPtr<Element> brNode = mHTMLEditor->CreateBR(pNode, 0);
+      NS_ENSURE_STATE(brNode);
+
+      // Set selection to before the break
+      res = aSelection.Collapse(pNode, 0);
       NS_ENSURE_SUCCESS(res, res);
-
-      // set selection to before the break
-      res = aSelection->Collapse(pNode, 0);
-    }
-    else
-    {
-      headerParent = nsEditor::GetNodeLocation(sibling, &offset);
-      // put selection after break
-      res = aSelection->Collapse(headerParent,offset+1);
-    }
-  }
-  else
-  {
-    // put selection at front of righthand heading
-    res = aSelection->Collapse(aHeader,0);
-  }
-  return res;
+    } else {
+      headerParent = sibling->GetParentNode();
+      offset = headerParent ? headerParent->IndexOf(sibling) : -1;
+      // Put selection after break
+      res = aSelection.Collapse(headerParent, offset + 1);
+      NS_ENSURE_SUCCESS(res, res);
+    }
+  } else {
+    // Put selection at front of righthand heading
+    res = aSelection.Collapse(&aHeader, 0);
+    NS_ENSURE_SUCCESS(res, res);
+  }
+  return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // ReturnInParagraph: do the right thing for returns pressed in paragraphs
 //
 nsresult
 nsHTMLEditRules::ReturnInParagraph(Selection* aSelection,
                                    nsIDOMNode* aPara,
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -199,18 +199,18 @@ protected:
   nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat);
   enum class Lists { no, yes };
   enum class Tables { no, yes };
   void GetInnerContent(nsINode& aNode,
                        nsTArray<mozilla::OwningNonNull<nsINode>>& aOutArrayOfNodes,
                        int32_t* aIndex, Lists aLists = Lists::yes,
                        Tables aTables = Tables::yes);
   mozilla::dom::Element* IsInListItem(nsINode* aNode);
-  nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
-                          nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
+  nsresult ReturnInHeader(mozilla::dom::Selection& aSelection,
+                          mozilla::dom::Element& aHeader, nsINode& aNode,
                           int32_t aOffset);
   nsresult ReturnInParagraph(mozilla::dom::Selection* aSelection,
                              nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
                              int32_t aOffset, bool* aCancel, bool* aHandled);
   nsresult SplitParagraph(nsIDOMNode *aPara,
                           nsIDOMNode *aBRNode,
                           mozilla::dom::Selection* aSelection,
                           nsCOMPtr<nsIDOMNode> *aSelNode,