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

Unified Diff: chrome/browser/extensions/extension_l10n_util.cc

Issue 293037: Implementing better fallback algorithm.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_l10n_util.cc
===================================================================
--- chrome/browser/extensions/extension_l10n_util.cc (revision 29587)
+++ chrome/browser/extensions/extension_l10n_util.cc (working copy)
@@ -10,6 +10,7 @@
#include "app/l10n_util.h"
#include "base/file_util.h"
+#include "base/linked_ptr.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/extensions/extension.h"
@@ -29,49 +30,85 @@
*error = errors::kInvalidDefaultLocale;
return "";
}
- // Normalize underscores to hyphens.
- std::replace(default_locale.begin(), default_locale.end(), '_', '-');
+
return default_locale;
}
bool AddLocale(const std::set<std::string>& chrome_locales,
const FilePath& locale_folder,
+ const std::string& locale_name,
std::set<std::string>* valid_locales,
- std::string* locale_name,
std::string* error) {
- // Normalize underscores to hyphens because that's what our locale files use.
- std::replace(locale_name->begin(), locale_name->end(), '_', '-');
// Accept name that starts with a . but don't add it to the list of supported
// locales.
- if (locale_name->find(".") == 0)
+ if (locale_name.find(".") == 0)
return true;
- if (chrome_locales.find(*locale_name) == chrome_locales.end()) {
+ if (chrome_locales.find(locale_name) == chrome_locales.end()) {
// Fail if there is an extension locale that's not in the Chrome list.
*error = StringPrintf("Supplied locale %s is not supported.",
- locale_name->c_str());
+ locale_name.c_str());
return false;
}
// Check if messages file is actually present (but don't check content).
if (file_util::PathExists(
locale_folder.AppendASCII(Extension::kMessagesFilename))) {
- valid_locales->insert(*locale_name);
+ valid_locales->insert(locale_name);
} else {
*error = StringPrintf("Catalog file is missing for locale %s.",
- locale_name->c_str());
+ locale_name.c_str());
return false;
}
return true;
}
+// Converts all - into _, to be consistent with ICU and file system names.
+static std::string NormalizeLocale(const std::string& locale) {
+ std::string normalized_locale(locale);
+ std::replace(normalized_locale.begin(), normalized_locale.end(), '-', '_');
+
+ return normalized_locale;
+}
+
+// Produce a vector of parent locales for given locale.
+// It includes the current locale in the result.
+// sr_Cyrl_RS generates sr_Cyrl_RS, sr_Cyrl and sr.
+static void GetParentLocales(const std::string& current_locale,
+ std::vector<std::string>* parent_locales) {
+ std::string locale(NormalizeLocale(current_locale));
+
+ const int kNameCapacity = 256;
+ char parent[kNameCapacity];
+ strncpy(parent, locale.c_str(), kNameCapacity);
+ parent_locales->push_back(parent);
+ UErrorCode err = U_ZERO_ERROR;
+ while (uloc_getParent(parent, parent, kNameCapacity, &err) > 0) {
+ if (err != U_ZERO_ERROR)
+ break;
+ parent_locales->push_back(parent);
+ }
+}
+
+// Extends list of Chrome locales to them and their parents, so we can do
+// proper fallback.
+static void GetAllLocales(std::set<std::string>* all_locales) {
+ const std::vector<std::string>& available_locales =
+ l10n_util::GetAvailableLocales();
+ // Add all parents of the current locale to the available locales set.
+ // I.e. for sr_Cyrl_RS we add sr_Cyrl_RS, sr_Cyrl and sr.
+ for (size_t i = 0; i < available_locales.size(); ++i) {
+ std::vector<std::string> result;
+ GetParentLocales(available_locales[i], &result);
+ all_locales->insert(result.begin(), result.end());
+ }
+}
+
bool GetValidLocales(const FilePath& locale_path,
std::set<std::string>* valid_locales,
std::string* error) {
- // Get available chrome locales as a set.
- const std::vector<std::string>& available_locales =
- l10n_util::GetAvailableLocales();
- static std::set<std::string> chrome_locales(available_locales.begin(),
- available_locales.end());
+ static std::set<std::string> chrome_locales;
+ GetAllLocales(&chrome_locales);
+
// Enumerate all supplied locales in the extension.
file_util::FileEnumerator locales(locale_path,
false,
@@ -82,8 +119,8 @@
WideToASCII(locale_folder.BaseName().ToWStringHack());
if (!AddLocale(chrome_locales,
locale_folder,
+ locale_name,
valid_locales,
- &locale_name,
error)) {
return false;
}
@@ -103,9 +140,8 @@
static DictionaryValue* LoadMessageFile(const FilePath& locale_path,
const std::string& locale,
std::string* error) {
+
std::string extension_locale = locale;
- // Normalize hyphens to underscores because that's what our locale files use.
- std::replace(extension_locale.begin(), extension_locale.end(), '-', '_');
FilePath file = locale_path.AppendASCII(extension_locale)
.AppendASCII(Extension::kMessagesFilename);
JSONFileValueSerializer messages_serializer(file);
@@ -124,24 +160,31 @@
const FilePath& locale_path,
const std::string& default_locale,
const std::string& application_locale,
+ const std::set<std::string>& valid_locales,
std::string* error) {
- scoped_ptr<DictionaryValue> default_catalog(
- LoadMessageFile(locale_path, default_locale, error));
- if (!default_catalog.get()) {
- return false;
- }
+ // Order locales to load as current_locale, first_parent, ..., default_locale.
+ std::vector<std::string> all_fallback_locales;
+ if (!application_locale.empty() && application_locale != default_locale)
+ GetParentLocales(application_locale, &all_fallback_locales);
+ all_fallback_locales.push_back(default_locale);
- scoped_ptr<DictionaryValue> app_catalog(
- LoadMessageFile(locale_path, application_locale, error));
- if (!app_catalog.get()) {
- // Only default catalog has to be present. This is not an error.
- app_catalog.reset(new DictionaryValue);
- error->clear();
+ std::vector<linked_ptr<DictionaryValue> > catalogs;
+ for (size_t i = 0; i < all_fallback_locales.size(); ++i) {
+ // Skip all parent locales that are not supplied.
+ if (valid_locales.find(all_fallback_locales[i]) == valid_locales.end())
+ continue;
+ linked_ptr<DictionaryValue> catalog(
+ LoadMessageFile(locale_path, all_fallback_locales[i], error));
+ if (!catalog.get()) {
+ // If locale is valid, but messages.json is corrupted or missing, return
+ // an error.
+ return false;
+ } else {
+ catalogs.push_back(catalog);
+ }
}
- return ExtensionMessageBundle::Create(*default_catalog,
- *app_catalog,
- error);
+ return ExtensionMessageBundle::Create(catalogs, error);
}
FilePath GetL10nRelativePath(const FilePath& relative_resource_path) {
« no previous file with comments | « chrome/browser/extensions/extension_l10n_util.h ('k') | chrome/browser/extensions/extension_l10n_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698