From b3e1134a1a86c98dc4cd011a7d202e7eec346765 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Thu, 5 Mar 2020 11:58:19 -0800 Subject: [PATCH] feat: add events for spellcheck dictionary downloads (#22449) --- docs/api/session.md | 39 +++++++++++ patches/chromium/.patches | 1 + ...to_add_observers_on_created_hunspell.patch | 64 +++++++++++++++++++ shell/browser/api/electron_api_session.cc | 25 ++++++++ shell/browser/api/electron_api_session.h | 12 +++- 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 patches/chromium/feat_allow_embedders_to_add_observers_on_created_hunspell.patch diff --git a/docs/api/session.md b/docs/api/session.md index e3d0191513a..8d82a77a4b8 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -105,6 +105,45 @@ Returns: Emitted when a render process requests preconnection to a URL, generally due to a [resource hint](https://w3c.github.io/resource-hints/). +#### Event: 'spellcheck-dictionary-initialized' + +Returns: + +* `event` Event +* `languageCode` String - The language code of the dictionary file + +Emitted when a hunspell dictionary file has been successfully initialized. This +occurs after the file has been downloaded. + +#### Event: 'spellcheck-dictionary-download-begin' + +Returns: + +* `event` Event +* `languageCode` String - The language code of the dictionary file + +Emitted when a hunspell dictionary file starts downloading + +#### Event: 'spellcheck-dictionary-download-success' + +Returns: + +* `event` Event +* `languageCode` String - The language code of the dictionary file + +Emitted when a hunspell dictionary file has been successfully downloaded + +#### Event: 'spellcheck-dictionary-download-failure' + +Returns: + +* `event` Event +* `languageCode` String - The language code of the dictionary file + +Emitted when a hunspell dictionary file download fails. For details +on the failure you should collect a netlog and inspect the download +request. + ### Instance Methods The following methods are available on instances of `Session`: diff --git a/patches/chromium/.patches b/patches/chromium/.patches index 37d6880cda8..6d56a9a624c 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -89,3 +89,4 @@ feat_add_support_for_overriding_the_base_spellchecker_download_url.patch feat_enable_offscreen_rendering_with_viz_compositor.patch delay_lock_the_protocol_scheme_registry.patch gpu_notify_when_dxdiag_request_fails.patch +feat_allow_embedders_to_add_observers_on_created_hunspell.patch diff --git a/patches/chromium/feat_allow_embedders_to_add_observers_on_created_hunspell.patch b/patches/chromium/feat_allow_embedders_to_add_observers_on_created_hunspell.patch new file mode 100644 index 00000000000..5713b443966 --- /dev/null +++ b/patches/chromium/feat_allow_embedders_to_add_observers_on_created_hunspell.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Attard +Date: Sun, 1 Mar 2020 16:33:55 -0800 +Subject: feat: allow embedders to add observers on created hunspell + dictionaries + + +diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc +index 0dc509bafcfab2637aab4ea55769cd06ad3492c9..3b1f02e354c5c5a85e9193859ca8e7497f02cf86 100644 +--- a/chrome/browser/spellchecker/spellcheck_service.cc ++++ b/chrome/browser/spellchecker/spellcheck_service.cc +@@ -284,6 +284,9 @@ void SpellcheckService::LoadHunspellDictionaries() { + std::make_unique(dictionary, context_, + this)); + hunspell_dictionaries_.back()->AddObserver(this); ++ if (hunspell_observer_) { ++ hunspell_dictionaries_.back()->AddObserver(hunspell_observer_); ++ } + hunspell_dictionaries_.back()->Load(); + } + +@@ -297,6 +300,20 @@ SpellcheckService::GetHunspellDictionaries() { + return hunspell_dictionaries_; + } + ++void SpellcheckService::SetHunspellObserver(SpellcheckHunspellDictionary::Observer* observer) { ++ if (hunspell_observer_) { ++ for (auto& dict : hunspell_dictionaries_) { ++ dict->RemoveObserver(hunspell_observer_); ++ } ++ } ++ if (observer) { ++ for (auto& dict : hunspell_dictionaries_) { ++ dict->AddObserver(observer); ++ } ++ } ++ hunspell_observer_ = observer; ++} ++ + bool SpellcheckService::LoadExternalDictionary(std::string language, + std::string locale, + std::string path, +diff --git a/chrome/browser/spellchecker/spellcheck_service.h b/chrome/browser/spellchecker/spellcheck_service.h +index 557a0a2a91821a595181481f92b2a2a06dcb1f50..59e24da4be927303df8c4aac87f50778c1c208b0 100644 +--- a/chrome/browser/spellchecker/spellcheck_service.h ++++ b/chrome/browser/spellchecker/spellcheck_service.h +@@ -116,6 +116,8 @@ class SpellcheckService : public KeyedService, + const std::vector>& + GetHunspellDictionaries(); + ++ void SetHunspellObserver(SpellcheckHunspellDictionary::Observer* observer); ++ + // Load a dictionary from a given path. Format specifies how the dictionary + // is stored. Return value is true if successful. + bool LoadExternalDictionary(std::string language, +@@ -213,6 +215,8 @@ class SpellcheckService : public KeyedService, + // A pointer to the BrowserContext which this service refers to. + content::BrowserContext* context_; + ++ SpellcheckHunspellDictionary::Observer* hunspell_observer_ = nullptr; ++ + std::unique_ptr metrics_; + + std::unique_ptr custom_dictionary_; diff --git a/shell/browser/api/electron_api_session.cc b/shell/browser/api/electron_api_session.cc index 78cde59d37d..25c83b1249f 100644 --- a/shell/browser/api/electron_api_session.cc +++ b/shell/browser/api/electron_api_session.cc @@ -279,11 +279,23 @@ Session::Session(v8::Isolate* isolate, ElectronBrowserContext* browser_context) Init(isolate); AttachAsUserData(browser_context); + + SpellcheckService* service = + SpellcheckServiceFactory::GetForContext(browser_context_.get()); + if (service) { + service->SetHunspellObserver(this); + } } Session::~Session() { content::BrowserContext::GetDownloadManager(browser_context()) ->RemoveObserver(this); + + SpellcheckService* service = + SpellcheckServiceFactory::GetForContext(browser_context_.get()); + if (service) { + service->SetHunspellObserver(nullptr); + } // TODO(zcbenz): Now since URLRequestContextGetter is gone, is this still // needed? // Refs https://github.com/electron/electron/pull/12305. @@ -312,6 +324,19 @@ void Session::OnDownloadCreated(content::DownloadManager* manager, } } +void Session::OnHunspellDictionaryInitialized(const std::string& language) { + Emit("spellcheck-dictionary-initialized", language); +} +void Session::OnHunspellDictionaryDownloadBegin(const std::string& language) { + Emit("spellcheck-dictionary-download-begin", language); +} +void Session::OnHunspellDictionaryDownloadSuccess(const std::string& language) { + Emit("spellcheck-dictionary-download-success", language); +} +void Session::OnHunspellDictionaryDownloadFailure(const std::string& language) { + Emit("spellcheck-dictionary-download-failure", language); +} + v8::Local Session::ResolveProxy(gin_helper::Arguments* args) { v8::Isolate* isolate = args->isolate(); gin_helper::Promise promise(isolate); diff --git a/shell/browser/api/electron_api_session.h b/shell/browser/api/electron_api_session.h index 7e1498162d1..6beced55f5a 100644 --- a/shell/browser/api/electron_api_session.h +++ b/shell/browser/api/electron_api_session.h @@ -9,6 +9,7 @@ #include #include "base/values.h" +#include "chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h" #include "content/public/browser/download_manager.h" #include "electron/buildflags/buildflags.h" #include "gin/handle.h" @@ -37,7 +38,8 @@ class ElectronBrowserContext; namespace api { class Session : public gin_helper::TrackableObject, - public content::DownloadManager::Observer { + public content::DownloadManager::Observer, + public SpellcheckHunspellDictionary::Observer { public: // Gets or creates Session from the |browser_context|. static gin::Handle CreateFrom( @@ -116,6 +118,14 @@ class Session : public gin_helper::TrackableObject, void OnDownloadCreated(content::DownloadManager* manager, download::DownloadItem* item) override; + // SpellcheckHunspellDictionary::Observer + void OnHunspellDictionaryInitialized(const std::string& language) override; + void OnHunspellDictionaryDownloadBegin(const std::string& language) override; + void OnHunspellDictionaryDownloadSuccess( + const std::string& language) override; + void OnHunspellDictionaryDownloadFailure( + const std::string& language) override; + private: // Cached gin_helper::Wrappable objects. v8::Global cookies_;