| Index: chrome/browser/spellchecker/spellcheck_host_impl.cc
|
| diff --git a/chrome/browser/spellchecker/spellcheck_host_impl.cc b/chrome/browser/spellchecker/spellcheck_host_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..680919cfbdd5c63a877815add283202360f4a3d6
|
| --- /dev/null
|
| +++ b/chrome/browser/spellchecker/spellcheck_host_impl.cc
|
| @@ -0,0 +1,130 @@
|
| +// Copyright 2017 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.
|
| +
|
| +#include "chrome/browser/spellchecker/spellcheck_host_impl.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
|
| +#include "chrome/browser/spellchecker/spellcheck_factory.h"
|
| +#include "chrome/browser/spellchecker/spellcheck_service.h"
|
| +#include "components/spellcheck/browser/spellcheck_host_metrics.h"
|
| +#include "components/spellcheck/browser/spelling_service_client.h"
|
| +#include "components/spellcheck/common/spellcheck_result.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| +#include "mojo/public/cpp/bindings/strong_binding.h"
|
| +#include "services/service_manager/public/cpp/bind_source_info.h"
|
| +
|
| +SpellCheckHostImpl::SpellCheckHostImpl(int render_process_id)
|
| + : render_process_id_(render_process_id),
|
| + client_(new SpellingServiceClient) {}
|
| +
|
| +SpellCheckHostImpl::~SpellCheckHostImpl() = default;
|
| +
|
| +// static
|
| +void SpellCheckHostImpl::Create(
|
| + int render_process_id,
|
| + const service_manager::BindSourceInfo& source_info,
|
| + spellcheck::mojom::SpellCheckHostRequest request) {
|
| + mojo::MakeStrongBinding(
|
| + base::MakeUnique<SpellCheckHostImpl>(render_process_id),
|
| + std::move(request));
|
| +}
|
| +
|
| +void SpellCheckHostImpl::RequestDictionary() {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + // The renderer has requested that we initialize its spellchecker. This
|
| + // generally should only be called once per session, as after the first
|
| + // call, future renderers will be passed the initialization information
|
| + // on startup (or when the dictionary changes in some way).
|
| + SpellcheckService* spellcheck = GetSpellcheckService();
|
| + if (!spellcheck)
|
| + return; // Teardown.
|
| +
|
| + // The spellchecker initialization already started and finished; just
|
| + // send it to the renderer.
|
| + spellcheck->InitForRenderer(
|
| + content::RenderProcessHost::FromID(render_process_id_));
|
| +
|
| + // TODO(rlp): Ensure that we do not initialize the hunspell dictionary
|
| + // more than once if we get requests from different renderers.
|
| +}
|
| +
|
| +void SpellCheckHostImpl::NotifyChecked(const base::string16& word,
|
| + bool misspelled) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + SpellcheckService* spellcheck = GetSpellcheckService();
|
| + if (!spellcheck)
|
| + return; // Teardown.
|
| + if (spellcheck->GetMetrics())
|
| + spellcheck->GetMetrics()->RecordCheckedWordStats(word, misspelled);
|
| +}
|
| +
|
| +void SpellCheckHostImpl::CallSpellingService(
|
| + const base::string16& text,
|
| + const CallSpellingServiceCallback& callback) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| + DCHECK(!text.empty());
|
| +
|
| +#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
|
| + content::RenderProcessHost* host =
|
| + content::RenderProcessHost::FromID(render_process_id_);
|
| +
|
| + // Checks the user profile and sends a JSON-RPC request to the Spelling
|
| + // service if a user enables the "Ask Google for suggestions" option. When
|
| + // a response is received (including an error) from the remote Spelling
|
| + // service, calls CallSpellingServiceDone.
|
| + client_->RequestTextCheck(
|
| + host ? host->GetBrowserContext() : nullptr,
|
| + SpellingServiceClient::SPELLCHECK, text,
|
| + base::Bind(&SpellCheckHostImpl::CallSpellingServiceDone,
|
| + base::Unretained(this), callback));
|
| +#else
|
| + callback.Run(false, std::vector<SpellCheckResult>());
|
| +#endif
|
| +}
|
| +
|
| +#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
|
| +void SpellCheckHostImpl::CallSpellingServiceDone(
|
| + const CallSpellingServiceCallback& callback,
|
| + bool success,
|
| + const base::string16& text,
|
| + const std::vector<SpellCheckResult>& service_results) {
|
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| +
|
| + SpellcheckService* spellcheck = GetSpellcheckService();
|
| + if (!spellcheck) { // Teardown.
|
| + callback.Run(false, std::vector<SpellCheckResult>());
|
| + return;
|
| + }
|
| +
|
| + std::vector<SpellCheckResult> filter_results = FilterCustomWordResults(
|
| + base::UTF16ToUTF8(text), *spellcheck->GetCustomDictionary(),
|
| + service_results);
|
| + callback.Run(success, filter_results);
|
| +}
|
| +
|
| +// static
|
| +std::vector<SpellCheckResult> SpellCheckHostImpl::FilterCustomWordResults(
|
| + const std::string& text,
|
| + const SpellcheckCustomDictionary& custom_dictionary,
|
| + const std::vector<SpellCheckResult>& service_results) {
|
| + std::vector<SpellCheckResult> results;
|
| + for (const auto& result : service_results) {
|
| + const std::string word = text.substr(result.location, result.length);
|
| + if (!custom_dictionary.HasWord(word))
|
| + results.push_back(result);
|
| + }
|
| +
|
| + return results;
|
| +}
|
| +#endif // !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
|
| +
|
| +SpellcheckService* SpellCheckHostImpl::GetSpellcheckService() const {
|
| + return SpellcheckServiceFactory::GetForRenderProcessId(render_process_id_);
|
| +}
|
|
|