| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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_message_bundle.h" | 5 #include "chrome/common/extensions/extension_message_bundle.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> |
| 8 | 9 |
| 9 #include "base/hash_tables.h" | 10 #include "base/hash_tables.h" |
| 11 #include "base/linked_ptr.h" |
| 10 #include "base/scoped_ptr.h" | 12 #include "base/scoped_ptr.h" |
| 11 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 12 #include "base/values.h" | 14 #include "base/values.h" |
| 13 | 15 |
| 14 const wchar_t* ExtensionMessageBundle::kContentKey = L"content"; | 16 const wchar_t* ExtensionMessageBundle::kContentKey = L"content"; |
| 15 const wchar_t* ExtensionMessageBundle::kMessageKey = L"message"; | 17 const wchar_t* ExtensionMessageBundle::kMessageKey = L"message"; |
| 16 const wchar_t* ExtensionMessageBundle::kPlaceholdersKey = L"placeholders"; | 18 const wchar_t* ExtensionMessageBundle::kPlaceholdersKey = L"placeholders"; |
| 17 | 19 |
| 18 const char* ExtensionMessageBundle::kPlaceholderBegin = "$"; | 20 const char* ExtensionMessageBundle::kPlaceholderBegin = "$"; |
| 19 const char* ExtensionMessageBundle::kPlaceholderEnd = "$"; | 21 const char* ExtensionMessageBundle::kPlaceholderEnd = "$"; |
| 20 const char* ExtensionMessageBundle::kMessageBegin = "__MSG_"; | 22 const char* ExtensionMessageBundle::kMessageBegin = "__MSG_"; |
| 21 const char* ExtensionMessageBundle::kMessageEnd = "__"; | 23 const char* ExtensionMessageBundle::kMessageEnd = "__"; |
| 22 | 24 |
| 23 const char* ExtensionMessageBundle::kExtensionName = "chrome_extension_name"; | 25 const char* ExtensionMessageBundle::kExtensionName = "chrome_extension_name"; |
| 24 const char* ExtensionMessageBundle::kExtensionDescription = | 26 const char* ExtensionMessageBundle::kExtensionDescription = |
| 25 "chrome_extension_description"; | 27 "chrome_extension_description"; |
| 26 | 28 |
| 27 // Formats message in case we encounter a bad formed key in the JSON object. | 29 // Formats message in case we encounter a bad formed key in the JSON object. |
| 28 // Returns false and sets |error| to actual error message. | 30 // Returns false and sets |error| to actual error message. |
| 29 static bool BadKeyMessage(const std::string& name, std::string* error) { | 31 static bool BadKeyMessage(const std::string& name, std::string* error) { |
| 30 *error = StringPrintf("Name of a key \"%s\" is invalid. Only ASCII [a-z], " | 32 *error = StringPrintf("Name of a key \"%s\" is invalid. Only ASCII [a-z], " |
| 31 "[A-Z], [0-9] and \"_\" are allowed.", name.c_str()); | 33 "[A-Z], [0-9] and \"_\" are allowed.", name.c_str()); |
| 32 return false; | 34 return false; |
| 33 } | 35 } |
| 34 | 36 |
| 35 // static | 37 // static |
| 36 ExtensionMessageBundle* ExtensionMessageBundle::Create( | 38 ExtensionMessageBundle* ExtensionMessageBundle::Create( |
| 37 const DictionaryValue& default_locale_catalog, | 39 const CatalogVector& locale_catalogs, |
| 38 const DictionaryValue& current_locale_catalog, | |
| 39 std::string* error) { | 40 std::string* error) { |
| 40 scoped_ptr<ExtensionMessageBundle> message_bundle( | 41 scoped_ptr<ExtensionMessageBundle> message_bundle( |
| 41 new ExtensionMessageBundle); | 42 new ExtensionMessageBundle); |
| 42 if (!message_bundle->Init(default_locale_catalog, | 43 if (!message_bundle->Init(locale_catalogs, error)) |
| 43 current_locale_catalog, | |
| 44 error)) | |
| 45 return NULL; | 44 return NULL; |
| 46 | 45 |
| 47 return message_bundle.release(); | 46 return message_bundle.release(); |
| 48 } | 47 } |
| 49 | 48 |
| 50 bool ExtensionMessageBundle::Init(const DictionaryValue& default_locale_catalog, | 49 bool ExtensionMessageBundle::Init(const CatalogVector& locale_catalogs, |
| 51 const DictionaryValue& current_locale_catalog, | |
| 52 std::string* error) { | 50 std::string* error) { |
| 53 dictionary_.clear(); | 51 dictionary_.clear(); |
| 54 | 52 |
| 55 // Create a single dictionary out of default and current_locale catalogs. | 53 CatalogVector::const_reverse_iterator it = locale_catalogs.rbegin(); |
| 56 // If message is missing from current_locale catalog, we take one from default | 54 for (; it != locale_catalogs.rend(); ++it) { |
| 57 // catalog. | 55 DictionaryValue* catalog = (*it).get(); |
| 58 DictionaryValue::key_iterator key_it = current_locale_catalog.begin_keys(); | 56 DictionaryValue::key_iterator key_it = catalog->begin_keys(); |
| 59 for (; key_it != current_locale_catalog.end_keys(); ++key_it) { | 57 for (; key_it != catalog->end_keys(); ++key_it) { |
| 60 std::string key(StringToLowerASCII(WideToUTF8(*key_it))); | 58 std::string key(StringToLowerASCII(WideToUTF8(*key_it))); |
| 61 if (!IsValidName(*key_it)) | 59 if (!IsValidName(*key_it)) |
| 62 return BadKeyMessage(key, error); | 60 return BadKeyMessage(key, error); |
| 63 std::string value; | 61 std::string value; |
| 64 if (!GetMessageValue(*key_it, current_locale_catalog, &value, error)) | 62 if (!GetMessageValue(*key_it, *catalog, &value, error)) |
| 65 return false; | 63 return false; |
| 66 // Keys are not case-sensitive. | 64 // Keys are not case-sensitive. |
| 67 dictionary_[key] = value; | 65 dictionary_[key] = value; |
| 68 } | 66 } |
| 69 | |
| 70 key_it = default_locale_catalog.begin_keys(); | |
| 71 for (; key_it != default_locale_catalog.end_keys(); ++key_it) { | |
| 72 std::string key(StringToLowerASCII(WideToUTF8(*key_it))); | |
| 73 if (!IsValidName(*key_it)) | |
| 74 return BadKeyMessage(key, error); | |
| 75 // Add only messages that are not provided by app_catalog. | |
| 76 if (dictionary_.find(key) != dictionary_.end()) | |
| 77 continue; | |
| 78 std::string value; | |
| 79 if (!GetMessageValue(*key_it, default_locale_catalog, &value, error)) | |
| 80 return false; | |
| 81 // Keys are not case-sensitive. | |
| 82 dictionary_[key] = value; | |
| 83 } | 67 } |
| 84 | 68 |
| 85 return true; | 69 return true; |
| 86 } | 70 } |
| 87 | 71 |
| 88 bool ExtensionMessageBundle::GetMessageValue(const std::wstring& wkey, | 72 bool ExtensionMessageBundle::GetMessageValue(const std::wstring& wkey, |
| 89 const DictionaryValue& catalog, | 73 const DictionaryValue& catalog, |
| 90 std::string* value, | 74 std::string* value, |
| 91 std::string* error) const { | 75 std::string* error) const { |
| 92 std::string key(WideToUTF8(wkey)); | 76 std::string key(WideToUTF8(wkey)); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 std::string ExtensionMessageBundle::GetL10nMessage( | 237 std::string ExtensionMessageBundle::GetL10nMessage( |
| 254 const std::string& name, const SubstitutionMap& dictionary) { | 238 const std::string& name, const SubstitutionMap& dictionary) { |
| 255 SubstitutionMap::const_iterator it = | 239 SubstitutionMap::const_iterator it = |
| 256 dictionary.find(StringToLowerASCII(name)); | 240 dictionary.find(StringToLowerASCII(name)); |
| 257 if (it != dictionary.end()) { | 241 if (it != dictionary.end()) { |
| 258 return it->second; | 242 return it->second; |
| 259 } | 243 } |
| 260 | 244 |
| 261 return ""; | 245 return ""; |
| 262 } | 246 } |
| OLD | NEW |