diff options
author | sidchat@google.com <sidchat@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-12 19:30:21 +0000 |
---|---|---|
committer | sidchat@google.com <sidchat@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-12 19:30:21 +0000 |
commit | eda2b5a29df212809fb3ee5a8e8c42017b635f1c (patch) | |
tree | e0b9116beca023c3400cee5e28baa7114dee9cd2 /chrome/browser | |
parent | 01804b55e214f78aec2618b811a5ffa7079104dd (diff) | |
download | chromium_src-eda2b5a29df212809fb3ee5a8e8c42017b635f1c.zip chromium_src-eda2b5a29df212809fb3ee5a8e8c42017b635f1c.tar.gz chromium_src-eda2b5a29df212809fb3ee5a8e8c42017b635f1c.tar.bz2 |
Add Automatic spell correction support in Chrome.
Issue=7624
Review URL: http://codereview.chromium.org/42608
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15888 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 1 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 16 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.h | 2 | ||||
-rw-r--r-- | chrome/browser/spellcheck_unittest.cc | 33 | ||||
-rw-r--r-- | chrome/browser/spellchecker.cc | 44 | ||||
-rw-r--r-- | chrome/browser/spellchecker.h | 6 |
6 files changed, 102 insertions, 0 deletions
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index f43e06ba..fce7128 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -264,6 +264,7 @@ bool BrowserRenderProcessHost::Init() { switches::kEnableStatsTable, switches::kEnableExtensions, switches::kEnableOutOfProcessDevTools, + switches::kAutoSpellCorrect, switches::kDisableAudio, switches::kSimpleDataSource, }; diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 0b86265..594163f 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -253,6 +253,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker, OnForwardToWorker) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SpellCheck, OnSpellCheck) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetAutoCorrectWord, + OnGetAutoCorrectWord) IPC_MESSAGE_HANDLER(ViewHostMsg_DnsPrefetch, OnDnsPrefetch) IPC_MESSAGE_HANDLER(ViewHostMsg_RendererHistograms, OnRendererHistograms) @@ -794,6 +796,20 @@ void ResourceMessageFilter::OnSpellCheck(const std::wstring& word, return; } + +void ResourceMessageFilter::OnGetAutoCorrectWord(const std::wstring& word, + IPC::Message* reply_msg) { + std::wstring autocorrect_word; + if (spellchecker_ != NULL) { + spellchecker_->GetAutoCorrectionWord(word, &autocorrect_word); + } + + ViewHostMsg_GetAutoCorrectWord::WriteReplyParams(reply_msg, + autocorrect_word); + Send(reply_msg); + return; +} + void ResourceMessageFilter::Observe(NotificationType type, const NotificationSource &source, const NotificationDetails &details) { diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index c28618b..8a406f0 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -146,6 +146,8 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, const GURL& referrer); void OnSpellCheck(const std::wstring& word, IPC::Message* reply_msg); + void OnGetAutoCorrectWord(const std::wstring& word, + IPC::Message* reply_msg); void OnDnsPrefetch(const std::vector<std::string>& hostnames); void OnRendererHistograms(const std::vector<std::string>& histogram_info); void OnReceiveContextMenuMsg(const IPC::Message& msg); diff --git a/chrome/browser/spellcheck_unittest.cc b/chrome/browser/spellcheck_unittest.cc index 8a9731f..aa76bf0 100644 --- a/chrome/browser/spellcheck_unittest.cc +++ b/chrome/browser/spellcheck_unittest.cc @@ -495,3 +495,36 @@ TEST_F(SpellCheckTest, DISABLED_SpellCheckSuggestionsAddToDictionary_EN_US) { // Remove the temp custom dictionary file. file_util::Delete(custom_dictionary_file, false); } + +TEST_F(SpellCheckTest, GetAutoCorrectionWord_EN_US) { + static const struct { + // A misspelled word. + const wchar_t* input; + + // An expected result for this test case. + // Should be an empty string if there are no suggestions for auto correct. + const wchar_t* expected_result; + } kTestCases[] = { + {L"teh", L"the"}, + {L"moer", L"more"}, + {L"watre", L"water"}, + {L"noen", L""}, + {L"what", L""}, + }; + + FilePath hunspell_directory = GetHunspellDirectory(); + ASSERT_FALSE(hunspell_directory.empty()); + + scoped_refptr<SpellChecker> spell_checker(new SpellChecker( + hunspell_directory, "en-US", NULL, FilePath())); + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + std::wstring misspelled_word(kTestCases[i].input); + std::wstring expected_autocorrect_word(kTestCases[i].expected_result); + std::wstring autocorrect_word; + spell_checker->GetAutoCorrectionWord(misspelled_word, &autocorrect_word); + + // Check for spelling. + EXPECT_EQ(expected_autocorrect_word, autocorrect_word); + } +} diff --git a/chrome/browser/spellchecker.cc b/chrome/browser/spellchecker.cc index 1a28cf1..75ef204 100644 --- a/chrome/browser/spellchecker.cc +++ b/chrome/browser/spellchecker.cc @@ -30,6 +30,7 @@ using base::TimeTicks; static const int kMaxSuggestions = 5; // Max number of dictionary suggestions. +static const int kMaxAutoCorrectWordSize = 8; namespace { @@ -475,6 +476,49 @@ bool SpellChecker::Initialize() { return false; } +void SpellChecker::GetAutoCorrectionWord(const std::wstring& word, + std::wstring* autocorrect_word) { + autocorrect_word->clear(); + int word_length = static_cast<int>(word.size()); + if (word_length < 2 || word_length > kMaxAutoCorrectWordSize) + return; + + wchar_t misspelled_word[kMaxAutoCorrectWordSize + 1]; + const wchar_t* word_char = word.c_str(); + for (int i = 0; i <= kMaxAutoCorrectWordSize; i++) { + if (i >= word_length) + misspelled_word[i] = NULL; + else + misspelled_word[i] = word_char[i]; + } + + // Swap adjacent characters and spellcheck. + int misspelling_start, misspelling_len; + for (int i = 0; i < word_length - 1; i++) { + // Swap. + std::swap(misspelled_word[i], misspelled_word[i + 1]); + + // Check spelling. + misspelling_start = misspelling_len = 0; + SpellCheckWord(misspelled_word, word_length, &misspelling_start, + &misspelling_len, NULL); + + // Make decision: if only one swap produced a valid word, then we want to + // return it. If we found two or more, we don't do autocorrection. + if (misspelling_len == 0) { + if (autocorrect_word->empty()) { + autocorrect_word->assign(misspelled_word); + } else { + autocorrect_word->clear(); + return; + } + } + + // Restore the swapped characters. + std::swap(misspelled_word[i], misspelled_word[i + 1]); + } +} + void SpellChecker::AddCustomWordsToHunspell() { // Add custom words to Hunspell. // This should be done in File Loop, but since Hunspell is in this IO Loop, diff --git a/chrome/browser/spellchecker.h b/chrome/browser/spellchecker.h index 2827991..0c0b535 100644 --- a/chrome/browser/spellchecker.h +++ b/chrome/browser/spellchecker.h @@ -75,6 +75,12 @@ class SpellChecker : public base::RefCountedThreadSafe<SpellChecker> { int* misspelling_len, std::vector<std::wstring>* optional_suggestions); + // Find a possible correctly spelled word for a misspelled word. Computes an + // empty string if input misspelled word is too long, there is ambiguity, or + // the correct spelling cannot be determined. + void GetAutoCorrectionWord(const std::wstring& word, + std::wstring* autocorrect_word); + // Add custom word to the dictionary, which means: // a) Add it to the current hunspell object for immediate use, // b) Add the word to a file in disk for custom dictionary. |