Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add session.listWordsInSpellCheckerDictionary API #22128

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/api/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<String[]>` - 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
Expand Down
62 changes: 62 additions & 0 deletions shell/browser/api/electron_api_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -226,6 +227,42 @@ void DestroyGlobalHandle(v8::Isolate* isolate,
}
}

class DictionaryObserver final : public SpellcheckCustomDictionary::Observer {
private:
std::unique_ptr<gin_helper::Promise<std::set<std::string>>> promise_;
base::WeakPtr<SpellcheckService> spellcheck_;

public:
DictionaryObserver(gin_helper::Promise<std::set<std::string>> promise,
base::WeakPtr<SpellcheckService> spellcheck)
: spellcheck_(spellcheck) {
promise_ = std::make_unique<gin_helper::Promise<std::set<std::string>>>(
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)
Expand Down Expand Up @@ -766,6 +803,29 @@ void SetSpellCheckerDictionaryDownloadURL(gin_helper::ErrorThrower thrower,
SpellcheckHunspellDictionary::SetDownloadURLForTesting(url);
}

v8::Local<v8::Promise> Session::ListWordsInSpellCheckerDictionary() {
gin_helper::Promise<std::set<std::string>> promise(isolate());
v8::Local<v8::Promise> 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) {
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
if (spellcheck::UseBrowserSpellChecker()) {
Expand Down Expand Up @@ -865,6 +925,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
&spellcheck::SpellCheckLanguages)
.SetMethod("setSpellCheckerDictionaryDownloadURL",
&SetSpellCheckerDictionaryDownloadURL)
.SetMethod("listWordsInSpellCheckerDictionary",
&Session::ListWordsInSpellCheckerDictionary)
.SetMethod("addWordToSpellCheckerDictionary",
&Session::AddWordToSpellCheckerDictionary)
#endif
Expand Down
1 change: 1 addition & 0 deletions shell/browser/api/electron_api_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class Session : public gin_helper::TrackableObject<Session>,
base::Value GetSpellCheckerLanguages();
void SetSpellCheckerLanguages(gin_helper::ErrorThrower thrower,
const std::vector<std::string>& languages);
v8::Local<v8::Promise> ListWordsInSpellCheckerDictionary();
bool AddWordToSpellCheckerDictionary(const std::string& word);
#endif

Expand Down