Bug 1456879 - Clean up spellchecker not to use nsIDOM* if possible. r?masayuki
Without XPCOM and related method, I want to remove dependencies of nsIDOM*
from spellchecker. Also, it is unnecessary to use nsISelectionPrivate since
we can use mozilla::dom::Selection instead.
MozReview-Commit-ID: 1Zheq3Hsepj
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -45,28 +45,23 @@
#include "mozilla/dom/MouseEvent.h"
#include "mozilla/dom/Selection.h"
#include "mozInlineSpellWordUtil.h"
#include "mozISpellI18NManager.h"
#include "mozISpellI18NUtil.h"
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsIDOMNode.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMNode.h"
-#include "nsIDOMNodeList.h"
#include "nsGenericHTMLElement.h"
#include "nsRange.h"
#include "nsIPlaintextEditor.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsIRunnable.h"
#include "nsISelection.h"
-#include "nsISelectionPrivate.h"
#include "nsISelectionController.h"
#include "nsIServiceManager.h"
#include "nsITextServicesFilter.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsUnicharUtils.h"
#include "nsIContent.h"
#include "nsIContentInlines.h"
@@ -362,17 +357,17 @@ mozInlineSpellStatus::FinishNavigationEv
if (NS_WARN_IF(err.Failed())) {
return err.StealNSResult();
}
uint32_t oldAnchorOffset = mOldNavigationAnchorRange->StartOffset();
// find the word on the old caret position, this is the one that we MAY need
// to check
RefPtr<nsRange> oldWord;
- nsresult rv = aWordUtil.GetRangeForWord(oldAnchorNode->AsDOMNode(),
+ nsresult 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->mTextEditor) {
return NS_ERROR_FAILURE; // editor is gone
}
@@ -423,24 +418,24 @@ mozInlineSpellStatus::FillNoCheckRangeFr
{
ErrorResult err;
nsCOMPtr<nsINode> anchorNode = mAnchorRange->GetStartContainer(err);
if (NS_WARN_IF(err.Failed())) {
return err.StealNSResult();
}
uint32_t anchorOffset = mAnchorRange->StartOffset();
- return aWordUtil.GetRangeForWord(anchorNode->AsDOMNode(),
+ return aWordUtil.GetRangeForWord(anchorNode,
static_cast<int32_t>(anchorOffset),
getter_AddRefs(mNoCheckRange));
}
// mozInlineSpellStatus::GetDocument
//
-// Returns the nsIDOMDocument object for the document for the
+// Returns the nsIDocument object for the document for the
// current spellchecker.
nsIDocument*
mozInlineSpellStatus::GetDocument() const
{
if (!mSpellChecker->mTextEditor) {
return nullptr;
}
@@ -932,17 +927,17 @@ mozInlineSpellChecker::GetMisspelledWord
{
if (NS_WARN_IF(!aNode)) {
return NS_ERROR_INVALID_ARG;
}
RefPtr<Selection> spellCheckSelection = GetSpellCheckSelection();
if (NS_WARN_IF(!spellCheckSelection)) {
return NS_ERROR_FAILURE;
}
- return IsPointInSelection(spellCheckSelection, aNode, aOffset, newword);
+ return IsPointInSelection(*spellCheckSelection, aNode, aOffset, newword);
}
// mozInlineSpellChecker::ReplaceWord
NS_IMETHODIMP
mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset,
const nsAString &newword)
{
@@ -1045,45 +1040,43 @@ mozInlineSpellChecker::IgnoreWords(const
void
mozInlineSpellChecker::DidSplitNode(nsINode* aExistingRightNode,
nsINode* aNewLeftNode)
{
if (!mIsListeningToEditActions) {
return;
}
- nsIDOMNode* newLeftDOMNode =
- aNewLeftNode ? aNewLeftNode->AsDOMNode() : nullptr;
- SpellCheckBetweenNodes(newLeftDOMNode, 0, newLeftDOMNode, 0);
+ SpellCheckBetweenNodes(aNewLeftNode, 0, aNewLeftNode, 0);
}
void
mozInlineSpellChecker::DidJoinNodes(nsINode& aLeftNode,
nsINode& aRightNode)
{
if (!mIsListeningToEditActions) {
return;
}
- SpellCheckBetweenNodes(aRightNode.AsDOMNode(), 0, aRightNode.AsDOMNode(), 0);
+ SpellCheckBetweenNodes(&aRightNode, 0, &aRightNode, 0);
}
// mozInlineSpellChecker::MakeSpellCheckRange
//
// Given begin and end positions, this function constructs a range as
// required for ScheduleSpellCheck. If the start and end nodes are nullptr,
// then the entire range will be selected, and you can supply -1 as the
// offset to the end range to select all of that node.
//
// If the resulting range would be empty, nullptr is put into *aRange and the
// function succeeds.
nsresult
mozInlineSpellChecker::MakeSpellCheckRange(
- nsIDOMNode* aStartNode, int32_t aStartOffset,
- nsIDOMNode* aEndNode, int32_t aEndOffset,
+ nsINode* aStartNode, int32_t aStartOffset,
+ nsINode* aEndNode, int32_t aEndOffset,
nsRange** aRange)
{
nsresult rv;
*aRange = nullptr;
if (NS_WARN_IF(!mTextEditor)) {
return NS_ERROR_FAILURE;
}
@@ -1092,66 +1085,62 @@ mozInlineSpellChecker::MakeSpellCheckRan
if (NS_WARN_IF(!doc)) {
return NS_ERROR_FAILURE;
}
RefPtr<nsRange> range = new nsRange(doc);
// possibly use full range of the editor
if (! aStartNode || ! aEndNode) {
- nsCOMPtr<nsIDOMElement> domRootElement =
- do_QueryInterface(mTextEditor->GetRoot());
+ Element* domRootElement = mTextEditor->GetRoot();
if (NS_WARN_IF(!domRootElement)) {
return NS_ERROR_FAILURE;
}
aStartNode = aEndNode = domRootElement;
aStartOffset = 0;
aEndOffset = -1;
}
if (aEndOffset == -1) {
// It's hard to say whether it's better to just do nsINode::GetChildCount or
// get the ChildNodes() and then its length. The latter is faster if we
// keep going through this code for the same nodes (because it caches the
// length). The former is faster if we keep getting different nodes here...
//
// Let's do the thing which can't end up with bad O(N^2) behavior.
- nsCOMPtr<nsINode> endNode = do_QueryInterface(aEndNode);
- aEndOffset = endNode->ChildNodes()->Length();
+ aEndOffset = aEndNode->ChildNodes()->Length();
}
// sometimes we are are requested to check an empty range (possibly an empty
// document). This will result in assertions later.
if (aStartNode == aEndNode && aStartOffset == aEndOffset)
return NS_OK;
- nsCOMPtr<nsINode> startNode = do_QueryInterface(aStartNode);
- nsCOMPtr<nsINode> endNode = do_QueryInterface(aEndNode);
if (aEndOffset) {
- rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, aEndOffset);
+ rv = range->SetStartAndEnd(aStartNode, aStartOffset, aEndNode, aEndOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
uint32_t endOffset;
- endNode = nsRange::GetContainerAndOffsetAfter(endNode, &endOffset);
- rv = range->SetStartAndEnd(startNode, aStartOffset, endNode, endOffset);
+ aEndNode = nsRange::GetContainerAndOffsetAfter(aEndNode, &endOffset);
+ rv = range->SetStartAndEnd(aStartNode, aStartOffset, aEndNode, endOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
range.swap(*aRange);
return NS_OK;
}
nsresult
-mozInlineSpellChecker::SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
+mozInlineSpellChecker::SpellCheckBetweenNodes(nsINode *aStartNode,
int32_t aStartOffset,
- nsIDOMNode *aEndNode,
+ nsINode *aEndNode,
int32_t aEndOffset)
{
RefPtr<nsRange> range;
nsresult rv = MakeSpellCheckRange(aStartNode, aStartOffset,
aEndNode, aEndOffset,
getter_AddRefs(range));
NS_ENSURE_SUCCESS(rv, rv);
@@ -1626,29 +1615,28 @@ mozInlineSpellChecker::ResumeCheck(Uniqu
// Determines if a given (node,offset) point is inside the given
// selection. If so, the specific range of the selection that
// intersects is places in *aRange. (There may be multiple disjoint
// ranges in a selection.)
//
// If there is no intersection, *aRange will be nullptr.
nsresult
-mozInlineSpellChecker::IsPointInSelection(nsISelection *aSelection,
+mozInlineSpellChecker::IsPointInSelection(Selection& aSelection,
nsIDOMNode *aNode,
int32_t aOffset,
nsIDOMRange **aRange)
{
*aRange = nullptr;
- nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection));
-
nsTArray<nsRange*> ranges;
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
- nsresult rv = privSel->GetRangesForIntervalArray(node, aOffset, node, aOffset,
- true, &ranges);
+ nsresult rv = aSelection.GetRangesForIntervalArray(node, aOffset,
+ node, aOffset,
+ true, &ranges);
NS_ENSURE_SUCCESS(rv, rv);
if (ranges.Length() == 0)
return NS_OK; // no matches
// there may be more than one range returned, and we don't know what do
// do with that, so just get the first one
NS_ADDREF(*aRange = ranges[0]);
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -57,18 +57,20 @@ public:
RefPtr<mozInlineSpellChecker> mSpellChecker;
// The total number of words checked in this sequence, using this tally tells
// us when to stop. This count is preserved as we continue checking in new
// messages.
int32_t mWordCount;
// what happened?
- enum Operation { eOpChange, // for SpellCheckAfterChange except deleteSelection
- eOpChangeDelete, // for SpellCheckAfterChange deleteSelection
+ enum Operation { eOpChange, // for SpellCheckAfterEditorChange except
+ // deleteSelection
+ eOpChangeDelete, // for SpellCheckAfterEditorChange with
+ // deleteSelection
eOpNavigation, // for HandleNavigationEvent
eOpSelection, // re-check all misspelled words
eOpResume }; // for resuming a previously started check
Operation mOp;
// Used for events where we have already computed the range to use. It can
// also be nullptr in these cases where we need to check the entire range.
RefPtr<nsRange> mRange;
@@ -196,57 +198,53 @@ public:
nsresult OnBlur(mozilla::dom::Event* aEvent);
nsresult OnMouseClick(mozilla::dom::Event* aMouseEvent);
nsresult OnKeyPress(mozilla::dom::Event* aKeyEvent);
mozInlineSpellChecker();
// spell checks all of the words between two nodes
- nsresult SpellCheckBetweenNodes(nsIDOMNode *aStartNode,
+ nsresult SpellCheckBetweenNodes(nsINode* aStartNode,
int32_t aStartOffset,
- nsIDOMNode *aEndNode,
+ nsINode* aEndNode,
int32_t aEndOffset);
// examines the dom node in question and returns true if the inline spell
// checker should skip the node (i.e. the text is inside of a block quote
// or an e-mail signature...)
bool ShouldSpellCheckNode(mozilla::TextEditor* aTextEditor, nsINode *aNode);
- nsresult SpellCheckAfterChange(nsIDOMNode* aCursorNode, int32_t aCursorOffset,
- nsIDOMNode* aPreviousNode, int32_t aPreviousOffset,
- nsISelection* aSpellCheckSelection);
-
// spell check the text contained within aRange, potentially scheduling
// another check in the future if the time threshold is reached
nsresult ScheduleSpellCheck(mozilla::UniquePtr<mozInlineSpellStatus>&& aStatus);
nsresult DoSpellCheckSelection(mozInlineSpellWordUtil& aWordUtil,
mozilla::dom::Selection* aSpellCheckSelection);
nsresult DoSpellCheck(mozInlineSpellWordUtil& aWordUtil,
mozilla::dom::Selection *aSpellCheckSelection,
const mozilla::UniquePtr<mozInlineSpellStatus>& aStatus,
bool* aDoneChecking);
// helper routine to determine if a point is inside of the passed in selection.
- nsresult IsPointInSelection(nsISelection *aSelection,
+ nsresult IsPointInSelection(mozilla::dom::Selection& aSelection,
nsIDOMNode *aNode,
int32_t aOffset,
nsIDOMRange **aRange);
nsresult CleanupRangesInSelection(mozilla::dom::Selection *aSelection);
nsresult RemoveRange(mozilla::dom::Selection *aSpellCheckSelection,
nsRange *aRange);
nsresult AddRange(mozilla::dom::Selection *aSpellCheckSelection,
nsRange* aRange);
bool SpellCheckSelectionIsFull() { return mNumWordsInSpellSelection >= mMaxNumWordsInSpellSelection; }
- nsresult MakeSpellCheckRange(nsIDOMNode* aStartNode, int32_t aStartOffset,
- nsIDOMNode* aEndNode, int32_t aEndOffset,
+ nsresult MakeSpellCheckRange(nsINode* aStartNode, int32_t aStartOffset,
+ nsINode* aEndNode, int32_t aEndOffset,
nsRange** aRange);
// DOM and editor event registration helper routines
nsresult RegisterEventListeners();
nsresult UnregisterEventListeners();
nsresult HandleNavigationEvent(bool aForceWordSpellCheck, int32_t aNewPositionOffset = 0);
already_AddRefed<mozilla::dom::Selection> GetSpellCheckSelection();
--- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
@@ -7,20 +7,17 @@
#include "mozilla/BinarySearch.h"
#include "mozilla/TextEditor.h"
#include "mozilla/dom/Element.h"
#include "nsDebug.h"
#include "nsAtom.h"
#include "nsComponentManagerUtils.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMRange.h"
#include "nsIEditor.h"
-#include "nsIDOMNode.h"
#include "nsUnicodeProperties.h"
#include "nsServiceManagerUtils.h"
#include "nsIContent.h"
#include "nsTextFragment.h"
#include "nsRange.h"
#include "nsContentUtils.h"
#include "nsIFrame.h"
#include <algorithm>
@@ -57,17 +54,16 @@ mozInlineSpellWordUtil::Init(TextEditor*
if (NS_WARN_IF(!aTextEditor)) {
return NS_ERROR_FAILURE;
}
mDocument = aTextEditor->GetDocument();
if (NS_WARN_IF(!mDocument)) {
return NS_ERROR_FAILURE;
}
- mDOMDocument = do_QueryInterface(mDocument);
// Find the root node for the editor. For contenteditable we'll need something
// cleverer here.
mRootNode = aTextEditor->GetRoot();
if (NS_WARN_IF(!mRootNode)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
@@ -237,23 +233,22 @@ mozInlineSpellWordUtil::MakeNodeOffsetRa
NodeOffset begin = MapSoftTextOffsetToDOMPosition(aWord.mSoftTextOffset, HINT_BEGIN);
NodeOffset end = MapSoftTextOffsetToDOMPosition(aWord.EndOffset(), HINT_END);
*aNodeOffsetRange = NodeOffsetRange(begin, end);
}
// mozInlineSpellWordUtil::GetRangeForWord
nsresult
-mozInlineSpellWordUtil::GetRangeForWord(nsIDOMNode* aWordNode,
+mozInlineSpellWordUtil::GetRangeForWord(nsINode* aWordNode,
int32_t aWordOffset,
nsRange** aRange)
{
// Set our soft end and start
- nsCOMPtr<nsINode> wordNode = do_QueryInterface(aWordNode);
- NodeOffset pt = NodeOffset(wordNode, aWordOffset);
+ NodeOffset pt = NodeOffset(aWordNode, aWordOffset);
if (!mSoftTextValid || pt != mSoftBegin || pt != mSoftEnd) {
InvalidateWords();
mSoftBegin = mSoftEnd = pt;
nsresult rv = EnsureWords();
if (NS_FAILED(rv)) {
return rv;
}
@@ -330,18 +325,19 @@ mozInlineSpellWordUtil::GetNextWord(nsAS
//
// Convenience function for creating a range over the current document.
nsresult
mozInlineSpellWordUtil::MakeRange(NodeOffset aBegin, NodeOffset aEnd,
nsRange** aRange)
{
NS_ENSURE_ARG_POINTER(aBegin.mNode);
- if (!mDOMDocument)
+ if (!mDocument) {
return NS_ERROR_NOT_INITIALIZED;
+ }
RefPtr<nsRange> range = new nsRange(aBegin.mNode);
nsresult rv = range->SetStartAndEnd(aBegin.mNode, aBegin.mOffset,
aEnd.mNode, aEnd.mOffset);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
range.forget(aRange);
--- a/extensions/spellcheck/src/mozInlineSpellWordUtil.h
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.h
@@ -1,18 +1,18 @@
/* -*- Mode: C++; tab-width: 8; 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 mozInlineSpellWordUtil_h
#define mozInlineSpellWordUtil_h
+#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
-#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsString.h"
#include "nsTArray.h"
//#define DEBUG_SPELLCHECK
class nsRange;
class nsINode;
@@ -83,17 +83,17 @@ public:
* 2. Call SetEnd to set where you want to stop spellchecking. We'll stop
* at the word boundary after that. If SetEnd is not called, we'll stop
* at the end of the document's root element.
* 3. Call SetPosition to initialize the current position inside the
* previously given range.
* 4. Call GetNextWord over and over until it returns false.
*/
-class mozInlineSpellWordUtil
+class MOZ_STACK_CLASS mozInlineSpellWordUtil
{
public:
mozInlineSpellWordUtil()
: mRootNode(nullptr),
mSoftBegin(nullptr, 0), mSoftEnd(nullptr, 0),
mNextWordIndex(-1), mSoftTextValid(false) {}
nsresult Init(mozilla::TextEditor* aTextEditor);
@@ -108,17 +108,17 @@ public:
// DOM range that exactly encloses that word's characters. The current
// position will be at the end of the word. This will find the previous
// word if the current position is space, so if you care that the point is
// inside the word, you should check the range.
//
// THIS CHANGES THE CURRENT POSITION AND RANGE. It is designed to be called
// before you actually generate the range you are interested in and iterate
// the words in it.
- nsresult GetRangeForWord(nsIDOMNode* aWordNode, int32_t aWordOffset,
+ nsresult GetRangeForWord(nsINode* aWordNode, int32_t aWordOffset,
nsRange** aRange);
// Convenience functions, object must be initialized
nsresult MakeRange(NodeOffset aBegin, NodeOffset aEnd, nsRange** aRange);
// Moves to the the next word in the range, and retrieves it's text and range.
// An empty word and a nullptr range are returned when we are done checking.
// aSkipChecking will be set if the word is "special" and shouldn't be
@@ -126,24 +126,22 @@ public:
nsresult GetNextWord(nsAString& aText,
NodeOffsetRange* aNodeOffsetRange,
bool* aSkipChecking);
// Call to normalize some punctuation. This function takes an autostring
// so we can access characters directly.
static void NormalizeWord(nsAString& aWord);
- nsIDOMDocument* GetDOMDocument() const { return mDOMDocument; }
nsIDocument* GetDocument() const { return mDocument; }
nsINode* GetRootNode() { return mRootNode; }
private:
// cached stuff for the editor, set by Init
- nsCOMPtr<nsIDOMDocument> mDOMDocument;
nsCOMPtr<nsIDocument> mDocument;
// range to check, see SetPosition and SetEnd
nsINode* mRootNode;
NodeOffset mSoftBegin;
NodeOffset mSoftEnd;
// DOM text covering the soft range, with newlines added at block boundaries