Title: [200089] trunk/Source/WebCore
Revision
200089
Author
fpi...@apple.com
Date
2016-04-26 09:22:32 -0700 (Tue, 26 Apr 2016)

Log Message

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):

Modified Paths

Diff

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));
         }
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to