Bug 181137 - part 6: Make nsFilteredContentIterator not derived from nsIContentIterator r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 11 Jan 2019 01:51:35 +0000
changeset 453437 61f2c3b1b36815443550ebb9378294c3b5a61ea8
parent 453436 0d3c97c78d7ce2dc4a6790caa84b47b62d097b34
child 453438 2a320da37ca0e1f47828e346f6b5e09ff2196ea8
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 6: Make nsFilteredContentIterator not derived from nsIContentIterator r=smaug nsFilteredContentIterator is used only by TextServicesDocument and there is no reason that it should be derived from nsIContentIterator except consistency. Additionally, it's now only class which is derived from nsIContentIterator except ContentIteratorBase. So, after this change, we can get rid of nsIContentIterator completely. This patch moves nsFilteredContentIterator into mozilla namespace and makes TextServicesDocument treat FilteredContentIterator directly instead of nsIContentIterator interface. Differential Revision: https://phabricator.services.mozilla.com/D15925
editor/spellchecker/FilteredContentIterator.cpp
editor/spellchecker/FilteredContentIterator.h
editor/spellchecker/TextServicesDocument.cpp
editor/spellchecker/TextServicesDocument.h
editor/spellchecker/moz.build
editor/spellchecker/nsFilteredContentIterator.cpp
editor/spellchecker/nsFilteredContentIterator.h
rename from editor/spellchecker/nsFilteredContentIterator.cpp
rename to editor/spellchecker/FilteredContentIterator.cpp
--- a/editor/spellchecker/nsFilteredContentIterator.cpp
+++ b/editor/spellchecker/FilteredContentIterator.cpp
@@ -1,14 +1,14 @@
 /* -*- 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 "nsFilteredContentIterator.h"
+#include "FilteredContentIterator.h"
 
 #include "mozilla/ContentIterator.h"
 #include "mozilla/Move.h"
 #include "mozilla/mozalloc.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsComposeTxtSrvFilter.h"
 #include "nsContentUtils.h"
@@ -16,103 +16,91 @@
 #include "nsError.h"
 #include "nsAtom.h"
 #include "nsIContent.h"
 #include "nsINode.h"
 #include "nsISupportsBase.h"
 #include "nsISupportsUtils.h"
 #include "nsRange.h"
 
-using namespace mozilla;
+namespace mozilla {
 
-//------------------------------------------------------------
-nsFilteredContentIterator::nsFilteredContentIterator(
+FilteredContentIterator::FilteredContentIterator(
     UniquePtr<nsComposeTxtSrvFilter> aFilter)
     : mPostIterator(new PostContentIterator()),
       mPreIterator(new PreContentIterator()),
       mFilter(std::move(aFilter)),
       mDidSkip(false),
       mIsOutOfRange(false),
       mDirection(eDirNotSet) {}
 
-//------------------------------------------------------------
-nsFilteredContentIterator::~nsFilteredContentIterator() {}
-
-//------------------------------------------------------------
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFilteredContentIterator)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFilteredContentIterator)
+FilteredContentIterator::~FilteredContentIterator() {}
 
-NS_INTERFACE_MAP_BEGIN(nsFilteredContentIterator)
-  NS_INTERFACE_MAP_ENTRY(nsIContentIterator)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentIterator)
-  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsFilteredContentIterator)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTION(nsFilteredContentIterator, mCurrentIterator,
+NS_IMPL_CYCLE_COLLECTION(FilteredContentIterator, mCurrentIterator,
                          mPostIterator, mPreIterator, mRange)
 
-//------------------------------------------------------------
-nsresult nsFilteredContentIterator::Init(nsINode* aRoot) {
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(FilteredContentIterator, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(FilteredContentIterator, Release)
+
+nsresult FilteredContentIterator::Init(nsINode* aRoot) {
   NS_ENSURE_ARG_POINTER(aRoot);
   NS_ENSURE_TRUE(mPreIterator, NS_ERROR_FAILURE);
   NS_ENSURE_TRUE(mPostIterator, NS_ERROR_FAILURE);
   mIsOutOfRange = false;
   mDirection = eForward;
   mCurrentIterator = mPreIterator;
 
   mRange = new nsRange(aRoot);
   mRange->SelectNode(*aRoot, IgnoreErrors());
 
   nsresult rv = mPreIterator->Init(mRange);
   NS_ENSURE_SUCCESS(rv, rv);
   return mPostIterator->Init(mRange);
 }
 
-//------------------------------------------------------------
-nsresult nsFilteredContentIterator::Init(nsRange* aRange) {
+nsresult FilteredContentIterator::Init(nsRange* aRange) {
   if (NS_WARN_IF(!aRange)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   if (NS_WARN_IF(!aRange->IsPositioned())) {
     return NS_ERROR_INVALID_ARG;
   }
 
   mRange = aRange->CloneRange();
 
   return InitWithRange();
 }
 
-//------------------------------------------------------------
-nsresult nsFilteredContentIterator::Init(nsINode* aStartContainer,
-                                         uint32_t aStartOffset,
-                                         nsINode* aEndContainer,
-                                         uint32_t aEndOffset) {
+nsresult FilteredContentIterator::Init(nsINode* aStartContainer,
+                                       uint32_t aStartOffset,
+                                       nsINode* aEndContainer,
+                                       uint32_t aEndOffset) {
   return Init(RawRangeBoundary(aStartContainer, aStartOffset),
               RawRangeBoundary(aEndContainer, aEndOffset));
 }
 
-nsresult nsFilteredContentIterator::Init(const RawRangeBoundary& aStart,
-                                         const RawRangeBoundary& aEnd) {
+nsresult FilteredContentIterator::Init(const RawRangeBoundary& aStart,
+                                       const RawRangeBoundary& aEnd) {
   RefPtr<nsRange> range;
   nsresult rv = nsRange::CreateRange(aStart, aEnd, getter_AddRefs(range));
   if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!range) ||
       NS_WARN_IF(!range->IsPositioned())) {
     return NS_ERROR_INVALID_ARG;
   }
 
   MOZ_ASSERT(range->StartRef() == aStart);
   MOZ_ASSERT(range->EndRef() == aEnd);
 
   mRange = std::move(range);
 
   return InitWithRange();
 }
 
-nsresult nsFilteredContentIterator::InitWithRange() {
+nsresult FilteredContentIterator::InitWithRange() {
   MOZ_ASSERT(mRange);
   MOZ_ASSERT(mRange->IsPositioned());
 
   if (NS_WARN_IF(!mPreIterator) || NS_WARN_IF(!mPostIterator)) {
     return NS_ERROR_FAILURE;
   }
 
   mIsOutOfRange = false;
@@ -121,18 +109,17 @@ nsresult nsFilteredContentIterator::Init
 
   nsresult rv = mPreIterator->Init(mRange);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return mPostIterator->Init(mRange);
 }
 
-//------------------------------------------------------------
-nsresult nsFilteredContentIterator::SwitchDirections(bool aChangeToForward) {
+nsresult FilteredContentIterator::SwitchDirections(bool aChangeToForward) {
   nsINode* node = mCurrentIterator->GetCurrentNode();
 
   if (aChangeToForward) {
     mCurrentIterator = mPreIterator;
     mDirection = eForward;
   } else {
     mCurrentIterator = mPostIterator;
     mDirection = eBackward;
@@ -143,18 +130,17 @@ nsresult nsFilteredContentIterator::Swit
     if (NS_FAILED(rv)) {
       mIsOutOfRange = true;
       return rv;
     }
   }
   return NS_OK;
 }
 
-//------------------------------------------------------------
-void nsFilteredContentIterator::First() {
+void FilteredContentIterator::First() {
   if (!mCurrentIterator) {
     NS_ERROR("Missing iterator!");
 
     return;
   }
 
   // If we are switching directions then
   // we need to switch how we process the nodes
@@ -171,18 +157,17 @@ void nsFilteredContentIterator::First() 
   }
 
   nsINode* currentNode = mCurrentIterator->GetCurrentNode();
 
   bool didCross;
   CheckAdvNode(currentNode, didCross, eForward);
 }
 
-//------------------------------------------------------------
-void nsFilteredContentIterator::Last() {
+void FilteredContentIterator::Last() {
   if (!mCurrentIterator) {
     NS_ERROR("Missing iterator!");
 
     return;
   }
 
   // If we are switching directions then
   // we need to switch how we process the nodes
@@ -257,21 +242,20 @@ static bool ContentIsInTraversalRange(ns
   NS_ENSURE_TRUE(aNextContent && aRange, false);
 
   return ContentIsInTraversalRange(
       aNextContent, aIsPreMode, aRange->GetStartContainer(),
       static_cast<int32_t>(aRange->StartOffset()), aRange->GetEndContainer(),
       static_cast<int32_t>(aRange->EndOffset()));
 }
 
-//------------------------------------------------------------
 // Helper function to advance to the next or previous node
-nsresult nsFilteredContentIterator::AdvanceNode(nsINode* aNode,
-                                                nsINode*& aNewNode,
-                                                eDirectionType aDir) {
+nsresult FilteredContentIterator::AdvanceNode(nsINode* aNode,
+                                              nsINode*& aNewNode,
+                                              eDirectionType aDir) {
   nsCOMPtr<nsIContent> nextNode;
   if (aDir == eForward) {
     nextNode = aNode->GetNextSibling();
   } else {
     nextNode = aNode->GetPreviousSibling();
   }
 
   if (nextNode) {
@@ -305,20 +289,19 @@ nsresult nsFilteredContentIterator::Adva
 
   // if we get here it pretty much means
   // we went out of the DOM Range
   mIsOutOfRange = true;
 
   return NS_ERROR_FAILURE;
 }
 
-//------------------------------------------------------------
 // Helper function to see if the next/prev node should be skipped
-void nsFilteredContentIterator::CheckAdvNode(nsINode* aNode, bool& aDidSkip,
-                                             eDirectionType aDir) {
+void FilteredContentIterator::CheckAdvNode(nsINode* aNode, bool& aDidSkip,
+                                           eDirectionType aDir) {
   aDidSkip = false;
   mIsOutOfRange = false;
 
   if (aNode && mFilter) {
     nsCOMPtr<nsINode> currentNode = aNode;
     while (1) {
       if (mFilter->Skip(aNode)) {
         aDidSkip = true;
@@ -337,17 +320,17 @@ void nsFilteredContentIterator::CheckAdv
           mCurrentIterator->PositionAt(content);
         }
         return;  // found something
       }
     }
   }
 }
 
-void nsFilteredContentIterator::Next() {
+void FilteredContentIterator::Next() {
   if (mIsOutOfRange || !mCurrentIterator) {
     NS_ASSERTION(mCurrentIterator, "Missing iterator!");
 
     return;
   }
 
   // If we are switching directions then
   // we need to switch how we process the nodes
@@ -366,17 +349,17 @@ void nsFilteredContentIterator::Next() {
 
   // If we can't get the current node then
   // don't check to see if we can skip it
   nsINode* currentNode = mCurrentIterator->GetCurrentNode();
 
   CheckAdvNode(currentNode, mDidSkip, eForward);
 }
 
-void nsFilteredContentIterator::Prev() {
+void FilteredContentIterator::Prev() {
   if (mIsOutOfRange || !mCurrentIterator) {
     NS_ASSERTION(mCurrentIterator, "Missing iterator!");
 
     return;
   }
 
   // If we are switching directions then
   // we need to switch how we process the nodes
@@ -395,29 +378,31 @@ void nsFilteredContentIterator::Prev() {
 
   // If we can't get the current node then
   // don't check to see if we can skip it
   nsINode* currentNode = mCurrentIterator->GetCurrentNode();
 
   CheckAdvNode(currentNode, mDidSkip, eBackward);
 }
 
-nsINode* nsFilteredContentIterator::GetCurrentNode() {
+nsINode* FilteredContentIterator::GetCurrentNode() {
   if (mIsOutOfRange || !mCurrentIterator) {
     return nullptr;
   }
 
   return mCurrentIterator->GetCurrentNode();
 }
 
-bool nsFilteredContentIterator::IsDone() {
+bool FilteredContentIterator::IsDone() {
   if (mIsOutOfRange || !mCurrentIterator) {
     return true;
   }
 
   return mCurrentIterator->IsDone();
 }
 
-nsresult nsFilteredContentIterator::PositionAt(nsINode* aCurNode) {
+nsresult FilteredContentIterator::PositionAt(nsINode* aCurNode) {
   NS_ENSURE_TRUE(mCurrentIterator, NS_ERROR_FAILURE);
   mIsOutOfRange = false;
   return mCurrentIterator->PositionAt(aCurNode);
 }
+
+}  // namespace mozilla
rename from editor/spellchecker/nsFilteredContentIterator.h
rename to editor/spellchecker/FilteredContentIterator.h
--- a/editor/spellchecker/nsFilteredContentIterator.h
+++ b/editor/spellchecker/FilteredContentIterator.h
@@ -1,83 +1,83 @@
 /* -*- 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/. */
 
-#ifndef nsFilteredContentIterator_h__
-#define nsFilteredContentIterator_h__
+#ifndef FilteredContentIterator_h
+#define FilteredContentIterator_h
 
+#include "nsComposeTxtSrvFilter.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsImpl.h"
 #include "nscore.h"
 #include "mozilla/ContentIterator.h"
 #include "mozilla/UniquePtr.h"
 
 class nsAtom;
-class nsComposeTxtSrvFilter;
 class nsINode;
 class nsRange;
 
-class nsFilteredContentIterator final : public nsIContentIterator {
+namespace mozilla {
+
+class FilteredContentIterator final {
  public:
-  // nsISupports interface...
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsFilteredContentIterator)
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(FilteredContentIterator)
+  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(FilteredContentIterator)
 
-  explicit nsFilteredContentIterator(
-      mozilla::UniquePtr<nsComposeTxtSrvFilter> aFilter);
+  explicit FilteredContentIterator(UniquePtr<nsComposeTxtSrvFilter> aFilter);
 
-  /* nsIContentIterator */
-  virtual nsresult Init(nsINode* aRoot) override;
-  virtual nsresult Init(nsRange* aRange) override;
-  virtual nsresult Init(nsINode* aStartContainer, uint32_t aStartOffset,
-                        nsINode* aEndContainer, uint32_t aEndOffset) override;
-  virtual nsresult Init(const mozilla::RawRangeBoundary& aStart,
-                        const mozilla::RawRangeBoundary& aEnd) override;
-  virtual void First() override;
-  virtual void Last() override;
-  virtual void Next() override;
-  virtual void Prev() override;
-  virtual nsINode* GetCurrentNode() override;
-  virtual bool IsDone() override;
-  virtual nsresult PositionAt(nsINode* aCurNode) override;
+  nsresult Init(nsINode* aRoot);
+  nsresult Init(nsRange* aRange);
+  nsresult Init(nsINode* aStartContainer, uint32_t aStartOffset,
+                nsINode* aEndContainer, uint32_t aEndOffset);
+  nsresult Init(const RawRangeBoundary& aStart, const RawRangeBoundary& aEnd);
+  void First();
+  void Last();
+  void Next();
+  void Prev();
+  nsINode* GetCurrentNode();
+  bool IsDone();
+  nsresult PositionAt(nsINode* aCurNode);
 
   /* Helpers */
   bool DidSkip() { return mDidSkip; }
   void ClearDidSkip() { mDidSkip = false; }
 
  protected:
-  nsFilteredContentIterator()
+  FilteredContentIterator()
       : mDidSkip(false), mIsOutOfRange(false), mDirection{eDirNotSet} {}
 
-  virtual ~nsFilteredContentIterator();
+  virtual ~FilteredContentIterator();
 
   /**
    * Callers must guarantee that mRange isn't nullptr and it's positioned.
    */
   nsresult InitWithRange();
 
   // enum to give us the direction
   typedef enum { eDirNotSet, eForward, eBackward } eDirectionType;
   nsresult AdvanceNode(nsINode* aNode, nsINode*& aNewNode, eDirectionType aDir);
   void CheckAdvNode(nsINode* aNode, bool& aDidSkip, eDirectionType aDir);
   nsresult SwitchDirections(bool aChangeToForward);
 
-  RefPtr<mozilla::ContentIteratorBase> mCurrentIterator;
-  RefPtr<mozilla::PostContentIterator> mPostIterator;
-  RefPtr<mozilla::PreContentIterator> mPreIterator;
+  RefPtr<ContentIteratorBase> mCurrentIterator;
+  RefPtr<PostContentIterator> mPostIterator;
+  RefPtr<PreContentIterator> mPreIterator;
 
   RefPtr<nsAtom> mBlockQuoteAtom;
   RefPtr<nsAtom> mScriptAtom;
   RefPtr<nsAtom> mTextAreaAtom;
   RefPtr<nsAtom> mSelectAreaAtom;
   RefPtr<nsAtom> mMapAtom;
 
-  mozilla::UniquePtr<nsComposeTxtSrvFilter> mFilter;
+  UniquePtr<nsComposeTxtSrvFilter> mFilter;
   RefPtr<nsRange> mRange;
   bool mDidSkip;
   bool mIsOutOfRange;
   eDirectionType mDirection;
 };
 
-#endif
+}  // namespace mozilla
+
+#endif  // #ifndef FilteredContentIterator_h
--- a/editor/spellchecker/TextServicesDocument.cpp
+++ b/editor/spellchecker/TextServicesDocument.cpp
@@ -1,31 +1,30 @@
 /* -*- 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 "TextServicesDocument.h"
 
+#include "FilteredContentIterator.h"  // for FilteredContentIterator
 #include "mozilla/Assertions.h"   // for MOZ_ASSERT, etc
 #include "mozilla/EditorUtils.h"  // for AutoTransactionBatchExternal
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/mozalloc.h"    // for operator new, etc
 #include "mozilla/TextEditor.h"  // for TextEditor
 #include "nsAString.h"           // for nsAString::Length, etc
 #include "nsContentUtils.h"      // for nsContentUtils
 #include "nsComposeTxtSrvFilter.h"
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
 #include "nsDependentSubstring.h"       // for Substring
 #include "nsError.h"                    // for NS_OK, NS_ERROR_FAILURE, etc
-#include "nsFilteredContentIterator.h"  // for nsFilteredContentIterator
 #include "nsGenericHTMLElement.h"       // for nsGenericHTMLElement
 #include "nsIContent.h"                 // for nsIContent, etc
-#include "nsIContentIterator.h"         // for nsIContentIterator
 #include "nsID.h"                       // for NS_GET_IID
 #include "nsIEditor.h"                  // for nsIEditor, etc
 #include "nsINode.h"                    // for nsINode
 #include "nsISelectionController.h"     // for nsISelectionController, etc
 #include "nsISupportsBase.h"            // for nsISupports
 #include "nsISupportsUtils.h"           // for NS_IF_ADDREF, NS_ADDREF, etc
 #include "mozilla/intl/WordBreaker.h"   // for WordRange, WordBreaker
 #include "nsRange.h"                    // for nsRange
@@ -81,17 +80,17 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(TextSer
 
 NS_INTERFACE_MAP_BEGIN(TextServicesDocument)
   NS_INTERFACE_MAP_ENTRY(nsIEditActionListener)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditActionListener)
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(TextServicesDocument)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION(TextServicesDocument, mDocument, mSelCon, mTextEditor,
-                         mIterator, mPrevTextBlock, mNextTextBlock, mExtent)
+                         mFilteredIter, mPrevTextBlock, mNextTextBlock, mExtent)
 
 nsresult TextServicesDocument::InitWithEditor(nsIEditor* aEditor) {
   nsCOMPtr<nsISelectionController> selCon;
 
   NS_ENSURE_TRUE(aEditor, NS_ERROR_NULL_POINTER);
 
   // Check to see if we already have an mSelCon. If we do, it
   // better be the same one the editor uses!
@@ -116,17 +115,17 @@ nsresult TextServicesDocument::InitWithE
   RefPtr<Document> doc = aEditor->AsEditorBase()->GetDocument();
   if (!doc || (mDocument && doc != mDocument)) {
     return NS_ERROR_FAILURE;
   }
 
   if (!mDocument) {
     mDocument = doc;
 
-    rv = CreateDocumentContentIterator(getter_AddRefs(mIterator));
+    rv = CreateDocumentContentIterator(getter_AddRefs(mFilteredIter));
 
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     mIteratorStatus = IteratorStatus::eDone;
 
     rv = FirstBlock();
@@ -149,17 +148,18 @@ nsresult TextServicesDocument::SetExtent
 
   // We need to store a copy of aDOMRange since we don't
   // know where it came from.
 
   mExtent = aRange->CloneRange();
 
   // Create a new iterator based on our new extent range.
 
-  nsresult rv = CreateContentIterator(mExtent, getter_AddRefs(mIterator));
+  nsresult rv =
+      CreateFilteredContentIterator(mExtent, getter_AddRefs(mFilteredIter));
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // Now position the iterator at the start of the first block
   // in the range.
 
@@ -181,49 +181,49 @@ nsresult TextServicesDocument::ExpandRan
   nsresult rv =
       GetRangeEndPoints(aRange, getter_AddRefs(rngStartNode), &rngStartOffset,
                         getter_AddRefs(rngEndNode), &rngEndOffset);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create a content iterator based on the range.
 
-  nsCOMPtr<nsIContentIterator> iter;
-  rv = CreateContentIterator(aRange, getter_AddRefs(iter));
+  RefPtr<FilteredContentIterator> filteredIter;
+  rv = CreateFilteredContentIterator(aRange, getter_AddRefs(filteredIter));
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Find the first text node in the range.
 
   IteratorStatus iterStatus = IteratorStatus::eDone;
 
-  rv = FirstTextNode(iter, &iterStatus);
+  rv = FirstTextNode(filteredIter, &iterStatus);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (iterStatus == IteratorStatus::eDone) {
     // No text was found so there's no adjustment necessary!
     return NS_OK;
   }
 
-  nsINode* firstText = iter->GetCurrentNode();
+  nsINode* firstText = filteredIter->GetCurrentNode();
   NS_ENSURE_TRUE(firstText, NS_ERROR_FAILURE);
 
   // Find the last text node in the range.
 
-  rv = LastTextNode(iter, &iterStatus);
+  rv = LastTextNode(filteredIter, &iterStatus);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (iterStatus == IteratorStatus::eDone) {
     // We should never get here because a first text block
     // was found above.
     NS_ASSERTION(false, "Found a first without a last!");
     return NS_ERROR_FAILURE;
   }
 
-  nsINode* lastText = iter->GetCurrentNode();
+  nsINode* lastText = filteredIter->GetCurrentNode();
   NS_ENSURE_TRUE(lastText, NS_ERROR_FAILURE);
 
   // Now make sure our end points are in terms of text nodes in the range!
 
   if (rngStartNode != firstText) {
     // The range includes the start of the first text node!
     rngStartNode = firstText;
     rngStartOffset = 0;
@@ -233,33 +233,33 @@ nsresult TextServicesDocument::ExpandRan
     // The range includes the end of the last text node!
     rngEndNode = lastText;
     rngEndOffset = lastText->Length();
   }
 
   // Create a doc iterator so that we can scan beyond
   // the bounds of the extent range.
 
-  nsCOMPtr<nsIContentIterator> docIter;
-  rv = CreateDocumentContentIterator(getter_AddRefs(docIter));
+  RefPtr<FilteredContentIterator> docFilteredIter;
+  rv = CreateDocumentContentIterator(getter_AddRefs(docFilteredIter));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Grab all the text in the block containing our
   // first text node.
 
-  rv = docIter->PositionAt(firstText);
+  rv = docFilteredIter->PositionAt(firstText);
   NS_ENSURE_SUCCESS(rv, rv);
 
   iterStatus = IteratorStatus::eValid;
 
   nsTArray<OffsetEntry*> offsetTable;
   nsAutoString blockStr;
 
-  rv =
-      CreateOffsetTable(&offsetTable, docIter, &iterStatus, nullptr, &blockStr);
+  rv = CreateOffsetTable(&offsetTable, docFilteredIter, &iterStatus, nullptr,
+                         &blockStr);
   if (NS_FAILED(rv)) {
     ClearOffsetTable(&offsetTable);
     return rv;
   }
 
   nsCOMPtr<nsINode> wordStartNode, wordEndNode;
   int32_t wordStartOffset, wordEndOffset;
 
@@ -272,23 +272,23 @@ nsresult TextServicesDocument::ExpandRan
   NS_ENSURE_SUCCESS(rv, rv);
 
   rngStartNode = wordStartNode;
   rngStartOffset = wordStartOffset;
 
   // Grab all the text in the block containing our
   // last text node.
 
-  rv = docIter->PositionAt(lastText);
+  rv = docFilteredIter->PositionAt(lastText);
   NS_ENSURE_SUCCESS(rv, rv);
 
   iterStatus = IteratorStatus::eValid;
 
-  rv =
-      CreateOffsetTable(&offsetTable, docIter, &iterStatus, nullptr, &blockStr);
+  rv = CreateOffsetTable(&offsetTable, docFilteredIter, &iterStatus, nullptr,
+                         &blockStr);
   if (NS_FAILED(rv)) {
     ClearOffsetTable(&offsetTable);
     return rv;
   }
 
   rv = FindWordBounds(&offsetTable, &blockStr, rngEndNode, rngEndOffset,
                       getter_AddRefs(wordStartNode), &wordStartOffset,
                       getter_AddRefs(wordEndNode), &wordEndOffset);
@@ -323,30 +323,30 @@ nsresult TextServicesDocument::SetFilter
   return NS_OK;
 }
 
 nsresult TextServicesDocument::GetCurrentTextBlock(nsString* aStr) {
   NS_ENSURE_TRUE(aStr, NS_ERROR_NULL_POINTER);
 
   aStr->Truncate();
 
-  NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
-
-  nsresult rv = CreateOffsetTable(&mOffsetTable, mIterator, &mIteratorStatus,
-                                  mExtent, aStr);
+  NS_ENSURE_TRUE(mFilteredIter, NS_ERROR_FAILURE);
+
+  nsresult rv = CreateOffsetTable(&mOffsetTable, mFilteredIter,
+                                  &mIteratorStatus, mExtent, aStr);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult TextServicesDocument::FirstBlock() {
-  NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
-
-  nsresult rv = FirstTextNode(mIterator, &mIteratorStatus);
+  NS_ENSURE_TRUE(mFilteredIter, NS_ERROR_FAILURE);
+
+  nsresult rv = FirstTextNode(mFilteredIter, &mIteratorStatus);
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // Keep track of prev and next blocks, just in case
   // the text service blows away the current block.
 
@@ -369,27 +369,26 @@ nsresult TextServicesDocument::LastSelec
     int32_t* aSelLength) {
   NS_ENSURE_TRUE(aSelStatus && aSelOffset && aSelLength, NS_ERROR_NULL_POINTER);
 
   mIteratorStatus = IteratorStatus::eDone;
 
   *aSelStatus = BlockSelectionStatus::eBlockNotFound;
   *aSelOffset = *aSelLength = -1;
 
-  if (!mSelCon || !mIterator) {
+  if (!mSelCon || !mFilteredIter) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<Selection> selection =
       mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
   if (NS_WARN_IF(!selection)) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIContentIterator> iter;
   RefPtr<nsRange> range;
   nsCOMPtr<nsINode> parent;
 
   if (selection->IsCollapsed()) {
     // We have a caret. Check if the caret is in a text node.
     // If it is, make the text node's block the current block.
     // If the caret isn't in a text node, search forwards in
     // the document, till we find a text node.
@@ -406,31 +405,31 @@ nsresult TextServicesDocument::LastSelec
     }
 
     nsresult rv;
     if (parent->IsText()) {
       // The caret is in a text node. Find the beginning
       // of the text block containing this text node and
       // return.
 
-      rv = mIterator->PositionAt(parent);
+      rv = mFilteredIter->PositionAt(parent);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
-      rv = FirstTextNodeInCurrentBlock(mIterator);
+      rv = FirstTextNodeInCurrentBlock(mFilteredIter);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
       mIteratorStatus = IteratorStatus::eValid;
 
-      rv = CreateOffsetTable(&mOffsetTable, mIterator, &mIteratorStatus,
+      rv = CreateOffsetTable(&mOffsetTable, mFilteredIter, &mIteratorStatus,
                              mExtent, nullptr);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
       rv = GetSelection(aSelStatus, aSelOffset, aSelLength);
 
@@ -455,53 +454,53 @@ nsresult TextServicesDocument::LastSelec
       }
 
       if (range->Collapsed()) {
         // If we get here, the range is collapsed because there is nothing after
         // the caret! Just return NS_OK;
         return NS_OK;
       }
 
-      rv = CreateContentIterator(range, getter_AddRefs(iter));
+      RefPtr<FilteredContentIterator> filteredIter;
+      rv = CreateFilteredContentIterator(range, getter_AddRefs(filteredIter));
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
-      iter->First();
+      filteredIter->First();
 
       nsIContent* content = nullptr;
-      while (!iter->IsDone()) {
-        nsINode* currentNode = iter->GetCurrentNode();
+      for (; !filteredIter->IsDone(); filteredIter->Next()) {
+        nsINode* currentNode = filteredIter->GetCurrentNode();
         if (currentNode->IsText()) {
           content = currentNode->AsContent();
           break;
         }
-        iter->Next();
       }
 
       if (!content) {
         return NS_OK;
       }
 
-      rv = mIterator->PositionAt(content);
+      rv = mFilteredIter->PositionAt(content);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
-      rv = FirstTextNodeInCurrentBlock(mIterator);
+      rv = FirstTextNodeInCurrentBlock(mFilteredIter);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
       mIteratorStatus = IteratorStatus::eValid;
 
-      rv = CreateOffsetTable(&mOffsetTable, mIterator, &mIteratorStatus,
+      rv = CreateOffsetTable(&mOffsetTable, mFilteredIter, &mIteratorStatus,
                              mExtent, nullptr);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
       rv = GetSelection(aSelStatus, aSelOffset, aSelLength);
 
@@ -536,59 +535,59 @@ nsresult TextServicesDocument::LastSelec
     range = selection->GetRangeAt(i);
 
     if (!range) {
       return NS_OK;  // XXX Really?
     }
 
     // Create an iterator for the range.
 
-    nsresult rv = CreateContentIterator(range, getter_AddRefs(iter));
+    RefPtr<FilteredContentIterator> filteredIter;
+    nsresult rv =
+        CreateFilteredContentIterator(range, getter_AddRefs(filteredIter));
 
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    iter->Last();
+    filteredIter->Last();
 
     // Now walk through the range till we find a text node.
 
-    while (!iter->IsDone()) {
-      if (iter->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
+    for (; !filteredIter->IsDone(); filteredIter->Prev()) {
+      if (filteredIter->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
         // We found a text node, so position the document's
         // iterator at the beginning of the block, then get
         // the selection in terms of the string offset.
 
-        rv = mIterator->PositionAt(iter->GetCurrentNode());
+        rv = mFilteredIter->PositionAt(filteredIter->GetCurrentNode());
 
         if (NS_FAILED(rv)) {
           return rv;
         }
 
-        rv = FirstTextNodeInCurrentBlock(mIterator);
+        rv = FirstTextNodeInCurrentBlock(mFilteredIter);
 
         if (NS_FAILED(rv)) {
           return rv;
         }
 
         mIteratorStatus = IteratorStatus::eValid;
 
-        rv = CreateOffsetTable(&mOffsetTable, mIterator, &mIteratorStatus,
+        rv = CreateOffsetTable(&mOffsetTable, mFilteredIter, &mIteratorStatus,
                                mExtent, nullptr);
 
         if (NS_FAILED(rv)) {
           return rv;
         }
 
         rv = GetSelection(aSelStatus, aSelOffset, aSelLength);
 
         return rv;
       }
-
-      iter->Prev();
     }
   }
 
   // If we get here, we didn't find any text node in the selection!
   // Create a range that extends from the end of the selection,
   // to the end of the document, then iterate forwards through
   // it till you find a text node!
 
@@ -611,82 +610,82 @@ nsresult TextServicesDocument::LastSelec
   }
 
   if (range->Collapsed()) {
     // If we get here, the range is collapsed because there is nothing after
     // the current selection! Just return NS_OK;
     return NS_OK;
   }
 
-  nsresult rv = CreateContentIterator(range, getter_AddRefs(iter));
+  RefPtr<FilteredContentIterator> filteredIter;
+  nsresult rv =
+      CreateFilteredContentIterator(range, getter_AddRefs(filteredIter));
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  iter->First();
-
-  while (!iter->IsDone()) {
-    if (iter->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
+  filteredIter->First();
+
+  for (; !filteredIter->IsDone(); filteredIter->Next()) {
+    if (filteredIter->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
       // We found a text node! Adjust the document's iterator to point
       // to the beginning of its text block, then get the current selection.
-      rv = mIterator->PositionAt(iter->GetCurrentNode());
+      rv = mFilteredIter->PositionAt(filteredIter->GetCurrentNode());
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
-      rv = FirstTextNodeInCurrentBlock(mIterator);
+      rv = FirstTextNodeInCurrentBlock(mFilteredIter);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
       mIteratorStatus = IteratorStatus::eValid;
 
-      rv = CreateOffsetTable(&mOffsetTable, mIterator, &mIteratorStatus,
+      rv = CreateOffsetTable(&mOffsetTable, mFilteredIter, &mIteratorStatus,
                              mExtent, nullptr);
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
       rv = GetSelection(aSelStatus, aSelOffset, aSelLength);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       return NS_OK;
     }
-
-    iter->Next();
   }
 
   // If we get here, we didn't find any block before or inside
   // the selection! Just return OK.
   return NS_OK;
 }
 
 nsresult TextServicesDocument::PrevBlock() {
-  NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(mFilteredIter, NS_ERROR_FAILURE);
 
   if (mIteratorStatus == IteratorStatus::eDone) {
     return NS_OK;
   }
 
   switch (mIteratorStatus) {
     case IteratorStatus::eValid:
     case IteratorStatus::eNext: {
-      nsresult rv = FirstTextNodeInPrevBlock(mIterator);
+      nsresult rv = FirstTextNodeInPrevBlock(mFilteredIter);
 
       if (NS_FAILED(rv)) {
         mIteratorStatus = IteratorStatus::eDone;
         return rv;
       }
 
-      if (mIterator->IsDone()) {
+      if (mFilteredIter->IsDone()) {
         mIteratorStatus = IteratorStatus::eDone;
         return NS_OK;
       }
 
       mIteratorStatus = IteratorStatus::eValid;
       break;
     }
     case IteratorStatus::ePrev:
@@ -715,34 +714,34 @@ nsresult TextServicesDocument::PrevBlock
     mNextTextBlock = nullptr;
   }
 
   // XXX The result of GetFirstTextNodeInNextBlock() or NS_OK.
   return rv;
 }
 
 nsresult TextServicesDocument::NextBlock() {
-  NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(mFilteredIter, NS_ERROR_FAILURE);
 
   if (mIteratorStatus == IteratorStatus::eDone) {
     return NS_OK;
   }
 
   switch (mIteratorStatus) {
     case IteratorStatus::eValid: {
       // Advance the iterator to the next text block.
 
-      nsresult rv = FirstTextNodeInNextBlock(mIterator);
+      nsresult rv = FirstTextNodeInNextBlock(mFilteredIter);
 
       if (NS_FAILED(rv)) {
         mIteratorStatus = IteratorStatus::eDone;
         return rv;
       }
 
-      if (mIterator->IsDone()) {
+      if (mFilteredIter->IsDone()) {
         mIteratorStatus = IteratorStatus::eDone;
         return NS_OK;
       }
 
       mIteratorStatus = IteratorStatus::eValid;
       break;
     }
     case IteratorStatus::eNext:
@@ -781,17 +780,17 @@ nsresult TextServicesDocument::NextBlock
   return rv;
 }
 
 nsresult TextServicesDocument::IsDone(bool* aIsDone) {
   NS_ENSURE_TRUE(aIsDone, NS_ERROR_NULL_POINTER);
 
   *aIsDone = false;
 
-  NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(mFilteredIter, NS_ERROR_FAILURE);
 
   *aIsDone = mIteratorStatus == IteratorStatus::eDone;
 
   return NS_OK;
 }
 
 nsresult TextServicesDocument::SetSelection(int32_t aOffset, int32_t aLength) {
   NS_ENSURE_TRUE(mSelCon && aOffset >= 0 && aLength >= 0, NS_ERROR_FAILURE);
@@ -938,17 +937,17 @@ nsresult TextServicesDocument::DeleteSel
 
     if (i != mSelStartIndex && i != mSelEndIndex) {
       // The entire entry is contained in the selection. Mark the
       // entry invalid.
       entry->mIsValid = false;
     }
   }
 
-  // Make sure mIterator always points to something valid!
+  // Make sure mFilteredIter always points to something valid!
 
   AdjustContentIterator();
 
   // Now delete the actual content!
   RefPtr<TextEditor> textEditor = mTextEditor;
   nsresult rv = textEditor->DeleteSelectionAsAction(nsIEditor::ePrevious,
                                                     nsIEditor::eStrip);
   if (NS_FAILED(rv)) {
@@ -977,34 +976,35 @@ nsresult TextServicesDocument::DeleteSel
 
       nsCOMPtr<nsIContent> curContent;
 
       if (mIteratorStatus != IteratorStatus::eDone) {
         // The old iterator is still pointing to something valid,
         // so get its current node so we can restore it after we
         // create the new iterator!
 
-        curContent = mIterator->GetCurrentNode()
-                         ? mIterator->GetCurrentNode()->AsContent()
+        curContent = mFilteredIter->GetCurrentNode()
+                         ? mFilteredIter->GetCurrentNode()->AsContent()
                          : nullptr;
       }
 
       // Create the new iterator.
 
-      rv = CreateContentIterator(mExtent, getter_AddRefs(mIterator));
+      rv =
+          CreateFilteredContentIterator(mExtent, getter_AddRefs(mFilteredIter));
 
       if (NS_FAILED(rv)) {
         return rv;
       }
 
       // Now make the new iterator point to the content node
       // the old one was pointing at.
 
       if (curContent) {
-        rv = mIterator->PositionAt(curContent);
+        rv = mFilteredIter->PositionAt(curContent);
 
         if (NS_FAILED(rv)) {
           mIteratorStatus = IteratorStatus::eDone;
         } else {
           mIteratorStatus = IteratorStatus::eValid;
         }
       }
     }
@@ -1235,17 +1235,17 @@ nsresult TextServicesDocument::InsertTex
       return rv;
     }
   }
 
   return NS_OK;
 }
 
 void TextServicesDocument::DidDeleteNode(nsINode* aChild) {
-  if (NS_WARN_IF(!mIterator)) {
+  if (NS_WARN_IF(!mFilteredIter)) {
     return;
   }
 
   int32_t nodeIndex = 0;
   bool hasEntry = false;
   OffsetEntry* entry;
 
   nsresult rv =
@@ -1255,17 +1255,17 @@ void TextServicesDocument::DidDeleteNode
   }
 
   if (!hasEntry) {
     // It's okay if the node isn't in the offset table, the
     // editor could be cleaning house.
     return;
   }
 
-  nsINode* node = mIterator->GetCurrentNode();
+  nsINode* node = mFilteredIter->GetCurrentNode();
   if (node && node == aChild && mIteratorStatus != IteratorStatus::eDone) {
     // XXX: This should never really happen because
     // AdjustContentIterator() should have been called prior
     // to the delete to try and position the iterator on the
     // next valid text node in the offset table, and if there
     // wasn't a next, it would've set mIteratorStatus to eIsDone.
 
     NS_ERROR("DeleteNode called for current iterator node.");
@@ -1360,49 +1360,49 @@ void TextServicesDocument::DidJoinNodes(
     if (entry->mIsValid) {
       entry->mNodeOffset += nodeLength;
     }
   }
 
   // Now check to see if the iterator is pointing to the
   // left node. If it is, make it point to the right node!
 
-  if (mIterator->GetCurrentNode() == &aLeftNode) {
-    mIterator->PositionAt(&aRightNode);
+  if (mFilteredIter->GetCurrentNode() == &aLeftNode) {
+    mFilteredIter->PositionAt(&aRightNode);
   }
 }
 
-nsresult TextServicesDocument::CreateContentIterator(
-    nsRange* aRange, nsIContentIterator** aIterator) {
-  NS_ENSURE_TRUE(aRange && aIterator, NS_ERROR_NULL_POINTER);
-
-  *aIterator = nullptr;
+nsresult TextServicesDocument::CreateFilteredContentIterator(
+    nsRange* aRange, FilteredContentIterator** aFilteredIter) {
+  NS_ENSURE_TRUE(aRange && aFilteredIter, NS_ERROR_NULL_POINTER);
+
+  *aFilteredIter = nullptr;
 
   UniquePtr<nsComposeTxtSrvFilter> composeFilter;
   switch (mTxtSvcFilterType) {
     case nsIEditorSpellCheck::FILTERTYPE_NORMAL:
       composeFilter = nsComposeTxtSrvFilter::CreateNormalFilter();
       break;
     case nsIEditorSpellCheck::FILTERTYPE_MAIL:
       composeFilter = nsComposeTxtSrvFilter::CreateMailFilter();
       break;
   }
 
-  // Create a nsFilteredContentIterator
+  // Create a FilteredContentIterator
   // This class wraps the ContentIterator in order to give itself a chance
   // to filter out certain content nodes
-  RefPtr<nsFilteredContentIterator> filter =
-      new nsFilteredContentIterator(std::move(composeFilter));
+  RefPtr<FilteredContentIterator> filter =
+      new FilteredContentIterator(std::move(composeFilter));
 
   nsresult rv = filter->Init(aRange);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  filter.forget(aIterator);
+  filter.forget(aFilteredIter);
   return NS_OK;
 }
 
 Element* TextServicesDocument::GetDocumentContentRootNode() const {
   if (NS_WARN_IF(!mDocument)) {
     return nullptr;
   }
 
@@ -1471,32 +1471,32 @@ TextServicesDocument::CreateDocumentCont
                                      getter_AddRefs(range));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
   return range.forget();
 }
 
 nsresult TextServicesDocument::CreateDocumentContentIterator(
-    nsIContentIterator** aIterator) {
-  NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
+    FilteredContentIterator** aFilteredIter) {
+  NS_ENSURE_TRUE(aFilteredIter, NS_ERROR_NULL_POINTER);
 
   RefPtr<nsRange> range = CreateDocumentContentRange();
   if (NS_WARN_IF(!range)) {
-    *aIterator = nullptr;
+    *aFilteredIter = nullptr;
     return NS_ERROR_FAILURE;
   }
 
-  return CreateContentIterator(range, aIterator);
+  return CreateFilteredContentIterator(range, aFilteredIter);
 }
 
 nsresult TextServicesDocument::AdjustContentIterator() {
-  NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsINode> node = mIterator->GetCurrentNode();
+  NS_ENSURE_TRUE(mFilteredIter, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsINode> node = mFilteredIter->GetCurrentNode();
   NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
   size_t tcount = mOffsetTable.Length();
 
   nsINode* prevValidNode = nullptr;
   nsINode* nextValidNode = nullptr;
   bool foundEntry = false;
   OffsetEntry* entry;
@@ -1535,79 +1535,66 @@ nsresult TextServicesDocument::AdjustCon
     }
   } else if (nextValidNode) {
     if (nextValidNode->IsContent()) {
       content = nextValidNode->AsContent();
     }
   }
 
   if (content) {
-    nsresult rv = mIterator->PositionAt(content);
+    nsresult rv = mFilteredIter->PositionAt(content);
 
     if (NS_FAILED(rv)) {
       mIteratorStatus = IteratorStatus::eDone;
     } else {
       mIteratorStatus = IteratorStatus::eValid;
     }
     return rv;
   }
 
   // If we get here, there aren't any valid entries
   // in the offset table! Try to position the iterator
   // on the next text block first, then previous if
   // one doesn't exist!
 
   if (mNextTextBlock) {
-    nsresult rv = mIterator->PositionAt(mNextTextBlock);
+    nsresult rv = mFilteredIter->PositionAt(mNextTextBlock);
 
     if (NS_FAILED(rv)) {
       mIteratorStatus = IteratorStatus::eDone;
       return rv;
     }
 
     mIteratorStatus = IteratorStatus::eNext;
   } else if (mPrevTextBlock) {
-    nsresult rv = mIterator->PositionAt(mPrevTextBlock);
+    nsresult rv = mFilteredIter->PositionAt(mPrevTextBlock);
 
     if (NS_FAILED(rv)) {
       mIteratorStatus = IteratorStatus::eDone;
       return rv;
     }
 
     mIteratorStatus = IteratorStatus::ePrev;
   } else {
     mIteratorStatus = IteratorStatus::eDone;
   }
   return NS_OK;
 }
 
 // static
-bool TextServicesDocument::DidSkip(nsIContentIterator* aFilteredIter) {
-  // We can assume here that the Iterator is a nsFilteredContentIterator because
-  // all the iterator are created in CreateContentIterator which create a
-  // nsFilteredContentIterator
-  // So if the iterator bailed on one of the "filtered" content nodes then we
-  // consider that to be a block and bail with true
-  if (aFilteredIter) {
-    nsFilteredContentIterator* filter =
-        static_cast<nsFilteredContentIterator*>(aFilteredIter);
-    if (filter && filter->DidSkip()) {
-      return true;
-    }
-  }
-  return false;
+bool TextServicesDocument::DidSkip(FilteredContentIterator* aFilteredIter) {
+  return aFilteredIter && aFilteredIter->DidSkip();
 }
 
 // static
-void TextServicesDocument::ClearDidSkip(nsIContentIterator* aFilteredIter) {
+void TextServicesDocument::ClearDidSkip(
+    FilteredContentIterator* aFilteredIter) {
   // Clear filter's skip flag
   if (aFilteredIter) {
-    nsFilteredContentIterator* filter =
-        static_cast<nsFilteredContentIterator*>(aFilteredIter);
-    filter->ClearDidSkip();
+    aFilteredIter->ClearDidSkip();
   }
 }
 
 // static
 bool TextServicesDocument::IsBlockNode(nsIContent* aContent) {
   if (!aContent) {
     NS_ERROR("How did a null pointer get passed to IsBlockNode?");
     return false;
@@ -1919,89 +1906,85 @@ nsresult TextServicesDocument::GetCollap
   // this range, with its initial position set to the closest
   // child of this non-text node. Then look for the closest text
   // node.
 
   nsresult rv = nsRange::CreateRange(eStart->mNode, eStartOffset, eEnd->mNode,
                                      eEndOffset, getter_AddRefs(range));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIContentIterator> iter;
-  rv = CreateContentIterator(range, getter_AddRefs(iter));
+  RefPtr<FilteredContentIterator> filteredIter;
+  rv = CreateFilteredContentIterator(range, getter_AddRefs(filteredIter));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIContent* saveNode;
   if (parent->HasChildren()) {
     // XXX: We need to make sure that all of parent's
     //      children are in the text block.
 
     // If the parent has children, position the iterator
     // on the child that is to the left of the offset.
 
     nsIContent* content = range->GetChildAtStartOffset();
     if (content && parent->GetFirstChild() != content) {
       content = content->GetPreviousSibling();
     }
     NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 
-    rv = iter->PositionAt(content);
+    rv = filteredIter->PositionAt(content);
     NS_ENSURE_SUCCESS(rv, rv);
 
     saveNode = content;
   } else {
     // The parent has no children, so position the iterator
     // on the parent.
     NS_ENSURE_TRUE(parent->IsContent(), NS_ERROR_FAILURE);
     nsCOMPtr<nsIContent> content = parent->AsContent();
 
-    rv = iter->PositionAt(content);
+    rv = filteredIter->PositionAt(content);
     NS_ENSURE_SUCCESS(rv, rv);
 
     saveNode = content;
   }
 
   // Now iterate to the left, towards the beginning of
   // the text block, to find the first text node you
   // come across.
 
   nsIContent* node = nullptr;
-  while (!iter->IsDone()) {
-    nsINode* current = iter->GetCurrentNode();
+  for (; !filteredIter->IsDone(); filteredIter->Prev()) {
+    nsINode* current = filteredIter->GetCurrentNode();
     if (current->NodeType() == nsINode::TEXT_NODE) {
       node = current->AsContent();
       break;
     }
-
-    iter->Prev();
   }
 
   if (node) {
     // We found a node, now set the offset to the end
     // of the text node.
     offset = node->TextLength();
   } else {
     // We should never really get here, but I'm paranoid.
 
     // We didn't find a text node above, so iterate to
     // the right, towards the end of the text block, looking
     // for a text node.
 
-    rv = iter->PositionAt(saveNode);
+    rv = filteredIter->PositionAt(saveNode);
     NS_ENSURE_SUCCESS(rv, rv);
 
     node = nullptr;
-    while (!iter->IsDone()) {
-      nsINode* current = iter->GetCurrentNode();
+    for (; !filteredIter->IsDone(); filteredIter->Next()) {
+      nsINode* current = filteredIter->GetCurrentNode();
 
       if (current->NodeType() == nsINode::TEXT_NODE) {
         node = current->AsContent();
         break;
       }
-
-      iter->Next();
     }
 
     NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
 
     // We found a text node, so set the offset to
     // the beginning of the node.
 
     offset = 0;
@@ -2159,66 +2142,61 @@ nsresult TextServicesDocument::GetUncoll
 
   nsresult rv = nsRange::CreateRange(p1, o1, p2, o2, getter_AddRefs(range));
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Now iterate over this range to figure out the selection's
   // block offset and length.
 
-  nsCOMPtr<nsIContentIterator> iter;
-
-  rv = CreateContentIterator(range, getter_AddRefs(iter));
+  RefPtr<FilteredContentIterator> filteredIter;
+  rv = CreateFilteredContentIterator(range, getter_AddRefs(filteredIter));
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Find the first text node in the range.
 
   bool found;
   nsCOMPtr<nsIContent> content;
 
-  iter->First();
+  filteredIter->First();
 
   if (!p1->IsText()) {
     found = false;
 
-    while (!iter->IsDone()) {
-      nsINode* node = iter->GetCurrentNode();
+    for (; !filteredIter->IsDone(); filteredIter->Next()) {
+      nsINode* node = filteredIter->GetCurrentNode();
 
       if (node->IsText()) {
         p1 = node;
         o1 = 0;
         found = true;
 
         break;
       }
-
-      iter->Next();
     }
 
     NS_ENSURE_TRUE(found, NS_ERROR_FAILURE);
   }
 
   // Find the last text node in the range.
 
-  iter->Last();
+  filteredIter->Last();
 
   if (!p2->IsText()) {
     found = false;
-    while (!iter->IsDone()) {
-      nsINode* node = iter->GetCurrentNode();
+    for (; !filteredIter->IsDone(); filteredIter->Prev()) {
+      nsINode* node = filteredIter->GetCurrentNode();
       if (node->IsText()) {
         p2 = node;
         o2 = p2->Length();
         found = true;
 
         break;
       }
-
-      iter->Prev();
     }
 
     NS_ENSURE_TRUE(found, NS_ERROR_FAILURE);
   }
 
   found = false;
   *aSelLength = 0;
 
@@ -2281,236 +2259,233 @@ nsresult TextServicesDocument::GetRangeE
   NS_IF_ADDREF(*aEndContainer = aRange->GetEndContainer());
   NS_ENSURE_TRUE(aEndContainer, NS_ERROR_FAILURE);
 
   *aEndOffset = static_cast<int32_t>(aRange->EndOffset());
   return NS_OK;
 }
 
 // static
-nsresult TextServicesDocument::FirstTextNode(nsIContentIterator* aIterator,
-                                             IteratorStatus* aIteratorStatus) {
+nsresult TextServicesDocument::FirstTextNode(
+    FilteredContentIterator* aFilteredIter, IteratorStatus* aIteratorStatus) {
   if (aIteratorStatus) {
     *aIteratorStatus = IteratorStatus::eDone;
   }
 
-  aIterator->First();
-
-  while (!aIterator->IsDone()) {
-    if (aIterator->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
+  for (aFilteredIter->First(); !aFilteredIter->IsDone();
+       aFilteredIter->Next()) {
+    if (aFilteredIter->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
       if (aIteratorStatus) {
         *aIteratorStatus = IteratorStatus::eValid;
       }
       break;
     }
-    aIterator->Next();
   }
 
   return NS_OK;
 }
 
 // static
-nsresult TextServicesDocument::LastTextNode(nsIContentIterator* aIterator,
-                                            IteratorStatus* aIteratorStatus) {
+nsresult TextServicesDocument::LastTextNode(
+    FilteredContentIterator* aFilteredIter, IteratorStatus* aIteratorStatus) {
   if (aIteratorStatus) {
     *aIteratorStatus = IteratorStatus::eDone;
   }
 
-  aIterator->Last();
-
-  while (!aIterator->IsDone()) {
-    if (aIterator->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
+  for (aFilteredIter->Last(); !aFilteredIter->IsDone(); aFilteredIter->Prev()) {
+    if (aFilteredIter->GetCurrentNode()->NodeType() == nsINode::TEXT_NODE) {
       if (aIteratorStatus) {
         *aIteratorStatus = IteratorStatus::eValid;
       }
       break;
     }
-    aIterator->Prev();
   }
 
   return NS_OK;
 }
 
 // static
 nsresult TextServicesDocument::FirstTextNodeInCurrentBlock(
-    nsIContentIterator* aIter) {
-  NS_ENSURE_TRUE(aIter, NS_ERROR_NULL_POINTER);
-
-  ClearDidSkip(aIter);
+    FilteredContentIterator* aFilteredIter) {
+  NS_ENSURE_TRUE(aFilteredIter, NS_ERROR_NULL_POINTER);
+
+  ClearDidSkip(aFilteredIter);
 
   nsCOMPtr<nsIContent> last;
 
   // Walk backwards over adjacent text nodes until
   // we hit a block boundary:
 
-  while (!aIter->IsDone()) {
-    nsCOMPtr<nsIContent> content = aIter->GetCurrentNode()->IsContent()
-                                       ? aIter->GetCurrentNode()->AsContent()
-                                       : nullptr;
+  while (!aFilteredIter->IsDone()) {
+    nsCOMPtr<nsIContent> content =
+        aFilteredIter->GetCurrentNode()->IsContent()
+            ? aFilteredIter->GetCurrentNode()->AsContent()
+            : nullptr;
     if (last && IsBlockNode(content)) {
       break;
     }
     if (IsTextNode(content)) {
       if (last && !HasSameBlockNodeParent(content, last)) {
         // We're done, the current text node is in a
         // different block.
         break;
       }
       last = content;
     }
 
-    aIter->Prev();
-
-    if (DidSkip(aIter)) {
+    aFilteredIter->Prev();
+
+    if (DidSkip(aFilteredIter)) {
       break;
     }
   }
 
   if (last) {
-    aIter->PositionAt(last);
+    aFilteredIter->PositionAt(last);
   }
 
   // XXX: What should we return if last is null?
 
   return NS_OK;
 }
 
 // static
 nsresult TextServicesDocument::FirstTextNodeInPrevBlock(
-    nsIContentIterator* aIterator) {
-  NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
-
-  // XXX: What if mIterator is not currently on a text node?
-
-  // Make sure mIterator is pointing to the first text node in the
+    FilteredContentIterator* aFilteredIter) {
+  NS_ENSURE_TRUE(aFilteredIter, NS_ERROR_NULL_POINTER);
+
+  // XXX: What if mFilteredIter is not currently on a text node?
+
+  // Make sure mFilteredIter is pointing to the first text node in the
   // current block:
 
-  nsresult rv = FirstTextNodeInCurrentBlock(aIterator);
+  nsresult rv = FirstTextNodeInCurrentBlock(aFilteredIter);
 
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
-  // Point mIterator to the first node before the first text node:
-
-  aIterator->Prev();
-
-  if (aIterator->IsDone()) {
+  // Point mFilteredIter to the first node before the first text node:
+
+  aFilteredIter->Prev();
+
+  if (aFilteredIter->IsDone()) {
     return NS_ERROR_FAILURE;
   }
 
   // Now find the first text node of the next block:
 
-  return FirstTextNodeInCurrentBlock(aIterator);
+  return FirstTextNodeInCurrentBlock(aFilteredIter);
 }
 
 // static
 nsresult TextServicesDocument::FirstTextNodeInNextBlock(
-    nsIContentIterator* aIterator) {
+    FilteredContentIterator* aFilteredIter) {
   nsCOMPtr<nsIContent> prev;
   bool crossedBlockBoundary = false;
 
-  NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
-
-  ClearDidSkip(aIterator);
-
-  while (!aIterator->IsDone()) {
+  NS_ENSURE_TRUE(aFilteredIter, NS_ERROR_NULL_POINTER);
+
+  ClearDidSkip(aFilteredIter);
+
+  while (!aFilteredIter->IsDone()) {
     nsCOMPtr<nsIContent> content =
-        aIterator->GetCurrentNode()->IsContent()
-            ? aIterator->GetCurrentNode()->AsContent()
+        aFilteredIter->GetCurrentNode()->IsContent()
+            ? aFilteredIter->GetCurrentNode()->AsContent()
             : nullptr;
 
     if (IsTextNode(content)) {
       if (crossedBlockBoundary ||
           (prev && !HasSameBlockNodeParent(prev, content))) {
         break;
       }
       prev = content;
     } else if (!crossedBlockBoundary && IsBlockNode(content)) {
       crossedBlockBoundary = true;
     }
 
-    aIterator->Next();
-
-    if (!crossedBlockBoundary && DidSkip(aIterator)) {
+    aFilteredIter->Next();
+
+    if (!crossedBlockBoundary && DidSkip(aFilteredIter)) {
       crossedBlockBoundary = true;
     }
   }
 
   return NS_OK;
 }
 
 nsresult TextServicesDocument::GetFirstTextNodeInPrevBlock(
     nsIContent** aContent) {
   NS_ENSURE_TRUE(aContent, NS_ERROR_NULL_POINTER);
 
   *aContent = 0;
 
   // Save the iterator's current content node so we can restore
   // it when we are done:
 
-  nsINode* node = mIterator->GetCurrentNode();
-
-  nsresult rv = FirstTextNodeInPrevBlock(mIterator);
+  nsINode* node = mFilteredIter->GetCurrentNode();
+
+  nsresult rv = FirstTextNodeInPrevBlock(mFilteredIter);
 
   if (NS_FAILED(rv)) {
     // Try to restore the iterator before returning.
-    mIterator->PositionAt(node);
+    mFilteredIter->PositionAt(node);
     return rv;
   }
 
-  if (!mIterator->IsDone()) {
+  if (!mFilteredIter->IsDone()) {
     nsCOMPtr<nsIContent> current =
-        mIterator->GetCurrentNode()->IsContent()
-            ? mIterator->GetCurrentNode()->AsContent()
+        mFilteredIter->GetCurrentNode()->IsContent()
+            ? mFilteredIter->GetCurrentNode()->AsContent()
             : nullptr;
     current.forget(aContent);
   }
 
   // Restore the iterator:
 
-  return mIterator->PositionAt(node);
+  return mFilteredIter->PositionAt(node);
 }
 
 nsresult TextServicesDocument::GetFirstTextNodeInNextBlock(
     nsIContent** aContent) {
   NS_ENSURE_TRUE(aContent, NS_ERROR_NULL_POINTER);
 
   *aContent = 0;
 
   // Save the iterator's current content node so we can restore
   // it when we are done:
 
-  nsINode* node = mIterator->GetCurrentNode();
-
-  nsresult rv = FirstTextNodeInNextBlock(mIterator);
+  nsINode* node = mFilteredIter->GetCurrentNode();
+
+  nsresult rv = FirstTextNodeInNextBlock(mFilteredIter);
 
   if (NS_FAILED(rv)) {
     // Try to restore the iterator before returning.
-    mIterator->PositionAt(node);
+    mFilteredIter->PositionAt(node);
     return rv;
   }
 
-  if (!mIterator->IsDone()) {
+  if (!mFilteredIter->IsDone()) {
     nsCOMPtr<nsIContent> current =
-        mIterator->GetCurrentNode()->IsContent()
-            ? mIterator->GetCurrentNode()->AsContent()
+        mFilteredIter->GetCurrentNode()->IsContent()
+            ? mFilteredIter->GetCurrentNode()->AsContent()
             : nullptr;
     current.forget(aContent);
   }
 
   // Restore the iterator:
-  return mIterator->PositionAt(node);
+  return mFilteredIter->PositionAt(node);
 }
 
 nsresult TextServicesDocument::CreateOffsetTable(
-    nsTArray<OffsetEntry*>* aOffsetTable, nsIContentIterator* aIterator,
-    IteratorStatus* aIteratorStatus, nsRange* aIterRange, nsString* aStr) {
+    nsTArray<OffsetEntry*>* aOffsetTable,
+    FilteredContentIterator* aFilteredIter, IteratorStatus* aIteratorStatus,
+    nsRange* aIterRange, nsString* aStr) {
   nsCOMPtr<nsIContent> first;
   nsCOMPtr<nsIContent> prev;
 
-  NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
+  NS_ENSURE_TRUE(aFilteredIter, NS_ERROR_NULL_POINTER);
 
   ClearOffsetTable(aOffsetTable);
 
   if (aStr) {
     aStr->Truncate();
   }
 
   if (*aIteratorStatus == IteratorStatus::eDone) {
@@ -2531,28 +2506,28 @@ nsresult TextServicesDocument::CreateOff
 
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // The text service could have added text nodes to the beginning
   // of the current block and called this method again. Make sure
   // we really are at the beginning of the current block:
 
-  nsresult rv = FirstTextNodeInCurrentBlock(aIterator);
+  nsresult rv = FirstTextNodeInCurrentBlock(aFilteredIter);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   int32_t offset = 0;
 
-  ClearDidSkip(aIterator);
-
-  while (!aIterator->IsDone()) {
+  ClearDidSkip(aFilteredIter);
+
+  while (!aFilteredIter->IsDone()) {
     nsCOMPtr<nsIContent> content =
-        aIterator->GetCurrentNode()->IsContent()
-            ? aIterator->GetCurrentNode()->AsContent()
+        aFilteredIter->GetCurrentNode()->IsContent()
+            ? aFilteredIter->GetCurrentNode()->AsContent()
             : nullptr;
     if (IsTextNode(content)) {
       if (prev && !HasSameBlockNodeParent(prev, content)) {
         break;
       }
 
       nsString str;
       content->GetNodeValue(str);
@@ -2604,27 +2579,27 @@ nsresult TextServicesDocument::CreateOff
       }
     }
     // XXX This should be checked before IsTextNode(), but IsBlockNode() returns
     //     true even if content is a text node.  See bug 1311934.
     else if (IsBlockNode(content)) {
       break;
     }
 
-    aIterator->Next();
-
-    if (DidSkip(aIterator)) {
+    aFilteredIter->Next();
+
+    if (DidSkip(aFilteredIter)) {
       break;
     }
   }
 
   if (first) {
     // Always leave the iterator pointing at the first
     // text node of the current block!
-    aIterator->PositionAt(first);
+    aFilteredIter->PositionAt(first);
   } else {
     // If we never ran across a text node, the iterator
     // might have been pointing to something invalid to
     // begin with.
     *aIteratorStatus = IteratorStatus::eDone;
   }
 
   return NS_OK;
--- a/editor/spellchecker/TextServicesDocument.h
+++ b/editor/spellchecker/TextServicesDocument.h
@@ -10,24 +10,24 @@
 #include "nsCycleCollectionParticipant.h"
 #include "nsIEditActionListener.h"
 #include "nsISupportsImpl.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
 #include "nscore.h"
 
 class nsIContent;
-class nsIContentIterator;
 class nsIEditor;
 class nsINode;
 class nsISelectionController;
 class nsRange;
 
 namespace mozilla {
 
+class FilteredContentIterator;
 class OffsetEntry;
 class TextEditor;
 
 namespace dom {
 class Document;
 class Element;
 };
 
@@ -46,17 +46,17 @@ class TextServicesDocument final : publi
     ePrev,
     // No TN in CB, I points to first TN in next block.
     eNext,
   };
 
   RefPtr<dom::Document> mDocument;
   nsCOMPtr<nsISelectionController> mSelCon;
   RefPtr<TextEditor> mTextEditor;
-  nsCOMPtr<nsIContentIterator> mIterator;
+  RefPtr<FilteredContentIterator> mFilteredIter;
   nsCOMPtr<nsIContent> mPrevTextBlock;
   nsCOMPtr<nsIContent> mNextTextBlock;
   nsTArray<OffsetEntry*> mOffsetTable;
   RefPtr<nsRange> mExtent;
   uint32_t mTxtSvcFilterType;
 
   int32_t mSelStartIndex;
   int32_t mSelStartOffset;
@@ -226,44 +226,48 @@ class TextServicesDocument final : publi
   void DidJoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
 
   static nsresult GetRangeEndPoints(nsRange* aRange, nsINode** aStartContainer,
                                     int32_t* aStartOffset,
                                     nsINode** aEndContainer,
                                     int32_t* aEndOffset);
 
  private:
-  nsresult CreateContentIterator(nsRange* aRange,
-                                 nsIContentIterator** aIterator);
+  nsresult CreateFilteredContentIterator(
+      nsRange* aRange, FilteredContentIterator** aFilteredIter);
 
   dom::Element* GetDocumentContentRootNode() const;
   already_AddRefed<nsRange> CreateDocumentContentRange();
   already_AddRefed<nsRange> CreateDocumentContentRootToNodeOffsetRange(
       nsINode* aParent, uint32_t aOffset, bool aToStart);
-  nsresult CreateDocumentContentIterator(nsIContentIterator** aIterator);
+  nsresult CreateDocumentContentIterator(
+      FilteredContentIterator** aFilteredIter);
 
   nsresult AdjustContentIterator();
 
-  static nsresult FirstTextNode(nsIContentIterator* aIterator,
+  static nsresult FirstTextNode(FilteredContentIterator* aFilteredIter,
                                 IteratorStatus* aIteratorStatus);
-  static nsresult LastTextNode(nsIContentIterator* aIterator,
+  static nsresult LastTextNode(FilteredContentIterator* aFilteredIter,
                                IteratorStatus* aIteratorStatus);
 
-  static nsresult FirstTextNodeInCurrentBlock(nsIContentIterator* aIterator);
-  static nsresult FirstTextNodeInPrevBlock(nsIContentIterator* aIterator);
-  static nsresult FirstTextNodeInNextBlock(nsIContentIterator* aIterator);
+  static nsresult FirstTextNodeInCurrentBlock(
+      FilteredContentIterator* aFilteredIter);
+  static nsresult FirstTextNodeInPrevBlock(
+      FilteredContentIterator* aFilteredIter);
+  static nsresult FirstTextNodeInNextBlock(
+      FilteredContentIterator* aFilteredIter);
 
   nsresult GetFirstTextNodeInPrevBlock(nsIContent** aContent);
   nsresult GetFirstTextNodeInNextBlock(nsIContent** aContent);
 
   static bool IsBlockNode(nsIContent* aContent);
   static bool IsTextNode(nsIContent* aContent);
 
-  static bool DidSkip(nsIContentIterator* aFilteredIter);
-  static void ClearDidSkip(nsIContentIterator* aFilteredIter);
+  static bool DidSkip(FilteredContentIterator* aFilteredIter);
+  static void ClearDidSkip(FilteredContentIterator* aFilteredIter);
 
   static bool HasSameBlockNodeParent(nsIContent* aContent1,
                                      nsIContent* aContent2);
 
   nsresult SetSelectionInternal(int32_t aOffset, int32_t aLength,
                                 bool aDoUpdate);
   nsresult GetSelection(BlockSelectionStatus* aSelStatus, int32_t* aSelOffset,
                         int32_t* aSelLength);
@@ -271,17 +275,17 @@ class TextServicesDocument final : publi
                                  int32_t* aSelOffset, int32_t* aSelLength);
   nsresult GetUncollapsedSelection(BlockSelectionStatus* aSelStatus,
                                    int32_t* aSelOffset, int32_t* aSelLength);
 
   bool SelectionIsCollapsed();
   bool SelectionIsValid();
 
   static nsresult CreateOffsetTable(nsTArray<OffsetEntry*>* aOffsetTable,
-                                    nsIContentIterator* aIterator,
+                                    FilteredContentIterator* aFilteredIter,
                                     IteratorStatus* aIteratorStatus,
                                     nsRange* aIterRange, nsString* aStr);
   static nsresult ClearOffsetTable(nsTArray<OffsetEntry*>* aOffsetTable);
 
   static nsresult NodeHasOffsetEntry(nsTArray<OffsetEntry*>* aOffsetTable,
                                      nsINode* aNode, bool* aHasEntry,
                                      int32_t* aEntryIndex);
 
--- a/editor/spellchecker/moz.build
+++ b/editor/spellchecker/moz.build
@@ -14,14 +14,14 @@ XPIDL_MODULE = 'txtsvc'
 
 EXPORTS.mozilla += [
     'EditorSpellCheck.h',
     'TextServicesDocument.h',
 ]
 
 UNIFIED_SOURCES += [
     'EditorSpellCheck.cpp',
+    'FilteredContentIterator.cpp',
     'nsComposeTxtSrvFilter.cpp',
-    'nsFilteredContentIterator.cpp',
     'TextServicesDocument.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'