Modified: trunk/Source/WebCore/ChangeLog (200088 => 200089)
--- trunk/Source/WebCore/ChangeLog 2016-04-26 16:12:19 UTC (rev 200088)
+++ trunk/Source/WebCore/ChangeLog 2016-04-26 16:22:32 UTC (rev 200089)
@@ -1,3 +1,26 @@
+2016-04-25 Filip Pizlo <fpi...@apple.com>
+
+ WebCore on Mac ignores the user's preferred region (country) while getting the language
+ https://bugs.webkit.org/show_bug.cgi?id=156993
+
+ Reviewed by Geoffrey Garen.
+
+ I don't know how to test this since this depends on user settings.
+
+ WebCore was previously getting the list of preferred languages, and for each one, deducing
+ the default region. That's wrong, since for example it doesn't respect the user's choice (in
+ System Preferences) to display dates/calenders/etc according to a different region (like how
+ I have my machine set to en-pl right now).
+
+ It might be possible for the country code we get via kCFLocaleCountryCode to be something
+ that our ICU doesn't handle. To defend against this, we search for the resulting country
+ code in ICU's ISO countries list. If it doesn't appear in that list, we fall back on old
+ behavior.
+
+ * platform/mac/Language.mm:
+ (WebCore::httpStyleLanguageCode):
+ (WebCore::platformUserPreferredLanguages):
+
2016-04-26 Chris Dumez <cdu...@apple.com>
[Web IDL] Specify default values for optional parameters of TypedArray types
Modified: trunk/Source/WebCore/platform/mac/Language.mm (200088 => 200089)
--- trunk/Source/WebCore/platform/mac/Language.mm 2016-04-26 16:12:19 UTC (rev 200088)
+++ trunk/Source/WebCore/platform/mac/Language.mm 2016-04-26 16:22:32 UTC (rev 200089)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2005, 2006, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2010, 2011, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#import "CFBundleSPI.h"
#import "WebCoreNSStringExtras.h"
#import <mutex>
+#import <unicode/uloc.h>
#import <wtf/Assertions.h>
#import <wtf/Lock.h>
#import <wtf/NeverDestroyed.h>
@@ -69,7 +70,7 @@
namespace WebCore {
-static String httpStyleLanguageCode(NSString *language)
+static String httpStyleLanguageCode(NSString *language, NSString *country)
{
SInt32 languageCode;
SInt32 regionCode;
@@ -87,9 +88,19 @@
// Make the string lowercase.
NSString *lowercaseLanguageCode = [language lowercaseString];
-
- // Turn a '_' into a '-' if it appears after a 2-letter language code.
+ NSString *lowercaseCountryCode = [country lowercaseString];
+
+ // If we see a "_" after a 2-letter language code:
+ // If the country is valid, replace the "_" and whatever comes after it with "-" followed by the
+ // country code.
+ // Otherwise, replace the "_" with a "-" and use whatever country
+ // CFBundleCopyLocalizationForLocalizationInfo() returned.
if ([lowercaseLanguageCode length] >= 3 && [lowercaseLanguageCode characterAtIndex:2] == '_') {
+ if (country)
+ return [NSString stringWithFormat:@"%@-%@", [lowercaseLanguageCode substringWithRange:NSMakeRange(0, 2)], lowercaseCountryCode];
+
+ // Fall back to older behavior, which used the original language-based code but just changed
+ // the "_" to a "-".
RetainPtr<NSMutableString> mutableLanguageCode = adoptNS([lowercaseLanguageCode mutableCopy]);
[mutableLanguageCode.get() replaceCharactersInRange:NSMakeRange(2, 1) withString:@"-"];
return mutableLanguageCode.get();
@@ -98,6 +109,18 @@
return lowercaseLanguageCode;
}
+static bool isValidICUCountryCode(NSString* countryCode)
+{
+ const char* const* countries = uloc_getISOCountries();
+ const char* countryUTF8 = [countryCode UTF8String];
+ for (unsigned i = 0; countries[i]; ++i) {
+ const char* possibleCountry = countries[i];
+ if (!strcmp(countryUTF8, possibleCountry))
+ return true;
+ }
+ return false;
+}
+
Vector<String> platformUserPreferredLanguages()
{
#if PLATFORM(MAC)
@@ -113,13 +136,19 @@
Vector<String>& userPreferredLanguages = preferredLanguages();
if (userPreferredLanguages.isEmpty()) {
+ RetainPtr<CFLocaleRef> locale = adoptCF(CFLocaleCopyCurrent());
+ NSString *countryCode = (NSString *)CFLocaleGetValue(locale.get(), kCFLocaleCountryCode);
+
+ if (!isValidICUCountryCode(countryCode))
+ countryCode = nil;
+
RetainPtr<CFArrayRef> languages = adoptCF(CFLocaleCopyPreferredLanguages());
CFIndex languageCount = CFArrayGetCount(languages.get());
if (!languageCount)
userPreferredLanguages.append("en");
else {
for (CFIndex i = 0; i < languageCount; i++)
- userPreferredLanguages.append(httpStyleLanguageCode((NSString *)CFArrayGetValueAtIndex(languages.get(), i)));
+ userPreferredLanguages.append(httpStyleLanguageCode((NSString *)CFArrayGetValueAtIndex(languages.get(), i), countryCode));
}
}