Bug 1149163 part 2 - Make nsDOMIterator infallible; r=froydnj
☠☠ backed out by 329dd852c06b ☠ ☠
authorAryeh Gregor <ayg@aryeh.name>
Wed, 22 Apr 2015 14:26:57 +0300
changeset 240497 bc75a87a2b7d47a26e832682c13841ea7b97703f
parent 240496 4392cf02f1c07e79475cb621c861aa8efa6912e4
child 240498 2817e4601371992a3fafd859c33dc5c57a8b34e3
push id28636
push userkwierso@gmail.com
push dateThu, 23 Apr 2015 00:16:12 +0000
treeherdermozilla-central@a5af73b32ac8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1149163
milestone40.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 1149163 part 2 - Make nsDOMIterator infallible; r=froydnj
editor/libeditor/nsEditorUtils.cpp
editor/libeditor/nsEditorUtils.h
editor/libeditor/nsHTMLDataTransfer.cpp
editor/libeditor/nsHTMLEditRules.cpp
--- a/editor/libeditor/nsEditorUtils.cpp
+++ b/editor/libeditor/nsEditorUtils.cpp
@@ -61,101 +61,79 @@ nsAutoSelectionReset::Abort()
     mEd->StopPreservingSelection();
 }
 
 
 /******************************************************************************
  * some helper classes for iterating the dom tree
  *****************************************************************************/
 
-nsDOMIterator::nsDOMIterator() :
-mIter(nullptr)
+nsDOMIterator::nsDOMIterator(nsRange& aRange)
+{
+  MOZ_ASSERT(aRange.GetStartParent(), "Invalid range");
+  mIter = NS_NewContentIterator();
+  DebugOnly<nsresult> res = mIter->Init(&aRange);
+  MOZ_ASSERT(NS_SUCCEEDED(res));
+}
+
+nsDOMIterator::nsDOMIterator(nsIDOMNode& aNode)
+{
+  mIter = NS_NewContentIterator();
+  nsCOMPtr<nsINode> node = do_QueryInterface(&aNode);
+  NS_ENSURE_TRUE(node, );
+  DebugOnly<nsresult> res = mIter->Init(node);
+  MOZ_ASSERT(NS_SUCCEEDED(res));
+}
+
+nsDOMIterator::nsDOMIterator()
 {
 }
-    
+
 nsDOMIterator::~nsDOMIterator()
 {
 }
-    
-nsresult
-nsDOMIterator::Init(nsRange* aRange)
-{
-  nsresult res;
-  mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
-  return mIter->Init(aRange);
-}
 
-nsresult
-nsDOMIterator::Init(nsIDOMNode* aNode)
-{
-  nsresult res;
-  mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
-  return mIter->Init(content);
-}
-
-nsresult
+void
 nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor,
                           nsTArray<nsCOMPtr<nsINode>>& arrayOfNodes) const
 {
   // Iterate through dom and build list
-  while (!mIter->IsDone()) {
+  for (; !mIter->IsDone(); mIter->Next()) {
     nsCOMPtr<nsINode> node = mIter->GetCurrentNode();
-    NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
 
     if (functor(node)) {
       arrayOfNodes.AppendElement(node);
     }
-    mIter->Next();
   }
-  return NS_OK;
 }
 
-nsresult
+void
 nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor,
                           nsCOMArray<nsIDOMNode>& arrayOfNodes) const
 {
-  nsCOMPtr<nsIDOMNode> node;
-  
   // iterate through dom and build list
-  while (!mIter->IsDone())
-  {
-    node = do_QueryInterface(mIter->GetCurrentNode());
-    NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
+  for (; !mIter->IsDone(); mIter->Next()) {
+    nsCOMPtr<nsIDOMNode> node = mIter->GetCurrentNode()->AsDOMNode();
 
-    if (functor(node))
-    {
+    if (functor(node)) {
       arrayOfNodes.AppendObject(node);
     }
-    mIter->Next();
   }
-  return NS_OK;
 }
 
-nsDOMSubtreeIterator::nsDOMSubtreeIterator()
+nsDOMSubtreeIterator::nsDOMSubtreeIterator(nsRange& aRange)
 {
+  mIter = NS_NewContentSubtreeIterator();
+  DebugOnly<nsresult> res = mIter->Init(&aRange);
+  MOZ_ASSERT(NS_SUCCEEDED(res));
 }
-    
+
 nsDOMSubtreeIterator::~nsDOMSubtreeIterator()
 {
 }
-    
-nsresult
-nsDOMSubtreeIterator::Init(nsRange* aRange)
-{
-  nsresult res;
-  mIter = do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
-  return mIter->Init(aRange);
-}
 
 /******************************************************************************
  * some general purpose editor utils
  *****************************************************************************/
 
 bool
 nsEditorUtils::IsDescendantOf(nsINode* aNode, nsINode* aParent, int32_t* aOffset)
 {
--- a/editor/libeditor/nsEditorUtils.h
+++ b/editor/libeditor/nsEditorUtils.h
@@ -172,36 +172,36 @@ class nsBoolDomIterFunctor
     {
       return operator()(GetAsDOMNode(aNode));
     }
 };
 
 class MOZ_STACK_CLASS nsDOMIterator
 {
   public:
-    nsDOMIterator();
+    explicit nsDOMIterator(nsRange& aRange);
+    explicit nsDOMIterator(nsIDOMNode& aNode);
     virtual ~nsDOMIterator();
-    
-    nsresult Init(nsRange* aRange);
-    nsresult Init(nsIDOMNode* aNode);
-    nsresult AppendList(nsBoolDomIterFunctor& functor,
-                        nsTArray<nsCOMPtr<nsINode>>& arrayOfNodes) const;
-    nsresult AppendList(nsBoolDomIterFunctor& functor,
-                        nsCOMArray<nsIDOMNode>& arrayOfNodes) const;
+
+    void AppendList(nsBoolDomIterFunctor& functor,
+                    nsTArray<nsCOMPtr<nsINode>>& arrayOfNodes) const;
+    void AppendList(nsBoolDomIterFunctor& functor,
+                    nsCOMArray<nsIDOMNode>& arrayOfNodes) const;
   protected:
     nsCOMPtr<nsIContentIterator> mIter;
+
+    // For nsDOMSubtreeIterator
+    nsDOMIterator();
 };
 
 class MOZ_STACK_CLASS nsDOMSubtreeIterator : public nsDOMIterator
 {
   public:
-    nsDOMSubtreeIterator();
+    explicit nsDOMSubtreeIterator(nsRange& aRange);
     virtual ~nsDOMSubtreeIterator();
-
-    nsresult Init(nsRange* aRange);
 };
 
 class nsTrivialFunctor : public nsBoolDomIterFunctor
 {
   public:
     virtual bool operator()(nsIDOMNode* aNode)  // used to build list of all nodes iterator covers
     {
       return true;
--- a/editor/libeditor/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/nsHTMLDataTransfer.cpp
@@ -2192,21 +2192,20 @@ nsresult nsHTMLEditor::CreateListOfNodes
   }
 
   nsRefPtr<nsRange> docFragRange;
   rv = nsRange::CreateRange(aStartNode, aStartOffset, aEndNode, aEndOffset, getter_AddRefs(docFragRange));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // now use a subtree iterator over the range to create a list of nodes
   nsTrivialFunctor functor;
-  nsDOMSubtreeIterator iter;
-  rv = iter.Init(docFragRange);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsDOMSubtreeIterator iter(*docFragRange);
+  iter.AppendList(functor, outNodeList);
 
-  return iter.AppendList(functor, outNodeList);
+  return NS_OK;
 }
 
 nsresult
 nsHTMLEditor::GetListAndTableParents(bool aEnd,
                                      nsCOMArray<nsIDOMNode>& aListOfNodes,
                                      nsCOMArray<nsIDOMNode>& outArray)
 {
   int32_t listCount = aListOfNodes.Count();
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -2435,21 +2435,18 @@ nsHTMLEditRules::WillDeleteSelection(Sel
 
         uint32_t rangeCount = aSelection->RangeCount();
         for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
           OwningNonNull<nsRange> range = *aSelection->GetRangeAt(rangeIdx);
 
           // Build a list of nodes in the range
           nsTArray<nsCOMPtr<nsINode>> arrayOfNodes;
           nsTrivialFunctor functor;
-          nsDOMSubtreeIterator iter;
-          res = iter.Init(range);
-          NS_ENSURE_SUCCESS(res, res);
-          res = iter.AppendList(functor, arrayOfNodes);
-          NS_ENSURE_SUCCESS(res, res);
+          nsDOMSubtreeIterator iter(*range);
+          iter.AppendList(functor, arrayOfNodes);
 
           // Now that we have the list, delete non-table elements
           int32_t listCount = arrayOfNodes.Length();
           for (int32_t j = 0; j < listCount; j++) {
             nsCOMPtr<nsINode> somenode = do_QueryInterface(arrayOfNodes[0]);
             NS_ENSURE_STATE(somenode);
             DeleteNonTableElements(somenode);
             arrayOfNodes.RemoveElementAt(0);
@@ -4928,21 +4925,18 @@ nsresult
 nsHTMLEditRules::AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType)
 {
   NS_ENSURE_TRUE(aNode && alignType, NS_ERROR_NULL_POINTER);
   nsresult res;
   
   // gather list of table cells or list items
   nsCOMArray<nsIDOMNode> arrayOfNodes;
   nsTableCellAndListItemFunctor functor;
-  nsDOMIterator iter;
-  res = iter.Init(aNode);
-  NS_ENSURE_SUCCESS(res, res);
-  res = iter.AppendList(functor, arrayOfNodes);
-  NS_ENSURE_SUCCESS(res, res);
+  nsDOMIterator iter(*aNode);
+  iter.AppendList(functor, arrayOfNodes);
   
   // now that we have the list, align their contents as requested
   int32_t listCount = arrayOfNodes.Count();
   int32_t j;
 
   for (j = 0; j < listCount; j++)
   {
     nsIDOMNode* node = arrayOfNodes[0];
@@ -5934,32 +5928,28 @@ nsHTMLEditRules::GetNodesForOperation(ns
     }
     NS_ENSURE_SUCCESS(res, res);
   }
   // gather up a list of all the nodes
   for (i = 0; i < rangeCount; i++)
   {
     opRange = inArrayOfRanges[i];
     
-    nsDOMSubtreeIterator iter;
-    res = iter.Init(opRange);
-    NS_ENSURE_SUCCESS(res, res);
+    nsDOMSubtreeIterator iter(*opRange);
     if (outArrayOfNodes.Count() == 0) {
       nsTrivialFunctor functor;
-      res = iter.AppendList(functor, outArrayOfNodes);
-      NS_ENSURE_SUCCESS(res, res);    
+      iter.AppendList(functor, outArrayOfNodes);
     }
     else {
       // We don't want duplicates in outArrayOfNodes, so we use an
       // iterator/functor that only return nodes that are not already in
       // outArrayOfNodes.
       nsCOMArray<nsIDOMNode> nodes;
       nsUniqueFunctor functor(outArrayOfNodes);
-      res = iter.AppendList(functor, nodes);
-      NS_ENSURE_SUCCESS(res, res);
+      iter.AppendList(functor, nodes);
       if (!outArrayOfNodes.AppendObjects(nodes))
         return NS_ERROR_OUT_OF_MEMORY;
     }
   }    
 
   // certain operations should not act on li's and td's, but rather inside 
   // them.  alter the list as needed
   if (inOperationType == EditAction::makeBasicBlock) {
@@ -6339,21 +6329,18 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsID
 {
   nsCOMPtr<nsINode> node = do_QueryInterface(inNode);
   NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
 
   // first step is to build up a list of all the break nodes inside 
   // the inline container.
   nsCOMArray<nsIDOMNode> arrayOfBreaks;
   nsBRNodeFunctor functor;
-  nsDOMIterator iter;
-  nsresult res = iter.Init(inNode);
-  NS_ENSURE_SUCCESS(res, res);
-  res = iter.AppendList(functor, arrayOfBreaks);
-  NS_ENSURE_SUCCESS(res, res);
+  nsDOMIterator iter(*inNode);
+  iter.AppendList(functor, arrayOfBreaks);
   
   // if there aren't any breaks, just put inNode itself in the array
   int32_t listCount = arrayOfBreaks.Count();
   if (!listCount)
   {
     if (!outArrayOfNodes.AppendObject(inNode))
       return NS_ERROR_FAILURE;
   }
@@ -6371,17 +6358,17 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsID
     for (i=0; i< listCount; i++)
     {
       breakNode = do_QueryInterface(arrayOfBreaks[i]);
       NS_ENSURE_TRUE(breakNode, NS_ERROR_NULL_POINTER);
       NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER);
       splitParentNode = GetAsDOMNode(nsEditor::GetNodeLocation(breakNode,
                                                                &splitOffset));
       NS_ENSURE_STATE(mHTMLEditor);
-      res = mHTMLEditor->SplitNodeDeep(splitDeepNode, splitParentNode, splitOffset,
+      nsresult res = mHTMLEditor->SplitNodeDeep(splitDeepNode, splitParentNode, splitOffset,
                           &resultOffset, false, address_of(leftNode), address_of(rightNode));
       NS_ENSURE_SUCCESS(res, res);
       // put left node in node list
       if (leftNode)
       {
         // might not be a left node.  a break might have been at the very
         // beginning of inline container, in which case splitnodedeep
         // would not actually split anything
@@ -6399,17 +6386,17 @@ nsHTMLEditRules::BustUpInlinesAtBRs(nsID
     }
     // now tack on remaining rightNode, if any, to the list
     if (rightNode)
     {
       if (!outArrayOfNodes.AppendObject(rightNode))
         return NS_ERROR_FAILURE;
     }
   }
-  return res;
+  return NS_OK;
 }
 
 
 nsCOMPtr<nsIDOMNode> 
 nsHTMLEditRules::GetHighestInlineParent(nsIDOMNode* aNode)
 {
   NS_ENSURE_TRUE(aNode, nullptr);
   if (IsBlockNode(aNode)) return nullptr;
@@ -7617,40 +7604,37 @@ nsHTMLEditRules::AdjustSpecialBreaks(boo
 {
   nsCOMArray<nsIDOMNode> arrayOfNodes;
   nsCOMPtr<nsISupports> isupports;
   int32_t nodeCount,j;
   
   // gather list of empty nodes
   NS_ENSURE_STATE(mHTMLEditor);
   nsEmptyEditableFunctor functor(mHTMLEditor);
-  nsDOMIterator iter;
-  nsresult res = iter.Init(mDocChangeRange);
-  NS_ENSURE_SUCCESS(res, res);
-  res = iter.AppendList(functor, arrayOfNodes);
-  NS_ENSURE_SUCCESS(res, res);
+  nsDOMIterator iter(*mDocChangeRange);
+  iter.AppendList(functor, arrayOfNodes);
 
   // put moz-br's into these empty li's and td's
   nodeCount = arrayOfNodes.Count();
   for (j = 0; j < nodeCount; j++)
   {
     // need to put br at END of node.  It may have
     // empty containers in it and still pass the "IsEmptynode" test,
     // and we want the br's to be after them.  Also, we want the br
     // to be after the selection if the selection is in this node.
     uint32_t len;
     nsCOMPtr<nsIDOMNode> theNode = arrayOfNodes[0];
     arrayOfNodes.RemoveObjectAt(0);
-    res = nsEditor::GetLengthOfDOMNode(theNode, len);
+    nsresult res = nsEditor::GetLengthOfDOMNode(theNode, len);
     NS_ENSURE_SUCCESS(res, res);
     res = CreateMozBR(theNode, (int32_t)len);
     NS_ENSURE_SUCCESS(res, res);
   }
   
-  return res;
+  return NS_OK;
 }
 
 nsresult 
 nsHTMLEditRules::AdjustWhitespace(Selection* aSelection)
 {
   // get selection point
   nsCOMPtr<nsIDOMNode> selNode;
   int32_t selOffset;