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 <map> | |
6 #include <set> | |
7 #include <string> | |
8 #include <vector> | |
9 | |
5 #include "chrome/renderer/extensions/extension_process_bindings.h" | 10 #include "chrome/renderer/extensions/extension_process_bindings.h" |
6 | 11 |
7 #include "base/singleton.h" | 12 #include "base/singleton.h" |
8 #include "chrome/common/extensions/extension.h" | 13 #include "chrome/common/extensions/extension.h" |
14 #include "chrome/common/extensions/extension_message_bundle.h" | |
9 #include "chrome/common/extensions/url_pattern.h" | 15 #include "chrome/common/extensions/url_pattern.h" |
10 #include "chrome/common/render_messages.h" | 16 #include "chrome/common/render_messages.h" |
11 #include "chrome/common/url_constants.h" | 17 #include "chrome/common/url_constants.h" |
12 #include "chrome/renderer/extensions/bindings_utils.h" | 18 #include "chrome/renderer/extensions/bindings_utils.h" |
13 #include "chrome/renderer/extensions/event_bindings.h" | 19 #include "chrome/renderer/extensions/event_bindings.h" |
14 #include "chrome/renderer/extensions/js_only_v8_extensions.h" | 20 #include "chrome/renderer/extensions/js_only_v8_extensions.h" |
15 #include "chrome/renderer/extensions/renderer_extension_bindings.h" | 21 #include "chrome/renderer/extensions/renderer_extension_bindings.h" |
16 #include "chrome/renderer/render_view.h" | 22 #include "chrome/renderer/render_view.h" |
17 #include "grit/common_resources.h" | 23 #include "grit/common_resources.h" |
18 #include "grit/renderer_resources.h" | 24 #include "grit/renderer_resources.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
34 | 40 |
35 // A map of extension ID to vector of page action ids. | 41 // A map of extension ID to vector of page action ids. |
36 typedef std::map< std::string, std::vector<std::string> > PageActionIdMap; | 42 typedef std::map< std::string, std::vector<std::string> > PageActionIdMap; |
37 | 43 |
38 // A map of permission name to whether its enabled for this extension. | 44 // A map of permission name to whether its enabled for this extension. |
39 typedef std::map<std::string, bool> PermissionsMap; | 45 typedef std::map<std::string, bool> PermissionsMap; |
40 | 46 |
41 // A map of extension ID to permissions map. | 47 // A map of extension ID to permissions map. |
42 typedef std::map<std::string, PermissionsMap> ExtensionPermissionsMap; | 48 typedef std::map<std::string, PermissionsMap> ExtensionPermissionsMap; |
43 | 49 |
50 // A map of message name to message. | |
51 typedef std::map<std::string, std::string> L10nMessagesMap; | |
52 | |
53 // A map of extension ID to l10n message map. | |
54 typedef std::map<std::string, L10nMessagesMap > | |
55 ExtensionToL10nMessagesMap; | |
56 | |
44 const char kExtensionName[] = "chrome/ExtensionProcessBindings"; | 57 const char kExtensionName[] = "chrome/ExtensionProcessBindings"; |
45 const char* kExtensionDeps[] = { | 58 const char* kExtensionDeps[] = { |
46 BaseJsV8Extension::kName, | 59 BaseJsV8Extension::kName, |
47 EventBindings::kName, | 60 EventBindings::kName, |
48 JsonSchemaJsV8Extension::kName, | 61 JsonSchemaJsV8Extension::kName, |
49 RendererExtensionBindings::kName, | 62 RendererExtensionBindings::kName, |
50 ExtensionApiTestV8Extension::kName, | 63 ExtensionApiTestV8Extension::kName, |
51 }; | 64 }; |
52 | 65 |
53 struct SingletonData { | 66 struct SingletonData { |
54 std::set<std::string> function_names_; | 67 std::set<std::string> function_names_; |
55 PageActionIdMap page_action_ids_; | 68 PageActionIdMap page_action_ids_; |
56 ExtensionPermissionsMap permissions_; | 69 ExtensionPermissionsMap permissions_; |
70 ExtensionToL10nMessagesMap extension_l10n_messages_map_; | |
57 }; | 71 }; |
58 | 72 |
59 static std::set<std::string>* GetFunctionNameSet() { | 73 static std::set<std::string>* GetFunctionNameSet() { |
60 return &Singleton<SingletonData>()->function_names_; | 74 return &Singleton<SingletonData>()->function_names_; |
61 } | 75 } |
62 | 76 |
63 static PageActionIdMap* GetPageActionMap() { | 77 static PageActionIdMap* GetPageActionMap() { |
64 return &Singleton<SingletonData>()->page_action_ids_; | 78 return &Singleton<SingletonData>()->page_action_ids_; |
65 } | 79 } |
66 | 80 |
67 static PermissionsMap* GetPermissionsMap(const std::string& extension_id) { | 81 static PermissionsMap* GetPermissionsMap(const std::string& extension_id) { |
68 return &Singleton<SingletonData>()->permissions_[extension_id]; | 82 return &Singleton<SingletonData>()->permissions_[extension_id]; |
69 } | 83 } |
70 | 84 |
85 static ExtensionToL10nMessagesMap* GetExtensionToL10nMessagesMap() { | |
86 return &Singleton<SingletonData>()->extension_l10n_messages_map_; | |
87 } | |
88 | |
89 static L10nMessagesMap* GetL10nMessagesMap(const std::string extension_id) { | |
90 ExtensionToL10nMessagesMap::iterator it = | |
91 Singleton<SingletonData>()->extension_l10n_messages_map_.find(extension_id); | |
92 if (it != Singleton<SingletonData>()->extension_l10n_messages_map_.end()) { | |
93 return &(it->second); | |
94 } else { | |
95 return NULL; | |
96 } | |
97 } | |
98 | |
71 class ExtensionImpl : public ExtensionBase { | 99 class ExtensionImpl : public ExtensionBase { |
72 public: | 100 public: |
73 ExtensionImpl() : ExtensionBase( | 101 ExtensionImpl() : ExtensionBase( |
74 kExtensionName, GetStringResource<IDR_EXTENSION_PROCESS_BINDINGS_JS>(), | 102 kExtensionName, GetStringResource<IDR_EXTENSION_PROCESS_BINDINGS_JS>(), |
75 arraysize(kExtensionDeps), kExtensionDeps) {} | 103 arraysize(kExtensionDeps), kExtensionDeps) {} |
76 | 104 |
77 static void SetFunctionNames(const std::vector<std::string>& names) { | 105 static void SetFunctionNames(const std::vector<std::string>& names) { |
78 std::set<std::string>* name_set = GetFunctionNameSet(); | 106 std::set<std::string>* name_set = GetFunctionNameSet(); |
79 for (size_t i = 0; i < names.size(); ++i) { | 107 for (size_t i = 0; i < names.size(); ++i) { |
80 name_set->insert(names[i]); | 108 name_set->insert(names[i]); |
(...skipping 21 matching lines...) Expand all Loading... | |
102 } else if (name->Equals(v8::String::New("GetNextRequestId"))) { | 130 } else if (name->Equals(v8::String::New("GetNextRequestId"))) { |
103 return v8::FunctionTemplate::New(GetNextRequestId); | 131 return v8::FunctionTemplate::New(GetNextRequestId); |
104 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { | 132 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { |
105 return v8::FunctionTemplate::New(OpenChannelToTab); | 133 return v8::FunctionTemplate::New(OpenChannelToTab); |
106 } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) { | 134 } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) { |
107 return v8::FunctionTemplate::New(GetCurrentPageActions); | 135 return v8::FunctionTemplate::New(GetCurrentPageActions); |
108 } else if (name->Equals(v8::String::New("StartRequest"))) { | 136 } else if (name->Equals(v8::String::New("StartRequest"))) { |
109 return v8::FunctionTemplate::New(StartRequest); | 137 return v8::FunctionTemplate::New(StartRequest); |
110 } else if (name->Equals(v8::String::New("GetRenderViewId"))) { | 138 } else if (name->Equals(v8::String::New("GetRenderViewId"))) { |
111 return v8::FunctionTemplate::New(GetRenderViewId); | 139 return v8::FunctionTemplate::New(GetRenderViewId); |
140 } else if (name->Equals(v8::String::New("GetL10nMessage"))) { | |
141 return v8::FunctionTemplate::New(GetL10nMessage); | |
112 } | 142 } |
113 | 143 |
114 return ExtensionBase::GetNativeFunction(name); | 144 return ExtensionBase::GetNativeFunction(name); |
115 } | 145 } |
116 | 146 |
117 private: | 147 private: |
118 static v8::Handle<v8::Value> GetExtensionAPIDefinition( | 148 static v8::Handle<v8::Value> GetExtensionAPIDefinition( |
119 const v8::Arguments& args) { | 149 const v8::Arguments& args) { |
120 return v8::String::New(GetStringResource<IDR_EXTENSION_API_JSON>()); | 150 return v8::String::New(GetStringResource<IDR_EXTENSION_API_JSON>()); |
121 } | 151 } |
122 | 152 |
123 // Returns true is |type| "isa" |match|. | 153 // Returns true is |type| "isa" |match|. |
124 static bool ViewTypeMatches(ViewType::Type type, ViewType::Type match) { | 154 static bool ViewTypeMatches(ViewType::Type type, ViewType::Type match) { |
125 if (type == match) | 155 if (type == match) |
126 return true; | 156 return true; |
127 | 157 |
128 // INVALID means match all. | 158 // INVALID means match all. |
129 if (match == ViewType::INVALID) | 159 if (match == ViewType::INVALID) |
130 return true; | 160 return true; |
131 | 161 |
132 // TODO(erikkay) for now, special case mole as a type of toolstrip. | 162 // TODO(erikkay) for now, special case mole as a type of toolstrip. |
133 // Perhaps this isn't the right long-term thing to do. | 163 // Perhaps this isn't the right long-term thing to do. |
134 if (match == ViewType::EXTENSION_TOOLSTRIP && | 164 if (match == ViewType::EXTENSION_TOOLSTRIP && |
135 type == ViewType::EXTENSION_MOLE) { | 165 type == ViewType::EXTENSION_MOLE) { |
136 return true; | 166 return true; |
137 } | 167 } |
138 | 168 |
139 return false; | 169 return false; |
140 } | 170 } |
141 | 171 |
142 static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) { | 172 static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) { |
143 if (args.Length() != 2) | 173 if (args.Length() != 2) |
144 return v8::Undefined(); | 174 return v8::Undefined(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 v8::Local<v8::Array> page_action_vector = v8::Array::New(size); | 278 v8::Local<v8::Array> page_action_vector = v8::Array::New(size); |
249 for (size_t i = 0; i < size; ++i) { | 279 for (size_t i = 0; i < size; ++i) { |
250 std::string page_action_id = page_actions[i]; | 280 std::string page_action_id = page_actions[i]; |
251 page_action_vector->Set(v8::Integer::New(i), | 281 page_action_vector->Set(v8::Integer::New(i), |
252 v8::String::New(page_action_id.c_str())); | 282 v8::String::New(page_action_id.c_str())); |
253 } | 283 } |
254 | 284 |
255 return page_action_vector; | 285 return page_action_vector; |
256 } | 286 } |
257 | 287 |
288 static v8::Handle<v8::Value> GetL10nMessage(const v8::Arguments& args) { | |
289 if (args.Length() != 2 || !args[0]->IsString()) | |
Erik does not do reviews
2009/09/26 00:35:48
NOTREACHED()
| |
290 return v8::String::New(""); | |
Erik does not do reviews
2009/09/26 00:35:48
return V8::Undefined instead (and the other places
| |
291 | |
292 L10nMessagesMap* l10n_messages = | |
293 GetL10nMessagesMap(ExtensionIdForCurrentContext()); | |
294 if (!l10n_messages) | |
295 return v8::String::New(""); | |
296 | |
297 std::string message_name = *v8::String::AsciiValue(args[0]); | |
298 std::string message = | |
299 ExtensionMessageBundle::GetL10nMessage(message_name, *l10n_messages); | |
300 | |
301 std::vector<string16> substitutions; | |
302 if (args[1]->IsNull() || args[1]->IsUndefined()) { | |
303 // chrome.i18n.getMessage("message_name"); | |
304 // chrome.i18n.getMessage("message_name", null); | |
305 return v8::String::New(message.c_str()); | |
306 } else if (args[1]->IsString()) { | |
307 // chrome.i18n.getMessage("message_name", "one param"); | |
308 std::string substitute = *v8::String::Utf8Value(args[1]->ToString()); | |
309 substitutions.push_back(UTF8ToUTF16(substitute)); | |
310 } else if (args[1]->IsArray()) { | |
311 // chrome.i18n.getMessage("message_name", ["more", "params"]); | |
312 v8::Array* placeholders = static_cast<v8::Array*>(*args[1]); | |
Erik does not do reviews
2009/09/26 00:35:48
verify that the length of placeholders is > 0 and
| |
313 for (uint32_t i = 0; i < placeholders->Length(); ++i) { | |
314 std::string substitute = | |
315 *v8::String::Utf8Value( | |
316 placeholders->Get(v8::Integer::New(i))->ToString()); | |
317 substitutions.push_back(UTF8ToUTF16(substitute)); | |
318 } | |
319 } else { | |
Erik does not do reviews
2009/09/26 00:35:48
NOTREACHED()
| |
320 return v8::String::New(""); | |
321 } | |
322 | |
323 return v8::String::New(UTF16ToUTF8(ReplaceStringPlaceholders( | |
324 UTF8ToUTF16(message), substitutions, NULL)).c_str()); | |
325 } | |
326 | |
258 // Starts an API request to the browser, with an optional callback. The | 327 // Starts an API request to the browser, with an optional callback. The |
259 // callback will be dispatched to EventBindings::HandleResponse. | 328 // callback will be dispatched to EventBindings::HandleResponse. |
260 static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { | 329 static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { |
261 // Get the current RenderView so that we can send a routed IPC message from | 330 // Get the current RenderView so that we can send a routed IPC message from |
262 // the correct source. | 331 // the correct source. |
263 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); | 332 RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); |
264 if (!renderview) | 333 if (!renderview) |
265 return v8::Undefined(); | 334 return v8::Undefined(); |
266 | 335 |
267 if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsString() || | 336 if (args.Length() != 4 || !args[0]->IsString() || !args[1]->IsString() || |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 | 393 |
325 v8::HandleScope handle_scope; | 394 v8::HandleScope handle_scope; |
326 v8::Handle<v8::Value> argv[5]; | 395 v8::Handle<v8::Value> argv[5]; |
327 argv[0] = v8::Integer::New(request_id); | 396 argv[0] = v8::Integer::New(request_id); |
328 argv[1] = v8::String::New(request->second->name.c_str()); | 397 argv[1] = v8::String::New(request->second->name.c_str()); |
329 argv[2] = v8::Boolean::New(success); | 398 argv[2] = v8::Boolean::New(success); |
330 argv[3] = v8::String::New(response.c_str()); | 399 argv[3] = v8::String::New(response.c_str()); |
331 argv[4] = v8::String::New(error.c_str()); | 400 argv[4] = v8::String::New(error.c_str()); |
332 v8::Handle<v8::Value> retval = bindings_utils::CallFunctionInContext( | 401 v8::Handle<v8::Value> retval = bindings_utils::CallFunctionInContext( |
333 request->second->context, "handleResponse", arraysize(argv), argv); | 402 request->second->context, "handleResponse", arraysize(argv), argv); |
334 // In debug, the js will validate the callback parameters and return a | 403 // In debug, the js will validate the callback parameters and return a |
335 // string if a validation error has occured. | 404 // string if a validation error has occured. |
336 #ifdef _DEBUG | 405 #ifdef _DEBUG |
337 if (!retval.IsEmpty() && !retval->IsUndefined()) { | 406 if (!retval.IsEmpty() && !retval->IsUndefined()) { |
338 std::string error = *v8::String::AsciiValue(retval); | 407 std::string error = *v8::String::AsciiValue(retval); |
339 DCHECK(false) << error; | 408 DCHECK(false) << error; |
340 } | 409 } |
341 #endif | 410 #endif |
342 | 411 |
343 pending_requests.erase(request); | 412 pending_requests.erase(request); |
344 } | 413 } |
345 | 414 |
346 // static | 415 // static |
347 void ExtensionProcessBindings::SetPageActions( | 416 void ExtensionProcessBindings::SetPageActions( |
348 const std::string& extension_id, | 417 const std::string& extension_id, |
349 const std::vector<std::string>& page_actions) { | 418 const std::vector<std::string>& page_actions) { |
350 PageActionIdMap& page_action_map = *GetPageActionMap(); | 419 PageActionIdMap& page_action_map = *GetPageActionMap(); |
351 if (!page_actions.empty()) { | 420 if (!page_actions.empty()) { |
352 page_action_map[extension_id] = page_actions; | 421 page_action_map[extension_id] = page_actions; |
353 } else { | 422 } else { |
354 if (page_action_map.find(extension_id) != page_action_map.end()) | 423 if (page_action_map.find(extension_id) != page_action_map.end()) |
355 page_action_map.erase(extension_id); | 424 page_action_map.erase(extension_id); |
356 } | 425 } |
357 } | 426 } |
358 | 427 |
359 // static | 428 // static |
429 void ExtensionProcessBindings::SetL10nMessages( | |
430 const std::string& extension_id, | |
431 const std::map<std::string, std::string>& l10n_messages) { | |
432 ExtensionToL10nMessagesMap& l10n_messages_map = | |
433 *GetExtensionToL10nMessagesMap(); | |
434 l10n_messages_map[extension_id] = l10n_messages; | |
435 } | |
436 | |
437 // static | |
360 void ExtensionProcessBindings::SetAPIPermissions( | 438 void ExtensionProcessBindings::SetAPIPermissions( |
361 const std::string& extension_id, | 439 const std::string& extension_id, |
362 const std::vector<std::string>& permissions) { | 440 const std::vector<std::string>& permissions) { |
363 PermissionsMap& permissions_map = *GetPermissionsMap(extension_id); | 441 PermissionsMap& permissions_map = *GetPermissionsMap(extension_id); |
364 | 442 |
365 // Default all the API permissions to off. We will reset them below. | 443 // Default all the API permissions to off. We will reset them below. |
366 for (size_t i = 0; i < Extension::kNumPermissions; ++i) | 444 for (size_t i = 0; i < Extension::kNumPermissions; ++i) |
367 permissions_map[Extension::kPermissionNames[i]] = false; | 445 permissions_map[Extension::kPermissionNames[i]] = false; |
368 for (size_t i = 0; i < permissions.size(); ++i) | 446 for (size_t i = 0; i < permissions.size(); ++i) |
369 permissions_map[permissions[i]] = true; | 447 permissions_map[permissions[i]] = true; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
433 return; | 511 return; |
434 | 512 |
435 v8::HandleScope handle_scope; | 513 v8::HandleScope handle_scope; |
436 WebFrame* frame = view->GetMainFrame(); | 514 WebFrame* frame = view->GetMainFrame(); |
437 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); | 515 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); |
438 v8::Handle<v8::Value> argv[1]; | 516 v8::Handle<v8::Value> argv[1]; |
439 argv[0] = v8::String::New(type_str); | 517 argv[0] = v8::String::New(type_str); |
440 bindings_utils::CallFunctionInContext(context, "setViewType", | 518 bindings_utils::CallFunctionInContext(context, "setViewType", |
441 arraysize(argv), argv); | 519 arraysize(argv), argv); |
442 } | 520 } |
OLD | NEW |