dom/encoding/FallbackEncoding.cpp

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:a13fde5dd5b9
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "mozilla/dom/FallbackEncoding.h"
6
7 #include "mozilla/dom/EncodingUtils.h"
8 #include "nsUConvPropertySearch.h"
9 #include "nsIChromeRegistry.h"
10 #include "mozilla/Preferences.h"
11 #include "mozilla/Services.h"
12
13 namespace mozilla {
14 namespace dom {
15
16 static const char* localesFallbacks[][3] = {
17 #include "localesfallbacks.properties.h"
18 };
19
20 static const char* domainsFallbacks[][3] = {
21 #include "domainsfallbacks.properties.h"
22 };
23
24 static const char* nonParticipatingDomains[][3] = {
25 #include "nonparticipatingdomains.properties.h"
26 };
27
28 FallbackEncoding* FallbackEncoding::sInstance = nullptr;
29 bool FallbackEncoding::sGuessFallbackFromTopLevelDomain = true;
30
31 FallbackEncoding::FallbackEncoding()
32 {
33 MOZ_COUNT_CTOR(FallbackEncoding);
34 MOZ_ASSERT(!FallbackEncoding::sInstance,
35 "Singleton already exists.");
36 }
37
38 FallbackEncoding::~FallbackEncoding()
39 {
40 MOZ_COUNT_DTOR(FallbackEncoding);
41 }
42
43 void
44 FallbackEncoding::Get(nsACString& aFallback)
45 {
46 if (!mFallback.IsEmpty()) {
47 aFallback = mFallback;
48 return;
49 }
50
51 const nsAdoptingCString& override =
52 Preferences::GetCString("intl.charset.fallback.override");
53 // Don't let the user break things by setting the override to unreasonable
54 // values via about:config
55 if (!EncodingUtils::FindEncodingForLabel(override, mFallback) ||
56 !EncodingUtils::IsAsciiCompatible(mFallback) ||
57 mFallback.EqualsLiteral("UTF-8")) {
58 mFallback.Truncate();
59 }
60
61 if (!mFallback.IsEmpty()) {
62 aFallback = mFallback;
63 return;
64 }
65
66 nsAutoCString locale;
67 nsCOMPtr<nsIXULChromeRegistry> registry =
68 mozilla::services::GetXULChromeRegistryService();
69 if (registry) {
70 registry->GetSelectedLocale(NS_LITERAL_CSTRING("global"), locale);
71 }
72
73 // Let's lower case the string just in case unofficial language packs
74 // don't stick to conventions.
75 ToLowerCase(locale); // ASCII lowercasing with CString input!
76
77 // Special case Traditional Chinese before throwing away stuff after the
78 // language itself. Today we only ship zh-TW, but be defensive about
79 // possible future values.
80 if (locale.EqualsLiteral("zh-tw") ||
81 locale.EqualsLiteral("zh-hk") ||
82 locale.EqualsLiteral("zh-mo") ||
83 locale.EqualsLiteral("zh-hant")) {
84 mFallback.AssignLiteral("Big5");
85 aFallback = mFallback;
86 return;
87 }
88
89 // Throw away regions and other variants to accommodate weird stuff seen
90 // in telemetry--apparently unofficial language packs.
91 int32_t index = locale.FindChar('-');
92 if (index >= 0) {
93 locale.Truncate(index);
94 }
95
96 if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
97 localesFallbacks, ArrayLength(localesFallbacks), locale, mFallback))) {
98 mFallback.AssignLiteral("windows-1252");
99 }
100
101 aFallback = mFallback;
102 }
103
104 void
105 FallbackEncoding::FromLocale(nsACString& aFallback)
106 {
107 MOZ_ASSERT(FallbackEncoding::sInstance,
108 "Using uninitialized fallback cache.");
109 FallbackEncoding::sInstance->Get(aFallback);
110 }
111
112 // PrefChangedFunc
113 void
114 FallbackEncoding::PrefChanged(const char*, void*)
115 {
116 MOZ_ASSERT(FallbackEncoding::sInstance,
117 "Pref callback called with null fallback cache.");
118 FallbackEncoding::sInstance->Invalidate();
119 }
120
121 void
122 FallbackEncoding::Initialize()
123 {
124 MOZ_ASSERT(!FallbackEncoding::sInstance,
125 "Initializing pre-existing fallback cache.");
126 FallbackEncoding::sInstance = new FallbackEncoding;
127 Preferences::RegisterCallback(FallbackEncoding::PrefChanged,
128 "intl.charset.fallback.override",
129 nullptr);
130 Preferences::RegisterCallback(FallbackEncoding::PrefChanged,
131 "general.useragent.locale",
132 nullptr);
133 Preferences::AddBoolVarCache(&sGuessFallbackFromTopLevelDomain,
134 "intl.charset.fallback.tld");
135 }
136
137 void
138 FallbackEncoding::Shutdown()
139 {
140 MOZ_ASSERT(FallbackEncoding::sInstance,
141 "Releasing non-existent fallback cache.");
142 delete FallbackEncoding::sInstance;
143 FallbackEncoding::sInstance = nullptr;
144 }
145
146 bool
147 FallbackEncoding::IsParticipatingTopLevelDomain(const nsACString& aTLD)
148 {
149 nsAutoCString dummy;
150 return NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
151 nonParticipatingDomains,
152 ArrayLength(nonParticipatingDomains),
153 aTLD,
154 dummy));
155 }
156
157 void
158 FallbackEncoding::FromTopLevelDomain(const nsACString& aTLD,
159 nsACString& aFallback)
160 {
161 if (NS_FAILED(nsUConvPropertySearch::SearchPropertyValue(
162 domainsFallbacks, ArrayLength(domainsFallbacks), aTLD, aFallback))) {
163 aFallback.AssignLiteral("windows-1252");
164 }
165 }
166
167 } // namespace dom
168 } // namespace mozilla

mercurial