summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/chrome_frame.gyp17
-rw-r--r--chrome_frame/chrome_frame_plugin.h7
-rw-r--r--chrome_frame/resources/chrome_frame_resources.grd15
-rw-r--r--chrome_frame/simple_resource_loader.cc136
-rw-r--r--chrome_frame/simple_resource_loader.h55
-rw-r--r--chrome_frame/utils.cc27
6 files changed, 222 insertions, 35 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index 159b762..66514ef 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -284,6 +284,7 @@
'../third_party/libxml/libxml.gyp:libxml',
'../third_party/libxslt/libxslt.gyp:libxslt',
'chrome_frame_strings',
+ 'chrome_frame_utils',
'npchrome_frame',
'xulrunner_sdk',
],
@@ -459,6 +460,7 @@
'type': 'static_library',
'dependencies': [
'chrome_frame_strings',
+ 'chrome_frame_utils',
'../chrome/chrome.gyp:common',
'xulrunner_sdk',
],
@@ -570,10 +572,24 @@
],
},
{
+ 'target_name': 'chrome_frame_utils',
+ # The intent is that shared util code can be built into a separate lib.
+ # Currently on the resource loading code is here.
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base_i18n',
+ ],
+ 'sources': [
+ 'simple_resource_loader.cc',
+ 'simple_resource_loader.h',
+ ],
+ },
+ {
'target_name': 'chrome_frame_ie',
'type': 'static_library',
'dependencies': [
'chrome_frame_strings',
+ 'chrome_frame_utils',
'../chrome/chrome.gyp:common',
'../chrome/chrome.gyp:utility',
'../build/temp_gyp/googleurl.gyp:googleurl',
@@ -667,6 +683,7 @@
'chrome_frame_ie',
'chrome_frame_npapi',
'chrome_frame_strings',
+ 'chrome_frame_utils',
'chrome_launcher',
'xulrunner_sdk',
'../chrome/chrome.gyp:common',
diff --git a/chrome_frame/chrome_frame_plugin.h b/chrome_frame/chrome_frame_plugin.h
index 078a611..17fb6572 100644
--- a/chrome_frame/chrome_frame_plugin.h
+++ b/chrome_frame/chrome_frame_plugin.h
@@ -8,8 +8,11 @@
#include "base/ref_counted.h"
#include "base/win_util.h"
#include "chrome_frame/chrome_frame_automation.h"
+#include "chrome_frame/simple_resource_loader.h"
#include "chrome_frame/utils.h"
+#include "grit/chromium_strings.h"
+
#define IDC_ABOUT_CHROME_FRAME 40018
// A class to implement common functionality for all types of
@@ -181,10 +184,8 @@ END_MSG_MAP()
// Override in most-derived class if needed.
bool PreProcessContextMenu(HMENU menu) {
// Add an "About" item.
- // TODO: The string should be localized and menu should
- // be modified in ExternalTabContainer:: once we go public.
AppendMenu(menu, MF_STRING, IDC_ABOUT_CHROME_FRAME,
- L"About Chrome Frame...");
+ SimpleResourceLoader::Get(IDS_CHROME_FRAME_MENU_ABOUT).c_str());
return true;
}
diff --git a/chrome_frame/resources/chrome_frame_resources.grd b/chrome_frame/resources/chrome_frame_resources.grd
index ee6a846..abd6547 100644
--- a/chrome_frame/resources/chrome_frame_resources.grd
+++ b/chrome_frame/resources/chrome_frame_resources.grd
@@ -20,20 +20,7 @@ for localizable strings
<output filename="chrome_frame_resources.pak" type="data_package" />
</outputs>
<release seq="1">
- <messages>
- <message name="IDS_VERSIONMISMATCH_HEADER">
- ChromeFrame Update.
- </message>
- <message name="IDS_VERSIONMISMATCH">
- ChromeFrame has been updated. Please restart your browser. Chrome version: <ph name="TODO_0001">%ls<ex>TODO</ex></ph>, Chrome Frame version: <ph name="TODO_0002">%ls<ex>TODO</ex></ph>
- </message>
- <message name="IDS_VERSIONUNKNOWN">
- Very old
- </message>
- <message name="IDS_CHROME_FRAME_MENU_ABOUT" desc="About Chrome Frame label">
- About Chrome Frame...
- </message>
- </messages>
+ <!-- TODO(robertshield): All that's left now is to localize the dialog resource. -->
<structures first_id="50000">
<structure name="IDD_FIND_DIALOG" file="structured_resources.rc" type="dialog" >
</structure>
diff --git a/chrome_frame/simple_resource_loader.cc b/chrome_frame/simple_resource_loader.cc
new file mode 100644
index 0000000..2eb2167
--- /dev/null
+++ b/chrome_frame/simple_resource_loader.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome_frame/simple_resource_loader.h"
+
+#include <atlbase.h>
+#include <string>
+
+#include "base/base_paths.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/i18n/rtl.h"
+#include "base/string_util.h"
+#include "base/win_util.h"
+
+const wchar_t kLocalesDirName[] = L"Locales";
+
+HINSTANCE SimpleResourceLoader::locale_dll_handle_;
+
+SimpleResourceLoader::SimpleResourceLoader() {
+ // Find and load the resource DLL.
+ std::wstring locale = GetSystemLocale();
+ std::wstring locale_dll_path;
+
+ if (GetLocaleFilePath(locale, &locale_dll_path)) {
+ DCHECK(locale_dll_handle_ == NULL) << "Locale DLL is already loaded!";
+ locale_dll_handle_ = LoadLocaleDll(locale_dll_path);
+ DCHECK(locale_dll_handle_ != NULL) << "Failed to load locale dll!";
+ }
+}
+
+
+std::wstring SimpleResourceLoader::GetSystemLocale() {
+ std::string language, region;
+ base::i18n::GetLanguageAndRegionFromOS(&language, &region);
+ std::string ret;
+ if (!language.empty())
+ ret.append(language);
+ if (!region.empty()) {
+ ret.append("-");
+ ret.append(region);
+ }
+ return ASCIIToWide(ret);
+}
+
+bool SimpleResourceLoader::GetLocaleFilePath(const std::wstring& locale,
+ std::wstring* file_path) {
+ DCHECK(file_path);
+
+ FilePath module_path;
+ PathService::Get(base::DIR_MODULE, &module_path);
+ FilePath locales_path = module_path.Append(kLocalesDirName);
+
+ // We may be residing in the "locales" directory's parent, or we might be
+ // in a sibling directory. Move up one and look for Locales again in the
+ // latter case.
+ if (!file_util::DirectoryExists(locales_path)) {
+ locales_path = module_path.DirName();
+ locales_path = locales_path.Append(kLocalesDirName);
+ }
+
+ bool found_dll = false;
+ if (file_util::DirectoryExists(locales_path)) {
+ std::wstring dll_name(locale);
+ dll_name += L".dll";
+
+ // First look for the named locale DLL.
+ FilePath look_path(locales_path.Append(dll_name));
+ if (file_util::PathExists(look_path)) {
+ *file_path = look_path.value();
+ found_dll = true;
+ } else {
+
+ // If we didn't find it, try defaulting to en-US.dll.
+ dll_name = L"en-US.dll";
+ look_path = locales_path.Append(dll_name);
+ if (file_util::PathExists(look_path)) {
+ *file_path = look_path.value();
+ found_dll = true;
+ }
+ }
+ } else {
+ NOTREACHED() << "Could not locate locales DLL directory.";
+ }
+
+ return found_dll;
+}
+
+HINSTANCE SimpleResourceLoader::LoadLocaleDll(const std::wstring& dll_path) {
+ DWORD load_flags = 0;
+ if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) {
+ load_flags = LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
+ LOAD_LIBRARY_AS_IMAGE_RESOURCE;
+ } else {
+ load_flags = DONT_RESOLVE_DLL_REFERENCES;
+ }
+
+ // The dll should only have resources, not executable code.
+ HINSTANCE locale_dll_handle = LoadLibraryEx(dll_path.c_str(), NULL,
+ load_flags);
+ DCHECK(locale_dll_handle != NULL) << "unable to load generated resources: "
+ << GetLastError();
+
+ return locale_dll_handle;
+}
+
+std::wstring SimpleResourceLoader::GetLocalizedResource(int message_id) {
+ if (!locale_dll_handle_) {
+ LOG(WARNING) << "locale resources are not loaded";
+ return std::wstring();
+ }
+
+ DCHECK(IS_INTRESOURCE(message_id));
+
+ const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage(
+ locale_dll_handle_, message_id);
+ if (!image) {
+ // Fall back on the current module (shouldn't be any strings here except
+ // in unittests).
+ image = AtlGetStringResourceImage(_AtlBaseModule.GetModuleInstance(),
+ message_id);
+ if (!image) {
+ NOTREACHED() << "unable to find resource: " << message_id;
+ return std::wstring();
+ }
+ }
+ return std::wstring(image->achString, image->nLength);
+}
+
+// static
+std::wstring SimpleResourceLoader::Get(int message_id) {
+ SimpleResourceLoader* loader = SimpleResourceLoader::instance();
+ return loader->GetLocalizedResource(message_id);
+}
diff --git a/chrome_frame/simple_resource_loader.h b/chrome_frame/simple_resource_loader.h
new file mode 100644
index 0000000..2ec9860
--- /dev/null
+++ b/chrome_frame/simple_resource_loader.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This class implements a simplified and much stripped down version of
+// Chrome's app/resource_bundle machinery. It notably avoids unwanted
+// dependencies on things like Skia.
+//
+
+#ifndef CHROME_FRAME_SIMPLE_RESOURCE_LOADER_H_
+#define CHROME_FRAME_SIMPLE_RESOURCE_LOADER_H_
+
+#include <windows.h>
+#include <string>
+
+#include "base/singleton.h"
+
+class SimpleResourceLoader {
+ public:
+
+ static SimpleResourceLoader* instance() {
+ return Singleton<SimpleResourceLoader>::get();
+ }
+
+ // Helper method to return the string resource identified by message_id
+ // from the currently loaded locale dll.
+ static std::wstring Get(int message_id);
+
+ private:
+ SimpleResourceLoader();
+
+ // Retrieves the system locale in the <language>-<region> format using ICU.
+ std::wstring GetSystemLocale();
+
+ // Uses |locale| to build the resource DLL name and then looks for the named
+ // DLL in known locales paths. If it doesn't find it, it falls back to
+ // looking for an en-US.dll.
+ //
+ // Returns true if a locale DLL can be found, false otherwise.
+ bool GetLocaleFilePath(const std::wstring& locale, std::wstring* file_path);
+
+ // Loads the locale dll at the given path. Returns a handle to the DLL or
+ // NULL on failure.
+ HINSTANCE LoadLocaleDll(const std::wstring& dll_path);
+
+ // Returns the string resource identified by message_id from the currently
+ // loaded locale dll.
+ std::wstring GetLocalizedResource(int message_id);
+
+ friend struct DefaultSingletonTraits<SimpleResourceLoader>;
+
+ static HINSTANCE locale_dll_handle_;
+};
+
+#endif // CHROME_FRAME_SIMPLE_RESOURCE_LOADER_H_
diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc
index bec0595..7fcdde8 100644
--- a/chrome_frame/utils.cc
+++ b/chrome_frame/utils.cc
@@ -22,10 +22,12 @@
#include "chrome/installer/util/chrome_frame_distribution.h"
#include "chrome_frame/extra_system_apis.h"
#include "chrome_frame/html_utils.h"
+#include "chrome_frame/simple_resource_loader.h"
#include "chrome_frame/utils.h"
#include "googleurl/src/gurl.h"
#include "googleurl/src/url_canon.h"
-#include "grit/chrome_frame_resources.h"
+
+#include "grit/chromium_strings.h"
// Note that these values are all lower case and are compared to
// lower-case-transformed values.
@@ -285,19 +287,6 @@ HRESULT UtilGetXUACompatContentValue(const std::wstring& html_string,
return E_FAIL;
}
-std::wstring GetResourceString(int resource_id) {
- std::wstring resource_string;
- HMODULE this_module = reinterpret_cast<HMODULE>(&__ImageBase);
- const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage(
- this_module, resource_id);
- if (image) {
- resource_string.assign(image->achString, image->nLength);
- } else {
- NOTREACHED() << "Unable to find resource id " << resource_id;
- }
- return resource_string;
-}
-
void DisplayVersionMismatchWarning(HWND parent,
const std::string& server_version) {
// Obtain the current module version.
@@ -307,14 +296,16 @@ void DisplayVersionMismatchWarning(HWND parent,
std::wstring version_string(file_version_info->file_version());
std::wstring wide_server_version;
if (server_version.empty()) {
- wide_server_version = GetResourceString(IDS_VERSIONUNKNOWN);
+ wide_server_version = SimpleResourceLoader::Get(IDS_VERSIONUNKNOWN);
} else {
wide_server_version = ASCIIToWide(server_version);
}
- std::wstring title = GetResourceString(IDS_VERSIONMISMATCH_HEADER);
+ std::wstring title = SimpleResourceLoader::Get(IDS_VERSIONMISMATCH_HEADER);
std::wstring message;
- SStringPrintf(&message, GetResourceString(IDS_VERSIONMISMATCH).c_str(),
- wide_server_version.c_str(), version_string.c_str());
+ SStringPrintf(&message,
+ SimpleResourceLoader::Get(IDS_VERSIONMISMATCH).c_str(),
+ wide_server_version.c_str(),
+ version_string.c_str());
::MessageBox(parent, message.c_str(), title.c_str(), MB_OK);
}