Bug 1430982 - part 3: Make mozSpellChecker and nsEditorSpellChecker treat TextServicesDocument directly rather than nsITextServicesDocument r?m_kato
Now, TextServicesDocument can be treated by anybody. So, let's make
mozSpellChecker and nsEditorSpellChecker treat it directly instead of
nsITextServicesDocument.
MozReview-Commit-ID: 2tMy6y3i17b
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -2,21 +2,22 @@
/* vim: set ts=2 sts=2 sw=2 tw=80: */
/* 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 <stdlib.h> // for getenv
#include "mozilla/Attributes.h" // for final
-#include "mozilla/Preferences.h" // for Preferences
#include "mozilla/dom/Element.h" // for Element
#include "mozilla/dom/Selection.h"
#include "mozilla/intl/LocaleService.h" // for retrieving app locale
#include "mozilla/mozalloc.h" // for operator delete, etc
+#include "mozilla/Preferences.h" // for Preferences
+#include "mozilla/TextServicesDocument.h" // for TextServicesDocument
#include "nsAString.h" // for nsAString::IsEmpty, etc
#include "nsComponentManagerUtils.h" // for do_CreateInstance
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
#include "nsDependentSubstring.h" // for Substring
#include "nsEditorSpellCheck.h"
#include "nsError.h" // for NS_ERROR_NOT_INITIALIZED, etc
#include "nsIContent.h" // for nsIContent
#include "nsIContentPrefService2.h" // for nsIContentPrefService2, etc
@@ -372,26 +373,22 @@ nsEditorSpellCheck::InitSpellChecker(nsI
nsCOMPtr<nsIDOMDocument> domDoc;
mEditor->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
NS_ENSURE_STATE(doc);
nsresult rv;
// We can spell check with any editor type
- nsCOMPtr<nsITextServicesDocument>tsDoc =
- do_CreateInstance("@mozilla.org/textservices/textservicesdocument;1", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- NS_ENSURE_TRUE(tsDoc, NS_ERROR_NULL_POINTER);
-
- tsDoc->SetFilter(mTxtSrvFilter);
+ RefPtr<TextServicesDocument> textServicesDocument =
+ new TextServicesDocument();
+ textServicesDocument->SetFilter(mTxtSrvFilter);
// Pass the editor to the text services document
- rv = tsDoc->InitWithEditor(aEditor);
+ rv = textServicesDocument->InitWithEditor(aEditor);
NS_ENSURE_SUCCESS(rv, rv);
if (aEnableSelectionChecking) {
// Find out if the section is collapsed or not.
// If it isn't, we want to spellcheck just the selection.
nsCOMPtr<nsISelection> domSelection;
aEditor->GetSelection(getter_AddRefs(domSelection));
@@ -407,34 +404,34 @@ nsEditorSpellCheck::InitSpellChecker(nsI
if (!range->Collapsed()) {
// We don't want to touch the range in the selection,
// so create a new copy of it.
RefPtr<nsRange> rangeBounds = range->CloneRange();
// Make sure the new range spans complete words.
- rv = tsDoc->ExpandRangeToWordBoundaries(rangeBounds);
+ rv = textServicesDocument->ExpandRangeToWordBoundaries(rangeBounds);
NS_ENSURE_SUCCESS(rv, rv);
// Now tell the text services that you only want
// to iterate over the text in this range.
- rv = tsDoc->SetExtent(rangeBounds);
+ rv = textServicesDocument->SetExtent(rangeBounds);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
mSpellChecker = do_CreateInstance(NS_SPELLCHECKER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NULL_POINTER);
- rv = mSpellChecker->SetDocument(tsDoc, true);
+ rv = mSpellChecker->SetDocument(textServicesDocument, true);
NS_ENSURE_SUCCESS(rv, rv);
// do not fail if UpdateCurrentDictionary fails because this method may
// succeed later.
rv = UpdateCurrentDictionary(aCallback);
if (NS_FAILED(rv) && aCallback) {
// However, if it does fail, we still need to call the callback since we
// discard the failure. Do it asynchronously so that the caller is always
--- a/editor/txtsvc/nsISpellChecker.h
+++ b/editor/txtsvc/nsISpellChecker.h
@@ -13,33 +13,36 @@
#define NS_SPELLCHECKER_CONTRACTID "@mozilla.org/spellchecker;1"
#define NS_ISPELLCHECKER_IID \
{ /* 27bff957-b486-40ae-9f5d-af0cdd211868 */ \
0x27bff957, 0xb486, 0x40ae, \
{ 0x9f, 0x5d, 0xaf, 0x0c, 0xdd, 0x21, 0x18, 0x68 } }
-class nsITextServicesDocument;
+namespace mozilla {
+class TextServicesDocument;
+} // namespace mozilla
/**
* A generic interface for a spelling checker.
*/
class nsISpellChecker : public nsISupports{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISPELLCHECKER_IID)
/**
* Tells the spellchecker what document to check.
* @param aDoc is the document to check.
* @param aFromStartOfDoc If true, start check from beginning of document,
* if false, start check from current cursor position.
*/
- NS_IMETHOD SetDocument(nsITextServicesDocument *aDoc, bool aFromStartofDoc) = 0;
+ NS_IMETHOD SetDocument(mozilla::TextServicesDocument* aDoc,
+ bool aFromStartofDoc) = 0;
/**
* Selects (hilites) the next misspelled word in the document.
* @param aWord will contain the misspelled word.
* @param aSuggestions is an array of nsStrings, that represent the
* suggested replacements for the misspelled word.
*/
NS_IMETHOD NextMisspelledWord(nsAString &aWord, nsTArray<nsString> *aSuggestions) = 0;
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -5,38 +5,40 @@
#include "mozSpellChecker.h"
#include "nsIServiceManager.h"
#include "mozISpellI18NManager.h"
#include "nsIStringEnumerator.h"
#include "nsICategoryManager.h"
#include "nsISupportsPrimitives.h"
#include "nsISimpleEnumerator.h"
+#include "mozilla/dom/ContentChild.h"
#include "mozilla/PRemoteSpellcheckEngineChild.h"
-#include "mozilla/dom/ContentChild.h"
+#include "mozilla/TextServicesDocument.h"
#include "nsXULAppAPI.h"
using mozilla::dom::ContentChild;
using mozilla::GenericPromise;
using mozilla::PRemoteSpellcheckEngineChild;
using mozilla::RemoteSpellcheckEngineChild;
+using mozilla::TextServicesDocument;
#define DEFAULT_SPELL_CHECKER "@mozilla.org/spellchecker/engine;1"
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozSpellChecker)
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozSpellChecker)
NS_INTERFACE_MAP_BEGIN(mozSpellChecker)
NS_INTERFACE_MAP_ENTRY(nsISpellChecker)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISpellChecker)
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozSpellChecker)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(mozSpellChecker,
- mTsDoc,
+ mTextServicesDocument,
mPersonalDictionary)
mozSpellChecker::mozSpellChecker()
: mEngine(nullptr)
{
}
mozSpellChecker::~mozSpellChecker()
@@ -67,19 +69,20 @@ mozSpellChecker::Init()
} else {
mPersonalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
}
return NS_OK;
}
NS_IMETHODIMP
-mozSpellChecker::SetDocument(nsITextServicesDocument *aDoc, bool aFromStartofDoc)
+mozSpellChecker::SetDocument(TextServicesDocument* aTextServicesDocument,
+ bool aFromStartofDoc)
{
- mTsDoc = aDoc;
+ mTextServicesDocument = aTextServicesDocument;
mFromStart = aFromStartofDoc;
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::NextMisspelledWord(nsAString &aWord, nsTArray<nsString> *aSuggestions)
{
@@ -89,43 +92,44 @@ mozSpellChecker::NextMisspelledWord(nsAS
int32_t selOffset;
int32_t begin,end;
nsresult result;
result = SetupDoc(&selOffset);
bool isMisspelled,done;
if (NS_FAILED(result))
return result;
- while( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done )
- {
- nsString str;
- result = mTsDoc->GetCurrentTextBlock(&str);
+ while (NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done) {
+ nsString str;
+ result = mTextServicesDocument->GetCurrentTextBlock(&str);
- if (NS_FAILED(result))
- return result;
- do{
- result = mConverter->FindNextWord(str.get(),str.Length(),selOffset,&begin,&end);
- if(NS_SUCCEEDED(result)&&(begin != -1)){
- const nsAString &currWord = Substring(str, begin, end - begin);
- result = CheckWord(currWord, &isMisspelled, aSuggestions);
- if(isMisspelled){
- aWord = currWord;
- mTsDoc->SetSelection(begin, end-begin);
- // After ScrollSelectionIntoView(), the pending notifications might
- // be flushed and PresShell/PresContext/Frames may be dead.
- // See bug 418470.
- mTsDoc->ScrollSelectionIntoView();
- return NS_OK;
- }
+ if (NS_FAILED(result)) {
+ return result;
+ }
+ do {
+ result = mConverter->FindNextWord(str.get(), str.Length(),
+ selOffset, &begin, &end);
+ if (NS_SUCCEEDED(result) && begin != -1) {
+ const nsAString &currWord = Substring(str, begin, end - begin);
+ result = CheckWord(currWord, &isMisspelled, aSuggestions);
+ if (isMisspelled) {
+ aWord = currWord;
+ mTextServicesDocument->SetSelection(begin, end - begin);
+ // After ScrollSelectionIntoView(), the pending notifications might
+ // be flushed and PresShell/PresContext/Frames may be dead.
+ // See bug 418470.
+ mTextServicesDocument->ScrollSelectionIntoView();
+ return NS_OK;
}
- selOffset = end;
- }while(end != -1);
- mTsDoc->NextBlock();
- selOffset=0;
- }
+ }
+ selOffset = end;
+ } while(end != -1);
+ mTextServicesDocument->NextBlock();
+ selOffset=0;
+ }
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::CheckWord(const nsAString &aWord, bool *aIsMisspelled, nsTArray<nsString> *aSuggestions)
{
nsresult result;
bool correct;
@@ -182,83 +186,83 @@ mozSpellChecker::Replace(const nsAString
bool done;
nsresult result;
nsAutoString str;
// find out where we are
result = SetupDoc(&selOffset);
if(NS_FAILED(result))
return result;
- result = GetCurrentBlockIndex(mTsDoc,&startBlock);
+ result = GetCurrentBlockIndex(mTextServicesDocument,&startBlock);
if(NS_FAILED(result))
return result;
//start at the beginning
- result = mTsDoc->FirstBlock();
+ result = mTextServicesDocument->FirstBlock();
currOffset=0;
currentBlock = 0;
- while( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done )
- {
- result = mTsDoc->GetCurrentTextBlock(&str);
- do{
- result = mConverter->FindNextWord(str.get(),str.Length(),currOffset,&begin,&end);
- if(NS_SUCCEEDED(result)&&(begin != -1)){
- if (aOldWord.Equals(Substring(str, begin, end-begin))) {
- // if we are before the current selection point but in the same block
- // move the selection point forwards
- if((currentBlock == startBlock)&&(begin < selOffset)){
- selOffset +=
- int32_t(aNewWord.Length()) - int32_t(aOldWord.Length());
- if(selOffset < begin) selOffset=begin;
+ while (NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done) {
+ result = mTextServicesDocument->GetCurrentTextBlock(&str);
+ do {
+ result = mConverter->FindNextWord(str.get(),str.Length(),currOffset,&begin,&end);
+ if (NS_SUCCEEDED(result) && (begin != -1)) {
+ if (aOldWord.Equals(Substring(str, begin, end-begin))) {
+ // if we are before the current selection point but in the same
+ // block move the selection point forwards
+ if (currentBlock == startBlock && begin < selOffset) {
+ selOffset +=
+ int32_t(aNewWord.Length()) - int32_t(aOldWord.Length());
+ if (selOffset < begin) {
+ selOffset=begin;
}
- mTsDoc->SetSelection(begin, end-begin);
- mTsDoc->InsertText(&newWord);
- mTsDoc->GetCurrentTextBlock(&str);
- end += (aNewWord.Length() - aOldWord.Length()); // recursion was cute in GEB, not here.
}
+ mTextServicesDocument->SetSelection(begin, end-begin);
+ mTextServicesDocument->InsertText(&newWord);
+ mTextServicesDocument->GetCurrentTextBlock(&str);
+ end += (aNewWord.Length() - aOldWord.Length()); // recursion was cute in GEB, not here.
}
- currOffset = end;
- }while(currOffset != -1);
- mTsDoc->NextBlock();
- currentBlock++;
- currOffset=0;
- }
+ }
+ currOffset = end;
+ } while(currOffset != -1);
+ mTextServicesDocument->NextBlock();
+ currentBlock++;
+ currOffset=0;
+ }
// We are done replacing. Put the selection point back where we found it (or equivalent);
- result = mTsDoc->FirstBlock();
+ result = mTextServicesDocument->FirstBlock();
currentBlock = 0;
- while(( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done ) &&(currentBlock < startBlock)){
- mTsDoc->NextBlock();
+ while(NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done &&
+ currentBlock < startBlock) {
+ mTextServicesDocument->NextBlock();
}
//After we have moved to the block where the first occurrence of replace was done, put the
//selection to the next word following it. In case there is no word following it i.e if it happens
//to be the last word in that block, then move to the next block and put the selection to the
//first word in that block, otherwise when the Setupdoc() is called, it queries the LastSelectedBlock()
//and the selection offset of the last occurrence of the replaced word is taken instead of the first
//occurrence and things get messed up as reported in the bug 244969
- if( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done ){
+ if (NS_SUCCEEDED(mTextServicesDocument->IsDone(&done)) && !done){
nsString str;
- result = mTsDoc->GetCurrentTextBlock(&str);
+ result = mTextServicesDocument->GetCurrentTextBlock(&str);
result = mConverter->FindNextWord(str.get(),str.Length(),selOffset,&begin,&end);
- if(end == -1)
- {
- mTsDoc->NextBlock();
- selOffset=0;
- result = mTsDoc->GetCurrentTextBlock(&str);
- result = mConverter->FindNextWord(str.get(),str.Length(),selOffset,&begin,&end);
- mTsDoc->SetSelection(begin, 0);
- }
- else
- mTsDoc->SetSelection(begin, 0);
+ if (end == -1) {
+ mTextServicesDocument->NextBlock();
+ selOffset=0;
+ result = mTextServicesDocument->GetCurrentTextBlock(&str);
+ result = mConverter->FindNextWord(str.get(),str.Length(),selOffset,&begin,&end);
+ mTextServicesDocument->SetSelection(begin, 0);
+ } else {
+ mTextServicesDocument->SetSelection(begin, 0);
+ }
}
- }
- else{
- mTsDoc->InsertText(&newWord);
+ } else {
+ mTextServicesDocument->InsertText(&newWord);
}
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::IgnoreAll(const nsAString &aWord)
{
if(mPersonalDictionary){
@@ -455,82 +459,81 @@ mozSpellChecker::SetupDoc(int32_t *outBl
{
nsresult rv;
nsITextServicesDocument::TSDBlockSelectionStatus blockStatus;
int32_t selOffset;
int32_t selLength;
*outBlockOffset = 0;
- if (!mFromStart)
- {
- rv = mTsDoc->LastSelectedBlock(&blockStatus, &selOffset, &selLength);
+ if (!mFromStart) {
+ rv = mTextServicesDocument->LastSelectedBlock(&blockStatus, &selOffset,
+ &selLength);
if (NS_SUCCEEDED(rv) && (blockStatus != nsITextServicesDocument::eBlockNotFound))
{
switch (blockStatus)
{
case nsITextServicesDocument::eBlockOutside: // No TB in S, but found one before/after S.
case nsITextServicesDocument::eBlockPartial: // S begins or ends in TB but extends outside of TB.
// the TS doc points to the block we want.
*outBlockOffset = selOffset + selLength;
break;
case nsITextServicesDocument::eBlockInside: // S extends beyond the start and end of TB.
// we want the block after this one.
- rv = mTsDoc->NextBlock();
+ rv = mTextServicesDocument->NextBlock();
*outBlockOffset = 0;
break;
case nsITextServicesDocument::eBlockContains: // TB contains entire S.
*outBlockOffset = selOffset + selLength;
break;
case nsITextServicesDocument::eBlockNotFound: // There is no text block (TB) in or before the selection (S).
default:
NS_NOTREACHED("Shouldn't ever get this status");
}
}
- else //failed to get last sel block. Just start at beginning
- {
- rv = mTsDoc->FirstBlock();
+ // Failed to get last sel block. Just start at beginning
+ else {
+ rv = mTextServicesDocument->FirstBlock();
*outBlockOffset = 0;
}
}
- else // we want the first block
- {
- rv = mTsDoc->FirstBlock();
+ // We want the first block
+ else {
+ rv = mTextServicesDocument->FirstBlock();
mFromStart = false;
}
return rv;
}
// utility method to discover which block we're in. The TSDoc interface doesn't give
// us this, because it can't assume a read-only document.
// shamelessly stolen from nsTextServicesDocument
nsresult
-mozSpellChecker::GetCurrentBlockIndex(nsITextServicesDocument *aDoc, int32_t *outBlockIndex)
+mozSpellChecker::GetCurrentBlockIndex(
+ TextServicesDocument* aTextServicesDocument,
+ int32_t* aOutBlockIndex)
{
int32_t blockIndex = 0;
bool isDone = false;
nsresult result = NS_OK;
- do
- {
- aDoc->PrevBlock();
-
- result = aDoc->IsDone(&isDone);
-
- if (!isDone)
- blockIndex ++;
-
+ do {
+ aTextServicesDocument->PrevBlock();
+ result = aTextServicesDocument->IsDone(&isDone);
+ if (!isDone) {
+ blockIndex++;
+ }
} while (NS_SUCCEEDED(result) && !isDone);
- *outBlockIndex = blockIndex;
+ *aOutBlockIndex = blockIndex;
return result;
}
nsresult
mozSpellChecker::GetEngineList(nsCOMArray<mozISpellCheckingEngine>* aSpellCheckingEngines)
{
MOZ_ASSERT(!XRE_IsContentProcess());
--- a/extensions/spellcheck/src/mozSpellChecker.h
+++ b/extensions/spellcheck/src/mozSpellChecker.h
@@ -5,17 +5,16 @@
#ifndef mozSpellChecker_h__
#define mozSpellChecker_h__
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsISpellChecker.h"
#include "nsString.h"
-#include "nsITextServicesDocument.h"
#include "mozIPersonalDictionary.h"
#include "mozISpellCheckingEngine.h"
#include "nsClassHashtable.h"
#include "nsTArray.h"
#include "mozISpellI18NUtil.h"
#include "nsCycleCollectionParticipant.h"
#include "RemoteSpellCheckEngineChild.h"
@@ -29,17 +28,18 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(mozSpellChecker)
mozSpellChecker();
nsresult Init();
// nsISpellChecker
- NS_IMETHOD SetDocument(nsITextServicesDocument *aDoc, bool aFromStartofDoc) override;
+ NS_IMETHOD SetDocument(mozilla::TextServicesDocument* aTextServicesDocument,
+ bool aFromStartofDoc) override;
NS_IMETHOD NextMisspelledWord(nsAString &aWord, nsTArray<nsString> *aSuggestions) override;
NS_IMETHOD CheckWord(const nsAString &aWord, bool *aIsMisspelled, nsTArray<nsString> *aSuggestions) override;
NS_IMETHOD Replace(const nsAString &aOldWord, const nsAString &aNewWord, bool aAllOccurrences) override;
NS_IMETHOD IgnoreAll(const nsAString &aWord) override;
NS_IMETHOD AddWordToPersonalDictionary(const nsAString &aWord) override;
NS_IMETHOD RemoveWordFromPersonalDictionary(const nsAString &aWord) override;
NS_IMETHOD GetPersonalDictionary(nsTArray<nsString> *aWordList) override;
@@ -53,27 +53,29 @@ public:
void DeleteRemoteEngine() {
mEngine = nullptr;
}
protected:
virtual ~mozSpellChecker();
nsCOMPtr<mozISpellI18NUtil> mConverter;
- nsCOMPtr<nsITextServicesDocument> mTsDoc;
+ RefPtr<mozilla::TextServicesDocument> mTextServicesDocument;
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
nsCOMPtr<mozISpellCheckingEngine> mSpellCheckingEngine;
bool mFromStart;
nsString mCurrentDictionary;
nsresult SetupDoc(int32_t *outBlockOffset);
- nsresult GetCurrentBlockIndex(nsITextServicesDocument *aDoc, int32_t *outBlockIndex);
+ nsresult GetCurrentBlockIndex(
+ mozilla::TextServicesDocument* aTextServicesDocument,
+ int32_t* aOutBlockIndex);
nsresult GetEngineList(nsCOMArray<mozISpellCheckingEngine> *aDictionaryList);
mozilla::RemoteSpellcheckEngineChild *mEngine;
friend class mozilla::RemoteSpellcheckEngineChild;
};
#endif // mozSpellChecker_h__