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

Side by Side Diff: chrome/common/extensions/extension_message_bundle.cc

Issue 546040: Add reserved messages to ExtensionMessageBundle dictionary. They are of the f... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 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) 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 #include <vector>
9 9
10 #include "app/l10n_util.h"
10 #include "base/hash_tables.h" 11 #include "base/hash_tables.h"
11 #include "base/linked_ptr.h" 12 #include "base/linked_ptr.h"
12 #include "base/scoped_ptr.h" 13 #include "base/scoped_ptr.h"
14 #include "base/stl_util-inl.h"
13 #include "base/string_util.h" 15 #include "base/string_util.h"
14 #include "base/values.h" 16 #include "base/values.h"
17 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/common/extensions/extension_error_utils.h"
19 #include "chrome/common/extensions/extension_l10n_util.h"
20
21 namespace errors = extension_manifest_errors;
15 22
16 const wchar_t* ExtensionMessageBundle::kContentKey = L"content"; 23 const wchar_t* ExtensionMessageBundle::kContentKey = L"content";
17 const wchar_t* ExtensionMessageBundle::kMessageKey = L"message"; 24 const wchar_t* ExtensionMessageBundle::kMessageKey = L"message";
18 const wchar_t* ExtensionMessageBundle::kPlaceholdersKey = L"placeholders"; 25 const wchar_t* ExtensionMessageBundle::kPlaceholdersKey = L"placeholders";
19 26
20 const char* ExtensionMessageBundle::kPlaceholderBegin = "$"; 27 const char* ExtensionMessageBundle::kPlaceholderBegin = "$";
21 const char* ExtensionMessageBundle::kPlaceholderEnd = "$"; 28 const char* ExtensionMessageBundle::kPlaceholderEnd = "$";
22 const char* ExtensionMessageBundle::kMessageBegin = "__MSG_"; 29 const char* ExtensionMessageBundle::kMessageBegin = "__MSG_";
23 const char* ExtensionMessageBundle::kMessageEnd = "__"; 30 const char* ExtensionMessageBundle::kMessageEnd = "__";
24 31
32 // Reserved messages names.
33 const char* ExtensionMessageBundle::kUILocaleKey = "@@ui_locale";
34 const char* ExtensionMessageBundle::kBidiDirectionKey = "@@bidi_dir";
35 const char* ExtensionMessageBundle::kBidiReversedDirectionKey =
36 "@@bidi_reversed_dir";
37 const char* ExtensionMessageBundle::kBidiStartEdgeKey = "@@bidi_start_edge";
38 const char* ExtensionMessageBundle::kBidiEndEdgeKey = "@@bidi_end_edge";
39
40 // Reserved messages values.
41 const char* ExtensionMessageBundle::kBidiLeftEdgeValue = "left";
42 const char* ExtensionMessageBundle::kBidiRightEdgeValue = "right";
43
25 // Formats message in case we encounter a bad formed key in the JSON object. 44 // Formats message in case we encounter a bad formed key in the JSON object.
26 // Returns false and sets |error| to actual error message. 45 // Returns false and sets |error| to actual error message.
27 static bool BadKeyMessage(const std::string& name, std::string* error) { 46 static bool BadKeyMessage(const std::string& name, std::string* error) {
28 *error = StringPrintf("Name of a key \"%s\" is invalid. Only ASCII [a-z], " 47 *error = StringPrintf("Name of a key \"%s\" is invalid. Only ASCII [a-z], "
29 "[A-Z], [0-9] and \"_\" are allowed.", name.c_str()); 48 "[A-Z], [0-9] and \"_\" are allowed.", name.c_str());
30 return false; 49 return false;
31 } 50 }
32 51
33 // static 52 // static
34 ExtensionMessageBundle* ExtensionMessageBundle::Create( 53 ExtensionMessageBundle* ExtensionMessageBundle::Create(
(...skipping 20 matching lines...) Expand all
55 if (!IsValidName(*key_it)) 74 if (!IsValidName(*key_it))
56 return BadKeyMessage(key, error); 75 return BadKeyMessage(key, error);
57 std::string value; 76 std::string value;
58 if (!GetMessageValue(*key_it, *catalog, &value, error)) 77 if (!GetMessageValue(*key_it, *catalog, &value, error))
59 return false; 78 return false;
60 // Keys are not case-sensitive. 79 // Keys are not case-sensitive.
61 dictionary_[key] = value; 80 dictionary_[key] = value;
62 } 81 }
63 } 82 }
64 83
84 if (!AppendReservedMessages(extension_l10n_util::CurrentLocaleOrDefault(),
85 error))
86 return false;
87
88 return true;
89 }
90
91 bool ExtensionMessageBundle::AppendReservedMessages(
92 const std::string& app_locale, std::string* error) {
93 SubstitutionMap append_messages;
94 append_messages[kUILocaleKey] = app_locale;
95
96 // Calling l10n_util::GetTextDirection on non-UI threads doesn't seems safe,
97 // so we use GetTextDirectionForLocale instead.
98 if (l10n_util::GetTextDirectionForLocale(app_locale.c_str()) ==
99 l10n_util::RIGHT_TO_LEFT) {
100 append_messages[kBidiDirectionKey] = "rtl";
101 append_messages[kBidiReversedDirectionKey] = "ltr";
102 append_messages[kBidiStartEdgeKey] = kBidiRightEdgeValue;
103 append_messages[kBidiEndEdgeKey] = kBidiLeftEdgeValue;
104 } else {
105 append_messages[kBidiDirectionKey] = "ltr";
106 append_messages[kBidiReversedDirectionKey] = "rtl";
107 append_messages[kBidiStartEdgeKey] = kBidiLeftEdgeValue;
108 append_messages[kBidiEndEdgeKey] = kBidiRightEdgeValue;
109 }
110
111 // Add all reserved messages to the dictionary, but check for collisions.
112 SubstitutionMap::iterator it = append_messages.begin();
113 for (; it != append_messages.end(); ++it) {
114 if (ContainsKey(dictionary_, it->first)) {
115 *error = ExtensionErrorUtils::FormatErrorMessage(
116 errors::kReservedMessageFound, it->first);
117 return false;
118 } else {
119 dictionary_[it->first] = it->second;
120 }
121 }
122
65 return true; 123 return true;
66 } 124 }
67 125
68 bool ExtensionMessageBundle::GetMessageValue(const std::wstring& wkey, 126 bool ExtensionMessageBundle::GetMessageValue(const std::wstring& wkey,
69 const DictionaryValue& catalog, 127 const DictionaryValue& catalog,
70 std::string* value, 128 std::string* value,
71 std::string* error) const { 129 std::string* error) const {
72 std::string key(WideToUTF8(wkey)); 130 std::string key(WideToUTF8(wkey));
73 // Get the top level tree for given key (name part). 131 // Get the top level tree for given key (name part).
74 DictionaryValue* name_tree; 132 DictionaryValue* name_tree;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 266 }
209 267
210 // static 268 // static
211 template <typename str> 269 template <typename str>
212 bool ExtensionMessageBundle::IsValidName(const str& name) { 270 bool ExtensionMessageBundle::IsValidName(const str& name) {
213 if (name.empty()) 271 if (name.empty())
214 return false; 272 return false;
215 273
216 for (typename str::const_iterator it = name.begin(); it != name.end(); ++it) { 274 for (typename str::const_iterator it = name.begin(); it != name.end(); ++it) {
217 // Allow only ascii 0-9, a-z, A-Z, and _ in the name. 275 // Allow only ascii 0-9, a-z, A-Z, and _ in the name.
218 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) && *it != '_') 276 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) && *it != '_' && *it != '@')
219 return false; 277 return false;
220 } 278 }
221 279
222 return true; 280 return true;
223 } 281 }
224 282
225 // Dictionary interface. 283 // Dictionary interface.
226 284
227 std::string ExtensionMessageBundle::GetL10nMessage( 285 std::string ExtensionMessageBundle::GetL10nMessage(
228 const std::string& name) const { 286 const std::string& name) const {
229 return GetL10nMessage(name, dictionary_); 287 return GetL10nMessage(name, dictionary_);
230 } 288 }
231 289
232 // static 290 // static
233 std::string ExtensionMessageBundle::GetL10nMessage( 291 std::string ExtensionMessageBundle::GetL10nMessage(
234 const std::string& name, const SubstitutionMap& dictionary) { 292 const std::string& name, const SubstitutionMap& dictionary) {
235 SubstitutionMap::const_iterator it = 293 SubstitutionMap::const_iterator it =
236 dictionary.find(StringToLowerASCII(name)); 294 dictionary.find(StringToLowerASCII(name));
237 if (it != dictionary.end()) { 295 if (it != dictionary.end()) {
238 return it->second; 296 return it->second;
239 } 297 }
240 298
241 return ""; 299 return "";
242 } 300 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698