summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h3
-rw-r--r--chrome/common/render_messages_internal.h4
-rw-r--r--chrome/renderer/render_view.cc9
-rw-r--r--chrome/renderer/render_view.h2
-rw-r--r--webkit/glue/editor_client_impl.cc12
-rw-r--r--webkit/glue/editor_client_impl.h2
-rw-r--r--webkit/glue/webview_delegate.h6
14 files changed, 143 insertions, 1 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.
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 3954f77..45e4e97 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -428,9 +428,11 @@ const wchar_t kWebWorkerShareProcesses[] = L"web-worker-share-processes";
// Enables the bookmark menu.
const wchar_t kBookmarkMenu[] = L"bookmark-menu";
+// Enables auto spell correction.
+const wchar_t kAutoSpellCorrect[] = L"auto-spell-correct";
+
// Enables StatsTable, logging statistics to a global named shared memory table.
const wchar_t kEnableStatsTable[] = L"enable-stats-table";
-
// Enables the Omnibox2 popup and functionality.
const wchar_t kEnableOmnibox2[] = L"enable-omnibox2";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index f5228121..ef3f796 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -162,8 +162,11 @@ extern const wchar_t kWebWorkerProcessPerCore[];
extern const wchar_t kWebWorkerShareProcesses[];
extern const wchar_t kBookmarkMenu[];
+
extern const wchar_t kEnableStatsTable[];
+extern const wchar_t kAutoSpellCorrect[];
+
extern const wchar_t kEnableOmnibox2[];
extern const wchar_t kDisableAudio[];
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 1966f9e..90882c1 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -815,6 +815,10 @@ IPC_BEGIN_MESSAGES(ViewHost)
int /* misspell location */,
int /* misspell length */)
+ IPC_SYNC_MESSAGE_ROUTED1_1(ViewHostMsg_GetAutoCorrectWord,
+ std::wstring /* word to check */,
+ std::wstring /* autocorrected word */)
+
// Initiate a download based on user actions like 'ALT+click'.
IPC_MESSAGE_ROUTED2(ViewHostMsg_DownloadUrl,
GURL /* url */,
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 99e662b..979f74f 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -2298,6 +2298,15 @@ void RenderView::SpellCheck(const std::wstring& word, int& misspell_location,
&misspell_length));
}
+void RenderView::GetAutoCorrectWord(const std::wstring& misspelled_word,
+ std::wstring& autocorrect_word) {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kAutoSpellCorrect)) {
+ Send(new ViewHostMsg_GetAutoCorrectWord(routing_id_, misspelled_word,
+ &autocorrect_word));
+ }
+}
+
void RenderView::SetInputMethodState(bool enabled) {
// Save the updated IME status and mark the input focus has been updated.
// The IME status is to be sent to a browser process next time when
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 7b5665d..a993327 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -309,6 +309,8 @@ class RenderView : public RenderWidget,
virtual bool WasOpenedByUserGesture() const;
virtual void SpellCheck(const std::wstring& word, int& misspell_location,
int& misspell_length);
+ virtual void GetAutoCorrectWord(const std::wstring& misspelled_word,
+ std::wstring& autocorrect_word);
virtual void SetInputMethodState(bool enabled);
virtual void ScriptedPrint(WebFrame* frame);
virtual void WebInspectorOpened(int num_resources);
diff --git a/webkit/glue/editor_client_impl.cc b/webkit/glue/editor_client_impl.cc
index c64a3cf..7216e4f 100644
--- a/webkit/glue/editor_client_impl.cc
+++ b/webkit/glue/editor_client_impl.cc
@@ -843,6 +843,18 @@ void EditorClientImpl::checkSpellingOfString(const UChar* str, int length,
*misspellingLength = spell_length;
}
+WebCore::String EditorClientImpl::getAutoCorrectSuggestionForMisspelledWord(
+ const WebCore::String& misspelledWord) {
+ WebViewDelegate* d = web_view_->delegate();
+ std::wstring autocorrect_word;
+ if (isContinuousSpellCheckingEnabled() && d) {
+ std::wstring word = webkit_glue::StringToStdWString(misspelledWord);
+ d->GetAutoCorrectWord(word, autocorrect_word);
+ }
+
+ return webkit_glue::StdWStringToString(autocorrect_word);
+}
+
void EditorClientImpl::checkGrammarOfString(const UChar*, int length,
WTF::Vector<WebCore::GrammarDetail>&,
int* badGrammarLocation,
diff --git a/webkit/glue/editor_client_impl.h b/webkit/glue/editor_client_impl.h
index 4104a4b..0778b48 100644
--- a/webkit/glue/editor_client_impl.h
+++ b/webkit/glue/editor_client_impl.h
@@ -92,6 +92,8 @@ class EditorClientImpl : public WebCore::EditorClient {
WTF::Vector<WebCore::GrammarDetail>&,
int* badGrammarLocation,
int* badGrammarLength);
+ virtual WebCore::String getAutoCorrectSuggestionForMisspelledWord(
+ const WebCore::String& misspelledWord);
virtual void updateSpellingUIWithGrammarString(const WebCore::String&,
const WebCore::GrammarDetail& detail);
virtual void updateSpellingUIWithMisspelledWord(const WebCore::String&);
diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h
index 193aef4..186940b 100644
--- a/webkit/glue/webview_delegate.h
+++ b/webkit/glue/webview_delegate.h
@@ -761,6 +761,12 @@ class WebViewDelegate : virtual public WebWidgetDelegate {
misspell_location = misspell_length = 0;
}
+ // Computes an auto correct word for a misspelled word. If no word is found,
+ // empty string is computed.
+ virtual void GetAutoCorrectWord(const std::wstring& misspelled_word,
+ std::wstring& autocorrect_word) {
+ }
+
// Changes the state of the input method editor.
virtual void SetInputMethodState(bool enabled) { }