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 |