diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/Language.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/platform/Language.cpp')
-rw-r--r-- | Source/WebCore/platform/Language.cpp | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/Source/WebCore/platform/Language.cpp b/Source/WebCore/platform/Language.cpp index fcd31259f..ec4b34924 100644 --- a/Source/WebCore/platform/Language.cpp +++ b/Source/WebCore/platform/Language.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2013, 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 @@ -27,24 +27,39 @@ #include "Language.h" #include <wtf/HashMap.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/PlatformUserPreferredLanguages.h> #include <wtf/RetainPtr.h> #include <wtf/text/WTFString.h> -#if PLATFORM(MAC) +#if USE(CF) && !PLATFORM(WIN) #include <CoreFoundation/CoreFoundation.h> #endif namespace WebCore { +static StaticLock userPreferredLanguagesMutex; + +static void registerLanguageDidChangeCallbackIfNecessary() +{ + static std::once_flag once; + std::call_once( + once, + [] { + setPlatformUserPreferredLanguagesChangedCallback(languageDidChange); + }); +} + typedef HashMap<void*, LanguageChangeObserverFunction> ObserverMap; static ObserverMap& observerMap() { - DEFINE_STATIC_LOCAL(ObserverMap, map, ()); - return map; + static NeverDestroyed<ObserverMap> map; + return map.get(); } void addLanguageChangeObserver(void* context, LanguageChangeObserverFunction customObserver) { + registerLanguageDidChangeCallbackIfNecessary(); observerMap().set(context, customObserver); } @@ -72,7 +87,7 @@ String defaultLanguage() static Vector<String>& preferredLanguagesOverride() { - DEFINE_STATIC_LOCAL(Vector<String>, override, ()); + static NeverDestroyed<Vector<String>> override; return override; } @@ -84,20 +99,34 @@ Vector<String> userPreferredLanguagesOverride() void overrideUserPreferredLanguages(const Vector<String>& override) { preferredLanguagesOverride() = override; + languageDidChange(); } - + +static Vector<String> isolatedCopy(const Vector<String>& strings) +{ + Vector<String> copy; + copy.reserveInitialCapacity(strings.size()); + for (auto& language : strings) + copy.uncheckedAppend(language.isolatedCopy()); + return copy; +} + Vector<String> userPreferredLanguages() { - Vector<String>& override = preferredLanguagesOverride(); - if (!override.isEmpty()) - return override; + { + std::lock_guard<StaticLock> lock(userPreferredLanguagesMutex); + Vector<String>& override = preferredLanguagesOverride(); + if (!override.isEmpty()) + return isolatedCopy(override); + } + registerLanguageDidChangeCallbackIfNecessary(); return platformUserPreferredLanguages(); } static String canonicalLanguageIdentifier(const String& languageCode) { - String lowercaseLanguageCode = languageCode.lower(); + String lowercaseLanguageCode = languageCode.convertToASCIILowercase(); if (lowercaseLanguageCode.length() >= 3 && lowercaseLanguageCode[2] == '_') lowercaseLanguageCode.replace(2, 1, "-"); @@ -105,22 +134,25 @@ static String canonicalLanguageIdentifier(const String& languageCode) return lowercaseLanguageCode; } -size_t indexOfBestMatchingLanguageInList(const String& language, const Vector<String>& languageList) +size_t indexOfBestMatchingLanguageInList(const String& language, const Vector<String>& languageList, bool& exactMatch) { + String lowercaseLanguage = language.convertToASCIILowercase(); String languageWithoutLocaleMatch; String languageMatchButNotLocale; size_t languageWithoutLocaleMatchIndex = 0; size_t languageMatchButNotLocaleMatchIndex = 0; - bool canMatchLanguageOnly = (language.length() == 2 || (language.length() >= 3 && language[2] == '-')); + bool canMatchLanguageOnly = (lowercaseLanguage.length() == 2 || (lowercaseLanguage.length() >= 3 && lowercaseLanguage[2] == '-')); for (size_t i = 0; i < languageList.size(); ++i) { String canonicalizedLanguageFromList = canonicalLanguageIdentifier(languageList[i]); - if (language == canonicalizedLanguageFromList) + if (lowercaseLanguage == canonicalizedLanguageFromList) { + exactMatch = true; return i; + } if (canMatchLanguageOnly && canonicalizedLanguageFromList.length() >= 2) { - if (language[0] == canonicalizedLanguageFromList[0] && language[1] == canonicalizedLanguageFromList[1]) { + if (lowercaseLanguage[0] == canonicalizedLanguageFromList[0] && lowercaseLanguage[1] == canonicalizedLanguageFromList[1]) { if (!languageWithoutLocaleMatch.length() && canonicalizedLanguageFromList.length() == 2) { languageWithoutLocaleMatch = languageList[i]; languageWithoutLocaleMatchIndex = i; @@ -133,6 +165,8 @@ size_t indexOfBestMatchingLanguageInList(const String& language, const Vector<St } } + exactMatch = false; + // If we have both a language-only match and a languge-but-not-locale match, return the // languge-only match as is considered a "better" match. For example, if the list // provided has both "en-GB" and "en" and the user prefers "en-US" we will return "en". @@ -147,11 +181,9 @@ size_t indexOfBestMatchingLanguageInList(const String& language, const Vector<St String displayNameForLanguageLocale(const String& localeName) { -#if PLATFORM(MAC) - if (!localeName.isNull() && !localeName.isEmpty()) { - RetainPtr<CFLocaleRef> currentLocale = adoptCF(CFLocaleCopyCurrent()); - return CFLocaleCopyDisplayNameForPropertyValue(currentLocale.get(), kCFLocaleIdentifier, localeName.createCFString().get()); - } +#if USE(CF) && !PLATFORM(WIN) + if (!localeName.isEmpty()) + return adoptCF(CFLocaleCopyDisplayNameForPropertyValue(adoptCF(CFLocaleCopyCurrent()).get(), kCFLocaleIdentifier, localeName.createCFString().get())).get(); #endif return localeName; } |