Bug 181137 - part 3: Make all users of ContentSutreeIterator treat it directly rather than via nsIContentIterator r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 11 Jan 2019 01:49:00 +0000
changeset 453434 5fb4b3194d8edf19acf42c3b27e26201beb95587
parent 453433 a29d33c6fca1a10e5fe337c4b223578cf2f51acb
child 453435 7b087e0123bdbda45fa0a9a41fdb78b196ee333f
push id35357
push usernerli@mozilla.com
push dateFri, 11 Jan 2019 21:54:07 +0000
treeherdermozilla-central@0ce024c91511 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs181137
milestone66.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 181137 - part 3: Make all users of ContentSutreeIterator treat it directly rather than via nsIContentIterator r=smaug Now, all users of ContentSubtreeIterator can access it directly. This patch makes them use the concrete class directly. Differential Revision: https://phabricator.services.mozilla.com/D15920
dom/base/ContentIterator.cpp
dom/base/ScriptableContentIterator.cpp
dom/base/Selection.cpp
dom/base/nsIContentIterator.h
dom/base/nsRange.cpp
editor/libeditor/DeleteRangeTransaction.cpp
editor/libeditor/EditorUtils.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLStyleEditor.cpp
layout/base/PresShell.cpp
--- a/dom/base/ContentIterator.cpp
+++ b/dom/base/ContentIterator.cpp
@@ -19,21 +19,16 @@ already_AddRefed<nsIContentIterator> NS_
   return iter.forget();
 }
 
 already_AddRefed<nsIContentIterator> NS_NewPreContentIterator() {
   nsCOMPtr<nsIContentIterator> iter = new mozilla::PreContentIterator();
   return iter.forget();
 }
 
-already_AddRefed<nsIContentIterator> NS_NewContentSubtreeIterator() {
-  nsCOMPtr<nsIContentIterator> iter = new mozilla::ContentSubtreeIterator();
-  return iter.forget();
-}
-
 namespace mozilla {
 
 ///////////////////////////////////////////////////////////////////////////
 // NodeIsInTraversalRange: returns true if content is visited during
 // the traversal of the range in the specified mode.
 //
 static bool NodeIsInTraversalRange(nsINode* aNode, bool aIsPreMode,
                                    const RawRangeBoundary& aStart,
--- a/dom/base/ScriptableContentIterator.cpp
+++ b/dom/base/ScriptableContentIterator.cpp
@@ -1,15 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ScriptableContentIterator.h"
+
+#include "mozilla/ContentIterator.h"
 #include "nsINode.h"
 #include "nsRange.h"
 
 namespace mozilla {
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptableContentIterator)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptableContentIterator)
 
@@ -31,17 +33,17 @@ void ScriptableContentIterator::EnsureCo
     case POST_ORDER_ITERATOR:
     default:
       mContentIterator = NS_NewContentIterator();
       break;
     case PRE_ORDER_ITERATOR:
       mContentIterator = NS_NewPreContentIterator();
       break;
     case SUBTREE_ITERATOR:
-      mContentIterator = NS_NewContentSubtreeIterator();
+      mContentIterator = new ContentSubtreeIterator();
       break;
   }
 }
 
 NS_IMETHODIMP
 ScriptableContentIterator::InitWithRootNode(IteratorType aType,
                                             nsINode* aRoot) {
   if (aType == NOT_INITIALIZED ||
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -9,16 +9,17 @@
  */
 
 #include "mozilla/dom/Selection.h"
 
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/AutoCopyListener.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/ContentIterator.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/SelectionBinding.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/HTMLEditor.h"
 #include "mozilla/RangeBoundary.h"
 #include "mozilla/Telemetry.h"
@@ -32,17 +33,16 @@
 #include "nsIContent.h"
 #include "nsRange.h"
 #include "nsITableCellLayout.h"
 #include "nsTArray.h"
 #include "nsTableWrapperFrame.h"
 #include "nsTableCellFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsCCUncollectableMarker.h"
-#include "nsIContentIterator.h"
 #include "nsIDocumentEncoder.h"
 #include "nsTextFragment.h"
 #include <algorithm>
 #include "nsContentUtils.h"
 
 #include "nsGkAtoms.h"
 #include "nsLayoutUtils.h"
 #include "nsBidiPresUtils.h"
@@ -1571,25 +1571,25 @@ nsresult Selection::SelectFrames(nsPresC
   if (aRange->Collapsed() ||
       (startNode == endNode && !startNode->HasChildren())) {
     if (!isFirstContentTextNode) {
       SelectFramesForContent(startContent, aSelect);
     }
     return NS_OK;
   }
 
-  nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
-  iter->Init(aRange);
-  if (isFirstContentTextNode && !iter->IsDone() &&
-      iter->GetCurrentNode() == startNode) {
-    iter->Next();  // first content has already been handled.
+  RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
+  subtreeIter->Init(aRange);
+  if (isFirstContentTextNode && !subtreeIter->IsDone() &&
+      subtreeIter->GetCurrentNode() == startNode) {
+    subtreeIter->Next();  // first content has already been handled.
   }
   nsCOMPtr<nsIContentIterator> inneriter = NS_NewContentIterator();
-  for (; !iter->IsDone(); iter->Next()) {
-    nsINode* node = iter->GetCurrentNode();
+  for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
+    nsINode* node = subtreeIter->GetCurrentNode();
     MOZ_ASSERT(node);
     nsIContent* content = node->IsContent() ? node->AsContent() : nullptr;
     SelectAllFramesForContent(inneriter, content, aSelect);
   }
 
   // We must now do the last one if it is not the same as the first
   if (endNode != startNode) {
     nsIContent* endContent =
--- a/dom/base/nsIContentIterator.h
+++ b/dom/base/nsIContentIterator.h
@@ -80,11 +80,10 @@ class nsIContentIterator : public nsISup
    */
   virtual nsresult PositionAt(nsINode* aCurNode) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentIterator, NS_ICONTENTITERATOR_IID)
 
 already_AddRefed<nsIContentIterator> NS_NewContentIterator();
 already_AddRefed<nsIContentIterator> NS_NewPreContentIterator();
-already_AddRefed<nsIContentIterator> NS_NewContentSubtreeIterator();
 
 #endif  // __nsIContentIterator_h___
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -11,21 +11,21 @@
 #include "nscore.h"
 #include "nsRange.h"
 
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsIContent.h"
 #include "mozilla/dom/Document.h"
 #include "nsError.h"
-#include "nsIContentIterator.h"
 #include "nsINodeList.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsTextFrame.h"
+#include "mozilla/ContentIterator.h"
 #include "mozilla/dom/CharacterData.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/RangeBinding.h"
 #include "mozilla/dom/DOMRect.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/Selection.h"
@@ -1486,26 +1486,26 @@ void nsRange::SelectNodeContents(nsINode
 // The Subtree Content Iterator only returns subtrees that are
 // completely within a given range. It doesn't return a CharacterData
 // node that contains either the start or end point of the range.,
 // nor does it return element nodes when nothing in the element is selected.
 // We need an iterator that will also include these start/end points
 // so that our methods/algorithms aren't cluttered with special
 // case code that tries to include these points while iterating.
 //
-// The RangeSubtreeIterator class mimics the nsIContentIterator
+// The RangeSubtreeIterator class mimics the ContentSubtreeIterator
 // methods we need, so should the Content Iterator support the
 // start/end points in the future, we can switchover relatively
 // easy.
 
 class MOZ_STACK_CLASS RangeSubtreeIterator {
  private:
   enum RangeSubtreeIterState { eDone = 0, eUseStart, eUseIterator, eUseEnd };
 
-  nsCOMPtr<nsIContentIterator> mIter;
+  RefPtr<ContentSubtreeIterator> mSubtreeIter;
   RangeSubtreeIterState mIterState;
 
   nsCOMPtr<nsINode> mStart;
   nsCOMPtr<nsINode> mEnd;
 
  public:
   RangeSubtreeIterator() : mIterState(eDone) {}
   ~RangeSubtreeIterator() {}
@@ -1557,27 +1557,27 @@ nsresult RangeSubtreeIterator::Init(nsRa
     // node. Null out the end pointer so we only visit the
     // node once!
 
     mEnd = nullptr;
   } else {
     // Now create a Content Subtree Iterator to be used
     // for the subtrees between the end points!
 
-    mIter = NS_NewContentSubtreeIterator();
-
-    nsresult res = mIter->Init(aRange);
+    mSubtreeIter = new ContentSubtreeIterator();
+
+    nsresult res = mSubtreeIter->Init(aRange);
     if (NS_FAILED(res)) return res;
 
-    if (mIter->IsDone()) {
+    if (mSubtreeIter->IsDone()) {
       // The subtree iterator thinks there's nothing
       // to iterate over, so just free it up so we
       // don't accidentally call into it.
 
-      mIter = nullptr;
+      mSubtreeIter = nullptr;
     }
   }
 
   // Initialize the iterator by calling First().
   // Note that we are ignoring the return value on purpose!
 
   First();
 
@@ -1586,86 +1586,86 @@ nsresult RangeSubtreeIterator::Init(nsRa
 
 already_AddRefed<nsINode> RangeSubtreeIterator::GetCurrentNode() {
   nsCOMPtr<nsINode> node;
 
   if (mIterState == eUseStart && mStart) {
     node = mStart;
   } else if (mIterState == eUseEnd && mEnd) {
     node = mEnd;
-  } else if (mIterState == eUseIterator && mIter) {
-    node = mIter->GetCurrentNode();
+  } else if (mIterState == eUseIterator && mSubtreeIter) {
+    node = mSubtreeIter->GetCurrentNode();
   }
 
   return node.forget();
 }
 
 void RangeSubtreeIterator::First() {
   if (mStart)
     mIterState = eUseStart;
-  else if (mIter) {
-    mIter->First();
+  else if (mSubtreeIter) {
+    mSubtreeIter->First();
 
     mIterState = eUseIterator;
   } else if (mEnd)
     mIterState = eUseEnd;
   else
     mIterState = eDone;
 }
 
 void RangeSubtreeIterator::Last() {
   if (mEnd)
     mIterState = eUseEnd;
-  else if (mIter) {
-    mIter->Last();
+  else if (mSubtreeIter) {
+    mSubtreeIter->Last();
 
     mIterState = eUseIterator;
   } else if (mStart)
     mIterState = eUseStart;
   else
     mIterState = eDone;
 }
 
 void RangeSubtreeIterator::Next() {
   if (mIterState == eUseStart) {
-    if (mIter) {
-      mIter->First();
+    if (mSubtreeIter) {
+      mSubtreeIter->First();
 
       mIterState = eUseIterator;
     } else if (mEnd)
       mIterState = eUseEnd;
     else
       mIterState = eDone;
   } else if (mIterState == eUseIterator) {
-    mIter->Next();
-
-    if (mIter->IsDone()) {
+    mSubtreeIter->Next();
+
+    if (mSubtreeIter->IsDone()) {
       if (mEnd)
         mIterState = eUseEnd;
       else
         mIterState = eDone;
     }
   } else
     mIterState = eDone;
 }
 
 void RangeSubtreeIterator::Prev() {
   if (mIterState == eUseEnd) {
-    if (mIter) {
-      mIter->Last();
+    if (mSubtreeIter) {
+      mSubtreeIter->Last();
 
       mIterState = eUseIterator;
     } else if (mStart)
       mIterState = eUseStart;
     else
       mIterState = eDone;
   } else if (mIterState == eUseIterator) {
-    mIter->Prev();
-
-    if (mIter->IsDone()) {
+    mSubtreeIter->Prev();
+
+    if (mSubtreeIter->IsDone()) {
       if (mStart)
         mIterState = eUseStart;
       else
         mIterState = eDone;
     }
   } else
     mIterState = eDone;
 }
--- a/editor/libeditor/DeleteRangeTransaction.cpp
+++ b/editor/libeditor/DeleteRangeTransaction.cpp
@@ -3,25 +3,25 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DeleteRangeTransaction.h"
 
 #include "DeleteNodeTransaction.h"
 #include "DeleteTextTransaction.h"
 #include "mozilla/Assertions.h"
+#include "mozilla/ContentIterator.h"
+#include "mozilla/dom/Selection.h"
 #include "mozilla/EditorBase.h"
-#include "mozilla/dom/Selection.h"
 #include "mozilla/mozalloc.h"
 #include "mozilla/RangeBoundary.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsIContent.h"
-#include "nsIContentIterator.h"
 #include "nsINode.h"
 #include "nsAString.h"
 
 namespace mozilla {
 
 using namespace dom;
 
 DeleteRangeTransaction::DeleteRangeTransaction(EditorBase& aEditorBase,
@@ -209,36 +209,36 @@ nsresult DeleteRangeTransaction::CreateT
 }
 
 nsresult DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween(
     nsRange* aRangeToDelete) {
   if (NS_WARN_IF(!mEditorBase)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
+  RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
 
-  nsresult rv = iter->Init(aRangeToDelete);
+  nsresult rv = subtreeIter->Init(aRangeToDelete);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  while (!iter->IsDone()) {
-    nsCOMPtr<nsINode> node = iter->GetCurrentNode();
+  while (!subtreeIter->IsDone()) {
+    nsCOMPtr<nsINode> node = subtreeIter->GetCurrentNode();
     if (NS_WARN_IF(!node)) {
       return NS_ERROR_NULL_POINTER;
     }
 
     RefPtr<DeleteNodeTransaction> deleteNodeTransaction =
         DeleteNodeTransaction::MaybeCreate(*mEditorBase, *node);
     // XXX This is odd handling.  Even if some nodes in the range are not
     //     editable, editor should append transactions because they could
     //     at undoing/redoing.  Additionally, if the transaction needs to
     //     delete/restore all nodes, it should at undoing/redoing.
     if (NS_WARN_IF(!deleteNodeTransaction)) {
       return NS_ERROR_FAILURE;
     }
     AppendChild(deleteNodeTransaction);
 
-    iter->Next();
+    subtreeIter->Next();
   }
   return NS_OK;
 }
 
 }  // namespace mozilla
--- a/editor/libeditor/EditorUtils.cpp
+++ b/editor/libeditor/EditorUtils.cpp
@@ -60,17 +60,17 @@ void DOMIterator::AppendList(
   }
 }
 
 DOMSubtreeIterator::DOMSubtreeIterator(
     MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
     : DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) {}
 
 nsresult DOMSubtreeIterator::Init(nsRange& aRange) {
-  mIter = NS_NewContentSubtreeIterator();
+  mIter = new ContentSubtreeIterator();
   return mIter->Init(&aRange);
 }
 
 DOMSubtreeIterator::~DOMSubtreeIterator() {}
 
 /******************************************************************************
  * some general purpose editor utils
  *****************************************************************************/
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/HTMLEditor.h"
 
 #include "mozilla/ComposerCommandsUpdater.h"
+#include "mozilla/ContentIterator.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/EditAction.h"
 #include "mozilla/EditorDOMPoint.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/mozInlineSpellChecker.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TextEvents.h"
 
@@ -29,17 +30,16 @@
 #include "mozilla/dom/DocumentInlines.h"
 #include "nsISelectionController.h"
 #include "nsILinkHandler.h"
 #include "nsIInlineSpellChecker.h"
 
 #include "mozilla/css/Loader.h"
 
 #include "nsIContent.h"
-#include "nsIContentIterator.h"
 #include "nsIMutableArray.h"
 #include "nsContentUtils.h"
 #include "nsIDocumentEncoder.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsFocusManager.h"
 #include "nsPIDOMWindow.h"
@@ -3773,28 +3773,28 @@ nsresult HTMLEditor::CollapseAdjacentTex
   NS_ENSURE_TRUE(aInRange, NS_ERROR_NULL_POINTER);
   AutoTransactionsConserveSelection dontChangeMySelection(*this);
   nsTArray<nsCOMPtr<nsINode>> textNodes;
   // we can't actually do anything during iteration, so store the text nodes in
   // an array don't bother ref counting them because we know we can hold them
   // for the lifetime of this method
 
   // build a list of editable text nodes
-  nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
-
-  iter->Init(aInRange);
-
-  while (!iter->IsDone()) {
-    nsINode* node = iter->GetCurrentNode();
+  RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
+
+  subtreeIter->Init(aInRange);
+
+  while (!subtreeIter->IsDone()) {
+    nsINode* node = subtreeIter->GetCurrentNode();
     if (node->NodeType() == nsINode::TEXT_NODE &&
         IsEditable(node->AsContent())) {
       textNodes.AppendElement(node);
     }
 
-    iter->Next();
+    subtreeIter->Next();
   }
 
   // now that I have a list of text nodes, collapse adjacent text nodes
   // NOTE: assumption that JoinNodes keeps the righthand node
   while (textNodes.Length() > 1) {
     // we assume a textNodes entry can't be nullptr
     nsINode* leftTextNode = textNodes[0];
     nsINode* rightTextNode = textNodes[1];
@@ -4435,29 +4435,30 @@ nsresult HTMLEditor::SetCSSBackgroundCol
         // starting textnode and an ending textnode which are only partially
         // contained by the range.
 
         // Let's handle the nodes reported by the iterator.  These nodes are
         // entirely contained in the selection range.  We build up a list of
         // them (since doing operations on the document during iteration would
         // perturb the iterator).
 
-        OwningNonNull<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
+        RefPtr<ContentSubtreeIterator> subtreeIter =
+            new ContentSubtreeIterator();
 
         nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
         nsCOMPtr<nsINode> node;
 
         // Iterate range and build up array
-        rv = iter->Init(range);
+        rv = subtreeIter->Init(range);
         // Init returns an error if no nodes in range.  This can easily happen
         // with the subtree iterator if the selection doesn't contain any
         // *whole* nodes.
         if (NS_SUCCEEDED(rv)) {
-          for (; !iter->IsDone(); iter->Next()) {
-            node = iter->GetCurrentNode();
+          for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
+            node = subtreeIter->GetCurrentNode();
             NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
             if (IsEditable(node)) {
               arrayOfNodes.AppendElement(*node);
             }
           }
         }
         // First check the start parent of the range to see if it needs to be
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/HTMLEditor.h"
 
 #include "HTMLEditUtils.h"
 #include "TextEditUtils.h"
 #include "TypeInState.h"
 #include "mozilla/Assertions.h"
+#include "mozilla/ContentIterator.h"
 #include "mozilla/EditAction.h"
 #include "mozilla/EditorUtils.h"
 #include "mozilla/SelectionState.h"
 #include "mozilla/TextEditRules.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
@@ -21,17 +22,16 @@
 #include "nsCOMPtr.h"
 #include "nsCaseTreatment.h"
 #include "nsComponentManagerUtils.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsAtom.h"
 #include "nsIContent.h"
-#include "nsIContentIterator.h"
 #include "nsNameSpaceManager.h"
 #include "nsINode.h"
 #include "nsISupportsImpl.h"
 #include "nsLiteralString.h"
 #include "nsRange.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
@@ -170,28 +170,28 @@ nsresult HTMLEditor::SetInlinePropertyIn
       // starting textnode and an ending textnode which are only partially
       // contained by the range.
 
       // Let's handle the nodes reported by the iterator.  These nodes are
       // entirely contained in the selection range.  We build up a list of them
       // (since doing operations on the document during iteration would perturb
       // the iterator).
 
-      OwningNonNull<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
+      RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
 
       nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
 
       // Iterate range and build up array
-      rv = iter->Init(range);
+      rv = subtreeIter->Init(range);
       // Init returns an error if there are no nodes in range.  This can easily
       // happen with the subtree iterator if the selection doesn't contain any
       // *whole* nodes.
       if (NS_SUCCEEDED(rv)) {
-        for (; !iter->IsDone(); iter->Next()) {
-          OwningNonNull<nsINode> node = *iter->GetCurrentNode();
+        for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
+          OwningNonNull<nsINode> node = *subtreeIter->GetCurrentNode();
 
           if (node->IsContent() && IsEditable(node)) {
             arrayOfNodes.AppendElement(*node->AsContent());
           }
         }
       }
       // First check the start parent of the range to see if it needs to be
       // separately handled (it does if it's a text node, due to how the
@@ -1336,23 +1336,25 @@ nsresult HTMLEditor::RemoveInlinePropert
               SetInlinePropertyOnTextNode(
                   *startNode->GetAsText(), range->StartOffset(),
                   range->EndOffset(), *aProperty, aAttribute, value);
             }
           }
         }
       } else {
         // Not the easy case.  Range not contained in single text node.
-        nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
+        RefPtr<ContentSubtreeIterator> subtreeIter =
+            new ContentSubtreeIterator();
 
         nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
 
         // Iterate range and build up array
-        for (iter->Init(range); !iter->IsDone(); iter->Next()) {
-          nsCOMPtr<nsINode> node = iter->GetCurrentNode();
+        for (subtreeIter->Init(range); !subtreeIter->IsDone();
+             subtreeIter->Next()) {
+          nsCOMPtr<nsINode> node = subtreeIter->GetCurrentNode();
           if (NS_WARN_IF(!node)) {
             return NS_ERROR_FAILURE;
           }
           if (IsEditable(node) && node->IsContent()) {
             arrayOfNodes.AppendElement(*node->AsContent());
           }
         }
 
@@ -1483,27 +1485,28 @@ nsresult HTMLEditor::RelativeFontChange(
       // starting textnode and an ending textnode which are only partially
       // contained by the range.
 
       // Let's handle the nodes reported by the iterator.  These nodes are
       // entirely contained in the selection range.  We build up a list of them
       // (since doing operations on the document during iteration would perturb
       // the iterator).
 
-      OwningNonNull<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
+      RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
 
       // Iterate range and build up array
-      rv = iter->Init(range);
+      rv = subtreeIter->Init(range);
       if (NS_SUCCEEDED(rv)) {
         nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
-        for (; !iter->IsDone(); iter->Next()) {
-          if (NS_WARN_IF(!iter->GetCurrentNode()->IsContent())) {
+        for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
+          if (NS_WARN_IF(!subtreeIter->GetCurrentNode()->IsContent())) {
             return NS_ERROR_FAILURE;
           }
-          OwningNonNull<nsIContent> node = *iter->GetCurrentNode()->AsContent();
+          OwningNonNull<nsIContent> node =
+              *subtreeIter->GetCurrentNode()->AsContent();
 
           if (IsEditable(node)) {
             arrayOfNodes.AppendElement(node);
           }
         }
 
         // Now that we have the list, do the font size change on each node
         for (auto& node : arrayOfNodes) {
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -7,16 +7,17 @@
 /* a presentation of a document, part 2 */
 
 #include "mozilla/PresShell.h"
 
 #include "mozilla/dom/FontFaceSet.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/ContentIterator.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Logging.h"
@@ -35,17 +36,16 @@
 #endif
 
 #include "gfxContext.h"
 #include "gfxPrefs.h"
 #include "gfxUserFontSet.h"
 #include "nsContentList.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
-#include "nsIContentIterator.h"
 #include "nsIPresShellInlines.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/PointerEventHandler.h"
 #include "mozilla/dom/PopupBlocker.h"
 #include "mozilla/dom/Document.h"
 #include "nsAnimationManager.h"
 #include "nsNameSpaceManager.h"  // for Pref-related rule management (bugs 22963,20760,31816)
 #include "nsFrame.h"
@@ -4659,18 +4659,18 @@ UniquePtr<RangePaintInfo> PresShell::Cre
   // get a display list containing the range
   auto info = MakeUnique<RangePaintInfo>(aRange, ancestorFrame);
   info->mBuilder.SetIncludeAllOutOfFlows();
   if (aForPrimarySelection) {
     info->mBuilder.SetSelectedFramesOnly();
   }
   info->mBuilder.EnterPresShell(ancestorFrame);
 
-  nsCOMPtr<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
-  nsresult rv = iter->Init(aRange);
+  RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
+  nsresult rv = subtreeIter->Init(aRange);
   if (NS_FAILED(rv)) {
     return nullptr;
   }
 
   auto BuildDisplayListForNode = [&](nsINode* aNode) {
     if (MOZ_UNLIKELY(!aNode->IsContent())) {
       return;
     }
@@ -4681,18 +4681,18 @@ UniquePtr<RangePaintInfo> PresShell::Cre
       info->mBuilder.SetVisibleRect(frame->GetVisualOverflowRect());
       info->mBuilder.SetDirtyRect(frame->GetVisualOverflowRect());
       frame->BuildDisplayListForStackingContext(&info->mBuilder, &info->mList);
     }
   };
   if (startContainer->NodeType() == nsINode::TEXT_NODE) {
     BuildDisplayListForNode(startContainer);
   }
-  for (; !iter->IsDone(); iter->Next()) {
-    nsCOMPtr<nsINode> node = iter->GetCurrentNode();
+  for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
+    nsCOMPtr<nsINode> node = subtreeIter->GetCurrentNode();
     BuildDisplayListForNode(node);
   }
   if (endContainer != startContainer &&
       endContainer->NodeType() == nsINode::TEXT_NODE) {
     BuildDisplayListForNode(endContainer);
   }
 
 #ifdef DEBUG