Bug 1191354 part 13 - Clean up nsHTMLEditRules::SplitBlock; r=ehsan
authorAryeh Gregor <ayg@aryeh.name>
Sun, 01 May 2016 16:16:15 +0300
changeset 295651 a5a4a49c518861102961a40b642eaff00264c533
parent 295650 5896fcd5c10ab630fdf63519bdd6410001806879
child 295652 e9c7181b7bb448768fd0e1f4370cf487445af118
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 13 - Clean up nsHTMLEditRules::SplitBlock; r=ehsan
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -4218,116 +4218,92 @@ nsHTMLEditRules::WillOutdent(Selection& 
 ///////////////////////////////////////////////////////////////////////////////
 // RemovePartOfBlock: Split aBlock and move aStartChild to aEndChild out of
 //                    aBlock.
 nsresult
 nsHTMLEditRules::RemovePartOfBlock(Element& aBlock,
                                    nsIContent& aStartChild,
                                    nsIContent& aEndChild)
 {
-  nsresult res = SplitBlock(aBlock.AsDOMNode(), aStartChild.AsDOMNode(),
-                            aEndChild.AsDOMNode());
-  NS_ENSURE_SUCCESS(res, res);
+  SplitBlock(aBlock, aStartChild, aEndChild);
   // Get rid of part of blockquote we are outdenting
 
   NS_ENSURE_STATE(mHTMLEditor);
-  return mHTMLEditor->RemoveBlockContainer(aBlock.AsDOMNode());
-}
-
-nsresult
-nsHTMLEditRules::SplitBlock(nsIDOMNode *aBlock,
-                            nsIDOMNode *aStartChild,
-                            nsIDOMNode *aEndChild,
-                            nsCOMPtr<nsIDOMNode> *aLeftNode,
-                            nsCOMPtr<nsIDOMNode> *aRightNode,
-                            nsCOMPtr<nsIDOMNode> *aMiddleNode)
-{
-  NS_ENSURE_TRUE(aBlock && aStartChild && aEndChild, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIContent> leftNode, rightNode;
-  int32_t startOffset, endOffset;
-
-  // get split point location
-  nsCOMPtr<nsIDOMNode> startParent = nsEditor::GetNodeLocation(aStartChild, &startOffset);
-
-  // do the splits!
-  nsCOMPtr<nsIContent> block = do_QueryInterface(aBlock);
-  NS_ENSURE_STATE(block || !aBlock);
-  nsCOMPtr<nsIContent> startParentContent = do_QueryInterface(startParent);
-  NS_ENSURE_STATE(startParentContent || !startParent);
-  NS_ENSURE_STATE(mHTMLEditor);
-  mHTMLEditor->SplitNodeDeep(*block, *startParentContent, startOffset,
-                             nsHTMLEditor::EmptyContainers::no,
-                             getter_AddRefs(leftNode),
-                             getter_AddRefs(rightNode));
-  if (rightNode) {
-    aBlock = GetAsDOMNode(rightNode);
-  }
-
-  // remember left portion of block if caller requested
-  if (aLeftNode)
-    *aLeftNode = GetAsDOMNode(leftNode);
-
-  // get split point location
-  nsCOMPtr<nsIDOMNode> endParent = nsEditor::GetNodeLocation(aEndChild, &endOffset);
-  endOffset++;  // want to be after lastBQChild
-
-  // do the splits!
-  nsCOMPtr<nsIContent> endParentContent = do_QueryInterface(endParent);
-  NS_ENSURE_STATE(endParentContent || !endParent);
-  NS_ENSURE_STATE(mHTMLEditor);
-  mHTMLEditor->SplitNodeDeep(*block, *endParentContent, endOffset,
-                             nsHTMLEditor::EmptyContainers::no,
-                             getter_AddRefs(leftNode),
-                             getter_AddRefs(rightNode));
-  if (leftNode) {
-    aBlock = GetAsDOMNode(leftNode);
-  }
-
-  // remember right portion of block if caller requested
-  if (aRightNode)
-    *aRightNode = GetAsDOMNode(rightNode);
-
-  if (aMiddleNode)
-    *aMiddleNode = aBlock;
+  nsresult res = mHTMLEditor->RemoveBlockContainer(aBlock.AsDOMNode());
+  NS_ENSURE_SUCCESS(res, res);
 
   return NS_OK;
 }
 
+void
+nsHTMLEditRules::SplitBlock(Element& aBlock,
+                            nsIContent& aStartChild,
+                            nsIContent& aEndChild,
+                            nsIContent** aOutLeftNode,
+                            nsIContent** aOutRightNode,
+                            nsIContent** aOutMiddleNode)
+{
+  // aStartChild and aEndChild must be exclusive descendants of aBlock
+  MOZ_ASSERT(nsEditorUtils::IsDescendantOf(&aStartChild, &aBlock) &&
+             nsEditorUtils::IsDescendantOf(&aEndChild, &aBlock));
+  NS_ENSURE_TRUE_VOID(mHTMLEditor);
+  nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
+
+  // Get split point location
+  OwningNonNull<nsIContent> startParent = *aStartChild.GetParent();
+  int32_t startOffset = startParent->IndexOf(&aStartChild);
+
+  // Do the splits!
+  nsCOMPtr<nsIContent> newMiddleNode1;
+  mHTMLEditor->SplitNodeDeep(aBlock, startParent, startOffset,
+                             nsHTMLEditor::EmptyContainers::no,
+                             aOutLeftNode, getter_AddRefs(newMiddleNode1));
+
+  // Get split point location
+  OwningNonNull<nsIContent> endParent = *aEndChild.GetParent();
+  // +1 because we want to be after the child
+  int32_t endOffset = 1 + endParent->IndexOf(&aEndChild);
+
+  // Do the splits!
+  nsCOMPtr<nsIContent> newMiddleNode2;
+  mHTMLEditor->SplitNodeDeep(aBlock, endParent, endOffset,
+                             nsHTMLEditor::EmptyContainers::no,
+                             getter_AddRefs(newMiddleNode2), aOutRightNode);
+
+  if (aOutMiddleNode) {
+    if (newMiddleNode2) {
+      newMiddleNode2.forget(aOutMiddleNode);
+    } else {
+      newMiddleNode1.forget(aOutMiddleNode);
+    }
+  }
+}
+
 nsresult
 nsHTMLEditRules::OutdentPartOfBlock(Element& aBlock,
                                     nsIContent& aStartChild,
                                     nsIContent& aEndChild,
                                     bool aIsBlockIndentedWithCSS,
                                     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);
+  nsCOMPtr<nsIContent> middleNode;
+  SplitBlock(aBlock, aStartChild, aEndChild, aOutLeftNode, aOutRightNode,
+             getter_AddRefs(middleNode));
 
   if (aIsBlockIndentedWithCSS) {
-    res = RelativeChangeIndentationOfElementNode(middleNodeDOM, -1);
+    nsresult res =
+      RelativeChangeIndentationOfElementNode(GetAsDOMNode(middleNode), -1);
     NS_ENSURE_SUCCESS(res, res);
   } else {
     NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->RemoveBlockContainer(middleNodeDOM);
+    nsresult res =
+      mHTMLEditor->RemoveBlockContainer(GetAsDOMNode(middleNode));
     NS_ENSURE_SUCCESS(res, res);
   }
 
   return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // ConvertListType:  convert list type and list item type.
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -204,22 +204,22 @@ protected:
                           nsCOMPtr<nsIDOMNode> *aSelNode,
                           int32_t *aOffset);
   nsresult ReturnInListItem(Selection& aSelection, Element& aHeader,
                             nsINode& aNode, int32_t aOffset);
   nsresult AfterEditInner(EditAction action,
                           nsIEditor::EDirection aDirection);
   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);
+  void     SplitBlock(Element& aBlock,
+                      nsIContent& aStartChild,
+                      nsIContent& aEndChild,
+                      nsIContent** aOutLeftNode = nullptr,
+                      nsIContent** aOutRightNode = nullptr,
+                      nsIContent** aOutMiddleNode = nullptr);
   nsresult OutdentPartOfBlock(Element& aBlock,
                               nsIContent& aStartChild,
                               nsIContent& aEndChild,
                               bool aIsBlockIndentedWithCSS,
                               nsIContent** aOutLeftNode,
                               nsIContent** aOutRightNode);
 
   nsresult ConvertListType(Element* aList, Element** aOutList,