diff --git a/atom/renderer/api/atom_api_spell_check_client.cc b/atom/renderer/api/atom_api_spell_check_client.cc index cc7716e75633..ba0b2c5fd65a 100644 --- a/atom/renderer/api/atom_api_spell_check_client.cc +++ b/atom/renderer/api/atom_api_spell_check_client.cc @@ -9,6 +9,7 @@ #include "atom/common/native_mate_converters/string16_converter.h" #include "base/logging.h" +#include "base/threading/thread_task_runner_handle.h" #include "chrome/renderer/spellchecker/spellcheck_worditerator.h" #include "native_mate/converter.h" #include "native_mate/dictionary.h" @@ -37,6 +38,27 @@ bool HasWordCharacters(const base::string16& text, int index) { } // namespace +class SpellCheckClient::SpellcheckRequest { + public: + SpellcheckRequest(const base::string16& text, + blink::WebTextCheckingCompletion* completion) + : text_(text), completion_(completion) { + DCHECK(completion); + } + ~SpellcheckRequest() {} + + base::string16 text() { return text_; } + blink::WebTextCheckingCompletion* completion() { return completion_; } + + private: + base::string16 text_; // Text to be checked in this task. + + // The interface to send the misspelled ranges to WebKit. + blink::WebTextCheckingCompletion* completion_; + + DISALLOW_COPY_AND_ASSIGN(SpellcheckRequest); +}; + SpellCheckClient::SpellCheckClient(const std::string& language, bool auto_spell_correct_turned_on, v8::Isolate* isolate, @@ -74,14 +96,23 @@ void SpellCheckClient::RequestCheckingOfText( const blink::WebString& textToCheck, blink::WebTextCheckingCompletion* completionCallback) { base::string16 text(textToCheck.Utf16()); + // Ignore invalid requests. if (text.empty() || !HasWordCharacters(text, 0)) { completionCallback->DidCancelCheckingText(); return; } - std::vector results; - SpellCheckText(text, false, &results); - completionCallback->DidFinishCheckingText(results); + // Clean up the previous request before starting a new request. + if (pending_request_param_.get()) { + pending_request_param_->completion()->DidCancelCheckingText(); + } + + pending_request_param_.reset(new SpellcheckRequest(text, completionCallback)); + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&SpellCheckClient::PerformSpellCheck, AsWeakPtr(), + base::Owned(pending_request_param_.release()))); } void SpellCheckClient::ShowSpellingUI(bool show) {} @@ -190,6 +221,14 @@ bool SpellCheckClient::IsValidContraction(const SpellCheckScope& scope, return true; } +void SpellCheckClient::PerformSpellCheck(SpellcheckRequest* param) { + DCHECK(param); + + std::vector results; + SpellCheckText(param->text(), false, &results); + param->completion()->DidFinishCheckingText(results); +} + SpellCheckClient::SpellCheckScope::SpellCheckScope( const SpellCheckClient& client) : handle_scope_(client.isolate_), diff --git a/atom/renderer/api/atom_api_spell_check_client.h b/atom/renderer/api/atom_api_spell_check_client.h index acdb2164437e..5216b455d0db 100644 --- a/atom/renderer/api/atom_api_spell_check_client.h +++ b/atom/renderer/api/atom_api_spell_check_client.h @@ -9,6 +9,7 @@ #include #include "base/callback.h" +#include "base/memory/weak_ptr.h" #include "chrome/renderer/spellchecker/spellcheck_worditerator.h" #include "native_mate/scoped_persistent.h" #include "third_party/WebKit/public/platform/WebSpellCheckPanelHostClient.h" @@ -18,14 +19,15 @@ namespace blink { struct WebTextCheckingResult; class WebTextCheckingCompletion; -} +} // namespace blink namespace atom { namespace api { class SpellCheckClient : public blink::WebSpellCheckPanelHostClient, - public blink::WebTextCheckClient { + public blink::WebTextCheckClient, + public base::SupportsWeakPtr { public: SpellCheckClient(const std::string& language, bool auto_spell_correct_turned_on, @@ -34,6 +36,7 @@ class SpellCheckClient : public blink::WebSpellCheckPanelHostClient, virtual ~SpellCheckClient(); private: + class SpellcheckRequest; // blink::WebTextCheckClient: void CheckSpelling( const blink::WebString& text, @@ -73,6 +76,9 @@ class SpellCheckClient : public blink::WebSpellCheckPanelHostClient, bool IsValidContraction(const SpellCheckScope& scope, const base::string16& word); + // Performs spell checking from the request queue. + void PerformSpellCheck(SpellcheckRequest* param); + // Represents character attributes used for filtering out characters which // are not supported by this SpellCheck object. SpellcheckCharAttribute character_attributes_; @@ -85,6 +91,11 @@ class SpellCheckClient : public blink::WebSpellCheckPanelHostClient, SpellcheckWordIterator text_iterator_; SpellcheckWordIterator contraction_iterator_; + // The parameters of a pending background-spellchecking request. + // (When WebKit sends two or more requests, we cancel the previous + // requests so we do not have to use vectors.) + std::unique_ptr pending_request_param_; + v8::Isolate* isolate_; v8::Persistent context_; mate::ScopedPersistent provider_;