Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: chrome/browser/character_encoding.cc

Issue 2254273003: Remove text encoding UI (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/character_encoding.h ('k') | chrome/browser/character_encoding_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/character_encoding.h" 5 #include "chrome/browser/character_encoding.h"
6 6
7 #include <stddef.h>
8
9 #include <map>
10 #include <memory>
11 #include <set>
12
13 #include "base/logging.h"
14 #include "base/macros.h" 7 #include "base/macros.h"
15 #include "base/strings/string_tokenizer.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "chrome/app/chrome_command_ids.h"
19 #include "chrome/grit/generated_resources.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "third_party/icu/source/common/unicode/ucnv.h" 8 #include "third_party/icu/source/common/unicode/ucnv.h"
22 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/base/l10n/l10n_util_collator.h"
24
25 using content::BrowserThread;
26 9
27 namespace { 10 namespace {
28 11
29 // The maximum length of short list of recently user selected encodings is 3. 12 // An array of all supported canonical encoding names.
30 const size_t kUserSelectedEncodingsMaxLength = 3; 13 const char* const kCanonicalEncodingNames[] = {
14 "Big5",
15 "EUC-JP",
16 "EUC-KR",
17 "gb18030",
18 "GBK",
19 "IBM866",
20 "ISO-2022-JP",
21 "ISO-8859-10",
22 "ISO-8859-13",
23 "ISO-8859-14",
24 "ISO-8859-15",
25 "ISO-8859-16",
26 "ISO-8859-2",
27 "ISO-8859-3",
28 "ISO-8859-4",
29 "ISO-8859-5",
30 "ISO-8859-6",
31 "ISO-8859-7",
32 "ISO-8859-8",
33 "ISO-8859-8-I",
34 "KOI8-R",
35 "KOI8-U",
36 "macintosh",
37 "Shift_JIS",
38 "UTF-16LE",
39 "UTF-8",
40 "windows-1250",
41 "windows-1251",
42 "windows-1252",
43 "windows-1253",
44 "windows-1254",
45 "windows-1255",
46 "windows-1256",
47 "windows-1257",
48 "windows-1258",
49 "windows-874"
50 };
51 } // namespace
31 52
32 typedef struct { 53 std::string GetCanonicalEncodingNameByAliasName(const std::string& alias_name) {
33 int resource_id; 54 for (size_t i = 0; i < arraysize(kCanonicalEncodingNames); ++i) {
34 const char* name; 55 if (alias_name == kCanonicalEncodingNames[i])
35 int category_string_id; 56 return alias_name;
36 } CanonicalEncodingData;
37
38 // An array of all supported canonical encoding names.
39 const CanonicalEncodingData kCanonicalEncodingNames[] = {
40 { IDC_ENCODING_UTF8, "UTF-8", IDS_ENCODING_UNICODE },
41 { IDC_ENCODING_UTF16LE, "UTF-16LE", IDS_ENCODING_UNICODE },
42 { IDC_ENCODING_WINDOWS1252, "windows-1252", IDS_ENCODING_WESTERN },
43 { IDC_ENCODING_GBK, "GBK", IDS_ENCODING_SIMP_CHINESE },
44 { IDC_ENCODING_GB18030, "gb18030", IDS_ENCODING_SIMP_CHINESE },
45 { IDC_ENCODING_BIG5, "Big5", IDS_ENCODING_TRAD_CHINESE },
46 { IDC_ENCODING_KOREAN, "EUC-KR", IDS_ENCODING_KOREAN },
47 { IDC_ENCODING_SHIFTJIS, "Shift_JIS", IDS_ENCODING_JAPANESE },
48 { IDC_ENCODING_EUCJP, "EUC-JP", IDS_ENCODING_JAPANESE },
49 { IDC_ENCODING_ISO2022JP, "ISO-2022-JP", IDS_ENCODING_JAPANESE },
50 { IDC_ENCODING_THAI, "windows-874", IDS_ENCODING_THAI },
51 { IDC_ENCODING_ISO885915, "ISO-8859-15", IDS_ENCODING_WESTERN },
52 { IDC_ENCODING_MACINTOSH, "macintosh", IDS_ENCODING_WESTERN },
53 { IDC_ENCODING_ISO88592, "ISO-8859-2", IDS_ENCODING_CENTRAL_EUROPEAN },
54 { IDC_ENCODING_WINDOWS1250, "windows-1250", IDS_ENCODING_CENTRAL_EUROPEAN },
55 { IDC_ENCODING_ISO88595, "ISO-8859-5", IDS_ENCODING_CYRILLIC },
56 { IDC_ENCODING_WINDOWS1251, "windows-1251", IDS_ENCODING_CYRILLIC },
57 { IDC_ENCODING_KOI8R, "KOI8-R", IDS_ENCODING_CYRILLIC },
58 { IDC_ENCODING_KOI8U, "KOI8-U", IDS_ENCODING_CYRILLIC },
59 { IDC_ENCODING_IBM866, "IBM866", IDS_ENCODING_CYRILLIC },
60 { IDC_ENCODING_ISO88597, "ISO-8859-7", IDS_ENCODING_GREEK },
61 { IDC_ENCODING_WINDOWS1253, "windows-1253", IDS_ENCODING_GREEK },
62 { IDC_ENCODING_WINDOWS1254, "windows-1254", IDS_ENCODING_TURKISH },
63 { IDC_ENCODING_WINDOWS1256, "windows-1256", IDS_ENCODING_ARABIC },
64 { IDC_ENCODING_ISO88596, "ISO-8859-6", IDS_ENCODING_ARABIC },
65 { IDC_ENCODING_WINDOWS1255, "windows-1255", IDS_ENCODING_HEBREW },
66 { IDC_ENCODING_ISO88598I, "ISO-8859-8-I", IDS_ENCODING_HEBREW },
67 { IDC_ENCODING_ISO88598, "ISO-8859-8", IDS_ENCODING_HEBREW },
68 { IDC_ENCODING_WINDOWS1258, "windows-1258", IDS_ENCODING_VIETNAMESE },
69 { IDC_ENCODING_ISO88594, "ISO-8859-4", IDS_ENCODING_BALTIC },
70 { IDC_ENCODING_ISO885913, "ISO-8859-13", IDS_ENCODING_BALTIC },
71 { IDC_ENCODING_WINDOWS1257, "windows-1257", IDS_ENCODING_BALTIC },
72 { IDC_ENCODING_ISO88593, "ISO-8859-3", IDS_ENCODING_SOUTH_EUROPEAN },
73 { IDC_ENCODING_ISO885910, "ISO-8859-10", IDS_ENCODING_NORDIC },
74 { IDC_ENCODING_ISO885914, "ISO-8859-14", IDS_ENCODING_CELTIC },
75 { IDC_ENCODING_ISO885916, "ISO-8859-16", IDS_ENCODING_ROMANIAN },
76 };
77
78 const int kCanonicalEncodingNamesLength = arraysize(kCanonicalEncodingNames);
79
80 typedef std::map<int, std::pair<const char*, int> >
81 IdToCanonicalEncodingNameMapType;
82 typedef std::map<const std::string, int> CanonicalEncodingNameToIdMapType;
83
84 typedef struct {
85 const char* canonical_form;
86 const char* display_form;
87 } CanonicalEncodingDisplayNamePair;
88
89 const CanonicalEncodingDisplayNamePair kCanonicalDisplayNameOverrides[] = {
90 // Only lists the canonical names where we want a different form for display.
91 { "macintosh", "Macintosh" },
92 { "windows-874", "Windows-874" },
93 { "windows-1250", "Windows-1250" },
94 { "windows-1251", "Windows-1251" },
95 { "windows-1252", "Windows-1252" },
96 { "windows-1253", "Windows-1253" },
97 { "windows-1254", "Windows-1254" },
98 { "windows-1255", "Windows-1255" },
99 { "windows-1256", "Windows-1256" },
100 { "windows-1257", "Windows-1257" },
101 { "windows-1258", "Windows-1258" },
102 };
103
104 const int kCanonicalDisplayNameOverridesLength =
105 arraysize(kCanonicalDisplayNameOverrides);
106
107 typedef std::map<std::string, const char*> CanonicalNameDisplayNameMapType;
108
109 class CanonicalEncodingMap {
110 public:
111 CanonicalEncodingMap() {}
112 const IdToCanonicalEncodingNameMapType* GetIdToCanonicalEncodingNameMapData();
113 const CanonicalEncodingNameToIdMapType* GetCanonicalEncodingNameToIdMapData();
114 const CanonicalNameDisplayNameMapType* GetCanonicalNameDisplayNameMapData();
115 std::vector<int>* locale_dependent_encoding_ids() {
116 return &locale_dependent_encoding_ids_;
117 } 57 }
118
119 std::vector<CharacterEncoding::EncodingInfo>* current_display_encodings() {
120 return &current_display_encodings_;
121 }
122
123 private:
124 std::unique_ptr<IdToCanonicalEncodingNameMapType> id_to_encoding_name_map_;
125 std::unique_ptr<CanonicalEncodingNameToIdMapType> encoding_name_to_id_map_;
126 std::unique_ptr<CanonicalNameDisplayNameMapType>
127 encoding_name_to_display_name_map_;
128 std::vector<int> locale_dependent_encoding_ids_;
129 std::vector<CharacterEncoding::EncodingInfo> current_display_encodings_;
130
131 DISALLOW_COPY_AND_ASSIGN(CanonicalEncodingMap);
132 };
133
134 const IdToCanonicalEncodingNameMapType*
135 CanonicalEncodingMap::GetIdToCanonicalEncodingNameMapData() {
136 // Testing and building map is not thread safe, this function is supposed to
137 // only run in UI thread. Myabe I should add a lock in here for making it as
138 // thread safe.
139 if (!id_to_encoding_name_map_.get()) {
140 id_to_encoding_name_map_.reset(new IdToCanonicalEncodingNameMapType);
141 for (int i = 0; i < kCanonicalEncodingNamesLength; ++i) {
142 int resource_id = kCanonicalEncodingNames[i].resource_id;
143 (*id_to_encoding_name_map_)[resource_id] =
144 std::make_pair(kCanonicalEncodingNames[i].name,
145 kCanonicalEncodingNames[i].category_string_id);
146 }
147 }
148 return id_to_encoding_name_map_.get();
149 }
150
151 const CanonicalEncodingNameToIdMapType*
152 CanonicalEncodingMap::GetCanonicalEncodingNameToIdMapData() {
153 if (!encoding_name_to_id_map_.get()) {
154 encoding_name_to_id_map_.reset(new CanonicalEncodingNameToIdMapType);
155 for (int i = 0; i < kCanonicalEncodingNamesLength; ++i) {
156 (*encoding_name_to_id_map_)[kCanonicalEncodingNames[i].name] =
157 kCanonicalEncodingNames[i].resource_id;
158 }
159 }
160 return encoding_name_to_id_map_.get();
161 }
162
163 const CanonicalNameDisplayNameMapType*
164 CanonicalEncodingMap::GetCanonicalNameDisplayNameMapData() {
165 if (!encoding_name_to_display_name_map_.get()) {
166 encoding_name_to_display_name_map_.reset(
167 new CanonicalNameDisplayNameMapType);
168 // First store the names in the kCanonicalEncodingNames list.
169 for (int i = 0; i < kCanonicalEncodingNamesLength; ++i) {
170 (*encoding_name_to_display_name_map_)[kCanonicalEncodingNames[i].name] =
171 kCanonicalEncodingNames[i].name;
172 }
173 // Then save in the overrides.
174 for (int i = 0; i < kCanonicalDisplayNameOverridesLength; ++i) {
175 (*encoding_name_to_display_name_map_)
176 [kCanonicalDisplayNameOverrides[i].canonical_form] =
177 kCanonicalDisplayNameOverrides[i].display_form;
178 }
179 DCHECK(static_cast<int>(encoding_name_to_display_name_map_->size()) ==
180 kCanonicalEncodingNamesLength)
181 << "Got an override that wasn't in the encoding list";
182 }
183 return encoding_name_to_display_name_map_.get();
184 }
185
186 // A static map object which contains all resourceid-nonsequenced canonical
187 // encoding names.
188 CanonicalEncodingMap* CanonicalEncodingMapSingleton() {
189 DCHECK_CURRENTLY_ON(BrowserThread::UI);
190 static CanonicalEncodingMap* singleton = new CanonicalEncodingMap;
191 return singleton;
192 }
193
194 const int kDefaultEncodingMenus[] = {
195 IDC_ENCODING_UTF16LE,
196 IDC_ENCODING_WINDOWS1252,
197 IDC_ENCODING_GBK,
198 IDC_ENCODING_GB18030,
199 IDC_ENCODING_BIG5,
200 IDC_ENCODING_KOREAN,
201 IDC_ENCODING_SHIFTJIS,
202 IDC_ENCODING_EUCJP,
203 IDC_ENCODING_ISO2022JP,
204 IDC_ENCODING_THAI,
205 IDC_ENCODING_ISO885915,
206 IDC_ENCODING_MACINTOSH,
207 IDC_ENCODING_ISO88592,
208 IDC_ENCODING_WINDOWS1250,
209 IDC_ENCODING_ISO88595,
210 IDC_ENCODING_WINDOWS1251,
211 IDC_ENCODING_KOI8R,
212 IDC_ENCODING_KOI8U,
213 IDC_ENCODING_IBM866,
214 IDC_ENCODING_ISO88597,
215 IDC_ENCODING_WINDOWS1253,
216 IDC_ENCODING_WINDOWS1254,
217 IDC_ENCODING_WINDOWS1256,
218 IDC_ENCODING_ISO88596,
219 IDC_ENCODING_WINDOWS1255,
220 IDC_ENCODING_ISO88598I,
221 IDC_ENCODING_ISO88598,
222 IDC_ENCODING_WINDOWS1258,
223 IDC_ENCODING_ISO88594,
224 IDC_ENCODING_ISO885913,
225 IDC_ENCODING_WINDOWS1257,
226 IDC_ENCODING_ISO88593,
227 IDC_ENCODING_ISO885910,
228 IDC_ENCODING_ISO885914,
229 IDC_ENCODING_ISO885916,
230 };
231
232 const int kDefaultEncodingMenusLength = arraysize(kDefaultEncodingMenus);
233
234 // Parse the input |encoding_list| which is a encoding list separated with
235 // comma, get available encoding ids and save them to |available_list|.
236 // The parameter |maximum_size| indicates maximum size of encoding items we
237 // want to get from the |encoding_list|.
238 void ParseEncodingListSeparatedWithComma(
239 const std::string& encoding_list, std::vector<int>* const available_list,
240 size_t maximum_size) {
241 base::StringTokenizer tokenizer(encoding_list, ",");
242 while (tokenizer.GetNext()) {
243 int id = CharacterEncoding::GetCommandIdByCanonicalEncodingName(
244 tokenizer.token());
245 // Ignore invalid encoding.
246 if (!id)
247 continue;
248 available_list->push_back(id);
249 if (available_list->size() == maximum_size)
250 return;
251 }
252 }
253
254 base::string16 GetEncodingDisplayName(const std::string& encoding_name,
255 int category_string_id) {
256 base::string16 category_name = l10n_util::GetStringUTF16(category_string_id);
257 if (category_string_id != IDS_ENCODING_KOREAN &&
258 category_string_id != IDS_ENCODING_THAI &&
259 category_string_id != IDS_ENCODING_TURKISH &&
260 category_string_id != IDS_ENCODING_VIETNAMESE &&
261 category_string_id != IDS_ENCODING_ROMANIAN) {
262 const CanonicalNameDisplayNameMapType* map =
263 CanonicalEncodingMapSingleton()->GetCanonicalNameDisplayNameMapData();
264 DCHECK(map);
265
266 CanonicalNameDisplayNameMapType::const_iterator found_name =
267 map->find(encoding_name);
268 DCHECK(found_name != map->end());
269 return l10n_util::GetStringFUTF16(IDS_ENCODING_DISPLAY_TEMPLATE,
270 category_name,
271 base::ASCIIToUTF16(found_name->second));
272 }
273 return category_name;
274 }
275
276 int GetEncodingCategoryStringIdByCommandId(int id) {
277 const IdToCanonicalEncodingNameMapType* map =
278 CanonicalEncodingMapSingleton()->GetIdToCanonicalEncodingNameMapData();
279 DCHECK(map);
280
281 IdToCanonicalEncodingNameMapType::const_iterator found_name = map->find(id);
282 if (found_name != map->end())
283 return found_name->second.second;
284 return 0;
285 }
286
287 std::string GetEncodingCategoryStringByCommandId(int id) {
288 int category_id = GetEncodingCategoryStringIdByCommandId(id);
289 if (category_id)
290 return l10n_util::GetStringUTF8(category_id);
291 return std::string();
292 }
293
294 } // namespace
295
296 CharacterEncoding::EncodingInfo::EncodingInfo(int id)
297 : encoding_id(id) {
298 encoding_category_name =
299 base::UTF8ToUTF16(GetEncodingCategoryStringByCommandId(id));
300 encoding_display_name = GetCanonicalEncodingDisplayNameByCommandId(id);
301 }
302
303 // Static.
304 int CharacterEncoding::GetCommandIdByCanonicalEncodingName(
305 const std::string& encoding_name) {
306 const CanonicalEncodingNameToIdMapType* map =
307 CanonicalEncodingMapSingleton()->GetCanonicalEncodingNameToIdMapData();
308 DCHECK(map);
309
310 CanonicalEncodingNameToIdMapType::const_iterator found_id =
311 map->find(encoding_name);
312 if (found_id != map->end())
313 return found_id->second;
314 return 0;
315 }
316
317 // Static.
318 std::string CharacterEncoding::GetCanonicalEncodingNameByCommandId(int id) {
319 const IdToCanonicalEncodingNameMapType* map =
320 CanonicalEncodingMapSingleton()->GetIdToCanonicalEncodingNameMapData();
321 DCHECK(map);
322
323 IdToCanonicalEncodingNameMapType::const_iterator found_name = map->find(id);
324 if (found_name != map->end())
325 return found_name->second.first;
326 return std::string();
327 }
328
329 // Static.
330 base::string16 CharacterEncoding::GetCanonicalEncodingDisplayNameByCommandId(
331 int id) {
332 const IdToCanonicalEncodingNameMapType* map =
333 CanonicalEncodingMapSingleton()->GetIdToCanonicalEncodingNameMapData();
334 DCHECK(map);
335
336 IdToCanonicalEncodingNameMapType::const_iterator found_name = map->find(id);
337 if (found_name != map->end())
338 return GetEncodingDisplayName(found_name->second.first,
339 found_name->second.second);
340 return base::string16();
341 }
342
343 // Static.
344 // Return count number of all supported canonical encoding.
345 int CharacterEncoding::GetSupportCanonicalEncodingCount() {
346 return kCanonicalEncodingNamesLength;
347 }
348
349 // Static.
350 std::string CharacterEncoding::GetCanonicalEncodingNameByIndex(int index) {
351 if (index < kCanonicalEncodingNamesLength)
352 return kCanonicalEncodingNames[index].name;
353 return std::string();
354 }
355
356 // Static.
357 base::string16 CharacterEncoding::GetCanonicalEncodingDisplayNameByIndex(
358 int index) {
359 if (index < kCanonicalEncodingNamesLength)
360 return GetEncodingDisplayName(kCanonicalEncodingNames[index].name,
361 kCanonicalEncodingNames[index].category_string_id);
362 return base::string16();
363 }
364
365 // Static.
366 int CharacterEncoding::GetEncodingCommandIdByIndex(int index) {
367 if (index < kCanonicalEncodingNamesLength)
368 return kCanonicalEncodingNames[index].resource_id;
369 return 0;
370 }
371
372 // Static.
373 std::string CharacterEncoding::GetCanonicalEncodingNameByAliasName(
374 const std::string& alias_name) {
375 // If the input alias_name is already canonical encoding name, just return it.
376 const CanonicalEncodingNameToIdMapType* map =
377 CanonicalEncodingMapSingleton()->GetCanonicalEncodingNameToIdMapData();
378 DCHECK(map);
379
380 CanonicalEncodingNameToIdMapType::const_iterator found_id =
381 map->find(alias_name);
382 if (found_id != map->end())
383 return alias_name;
384
385 const char* standards[3] = { "HTML", "MIME", "IANA" }; 58 const char* standards[3] = { "HTML", "MIME", "IANA" };
386 for (size_t i = 0; i < arraysize(standards); ++i) { 59 for (size_t i = 0; i < arraysize(standards); ++i) {
387 UErrorCode error_code = U_ZERO_ERROR; 60 UErrorCode error_code = U_ZERO_ERROR;
388 const char* canonical_name = ucnv_getCanonicalName( 61 const char* canonical_name = ucnv_getCanonicalName(
389 alias_name.c_str(), standards[i], &error_code); 62 alias_name.c_str(), standards[i], &error_code);
390 if (U_SUCCESS(error_code) && canonical_name) 63 if (U_SUCCESS(error_code) && canonical_name)
391 return canonical_name; 64 return canonical_name;
392 } 65 }
393 return std::string(); 66 return std::string();
394 } 67 }
395
396 // Static
397 // According to the behavior of user recently selected encoding short list in
398 // Firefox, we always put UTF-8 as top position, after then put user
399 // recent selected encodings, then put local dependent encoding items.
400 // At last, we put all remaining encoding items.
401 const std::vector<CharacterEncoding::EncodingInfo>*
402 CharacterEncoding::GetCurrentDisplayEncodings(
403 const std::string& locale,
404 const std::string& locale_encodings,
405 const std::string& recently_select_encodings) {
406 std::vector<int>* const locale_dependent_encoding_list =
407 CanonicalEncodingMapSingleton()->locale_dependent_encoding_ids();
408 std::vector<CharacterEncoding::EncodingInfo>* const encoding_list =
409 CanonicalEncodingMapSingleton()->current_display_encodings();
410
411 // Initialize locale dependent static encoding list.
412 if (locale_dependent_encoding_list->empty() && !locale_encodings.empty())
413 ParseEncodingListSeparatedWithComma(locale_encodings,
414 locale_dependent_encoding_list,
415 kUserSelectedEncodingsMaxLength);
416
417 CR_DEFINE_STATIC_LOCAL(std::string, cached_user_selected_encodings, ());
418 // Build current display encoding list.
419 if (encoding_list->empty() ||
420 cached_user_selected_encodings != recently_select_encodings) {
421 // Update user recently selected encodings.
422 cached_user_selected_encodings = recently_select_encodings;
423 // Clear old encoding list since user recently selected encodings changed.
424 encoding_list->clear();
425 // Always add UTF-8 to first encoding position.
426 encoding_list->push_back(EncodingInfo(IDC_ENCODING_UTF8));
427 std::set<int> inserted_encoding;
428 inserted_encoding.insert(IDC_ENCODING_UTF8);
429
430 // Parse user recently selected encodings and get list
431 std::vector<int> recently_select_encoding_list;
432 ParseEncodingListSeparatedWithComma(recently_select_encodings,
433 &recently_select_encoding_list,
434 kUserSelectedEncodingsMaxLength);
435
436 // Put 'cached encodings' (dynamic encoding list) after 'local dependent
437 // encoding list'.
438 recently_select_encoding_list.insert(recently_select_encoding_list.begin(),
439 locale_dependent_encoding_list->begin(),
440 locale_dependent_encoding_list->end());
441 for (std::vector<int>::iterator it = recently_select_encoding_list.begin();
442 it != recently_select_encoding_list.end(); ++it) {
443 // Test whether we have met this encoding id.
444 bool ok = inserted_encoding.insert(*it).second;
445 // Duplicated encoding, ignore it. Ideally, this situation should not
446 // happened, but just in case some one manually edit preference file.
447 if (!ok)
448 continue;
449 encoding_list->push_back(EncodingInfo(*it));
450 }
451 // Append a separator;
452 encoding_list->push_back(EncodingInfo(0));
453
454 // We need to keep "Unicode (UTF-16LE)" always at the top (among the rest
455 // of encodings) instead of being sorted along with other encodings. So if
456 // "Unicode (UTF-16LE)" is already in previous encodings, sort the rest
457 // of encodings. Otherwise Put "Unicode (UTF-16LE)" on the first of the
458 // rest of encodings, skip "Unicode (UTF-16LE)" and sort all left encodings.
459 int start_sorted_index = encoding_list->size();
460 if (inserted_encoding.find(IDC_ENCODING_UTF16LE) ==
461 inserted_encoding.end()) {
462 encoding_list->push_back(EncodingInfo(IDC_ENCODING_UTF16LE));
463 inserted_encoding.insert(IDC_ENCODING_UTF16LE);
464 start_sorted_index++;
465 }
466
467 // Add the rest of encodings that are neither in the static encoding list
468 // nor in the list of recently selected encodings.
469 // Build the encoding list sorted in the current locale sorting order.
470 for (int i = 0; i < kDefaultEncodingMenusLength; ++i) {
471 int id = kDefaultEncodingMenus[i];
472 // We have inserted this encoding, skip it.
473 if (inserted_encoding.find(id) != inserted_encoding.end())
474 continue;
475 encoding_list->push_back(EncodingInfo(id));
476 }
477 // Sort the encoding list.
478 l10n_util::SortVectorWithStringKey(locale,
479 encoding_list,
480 start_sorted_index,
481 encoding_list->size(),
482 true);
483 }
484 DCHECK(!encoding_list->empty());
485 return encoding_list;
486 }
487
488 // Static
489 bool CharacterEncoding::UpdateRecentlySelectedEncoding(
490 const std::string& original_selected_encodings,
491 int new_selected_encoding_id,
492 std::string* selected_encodings) {
493 // Get encoding name.
494 std::string encoding_name =
495 GetCanonicalEncodingNameByCommandId(new_selected_encoding_id);
496 DCHECK(!encoding_name.empty());
497 // Check whether the new encoding is in local dependent encodings or original
498 // recently selected encodings. If yes, do not add it.
499 std::vector<int>* locale_dependent_encoding_list =
500 CanonicalEncodingMapSingleton()->locale_dependent_encoding_ids();
501 DCHECK(locale_dependent_encoding_list);
502 std::vector<int> selected_encoding_list;
503 ParseEncodingListSeparatedWithComma(original_selected_encodings,
504 &selected_encoding_list,
505 kUserSelectedEncodingsMaxLength);
506 // Put 'cached encodings' (dynamic encoding list) after 'local dependent
507 // encoding list' for check.
508 std::vector<int> top_encoding_list(*locale_dependent_encoding_list);
509 // UTF8 is always in our optimized encoding list.
510 top_encoding_list.insert(top_encoding_list.begin(), IDC_ENCODING_UTF8);
511 top_encoding_list.insert(top_encoding_list.end(),
512 selected_encoding_list.begin(),
513 selected_encoding_list.end());
514 for (std::vector<int>::const_iterator it = top_encoding_list.begin();
515 it != top_encoding_list.end(); ++it)
516 if (*it == new_selected_encoding_id)
517 return false;
518 // Need to add the encoding id to recently selected encoding list.
519 // Remove the last encoding in original list.
520 if (selected_encoding_list.size() == kUserSelectedEncodingsMaxLength)
521 selected_encoding_list.pop_back();
522 // Insert new encoding to head of selected encoding list.
523 *selected_encodings = encoding_name;
524 // Generate the string for rest selected encoding list.
525 for (std::vector<int>::const_iterator it = selected_encoding_list.begin();
526 it != selected_encoding_list.end(); ++it) {
527 selected_encodings->append(1, L',');
528 selected_encodings->append(GetCanonicalEncodingNameByCommandId(*it));
529 }
530 return true;
531 }
OLDNEW
« no previous file with comments | « chrome/browser/character_encoding.h ('k') | chrome/browser/character_encoding_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698