Bug 1477917 - Part 2. Use AString instead of wstring in spellchecker. r=masayuki
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 26 Jul 2018 03:13:51 +0000
changeset 428442 86df0a5cc49aeb1d5cd1fd9943803359ea656d92
parent 428441 b7439662fa8f10c4dc640242c40194c734ab1c39
child 428443 55739a1e4de9fd0691e54baf04d55b4edad8a902
push id34336
push userncsoregi@mozilla.com
push dateThu, 26 Jul 2018 21:57:35 +0000
treeherdermozilla-central@3f362dfcc160 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1477917
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1477917 - Part 2. Use AString instead of wstring in spellchecker. r=masayuki The language parameter of mozIPersonalDictionary is unused, so we should remove this from parameter. Then, no one uses mLanguage member of mozHunspell now. Differential Revision: https://phabricator.services.mozilla.com/D2349
extensions/spellcheck/hunspell/glue/mozHunspell.cpp
extensions/spellcheck/hunspell/glue/mozHunspell.h
extensions/spellcheck/idl/mozIPersonalDictionary.idl
extensions/spellcheck/idl/mozISpellCheckingEngine.idl
extensions/spellcheck/src/mozPersonalDictionary.cpp
extensions/spellcheck/src/mozPersonalDictionary.h
extensions/spellcheck/src/mozSpellChecker.cpp
toolkit/modules/InlineSpellChecker.jsm
--- a/extensions/spellcheck/hunspell/glue/mozHunspell.cpp
+++ b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp
@@ -123,54 +123,53 @@ mozHunspell::Init()
 mozHunspell::~mozHunspell()
 {
   mozilla::UnregisterWeakMemoryReporter(this);
 
   mPersonalDictionary = nullptr;
   delete mHunspell;
 }
 
-NS_IMETHODIMP mozHunspell::GetDictionary(char16_t **aDictionary)
+NS_IMETHODIMP
+mozHunspell::GetDictionary(nsAString& aDictionary)
 {
-  NS_ENSURE_ARG_POINTER(aDictionary);
-
-  *aDictionary = ToNewUnicode(mDictionary);
-  return *aDictionary ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+  aDictionary = mDictionary;
+  return NS_OK;
 }
 
 /* set the Dictionary.
  * This also Loads the dictionary and initializes the converter using the dictionaries converter
  */
-NS_IMETHODIMP mozHunspell::SetDictionary(const char16_t *aDictionary)
+NS_IMETHODIMP
+mozHunspell::SetDictionary(const nsAString& aDictionary)
 {
-  NS_ENSURE_ARG_POINTER(aDictionary);
-
-  if (nsDependentString(aDictionary).IsEmpty()) {
+  if (aDictionary.IsEmpty()) {
     delete mHunspell;
     mHunspell = nullptr;
     mDictionary.Truncate();
     mAffixFileName.Truncate();
-    mLanguage.Truncate();
     mDecoder = nullptr;
     mEncoder = nullptr;
 
     return NS_OK;
   }
 
-  nsIURI* affFile = mDictionaries.GetWeak(nsDependentString(aDictionary));
-  if (!affFile)
+  nsIURI* affFile = mDictionaries.GetWeak(aDictionary);
+  if (!affFile) {
     return NS_ERROR_FILE_NOT_FOUND;
+  }
 
   nsAutoCString dictFileName, affFileName;
 
   nsresult rv = affFile->GetSpec(affFileName);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (mAffixFileName.Equals(affFileName.get()))
+  if (mAffixFileName.Equals(affFileName)) {
     return NS_OK;
+  }
 
   dictFileName = affFileName;
   int32_t dotPos = dictFileName.RFindChar('.');
   if (dotPos == -1)
     return NS_ERROR_FAILURE;
 
   dictFileName.SetLength(dotPos);
   dictFileName.AppendLiteral(".dic");
@@ -190,25 +189,16 @@ NS_IMETHODIMP mozHunspell::SetDictionary
   auto encoding =
     Encoding::ForLabelNoReplacement(mHunspell->get_dict_encoding());
   if (!encoding) {
     return NS_ERROR_UCONV_NOCONV;
   }
   mEncoder = encoding->NewEncoder();
   mDecoder = encoding->NewDecoderWithoutBOMHandling();
 
-  int32_t pos = mDictionary.FindChar('-');
-  if (pos == -1)
-    pos = mDictionary.FindChar('_');
-
-  if (pos == -1)
-    mLanguage.Assign(mDictionary);
-  else
-    mLanguage = Substring(mDictionary, 0, pos);
-
   return NS_OK;
 }
 
 NS_IMETHODIMP mozHunspell::GetPersonalDictionary(mozIPersonalDictionary * *aPersonalDictionary)
 {
   *aPersonalDictionary = mPersonalDictionary;
   NS_IF_ADDREF(*aPersonalDictionary);
   return NS_OK;
@@ -319,25 +309,25 @@ mozHunspell::DictionariesChanged(bool aN
 
   if (aNotifyChildProcesses) {
     ContentParent::NotifyUpdatedDictionaries();
   }
 
   // Check if the current dictionary is still available.
   // If not, try to replace it with another dictionary of the same language.
   if (!mDictionary.IsEmpty()) {
-    nsresult rv = SetDictionary(mDictionary.get());
+    nsresult rv = SetDictionary(mDictionary);
     if (NS_SUCCEEDED(rv))
       return;
   }
 
   // If the current dictionary has gone, and we don't have a good replacement,
   // set no current dictionary.
   if (!mDictionary.IsEmpty()) {
-    SetDictionary(EmptyString().get());
+    SetDictionary(EmptyString());
   }
 }
 
 NS_IMETHODIMP
 mozHunspell::LoadDictionariesFromDir(nsIFile* aDir)
 {
   nsresult rv;
 
@@ -386,89 +376,98 @@ mozHunspell::LoadDictionariesFromDir(nsI
 
     mDictionaries.Put(dict, uri);
   }
 
   return NS_OK;
 }
 
 nsresult
-mozHunspell::ConvertCharset(const char16_t* aStr, std::string* aDst)
+mozHunspell::ConvertCharset(const nsAString& aStr, std::string& aDst)
 {
-  NS_ENSURE_ARG_POINTER(aDst);
-  NS_ENSURE_TRUE(mEncoder, NS_ERROR_NULL_POINTER);
+  if (NS_WARN_IF(!mEncoder)) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
 
-  auto src = MakeStringSpan(aStr);
+  auto src = MakeSpan(aStr.BeginReading(), aStr.Length());
   CheckedInt<size_t> needed =
     mEncoder->MaxBufferLengthFromUTF16WithoutReplacement(src.Length());
   if (!needed.isValid()) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  aDst->resize(needed.value());
+  aDst.resize(needed.value());
 
-  char* dstPtr = &aDst->operator[](0);
+  char* dstPtr = &aDst[0];
   auto dst = MakeSpan(reinterpret_cast<uint8_t*>(dstPtr), needed.value());
 
   uint32_t result;
   size_t read;
   size_t written;
   Tie(result, read, written) =
     mEncoder->EncodeFromUTF16WithoutReplacement(src, dst, true);
   Unused << read;
   MOZ_ASSERT(result != kOutputFull);
   if (result != kInputEmpty) {
     return NS_ERROR_UENC_NOMAPPING;
   }
-  aDst->resize(written);
+  aDst.resize(written);
   mEncoder->Encoding()->NewEncoderInto(*mEncoder);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 mozHunspell::CollectReports(nsIHandleReportCallback* aHandleReport,
                             nsISupports* aData, bool aAnonymize)
 {
   MOZ_COLLECT_REPORT(
     "explicit/spell-check", KIND_HEAP, UNITS_BYTES,
     HunspellAllocator::MemoryAllocated(),
     "Memory used by the spell-checking engine.");
 
   return NS_OK;
 }
 
-NS_IMETHODIMP mozHunspell::Check(const char16_t *aWord, bool *aResult)
+NS_IMETHODIMP
+mozHunspell::Check(const nsAString& aWord, bool* aResult)
 {
-  NS_ENSURE_ARG_POINTER(aWord);
-  NS_ENSURE_ARG_POINTER(aResult);
+  if (NS_WARN_IF(!aResult)) {
+    return NS_ERROR_INVALID_ARG;
+  }
   NS_ENSURE_TRUE(mHunspell, NS_ERROR_FAILURE);
 
   std::string charsetWord;
-  nsresult rv = ConvertCharset(aWord, &charsetWord);
+  nsresult rv = ConvertCharset(aWord, charsetWord);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aResult = mHunspell->spell(charsetWord);
 
   if (!*aResult && mPersonalDictionary)
-    rv = mPersonalDictionary->Check(aWord, mLanguage.get(), aResult);
+    rv = mPersonalDictionary->Check(aWord, aResult);
 
   return rv;
 }
 
-NS_IMETHODIMP mozHunspell::Suggest(const char16_t *aWord, char16_t ***aSuggestions, uint32_t *aSuggestionCount)
+NS_IMETHODIMP
+mozHunspell::Suggest(const nsAString& aWord, char16_t*** aSuggestions,
+                     uint32_t* aSuggestionCount)
 {
-  NS_ENSURE_ARG_POINTER(aSuggestions);
-  NS_ENSURE_ARG_POINTER(aSuggestionCount);
+  if (NS_WARN_IF(!aSuggestions)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  if (NS_WARN_IF(!aSuggestionCount)) {
+    return NS_ERROR_INVALID_ARG;
+  }
   NS_ENSURE_TRUE(mHunspell, NS_ERROR_FAILURE);
 
   nsresult rv;
   *aSuggestionCount = 0;
 
   std::string charsetWord;
-  rv = ConvertCharset(aWord, &charsetWord);
+  rv = ConvertCharset(aWord, charsetWord);
   NS_ENSURE_SUCCESS(rv, rv);
 
   std::vector<std::string> suggestions = mHunspell->suggest(charsetWord);
   *aSuggestionCount = static_cast<uint32_t>(suggestions.size());
 
   if (*aSuggestionCount) {
     *aSuggestions  = (char16_t **)moz_xmalloc(*aSuggestionCount * sizeof(char16_t *));
     if (*aSuggestions) {
--- a/extensions/spellcheck/hunspell/glue/mozHunspell.h
+++ b/extensions/spellcheck/hunspell/glue/mozHunspell.h
@@ -94,33 +94,32 @@ public:
 
   mozHunspell();
 
   nsresult Init();
 
   void LoadDictionaryList(bool aNotifyChildProcesses);
 
   // helper method for converting a word to the charset of the dictionary
-  nsresult ConvertCharset(const char16_t* aStr, std::string* aDst);
+  nsresult ConvertCharset(const nsAString& aStr, std::string& aDst);
 
   NS_DECL_NSIMEMORYREPORTER
 
 protected:
   virtual ~mozHunspell();
 
   void DictionariesChanged(bool aNotifyChildProcesses);
 
   nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
   mozilla::UniquePtr<mozilla::Encoder> mEncoder;
   mozilla::UniquePtr<mozilla::Decoder> mDecoder;
 
   // Hashtable matches dictionary name to .aff file
   nsInterfaceHashtable<nsStringHashKey, nsIURI> mDictionaries;
   nsString  mDictionary;
-  nsString  mLanguage;
   nsCString mAffixFileName;
 
   // dynamic dirs used to search for dictionaries
   nsCOMArray<nsIFile> mDynamicDirectories;
   nsInterfaceHashtable<nsStringHashKey, nsIURI> mDynamicDictionaries;
 
   Hunspell  *mHunspell;
 };
--- a/extensions/spellcheck/idl/mozIPersonalDictionary.idl
+++ b/extensions/spellcheck/idl/mozIPersonalDictionary.idl
@@ -28,30 +28,30 @@ interface mozIPersonalDictionary : nsISu
   /**
    * Get the (lexicographically sorted) list of words
    */
   readonly attribute nsIStringEnumerator wordList;
 
   /**
    * Check a unicode string
    */
-  boolean check(in wstring word, in wstring lang);
+  boolean check(in AString word);
 
   /**
    * Add a word to the personal dictionary
    */
-  void addWord(in wstring word, in wstring lang);
+  void addWord(in AString word);
 
   /**
    * Remove a word from the personal dictionary
    */
-  void removeWord(in wstring word, in wstring lang);
+  void removeWord(in AString word);
 
   /**
    * Add a word to the ignore all list
    */
-  void ignoreWord(in wstring word);
+  void ignoreWord(in AString word);
 
   /**
    * Clear the ignore list
    */
   void endSession();
 };
--- a/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
+++ b/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
@@ -20,37 +20,38 @@ interface mozISpellCheckingEngine : nsIS
    * The name of the current dictionary. Is either a value from
    * getDictionaryList or the empty string if no dictionary is selected.
    * Setting this attribute to a value not in getDictionaryList will throw
    * NS_ERROR_FILE_NOT_FOUND.
    *
    * If the dictionary is changed to no dictionary (the empty string), an
    * observer is allowed to set another dictionary before it returns.
    */
-  attribute wstring dictionary;
+  attribute AString dictionary;
 
   /**
    * the personal dictionary
    */
   attribute mozIPersonalDictionary personalDictionary;
 
   /**
    * Get the list of dictionaries
    */
   void getDictionaryList([array, size_is(count)] out wstring dictionaries, out uint32_t count);
 
   /**
    * check a word
    */
-  boolean check(in wstring word);
+  boolean check(in AString word);
 
   /**
    * get a list of suggestions for a misspelled word
    */
-  void suggest(in wstring word,[array, size_is(count)] out wstring suggestions, out uint32_t count);
+  void suggest(in AString word, [array, size_is(count)] out wstring suggestions,
+               out uint32_t count);
 
   /**
    * Load dictionaries from the specified dir
    */
   void loadDictionariesFromDir(in nsIFile dir);
 
   /**
    * Add dictionaries from a directory to the spell checker
--- a/extensions/spellcheck/src/mozPersonalDictionary.cpp
+++ b/extensions/spellcheck/src/mozPersonalDictionary.cpp
@@ -308,17 +308,17 @@ void mozPersonalDictionary::SyncLoadInte
       if( (NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1)) done = true;
     }
     if (!done){
       nsAutoString word;
       while((c != '\n') && (c != '\r') && !done){
         word.Append(c);
         if( (NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1)) done = true;
       }
-      mDictionaryTable.PutEntry(word.get());
+      mDictionaryTable.PutEntry(word);
     }
   } while(!done);
 }
 
 void mozPersonalDictionary::WaitForSave()
 {
   // If no save is pending, we return straight away.
   if (!mSavePending) {
@@ -391,51 +391,54 @@ NS_IMETHODIMP mozPersonalDictionary::Get
     elems++;
   }
 
   array->Sort();
 
   return NS_NewAdoptingStringEnumerator(aWords, array);
 }
 
-NS_IMETHODIMP mozPersonalDictionary::Check(const char16_t *aWord, const char16_t *aLanguage, bool *aResult)
+NS_IMETHODIMP
+mozPersonalDictionary::Check(const nsAString& aWord, bool* aResult)
 {
-  NS_ENSURE_ARG_POINTER(aWord);
   NS_ENSURE_ARG_POINTER(aResult);
 
   WaitForLoad();
 
   *aResult = (mDictionaryTable.GetEntry(aWord) || mIgnoreTable.GetEntry(aWord));
   return NS_OK;
 }
 
-NS_IMETHODIMP mozPersonalDictionary::AddWord(const char16_t *aWord, const char16_t *aLang)
+NS_IMETHODIMP
+mozPersonalDictionary::AddWord(const nsAString& aWord)
 {
   nsresult res;
   WaitForLoad();
 
   mDictionaryTable.PutEntry(aWord);
   res = Save();
   return res;
 }
 
-NS_IMETHODIMP mozPersonalDictionary::RemoveWord(const char16_t *aWord, const char16_t *aLang)
+NS_IMETHODIMP
+mozPersonalDictionary::RemoveWord(const nsAString& aWord)
 {
   nsresult res;
   WaitForLoad();
 
   mDictionaryTable.RemoveEntry(aWord);
   res = Save();
   return res;
 }
 
-NS_IMETHODIMP mozPersonalDictionary::IgnoreWord(const char16_t *aWord)
+NS_IMETHODIMP
+mozPersonalDictionary::IgnoreWord(const nsAString& aWord)
 {
   // avoid adding duplicate words to the ignore list
-  if (aWord && !mIgnoreTable.GetEntry(aWord))
+  if (!mIgnoreTable.GetEntry(aWord))
     mIgnoreTable.PutEntry(aWord);
   return NS_OK;
 }
 
 NS_IMETHODIMP mozPersonalDictionary::EndSession()
 {
   WaitForLoad();
 
--- a/extensions/spellcheck/src/mozPersonalDictionary.h
+++ b/extensions/spellcheck/src/mozPersonalDictionary.h
@@ -46,18 +46,18 @@ protected:
   bool mIsLoaded;
 
   /* true if a dictionary save is pending */
   bool mSavePending;
 
   nsCOMPtr<nsIFile> mFile;
   mozilla::Monitor mMonitor;
   mozilla::Monitor mMonitorSave;
-  nsTHashtable<nsUnicharPtrHashKey> mDictionaryTable;
-  nsTHashtable<nsUnicharPtrHashKey> mIgnoreTable;
+  nsTHashtable<nsStringHashKey> mDictionaryTable;
+  nsTHashtable<nsStringHashKey> mIgnoreTable;
 
 private:
   /* wait for the asynchronous load of the dictionary to be completed */
   void WaitForLoad();
 
   /* enter the monitor before starting a synchronous load off the main-thread */
   void SyncLoad();
 
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -151,24 +151,24 @@ mozSpellChecker::CheckWord(const nsAStri
     }
     return rv ? NS_OK : NS_ERROR_NOT_AVAILABLE;
   }
 
   if(!mSpellCheckingEngine) {
     return NS_ERROR_NULL_POINTER;
   }
   *aIsMisspelled = false;
-  result = mSpellCheckingEngine->Check(PromiseFlatString(aWord).get(), &correct);
+  result = mSpellCheckingEngine->Check(aWord, &correct);
   NS_ENSURE_SUCCESS(result, result);
   if(!correct){
     if(aSuggestions){
       uint32_t count,i;
       char16_t **words;
 
-      result = mSpellCheckingEngine->Suggest(PromiseFlatString(aWord).get(), &words, &count);
+      result = mSpellCheckingEngine->Suggest(aWord, &words, &count);
       NS_ENSURE_SUCCESS(result, result);
       nsString* suggestions = aSuggestions->AppendElements(count);
       for(i=0;i<count;i++){
 	suggestions[i].Assign(words[i]);
       }
 
       if (count)
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
@@ -267,41 +267,41 @@ mozSpellChecker::Replace(const nsAString
     mTextServicesDocument->InsertText(&newWord);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 mozSpellChecker::IgnoreAll(const nsAString &aWord)
 {
-  if(mPersonalDictionary){
-    mPersonalDictionary->IgnoreWord(PromiseFlatString(aWord).get());
+  if (mPersonalDictionary) {
+    mPersonalDictionary->IgnoreWord(aWord);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 mozSpellChecker::AddWordToPersonalDictionary(const nsAString &aWord)
 {
   nsresult res;
-  char16_t empty=0;
-  if (!mPersonalDictionary)
-    return NS_ERROR_NULL_POINTER;
-  res = mPersonalDictionary->AddWord(PromiseFlatString(aWord).get(),&empty);
+  if (NS_WARN_IF(!mPersonalDictionary)) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  res = mPersonalDictionary->AddWord(aWord);
   return res;
 }
 
 NS_IMETHODIMP
 mozSpellChecker::RemoveWordFromPersonalDictionary(const nsAString &aWord)
 {
   nsresult res;
-  char16_t empty=0;
-  if (!mPersonalDictionary)
-    return NS_ERROR_NULL_POINTER;
-  res = mPersonalDictionary->RemoveWord(PromiseFlatString(aWord).get(),&empty);
+  if (NS_WARN_IF(!mPersonalDictionary)) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+  res = mPersonalDictionary->RemoveWord(aWord);
   return res;
 }
 
 NS_IMETHODIMP
 mozSpellChecker::GetPersonalDictionary(nsTArray<nsString> *aWordList)
 {
   if(!aWordList || !mPersonalDictionary)
     return NS_ERROR_NULL_POINTER;
@@ -374,20 +374,17 @@ mozSpellChecker::GetCurrentDictionary(ns
     return NS_OK;
   }
 
   if (!mSpellCheckingEngine) {
     aDictionary.Truncate();
     return NS_OK;
   }
 
-  nsAutoString dictname;
-  mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
-  aDictionary = dictname;
-  return NS_OK;
+  return mSpellCheckingEngine->GetDictionary(aDictionary);
 }
 
 NS_IMETHODIMP
 mozSpellChecker::SetCurrentDictionary(const nsAString &aDictionary)
 {
   if (XRE_IsContentProcess()) {
     nsString wrappedDict = nsString(aDictionary);
     bool isSuccess;
@@ -416,17 +413,17 @@ mozSpellChecker::SetCurrentDictionary(co
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (int32_t i = 0; i < spellCheckingEngines.Count(); i++) {
     // We must set mSpellCheckingEngine before we call SetDictionary, since
     // SetDictionary calls back to this spell checker to check if the
     // dictionary was set
     mSpellCheckingEngine = spellCheckingEngines[i];
 
-    rv = mSpellCheckingEngine->SetDictionary(PromiseFlatString(aDictionary).get());
+    rv = mSpellCheckingEngine->SetDictionary(aDictionary);
 
     if (NS_SUCCEEDED(rv)) {
       nsCOMPtr<mozIPersonalDictionary> personalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
       mSpellCheckingEngine->SetPersonalDictionary(personalDictionary.get());
 
       mConverter = new mozEnglishWordUtils;
       return NS_OK;
     }
--- a/toolkit/modules/InlineSpellChecker.jsm
+++ b/toolkit/modules/InlineSpellChecker.jsm
@@ -487,24 +487,24 @@ RemoteSpellChecker.prototype = {
     // child, but it's hard to access it. However, we know that
     // addToDictionary adds the word to the singleton personal dictionary, so
     // we just do that here.
     // NB: We also rely on the fact that we only ever pass an empty string in
     // as the "lang".
 
     let dictionary = Cc["@mozilla.org/spellchecker/personaldictionary;1"]
                        .getService(Ci.mozIPersonalDictionary);
-    dictionary.addWord(this._spellInfo.misspelling, "");
+    dictionary.addWord(this._spellInfo.misspelling);
 
     this._spellInfo.target.sendAsyncMessage("InlineSpellChecker:recheck", {});
   },
   undoAddToDictionary(word) {
     let dictionary = Cc["@mozilla.org/spellchecker/personaldictionary;1"]
                        .getService(Ci.mozIPersonalDictionary);
-    dictionary.removeWord(word, "");
+    dictionary.removeWord(word);
 
     this._spellInfo.target.sendAsyncMessage("InlineSpellChecker:recheck", {});
   },
   ignoreWord() {
     let dictionary = Cc["@mozilla.org/spellchecker/personaldictionary;1"]
                        .getService(Ci.mozIPersonalDictionary);
     dictionary.ignoreWord(this._spellInfo.misspelling);