// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_ #define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_ #include #include #include "base/containers/id_map.h" #include "base/macros.h" #include "build/build_config.h" #include "components/spellcheck/common/spellcheck.mojom.h" #include "components/spellcheck/spellcheck_buildflags.h" #include "content/public/renderer/render_frame_observer.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/web/web_text_check_client.h" #if defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER) #include #endif // defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER) class SpellCheck; struct SpellCheckResult; namespace base { class TimeTicks; } namespace blink { class WebTextCheckingCompletion; struct WebTextCheckingResult; } namespace service_manager { class LocalInterfaceProvider; } // This class deals with asynchronously invoking text spelling and grammar // checking services provided by the browser process (host). class SpellCheckProvider : public content::RenderFrameObserver, public blink::WebTextCheckClient { public: using WebTextCheckCompletions = base::IDMap>; #if defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER) // A struct to hold information related to hybrid spell check requests. struct HybridSpellCheckRequestInfo { bool used_hunspell; bool used_native; base::TimeTicks request_start_ticks; }; #endif // defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER) SpellCheckProvider( content::RenderFrame* render_frame, SpellCheck* spellcheck, service_manager::LocalInterfaceProvider* embedder_provider); ~SpellCheckProvider() override; // Requests async spell and grammar checks from the platform text checker // available in the browser process. The function does not have special // handling for partial words, as Blink guarantees that no request is made // when typing in the middle of a word. void RequestTextChecking( const base::string16& text, std::unique_ptr completion); // The number of ongoing spell check host requests. size_t pending_text_request_size() const { return text_check_completions_.size(); } // Replace shared spellcheck data. void set_spellcheck(SpellCheck* spellcheck) { spellcheck_ = spellcheck; } // content::RenderFrameObserver: void FocusedElementChanged(const blink::WebElement& element) override; private: friend class TestingSpellCheckProvider; class DictionaryUpdateObserverImpl; // Sets the SpellCheckHost (for unit tests). void SetSpellCheckHostForTesting( mojo::PendingRemote host) { spell_check_host_.Bind(std::move(host)); } // Reset dictionary_update_observer_ in TestingSpellCheckProvider dtor. void ResetDictionaryUpdateObserverForTesting(); // Returns the SpellCheckHost. spellcheck::mojom::SpellCheckHost& GetSpellCheckHost(); // Tries to satisfy a spellcheck request from the cache in |last_request_|. // Returns true (and cancels/finishes the completion) if it can, false // if the provider should forward the query on. bool SatisfyRequestFromCache(const base::string16& text, blink::WebTextCheckingCompletion* completion); // content::RenderFrameObserver: void OnDestruct() override; // blink::WebTextCheckClient: bool IsSpellCheckingEnabled() const override; void CheckSpelling( const blink::WebString& text, size_t& offset, size_t& length, blink::WebVector* optional_suggestions) override; void RequestCheckingOfText( const blink::WebString& text, std::unique_ptr completion) override; #if BUILDFLAG(USE_RENDERER_SPELLCHECKER) void OnRespondSpellingService(int identifier, const base::string16& text, bool success, const std::vector& results); #endif // Returns whether |text| has word characters, i.e. whether a spellchecker // needs to check this text. bool HasWordCharacters(const base::string16& text, size_t index) const; #if BUILDFLAG(USE_BROWSER_SPELLCHECKER) void OnRespondTextCheck( int identifier, const base::string16& line, const std::vector& results); // Makes mojo calls to the browser process to perform platform spellchecking. void RequestTextCheckingFromBrowser(const base::string16& text); #if defined(OS_WIN) // Callback for when spellcheck service has been initialized on demand. void OnRespondInitializeDictionaries( const base::string16& text, std::vector dictionaries, const std::vector& custom_words, bool enable); // Flag indicating that the spellcheck service has been initialized and // the dictionaries have been loaded initially. Used to avoid an unnecessary // mojo call to determine this in every text check request. bool dictionaries_loaded_ = false; #endif // defined(OS_WIN) #endif // BUILDFLAG(USE_BROWSER_SPELLCHECKER) // Holds ongoing spellchecking operations. WebTextCheckCompletions text_check_completions_; // The last text sent to the browser process for spellchecking, and its // spellcheck results and WebTextCheckCompletions identifier. base::string16 last_request_; blink::WebVector last_results_; int last_identifier_; // Weak pointer to shared (per renderer) spellcheck data. SpellCheck* spellcheck_; // Not owned. |embedder_provider_| should outlive SpellCheckProvider. service_manager::LocalInterfaceProvider* embedder_provider_; // Interface to the SpellCheckHost. mojo::Remote spell_check_host_; // Dictionary updated observer. std::unique_ptr dictionary_update_observer_; #if defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER) std::unordered_map hybrid_requests_info_; #endif // defined(OS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER) base::WeakPtrFactory weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(SpellCheckProvider); }; #endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_