Bug 1409185 - Generalize language-matching for date/time patterns in OSPreferences. r?jfkthame
MozReview-Commit-ID: LF98Avi6egj
--- a/intl/locale/LocaleService.cpp
+++ b/intl/locale/LocaleService.cpp
@@ -222,20 +222,49 @@ LocaleService::GetAppLocalesAsBCP47(nsTA
}
}
void
LocaleService::GetRegionalPrefsLocales(nsTArray<nsCString>& aRetVal)
{
bool useOSLocales = Preferences::GetBool("intl.regional_prefs.use_os_locales", false);
- if (useOSLocales && OSPreferences::GetInstance()->GetRegionalPrefsLocales(aRetVal)) {
+ // If the user specified that they want to use OS Regional Preferences locales,
+ // try to retrieve them and use.
+ if (useOSLocales) {
+ if (OSPreferences::GetInstance()->GetRegionalPrefsLocales(aRetVal)) {
+ return;
+ }
+
+ // If we fail to retrieve them, return the app locales.
+ GetAppLocalesAsBCP47(aRetVal);
return;
}
+ // Otherwise, fetch OS Regional Preferences locales and compare the first one
+ // to the app locale. If the language subtag matches, we can safely use
+ // the OS Regional Preferences locale.
+ //
+ // This facilitates scenarios such as Firefox in "en-US" and User sets
+ // regional prefs to "en-GB".
+ nsAutoCString appLocale;
+ AutoTArray<nsCString, 10> regionalPrefsLocales;
+ LocaleService::GetInstance()->GetAppLocaleAsBCP47(appLocale);
+
+ if (!OSPreferences::GetInstance()->GetRegionalPrefsLocales(regionalPrefsLocales)) {
+ GetAppLocalesAsBCP47(aRetVal);
+ return;
+ }
+
+ if (LocaleService::LanguagesMatch(appLocale, regionalPrefsLocales[0])) {
+ aRetVal = regionalPrefsLocales;
+ return;
+ }
+
+ // Otherwise use the app locales.
GetAppLocalesAsBCP47(aRetVal);
}
void
LocaleService::AssignAppLocales(const nsTArray<nsCString>& aAppLocales)
{
MOZ_ASSERT(!mIsServer, "This should only be called for LocaleService in client mode.");
--- a/intl/locale/OSPreferences.cpp
+++ b/intl/locale/OSPreferences.cpp
@@ -165,17 +165,19 @@ OSPreferences::GetDateTimePatternForStyl
break;
}
const int32_t kPatternMax = 160;
UChar pattern[kPatternMax];
nsAutoCString locale;
if (aLocale.IsEmpty()) {
- LocaleService::GetInstance()->GetAppLocaleAsBCP47(locale);
+ AutoTArray<nsCString, 10> regionalPrefsLocales;
+ LocaleService::GetInstance()->GetRegionalPrefsLocales(regionalPrefsLocales);
+ locale.Assign(regionalPrefsLocales[0]);
} else {
locale.Assign(aLocale);
}
UErrorCode status = U_ZERO_ERROR;
UDateFormat* df = udat_open(timeStyle, dateStyle,
locale.get(),
nullptr, -1, nullptr, -1, &status);
--- a/intl/locale/windows/OSPreferences_win.cpp
+++ b/intl/locale/windows/OSPreferences_win.cpp
@@ -47,35 +47,16 @@ OSPreferences::ReadRegionalPrefsLocales(
if (CanonicalizeLanguageTag(loc)) {
aLocaleList.AppendElement(loc);
return true;
}
return false;
}
-/**
- * Windows distinguishes between System Locale (the locale OS is in), and
- * User Locale (the locale used for regional settings etc.).
- *
- * For DateTimePattern, we want to retrieve the User Locale.
- */
-static void
-ReadUserLocale(nsCString& aRetVal)
-{
- WCHAR locale[LOCALE_NAME_MAX_LENGTH];
- if (NS_WARN_IF(!LCIDToLocaleName(LOCALE_USER_DEFAULT, locale,
- LOCALE_NAME_MAX_LENGTH, 0))) {
- aRetVal.AssignLiteral("en-US");
- return;
- }
-
- LossyCopyUTF16toASCII(locale, aRetVal);
-}
-
static LCTYPE
ToDateLCType(OSPreferences::DateTimeFormatStyle aFormatStyle)
{
switch (aFormatStyle) {
case OSPreferences::DateTimeFormatStyle::None:
return LOCALE_SLONGDATE;
case OSPreferences::DateTimeFormatStyle::Short:
return LOCALE_SSHORTDATE;
@@ -108,39 +89,16 @@ ToTimeLCType(OSPreferences::DateTimeForm
return LOCALE_STIMEFORMAT;
case OSPreferences::DateTimeFormatStyle::Invalid:
default:
MOZ_ASSERT_UNREACHABLE("invalid time format");
return LOCALE_STIMEFORMAT;
}
}
-LPWSTR
-GetWindowsLocaleFor(const nsACString& aLocale, LPWSTR aBuffer)
-{
- nsAutoCString reqLocale;
- nsAutoCString userLocale;
- ReadUserLocale(userLocale);
-
- if (aLocale.IsEmpty()) {
- LocaleService::GetInstance()->GetAppLocaleAsBCP47(reqLocale);
- } else {
- reqLocale.Assign(aLocale);
- }
-
- bool match = LocaleService::LanguagesMatch(reqLocale, userLocale);
- if (match || reqLocale.Length() >= LOCALE_NAME_MAX_LENGTH) {
- UTF8ToUnicodeBuffer(userLocale, (char16_t*)aBuffer);
- } else {
- UTF8ToUnicodeBuffer(reqLocale, (char16_t*)aBuffer);
- }
-
- return aBuffer;
-}
-
/**
* Windows API includes regional preferences from the user only
* if we pass empty locale string or if the locale string matches
* the current locale.
*
* Since Windows API only allows us to retrieve two options - short/long
* we map it to our four options as:
*
@@ -153,19 +111,18 @@ GetWindowsLocaleFor(const nsACString& aL
* for combined date/time string, since Windows API does not provide an
* option for this.
*/
bool
OSPreferences::ReadDateTimePattern(DateTimeFormatStyle aDateStyle,
DateTimeFormatStyle aTimeStyle,
const nsACString& aLocale, nsAString& aRetVal)
{
- WCHAR buffer[LOCALE_NAME_MAX_LENGTH];
-
- LPWSTR localeName = GetWindowsLocaleFor(aLocale, buffer);
+ WCHAR localeName[LOCALE_NAME_MAX_LENGTH];
+ UTF8ToUnicodeBuffer(aLocale, (char16_t*)localeName);
bool isDate = aDateStyle != DateTimeFormatStyle::None &&
aDateStyle != DateTimeFormatStyle::Invalid;
bool isTime = aTimeStyle != DateTimeFormatStyle::None &&
aTimeStyle != DateTimeFormatStyle::Invalid;
// If both date and time are wanted, we'll initially read them into a
// local string, and then insert them into the overall date+time pattern;