--- 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,