Bug 1190172 part 10 - Clean up nsHTMLEditor::ReturnInListItem; r=ehsan
authorAryeh Gregor <ayg@aryeh.name>
Sun, 01 May 2016 16:13:15 +0300
changeset 295636 6dabbd41ffa254694a008a45517c7de38a9a3e11
parent 295635 5c3bb21481f7b51779b6f08bc39d6cb70286e457
child 295637 66bdae3372cea5dd69adbdca7c77c7f470ea5040
push id19015
push usercbook@mozilla.com
push dateMon, 02 May 2016 09:39:23 +0000
treeherderfx-team@2080375bc69d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1190172
milestone49.0a1
Bug 1190172 part 10 - Clean up nsHTMLEditor::ReturnInListItem; r=ehsan
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
editor/libeditor/nsHTMLEditor.cpp
editor/libeditor/nsHTMLEditor.h
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -1560,18 +1560,17 @@ nsHTMLEditRules::WillInsertBreak(Selecti
   if (isEmpty) {
     nsCOMPtr<Element> br = mHTMLEditor->CreateBR(blockParent,
                                                  blockParent->Length());
     NS_ENSURE_STATE(br);
   }
 
   nsCOMPtr<Element> listItem = IsInListItem(blockParent);
   if (listItem && listItem != host) {
-    ReturnInListItem(&aSelection, GetAsDOMNode(listItem), GetAsDOMNode(node),
-                     offset);
+    ReturnInListItem(aSelection, *listItem, node, offset);
     *aHandled = true;
     return NS_OK;
   } else if (nsHTMLEditUtils::IsHeader(*blockParent)) {
     // Headers: close (or split) header
     ReturnInHeader(aSelection, *blockParent, node, offset);
     *aHandled = true;
     return NS_OK;
   } else if (blockParent->IsHTMLElement(nsGkAtoms::p)) {
@@ -6551,188 +6550,170 @@ nsHTMLEditRules::SplitParagraph(nsIDOMNo
     int32_t offset;
     nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(child, &offset);
     aSelection->Collapse(parent,offset);
   }
   return res;
 }
 
 
-///////////////////////////////////////////////////////////////////////////
-// ReturnInListItem: do the right thing for returns pressed in list items
-//
+/**
+ * ReturnInListItem: do the right thing for returns pressed in list items
+ */
 nsresult
-nsHTMLEditRules::ReturnInListItem(Selection* aSelection,
-                                  nsIDOMNode *aListItem,
-                                  nsIDOMNode *aNode,
+nsHTMLEditRules::ReturnInListItem(Selection& aSelection,
+                                  Element& aListItem,
+                                  nsINode& aNode,
                                   int32_t aOffset)
 {
-  nsCOMPtr<Element> listItem = do_QueryInterface(aListItem);
-  NS_ENSURE_TRUE(aSelection && listItem && aNode, NS_ERROR_NULL_POINTER);
-  nsresult res = NS_OK;
-
-  nsCOMPtr<nsIDOMNode> listitem;
-
-  // sanity check
-  NS_PRECONDITION(true == nsHTMLEditUtils::IsListItem(aListItem),
-                  "expected a list item and didn't get one");
-
-  // get the listitem parent and the active editing host.
+  MOZ_ASSERT(nsHTMLEditUtils::IsListItem(&aListItem));
+
   NS_ENSURE_STATE(mHTMLEditor);
-  nsIContent* rootContent = mHTMLEditor->GetActiveEditingHost();
-  nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(rootContent);
-  nsCOMPtr<nsINode> list = listItem->GetParentNode();
-  int32_t itemOffset = list ? list->IndexOf(listItem) : -1;
-
-  // if we are in an empty listitem, then we want to pop up out of the list
-  // but only if prefs says it's ok and if the parent isn't the active editing host.
+  nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
+
+  // Get the item parent and the active editing host.
+  nsCOMPtr<Element> root = mHTMLEditor->GetActiveEditingHost();
+
+  nsCOMPtr<Element> list = aListItem.GetParentElement();
+  int32_t itemOffset = list ? list->IndexOf(&aListItem) : -1;
+
+  // If we are in an empty item, then we want to pop up out of the list, but
+  // only if prefs say it's okay and if the parent isn't the active editing
+  // host.
   bool isEmpty;
-  res = IsEmptyBlock(aListItem, &isEmpty, true, false);
+  nsresult res = IsEmptyBlock(aListItem.AsDOMNode(), &isEmpty, true, false);
   NS_ENSURE_SUCCESS(res, res);
-  if (isEmpty && (rootNode != GetAsDOMNode(list)) &&
-      mReturnInEmptyLIKillsList) {
-    // get the list offset now -- before we might eventually split the list
+  if (isEmpty && root != list && mReturnInEmptyLIKillsList) {
+    // Get the list offset now -- before we might eventually split the list
     nsCOMPtr<nsINode> listParent = list->GetParentNode();
     int32_t offset = listParent ? listParent->IndexOf(list) : -1;
 
-    // are we the last list item in the list?
-    bool bIsLast;
-    NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->IsLastEditableChild(aListItem, &bIsLast);
+    // Are we the last list item in the list?
+    bool isLast;
+    res = mHTMLEditor->IsLastEditableChild(aListItem.AsDOMNode(), &isLast);
     NS_ENSURE_SUCCESS(res, res);
-    if (!bIsLast)
-    {
-      // we need to split the list!
-      nsCOMPtr<nsIDOMNode> tempNode;
-      NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->SplitNode(GetAsDOMNode(list), itemOffset,
-                                   getter_AddRefs(tempNode));
-      NS_ENSURE_SUCCESS(res, res);
-    }
-
-    // are we in a sublist?
+    if (!isLast) {
+      // We need to split the list!
+      ErrorResult rv;
+      mHTMLEditor->SplitNode(*list, itemOffset, rv);
+      NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult());
+    }
+
+    // Are we in a sublist?
     if (nsHTMLEditUtils::IsList(listParent)) {
-      // if so, move this list item out of this list and into the grandparent list
-      NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->MoveNode(listItem, listParent, offset + 1);
+      // If so, move item out of this list and into the grandparent list
+      res = mHTMLEditor->MoveNode(&aListItem, listParent, offset + 1);
       NS_ENSURE_SUCCESS(res, res);
-      res = aSelection->Collapse(aListItem,0);
-    }
-    else
-    {
-      // otherwise kill this listitem
-      NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->DeleteNode(aListItem);
+      res = aSelection.Collapse(&aListItem, 0);
       NS_ENSURE_SUCCESS(res, res);
-
-      // time to insert a paragraph
-      NS_NAMED_LITERAL_STRING(pType, "p");
-      nsCOMPtr<nsIDOMNode> pNode;
-      NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->CreateNode(pType, GetAsDOMNode(listParent),
-                                    offset + 1, getter_AddRefs(pNode));
+    } else {
+      // Otherwise kill this item
+      res = mHTMLEditor->DeleteNode(&aListItem);
       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));
+      // Time to insert a paragraph
+      nsCOMPtr<Element> pNode =
+        mHTMLEditor->CreateNode(nsGkAtoms::p, listParent, 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);
-    }
-    return res;
-  }
-
-  // else we want a new list item at the same list level.
-  // get ws code to adjust any ws
-  nsCOMPtr<nsINode> selNode(do_QueryInterface(aNode));
-  NS_ENSURE_STATE(mHTMLEditor);
-  res = nsWSRunObject::PrepareToSplitAcrossBlocks(mHTMLEditor, address_of(selNode), &aOffset);
+    }
+    return NS_OK;
+  }
+
+  // Else we want a new list item at the same list level.  Get ws code to
+  // adjust any ws.
+  nsCOMPtr<nsINode> selNode = &aNode;
+  res = nsWSRunObject::PrepareToSplitAcrossBlocks(mHTMLEditor,
+                                                  address_of(selNode),
+                                                  &aOffset);
   NS_ENSURE_SUCCESS(res, res);
-  // now split list item
-  NS_ENSURE_STATE(mHTMLEditor);
+  // Now split list item
   NS_ENSURE_STATE(selNode->IsContent());
-  mHTMLEditor->SplitNodeDeep(*listItem, *selNode->AsContent(), aOffset);
-  // hack: until I can change the damaged doc range code back to being
-  // extra inclusive, I have to manually detect certain list items that
-  // may be left empty.
-  nsCOMPtr<nsIDOMNode> prevItem;
-  NS_ENSURE_STATE(mHTMLEditor);
-  mHTMLEditor->GetPriorHTMLSibling(aListItem, address_of(prevItem));
-
-  if (prevItem && nsHTMLEditUtils::IsListItem(prevItem))
-  {
-    bool bIsEmptyNode;
-    NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->IsEmptyNode(prevItem, &bIsEmptyNode);
+  mHTMLEditor->SplitNodeDeep(aListItem, *selNode->AsContent(), aOffset);
+
+  // Hack: until I can change the damaged doc range code back to being
+  // extra-inclusive, I have to manually detect certain list items that may be
+  // left empty.
+  nsCOMPtr<nsIContent> prevItem = mHTMLEditor->GetPriorHTMLSibling(&aListItem);
+  if (prevItem && nsHTMLEditUtils::IsListItem(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);
     } else {
-      NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->IsEmptyNode(aListItem, &bIsEmptyNode, true);
+      res = mHTMLEditor->IsEmptyNode(&aListItem, &isEmptyNode, true);
       NS_ENSURE_SUCCESS(res, res);
-      if (bIsEmptyNode)
-      {
-        nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(aListItem);
+      if (isEmptyNode) {
+        nsCOMPtr<nsIAtom> nodeAtom = aListItem.NodeInfo()->NameAtom();
         if (nodeAtom == nsGkAtoms::dd || nodeAtom == nsGkAtoms::dt) {
-          int32_t itemOffset;
-          nsCOMPtr<nsIDOMNode> list = nsEditor::GetNodeLocation(aListItem, &itemOffset);
-
-          nsAutoString listTag(nodeAtom == nsGkAtoms::dt
-            ? NS_LITERAL_STRING("dd") : NS_LITERAL_STRING("dt"));
-          nsCOMPtr<nsIDOMNode> newListItem;
-          NS_ENSURE_STATE(mHTMLEditor);
-          res = mHTMLEditor->CreateNode(listTag, list, itemOffset+1, getter_AddRefs(newListItem));
+          nsCOMPtr<nsINode> list = aListItem.GetParentNode();
+          int32_t itemOffset = list ? list->IndexOf(&aListItem) : -1;
+
+          nsIAtom* listAtom = nodeAtom == nsGkAtoms::dt ? nsGkAtoms::dd
+                                                        : nsGkAtoms::dt;
+          nsCOMPtr<Element> newListItem =
+            mHTMLEditor->CreateNode(listAtom, list, itemOffset + 1);
+          NS_ENSURE_STATE(newListItem);
+          res = mEditor->DeleteNode(&aListItem);
           NS_ENSURE_SUCCESS(res, res);
-          res = mEditor->DeleteNode(aListItem);
+          res = aSelection.Collapse(newListItem, 0);
           NS_ENSURE_SUCCESS(res, res);
-          return aSelection->Collapse(newListItem, 0);
+
+          return NS_OK;
         }
 
-        nsCOMPtr<nsIDOMNode> brNode;
-        NS_ENSURE_STATE(mHTMLEditor);
-        res = mHTMLEditor->CopyLastEditableChildStyles(prevItem, aListItem, getter_AddRefs(brNode));
+        nsCOMPtr<Element> brNode;
+        res = mHTMLEditor->CopyLastEditableChildStyles(GetAsDOMNode(prevItem),
+          GetAsDOMNode(&aListItem), getter_AddRefs(brNode));
         NS_ENSURE_SUCCESS(res, res);
-        if (brNode)
-        {
-          int32_t offset;
-          nsCOMPtr<nsIDOMNode> brParent = nsEditor::GetNodeLocation(brNode, &offset);
-          return aSelection->Collapse(brParent, offset);
+        if (brNode) {
+          nsCOMPtr<nsINode> brParent = brNode->GetParentNode();
+          int32_t offset = brParent ? brParent->IndexOf(brNode) : -1;
+          res = aSelection.Collapse(brParent, offset);
+          NS_ENSURE_SUCCESS(res, res);
+
+          return NS_OK;
         }
-      }
-      else
-      {
-        NS_ENSURE_STATE(mHTMLEditor);
-        nsWSRunObject wsObj(mHTMLEditor, aListItem, 0);
-        nsCOMPtr<nsINode> visNode_;
+      } else {
+        nsWSRunObject wsObj(mHTMLEditor, &aListItem, 0);
+        nsCOMPtr<nsINode> visNode;
         int32_t visOffset = 0;
         WSType wsType;
-        nsCOMPtr<nsINode> aListItem_(do_QueryInterface(aListItem));
-        wsObj.NextVisibleNode(aListItem_, 0, address_of(visNode_),
+        wsObj.NextVisibleNode(&aListItem, 0, address_of(visNode),
                               &visOffset, &wsType);
-        nsCOMPtr<nsIDOMNode> visNode(GetAsDOMNode(visNode_));
         if (wsType == WSType::special || wsType == WSType::br ||
-            nsHTMLEditUtils::IsHR(visNode)) {
-          int32_t offset;
-          nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(visNode, &offset);
-          return aSelection->Collapse(parent, offset);
+            visNode->IsHTMLElement(nsGkAtoms::hr)) {
+          nsCOMPtr<nsINode> parent = visNode->GetParentNode();
+          int32_t offset = parent ? parent->IndexOf(visNode) : -1;
+          res = aSelection.Collapse(parent, offset);
+          NS_ENSURE_SUCCESS(res, res);
+
+          return NS_OK;
+        } else {
+          res = aSelection.Collapse(visNode, visOffset);
+          NS_ENSURE_SUCCESS(res, res);
+
+          return NS_OK;
         }
-        else
-        {
-          return aSelection->Collapse(visNode, visOffset);
-        }
-      }
-    }
-  }
-  res = aSelection->Collapse(aListItem,0);
-  return res;
+      }
+    }
+  }
+  res = aSelection.Collapse(&aListItem, 0);
+  NS_ENSURE_SUCCESS(res, res);
+
+  return NS_OK;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////////
 // MakeBlockquote: Put the list of nodes into one or more blockquotes.
 //
 nsresult
 nsHTMLEditRules::MakeBlockquote(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -211,18 +211,19 @@ protected:
   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,
                           int32_t *aOffset);
-  nsresult ReturnInListItem(mozilla::dom::Selection* aSelection,
-                            nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
+  nsresult ReturnInListItem(mozilla::dom::Selection& aSelection,
+                            mozilla::dom::Element& aHeader,
+                            nsINode& aNode,
                             int32_t aOffset);
   nsresult AfterEditInner(EditAction action,
                           nsIEditor::EDirection aDirection);
   nsresult RemovePartOfBlock(mozilla::dom::Element& aBlock,
                              nsIContent& aStartChild,
                              nsIContent& aEndChild);
   nsresult SplitBlock(nsIDOMNode *aBlock,
                       nsIDOMNode *aStartChild,
--- a/editor/libeditor/nsHTMLEditor.cpp
+++ b/editor/libeditor/nsHTMLEditor.cpp
@@ -4714,17 +4714,17 @@ nsHTMLEditor::AreNodesSameType(nsIConten
 
   // If CSS is enabled, we are stricter about span nodes.
   return mHTMLCSSUtils->ElementsSameStyle(aNode1->AsDOMNode(),
                                           aNode2->AsDOMNode());
 }
 
 nsresult
 nsHTMLEditor::CopyLastEditableChildStyles(nsIDOMNode * aPreviousBlock, nsIDOMNode * aNewBlock,
-                                          nsIDOMNode **aOutBrNode)
+                                          Element** aOutBrNode)
 {
   nsCOMPtr<nsINode> newBlock = do_QueryInterface(aNewBlock);
   NS_ENSURE_STATE(newBlock || !aNewBlock);
   *aOutBrNode = nullptr;
   nsCOMPtr<nsIDOMNode> child, tmp;
   nsresult res;
   // first, clear out aNewBlock.  Contract is that we want only the styles from previousBlock.
   res = aNewBlock->GetFirstChild(getter_AddRefs(child));
@@ -4768,17 +4768,17 @@ nsHTMLEditor::CopyLastEditableChildStyle
           CreateNode(childElement->NodeInfo()->NameAtom(), newBlock, 0);
         NS_ENSURE_STATE(newStyles);
       }
       CloneAttributes(newStyles, childElement);
     }
     childElement = childElement->GetParentElement();
   }
   if (deepestStyle) {
-    *aOutBrNode = GetAsDOMNode(CreateBR(deepestStyle, 0));
+    *aOutBrNode = CreateBR(deepestStyle, 0);
     NS_ENSURE_STATE(*aOutBrNode);
   }
   return NS_OK;
 }
 
 nsresult
 nsHTMLEditor::GetElementOrigin(nsIDOMElement * aElement, int32_t & aX, int32_t & aY)
 {
--- a/editor/libeditor/nsHTMLEditor.h
+++ b/editor/libeditor/nsHTMLEditor.h
@@ -138,17 +138,17 @@ public:
   NS_DECL_NSIHTMLABSPOSEDITOR
 
   /* ------------ nsIHTMLInlineTableEditor methods -------------- */
   /* ------- Implemented in nsHTMLInlineTableEditor.cpp --------- */
   NS_DECL_NSIHTMLINLINETABLEEDITOR
 
   /* ------------ nsIHTMLEditor methods -------------- */
   nsresult CopyLastEditableChildStyles(nsIDOMNode *aPreviousBlock, nsIDOMNode *aNewBlock,
-                                         nsIDOMNode **aOutBrNode);
+                                       mozilla::dom::Element** aOutBrNode);
 
   nsresult LoadHTML(const nsAString &aInputString);
 
   nsresult GetCSSBackgroundColorState(bool *aMixed, nsAString &aOutColor,
                                       bool aBlockLevel);
   NS_IMETHOD GetHTMLBackgroundColorState(bool *aMixed, nsAString &outColor);
 
   /* ------------ nsIEditorStyleSheets methods -------------- */