summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorsidchat@google.com <sidchat@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-12 19:30:21 +0000
committersidchat@google.com <sidchat@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-12 19:30:21 +0000
commiteda2b5a29df212809fb3ee5a8e8c42017b635f1c (patch)
treee0b9116beca023c3400cee5e28baa7114dee9cd2 /chrome/browser
parent01804b55e214f78aec2618b811a5ffa7079104dd (diff)
downloadchromium_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.cc1
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc16
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h2
-rw-r--r--chrome/browser/spellcheck_unittest.cc33
-rw-r--r--chrome/browser/spellchecker.cc44
-rw-r--r--chrome/browser/spellchecker.h6
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.