diff --git a/docs/api/session.md b/docs/api/session.md index 7179fb37836..e9575335bee 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -487,6 +487,11 @@ to host here. **Note:** On macOS the OS spellchecker is used and therefore we do not download any dictionary files. This API is a no-op on macOS. +#### `ses.listWordsInSpellCheckerDictionary()` + +Returns `Promise` - An array of all words in app's custom dictionary. +Resolves when the full dictionary is loaded from disk. + #### `ses.addWordToSpellCheckerDictionary(word)` * `word` String - The word you want to add to the dictionary diff --git a/shell/browser/api/electron_api_session.cc b/shell/browser/api/electron_api_session.cc index d1c90bcc0f3..e73727c9887 100644 --- a/shell/browser/api/electron_api_session.cc +++ b/shell/browser/api/electron_api_session.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -226,6 +227,42 @@ void DestroyGlobalHandle(v8::Isolate* isolate, } } +class DictionaryObserver final : public SpellcheckCustomDictionary::Observer { + private: + std::unique_ptr>> promise_; + base::WeakPtr spellcheck_; + + public: + DictionaryObserver(gin_helper::Promise> promise, + base::WeakPtr spellcheck) + : spellcheck_(spellcheck) { + promise_ = std::make_unique>>( + std::move(promise)); + if (spellcheck_) + spellcheck_->GetCustomDictionary()->AddObserver(this); + } + + ~DictionaryObserver() { + if (spellcheck_) + spellcheck_->GetCustomDictionary()->RemoveObserver(this); + } + + void OnCustomDictionaryLoaded() override { + if (spellcheck_) { + promise_->Resolve(spellcheck_->GetCustomDictionary()->GetWords()); + } else { + promise_->RejectWithErrorMessage( + "Spellcheck in unexpected state: failed to load custom dictionary."); + } + delete this; + } + + void OnCustomDictionaryChanged( + const SpellcheckCustomDictionary::Change& dictionary_change) override { + // noop + } +}; + } // namespace Session::Session(v8::Isolate* isolate, ElectronBrowserContext* browser_context) @@ -771,6 +808,29 @@ void SetSpellCheckerDictionaryDownloadURL(gin_helper::ErrorThrower thrower, SpellcheckHunspellDictionary::SetDownloadURLForTesting(url); } +v8::Local Session::ListWordsInSpellCheckerDictionary() { + gin_helper::Promise> promise(isolate()); + v8::Local handle = promise.GetHandle(); + + SpellcheckService* spellcheck = + SpellcheckServiceFactory::GetForContext(browser_context_.get()); + + if (!spellcheck) + promise.RejectWithErrorMessage( + "Spellcheck in unexpected state: failed to load custom dictionary."); + + if (spellcheck->GetCustomDictionary()->IsLoaded()) { + promise.Resolve(spellcheck->GetCustomDictionary()->GetWords()); + } else { + new DictionaryObserver(std::move(promise), spellcheck->GetWeakPtr()); + // Dictionary loads by default asynchronously, + // call the load function anyways just to be sure. + spellcheck->GetCustomDictionary()->Load(); + } + + return handle; +} + bool Session::AddWordToSpellCheckerDictionary(const std::string& word) { SpellcheckService* service = SpellcheckServiceFactory::GetForContext(browser_context_.get()); @@ -886,6 +946,8 @@ void Session::BuildPrototype(v8::Isolate* isolate, &spellcheck::SpellCheckLanguages) .SetMethod("setSpellCheckerDictionaryDownloadURL", &SetSpellCheckerDictionaryDownloadURL) + .SetMethod("listWordsInSpellCheckerDictionary", + &Session::ListWordsInSpellCheckerDictionary) .SetMethod("addWordToSpellCheckerDictionary", &Session::AddWordToSpellCheckerDictionary) .SetMethod("removeWordFromSpellCheckerDictionary", diff --git a/shell/browser/api/electron_api_session.h b/shell/browser/api/electron_api_session.h index 640d3104e26..8c9a04fdfb8 100644 --- a/shell/browser/api/electron_api_session.h +++ b/shell/browser/api/electron_api_session.h @@ -95,6 +95,7 @@ class Session : public gin_helper::TrackableObject, base::Value GetSpellCheckerLanguages(); void SetSpellCheckerLanguages(gin_helper::ErrorThrower thrower, const std::vector& languages); + v8::Local ListWordsInSpellCheckerDictionary(); bool AddWordToSpellCheckerDictionary(const std::string& word); bool RemoveWordFromSpellCheckerDictionary(const std::string& word); #endif