diff --git a/chrome/src/nsChromeRegistryChrome.cpp b/chrome/src/nsChromeRegistryChrome.cpp index 0c2252d1905..8031eef70f1 100644 --- a/chrome/src/nsChromeRegistryChrome.cpp +++ b/chrome/src/nsChromeRegistryChrome.cpp @@ -36,6 +36,7 @@ #include "nsIObserverService.h" #include "nsIPrefBranch.h" #include "nsIPrefService.h" +#include "mozilla/Preferences.h" #include "nsIResProtocolHandler.h" #include "nsIScriptError.h" #include "nsIVersionComparator.h" @@ -48,6 +49,7 @@ #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS" #define SELECTED_LOCALE_PREF "general.useragent.locale" #define SELECTED_SKIN_PREF "general.skins.selectedSkin" +#define PACKAGE_OVERRIDE_BRANCH "chrome.override_package." using namespace mozilla; @@ -196,20 +198,25 @@ NS_IMETHODIMP nsChromeRegistryChrome::GetLocalesForPackage(const nsACString& aPackage, nsIUTF8StringEnumerator* *aResult) { + nsCString realpackage; + nsresult rv = OverrideLocalePackage(aPackage, realpackage); + if (NS_FAILED(rv)) + return rv; + nsTArray *a = new nsTArray; if (!a) return NS_ERROR_OUT_OF_MEMORY; PackageEntry* entry = static_cast(PL_DHashTableOperate(&mPackagesHash, - & aPackage, + & realpackage, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { entry->locales.EnumerateToArray(a); } - nsresult rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a); + rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a); if (NS_FAILED(rv)) delete a; @@ -267,9 +274,13 @@ nsresult nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage, nsACString& aLocale) { + nsCString realpackage; + nsresult rv = OverrideLocalePackage(aPackage, realpackage); + if (NS_FAILED(rv)) + return rv; PackageEntry* entry = static_cast(PL_DHashTableOperate(&mPackagesHash, - & aPackage, + & realpackage, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_FREE(entry)) @@ -282,6 +293,21 @@ nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage, return NS_OK; } +nsresult +nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage, + nsACString& aOverride) +{ + const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage; + nsAdoptingCString override = mozilla::Preferences::GetCString(PromiseFlatCString(pref).get()); + if (override) { + aOverride = override; + } + else { + aOverride = aPackage; + } + return NS_OK; +} + nsresult nsChromeRegistryChrome::SelectLocaleFromPref(nsIPrefBranch* prefs) { diff --git a/chrome/src/nsChromeRegistryChrome.h b/chrome/src/nsChromeRegistryChrome.h index 211b54a79c9..57d3e6cb8b6 100644 --- a/chrome/src/nsChromeRegistryChrome.h +++ b/chrome/src/nsChromeRegistryChrome.h @@ -50,6 +50,8 @@ class nsChromeRegistryChrome : public nsChromeRegistry PLDHashEntryHdr *entry, uint32_t number, void *arg); + nsresult OverrideLocalePackage(const nsACString& aPackage, + nsACString& aOverride); nsresult SelectLocaleFromPref(nsIPrefBranch* prefs); nsresult UpdateSelectedLocale() MOZ_OVERRIDE; nsIURI* GetBaseURIFromPackage(const nsCString& aPackage, diff --git a/chrome/test/unit/data/test_bug848297.manifest b/chrome/test/unit/data/test_bug848297.manifest new file mode 100644 index 00000000000..d9730a9ce75 --- /dev/null +++ b/chrome/test/unit/data/test_bug848297.manifest @@ -0,0 +1,4 @@ +locale basepack en-US jar:en-US.jar!/locale/en-US/global/ +locale basepack fr jar:en-US.jar!/locale/en-US/global/ +locale overpack en-US jar:en-US.jar!/locale/en-US/global/ +locale overpack de jar:en-US.jar!/locale/en-US/global/ diff --git a/chrome/test/unit/test_bug848297.js b/chrome/test/unit/test_bug848297.js new file mode 100644 index 00000000000..0875370f791 --- /dev/null +++ b/chrome/test/unit/test_bug848297.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +var MANIFESTS = [ + do_get_file("data/test_bug848297.manifest") +]; + +// Stub in the locale service so we can control what gets returned as the OS locale setting +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +registerManifests(MANIFESTS); + +var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"] + .getService(Ci.nsIXULChromeRegistry) + .QueryInterface(Ci.nsIToolkitChromeRegistry); +chromeReg.checkForNewChrome(); + +var prefService = Cc["@mozilla.org/preferences-service;1"] + .getService(Ci.nsIPrefService) + .QueryInterface(Ci.nsIPrefBranch); + +function enum_to_array(strings) { + let rv = []; + while (strings.hasMore()) { + rv.push(strings.getNext()); + } + rv.sort(); + return rv; +} + +function run_test() { + + // without override + prefService.setCharPref("general.useragent.locale", "de"); + do_check_eq(chromeReg.getSelectedLocale("basepack"), "en-US"); + do_check_eq(chromeReg.getSelectedLocale("overpack"), "de"); + do_check_matches(enum_to_array(chromeReg.getLocalesForPackage("basepack")), + ['en-US', 'fr']); + + // with override + prefService.setCharPref("chrome.override_package.basepack", "overpack"); + do_check_eq(chromeReg.getSelectedLocale("basepack"), "de"); + do_check_matches(enum_to_array(chromeReg.getLocalesForPackage("basepack")), + ['de', 'en-US']); + +} diff --git a/chrome/test/unit/xpcshell.ini b/chrome/test/unit/xpcshell.ini index da5f4df5973..2134d8d95bf 100644 --- a/chrome/test/unit/xpcshell.ini +++ b/chrome/test/unit/xpcshell.ini @@ -11,6 +11,7 @@ tail = [test_bug415367.js] [test_bug519468.js] [test_bug564667.js] +[test_bug848297.js] [test_crlf.js] [test_data_protocol_registration.js] [test_no_remote_registration.js]