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

Side by Side Diff: extensions/common/extension_l10n_util.cc

Issue 228073005: Move core extensions l10n code to //extensions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: unused header is unused Created 6 years, 8 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 | Annotate | Revision Log
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/common/extensions/extension_l10n_util.h" 5 #include "extensions/common/extension_l10n_util.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/files/file_enumerator.h" 13 #include "base/files/file_enumerator.h"
14 #include "base/json/json_file_value_serializer.h" 14 #include "base/json/json_file_value_serializer.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/linked_ptr.h" 16 #include "base/memory/linked_ptr.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h" 19 #include "base/values.h"
20 #include "chrome/common/extensions/extension_file_util.h"
21 #include "chrome/common/extensions/message_bundle.h"
22 #include "chrome/common/url_constants.h"
23 #include "extensions/common/constants.h" 20 #include "extensions/common/constants.h"
24 #include "extensions/common/error_utils.h" 21 #include "extensions/common/error_utils.h"
22 #include "extensions/common/file_util.h"
25 #include "extensions/common/manifest_constants.h" 23 #include "extensions/common/manifest_constants.h"
24 #include "extensions/common/message_bundle.h"
26 #include "third_party/icu/source/common/unicode/uloc.h" 25 #include "third_party/icu/source/common/unicode/uloc.h"
27 #include "ui/base/l10n/l10n_util.h" 26 #include "ui/base/l10n/l10n_util.h"
28 27
29 namespace errors = extensions::manifest_errors; 28 namespace errors = extensions::manifest_errors;
30 namespace keys = extensions::manifest_keys; 29 namespace keys = extensions::manifest_keys;
31 30
32 namespace { 31 namespace {
33 32
34 // Loads contents of the messages file for given locale. If file is not found, 33 // Loads contents of the messages file for given locale. If file is not found,
35 // or there was parsing error we return NULL and set |error|. 34 // or there was parsing error we return NULL and set |error|.
36 // Caller owns the returned object. 35 // Caller owns the returned object.
37 base::DictionaryValue* LoadMessageFile(const base::FilePath& locale_path, 36 base::DictionaryValue* LoadMessageFile(const base::FilePath& locale_path,
38 const std::string& locale, 37 const std::string& locale,
39 std::string* error) { 38 std::string* error) {
40 base::FilePath file = locale_path.AppendASCII(locale) 39 base::FilePath file =
41 .Append(extensions::kMessagesFilename); 40 locale_path.AppendASCII(locale).Append(extensions::kMessagesFilename);
42 JSONFileValueSerializer messages_serializer(file); 41 JSONFileValueSerializer messages_serializer(file);
43 base::Value* dictionary = messages_serializer.Deserialize(NULL, error); 42 base::Value* dictionary = messages_serializer.Deserialize(NULL, error);
44 if (!dictionary) { 43 if (!dictionary) {
45 if (error->empty()) { 44 if (error->empty()) {
46 // JSONFileValueSerializer just returns NULL if file cannot be found. It 45 // JSONFileValueSerializer just returns NULL if file cannot be found. It
47 // doesn't set the error, so we have to do it. 46 // doesn't set the error, so we have to do it.
48 *error = base::StringPrintf("Catalog file is missing for locale %s.", 47 *error = base::StringPrintf("Catalog file is missing for locale %s.",
49 locale.c_str()); 48 locale.c_str());
50 } else { 49 } else {
51 *error = extensions::ErrorUtils::FormatErrorMessage( 50 *error = extensions::ErrorUtils::FormatErrorMessage(
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 171
173 base::ListValue* file_handlers = NULL; 172 base::ListValue* file_handlers = NULL;
174 if (manifest->GetList(keys::kFileBrowserHandlers, &file_handlers)) { 173 if (manifest->GetList(keys::kFileBrowserHandlers, &file_handlers)) {
175 key.assign(keys::kFileBrowserHandlers); 174 key.assign(keys::kFileBrowserHandlers);
176 for (size_t i = 0; i < file_handlers->GetSize(); i++) { 175 for (size_t i = 0; i < file_handlers->GetSize(); i++) {
177 base::DictionaryValue* handler = NULL; 176 base::DictionaryValue* handler = NULL;
178 if (!file_handlers->GetDictionary(i, &handler)) { 177 if (!file_handlers->GetDictionary(i, &handler)) {
179 *error = errors::kInvalidFileBrowserHandler; 178 *error = errors::kInvalidFileBrowserHandler;
180 return false; 179 return false;
181 } 180 }
182 if (!LocalizeManifestValue(keys::kPageActionDefaultTitle, messages, 181 if (!LocalizeManifestValue(
183 handler, error)) 182 keys::kPageActionDefaultTitle, messages, handler, error))
184 return false; 183 return false;
185 } 184 }
186 } 185 }
187 186
188 base::ListValue* media_galleries_handlers = NULL; 187 base::ListValue* media_galleries_handlers = NULL;
189 if (manifest->GetList(keys::kMediaGalleriesHandlers, 188 if (manifest->GetList(keys::kMediaGalleriesHandlers,
190 &media_galleries_handlers)) { 189 &media_galleries_handlers)) {
191 key.assign(keys::kMediaGalleriesHandlers); 190 key.assign(keys::kMediaGalleriesHandlers);
192 for (size_t i = 0; i < media_galleries_handlers->GetSize(); i++) { 191 for (size_t i = 0; i < media_galleries_handlers->GetSize(); i++) {
193 base::DictionaryValue* handler = NULL; 192 base::DictionaryValue* handler = NULL;
194 if (!media_galleries_handlers->GetDictionary(i, &handler)) { 193 if (!media_galleries_handlers->GetDictionary(i, &handler)) {
195 *error = errors::kInvalidMediaGalleriesHandler; 194 *error = errors::kInvalidMediaGalleriesHandler;
196 return false; 195 return false;
197 } 196 }
198 if (!LocalizeManifestValue(keys::kPageActionDefaultTitle, messages, 197 if (!LocalizeManifestValue(
199 handler, error)) 198 keys::kPageActionDefaultTitle, messages, handler, error))
200 return false; 199 return false;
201 } 200 }
202 } 201 }
203 202
204 // Initialize all input_components 203 // Initialize all input_components
205 base::ListValue* input_components = NULL; 204 base::ListValue* input_components = NULL;
206 if (manifest->GetList(keys::kInputComponents, &input_components)) { 205 if (manifest->GetList(keys::kInputComponents, &input_components)) {
207 for (size_t i = 0; i < input_components->GetSize(); ++i) { 206 for (size_t i = 0; i < input_components->GetSize(); ++i) {
208 base::DictionaryValue* module = NULL; 207 base::DictionaryValue* module = NULL;
209 if (!input_components->GetDictionary(i, &module)) { 208 if (!input_components->GetDictionary(i, &module)) {
(...skipping 14 matching lines...) Expand all
224 // Initialize app.launch.web_url. 223 // Initialize app.launch.web_url.
225 if (!LocalizeManifestValue(keys::kLaunchWebURL, messages, manifest, error)) 224 if (!LocalizeManifestValue(keys::kLaunchWebURL, messages, manifest, error))
226 return false; 225 return false;
227 226
228 // Initialize description of commmands. 227 // Initialize description of commmands.
229 base::DictionaryValue* commands_handler = NULL; 228 base::DictionaryValue* commands_handler = NULL;
230 if (manifest->GetDictionary(keys::kCommands, &commands_handler)) { 229 if (manifest->GetDictionary(keys::kCommands, &commands_handler)) {
231 for (base::DictionaryValue::Iterator iter(*commands_handler); 230 for (base::DictionaryValue::Iterator iter(*commands_handler);
232 !iter.IsAtEnd(); 231 !iter.IsAtEnd();
233 iter.Advance()) { 232 iter.Advance()) {
234 key.assign(base::StringPrintf("commands.%s.description", 233 key.assign(
235 iter.key().c_str())); 234 base::StringPrintf("commands.%s.description", iter.key().c_str()));
236 if (!LocalizeManifestValue(key, messages, manifest, error)) 235 if (!LocalizeManifestValue(key, messages, manifest, error))
237 return false; 236 return false;
238 } 237 }
239 } 238 }
240 239
241 // Initialize search_provider fields. 240 // Initialize search_provider fields.
242 base::DictionaryValue* search_provider = NULL; 241 base::DictionaryValue* search_provider = NULL;
243 if (manifest->GetDictionary(keys::kOverrideSearchProvider, 242 if (manifest->GetDictionary(keys::kOverrideSearchProvider,
244 &search_provider)) { 243 &search_provider)) {
245 for (base::DictionaryValue::Iterator iter(*search_provider); 244 for (base::DictionaryValue::Iterator iter(*search_provider);
246 !iter.IsAtEnd(); 245 !iter.IsAtEnd();
247 iter.Advance()) { 246 iter.Advance()) {
248 key.assign(base::StringPrintf( 247 key.assign(base::StringPrintf(
249 "%s.%s", keys::kOverrideSearchProvider, iter.key().c_str())); 248 "%s.%s", keys::kOverrideSearchProvider, iter.key().c_str()));
250 bool success = (key == keys::kSettingsOverrideAlternateUrls) ? 249 bool success =
251 LocalizeManifestListValue(key, messages, manifest, error) : 250 (key == keys::kSettingsOverrideAlternateUrls)
252 LocalizeManifestValue(key, messages, manifest, error); 251 ? LocalizeManifestListValue(key, messages, manifest, error)
252 : LocalizeManifestValue(key, messages, manifest, error);
253 if (!success) 253 if (!success)
254 return false; 254 return false;
255 } 255 }
256 } 256 }
257 257
258 // Initialize chrome_settings_overrides.homepage. 258 // Initialize chrome_settings_overrides.homepage.
259 if (!LocalizeManifestValue( 259 if (!LocalizeManifestValue(
260 keys::kOverrideHomepage, messages, manifest, error)) 260 keys::kOverrideHomepage, messages, manifest, error))
261 return false; 261 return false;
262 262
263 // Initialize chrome_settings_overrides.startup_pages. 263 // Initialize chrome_settings_overrides.startup_pages.
264 if (!LocalizeManifestListValue( 264 if (!LocalizeManifestListValue(
265 keys::kOverrideStartupPage, messages, manifest, error)) 265 keys::kOverrideStartupPage, messages, manifest, error))
266 return false; 266 return false;
267 267
268 // Add current locale key to the manifest, so we can overwrite prefs 268 // Add current locale key to the manifest, so we can overwrite prefs
269 // with new manifest when chrome locale changes. 269 // with new manifest when chrome locale changes.
270 manifest->SetString(keys::kCurrentLocale, CurrentLocaleOrDefault()); 270 manifest->SetString(keys::kCurrentLocale, CurrentLocaleOrDefault());
271 return true; 271 return true;
272 } 272 }
273 273
274 bool LocalizeExtension(const base::FilePath& extension_path, 274 bool LocalizeExtension(const base::FilePath& extension_path,
275 base::DictionaryValue* manifest, 275 base::DictionaryValue* manifest,
276 std::string* error) { 276 std::string* error) {
277 DCHECK(manifest); 277 DCHECK(manifest);
278 278
279 std::string default_locale = GetDefaultLocaleFromManifest(*manifest, error); 279 std::string default_locale = GetDefaultLocaleFromManifest(*manifest, error);
280 280
281 scoped_ptr<extensions::MessageBundle> message_bundle( 281 scoped_ptr<extensions::MessageBundle> message_bundle(
282 extension_file_util::LoadMessageBundle( 282 extensions::file_util::LoadMessageBundle(
283 extension_path, default_locale, error)); 283 extension_path, default_locale, error));
284 284
285 if (!message_bundle.get() && !error->empty()) 285 if (!message_bundle.get() && !error->empty())
286 return false; 286 return false;
287 287
288 if (message_bundle.get() && 288 if (message_bundle.get() &&
289 !LocalizeManifest(*message_bundle, manifest, error)) 289 !LocalizeManifest(*message_bundle, manifest, error))
290 return false; 290 return false;
291 291
292 return true; 292 return true;
293 } 293 }
294 294
295 bool AddLocale(const std::set<std::string>& chrome_locales, 295 bool AddLocale(const std::set<std::string>& chrome_locales,
296 const base::FilePath& locale_folder, 296 const base::FilePath& locale_folder,
297 const std::string& locale_name, 297 const std::string& locale_name,
298 std::set<std::string>* valid_locales, 298 std::set<std::string>* valid_locales,
299 std::string* error) { 299 std::string* error) {
300 // Accept name that starts with a . but don't add it to the list of supported 300 // Accept name that starts with a . but don't add it to the list of supported
301 // locales. 301 // locales.
302 if (locale_name.find(".") == 0) 302 if (locale_name.find(".") == 0)
303 return true; 303 return true;
304 if (chrome_locales.find(locale_name) == chrome_locales.end()) { 304 if (chrome_locales.find(locale_name) == chrome_locales.end()) {
305 // Warn if there is an extension locale that's not in the Chrome list, 305 // Warn if there is an extension locale that's not in the Chrome list,
306 // but don't fail. 306 // but don't fail.
307 DLOG(WARNING) << base::StringPrintf("Supplied locale %s is not supported.", 307 DLOG(WARNING) << base::StringPrintf("Supplied locale %s is not supported.",
308 locale_name.c_str()); 308 locale_name.c_str());
309 return true; 309 return true;
310 } 310 }
311 // Check if messages file is actually present (but don't check content). 311 // Check if messages file is actually present (but don't check content).
312 if (base::PathExists( 312 if (base::PathExists(locale_folder.Append(extensions::kMessagesFilename))) {
313 locale_folder.Append(extensions::kMessagesFilename))) {
314 valid_locales->insert(locale_name); 313 valid_locales->insert(locale_name);
315 } else { 314 } else {
316 *error = base::StringPrintf("Catalog file is missing for locale %s.", 315 *error = base::StringPrintf("Catalog file is missing for locale %s.",
317 locale_name.c_str()); 316 locale_name.c_str());
318 return false; 317 return false;
319 } 318 }
320 319
321 return true; 320 return true;
322 } 321 }
323 322
(...skipping 26 matching lines...) Expand all
350 all_fallback_locales->push_back(default_locale); 349 all_fallback_locales->push_back(default_locale);
351 } 350 }
352 351
353 bool GetValidLocales(const base::FilePath& locale_path, 352 bool GetValidLocales(const base::FilePath& locale_path,
354 std::set<std::string>* valid_locales, 353 std::set<std::string>* valid_locales,
355 std::string* error) { 354 std::string* error) {
356 std::set<std::string> chrome_locales; 355 std::set<std::string> chrome_locales;
357 GetAllLocales(&chrome_locales); 356 GetAllLocales(&chrome_locales);
358 357
359 // Enumerate all supplied locales in the extension. 358 // Enumerate all supplied locales in the extension.
360 base::FileEnumerator locales(locale_path, 359 base::FileEnumerator locales(
361 false, 360 locale_path, false, base::FileEnumerator::DIRECTORIES);
362 base::FileEnumerator::DIRECTORIES);
363 base::FilePath locale_folder; 361 base::FilePath locale_folder;
364 while (!(locale_folder = locales.Next()).empty()) { 362 while (!(locale_folder = locales.Next()).empty()) {
365 std::string locale_name = locale_folder.BaseName().MaybeAsASCII(); 363 std::string locale_name = locale_folder.BaseName().MaybeAsASCII();
366 if (locale_name.empty()) { 364 if (locale_name.empty()) {
367 NOTREACHED(); 365 NOTREACHED();
368 continue; // Not ASCII. 366 continue; // Not ASCII.
369 } 367 }
370 if (!AddLocale(chrome_locales, 368 if (!AddLocale(
371 locale_folder, 369 chrome_locales, locale_folder, locale_name, valid_locales, error)) {
372 locale_name,
373 valid_locales,
374 error)) {
375 return false; 370 return false;
376 } 371 }
377 } 372 }
378 373
379 if (valid_locales->empty()) { 374 if (valid_locales->empty()) {
380 *error = errors::kLocalesNoValidLocaleNamesListed; 375 *error = errors::kLocalesNoValidLocaleNamesListed;
381 return false; 376 return false;
382 } 377 }
383 378
384 return true; 379 return true;
385 } 380 }
386 381
387 extensions::MessageBundle* LoadMessageCatalogs( 382 extensions::MessageBundle* LoadMessageCatalogs(
388 const base::FilePath& locale_path, 383 const base::FilePath& locale_path,
389 const std::string& default_locale, 384 const std::string& default_locale,
390 const std::string& application_locale, 385 const std::string& application_locale,
391 const std::set<std::string>& valid_locales, 386 const std::set<std::string>& valid_locales,
392 std::string* error) { 387 std::string* error) {
393 std::vector<std::string> all_fallback_locales; 388 std::vector<std::string> all_fallback_locales;
394 GetAllFallbackLocales(application_locale, default_locale, 389 GetAllFallbackLocales(
395 &all_fallback_locales); 390 application_locale, default_locale, &all_fallback_locales);
396 391
397 std::vector<linked_ptr<base::DictionaryValue> > catalogs; 392 std::vector<linked_ptr<base::DictionaryValue> > catalogs;
398 for (size_t i = 0; i < all_fallback_locales.size(); ++i) { 393 for (size_t i = 0; i < all_fallback_locales.size(); ++i) {
399 // Skip all parent locales that are not supplied. 394 // Skip all parent locales that are not supplied.
400 if (valid_locales.find(all_fallback_locales[i]) == valid_locales.end()) 395 if (valid_locales.find(all_fallback_locales[i]) == valid_locales.end())
401 continue; 396 continue;
402 linked_ptr<base::DictionaryValue> catalog( 397 linked_ptr<base::DictionaryValue> catalog(
403 LoadMessageFile(locale_path, all_fallback_locales[i], error)); 398 LoadMessageFile(locale_path, all_fallback_locales[i], error));
404 if (!catalog.get()) { 399 if (!catalog.get()) {
405 // If locale is valid, but messages.json is corrupted or missing, return 400 // If locale is valid, but messages.json is corrupted or missing, return
406 // an error. 401 // an error.
407 return NULL; 402 return NULL;
408 } else { 403 } else {
409 catalogs.push_back(catalog); 404 catalogs.push_back(catalog);
410 } 405 }
411 } 406 }
412 407
413 return extensions::MessageBundle::Create(catalogs, error); 408 return extensions::MessageBundle::Create(catalogs, error);
414 } 409 }
415 410
416 bool ValidateExtensionLocales(const base::FilePath& extension_path, 411 bool ValidateExtensionLocales(const base::FilePath& extension_path,
417 const base::DictionaryValue* manifest, 412 const base::DictionaryValue* manifest,
418 std::string* error) { 413 std::string* error) {
419 std::string default_locale = GetDefaultLocaleFromManifest(*manifest, error); 414 std::string default_locale = GetDefaultLocaleFromManifest(*manifest, error);
420 415
421 if (default_locale.empty()) 416 if (default_locale.empty())
422 return true; 417 return true;
423 418
424 base::FilePath locale_path = 419 base::FilePath locale_path = extension_path.Append(extensions::kLocaleFolder);
425 extension_path.Append(extensions::kLocaleFolder);
426 420
427 std::set<std::string> valid_locales; 421 std::set<std::string> valid_locales;
428 if (!GetValidLocales(locale_path, &valid_locales, error)) 422 if (!GetValidLocales(locale_path, &valid_locales, error))
429 return false; 423 return false;
430 424
431 for (std::set<std::string>::const_iterator locale = valid_locales.begin(); 425 for (std::set<std::string>::const_iterator locale = valid_locales.begin();
432 locale != valid_locales.end(); ++locale) { 426 locale != valid_locales.end();
427 ++locale) {
433 std::string locale_error; 428 std::string locale_error;
434 scoped_ptr<base::DictionaryValue> catalog( 429 scoped_ptr<base::DictionaryValue> catalog(
435 LoadMessageFile(locale_path, *locale, &locale_error)); 430 LoadMessageFile(locale_path, *locale, &locale_error));
436 431
437 if (!locale_error.empty()) { 432 if (!locale_error.empty()) {
438 if (!error->empty()) 433 if (!error->empty())
439 error->append(" "); 434 error->append(" ");
440 error->append(locale_error); 435 error->append(locale_error);
441 } 436 }
442 } 437 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 ScopedLocaleForTest::ScopedLocaleForTest(const std::string& locale) 469 ScopedLocaleForTest::ScopedLocaleForTest(const std::string& locale)
475 : locale_(extension_l10n_util::CurrentLocaleOrDefault()) { 470 : locale_(extension_l10n_util::CurrentLocaleOrDefault()) {
476 extension_l10n_util::SetProcessLocale(locale); 471 extension_l10n_util::SetProcessLocale(locale);
477 } 472 }
478 473
479 ScopedLocaleForTest::~ScopedLocaleForTest() { 474 ScopedLocaleForTest::~ScopedLocaleForTest() {
480 extension_l10n_util::SetProcessLocale(locale_); 475 extension_l10n_util::SetProcessLocale(locale_);
481 } 476 }
482 477
483 } // namespace extension_l10n_util 478 } // namespace extension_l10n_util
OLDNEW
« no previous file with comments | « extensions/common/extension_l10n_util.h ('k') | extensions/common/extension_l10n_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698