diff options
author | jnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-01 01:53:19 +0000 |
---|---|---|
committer | jnd@chromium.org <jnd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-01 01:53:19 +0000 |
commit | 2f2afba1c5f04e5f83d7c62873bef8a0d166f291 (patch) | |
tree | b40f104b3b8d90268d27a53751ff29c7d68c413e | |
parent | 565a83eb237b0f746f1924901352ae4c8e75f1a4 (diff) | |
download | chromium_src-2f2afba1c5f04e5f83d7c62873bef8a0d166f291.zip chromium_src-2f2afba1c5f04e5f83d7c62873bef8a0d166f291.tar.gz chromium_src-2f2afba1c5f04e5f83d7c62873bef8a0d166f291.tar.bz2 |
Add encoding override support for Chrome frame. With this change, users can override current page encoding in Chrome Frame via clicking IE's encoding menu.
Unfortunately this change does not work on IE8 since the encoding menu is off on IE8.
This change was from http://codereview.chromium.org/460036/show, which was on a temporary machine which I can not access from China now. I will re-create the patch, make some modifications according to previous reviewers' comments. now I send to you for review.
BUG=24040
TEST=none
Review URL: http://codereview.chromium.org/1530012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43306 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/automation/automation_provider.cc | 19 | ||||
-rw-r--r-- | chrome/browser/automation/chrome_frame_automation_provider.cc | 3 | ||||
-rw-r--r-- | chrome_frame/chrome_active_document.cc | 58 | ||||
-rw-r--r-- | chrome_frame/chrome_active_document.h | 88 |
4 files changed, 164 insertions, 4 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 57a9506..c6ee650 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -2220,16 +2220,31 @@ void AutomationProvider::OverrideEncoding(int tab_handle, #if defined(OS_WIN) if (tab_tracker_->ContainsHandle(tab_handle)) { NavigationController* nav = tab_tracker_->GetResource(tab_handle); + if (!nav) + return; Browser* browser = FindAndActivateTab(nav); - DCHECK(browser); - if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) { + // If the browser has UI, simulate what a user would do. + // Activate the tab and then click the encoding menu. + if (browser && + browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU)) { int selected_encoding_id = CharacterEncoding::GetCommandIdByCanonicalEncodingName(encoding_name); if (selected_encoding_id) { browser->OverrideEncoding(selected_encoding_id); *success = true; } + } else { + // There is no UI, Chrome probably runs as Chrome-Frame mode. + // Try to get TabContents and call its override_encoding method. + TabContents* contents = nav->tab_contents(); + if (!contents) + return; + const std::string selected_encoding = + CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding_name); + if (selected_encoding.empty()) + return; + contents->SetOverrideEncoding(selected_encoding); } } #else diff --git a/chrome/browser/automation/chrome_frame_automation_provider.cc b/chrome/browser/automation/chrome_frame_automation_provider.cc index 9aa403d..112f2fc 100644 --- a/chrome/browser/automation/chrome_frame_automation_provider.cc +++ b/chrome/browser/automation/chrome_frame_automation_provider.cc @@ -63,7 +63,8 @@ bool ChromeFrameAutomationProvider::IsValidMessage(uint32 type) { case AutomationMsg_RequestData::ID: case AutomationMsg_RequestEnd::ID: case AutomationMsg_SaveAsAsync::ID: - case AutomationMsg_RemoveBrowsingData::ID: { + case AutomationMsg_RemoveBrowsingData::ID: + case AutomationMsg_OverrideEncoding::ID: { is_valid_message = true; break; } diff --git a/chrome_frame/chrome_active_document.cc b/chrome_frame/chrome_active_document.cc index 4f92e70..80ccd23 100644 --- a/chrome_frame/chrome_active_document.cc +++ b/chrome_frame/chrome_active_document.cc @@ -50,6 +50,13 @@ base::ThreadLocalPointer<ChromeActiveDocument> g_active_doc_cache; bool g_first_launch_by_process_ = true; +const DWORD kIEEncodingIdArray[] = { +#define DEFINE_ENCODING_ID_ARRAY(encoding_name, id, chrome_name) encoding_name, + INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID_ARRAY) +#undef DEFINE_ENCODING_ID_ARRAY + 0 // The Last data must be 0 to indicate the end of the encoding id array. +}; + ChromeActiveDocument::ChromeActiveDocument() : first_navigation_(true), is_automation_client_reused_(false), @@ -1083,6 +1090,57 @@ HRESULT ChromeActiveDocument::SetPageFontSize(const GUID* cmd_group_guid, return S_OK; } +HRESULT ChromeActiveDocument::OnEncodingChange(const GUID* cmd_group_guid, + DWORD command_id, + DWORD cmd_exec_opt, + VARIANT* in_args, + VARIANT* out_args) { + const struct EncodingMapData { + DWORD ie_encoding_id; + const char* chrome_encoding_name; + } kEncodingTestDatas[] = { +#define DEFINE_ENCODING_MAP(encoding_name, id, chrome_name) \ + { encoding_name, chrome_name }, + INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_MAP) +#undef DEFINE_ENCODING_MAP + }; + + if (!automation_client_.get()) { + NOTREACHED() << "Invalid automtion client"; + return E_FAIL; + } + + // Using ARRAYSIZE_UNSAFE in here is because we define the struct + // EncodingMapData inside function. + const char* chrome_encoding_name = NULL; + for (int i = 0; i < ARRAYSIZE_UNSAFE(kEncodingTestDatas); ++i) { + const struct EncodingMapData* encoding_data = &kEncodingTestDatas[i]; + if (command_id == encoding_data->ie_encoding_id) { + chrome_encoding_name = encoding_data->chrome_encoding_name; + break; + } + } + // Return E_FAIL when encountering invalid encoding id. + if (!chrome_encoding_name) + return E_FAIL; + + TabProxy* tab = GetTabProxy(); + if (!tab) { + NOTREACHED() << "Can not get TabProxy"; + return E_FAIL; + } + + if (chrome_encoding_name) + tab->OverrideEncoding(chrome_encoding_name); + + // Like we did on SetPageFontSize, we may forward the command back to IEFrame + // to update the menu state to indicate that which encoding was set. + // TODO(iyengar) + // Do some investigation into why this Exec call fails. + IEExec(&CGID_ExplorerBarDoc, command_id, cmd_exec_opt, NULL, NULL); + return S_OK; +} + void ChromeActiveDocument::OnGoToHistoryEntryOffset(int tab_handle, int offset) { DLOG(INFO) << __FUNCTION__ << " - offset:" << offset; diff --git a/chrome_frame/chrome_active_document.h b/chrome_frame/chrome_active_document.h index 07d7c20..7a7d560 100644 --- a/chrome_frame/chrome_active_document.h +++ b/chrome_frame/chrome_active_document.h @@ -49,6 +49,64 @@ class ChromeActiveDocument; // current travel log entry #define INTERNAL_CMDID_REPLACE_CURRENT_TRAVEL_LOG_ENTRY_URL (40) +// The following macro is to define the mapping of IE encoding menu item to +// corresponding available encoding name in Chrome. For each encoding +// definition, there are three fields. +// The first one is the definition name of encoding menu item in IE. +// The second one is execution id of the encoding menu item in IE, starting +// from 3609(IDM_MIMECSET__FIRST__) to 3699(IDM_MIMECSET__LAST__) end. For +// the details, please refer to mshtmcid.h. +// The last one is the available encoding name of the IE encoding menu item +// in Chrome. If the encoding menu item does not have corresponding encoding +// in Chrome, it will be "unknown". +// So far we don't support the encoding auto detect since we can not control +// the status of encoding menu, such as toggle status of encoding auto detect +// item on the encoding menu. +#define INTERNAL_IE_ENCODINGMENU_IDS(V) \ + V(INTERNAL_IE_ENCODINGMENU_ARABIC_ASMO708, 3609, "unknown") \ + V(INTERNAL_IE_ENCODINGMENU_ARABIC_DOS, 3610, "unknown") \ + V(INTERNAL_IE_ENCODINGMENU_ARABIC_ISO, 3611, "ISO-8859-6") \ + V(INTERNAL_IE_ENCODINGMENU_ARABIC_WINDOWS, 3612, "windows-1256") \ + V(INTERNAL_IE_ENCODINGMENU_BALTIC_ISO, 3614, "ISO-8859-4") \ + V(INTERNAL_IE_ENCODINGMENU_BALTIC_WINDOWS, 3615, "windows-1257") \ + V(INTERNAL_IE_ENCODINGMENU_CENTRAL_EUROPEAN_DOS, 3616, "unknown") \ + V(INTERNAL_IE_ENCODINGMENU_CENTRAL_EUROPEAN_ISO, 3617, "ISO-8859-2") \ + V(INTERNAL_IE_ENCODINGMENU_CENTRAL_EUROPEAN_WINDOWS, 3618, "windows-1250") \ + V(INTERNAL_IE_ENCODINGMENU_CHINESE_SIMP_GB18030, 3619, "gb18030") \ + V(INTERNAL_IE_ENCODINGMENU_CHINESE_SIMP_GB2312, 3620, "GBK") \ + V(INTERNAL_IE_ENCODINGMENU_CHINESE_SIMP_HZ, 3621, "unknown") \ + V(INTERNAL_IE_ENCODINGMENU_CHINESE_TRAD_BIG5, 3622, "Big5") \ + V(INTERNAL_IE_ENCODINGMENU_CYRILLIC_DOS, 3623, "unknown") \ + V(INTERNAL_IE_ENCODINGMENU_CYRILLIC_ISO, 3624, "ISO-8859-5") \ + V(INTERNAL_IE_ENCODINGMENU_CYRILLIC_KOI8R, 3625, "KOI8-R") \ + V(INTERNAL_IE_ENCODINGMENU_CYRILLIC_KOI8U, 3626, "KOI8-U") \ + V(INTERNAL_IE_ENCODINGMENU_CYRILLIC_WINDOWS, 3627, "windows-1251") \ + V(INTERNAL_IE_ENCODINGMENU_GREEK_ISO, 3628, "ISO-8859-7") \ + V(INTERNAL_IE_ENCODINGMENU_GREEK_WINDOWS, 3629, "windows-1253") \ + V(INTERNAL_IE_ENCODINGMENU_HEBREW_DOS, 3630, "unknown") \ + V(INTERNAL_IE_ENCODINGMENU_HEBREW_ISO_LOGICAL, 3631, "ISO-8859-8-I") \ + V(INTERNAL_IE_ENCODINGMENU_HEBREW_ISO_VISUAL, 3632, "ISO-8859-8") \ + V(INTERNAL_IE_ENCODINGMENU_HEBREW_WINDOWS, 3633, "windows-1255") \ + V(INTERNAL_IE_ENCODINGMENU_JAPAN_AUTOSELECT, 3634, "ISO-2022-JP") \ + V(INTERNAL_IE_ENCODINGMENU_JAPAN_EUC, 3635, "EUC-JP") \ + V(INTERNAL_IE_ENCODINGMENU_JAPAN_SHIFT_JIS, 3636, "Shift_JIS") \ + V(INTERNAL_IE_ENCODINGMENU_KOREA, 3637, "windows-949") \ + V(INTERNAL_IE_ENCODINGMENU_THAI, 3638, "windows-874") \ + V(INTERNAL_IE_ENCODINGMENU_TURKISH_ISO, 3639, "windows-1254") \ + V(INTERNAL_IE_ENCODINGMENU_TURKISH_WINDOWS, 3640, "windows-1254") \ + V(INTERNAL_IE_ENCODINGMENU_UTF8, 3641, "UTF-8") \ + V(INTERNAL_IE_ENCODINGMENU_USERDEFINED, 3642, "windows-1252") \ + V(INTERNAL_IE_ENCODINGMENU_VIETNAMESE, 3643, "windows-1258") \ + V(INTERNAL_IE_ENCODINGMENU_WEST_EUROPEAN_ISO8859_1, 3644, "ISO-8859-1") \ + V(INTERNAL_IE_ENCODINGMENU_WEST_EUROPEAN_WINDOWS, 3645, "windows-1252") \ + V(INTERNAL_IE_ENCODINGMENU_AUTODETECT, 3699, "unknown") + +#define DEFINE_ENCODING_ID(encoding_name, id, chrome_name) \ + const DWORD encoding_name = id; + INTERNAL_IE_ENCODINGMENU_IDS(DEFINE_ENCODING_ID) +#undef DEFINE_ENCODING_ID +extern const DWORD kIEEncodingIdArray[]; + #ifndef SBCMDID_MIXEDZONE // This command is sent by the frame to allow the document to return the URL // security zone for display. @@ -106,8 +164,28 @@ class ChromeActiveDocument; break; \ } +#define EXEC_GROUP_COMMANDS_HANDLER(group, group_commands, handler) \ + do { \ + const DWORD* commands = group_commands; \ + bool id_in_group_commands = false; \ + while (*commands) { \ + if (*commands == command_id) { \ + id_in_group_commands = true; \ + break; \ + } \ + commands++; \ + } \ + if (id_in_group_commands && ((group != NULL && cmd_group_guid != NULL && \ + IsEqualGUID(*(GUID*)group,*cmd_group_guid)) || \ + (group == NULL && cmd_group_guid == NULL))) { \ + hr = S_OK; \ + handler(cmd_group_guid, command_id, cmd_exec_opt, in_args, out_args); \ + break; \ + } \ + } while (0); + #define END_EXEC_COMMAND_MAP() \ - } while(0); \ + } while (0); \ return hr; \ } @@ -185,6 +263,10 @@ BEGIN_EXEC_COMMAND_MAP(ChromeActiveDocument) EXEC_COMMAND_HANDLER(&CGID_MSHTML, IDM_BASELINEFONT3, SetPageFontSize) EXEC_COMMAND_HANDLER(&CGID_MSHTML, IDM_BASELINEFONT4, SetPageFontSize) EXEC_COMMAND_HANDLER(&CGID_MSHTML, IDM_BASELINEFONT5, SetPageFontSize) + + EXEC_GROUP_COMMANDS_HANDLER(&CGID_MSHTML, kIEEncodingIdArray, + OnEncodingChange) + EXEC_COMMAND_HANDLER_NO_ARGS(&CGID_ShellDocView, DOCHOST_DISPLAY_PRIVACY, OnDisplayPrivacyInfo) END_EXEC_COMMAND_MAP() @@ -321,6 +403,10 @@ END_EXEC_COMMAND_MAP() HRESULT OnRefreshPage(const GUID* cmd_group_guid, DWORD command_id, DWORD cmd_exec_opt, VARIANT* in_args, VARIANT* out_args); + // Handler to set the page encoding info in Chrome. + HRESULT OnEncodingChange(const GUID* cmd_group_guid, DWORD command_id, + DWORD cmd_exec_opt, VARIANT* in_args, + VARIANT* out_args); // Get the travel log from the client site HRESULT GetBrowserServiceAndTravelLog(IBrowserService** browser_service, |