Chromium Code Reviews| 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 |