1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
// Copyright 2012 The Chromium Authors
// 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 <memory>
#include <vector>
#include "base/containers/id_map.h"
#include "base/memory/raw_ptr.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 BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
#include <unordered_map>
#endif // BUILDFLAG(IS_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<std::unique_ptr<blink::WebTextCheckingCompletion>>;
#if BUILDFLAG(IS_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 // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
SpellCheckProvider(content::RenderFrame* render_frame,
SpellCheck* spellcheck);
SpellCheckProvider(const SpellCheckProvider&) = delete;
SpellCheckProvider& operator=(const SpellCheckProvider&) = delete;
~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 std::u16string& text,
std::unique_ptr<blink::WebTextCheckingCompletion> 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;
// Returns the SpellCheckHost.
spellcheck::mojom::SpellCheckHost& GetSpellCheckHost();
private:
friend class TestingSpellCheckProvider;
class DictionaryUpdateObserverImpl;
// Sets the SpellCheckHost (for unit tests).
void SetSpellCheckHostForTesting(
mojo::PendingRemote<spellcheck::mojom::SpellCheckHost> host) {
spell_check_host_.Bind(std::move(host));
}
// Reset dictionary_update_observer_ in TestingSpellCheckProvider dtor.
void ResetDictionaryUpdateObserverForTesting();
// 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 std::u16string& 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,
std::vector<blink::WebString>* optional_suggestions) override;
void RequestCheckingOfText(
const blink::WebString& text,
std::unique_ptr<blink::WebTextCheckingCompletion> completion) override;
#if BUILDFLAG(USE_RENDERER_SPELLCHECKER)
void OnRespondSpellingService(int identifier,
const std::u16string& text,
bool success,
const std::vector<SpellCheckResult>& results);
#endif
// Returns whether |text| has word characters, i.e. whether a spellchecker
// needs to check this text.
bool HasWordCharacters(const std::u16string& text, size_t index) const;
#if BUILDFLAG(USE_BROWSER_SPELLCHECKER)
void OnRespondTextCheck(int identifier,
const std::u16string& line,
const std::vector<SpellCheckResult>& results);
// Makes mojo calls to the browser process to perform platform spellchecking.
void RequestTextCheckingFromBrowser(const std::u16string& text);
#if BUILDFLAG(IS_WIN)
// Callback for when spellcheck service has been initialized on demand.
void OnRespondInitializeDictionaries(
const std::u16string& text,
std::vector<spellcheck::mojom::SpellCheckBDictLanguagePtr> dictionaries,
const std::vector<std::string>& 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 // BUILDFLAG(IS_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.
std::u16string last_request_;
std::vector<blink::WebTextCheckingResult> last_results_;
int last_identifier_;
// Weak pointer to shared (per renderer) spellcheck data.
raw_ptr<SpellCheck, DanglingUntriaged> spellcheck_;
// Not owned. |embedder_provider_| should outlive SpellCheckProvider.
raw_ptr<service_manager::LocalInterfaceProvider> embedder_provider_;
// Interface to the SpellCheckHost.
mojo::Remote<spellcheck::mojom::SpellCheckHost> spell_check_host_;
// Dictionary updated observer.
std::unique_ptr<DictionaryUpdateObserverImpl> dictionary_update_observer_;
#if BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
std::unordered_map<int, HybridSpellCheckRequestInfo> hybrid_requests_info_;
#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(USE_BROWSER_SPELLCHECKER)
base::WeakPtrFactory<SpellCheckProvider> weak_factory_{this};
};
#endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_
|