| Index: chrome/renderer/spellchecker/spellcheck.cc
|
| diff --git a/chrome/renderer/spellchecker/spellcheck.cc b/chrome/renderer/spellchecker/spellcheck.cc
|
| index e8ccc1a76eb5a10ef8fa37f6ea797685f78dc632..e16927abc41a62236bb39b3967c41a66bf8b6bab 100644
|
| --- a/chrome/renderer/spellchecker/spellcheck.cc
|
| +++ b/chrome/renderer/spellchecker/spellcheck.cc
|
| @@ -4,8 +4,10 @@
|
|
|
| #include "chrome/renderer/spellchecker/spellcheck.h"
|
|
|
| +#include "base/bind.h"
|
| #include "base/file_util.h"
|
| #include "base/metrics/histogram.h"
|
| +#include "base/message_loop_proxy.h"
|
| #include "base/time.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/common/render_messages.h"
|
| @@ -14,15 +16,84 @@
|
| #include "chrome/common/spellcheck_result.h"
|
| #include "content/public/renderer/render_thread.h"
|
| #include "third_party/hunspell/src/hunspell/hunspell.hxx"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingCompletion.h"
|
| +#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingResult.h"
|
|
|
| using base::TimeTicks;
|
| using content::RenderThread;
|
| +using WebKit::WebVector;
|
| +using WebKit::WebTextCheckingResult;
|
| +using WebKit::WebTextCheckingType;
|
| +
|
| +namespace spellcheck {
|
| +void ToWebResultList(
|
| + int offset,
|
| + const std::vector<SpellCheckResult>& results,
|
| + WebVector<WebTextCheckingResult>* web_results) {
|
| + WebVector<WebTextCheckingResult> list(results.size());
|
| + for (size_t i = 0; i < results.size(); ++i) {
|
| + list[i] = WebTextCheckingResult(
|
| + static_cast<WebTextCheckingType>(results[i].type),
|
| + results[i].location + offset,
|
| + results[i].length,
|
| + results[i].replacement);
|
| + }
|
| +
|
| + list.swap(*web_results);
|
| +}
|
| +
|
| +WebVector<WebTextCheckingResult> ToWebResultList(
|
| + int offset,
|
| + const std::vector<SpellCheckResult>& results) {
|
| + WebVector<WebTextCheckingResult> web_results;
|
| + ToWebResultList(offset, results, &web_results);
|
| + return web_results;
|
| +}
|
| +} // namespace spellcheck
|
| +
|
| +class SpellCheck::SpellCheckRequestParam
|
| + : public base::RefCountedThreadSafe<SpellCheck::SpellCheckRequestParam> {
|
| + public:
|
| + SpellCheckRequestParam(const string16& text,
|
| + int offset,
|
| + WebKit::WebTextCheckingCompletion* completion)
|
| + : text_(text),
|
| + offset_(offset),
|
| + completion_(completion) {
|
| + DCHECK(completion);
|
| + }
|
| +
|
| + string16 text() {
|
| + return text_;
|
| + }
|
| +
|
| + int offset() {
|
| + return offset_;
|
| + }
|
| +
|
| + WebKit::WebTextCheckingCompletion* completion() {
|
| + return completion_;
|
| + }
|
| +
|
| + private:
|
| + // Text to be checked in this task.
|
| + string16 text_;
|
| +
|
| + // The text offset from the beginning.
|
| + int offset_;
|
| +
|
| + // The interface to send the misspelled ranges to WebKit.
|
| + WebKit::WebTextCheckingCompletion* completion_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SpellCheckRequestParam);
|
| +};
|
|
|
| SpellCheck::SpellCheck()
|
| : file_(base::kInvalidPlatformFileValue),
|
| auto_spell_correct_turned_on_(false),
|
| is_using_platform_spelling_engine_(false),
|
| - initialized_(false) {
|
| + initialized_(false),
|
| + dictionary_requested_(false) {
|
| // Wait till we check the first word before doing any initializing.
|
| }
|
|
|
| @@ -49,6 +120,8 @@ void SpellCheck::OnInit(IPC::PlatformFileForTransit bdict_file,
|
| Init(IPC::PlatformFileForTransitToPlatformFile(bdict_file),
|
| custom_words, language);
|
| auto_spell_correct_turned_on_ = auto_spell_correct;
|
| +
|
| + PostDelayedSpellCheckTask();
|
| }
|
|
|
| void SpellCheck::OnWordAdded(const std::string& word) {
|
| @@ -147,7 +220,6 @@ bool SpellCheck::SpellCheckWord(
|
|
|
| bool SpellCheck::SpellCheckParagraph(
|
| const string16& text,
|
| - int tag,
|
| std::vector<SpellCheckResult>* results) {
|
| #if !defined(OS_MACOSX)
|
| // Mac has its own spell checker, so this method will not be used.
|
| @@ -238,6 +310,41 @@ string16 SpellCheck::GetAutoCorrectionWord(const string16& word, int tag) {
|
| return autocorrect_word;
|
| }
|
|
|
| +void SpellCheck::RequestTextChecking(
|
| + const string16& text,
|
| + int offset,
|
| + WebKit::WebTextCheckingCompletion* completion) {
|
| +#if !defined(OS_MACOSX)
|
| + // Commented out on Mac, because SpellCheckRequest::PerformSpellCheck is not
|
| + // implemented on Mac. Mac uses its own spellchecker, so this method
|
| + // will not be used.
|
| +
|
| + DCHECK(!is_using_platform_spelling_engine_);
|
| +
|
| + // Clean up the previous request before starting a new request.
|
| + if (pending_request_param_.get()) {
|
| + pending_request_param_->completion()->didFinishCheckingText(
|
| + WebKit::WebVector<WebKit::WebTextCheckingResult>());
|
| + pending_request_param_ = NULL;
|
| + }
|
| +
|
| + if (InitializeIfNeeded()) {
|
| + // We will check this text after we finish loading the hunspell dictionary.
|
| + // Save parameters so that we can use them when we receive an init message
|
| + // from the browser process.
|
| + pending_request_param_ = new SpellCheckRequestParam(
|
| + text, offset, completion);
|
| + return;
|
| + }
|
| +
|
| + requested_params_.push(new SpellCheckRequestParam(text, offset, completion));
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE,
|
| + base::Bind(&SpellCheck::PerformSpellCheck, AsWeakPtr()));
|
| +#else
|
| + NOTREACHED();
|
| +#endif
|
| +}
|
| +
|
| void SpellCheck::InitializeHunspell() {
|
| if (hunspell_.get())
|
| return;
|
| @@ -272,9 +379,11 @@ bool SpellCheck::InitializeIfNeeded() {
|
| if (is_using_platform_spelling_engine_)
|
| return false;
|
|
|
| - if (!initialized_) {
|
| - RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary);
|
| - initialized_ = true;
|
| + if (!initialized_ && !dictionary_requested_) {
|
| + // RenderThread will not exist in test.
|
| + if (RenderThread::Get())
|
| + RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary);
|
| + dictionary_requested_ = true;
|
| return true;
|
| }
|
|
|
| @@ -282,7 +391,7 @@ bool SpellCheck::InitializeIfNeeded() {
|
| if (file_ != base::kInvalidPlatformFileValue)
|
| InitializeHunspell();
|
|
|
| - return false;
|
| + return !initialized_;
|
| }
|
|
|
| // When called, relays the request to check the spelling to the proper
|
| @@ -314,6 +423,41 @@ bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) {
|
| return word_correct;
|
| }
|
|
|
| +void SpellCheck::PostDelayedSpellCheckTask() {
|
| + if (!pending_request_param_)
|
| + return;
|
| +
|
| + if (file_ == base::kInvalidPlatformFileValue) {
|
| + pending_request_param_->completion()->didFinishCheckingText(
|
| + WebKit::WebVector<WebKit::WebTextCheckingResult>());
|
| + } else {
|
| + requested_params_.push(pending_request_param_);
|
| + base::MessageLoopProxy::current()->PostTask(FROM_HERE,
|
| + base::Bind(&SpellCheck::PerformSpellCheck, AsWeakPtr()));
|
| + }
|
| +
|
| + pending_request_param_ = NULL;
|
| +}
|
| +
|
| +void SpellCheck::PerformSpellCheck() {
|
| +#if !defined(OS_MACOSX)
|
| + DCHECK(!requested_params_.empty());
|
| + scoped_refptr<SpellCheckRequestParam> param = requested_params_.front();
|
| + DCHECK(param);
|
| + requested_params_.pop();
|
| +
|
| + std::vector<SpellCheckResult> results;
|
| + SpellCheckParagraph(param->text(), &results);
|
| + param->completion()->didFinishCheckingText(
|
| + spellcheck::ToWebResultList(param->offset(), results));
|
| +#else
|
| + // SpellCheck::SpellCheckParagraph is not implemented on Mac,
|
| + // so we return without spellchecking. Note that Mac uses its own
|
| + // spellchecker, this function won't be used.
|
| + NOTREACHED();
|
| +#endif
|
| +}
|
| +
|
| void SpellCheck::FillSuggestionList(
|
| const string16& wrong_word,
|
| std::vector<string16>* optional_suggestions) {
|
|
|