diff options
-rw-r--r-- | app/l10n_util.cc | 39 | ||||
-rw-r--r-- | app/l10n_util_mac.h | 4 | ||||
-rw-r--r-- | app/l10n_util_mac.mm | 53 | ||||
-rw-r--r-- | chrome/browser/browser_main_mac.mm | 6 | ||||
-rw-r--r-- | chrome/browser/dom_ui/tips_handler.cc | 6 | ||||
-rw-r--r-- | chrome/browser/web_resource/web_resource_service.cc | 21 | ||||
-rw-r--r-- | chrome/browser/web_resource/web_resource_service.h | 3 |
7 files changed, 96 insertions, 36 deletions
diff --git a/app/l10n_util.cc b/app/l10n_util.cc index d35f68d..f44ce37 100644 --- a/app/l10n_util.cc +++ b/app/l10n_util.cc @@ -25,6 +25,10 @@ #include <gtk/gtk.h> #endif +#if defined(OS_MACOSX) +#include "app/l10n_util_mac.h" +#endif + // TODO(playmobil): remove this undef once SkPostConfig.h is fixed. // skia/include/corecg/SkPostConfig.h #defines strcasecmp() so we can't use // base::strcasecmp() without #undefing it here. @@ -422,19 +426,16 @@ namespace l10n_util { // Represents the locale-specific text direction. static TextDirection g_text_direction = UNKNOWN_DIRECTION; -// On the Mac, we don't want to test preferences or ICU for the language, -// we want to use whatever Cocoa is using when it loaded the main nib file. -// It handles all the mapping and fallbacks for us, we just need to ask. -// See l10n_util_mac for that implementation. -#if !defined(OS_MACOSX) std::string GetApplicationLocale(const std::wstring& pref_locale) { +#if !defined(OS_MACOSX) + FilePath locale_path; PathService::Get(app::DIR_LOCALES, &locale_path); std::string resolved_locale; std::vector<std::string> candidates; const std::string system_locale = GetSystemLocale(); - // We only use --lang and the app pref on Windows. On Linux/Mac, we only + // We only use --lang and the app pref on Windows. On Linux, we only // look at the LC_*/LANG environment variables. We do, however, pass --lang // to renderer and plugin processes so they know what language the parent // process decided to use. @@ -482,8 +483,32 @@ std::string GetApplicationLocale(const std::wstring& pref_locale) { NOTREACHED(); return std::string(); -} + +#else // !defined(OS_MACOSX) + + // Use any override (Cocoa for the browser), otherwise use the command line + // argument. + std::string app_locale = l10n_util::GetLocaleOverride(); + if (app_locale.empty()) { + const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); + app_locale = parsed_command_line.GetSwitchValueASCII(switches::kLang); + } + + // The above should handle all of the cases Chrome normally hits, but for some + // unit tests, we need something to fall back too. + if (app_locale.empty()) + app_locale = "en-US"; + + // Windows/Linux call CheckAndResolveLocale which calls IsLocaleAvailable + // which calls SetICUDefaultLocale to let ICU use the same locale. Mac + // doesn't use a locale directory tree of resources (it uses Mac style + // resources), so mirror that ICU behavior by calling SetICUDefaultLocale + // directly. + UBool icu_set = SetICUDefaultLocale(app_locale); + DCHECK(icu_set); + return app_locale; #endif // !defined(OS_MACOSX) +} string16 GetDisplayNameForLocale(const std::string& locale_code, const std::string& display_locale, diff --git a/app/l10n_util_mac.h b/app/l10n_util_mac.h index 87ccb05..995d191 100644 --- a/app/l10n_util_mac.h +++ b/app/l10n_util_mac.h @@ -63,6 +63,10 @@ NSString* GetNSStringFWithFixup(int message_id, const string16& c, const string16& d); +// Support the override of the locale with the value from Cocoa. +void OverrideLocaleWithCocoaLocale(); +const std::string& GetLocaleOverride(); + } // namespace l10n_util #endif // APP_L10N_UTIL_MAC_H_ diff --git a/app/l10n_util_mac.mm b/app/l10n_util_mac.mm index fe09826..9861f14 100644 --- a/app/l10n_util_mac.mm +++ b/app/l10n_util_mac.mm @@ -5,14 +5,57 @@ #import <Foundation/Foundation.h> #include "app/l10n_util_mac.h" #include "base/sys_string_conversions.h" +#include "base/lazy_instance.h" + +namespace { + +class OverrideLocaleHolder { + public: + OverrideLocaleHolder() {} + const std::string& value() const { return value_; } + void set_value(const std::string override_value) { value_ = override_value; } + private: + DISALLOW_COPY_AND_ASSIGN(OverrideLocaleHolder); + std::string value_; +}; + +base::LazyInstance<OverrideLocaleHolder> + override_locale_holder(base::LINKER_INITIALIZED); + +} // namespace namespace l10n_util { -std::string GetApplicationLocale(const std::wstring& pref_locale) { - // NOTE: The Win/Linux version of this calls out to CheckAndResolveLocale - // to do some remapping. Since Mac is using real locales that Cocoa has - // to be able to load, that shouldn't be needed. - return [[[NSLocale currentLocale] localeIdentifier] UTF8String]; +const std::string& GetLocaleOverride() { + return override_locale_holder.Get().value(); +} + +void OverrideLocaleWithCocoaLocale() { + // NSBundle really should only be called on the main thread. + DCHECK([NSThread isMainThread]); + + // Chrome really only has one concept of locale, but Mac OS X has locale and + // language that can be set independently. After talking with Chrome UX folks + // (Cole), the best path from an experience point of view is to map the Mac OS + // X language into the Chrome locale. This way strings like "Yesterday" and + // "Today" are in the same language as raw dates like "March 20, 1999" (Chrome + // strings resources vs ICU generated strings). This also makes the Mac acts + // like other Chrome platforms. + NSArray* languageList = [[NSBundle mainBundle] preferredLocalizations]; + NSString* firstLocale = [languageList objectAtIndex:0]; + // Mac OS X uses "_" instead of "-", so swap to get a real locale value. + std::string locale_value = + [[firstLocale stringByReplacingOccurrencesOfString:@"_" + withString:@"-"] UTF8String]; + + // On disk the "en-US" resources are just "en" (http://crbug.com/25578), so + // the reverse mapping is done here to continue to feed Chrome the same values + // in all cases on all platforms. (l10n_util maps en to en-US if it gets + // passed this on the command line) + if (locale_value == "en") + locale_value = "en-US"; + + override_locale_holder.Get().set_value(locale_value); } // Remove the Windows-style accelerator marker and change "..." into an diff --git a/chrome/browser/browser_main_mac.mm b/chrome/browser/browser_main_mac.mm index 65b6970..27024f06 100644 --- a/chrome/browser/browser_main_mac.mm +++ b/chrome/browser/browser_main_mac.mm @@ -6,6 +6,8 @@ #import <Cocoa/Cocoa.h> +#include "app/app_switches.h" +#include "app/l10n_util_mac.h" #include "app/resource_bundle.h" #include "base/command_line.h" #include "base/debug_util.h" @@ -39,6 +41,10 @@ void WillInitializeMainMessageLoop(const MainFunctionParams& parameters) { // Now load the nib. [NSBundle loadNibNamed:@"MainMenu" owner:NSApp]; + // The browser process only wants to support the language Cocoa will use, so + // force the app locale to be overriden with that value. + l10n_util::OverrideLocaleWithCocoaLocale(); + // This is a no-op if the KeystoneRegistration framework is not present. // The framework is only distributed with branded Google Chrome builds. [[KeystoneGlue defaultKeystoneGlue] registerWithKeystone]; diff --git a/chrome/browser/dom_ui/tips_handler.cc b/chrome/browser/dom_ui/tips_handler.cc index 68ce766..35d3cc2 100644 --- a/chrome/browser/dom_ui/tips_handler.cc +++ b/chrome/browser/dom_ui/tips_handler.cc @@ -44,9 +44,9 @@ void TipsHandler::HandleGetTips(const Value* content) { PrefService* current_prefs = dom_ui_->GetProfile()->GetPrefs(); if (current_prefs->HasPrefPath(prefs::kNTPTipsServer)) { std::wstring server = current_prefs->GetString(prefs::kNTPTipsServer); - std::wstring tips_language = WebResourceService::GetWebResourceLanguage( - current_prefs); - if (!EndsWith(server, tips_language, false)) { + std::wstring locale = + ASCIIToWide(g_browser_process->GetApplicationLocale()); + if (!EndsWith(server, locale, false)) { dom_ui_->CallJavascriptFunction(L"tips", list_value); return; } diff --git a/chrome/browser/web_resource/web_resource_service.cc b/chrome/browser/web_resource/web_resource_service.cc index c26c8b1..c4ffa47 100644 --- a/chrome/browser/web_resource/web_resource_service.cc +++ b/chrome/browser/web_resource/web_resource_service.cc @@ -211,19 +211,19 @@ void WebResourceService::Init() { resource_dispatcher_host_ = g_browser_process->resource_dispatcher_host(); web_resource_fetcher_ = new WebResourceFetcher(this); prefs_->RegisterStringPref(prefs::kNTPTipsCacheUpdate, L"0"); - std::wstring language = WebResourceService::GetWebResourceLanguage(prefs_); + std::wstring locale = ASCIIToWide(g_browser_process->GetApplicationLocale()); if (prefs_->HasPrefPath(prefs::kNTPTipsServer)) { web_resource_server_ = prefs_->GetString(prefs::kNTPTipsServer); // If we are in the correct locale, initialization is done. - if (EndsWith(web_resource_server_, language, false)) + if (EndsWith(web_resource_server_, locale, false)) return; } // If we have not yet set a server, or if the tips server is set to the wrong // locale, reset the server and force an immediate update of tips. web_resource_server_ = kDefaultResourceServer; - web_resource_server_.append(language); + web_resource_server_.append(locale); prefs_->SetString(prefs::kNTPTipsCacheUpdate, L""); } @@ -302,18 +302,3 @@ void WebResourceService::UpdateResourceCache(const std::string& json_data) { DoubleToWString(base::Time::Now().ToDoubleT())); prefs_->SetString(prefs::kNTPTipsServer, web_resource_server_); } - -// static -std::wstring WebResourceService::GetWebResourceLanguage(PrefService* prefs) { -#if defined OS_MACOSX - // OS X derives the language for the Chrome UI from the list of accepted - // languages, which can be different from the locale. - std::wstring languageList = prefs->GetString(prefs::kAcceptLanguages); - int pos = languageList.find(L","); - pos = pos >= 0 ? pos : languageList.length(); - return languageList.substr(0, pos); -#else - return ASCIIToWide(g_browser_process->GetApplicationLocale()); -#endif -} - diff --git a/chrome/browser/web_resource/web_resource_service.h b/chrome/browser/web_resource/web_resource_service.h index 86abf1a..a125cdc9 100644 --- a/chrome/browser/web_resource/web_resource_service.h +++ b/chrome/browser/web_resource/web_resource_service.h @@ -26,9 +26,6 @@ class WebResourceService // the process that will parse the JSON, and then update the cache. void UpdateResourceCache(const std::string& json_data); - // Get the language appropriate for delivery of the web resources. - static std::wstring GetWebResourceLanguage(PrefService* prefs); - static const wchar_t* kTipDictionaryPrefName; static const wchar_t* kCurrentTipPrefName; static const wchar_t* kTipCachePrefName; |