Bug 1191354 part 12 - Clean up nsHTMLEditRules::OutdentPartOfBlock; r=ehsan
authorAryeh Gregor <ayg@aryeh.name>
Sun, 01 May 2016 16:16:03 +0300
changeset 295650 5896fcd5c10ab630fdf63519bdd6410001806879
parent 295649 3739ead5ce63c9cdec7a3b7fc11ade4c37efacbd
child 295651 a5a4a49c518861102961a40b642eaff00264c533
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
bugs1191354
milestone49.0a1
Bug 1191354 part 12 - Clean up nsHTMLEditRules::OutdentPartOfBlock; r=ehsan
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -3959,17 +3959,17 @@ nsHTMLEditRules::WillHTMLIndent(Selectio
 
 nsresult
 nsHTMLEditRules::WillOutdent(Selection& aSelection,
                              bool* aCancel, bool* aHandled)
 {
   MOZ_ASSERT(aCancel && aHandled);
   *aCancel = false;
   *aHandled = true;
-  nsCOMPtr<nsIDOMNode> rememberedLeftBQ, rememberedRightBQ;
+  nsCOMPtr<nsIContent> rememberedLeftBQ, rememberedRightBQ;
   NS_ENSURE_STATE(mHTMLEditor);
   nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
   bool useCSS = mHTMLEditor->IsCSSEnabled();
 
   nsresult res = NormalizeSelection(&aSelection);
   NS_ENSURE_SUCCESS(res, res);
 
   // Some scoping for selection resetting - we may need to tweak it
@@ -4001,22 +4001,20 @@ nsHTMLEditRules::WillOutdent(Selection& 
       nsCOMPtr<nsINode> curParent = curNode->GetParentNode();
       int32_t offset = curParent ? curParent->IndexOf(curNode) : -1;
 
       // Is it a blockquote?
       if (curNode->IsHTMLElement(nsGkAtoms::blockquote)) {
         // If it is a blockquote, remove it.  So we need to finish up dealng
         // with any curBlockQuote first.
         if (curBlockQuote) {
-          res = OutdentPartOfBlock(GetAsDOMNode(curBlockQuote),
-                                   GetAsDOMNode(firstBQChild),
-                                   GetAsDOMNode(lastBQChild),
+          res = OutdentPartOfBlock(*curBlockQuote, *firstBQChild, *lastBQChild,
                                    curBlockQuoteIsIndentedWithCSS,
-                                   address_of(rememberedLeftBQ),
-                                   address_of(rememberedRightBQ));
+                                   getter_AddRefs(rememberedLeftBQ),
+                                   getter_AddRefs(rememberedRightBQ));
           NS_ENSURE_SUCCESS(res, res);
           curBlockQuote = nullptr;
           firstBQChild = nullptr;
           lastBQChild = nullptr;
           curBlockQuoteIsIndentedWithCSS = false;
         }
         res = mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(curNode));
         NS_ENSURE_SUCCESS(res, res);
@@ -4040,22 +4038,20 @@ nsHTMLEditRules::WillOutdent(Selection& 
         }
       }
       // Is it a list item?
       if (nsHTMLEditUtils::IsListItem(curNode)) {
         // If it is a list item, that means we are not outdenting whole list.
         // So we need to finish up dealing with any curBlockQuote, and then pop
         // this list item.
         if (curBlockQuote) {
-          res = OutdentPartOfBlock(GetAsDOMNode(curBlockQuote),
-                                   GetAsDOMNode(firstBQChild),
-                                   GetAsDOMNode(lastBQChild),
+          res = OutdentPartOfBlock(*curBlockQuote, *firstBQChild, *lastBQChild,
                                    curBlockQuoteIsIndentedWithCSS,
-                                   address_of(rememberedLeftBQ),
-                                   address_of(rememberedRightBQ));
+                                   getter_AddRefs(rememberedLeftBQ),
+                                   getter_AddRefs(rememberedRightBQ));
           NS_ENSURE_SUCCESS(res, res);
           curBlockQuote = nullptr;
           firstBQChild = nullptr;
           lastBQChild = nullptr;
           curBlockQuoteIsIndentedWithCSS = false;
         }
         bool unused;
         res = PopListItem(GetAsDOMNode(curNode), &unused);
@@ -4068,22 +4064,21 @@ nsHTMLEditRules::WillOutdent(Selection& 
         if (nsEditorUtils::IsDescendantOf(curNode, curBlockQuote)) {
           lastBQChild = curNode;
           // Then we don't need to do anything different for this node
           continue;
         } else {
           // Otherwise, we have progressed beyond end of curBlockQuote, so
           // let's handle it now.  We need to remove the portion of
           // curBlockQuote that contains [firstBQChild - lastBQChild].
-          res = OutdentPartOfBlock(GetAsDOMNode(curBlockQuote),
-                                   GetAsDOMNode(firstBQChild),
-                                   GetAsDOMNode(lastBQChild),
+          res = OutdentPartOfBlock(*curBlockQuote, *firstBQChild,
+                                   *lastBQChild,
                                    curBlockQuoteIsIndentedWithCSS,
-                                   address_of(rememberedLeftBQ),
-                                   address_of(rememberedRightBQ));
+                                   getter_AddRefs(rememberedLeftBQ),
+                                   getter_AddRefs(rememberedRightBQ));
           NS_ENSURE_SUCCESS(res, res);
           curBlockQuote = nullptr;
           firstBQChild = nullptr;
           lastBQChild = nullptr;
           curBlockQuoteIsIndentedWithCSS = false;
           // Fall out and handle curNode
         }
       }
@@ -4174,54 +4169,49 @@ nsHTMLEditRules::WillOutdent(Selection& 
           if (element) {
             RelativeChangeIndentationOfElementNode(element->AsDOMNode(), -1);
           }
         }
       }
     }
     if (curBlockQuote) {
       // We have a blockquote we haven't finished handling
-      res = OutdentPartOfBlock(GetAsDOMNode(curBlockQuote),
-                               GetAsDOMNode(firstBQChild),
-                               GetAsDOMNode(lastBQChild),
+      res = OutdentPartOfBlock(*curBlockQuote, *firstBQChild, *lastBQChild,
                                curBlockQuoteIsIndentedWithCSS,
-                               address_of(rememberedLeftBQ),
-                               address_of(rememberedRightBQ));
+                               getter_AddRefs(rememberedLeftBQ),
+                               getter_AddRefs(rememberedRightBQ));
       NS_ENSURE_SUCCESS(res, res);
     }
   }
   // Make sure selection didn't stick to last piece of content in old bq (only
   // a problem for collapsed selections)
   if (rememberedLeftBQ || rememberedRightBQ) {
     if (aSelection.Collapsed()) {
       // Push selection past end of rememberedLeftBQ
       NS_ENSURE_TRUE(aSelection.GetRangeAt(0), NS_OK);
       nsCOMPtr<nsINode> startNode = aSelection.GetRangeAt(0)->GetStartParent();
       int32_t startOffset = aSelection.GetRangeAt(0)->StartOffset();
       if (rememberedLeftBQ &&
-          (GetAsDOMNode(startNode) == rememberedLeftBQ ||
-           nsEditorUtils::IsDescendantOf(GetAsDOMNode(startNode),
-                                         rememberedLeftBQ))) {
+          (startNode == rememberedLeftBQ ||
+           nsEditorUtils::IsDescendantOf(startNode, rememberedLeftBQ))) {
         // Selection is inside rememberedLeftBQ - push it past it.
-        nsCOMPtr<nsIDOMNode> startNodeDOM =
-          nsEditor::GetNodeLocation(rememberedLeftBQ, &startOffset);
-        startOffset++;
-        aSelection.Collapse(startNodeDOM, startOffset);
+        startNode = rememberedLeftBQ->GetParentNode();
+        startOffset = startNode ? 1 + startNode->IndexOf(rememberedLeftBQ) : 0;
+        aSelection.Collapse(startNode, startOffset);
       }
       // And pull selection before beginning of rememberedRightBQ
       startNode = aSelection.GetRangeAt(0)->GetStartParent();
       startOffset = aSelection.GetRangeAt(0)->StartOffset();
       if (rememberedRightBQ &&
-          (GetAsDOMNode(startNode) == rememberedRightBQ ||
-           nsEditorUtils::IsDescendantOf(GetAsDOMNode(startNode),
-                                         rememberedRightBQ))) {
+          (startNode == rememberedRightBQ ||
+           nsEditorUtils::IsDescendantOf(startNode, rememberedRightBQ))) {
         // Selection is inside rememberedRightBQ - push it before it.
-        nsCOMPtr<nsIDOMNode> startNodeDOM =
-          nsEditor::GetNodeLocation(rememberedRightBQ, &startOffset);
-        aSelection.Collapse(startNodeDOM, startOffset);
+        startNode = rememberedRightBQ->GetParentNode();
+        startOffset = startNode ? startNode->IndexOf(rememberedRightBQ) : -1;
+        aSelection.Collapse(startNode, startOffset);
       }
     }
     return NS_OK;
   }
   return NS_OK;
 }
 
 
@@ -4298,36 +4288,50 @@ nsHTMLEditRules::SplitBlock(nsIDOMNode *
 
   if (aMiddleNode)
     *aMiddleNode = aBlock;
 
   return NS_OK;
 }
 
 nsresult
-nsHTMLEditRules::OutdentPartOfBlock(nsIDOMNode *aBlock,
-                                    nsIDOMNode *aStartChild,
-                                    nsIDOMNode *aEndChild,
+nsHTMLEditRules::OutdentPartOfBlock(Element& aBlock,
+                                    nsIContent& aStartChild,
+                                    nsIContent& aEndChild,
                                     bool aIsBlockIndentedWithCSS,
-                                    nsCOMPtr<nsIDOMNode> *aLeftNode,
-                                    nsCOMPtr<nsIDOMNode> *aRightNode)
-{
-  nsCOMPtr<nsIDOMNode> middleNode;
-  nsresult res = SplitBlock(aBlock, aStartChild, aEndChild,
-                            aLeftNode,
-                            aRightNode,
-                            address_of(middleNode));
+                                    nsIContent** aOutLeftNode,
+                                    nsIContent** aOutRightNode)
+{
+  MOZ_ASSERT(aOutLeftNode && aOutRightNode);
+
+  nsCOMPtr<nsIDOMNode> leftNodeDOM, rightNodeDOM, middleNodeDOM;
+  nsresult res = SplitBlock(aBlock.AsDOMNode(), aStartChild.AsDOMNode(),
+                            aEndChild.AsDOMNode(), address_of(leftNodeDOM),
+                            address_of(rightNodeDOM),
+                            address_of(middleNodeDOM));
   NS_ENSURE_SUCCESS(res, res);
+
+  nsCOMPtr<nsIContent> leftNode = do_QueryInterface(leftNodeDOM);
+  NS_ENSURE_STATE(leftNode || !leftNodeDOM);
+  leftNode.forget(aOutLeftNode);
+
+  nsCOMPtr<nsIContent> rightNode = do_QueryInterface(rightNodeDOM);
+  NS_ENSURE_STATE(rightNode || !rightNodeDOM);
+  rightNode.forget(aOutRightNode);
+
   if (aIsBlockIndentedWithCSS) {
-    res = RelativeChangeIndentationOfElementNode(middleNode, -1);
+    res = RelativeChangeIndentationOfElementNode(middleNodeDOM, -1);
+    NS_ENSURE_SUCCESS(res, res);
   } else {
     NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->RemoveBlockContainer(middleNode);
-  }
-  return res;
+    res = mHTMLEditor->RemoveBlockContainer(middleNodeDOM);
+    NS_ENSURE_SUCCESS(res, res);
+  }
+
+  return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // ConvertListType:  convert list type and list item type.
 //
 //
 nsresult
 nsHTMLEditRules::ConvertListType(Element* aList,
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -210,22 +210,22 @@ protected:
   nsresult RemovePartOfBlock(Element& aBlock, nsIContent& aStartChild,
                              nsIContent& aEndChild);
   nsresult SplitBlock(nsIDOMNode *aBlock,
                       nsIDOMNode *aStartChild,
                       nsIDOMNode *aEndChild,
                       nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
                       nsCOMPtr<nsIDOMNode> *aRightNode = 0,
                       nsCOMPtr<nsIDOMNode> *aMiddleNode = 0);
-  nsresult OutdentPartOfBlock(nsIDOMNode *aBlock,
-                              nsIDOMNode *aStartChild,
-                              nsIDOMNode *aEndChild,
+  nsresult OutdentPartOfBlock(Element& aBlock,
+                              nsIContent& aStartChild,
+                              nsIContent& aEndChild,
                               bool aIsBlockIndentedWithCSS,
-                              nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
-                              nsCOMPtr<nsIDOMNode> *aRightNode = 0);
+                              nsIContent** aOutLeftNode,
+                              nsIContent** aOutRightNode);
 
   nsresult ConvertListType(Element* aList, Element** aOutList,
                            nsIAtom* aListType, nsIAtom* aItemType);
 
   nsresult CreateStyleForInsertText(Selection& aSelection, nsIDocument& aDoc);
   enum class MozBRCounts { yes, no };
   nsresult IsEmptyBlock(Element& aNode, bool* aOutIsEmptyBlock,
                         MozBRCounts aMozBRCounts = MozBRCounts::yes);