Index: chrome/renderer/spellchecker/spellcheck.cc |
diff --git a/chrome/renderer/spellchecker/spellcheck.cc b/chrome/renderer/spellchecker/spellcheck.cc |
index a423dff25264a7bda8a2a7b1c511809673448efc..0647799af5166311ac5e9817b75f5dad8cd518c9 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.h" |
#include "base/time.h" |
#include "base/utf_string_conversions.h" |
#include "chrome/common/render_messages.h" |
@@ -13,16 +15,76 @@ |
#include "chrome/common/spellcheck_messages.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" |
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" |
using base::TimeTicks; |
using content::RenderThread; |
+// A request that checks the spellings of the specified text. |
+class SpellCheck::SpellCheckRequest |
+ : public base::RefCountedThreadSafe<SpellCheck::SpellCheckRequest> { |
Hironori Bono
2012/01/27 06:17:41
I do not think we need a new class for this use-ca
shinyak
2012/01/30 06:53:05
Actually |text| is a temporary object, so the refe
|
+ public: |
+ SpellCheckRequest(const string16& text, |
+ int tag, |
+ WebKit::WebTextCheckingCompletion* completion, |
+ SpellCheck* spellcheck) |
+ : text_(text), |
+ tag_(tag), |
+ completion_(completion), |
+ spellcheck_(spellcheck) { |
+ DCHECK(completion); |
+ DCHECK(spellcheck); |
+ } |
+ |
+ // Performs spellchecking and calls the callback function. |
+ void PerformSpellCheck() { |
+#if !defined(OS_MACOSX) |
+ std::vector<WebKit::WebTextCheckingResult> results; |
+ spellcheck_->SpellCheckParagraph(text_, tag_, &results); |
Hironori Bono
2012/01/27 06:17:41
This call surely creates confusing crashes when a
shinyak
2012/01/30 06:53:05
Done.
|
+ completion_->didFinishCheckingText(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. |
Hironori Bono
2012/01/27 06:17:41
Use NOTREACHED() and let a renderer crash when som
shinyak
2012/01/30 06:53:05
Done.
|
+ completion_->didFinishCheckingText( |
+ WebKit::WebVector<WebKit::WebTextCheckingResult>()); |
+#endif |
+ } |
+ |
+ // Calls the callback function without doing spellchecking. |
+ // Text is considered as having no misspellings. |
+ void CancelSpellCheckRequest() { |
+ completion_->didFinishCheckingText( |
+ WebKit::WebVector<WebKit::WebTextCheckingResult>()); |
+ } |
+ |
+ private: |
+ friend class base::RefCountedThreadSafe<SpellCheckRequest>; |
+ |
+ ~SpellCheckRequest() { |
+ } |
+ |
+ // Text to be checked in this task. |
+ string16 text_; |
+ |
+ // The document tag provided by WebKit. |
+ int tag_; |
+ |
+ // The interface to send the misspelled ranges to WebKit. |
+ WebKit::WebTextCheckingCompletion* completion_; |
+ |
+ // The spellchecker shared in this process. |
+ SpellCheck* spellcheck_; |
+}; |
+ |
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 +111,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) { |
@@ -238,6 +302,38 @@ string16 SpellCheck::GetAutoCorrectionWord(const string16& word, int tag) { |
return autocorrect_word; |
} |
+void SpellCheck::RequestTextChecking( |
+ const string16& text, |
+ int tag, |
+ 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_) { |
+ pending_request_->CancelSpellCheckRequest(); |
+ pending_request_ = 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_ = new SpellCheckRequest(text, tag, completion, this); |
+ return; |
+ } |
+ |
+ scoped_refptr<SpellCheckRequest> request( |
+ new SpellCheckRequest(text, tag, completion, this)); |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&SpellCheckRequest::PerformSpellCheck, request)); |
+#endif |
+} |
+ |
void SpellCheck::InitializeHunspell() { |
if (hunspell_.get()) |
return; |
@@ -272,9 +368,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 +380,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 +412,20 @@ bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) { |
return word_correct; |
} |
+void SpellCheck::PostDelayedSpellCheckTask() { |
+ if (!pending_request_) |
+ return; |
+ |
+ if (file_ == base::kInvalidPlatformFileValue) { |
+ pending_request_->CancelSpellCheckRequest(); |
+ } else { |
+ MessageLoop::current()->PostTask(FROM_HERE, |
Hironori Bono
2012/01/27 06:17:41
This is an old way to post a task. (This code cras
shinyak
2012/01/30 06:53:05
Done.
|
+ base::Bind(&SpellCheckRequest::PerformSpellCheck, pending_request_)); |
+ } |
+ |
+ pending_request_ = NULL; |
+} |
+ |
void SpellCheck::FillSuggestionList( |
const string16& wrong_word, |
std::vector<string16>* optional_suggestions) { |