1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/encoding/FallbackEncoding.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,168 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "mozilla/dom/FallbackEncoding.h" 1.9 + 1.10 +#include "mozilla/dom/EncodingUtils.h" 1.11 +#include "nsUConvPropertySearch.h" 1.12 +#include "nsIChromeRegistry.h" 1.13 +#include "mozilla/Preferences.h" 1.14 +#include "mozilla/Services.h" 1.15 + 1.16 +namespace mozilla { 1.17 +namespace dom { 1.18 + 1.19 +static const char* localesFallbacks[][3] = { 1.20 +#include "localesfallbacks.properties.h" 1.21 +}; 1.22 + 1.23 +static const char* domainsFallbacks[][3] = { 1.24 +#include "domainsfallbacks.properties.h" 1.25 +}; 1.26 + 1.27 +static const char* nonParticipatingDomains[][3] = { 1.28 +#include "nonparticipatingdomains.properties.h" 1.29 +}; 1.30 + 1.31 +FallbackEncoding* FallbackEncoding::sInstance = nullptr; 1.32 +bool FallbackEncoding::sGuessFallbackFromTopLevelDomain = true; 1.33 + 1.34 +FallbackEncoding::FallbackEncoding() 1.35 +{ 1.36 + MOZ_COUNT_CTOR(FallbackEncoding); 1.37 + MOZ_ASSERT(!FallbackEncoding::sInstance, 1.38 + "Singleton already exists."); 1.39 +} 1.40 + 1.41 +FallbackEncoding::~FallbackEncoding() 1.42 +{ 1.43 + MOZ_COUNT_DTOR(FallbackEncoding); 1.44 +} 1.45 + 1.46 +void 1.47 +FallbackEncoding::Get(nsACString& aFallback) 1.48 +{ 1.49 + if (!mFallback.IsEmpty()) { 1.50 + aFallback = mFallback; 1.51 + return; 1.52 + } 1.53 + 1.54 + const nsAdoptingCString& override = 1.55 + Preferences::GetCString("intl.charset.fallback.override"); 1.56 + // Don't let the user break things by setting the override to unreasonable 1.57 + // values via about:config 1.58 + if (!EncodingUtils::FindEncodingForLabel(override, mFallback) || 1.59 + !EncodingUtils::IsAsciiCompatible(mFallback) || 1.60 + mFallback.EqualsLiteral("UTF-8")) { 1.61 + mFallback.Truncate(); 1.62 + } 1.63 + 1.64 + if (!mFallback.IsEmpty()) { 1.65 + aFallback = mFallback; 1.66 + return; 1.67 + } 1.68 + 1.69 + nsAutoCString locale; 1.70 + nsCOMPtr<nsIXULChromeRegistry> registry = 1.71 + mozilla::services::GetXULChromeRegistryService(); 1.72 + if (registry) { 1.73 + registry->GetSelectedLocale(NS_LITERAL_CSTRING("global"), locale); 1.74 + } 1.75 + 1.76 + // Let's lower case the string just in case unofficial language packs 1.77 + // don't stick to conventions. 1.78 + ToLowerCase(locale); // ASCII lowercasing with CString input! 1.79 + 1.80 + // Special case Traditional Chinese before throwing away stuff after the 1.81 + // language itself. Today we only ship zh-TW, but be defensive about 1.82 + // possible future values. 1.83 + if (locale.EqualsLiteral("zh-tw") || 1.84 + locale.EqualsLiteral("zh-hk") || 1.85 + locale.EqualsLiteral("zh-mo") || 1.86 + locale.EqualsLiteral("zh-hant")) { 1.87 + mFallback.AssignLiteral("Big5"); 1.88 + aFallback = mFallback; 1.89 + return; 1.90 + } 1.91 + 1.92 + // Throw away regions and other variants to accommodate weird stuff seen 1.93 + // in telemetry--apparently unofficial language packs. 1.94 + int32_t index = locale.FindChar('-'); 1.95 + if (index >= 0) { 1.96 + locale.Truncate(index); 1.97 + } 1.98 + 1.99 + if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue( 1.100 + localesFallbacks, ArrayLength(localesFallbacks), locale, mFallback))) { 1.101 + mFallback.AssignLiteral("windows-1252"); 1.102 + } 1.103 + 1.104 + aFallback = mFallback; 1.105 +} 1.106 + 1.107 +void 1.108 +FallbackEncoding::FromLocale(nsACString& aFallback) 1.109 +{ 1.110 + MOZ_ASSERT(FallbackEncoding::sInstance, 1.111 + "Using uninitialized fallback cache."); 1.112 + FallbackEncoding::sInstance->Get(aFallback); 1.113 +} 1.114 + 1.115 +// PrefChangedFunc 1.116 +void 1.117 +FallbackEncoding::PrefChanged(const char*, void*) 1.118 +{ 1.119 + MOZ_ASSERT(FallbackEncoding::sInstance, 1.120 + "Pref callback called with null fallback cache."); 1.121 + FallbackEncoding::sInstance->Invalidate(); 1.122 +} 1.123 + 1.124 +void 1.125 +FallbackEncoding::Initialize() 1.126 +{ 1.127 + MOZ_ASSERT(!FallbackEncoding::sInstance, 1.128 + "Initializing pre-existing fallback cache."); 1.129 + FallbackEncoding::sInstance = new FallbackEncoding; 1.130 + Preferences::RegisterCallback(FallbackEncoding::PrefChanged, 1.131 + "intl.charset.fallback.override", 1.132 + nullptr); 1.133 + Preferences::RegisterCallback(FallbackEncoding::PrefChanged, 1.134 + "general.useragent.locale", 1.135 + nullptr); 1.136 + Preferences::AddBoolVarCache(&sGuessFallbackFromTopLevelDomain, 1.137 + "intl.charset.fallback.tld"); 1.138 +} 1.139 + 1.140 +void 1.141 +FallbackEncoding::Shutdown() 1.142 +{ 1.143 + MOZ_ASSERT(FallbackEncoding::sInstance, 1.144 + "Releasing non-existent fallback cache."); 1.145 + delete FallbackEncoding::sInstance; 1.146 + FallbackEncoding::sInstance = nullptr; 1.147 +} 1.148 + 1.149 +bool 1.150 +FallbackEncoding::IsParticipatingTopLevelDomain(const nsACString& aTLD) 1.151 +{ 1.152 + nsAutoCString dummy; 1.153 + return NS_FAILED(nsUConvPropertySearch::SearchPropertyValue( 1.154 + nonParticipatingDomains, 1.155 + ArrayLength(nonParticipatingDomains), 1.156 + aTLD, 1.157 + dummy)); 1.158 +} 1.159 + 1.160 +void 1.161 +FallbackEncoding::FromTopLevelDomain(const nsACString& aTLD, 1.162 + nsACString& aFallback) 1.163 +{ 1.164 + if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue( 1.165 + domainsFallbacks, ArrayLength(domainsFallbacks), aTLD, aFallback))) { 1.166 + aFallback.AssignLiteral("windows-1252"); 1.167 + } 1.168 +} 1.169 + 1.170 +} // namespace dom 1.171 +} // namespace mozilla