Bug 1502661 - Part 2. Add async method to check word by spellchecker. r=masayuki
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Tue, 18 Dec 2018 20:23:44 +0900
changeset 514254 77ec2b95a66441cd1fa3d6a173d4ab6159407774
parent 514253 ae2e40fee31665a104031f3ddd239919a6c9ab61
child 514255 683f9ffb0443ae71eabf1c78d4fa65223e7b0549
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1502661
milestone66.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 1502661 - Part 2. Add async method to check word by spellchecker. r=masayuki For mozInlineSpellChecker, I would like to add promse-based method to check word. But this method is - On content process, it works by async. - On chrome process, it works by sync. Some reftests with non-e10s don't wait that spellchecker is finished correctly due to race condition of spellchecker dictionary update. So it uses sync'd promise on chrome. Differential Revision: https://phabricator.services.mozilla.com/D14836
editor/spellchecker/EditorSpellCheck.cpp
editor/spellchecker/EditorSpellCheck.h
extensions/spellcheck/src/mozSpellChecker.cpp
extensions/spellcheck/src/mozSpellChecker.h
--- a/editor/spellchecker/EditorSpellCheck.cpp
+++ b/editor/spellchecker/EditorSpellCheck.cpp
@@ -436,16 +436,26 @@ EditorSpellCheck::CheckCurrentWord(const
 NS_IMETHODIMP
 EditorSpellCheck::CheckCurrentWordNoSuggest(const nsAString& aSuggestedWord,
                                             bool* aIsMisspelled) {
   NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NOT_INITIALIZED);
 
   return mSpellChecker->CheckWord(aSuggestedWord, aIsMisspelled, nullptr);
 }
 
+RefPtr<CheckWordPromise> EditorSpellCheck::CheckCurrentWordsNoSuggest(
+    const nsTArray<nsString>& aSuggestedWords) {
+  if (NS_WARN_IF(!mSpellChecker)) {
+    return CheckWordPromise::CreateAndReject(NS_ERROR_NOT_INITIALIZED,
+                                             __func__);
+  }
+
+  return mSpellChecker->CheckWords(aSuggestedWords);
+}
+
 NS_IMETHODIMP
 EditorSpellCheck::ReplaceWord(const nsAString& aMisspelledWord,
                               const nsAString& aReplaceWord,
                               bool aAllOccurrences) {
   NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NOT_INITIALIZED);
 
   return mSpellChecker->Replace(aMisspelledWord, aReplaceWord, aAllOccurrences);
 }
--- a/editor/spellchecker/EditorSpellCheck.h
+++ b/editor/spellchecker/EditorSpellCheck.h
@@ -1,17 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; 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 mozilla_EditorSpellCheck_h
 #define mozilla_EditorSpellCheck_h
 
-#include "nsCOMPtr.h"  // for nsCOMPtr
+#include "mozilla/mozSpellChecker.h"  // for mozilla::CheckWordPromise
+#include "nsCOMPtr.h"                 // for nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsIEditorSpellCheck.h"  // for NS_DECL_NSIEDITORSPELLCHECK, etc
 #include "nsISupportsImpl.h"
 #include "nsString.h"  // for nsString
 #include "nsTArray.h"  // for nsTArray
 #include "nscore.h"    // for nsresult
 
 class mozSpellChecker;
@@ -37,16 +38,29 @@ class EditorSpellCheck final : public ns
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(EditorSpellCheck)
 
   /* Declare all methods in the nsIEditorSpellCheck interface */
   NS_DECL_NSIEDITORSPELLCHECK
 
   mozSpellChecker* GetSpellChecker();
 
+  /**
+   * Like CheckCurrentWord, checks the word you give it, returning true via
+   * promise if it's misspelled.
+   * This is faster than CheckCurrentWord because it does not compute
+   * any suggestions.
+   *
+   * Watch out: this does not clear any suggestions left over from previous
+   * calls to CheckCurrentWord, so there may be suggestions, but they will be
+   * invalid.
+   */
+  RefPtr<mozilla::CheckWordPromise> CheckCurrentWordsNoSuggest(
+      const nsTArray<nsString>& aSuggestedWords);
+
  protected:
   virtual ~EditorSpellCheck();
 
   RefPtr<mozSpellChecker> mSpellChecker;
   RefPtr<EditorBase> mEditor;
 
   nsTArray<nsString> mSuggestedWordList;
 
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -111,16 +111,44 @@ nsresult mozSpellChecker::NextMisspelled
       selOffset = end;
     } while (end != -1);
     mTextServicesDocument->NextBlock();
     selOffset = 0;
   }
   return NS_OK;
 }
 
+RefPtr<CheckWordPromise> mozSpellChecker::CheckWords(
+    const nsTArray<nsString> &aWords) {
+  if (XRE_IsContentProcess()) {
+    return mEngine->SendCheckAsync(aWords)->Then(
+        GetMainThreadSerialEventTarget(), __func__,
+        [](nsTArray<bool> &&aIsMisspelled) {
+          return CheckWordPromise::CreateAndResolve(std::move(aIsMisspelled),
+                                                    __func__);
+        },
+        [](mozilla::ipc::ResponseRejectReason &&aReason) {
+          return CheckWordPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE,
+                                                   __func__);
+        });
+  }
+
+  nsTArray<bool> misspells;
+  misspells.SetCapacity(aWords.Length());
+  for (auto &word : aWords) {
+    bool misspelled;
+    nsresult rv = CheckWord(word, &misspelled, nullptr);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return CheckWordPromise::CreateAndReject(rv, __func__);
+    }
+    misspells.AppendElement(misspelled);
+  }
+  return CheckWordPromise::CreateAndResolve(std::move(misspells), __func__);
+}
+
 nsresult mozSpellChecker::CheckWord(const nsAString &aWord, bool *aIsMisspelled,
                                     nsTArray<nsString> *aSuggestions) {
   nsresult result;
   bool correct;
 
   if (XRE_IsContentProcess()) {
     nsString wordwrapped = nsString(aWord);
     bool rv;
--- a/extensions/spellcheck/src/mozSpellChecker.h
+++ b/extensions/spellcheck/src/mozSpellChecker.h
@@ -1,30 +1,32 @@
 /* -*- Mode: C++; tab-width: 2; 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 mozSpellChecker_h__
 #define mozSpellChecker_h__
 
+#include "mozilla/MozPromise.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsString.h"
 #include "mozIPersonalDictionary.h"
 #include "mozISpellCheckingEngine.h"
 #include "nsClassHashtable.h"
 #include "nsTArray.h"
 #include "nsCycleCollectionParticipant.h"
 
 class mozEnglishWordUtils;
 
 namespace mozilla {
 class RemoteSpellcheckEngineChild;
 class TextServicesDocument;
+typedef MozPromise<nsTArray<bool>, nsresult, false> CheckWordPromise;
 }  // namespace mozilla
 
 class mozSpellChecker final {
  public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(mozSpellChecker)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(mozSpellChecker)
 
   static already_AddRefed<mozSpellChecker> Create() {
@@ -59,16 +61,23 @@ class mozSpellChecker final {
    * @param aSuggestions is an array of nsStrings which represent the
    * suggested replacements for the misspelled word. The array will be empty
    * if there aren't any suggestions.
    */
   nsresult CheckWord(const nsAString& aWord, bool* aIsMisspelled,
                      nsTArray<nsString>* aSuggestions);
 
   /**
+   * This is a flavor of CheckWord, is async version of CheckWord.
+   * @Param aWords is array of words to check
+   */
+  RefPtr<mozilla::CheckWordPromise> CheckWords(
+      const nsTArray<nsString>& aWords);
+
+  /**
    * Replaces the old word with the specified new word.
    * @param aOldWord is the word to be replaced.
    * @param aNewWord is the word that is to replace old word.
    * @param aAllOccurrences will replace all occurrences of old
    * word, in the document, with new word when it is true. If
    * false, it will replace the 1st occurrence only!
    */
   nsresult Replace(const nsAString& aOldWord, const nsAString& aNewWord,