Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2644)

Unified Diff: chrome/renderer/spellchecker/spellcheck.cc

Issue 9169082: Asynchronous spellchecking on Win and Linux (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Build fix Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/renderer/spellchecker/spellcheck.h ('k') | chrome/renderer/spellchecker/spellcheck_provider.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
« no previous file with comments | « chrome/renderer/spellchecker/spellcheck.h ('k') | chrome/renderer/spellchecker/spellcheck_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698