Bug 1408829 - Make spellCheckAfterEditorChange as noscript. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Wed, 29 Nov 2017 18:00:11 +0900
changeset 705005 7ff9018ec6bb74464fe3fff6e6a4551862ea9e86
parent 704807 cb9092a90f6ef501e6de8eb5fc6ce19e2717193f
child 742217 bb70a7022a422e32ea78c00444ba26ef6b4c2d50
push id91314
push userbmo:m_kato@ga2.so-net.ne.jp
push dateWed, 29 Nov 2017 09:04:26 +0000
reviewersmasayuki
bugs1408829
milestone59.0a1
Bug 1408829 - Make spellCheckAfterEditorChange as noscript. r?masayuki No one uses nsIInlineSpellChecker.spellCheckAfterEditorChange from script. So I think we can mark this interface as noscript. Since this method is scriptable, we need QI to get nsIDOMNode. If we can change to noscript, it can reduce QI to get nsIDOMNode. MozReview-Commit-ID: GC0WuFyTlaZ
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditRules.h
editor/txtsvc/nsIInlineSpellChecker.idl
extensions/spellcheck/src/mozInlineSpellChecker.cpp
extensions/spellcheck/src/mozInlineSpellChecker.h
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -4995,22 +4995,22 @@ EditorBase::HandleKeyPressEvent(WidgetKe
       return NS_OK;
   }
   return NS_OK;
 }
 
 nsresult
 EditorBase::HandleInlineSpellCheck(EditAction action,
                                    Selection* aSelection,
-                                   nsIDOMNode* previousSelectedNode,
-                                   int32_t previousSelectedOffset,
-                                   nsIDOMNode* aStartContainer,
-                                   int32_t aStartOffset,
-                                   nsIDOMNode* aEndContainer,
-                                   int32_t aEndOffset)
+                                   nsINode* previousSelectedNode,
+                                   uint32_t previousSelectedOffset,
+                                   nsINode* aStartContainer,
+                                   uint32_t aStartOffset,
+                                   nsINode* aEndContainer,
+                                   uint32_t aEndOffset)
 {
   // Have to cast action here because this method is from an IDL
   return mInlineSpellChecker ? mInlineSpellChecker->SpellCheckAfterEditorChange(
                                  (int32_t)action, aSelection,
                                  previousSelectedNode, previousSelectedOffset,
                                  aStartContainer, aStartOffset, aEndContainer,
                                  aEndOffset)
                              : NS_OK;
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -1178,22 +1178,22 @@ public:
   virtual nsresult EndUpdateViewBatch();
 
   bool GetShouldTxnSetSelection();
 
   virtual nsresult HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent);
 
   nsresult HandleInlineSpellCheck(EditAction action,
                                   Selection* aSelection,
-                                  nsIDOMNode* previousSelectedNode,
-                                  int32_t previousSelectedOffset,
-                                  nsIDOMNode* aStartContainer,
-                                  int32_t aStartOffset,
-                                  nsIDOMNode* aEndContainer,
-                                  int32_t aEndOffset);
+                                  nsINode* previousSelectedNode,
+                                  uint32_t previousSelectedOffset,
+                                  nsINode* aStartContainer,
+                                  uint32_t aStartOffset,
+                                  nsINode* aEndContainer,
+                                  uint32_t aEndOffset);
 
   virtual already_AddRefed<dom::EventTarget> GetDOMEventTarget() = 0;
 
   /**
    * Fast non-refcounting editor root element accessor
    */
   Element* GetRoot() const { return mRootElement; }
 
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -560,22 +560,22 @@ HTMLEditRules::AfterEditInner(EditAction
     }
   }
 
   NS_ENSURE_STATE(mHTMLEditor);
 
   nsresult rv =
     mHTMLEditor->HandleInlineSpellCheck(
                    action, selection,
-                   GetAsDOMNode(mRangeItem->mStartContainer),
+                   mRangeItem->mStartContainer,
                    mRangeItem->mStartOffset,
-                   GetAsDOMNode(rangeStartContainer),
-                   static_cast<int32_t>(rangeStartOffset),
-                   GetAsDOMNode(rangeEndContainer),
-                   static_cast<int32_t>(rangeEndOffset));
+                   rangeStartContainer,
+                   rangeStartOffset,
+                   rangeEndContainer,
+                   rangeEndOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // detect empty doc
   rv = CreateBogusNodeIfNeeded(selection);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // adjust selection HINT if needed
   if (!mDidExplicitlySetInterline) {
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -222,17 +222,17 @@ TextEditRules::AfterEdit(EditAction acti
   if (!--mActionNesting) {
     NS_ENSURE_STATE(mTextEditor);
     RefPtr<Selection> selection = mTextEditor->GetSelection();
     NS_ENSURE_STATE(selection);
 
     NS_ENSURE_STATE(mTextEditor);
     nsresult rv =
       mTextEditor->HandleInlineSpellCheck(action, selection,
-                                          GetAsDOMNode(mCachedSelectionNode),
+                                          mCachedSelectionNode,
                                           mCachedSelectionOffset,
                                           nullptr, 0, nullptr, 0);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // no longer uses mCachedSelectionNode, so release it.
     mCachedSelectionNode = nullptr;
 
     // if only trailing <br> remaining remove it
--- a/editor/libeditor/TextEditRules.h
+++ b/editor/libeditor/TextEditRules.h
@@ -292,17 +292,17 @@ protected:
   // A buffer we use to track the IME composition string.
   nsString mPasswordIMEText;
   uint32_t mPasswordIMEIndex;
   // Magic node acts as placeholder in empty doc.
   nsCOMPtr<nsIContent> mBogusNode;
   // Cached selected node.
   nsCOMPtr<nsINode> mCachedSelectionNode;
   // Cached selected offset.
-  int32_t mCachedSelectionOffset;
+  uint32_t mCachedSelectionOffset;
   uint32_t mActionNesting;
   bool mLockRulesSniffing;
   bool mDidExplicitlySetInterline;
   // In bidirectional text, delete characters not visually adjacent to the
   // caret without moving the caret first.
   bool mDeleteBidiImmediately;
   // The top level editor action.
   EditAction mTheAction;
--- a/editor/txtsvc/nsIInlineSpellChecker.idl
+++ b/editor/txtsvc/nsIInlineSpellChecker.idl
@@ -5,34 +5,40 @@
 
 #include "nsISupports.idl"
 #include "domstubs.idl"
 
 interface nsISelection;
 interface nsIEditor;
 interface nsIEditorSpellCheck;
 
+%{ C++
+class nsINode;
+%}
+[ptr] native nsINodePtr(nsINode);
+
 [scriptable, uuid(b7b7a77c-40c4-4196-b0b7-b0338243b3fe)]
 interface nsIInlineSpellChecker : nsISupports
 {
   readonly attribute nsIEditorSpellCheck spellChecker;
 
   void init(in nsIEditor aEditor);
   void cleanup(in boolean aDestroyingFrames);
 
   attribute boolean enableRealTimeSpell;
 
-  void spellCheckAfterEditorChange(in long aAction,
-                                   in nsISelection aSelection,
-                                   in nsIDOMNode aPreviousSelectedNode,
-                                   in long aPreviousSelectedOffset,
-                                   in nsIDOMNode aStartNode,
-                                   in long aStartOffset,
-                                   in nsIDOMNode aEndNode,
-                                   in long aEndOffset);
+  [noscript] void spellCheckAfterEditorChange(
+                    in long aAction,
+                    in nsISelection aSelection,
+                    in nsINodePtr aPreviousSelectedNode,
+                    in unsigned long aPreviousSelectedOffset,
+                    in nsINodePtr aStartNode,
+                    in unsigned long aStartOffset,
+                    in nsINodePtr aEndNode,
+                    in unsigned long aEndOffset);
 
   void spellCheckRange(in nsIDOMRange aSelection);
 
   nsIDOMRange getMisspelledWord(in nsIDOMNode aNode, in long aOffset);
   void replaceWord(in nsIDOMNode aNode, in long aOffset, in AString aNewword);
   void addWordToDictionary(in AString aWord);
   void removeWordFromDictionary(in AString aWord);
 
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -110,96 +110,96 @@ mozInlineSpellStatus::mozInlineSpellStat
 //    This is the most complicated case. For changes, we need to compute the
 //    range of stuff that changed based on the old and new caret positions,
 //    as well as use a range possibly provided by the editor (start and end,
 //    which are usually nullptr) to get a range with the union of these.
 
 nsresult
 mozInlineSpellStatus::InitForEditorChange(
     EditAction aAction,
-    nsIDOMNode* aAnchorNode, int32_t aAnchorOffset,
-    nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
-    nsIDOMNode* aStartNode, int32_t aStartOffset,
-    nsIDOMNode* aEndNode, int32_t aEndOffset)
+    nsINode* aAnchorNode, uint32_t aAnchorOffset,
+    nsINode* aPreviousNode, uint32_t aPreviousOffset,
+    nsINode* aStartNode, uint32_t aStartOffset,
+    nsINode* aEndNode, uint32_t aEndOffset)
 {
-  nsresult rv;
-
-  nsCOMPtr<nsIDOMDocument> doc;
-  rv = GetDocument(getter_AddRefs(doc));
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (NS_WARN_IF(!aAnchorNode) || NS_WARN_IF(!aPreviousNode)) {
+    return NS_ERROR_FAILURE;
+  }
 
   // save the anchor point as a range so we can find the current word later
-  rv = PositionToCollapsedRange(doc, aAnchorNode, aAnchorOffset,
-                                getter_AddRefs(mAnchorRange));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsINode> prevNode = do_QueryInterface(aPreviousNode);
-  NS_ENSURE_STATE(prevNode);
+  mAnchorRange = PositionToCollapsedRange(aAnchorNode, aAnchorOffset);
+  if (NS_WARN_IF(!mAnchorRange)) {
+    return NS_ERROR_FAILURE;
+  }
 
   bool deleted = aAction == EditAction::deleteSelection;
   if (aAction == EditAction::insertIMEText) {
     // IME may remove the previous node if it cancels composition when
     // there is no text around the composition.
-    deleted = !prevNode->IsInComposedDoc();
+    deleted = !aPreviousNode->IsInComposedDoc();
   }
 
   if (deleted) {
     // Deletes are easy, the range is just the current anchor. We set the range
     // to check to be empty, FinishInitOnEvent will fill in the range to be
     // the current word.
     mOp = eOpChangeDelete;
     mRange = nullptr;
     return NS_OK;
   }
 
   mOp = eOpChange;
 
   // range to check
-  mRange = new nsRange(prevNode);
+  mRange = new nsRange(aPreviousNode);
 
   // ...we need to put the start and end in the correct order
-  int16_t cmpResult;
-  rv = mAnchorRange->ComparePoint(aPreviousNode, aPreviousOffset, &cmpResult);
-  NS_ENSURE_SUCCESS(rv, rv);
+  ErrorResult errorResult;
+  int16_t cmpResult =
+    mAnchorRange->ComparePoint(*aPreviousNode, aPreviousOffset, errorResult);
+  if (NS_WARN_IF(errorResult.Failed())) {
+    return errorResult.StealNSResult();
+  }
+  nsresult rv;
   if (cmpResult < 0) {
     // previous anchor node is before the current anchor
-    nsCOMPtr<nsINode> previousNode = do_QueryInterface(aPreviousNode);
-    nsCOMPtr<nsINode> anchorNode = do_QueryInterface(aAnchorNode);
-    rv = mRange->SetStartAndEnd(previousNode, aPreviousOffset,
-                                anchorNode, aAnchorOffset);
+    rv = mRange->SetStartAndEnd(aPreviousNode, aPreviousOffset,
+                                aAnchorNode, aAnchorOffset);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   } else {
     // previous anchor node is after (or the same as) the current anchor
-    nsCOMPtr<nsINode> previousNode = do_QueryInterface(aPreviousNode);
-    nsCOMPtr<nsINode> anchorNode = do_QueryInterface(aAnchorNode);
-    rv = mRange->SetStartAndEnd(anchorNode, aAnchorOffset,
-                                previousNode, aPreviousOffset);
+    rv = mRange->SetStartAndEnd(aAnchorNode, aAnchorOffset,
+                                aPreviousNode, aPreviousOffset);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   // On insert save this range: DoSpellCheck optimizes things in this range.
   // Otherwise, just leave this nullptr.
   if (aAction == EditAction::insertText)
     mCreatedRange = mRange;
 
   // if we were given a range, we need to expand our range to encompass it
   if (aStartNode && aEndNode) {
-    rv = mRange->ComparePoint(aStartNode, aStartOffset, &cmpResult);
-    NS_ENSURE_SUCCESS(rv, rv);
+    cmpResult = mRange->ComparePoint(*aStartNode, aStartOffset, errorResult);
+    if (NS_WARN_IF(errorResult.Failed())) {
+      return errorResult.StealNSResult();
+    }
     if (cmpResult < 0) { // given range starts before
       rv = mRange->SetStart(aStartNode, aStartOffset);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
-    rv = mRange->ComparePoint(aEndNode, aEndOffset, &cmpResult);
-    NS_ENSURE_SUCCESS(rv, rv);
+    cmpResult = mRange->ComparePoint(*aEndNode, aEndOffset, errorResult);
+    if (NS_WARN_IF(errorResult.Failed())) {
+      return errorResult.StealNSResult();
+    }
     if (cmpResult > 0) { // given range ends after
       rv = mRange->SetEnd(aEndNode, aEndOffset);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   return NS_OK;
 }
@@ -209,53 +209,50 @@ mozInlineSpellStatus::InitForEditorChang
 //    For navigation events, we just need to store the new and old positions.
 //
 //    In some cases, we detect that we shouldn't check. If this event should
 //    not be processed, *aContinue will be false.
 
 nsresult
 mozInlineSpellStatus::InitForNavigation(
     bool aForceCheck, int32_t aNewPositionOffset,
-    nsIDOMNode* aOldAnchorNode, int32_t aOldAnchorOffset,
-    nsIDOMNode* aNewAnchorNode, int32_t aNewAnchorOffset,
+    nsINode* aOldAnchorNode, uint32_t aOldAnchorOffset,
+    nsINode* aNewAnchorNode, uint32_t aNewAnchorOffset,
     bool* aContinue)
 {
   mOp = eOpNavigation;
 
   mForceNavigationWordCheck = aForceCheck;
   mNewNavigationPositionOffset = aNewPositionOffset;
 
   // get the root node for checking
   TextEditor* textEditor = mSpellChecker->mTextEditor;
   if (NS_WARN_IF(!textEditor)) {
     return NS_ERROR_FAILURE;
   }
-  nsCOMPtr<nsINode> root = textEditor->GetRoot();
+  Element* root = textEditor->GetRoot();
   if (NS_WARN_IF(!root)) {
     return NS_ERROR_FAILURE;
   }
   // the anchor node might not be in the DOM anymore, check
-  nsresult rv = NS_ERROR_FAILURE;
-  nsCOMPtr<nsINode> currentAnchor = do_QueryInterface(aOldAnchorNode, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (root && currentAnchor && ! ContentIsDescendantOf(currentAnchor, root)) {
+  if (root && aOldAnchorNode && ! ContentIsDescendantOf(aOldAnchorNode, root)) {
     *aContinue = false;
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDOMDocument> doc;
-  rv = GetDocument(getter_AddRefs(doc));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = PositionToCollapsedRange(doc, aOldAnchorNode, aOldAnchorOffset,
-                                getter_AddRefs(mOldNavigationAnchorRange));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = PositionToCollapsedRange(doc, aNewAnchorNode, aNewAnchorOffset,
-                                getter_AddRefs(mAnchorRange));
-  NS_ENSURE_SUCCESS(rv, rv);
+  mOldNavigationAnchorRange =
+    PositionToCollapsedRange(aOldAnchorNode, aOldAnchorOffset);
+  if (NS_WARN_IF(!mOldNavigationAnchorRange)) {
+    return NS_ERROR_FAILURE;
+  }
+  mAnchorRange =
+    PositionToCollapsedRange(aNewAnchorNode, aNewAnchorOffset);
+  if (NS_WARN_IF(!mAnchorRange)) {
+    return NS_ERROR_FAILURE;
+  }
 
   *aContinue = true;
   return NS_OK;
 }
 
 // mozInlineSpellStatus::InitForSelection
 //
 //    It is easy for selections since we always re-check the spellcheck
@@ -425,57 +422,49 @@ mozInlineSpellStatus::FillNoCheckRangeFr
                                    getter_AddRefs(mNoCheckRange));
 }
 
 // mozInlineSpellStatus::GetDocument
 //
 //    Returns the nsIDOMDocument object for the document for the
 //    current spellchecker.
 
-nsresult
-mozInlineSpellStatus::GetDocument(nsIDOMDocument** aDocument)
+already_AddRefed<nsIDocument>
+mozInlineSpellStatus::GetDocument()
 {
-  *aDocument = nullptr;
   if (!mSpellChecker->mTextEditor) {
-    return NS_ERROR_UNEXPECTED;
+    return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDocument> domDoc =
-    mSpellChecker->mTextEditor->GetDOMDocument();
-  if (NS_WARN_IF(!domDoc)) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  domDoc.forget(aDocument);
-  return NS_OK;
+  return mSpellChecker->mTextEditor->GetDocument();
 }
 
 // mozInlineSpellStatus::PositionToCollapsedRange
 //
 //    Converts a given DOM position to a collapsed range covering that
 //    position. We use ranges to store DOM positions becuase they stay
 //    updated as the DOM is changed.
 
-nsresult
-mozInlineSpellStatus::PositionToCollapsedRange(nsIDOMDocument* aDocument,
-                                               nsIDOMNode* aNode,
-                                               int32_t aOffset,
-                                               nsRange** aRange)
+already_AddRefed<nsRange>
+mozInlineSpellStatus::PositionToCollapsedRange(nsINode* aNode,
+                                               uint32_t aOffset)
 {
-  *aRange = nullptr;
-  nsCOMPtr<nsINode> documentNode = do_QueryInterface(aDocument);
-  RefPtr<nsRange> range = new nsRange(documentNode);
-
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  nsresult rv = range->CollapseTo(node, aOffset);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
+  nsCOMPtr<nsIDocument> document = GetDocument();
+  if (NS_WARN_IF(!document)) {
+    return nullptr;
   }
 
-  range.swap(*aRange);
-  return NS_OK;
+  RefPtr<nsRange> range = new nsRange(document);
+
+  nsresult rv = range->CollapseTo(aNode, aOffset);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nullptr;
+  }
+
+  return range.forget();
 }
 
 // mozInlineSpellResume
 
 class mozInlineSpellResume : public Runnable
 {
 public:
   mozInlineSpellResume(UniquePtr<mozInlineSpellStatus>&& aStatus,
@@ -867,40 +856,36 @@ mozInlineSpellChecker::NotifyObservers(c
 //    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
 //    because you want the range (for example, pasting). We ignore them in
 //    this case.
 
 NS_IMETHODIMP
 mozInlineSpellChecker::SpellCheckAfterEditorChange(
     int32_t aAction, nsISelection *aSelection,
-    nsIDOMNode *aPreviousSelectedNode, int32_t aPreviousSelectedOffset,
-    nsIDOMNode *aStartNode, int32_t aStartOffset,
-    nsIDOMNode *aEndNode, int32_t aEndOffset)
+    nsINode *aPreviousSelectedNode, uint32_t aPreviousSelectedOffset,
+    nsINode *aStartNode, uint32_t aStartOffset,
+    nsINode *aEndNode, uint32_t aEndOffset)
 {
   nsresult rv;
   NS_ENSURE_ARG_POINTER(aSelection);
   if (!mSpellCheck)
     return NS_OK; // disabling spell checking is not an error
 
   // this means something has changed, and we never check the current word,
   // therefore, we should spellcheck for subsequent caret navigations
   mNeedsCheckAfterNavigation = true;
 
+  RefPtr<Selection> selection = aSelection->AsSelection();
+
   // the anchor node is the position of the caret
-  nsCOMPtr<nsIDOMNode> anchorNode;
-  rv = aSelection->GetAnchorNode(getter_AddRefs(anchorNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-  int32_t anchorOffset;
-  rv = aSelection->GetAnchorOffset(&anchorOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   auto status = MakeUnique<mozInlineSpellStatus>(this);
   rv = status->InitForEditorChange((EditAction)aAction,
-                                   anchorNode, anchorOffset,
+                                   selection->GetAnchorNode(),
+                                   selection->AnchorOffset(),
                                    aPreviousSelectedNode,
                                    aPreviousSelectedOffset,
                                    aStartNode, aStartOffset,
                                    aEndNode, aEndOffset);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = ScheduleSpellCheck(Move(status));
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1835,17 +1820,17 @@ mozInlineSpellChecker::SaveCurrentSelect
   }
 
   // figure out the old caret position based on the current selection
   RefPtr<Selection> selection = mTextEditor->GetSelection();
   if (NS_WARN_IF(!selection)) {
     return NS_ERROR_FAILURE;
   }
 
-  mCurrentSelectionAnchorNode = do_QueryInterface(selection->GetFocusNode());
+  mCurrentSelectionAnchorNode = selection->GetFocusNode();
   mCurrentSelectionOffset = selection->FocusOffset();
 
   return NS_OK;
 }
 
 // This is a copy of nsContentUtils::ContentIsDescendantOf. Another crime
 // for XPCOM's rap sheet
 bool // static
@@ -1885,18 +1870,18 @@ mozInlineSpellChecker::HandleNavigationE
 
   // If we already handled the navigation event and there is no possibility
   // anything has changed since then, we don't have to do anything. This
   // optimization makes a noticeable difference when you hold down a navigation
   // key like Page Down.
   if (! mNeedsCheckAfterNavigation)
     return NS_OK;
 
-  nsCOMPtr<nsIDOMNode> currentAnchorNode = mCurrentSelectionAnchorNode;
-  int32_t currentAnchorOffset = mCurrentSelectionOffset;
+  nsCOMPtr<nsINode> currentAnchorNode = mCurrentSelectionAnchorNode;
+  uint32_t currentAnchorOffset = mCurrentSelectionOffset;
 
   // now remember the new focus position resulting from the event
   rv = SaveCurrentSelectionPosition();
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool shouldPost;
   auto status = MakeUnique<mozInlineSpellStatus>(this);
   rv = status->InitForNavigation(aForceWordSpellCheck, aNewPositionOffset,
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -32,23 +32,23 @@ class UpdateCurrentDictionaryCallback;
 class mozInlineSpellResume;
 
 class mozInlineSpellStatus
 {
 public:
   explicit mozInlineSpellStatus(mozInlineSpellChecker* aSpellChecker);
 
   nsresult InitForEditorChange(EditAction aAction,
-                               nsIDOMNode* aAnchorNode, int32_t aAnchorOffset,
-                               nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
-                               nsIDOMNode* aStartNode, int32_t aStartOffset,
-                               nsIDOMNode* aEndNode, int32_t aEndOffset);
+                               nsINode* aAnchorNode, uint32_t aAnchorOffset,
+                               nsINode* aPreviousNode, uint32_t aPreviousOffset,
+                               nsINode* aStartNode, uint32_t aStartOffset,
+                               nsINode* aEndNode, uint32_t aEndOffset);
   nsresult InitForNavigation(bool aForceCheck, int32_t aNewPositionOffset,
-                             nsIDOMNode* aOldAnchorNode, int32_t aOldAnchorOffset,
-                             nsIDOMNode* aNewAnchorNode, int32_t aNewAnchorOffset,
+                             nsINode* aOldAnchorNode, uint32_t aOldAnchorOffset,
+                             nsINode* aNewAnchorNode, uint32_t aNewAnchorOffset,
                              bool* aContinue);
   nsresult InitForSelection();
   nsresult InitForRange(nsRange* aRange);
 
   nsresult FinishInitOnEvent(mozInlineSpellWordUtil& aWordUtil);
 
   // Return true if we plan to spell-check everything
   bool IsFullSpellCheck() const {
@@ -104,20 +104,19 @@ public:
   // Contains the offset passed in to HandleNavigationEvent
   int32_t mNewNavigationPositionOffset;
 
 protected:
   nsresult FinishNavigationEvent(mozInlineSpellWordUtil& aWordUtil);
 
   nsresult FillNoCheckRangeFromAnchor(mozInlineSpellWordUtil& aWordUtil);
 
-  nsresult GetDocument(nsIDOMDocument** aDocument);
-  nsresult PositionToCollapsedRange(nsIDOMDocument* aDocument,
-                                    nsIDOMNode* aNode, int32_t aOffset,
-                                    nsRange** aRange);
+  already_AddRefed<nsIDocument> GetDocument();
+  already_AddRefed<nsRange> PositionToCollapsedRange(nsINode* aNode,
+                                                     uint32_t aOffset);
 };
 
 class mozInlineSpellChecker final : public nsIInlineSpellChecker,
                                     public nsIEditActionListener,
                                     public nsIDOMEventListener,
                                     public nsSupportsWeakReference
 {
 private:
@@ -146,18 +145,18 @@ private:
   // total number of misspellings. When you have a large textarea prepopulated
   // with text with many misspellings, we can hit this limit. By making it
   // lower than the total number of misspelled words, new text typed by the
   // user can also have spellchecking in it.
   int32_t mMaxMisspellingsPerCheck;
 
   // we need to keep track of the current text position in the document
   // so we can spell check the old word when the user clicks around the document.
-  nsCOMPtr<nsIDOMNode> mCurrentSelectionAnchorNode;
-  int32_t              mCurrentSelectionOffset;
+  nsCOMPtr<nsINode> mCurrentSelectionAnchorNode;
+  uint32_t mCurrentSelectionOffset;
 
   // Tracks the number of pending spell checks *and* async operations that may
   // lead to spell checks, like updating the current dictionary.  This is
   // necessary so that observers can know when to wait for spell check to
   // complete.
   int32_t mNumPendingSpellChecks;
 
   // The number of calls to UpdateCurrentDictionary that haven't finished yet.