Bug 1388269 - part2: Make mozInlineSpellChecker store TextEditor instead of nsIEditor r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 14 Aug 2017 13:36:25 +0900
changeset 646320 1a3d91eb4ef27d9dfdc16297f2a2292e52f47add
parent 646319 ed9e14879c16bd88798112749b9c9b54b56be24a
child 646321 a66f8e5dc623a18225da475c71f0779dfefee11b
push id74070
push usermasayuki@d-toybox.com
push dateTue, 15 Aug 2017 04:00:57 +0000
reviewersm_kato
bugs1388269
milestone57.0a1
Bug 1388269 - part2: Make mozInlineSpellChecker store TextEditor instead of nsIEditor r?m_kato Then, can reduce a lot of unnecessary virtual calls and QI. MozReview-Commit-ID: 28JS4q2L1Vj
extensions/spellcheck/src/mozInlineSpellChecker.cpp
extensions/spellcheck/src/mozInlineSpellChecker.h
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -219,27 +219,26 @@ mozInlineSpellStatus::InitForNavigation(
     bool* aContinue)
 {
   mOp = eOpNavigation;
 
   mForceNavigationWordCheck = aForceCheck;
   mNewNavigationPositionOffset = aNewPositionOffset;
 
   // get the root node for checking
-  nsCOMPtr<nsIEditor> editor = mSpellChecker->mEditor;
-  if (NS_WARN_IF(!editor)) {
+  TextEditor* textEditor = mSpellChecker->mTextEditor;
+  if (NS_WARN_IF(!textEditor)) {
     return NS_ERROR_FAILURE;
   }
-  nsCOMPtr<nsIDOMElement> rootElt;
-  nsresult rv = editor->GetRootElement(getter_AddRefs(rootElt));
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  nsCOMPtr<nsINode> root = textEditor->GetRoot();
+  if (NS_WARN_IF(!root)) {
+    return NS_ERROR_FAILURE;
+  }
   // the anchor node might not be in the DOM anymore, check
-  nsCOMPtr<nsINode> root = do_QueryInterface(rootElt, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsresult rv = NS_ERROR_FAILURE;
   nsCOMPtr<nsINode> currentAnchor = do_QueryInterface(aOldAnchorNode, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   if (root && currentAnchor && ! ContentIsDescendantOf(currentAnchor, root)) {
     *aContinue = false;
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMDocument> doc;
@@ -343,19 +342,20 @@ mozInlineSpellStatus::FinishInitOnEvent(
 //    Notice that we don't set mNoCheckRange. We check here whether the cursor
 //    is in the word that needs checking, so it isn't necessary. Plus, the
 //    spellchecker isn't guaranteed to only check the given word, and it could
 //    remove the underline from the new word under the cursor.
 
 nsresult
 mozInlineSpellStatus::FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil)
 {
-  nsCOMPtr<nsIEditor> editor = mSpellChecker->mEditor;
-  if (! editor)
+  RefPtr<TextEditor> textEditor = mSpellChecker->mTextEditor;
+  if (!textEditor) {
     return NS_ERROR_FAILURE; // editor is gone
+  }
 
   NS_ASSERTION(mAnchorRange, "No anchor for navigation!");
   nsCOMPtr<nsIDOMNode> newAnchorNode, oldAnchorNode;
 
   // get the DOM position of the old caret, the range should be collapsed
   nsresult rv = mOldNavigationAnchorRange->GetStartContainer(
       getter_AddRefs(oldAnchorNode));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -365,17 +365,17 @@ mozInlineSpellStatus::FinishNavigationEv
   // to check
   RefPtr<nsRange> oldWord;
   rv = aWordUtil.GetRangeForWord(oldAnchorNode,
                                  static_cast<int32_t>(oldAnchorOffset),
                                  getter_AddRefs(oldWord));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // aWordUtil.GetRangeForWord flushes pending notifications, check editor again.
-  if (!mSpellChecker->mEditor) {
+  if (!mSpellChecker->mTextEditor) {
     return NS_ERROR_FAILURE; // editor is gone
   }
 
   // get the DOM position of the new caret, the range should be collapsed
   rv = mAnchorRange->GetStartContainer(getter_AddRefs(newAnchorNode));
   NS_ENSURE_SUCCESS(rv, rv);
   uint32_t newAnchorOffset = mAnchorRange->StartOffset();
 
@@ -429,28 +429,25 @@ mozInlineSpellStatus::FillNoCheckRangeFr
 //
 //    Returns the nsIDOMDocument object for the document for the
 //    current spellchecker.
 
 nsresult
 mozInlineSpellStatus::GetDocument(nsIDOMDocument** aDocument)
 {
   *aDocument = nullptr;
-  if (! mSpellChecker->mEditor)
+  if (!mSpellChecker->mTextEditor) {
     return NS_ERROR_UNEXPECTED;
-
-  nsCOMPtr<nsIEditor> editor = mSpellChecker->mEditor;
-  if (NS_WARN_IF(!editor)) {
-    return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  nsresult rv = editor->GetDocument(getter_AddRefs(domDoc));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(domDoc, NS_ERROR_NULL_POINTER);
+  nsCOMPtr<nsIDOMDocument> domDoc =
+    mSpellChecker->mTextEditor->GetDOMDocument();
+  if (NS_WARN_IF(!domDoc)) {
+    return NS_ERROR_NULL_POINTER;
+  }
   domDoc.forget(aDocument);
   return NS_OK;
 }
 
 // mozInlineSpellStatus::PositionToCollapsedRange
 //
 //    Converts a given DOM position to a collapsed range covering that
 //    position. We use ranges to store DOM positions becuase they stay
@@ -544,17 +541,17 @@ NS_INTERFACE_MAP_BEGIN(mozInlineSpellChe
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventListener)
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozInlineSpellChecker)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(mozInlineSpellChecker)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(mozInlineSpellChecker)
 
 NS_IMPL_CYCLE_COLLECTION(mozInlineSpellChecker,
-                         mEditor,
+                         mTextEditor,
                          mSpellCheck,
                          mTreeWalker,
                          mCurrentSelectionAnchorNode)
 
 mozInlineSpellChecker::SpellCheckingState
   mozInlineSpellChecker::gCanEnableSpellChecking =
   mozInlineSpellChecker::SpellCheck_Uninitialized;
 
@@ -581,19 +578,19 @@ NS_IMETHODIMP
 mozInlineSpellChecker::GetSpellChecker(nsIEditorSpellCheck **aSpellCheck)
 {
   *aSpellCheck = mSpellCheck;
   NS_IF_ADDREF(*aSpellCheck);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-mozInlineSpellChecker::Init(nsIEditor *aEditor)
+mozInlineSpellChecker::Init(nsIEditor* aEditor)
 {
-  mEditor = aEditor;
+  mTextEditor = aEditor ? aEditor->AsTextEditor() : nullptr;
   return NS_OK;
 }
 
 // mozInlineSpellChecker::Cleanup
 //
 //    Called by the editor when the editor is going away. This is important
 //    because we remove listeners. We do NOT clean up anything else in this
 //    function, because it can get called while DoSpellCheck is running!
@@ -621,38 +618,39 @@ nsresult mozInlineSpellChecker::Cleanup(
   // Notify ENDED observers now.  If we wait to notify as we normally do when
   // these async operations finish, then in the meantime the editor may create
   // another inline spell checker and cause more STARTED and ENDED
   // notifications to be broadcast.  Interleaved notifications for the same
   // editor but different inline spell checkers could easily confuse
   // observers.  They may receive two consecutive STARTED notifications for
   // example, which we guarantee will not happen.
 
-  nsCOMPtr<nsIEditor> editor = mEditor.forget();
+  RefPtr<TextEditor> textEditor = mTextEditor.forget();
   if (mPendingSpellCheck) {
     // Cancel the pending editor spell checker initialization.
     mPendingSpellCheck = nullptr;
     mPendingInitEditorSpellCheckCallback->Cancel();
     mPendingInitEditorSpellCheckCallback = nullptr;
-    ChangeNumPendingSpellChecks(-1, editor);
+    ChangeNumPendingSpellChecks(-1, textEditor);
   }
 
   // Increment this token so that pending UpdateCurrentDictionary calls and
   // scheduled spell checks are discarded when they finish.
   mDisabledAsyncToken++;
 
   if (mNumPendingUpdateCurrentDictionary > 0) {
     // Account for pending UpdateCurrentDictionary calls.
-    ChangeNumPendingSpellChecks(-mNumPendingUpdateCurrentDictionary, editor);
+    ChangeNumPendingSpellChecks(-mNumPendingUpdateCurrentDictionary,
+                                textEditor);
     mNumPendingUpdateCurrentDictionary = 0;
   }
   if (mNumPendingSpellChecks > 0) {
     // If mNumPendingSpellChecks is still > 0 at this point, the remainder is
     // pending scheduled spell checks.
-    ChangeNumPendingSpellChecks(-mNumPendingSpellChecks, editor);
+    ChangeNumPendingSpellChecks(-mNumPendingSpellChecks, textEditor);
   }
 
   mFullSpellCheckScheduled = false;
 
   return rv;
 }
 
 // mozInlineSpellChecker::CanEnableInlineSpellChecking
@@ -699,59 +697,50 @@ mozInlineSpellChecker::UpdateCanEnableIn
 // mozInlineSpellChecker::RegisterEventListeners
 //
 //    The inline spell checker listens to mouse events and keyboard navigation
 //    events.
 
 nsresult
 mozInlineSpellChecker::RegisterEventListeners()
 {
-  if (NS_WARN_IF(!mEditor)) {
+  if (NS_WARN_IF(!mTextEditor)) {
     return NS_ERROR_FAILURE;
   }
 
-  mEditor->AddEditActionListener(this);
-
-  nsCOMPtr<nsIDOMDocument> doc;
-  nsresult rv = mEditor->GetDocument(getter_AddRefs(doc));
-  NS_ENSURE_SUCCESS(rv, rv);
+  mTextEditor->AddEditActionListener(this);
 
-  nsCOMPtr<EventTarget> piTarget = do_QueryInterface(doc, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  piTarget->AddEventListener(NS_LITERAL_STRING("blur"), this,
-                             true, false);
-  piTarget->AddEventListener(NS_LITERAL_STRING("click"), this,
-                             false, false);
-  piTarget->AddEventListener(NS_LITERAL_STRING("keypress"), this,
-                             false, false);
+  nsCOMPtr<nsIDocument> doc = mTextEditor->GetDocument();
+  if (NS_WARN_IF(!doc)) {
+    return NS_ERROR_FAILURE;
+  }
+  doc->AddEventListener(NS_LITERAL_STRING("blur"), this, true, false);
+  doc->AddEventListener(NS_LITERAL_STRING("click"), this, false, false);
+  doc->AddEventListener(NS_LITERAL_STRING("keypress"), this, false, false);
   return NS_OK;
 }
 
 // mozInlineSpellChecker::UnregisterEventListeners
 
 nsresult
 mozInlineSpellChecker::UnregisterEventListeners()
 {
-  if (NS_WARN_IF(!mEditor)) {
+  if (NS_WARN_IF(!mTextEditor)) {
     return NS_ERROR_FAILURE;
   }
 
-  mEditor->RemoveEditActionListener(this);
-
-  nsCOMPtr<nsIDOMDocument> doc;
-  mEditor->GetDocument(getter_AddRefs(doc));
-  NS_ENSURE_TRUE(doc, NS_ERROR_NULL_POINTER);
+  mTextEditor->RemoveEditActionListener(this);
 
-  nsCOMPtr<EventTarget> piTarget = do_QueryInterface(doc);
-  NS_ENSURE_TRUE(piTarget, NS_ERROR_NULL_POINTER);
-
-  piTarget->RemoveEventListener(NS_LITERAL_STRING("blur"), this, true);
-  piTarget->RemoveEventListener(NS_LITERAL_STRING("click"), this, false);
-  piTarget->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, false);
+  nsCOMPtr<nsIDocument> doc = mTextEditor->GetDocument();
+  if (NS_WARN_IF(!doc)) {
+    return NS_ERROR_FAILURE;
+  }
+  doc->RemoveEventListener(NS_LITERAL_STRING("blur"), this, true);
+  doc->RemoveEventListener(NS_LITERAL_STRING("click"), this, false);
+  doc->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, false);
   return NS_OK;
 }
 
 // mozInlineSpellChecker::GetEnableRealTimeSpell
 
 NS_IMETHODIMP
 mozInlineSpellChecker::GetEnableRealTimeSpell(bool* aEnabled)
 {
@@ -797,17 +786,17 @@ mozInlineSpellChecker::SetEnableRealTime
 
   mPendingInitEditorSpellCheckCallback = new InitEditorSpellCheckCallback(this);
   if (!mPendingInitEditorSpellCheckCallback) {
     mPendingSpellCheck = nullptr;
     NS_ENSURE_STATE(mPendingInitEditorSpellCheckCallback);
   }
 
   nsresult rv = mPendingSpellCheck->InitSpellChecker(
-                  mEditor, false, mPendingInitEditorSpellCheckCallback);
+                  mTextEditor, false, mPendingInitEditorSpellCheckCallback);
   if (NS_FAILED(rv)) {
     mPendingSpellCheck = nullptr;
     mPendingInitEditorSpellCheckCallback = nullptr;
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   ChangeNumPendingSpellChecks(1);
 
@@ -849,27 +838,29 @@ mozInlineSpellChecker::ChangeNumPendingS
   if (oldNumPending == 0 && mNumPendingSpellChecks > 0) {
     NotifyObservers(INLINESPELL_STARTED_TOPIC, aEditor);
   } else if (oldNumPending > 0 && mNumPendingSpellChecks == 0) {
     NotifyObservers(INLINESPELL_ENDED_TOPIC, aEditor);
   }
 }
 
 // Broadcasts the given topic to observers.  aEditor is passed to observers if
-// nonnull; otherwise mEditor is passed.
+// nonnull; otherwise mTextEditor is passed.
 void
 mozInlineSpellChecker::NotifyObservers(const char* aTopic, nsIEditor* aEditor)
 {
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (!os)
     return;
   // XXX Do we need to grab the editor here?  If it's necessary, each observer
   //     should do it instead.
-  nsCOMPtr<nsIEditor> editor = aEditor ? aEditor : mEditor.get();
-  os->NotifyObservers(editor, aTopic, nullptr);
+  RefPtr<TextEditor> textEditor =
+    aEditor ? aEditor->AsTextEditor() : mTextEditor.get();
+  os->NotifyObservers(static_cast<nsIEditor*>(textEditor.get()),
+                      aTopic, nullptr);
 }
 
 // mozInlineSpellChecker::SpellCheckAfterEditorChange
 //
 //    Called by the editor when nearly anything happens to change the content.
 //
 //    The start and end positions specify a range for the thing that happened,
 //    but these are usually nullptr, even when you'd think they would be useful
@@ -953,45 +944,43 @@ mozInlineSpellChecker::GetMisspelledWord
 }
 
 // mozInlineSpellChecker::ReplaceWord
 
 NS_IMETHODIMP
 mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset,
                                    const nsAString &newword)
 {
-  if (NS_WARN_IF(!mEditor) || NS_WARN_IF(newword.IsEmpty())) {
+  if (NS_WARN_IF(!mTextEditor) || NS_WARN_IF(newword.IsEmpty())) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIDOMRange> range;
   nsresult res = GetMisspelledWord(aNode, aOffset, getter_AddRefs(range));
   NS_ENSURE_SUCCESS(res, res);
 
   if (range)
   {
     // This range was retrieved from the spellchecker selection. As
     // ranges cannot be shared between selections, we must clone it
     // before adding it to the editor's selection.
     nsCOMPtr<nsIDOMRange> editorRange;
     res = range->CloneRange(getter_AddRefs(editorRange));
     NS_ENSURE_SUCCESS(res, res);
 
-    AutoPlaceHolderBatch phb(mEditor, nullptr);
+    AutoPlaceHolderBatch phb(mTextEditor, nullptr);
 
     nsCOMPtr<nsISelection> selection;
-    res = mEditor->GetSelection(getter_AddRefs(selection));
+    res = mTextEditor->GetSelection(getter_AddRefs(selection));
     NS_ENSURE_SUCCESS(res, res);
     selection->RemoveAllRanges();
     selection->AddRange(editorRange);
 
-    MOZ_ASSERT(mEditor);
-    RefPtr<TextEditor> textEditor = mEditor->AsTextEditor();
-    MOZ_ASSERT(textEditor);
-    textEditor->InsertText(newword);
+    MOZ_ASSERT(mTextEditor);
+    mTextEditor->InsertText(newword);
   }
 
   return NS_OK;
 }
 
 // mozInlineSpellChecker::AddWordToDictionary
 
 NS_IMETHODIMP
@@ -1164,38 +1153,36 @@ nsresult
 mozInlineSpellChecker::MakeSpellCheckRange(
     nsIDOMNode* aStartNode, int32_t aStartOffset,
     nsIDOMNode* aEndNode, int32_t aEndOffset,
     nsRange** aRange)
 {
   nsresult rv;
   *aRange = nullptr;
 
-  if (NS_WARN_IF(!mEditor)) {
+  if (NS_WARN_IF(!mTextEditor)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIDocument> doc = mTextEditor->GetDocument();
+  if (NS_WARN_IF(!doc)) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIDOMDocument> doc;
-  rv = mEditor->GetDocument(getter_AddRefs(doc));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsINode> documentNode = do_QueryInterface(doc);
-  RefPtr<nsRange> range = new nsRange(documentNode);
+  RefPtr<nsRange> range = new nsRange(doc);
 
   // possibly use full range of the editor
-  nsCOMPtr<nsIDOMElement> rootElem;
   if (! aStartNode || ! aEndNode) {
-    rv = mEditor->GetRootElement(getter_AddRefs(rootElem));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    aStartNode = rootElem;
+    nsCOMPtr<nsIDOMElement> domRootElement =
+      do_QueryInterface(mTextEditor->GetRoot());
+    if (NS_WARN_IF(!domRootElement)) {
+      return NS_ERROR_FAILURE;
+    }
+    aStartNode = aEndNode = domRootElement;
     aStartOffset = 0;
-
-    aEndNode = rootElem;
     aEndOffset = -1;
   }
 
   if (aEndOffset == -1) {
     nsCOMPtr<nsIDOMNodeList> childNodes;
     rv = aEndNode->GetChildNodes(getter_AddRefs(childNodes));
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1464,19 +1451,20 @@ nsresult mozInlineSpellChecker::DoSpellC
                                              bool* aDoneChecking)
 {
   *aDoneChecking = true;
 
   NS_ENSURE_TRUE(mSpellCheck, NS_ERROR_NOT_INITIALIZED);
 
   // get the editor for ShouldSpellCheckNode, this may fail in reasonable
   // circumstances since the editor could have gone away
-  nsCOMPtr<nsIEditor> editor = mEditor;
-  if (! editor)
+  RefPtr<TextEditor> textEditor = mTextEditor;
+  if (!textEditor) {
     return NS_ERROR_FAILURE;
+  }
 
   if (aStatus->mRange->Collapsed())
     return NS_OK;
 
   // see if the selection has any ranges, if not, then we can optimize checking
   // range inclusion later (we have no ranges when we are initially checking or
   // when there are no misspelled words yet).
   int32_t originalRangeCount = aSpellCheckSelection->RangeCount();
@@ -1499,17 +1487,17 @@ nsresult mozInlineSpellChecker::DoSpellC
       return NS_OK;
     }
 
     aWordUtil.SetEnd(endNode, endOffset);
     aWordUtil.SetPosition(beginNode, beginOffset);
   }
 
   // aWordUtil.SetPosition flushes pending notifications, check editor again.
-  if (!mEditor) {
+  if (!mTextEditor) {
     return NS_ERROR_FAILURE;
   }
 
   int32_t wordsChecked = 0;
   PRTime beginTime = PR_Now();
 
   nsAutoString wordText;
   RefPtr<nsRange> wordRange;
@@ -1573,18 +1561,19 @@ nsresult mozInlineSpellChecker::DoSpellC
       }
     }
 
     // some words are special and don't need checking
     if (dontCheckWord)
       continue;
 
     // some nodes we don't spellcheck
-    if (!ShouldSpellCheckNode(editor, beginNode))
+    if (!ShouldSpellCheckNode(textEditor, beginNode)) {
       continue;
+    }
 
     // Don't check spelling if we're inside the noCheckRange. This needs to
     // be done after we clear any old selection because the excluded word
     // might have been previously marked.
     //
     // We do a simple check to see if the beginning of our word is in the
     // exclusion range. Because the exclusion range is a multiple of a word,
     // this is sufficient.
@@ -1656,22 +1645,22 @@ mozInlineSpellChecker::ResumeCheck(Uniqu
                  "How could this be false?  The full spell check is "
                  "calling us!!");
     mFullSpellCheckScheduled = false;
   }
 
   if (! mSpellCheck)
     return NS_OK; // spell checking has been turned off
 
-  if (!mEditor) {
+  if (!mTextEditor) {
     return NS_OK;
   }
 
   mozInlineSpellWordUtil wordUtil;
-  nsresult rv = wordUtil.Init(mEditor);
+  nsresult rv = wordUtil.Init(mTextEditor);
   if (NS_FAILED(rv))
     return NS_OK; // editor doesn't like us, don't assert
 
   nsCOMPtr<nsISelection> spellCheckSelectionRef;
   rv = GetSpellCheckSelection(getter_AddRefs(spellCheckSelectionRef));
   NS_ENSURE_SUCCESS(rv, rv);
 
   auto spellCheckSelection =
@@ -1818,42 +1807,43 @@ mozInlineSpellChecker::AddRange(nsISelec
 
   return rv;
 }
 
 nsresult
 mozInlineSpellChecker::GetSpellCheckSelection(
                          nsISelection** aSpellCheckSelection)
 {
-  if (NS_WARN_IF(!mEditor)) {
+  if (NS_WARN_IF(!mTextEditor)) {
     return NS_ERROR_FAILURE;
   }
-  nsCOMPtr<nsISelectionController> selcon;
-  nsresult rv = mEditor->GetSelectionController(getter_AddRefs(selcon));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return selcon->GetSelection(nsISelectionController::SELECTION_SPELLCHECK, aSpellCheckSelection);
+  RefPtr<Selection> selection =
+    mTextEditor->GetSelection(SelectionType::eSpellCheck);
+  if (!selection) {
+    return NS_ERROR_NULL_POINTER;
+  }
+  selection.forget(aSpellCheckSelection);
+  return NS_OK;
 }
 
 nsresult
 mozInlineSpellChecker::SaveCurrentSelectionPosition()
 {
-  if (NS_WARN_IF(!mEditor)) {
+  if (NS_WARN_IF(!mTextEditor)) {
     return NS_OK; // XXX Why NS_OK?
   }
 
   // figure out the old caret position based on the current selection
-  nsCOMPtr<nsISelection> selection;
-  nsresult rv = mEditor->GetSelection(getter_AddRefs(selection));
-  NS_ENSURE_SUCCESS(rv, rv);
+  RefPtr<Selection> selection = mTextEditor->GetSelection();
+  if (NS_WARN_IF(!selection)) {
+    return NS_ERROR_FAILURE;
+  }
 
-  rv = selection->GetFocusNode(getter_AddRefs(mCurrentSelectionAnchorNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  selection->GetFocusOffset(&mCurrentSelectionOffset);
+  mCurrentSelectionAnchorNode = do_QueryInterface(selection->GetFocusNode());
+  mCurrentSelectionOffset = selection->FocusOffset();
 
   return NS_OK;
 }
 
 // This is a copy of nsContentUtils::ContentIsDescendantOf. Another crime
 // for XPCOM's rap sheet
 bool // static
 ContentIsDescendantOf(nsINode* aPossibleDescendant,
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -1,17 +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/. */
 
 #ifndef __mozinlinespellchecker_h__
 #define __mozinlinespellchecker_h__
 
-#include "mozilla/EditorBase.h"
+#include "mozilla/TextEditor.h"
 
 #include "mozISpellI18NUtil.h"
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMTreeWalker.h"
 #include "nsIEditActionListener.h"
 #include "nsIEditorSpellCheck.h"
@@ -128,17 +128,17 @@ private:
   friend class mozInlineSpellResume;
 
   // Access with CanEnableInlineSpellChecking
   enum SpellCheckingState { SpellCheck_Uninitialized = -1,
                             SpellCheck_NotAvailable = 0,
                             SpellCheck_Available = 1};
   static SpellCheckingState gCanEnableSpellChecking;
 
-  nsCOMPtr<nsIEditor> mEditor;
+  RefPtr<mozilla::TextEditor> mTextEditor;
   nsCOMPtr<nsIEditorSpellCheck> mSpellCheck;
   nsCOMPtr<nsIEditorSpellCheck> mPendingSpellCheck;
   nsCOMPtr<nsIDOMTreeWalker> mTreeWalker;
   nsCOMPtr<mozISpellI18NUtil> mConverter;
 
   int32_t mNumWordsInSpellSelection;
   int32_t mMaxNumWordsInSpellSelection;