diff options
author | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-03 05:23:19 +0000 |
---|---|---|
committer | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-03 05:23:19 +0000 |
commit | 14fa2eb42feec5805b6df55d4eb2c1c5897649c5 (patch) | |
tree | 872aceaab9599ade9522882200ef345e05e298bd | |
parent | 7a5f33d653f43e6effd8247b2a3a623ec80c95b0 (diff) | |
download | chromium_src-14fa2eb42feec5805b6df55d4eb2c1c5897649c5.zip chromium_src-14fa2eb42feec5805b6df55d4eb2c1c5897649c5.tar.gz chromium_src-14fa2eb42feec5805b6df55d4eb2c1c5897649c5.tar.bz2 |
Make our IME backend platform-independent.
This change makes our IME backend run not only on Windows but also on Linux and Mac. This change also adds another unit-test which verifies the backend runs on Linux and Mac without problems.
Review URL: http://codereview.chromium.org/27124
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10783 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_win.cc | 6 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 8 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 1 | ||||
-rw-r--r-- | chrome/renderer/render_view_unittest.cc | 128 | ||||
-rw-r--r-- | webkit/glue/webview_impl.cc | 6 |
5 files changed, 138 insertions, 11 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index e0ed23e..1139000 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -699,7 +699,7 @@ LRESULT RenderWidgetHostViewWin::OnImeComposition( ImeComposition composition; if (ime_input_.GetResult(m_hWnd, lparam, &composition)) { Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(), - composition.string_type, + 1, composition.cursor_position, composition.target_start, composition.target_end, @@ -714,7 +714,7 @@ LRESULT RenderWidgetHostViewWin::OnImeComposition( // composition and send it to a renderer process. if (ime_input_.GetComposition(m_hWnd, lparam, &composition)) { Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(), - composition.string_type, + 0, composition.cursor_position, composition.target_start, composition.target_end, @@ -735,7 +735,7 @@ LRESULT RenderWidgetHostViewWin::OnImeEndComposition( // of the renderer process. std::wstring empty_string; Send(new ViewMsg_ImeSetComposition(render_widget_host_->routing_id(), - 0, -1, -1, -1, empty_string)); + -1, -1, -1, -1, empty_string)); ime_input_.ResetComposition(m_hWnd); } ime_input_.DestroyImeWindow(m_hWnd); diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 902ac0b..41b18a6 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -331,12 +331,12 @@ IPC_BEGIN_MESSAGES(View) // This message sends a string being composed with IME. // Parameters // * string_type (int) - // Represents the type of the string in the 'ime_string' parameter. + // Represents the type of the 'ime_string' parameter. // Its possible values and description are listed below: // Value Description - // 0 The parameter is not used. - // GCS_RESULTSTR The parameter represents a result string. - // GCS_COMPSTR The parameter represents a composition string. + // -1 The parameter is not used. + // 1 The parameter represents a result string. + // 0 The parameter represents a composition string. // * cursor_position (int) // Represents the position of the cursor // * target_start (int) diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index bbccfec..3ce6c3c 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -371,6 +371,7 @@ class RenderView : public RenderWidget, FRIEND_TEST(RenderViewTest, OnLoadAlternateHTMLText); FRIEND_TEST(RenderViewTest, OnNavStateChanged); FRIEND_TEST(RenderViewTest, OnImeStateChanged); + FRIEND_TEST(RenderViewTest, ImeComposition); explicit RenderView(RenderThreadBase* render_thread); diff --git a/chrome/renderer/render_view_unittest.cc b/chrome/renderer/render_view_unittest.cc index 31a5348..283bd2d 100644 --- a/chrome/renderer/render_view_unittest.cc +++ b/chrome/renderer/render_view_unittest.cc @@ -191,3 +191,131 @@ TEST_F(RenderViewTest, OnImeStateChanged) { } } +// Test that our IME backend can compose CJK words. +// Our IME front-end sends many platform-independent messages to the IME backend +// while it composes CJK words. This test sends the minimal messages captured +// on my local environment directly to the IME backend to verify if the backend +// can compose CJK words without any problems. +// This test uses an array of command sets because an IME composotion does not +// only depends on IME events, but also depends on window events, e.g. moving +// the window focus while composing a CJK text. To handle such complicated +// cases, this test should not only call IME-related functions in the +// RenderWidget class, but also call some RenderWidget members, e.g. +// ExecuteJavaScript(), RenderWidget::OnSetFocus(), etc. +TEST_F(RenderViewTest, ImeComposition) { + enum ImeCommand { + IME_INITIALIZE, + IME_SETINPUTMODE, + IME_SETFOCUS, + IME_SETCOMPOSITION, + }; + struct ImeMessage { + ImeCommand command; + bool enable; + int string_type; + int cursor_position; + int target_start; + int target_end; + const wchar_t* ime_string; + const wchar_t* result; + }; + static const ImeMessage kImeMessages[] = { + // Scenario 1: input a Chinese word with Microsoft IME (on Vista). + {IME_INITIALIZE, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETINPUTMODE, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETFOCUS, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETCOMPOSITION, false, 0, 1, -1, -1, L"n", L"n"}, + {IME_SETCOMPOSITION, false, 0, 2, -1, -1, L"ni", L"ni"}, + {IME_SETCOMPOSITION, false, 0, 3, -1, -1, L"nih", L"nih"}, + {IME_SETCOMPOSITION, false, 0, 4, -1, -1, L"niha", L"niha"}, + {IME_SETCOMPOSITION, false, 0, 5, -1, -1, L"nihao", L"nihao"}, + {IME_SETCOMPOSITION, false, 0, 2, -1, -1, L"\x4F60\x597D", L"\x4F60\x597D"}, + {IME_SETCOMPOSITION, false, 1, -1, -1, -1, L"\x4F60\x597D", + L"\x4F60\x597D"}, + {IME_SETCOMPOSITION, false, -1, -1, -1, -1, L"", L"\x4F60\x597D"}, + // Scenario 2: input a Japanese word with Microsoft IME (on Vista). + {IME_INITIALIZE, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETINPUTMODE, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETFOCUS, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETCOMPOSITION, false, 0, 1, 0, 1, L"\xFF4B", L"\xFF4B"}, + {IME_SETCOMPOSITION, false, 0, 1, 0, 1, L"\x304B", L"\x304B"}, + {IME_SETCOMPOSITION, false, 0, 2, 0, 2, L"\x304B\xFF4E", L"\x304B\xFF4E"}, + {IME_SETCOMPOSITION, false, 0, 3, 0, 3, L"\x304B\x3093\xFF4A", + L"\x304B\x3093\xFF4A"}, + {IME_SETCOMPOSITION, false, 0, 3, 0, 3, L"\x304B\x3093\x3058", + L"\x304B\x3093\x3058"}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 2, L"\x611F\x3058", L"\x611F\x3058"}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 2, L"\x6F22\x5B57", L"\x6F22\x5B57"}, + {IME_SETCOMPOSITION, false, 1, -1, -1, -1, L"\x6F22\x5B57", + L"\x6F22\x5B57"}, + {IME_SETCOMPOSITION, false, -1, -1, -1, -1, L"", L"\x6F22\x5B57"}, + // Scenario 3: input a Korean word with Microsot IME (on Vista). + {IME_INITIALIZE, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETINPUTMODE, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETFOCUS, true, 0, 0, 0, 0, NULL, NULL}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 1, L"\x3147", L"\x3147"}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 1, L"\xC544", L"\xC544"}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 1, L"\xC548", L"\xC548"}, + {IME_SETCOMPOSITION, false, 1, -1, -1, -1, L"\xC548", L"\xC548"}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 1, L"\x3134", L"\xC548\x3134"}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 1, L"\xB140", L"\xC548\xB140"}, + {IME_SETCOMPOSITION, false, 0, 0, 0, 1, L"\xB155", L"\xC548\xB155"}, + {IME_SETCOMPOSITION, false, -1, -1, -1, -1, L"", L"\xC548"}, + {IME_SETCOMPOSITION, false, 1, -1, -1, -1, L"\xB155", L"\xC548\xB155"}, + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kImeMessages); i++) { + const ImeMessage* ime_message = &kImeMessages[i]; + switch (ime_message->command) { + case IME_INITIALIZE: + // Load an HTML page consisting of a content-editable <div> element, + // and move the input focus to the <div> element, where we can use + // IMEs. + view_->OnImeSetInputMode(ime_message->enable); + view_->set_delay_seconds_for_form_state_sync(0); + LoadHTML("<html>" + "<head>" + "</head>" + "<body>" + "<div id=\"test1\" contenteditable=\"true\"></div>" + "</body>" + "</html>"); + ExecuteJavaScript("document.getElementById('test1').focus();"); + break; + + case IME_SETINPUTMODE: + // Activate (or deactivate) our IME back-end. + view_->OnImeSetInputMode(ime_message->enable); + break; + + case IME_SETFOCUS: + // Update the window focus. + view_->OnSetFocus(ime_message->enable); + break; + + case IME_SETCOMPOSITION: + view_->OnImeSetComposition(ime_message->string_type, + ime_message->cursor_position, + ime_message->target_start, + ime_message->target_end, + ime_message->ime_string); + break; + } + + // Update the status of our IME back-end. + // TODO(hbono): we should verify messages to be sent from the back-end. + view_->UpdateIME(); + ProcessPendingMessages(); + render_thread_.sink().ClearMessages(); + + if (ime_message->result) { + // Retrieve the content of this page and compare it with the expected + // result. + const int kMaxOutputCharacters = 128; + std::wstring output; + GetMainFrame()->GetContentAsPlainText(kMaxOutputCharacters, &output); + EXPECT_EQ(output, ime_message->result); + } + } +} + diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index dca001d..2fac917 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -1125,7 +1125,7 @@ bool WebViewImpl::ImeSetComposition(int string_type, return false; } - if (string_type == 0) { + if (string_type == -1) { // A browser process sent an IPC message which does not contain a valid // string, which means an ongoing composition has been canceled. // If the ongoing composition has been canceled, replace the ongoing @@ -1165,14 +1165,12 @@ bool WebViewImpl::ImeSetComposition(int string_type, // there are not any characters in the above region. editor->setComposition(composition_string, underlines, cursor_position, cursor_position); -#if defined(OS_WIN) // The given string is a result string, which means the ongoing // composition has been completed. I have to call the // Editor::confirmCompletion() and complete this composition. - if (string_type == GCS_RESULTSTR) { + if (string_type == 1) { editor->confirmComposition(); } -#endif } return editor->hasComposition(); |