OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/browser/extensions/api/declarative_content/content_action.h" | 5 #include "chrome/browser/extensions/api/declarative_content/content_action.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 // The following are concrete actions. | 55 // The following are concrete actions. |
56 // | 56 // |
57 | 57 |
58 // Action that instructs to show an extension's page action. | 58 // Action that instructs to show an extension's page action. |
59 class ShowPageAction : public ContentAction { | 59 class ShowPageAction : public ContentAction { |
60 public: | 60 public: |
61 ShowPageAction() {} | 61 ShowPageAction() {} |
62 | 62 |
63 static scoped_refptr<ContentAction> Create( | 63 static scoped_refptr<ContentAction> Create( |
64 content::BrowserContext* browser_context, | 64 content::BrowserContext* browser_context, |
65 const HostID& host_id, | |
66 const Extension* extension, | 65 const Extension* extension, |
67 const base::DictionaryValue* dict, | 66 const base::DictionaryValue* dict, |
68 std::string* error, | 67 std::string* error, |
69 bool* bad_message) { | 68 bool* bad_message) { |
70 // We can't show a page action if the extension doesn't have one. | 69 // We can't show a page action if the extension doesn't have one. |
71 if (ActionInfo::GetPageActionInfo(extension) == NULL) { | 70 if (ActionInfo::GetPageActionInfo(extension) == NULL) { |
72 *error = kNoPageAction; | 71 *error = kNoPageAction; |
73 return scoped_refptr<ContentAction>(); | 72 return scoped_refptr<ContentAction>(); |
74 } | 73 } |
75 return scoped_refptr<ContentAction>(new ShowPageAction); | 74 return scoped_refptr<ContentAction>(new ShowPageAction); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 }; | 118 }; |
120 | 119 |
121 // Action that sets an extension's action icon. | 120 // Action that sets an extension's action icon. |
122 class SetIcon : public ContentAction { | 121 class SetIcon : public ContentAction { |
123 public: | 122 public: |
124 SetIcon(const gfx::Image& icon, ActionInfo::Type action_type) | 123 SetIcon(const gfx::Image& icon, ActionInfo::Type action_type) |
125 : icon_(icon), action_type_(action_type) {} | 124 : icon_(icon), action_type_(action_type) {} |
126 | 125 |
127 static scoped_refptr<ContentAction> Create( | 126 static scoped_refptr<ContentAction> Create( |
128 content::BrowserContext* browser_context, | 127 content::BrowserContext* browser_context, |
129 const HostID& host_id, | |
130 const Extension* extension, | 128 const Extension* extension, |
131 const base::DictionaryValue* dict, | 129 const base::DictionaryValue* dict, |
132 std::string* error, | 130 std::string* error, |
133 bool* bad_message); | 131 bool* bad_message); |
134 | 132 |
135 // Implementation of ContentAction: | 133 // Implementation of ContentAction: |
136 Type GetType() const override { return ACTION_SET_ICON; } | 134 Type GetType() const override { return ACTION_SET_ICON; } |
137 void Apply(const std::string& extension_id, | 135 void Apply(const std::string& extension_id, |
138 const base::Time& extension_install_time, | 136 const base::Time& extension_install_time, |
139 ApplyInfo* apply_info) const override { | 137 ApplyInfo* apply_info) const override { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 | 211 |
214 struct ContentActionFactory { | 212 struct ContentActionFactory { |
215 // Factory methods for ContentAction instances. |extension| is the extension | 213 // Factory methods for ContentAction instances. |extension| is the extension |
216 // for which the action is being created. |dict| contains the json dictionary | 214 // for which the action is being created. |dict| contains the json dictionary |
217 // that describes the action. |error| is used to return error messages in case | 215 // that describes the action. |error| is used to return error messages in case |
218 // the extension passed an action that was syntactically correct but | 216 // the extension passed an action that was syntactically correct but |
219 // semantically incorrect. |bad_message| is set to true in case |dict| does | 217 // semantically incorrect. |bad_message| is set to true in case |dict| does |
220 // not confirm to the validated JSON specification. | 218 // not confirm to the validated JSON specification. |
221 typedef scoped_refptr<ContentAction>(*FactoryMethod)( | 219 typedef scoped_refptr<ContentAction>(*FactoryMethod)( |
222 content::BrowserContext* /* browser_context */, | 220 content::BrowserContext* /* browser_context */, |
223 const HostID& host_id /* host id */, | |
224 const Extension* /* extension */, | 221 const Extension* /* extension */, |
225 const base::DictionaryValue* /* dict */, | 222 const base::DictionaryValue* /* dict */, |
226 std::string* /* error */, | 223 std::string* /* error */, |
227 bool* /* bad_message */); | 224 bool* /* bad_message */); |
228 // Maps the name of a declarativeContent action type to the factory | 225 // Maps the name of a declarativeContent action type to the factory |
229 // function creating it. | 226 // function creating it. |
230 std::map<std::string, FactoryMethod> factory_methods; | 227 std::map<std::string, FactoryMethod> factory_methods; |
231 | 228 |
232 ContentActionFactory() { | 229 ContentActionFactory() { |
233 factory_methods[keys::kShowPageAction] = | 230 factory_methods[keys::kShowPageAction] = |
(...skipping 25 matching lines...) Expand all Loading... |
259 }; | 256 }; |
260 | 257 |
261 RequestContentScript::ScriptData::ScriptData() | 258 RequestContentScript::ScriptData::ScriptData() |
262 : all_frames(false), | 259 : all_frames(false), |
263 match_about_blank(false) {} | 260 match_about_blank(false) {} |
264 RequestContentScript::ScriptData::~ScriptData() {} | 261 RequestContentScript::ScriptData::~ScriptData() {} |
265 | 262 |
266 // static | 263 // static |
267 scoped_refptr<ContentAction> RequestContentScript::Create( | 264 scoped_refptr<ContentAction> RequestContentScript::Create( |
268 content::BrowserContext* browser_context, | 265 content::BrowserContext* browser_context, |
269 const HostID& host_id, | |
270 const Extension* extension, | 266 const Extension* extension, |
271 const base::DictionaryValue* dict, | 267 const base::DictionaryValue* dict, |
272 std::string* error, | 268 std::string* error, |
273 bool* bad_message) { | 269 bool* bad_message) { |
274 ScriptData script_data; | 270 ScriptData script_data; |
275 if (!InitScriptData(dict, error, bad_message, &script_data)) | 271 if (!InitScriptData(dict, error, bad_message, &script_data)) |
276 return scoped_refptr<ContentAction>(); | 272 return scoped_refptr<ContentAction>(); |
277 | 273 |
278 return scoped_refptr<ContentAction>(new RequestContentScript( | 274 return scoped_refptr<ContentAction>(new RequestContentScript( |
279 browser_context, | 275 browser_context, |
280 host_id, | |
281 extension, | 276 extension, |
282 script_data)); | 277 script_data)); |
283 } | 278 } |
284 | 279 |
285 // static | 280 // static |
286 scoped_refptr<ContentAction> RequestContentScript::CreateForTest( | 281 scoped_refptr<ContentAction> RequestContentScript::CreateForTest( |
287 DeclarativeUserScriptMaster* master, | 282 DeclarativeUserScriptMaster* master, |
288 const HostID& host_id, | |
289 const Extension* extension, | 283 const Extension* extension, |
290 const base::Value& json_action, | 284 const base::Value& json_action, |
291 std::string* error, | 285 std::string* error, |
292 bool* bad_message) { | 286 bool* bad_message) { |
293 // Simulate ContentAction-level initialization. Check that instance type is | 287 // Simulate ContentAction-level initialization. Check that instance type is |
294 // RequestContentScript. | 288 // RequestContentScript. |
295 ContentAction::ResetErrorData(error, bad_message); | 289 ContentAction::ResetErrorData(error, bad_message); |
296 const base::DictionaryValue* action_dict = NULL; | 290 const base::DictionaryValue* action_dict = NULL; |
297 std::string instance_type; | 291 std::string instance_type; |
298 if (!ContentAction::Validate( | 292 if (!ContentAction::Validate( |
299 json_action, | 293 json_action, |
300 error, | 294 error, |
301 bad_message, | 295 bad_message, |
302 &action_dict, | 296 &action_dict, |
303 &instance_type) || | 297 &instance_type) || |
304 instance_type != std::string(keys::kRequestContentScript)) | 298 instance_type != std::string(keys::kRequestContentScript)) |
305 return scoped_refptr<ContentAction>(); | 299 return scoped_refptr<ContentAction>(); |
306 | 300 |
307 // Normal RequestContentScript data initialization. | 301 // Normal RequestContentScript data initialization. |
308 ScriptData script_data; | 302 ScriptData script_data; |
309 if (!InitScriptData(action_dict, error, bad_message, &script_data)) | 303 if (!InitScriptData(action_dict, error, bad_message, &script_data)) |
310 return scoped_refptr<ContentAction>(); | 304 return scoped_refptr<ContentAction>(); |
311 | 305 |
312 // Inject provided DeclarativeUserScriptMaster, rather than looking it up | 306 // Inject provided DeclarativeUserScriptMaster, rather than looking it up |
313 // using a BrowserContext. | 307 // using a BrowserContext. |
314 return scoped_refptr<ContentAction>(new RequestContentScript( | 308 return scoped_refptr<ContentAction>(new RequestContentScript( |
315 master, | 309 master, |
316 host_id, | |
317 extension, | 310 extension, |
318 script_data)); | 311 script_data)); |
319 } | 312 } |
320 | 313 |
321 // static | 314 // static |
322 bool RequestContentScript::InitScriptData(const base::DictionaryValue* dict, | 315 bool RequestContentScript::InitScriptData(const base::DictionaryValue* dict, |
323 std::string* error, | 316 std::string* error, |
324 bool* bad_message, | 317 bool* bad_message, |
325 ScriptData* script_data) { | 318 ScriptData* script_data) { |
326 const base::ListValue* list_value = NULL; | 319 const base::ListValue* list_value = NULL; |
(...skipping 21 matching lines...) Expand all Loading... |
348 dict->GetBoolean( | 341 dict->GetBoolean( |
349 keys::kMatchAboutBlank, | 342 keys::kMatchAboutBlank, |
350 &script_data->match_about_blank)); | 343 &script_data->match_about_blank)); |
351 } | 344 } |
352 | 345 |
353 return true; | 346 return true; |
354 } | 347 } |
355 | 348 |
356 RequestContentScript::RequestContentScript( | 349 RequestContentScript::RequestContentScript( |
357 content::BrowserContext* browser_context, | 350 content::BrowserContext* browser_context, |
358 const HostID& host_id, | |
359 const Extension* extension, | 351 const Extension* extension, |
360 const ScriptData& script_data) { | 352 const ScriptData& script_data) { |
361 InitScript(host_id, extension, script_data); | 353 InitScript(extension, script_data); |
362 | 354 |
363 master_ = ExtensionSystem::Get(browser_context) | 355 master_ = ExtensionSystem::Get(browser_context) |
364 ->declarative_user_script_manager() | 356 ->declarative_user_script_manager() |
365 ->GetDeclarativeUserScriptMasterByID(host_id); | 357 ->GetDeclarativeUserScriptMasterByID(extension->id()); |
366 AddScript(); | 358 AddScript(); |
367 } | 359 } |
368 | 360 |
369 RequestContentScript::RequestContentScript( | 361 RequestContentScript::RequestContentScript( |
370 DeclarativeUserScriptMaster* master, | 362 DeclarativeUserScriptMaster* master, |
371 const HostID& host_id, | |
372 const Extension* extension, | 363 const Extension* extension, |
373 const ScriptData& script_data) { | 364 const ScriptData& script_data) { |
374 InitScript(host_id, extension, script_data); | 365 InitScript(extension, script_data); |
375 | 366 |
376 master_ = master; | 367 master_ = master; |
377 AddScript(); | 368 AddScript(); |
378 } | 369 } |
379 | 370 |
380 RequestContentScript::~RequestContentScript() { | 371 RequestContentScript::~RequestContentScript() { |
381 DCHECK(master_); | 372 DCHECK(master_); |
382 master_->RemoveScript(script_); | 373 master_->RemoveScript(script_); |
383 } | 374 } |
384 | 375 |
385 void RequestContentScript::InitScript(const HostID& host_id, | 376 void RequestContentScript::InitScript(const Extension* extension, |
386 const Extension* extension, | |
387 const ScriptData& script_data) { | 377 const ScriptData& script_data) { |
388 script_.set_id(UserScript::GenerateUserScriptID()); | 378 script_.set_id(UserScript::GenerateUserScriptID()); |
389 script_.set_host_id(host_id); | 379 script_.set_extension_id(extension->id()); |
390 script_.set_run_location(UserScript::BROWSER_DRIVEN); | 380 script_.set_run_location(UserScript::BROWSER_DRIVEN); |
391 script_.set_match_all_frames(script_data.all_frames); | 381 script_.set_match_all_frames(script_data.all_frames); |
392 script_.set_match_about_blank(script_data.match_about_blank); | 382 script_.set_match_about_blank(script_data.match_about_blank); |
393 for (std::vector<std::string>::const_iterator it = | 383 for (std::vector<std::string>::const_iterator it = |
394 script_data.css_file_names.begin(); | 384 script_data.css_file_names.begin(); |
395 it != script_data.css_file_names.end(); ++it) { | 385 it != script_data.css_file_names.end(); ++it) { |
396 GURL url = extension->GetResourceURL(*it); | 386 GURL url = extension->GetResourceURL(*it); |
397 ExtensionResource resource = extension->GetResource(*it); | 387 ExtensionResource resource = extension->GetResource(*it); |
398 script_.css_scripts().push_back(UserScript::File( | 388 script_.css_scripts().push_back(UserScript::File( |
399 resource.extension_root(), resource.relative_path(), url)); | 389 resource.extension_root(), resource.relative_path(), url)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 render_view_host->GetRoutingID(), | 426 render_view_host->GetRoutingID(), |
437 SessionTabHelper::IdForTab(contents), | 427 SessionTabHelper::IdForTab(contents), |
438 extension_id, | 428 extension_id, |
439 script_.id(), | 429 script_.id(), |
440 contents->GetLastCommittedURL())); | 430 contents->GetLastCommittedURL())); |
441 } | 431 } |
442 | 432 |
443 // static | 433 // static |
444 scoped_refptr<ContentAction> SetIcon::Create( | 434 scoped_refptr<ContentAction> SetIcon::Create( |
445 content::BrowserContext* browser_context, | 435 content::BrowserContext* browser_context, |
446 const HostID& host_id, | |
447 const Extension* extension, | 436 const Extension* extension, |
448 const base::DictionaryValue* dict, | 437 const base::DictionaryValue* dict, |
449 std::string* error, | 438 std::string* error, |
450 bool* bad_message) { | 439 bool* bad_message) { |
451 // We can't set a page or action's icon if the extension doesn't have one. | 440 // We can't set a page or action's icon if the extension doesn't have one. |
452 ActionInfo::Type type; | 441 ActionInfo::Type type; |
453 if (ActionInfo::GetPageActionInfo(extension) != NULL) { | 442 if (ActionInfo::GetPageActionInfo(extension) != NULL) { |
454 type = ActionInfo::TYPE_PAGE; | 443 type = ActionInfo::TYPE_PAGE; |
455 } else if (ActionInfo::GetBrowserActionInfo(extension) != NULL) { | 444 } else if (ActionInfo::GetBrowserActionInfo(extension) != NULL) { |
456 type = ActionInfo::TYPE_BROWSER; | 445 type = ActionInfo::TYPE_BROWSER; |
(...skipping 17 matching lines...) Expand all Loading... |
474 // ContentAction | 463 // ContentAction |
475 // | 464 // |
476 | 465 |
477 ContentAction::ContentAction() {} | 466 ContentAction::ContentAction() {} |
478 | 467 |
479 ContentAction::~ContentAction() {} | 468 ContentAction::~ContentAction() {} |
480 | 469 |
481 // static | 470 // static |
482 scoped_refptr<ContentAction> ContentAction::Create( | 471 scoped_refptr<ContentAction> ContentAction::Create( |
483 content::BrowserContext* browser_context, | 472 content::BrowserContext* browser_context, |
484 const HostID& host_id, | |
485 const Extension* extension, | 473 const Extension* extension, |
486 const base::Value& json_action, | 474 const base::Value& json_action, |
487 std::string* error, | 475 std::string* error, |
488 bool* bad_message) { | 476 bool* bad_message) { |
489 ResetErrorData(error, bad_message); | 477 ResetErrorData(error, bad_message); |
490 const base::DictionaryValue* action_dict = NULL; | 478 const base::DictionaryValue* action_dict = NULL; |
491 std::string instance_type; | 479 std::string instance_type; |
492 if (!Validate(json_action, error, bad_message, &action_dict, &instance_type)) | 480 if (!Validate(json_action, error, bad_message, &action_dict, &instance_type)) |
493 return scoped_refptr<ContentAction>(); | 481 return scoped_refptr<ContentAction>(); |
494 | 482 |
495 ContentActionFactory& factory = g_content_action_factory.Get(); | 483 ContentActionFactory& factory = g_content_action_factory.Get(); |
496 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator | 484 std::map<std::string, ContentActionFactory::FactoryMethod>::iterator |
497 factory_method_iter = factory.factory_methods.find(instance_type); | 485 factory_method_iter = factory.factory_methods.find(instance_type); |
498 if (factory_method_iter != factory.factory_methods.end()) | 486 if (factory_method_iter != factory.factory_methods.end()) |
499 return (*factory_method_iter->second)( | 487 return (*factory_method_iter->second)( |
500 browser_context, host_id, extension, action_dict, error, bad_message); | 488 browser_context, extension, action_dict, error, bad_message); |
501 | 489 |
502 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); | 490 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); |
503 return scoped_refptr<ContentAction>(); | 491 return scoped_refptr<ContentAction>(); |
504 } | 492 } |
505 | 493 |
506 bool ContentAction::Validate(const base::Value& json_action, | 494 bool ContentAction::Validate(const base::Value& json_action, |
507 std::string* error, | 495 std::string* error, |
508 bool* bad_message, | 496 bool* bad_message, |
509 const base::DictionaryValue** action_dict, | 497 const base::DictionaryValue** action_dict, |
510 std::string* instance_type) { | 498 std::string* instance_type) { |
511 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(action_dict)); | 499 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(action_dict)); |
512 INPUT_FORMAT_VALIDATE( | 500 INPUT_FORMAT_VALIDATE( |
513 (*action_dict)->GetString(keys::kInstanceType, instance_type)); | 501 (*action_dict)->GetString(keys::kInstanceType, instance_type)); |
514 return true; | 502 return true; |
515 } | 503 } |
516 | 504 |
517 } // namespace extensions | 505 } // namespace extensions |
OLD | NEW |