Chromium Code Reviews| Index: chrome/browser/extensions/api/declarative_content/content_action.cc |
| diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc |
| index 751f8d53383c946c633b1ef23066a414675e8554..5e0ac57a96963b5a5ed46a511ea94af86316887c 100644 |
| --- a/chrome/browser/extensions/api/declarative_content/content_action.cc |
| +++ b/chrome/browser/extensions/api/declarative_content/content_action.cc |
| @@ -29,6 +29,9 @@ const char kInvalidInstanceTypeError[] = |
| "An action has an invalid instanceType: %s"; |
| const char kNoPageAction[] = |
| "Can't use declarativeContent.ShowPageAction without a page action"; |
| +const char kMissingParameter[] = "Missing parameter is required: %s"; |
| +const char kInvalidTypeOfParameter[] = "Attribute '%s' has an invalid type. " |
| + "Expected type: %s"; |
| #define INPUT_FORMAT_VALIDATE(test) do { \ |
| if (!(test)) { \ |
| @@ -94,6 +97,134 @@ class ShowPageAction : public ContentAction { |
| DISALLOW_COPY_AND_ASSIGN(ShowPageAction); |
| }; |
| +// Action that injects a content script. |
| +class RequestContentScript : public ContentAction { |
| + public: |
| + RequestContentScript(const std::vector<std::string>& css_file_names, |
| + const std::vector<std::string>& js_file_names, |
| + const bool all_frames, |
| + const bool match_about_blank) |
| + : css_file_names_(css_file_names), |
| + js_file_names_(js_file_names), |
| + all_frames_(all_frames), |
| + match_about_blank_(match_about_blank) {} |
| + |
| + static scoped_refptr<ContentAction> Create(const Extension* extension, |
| + const base::DictionaryValue* dict, |
| + std::string* error, |
| + bool* bad_message); |
| + |
| + // Implementation of ContentAction: |
| + virtual Type GetType() const OVERRIDE { |
| + return ACTION_REQUEST_CONTENT_SCRIPT; |
| + } |
| + |
| + virtual void Apply(const std::string& extension_id, |
| + const base::Time& extension_install_time, |
| + ApplyInfo* apply_info) const OVERRIDE { |
| + // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: |
| + // load new user script. |
| + } |
| + |
| + virtual void Revert(const std::string& extension_id, |
| + const base::Time& extension_install_time, |
| + ApplyInfo* apply_info) const OVERRIDE { |
| + // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: |
| + // do not load user script if Apply() runs again on the same page. |
| + } |
| + |
| + private: |
| + virtual ~RequestContentScript() {} |
| + |
| + std::vector<std::string> css_file_names_; |
| + std::vector<std::string> js_file_names_; |
| + bool all_frames_; |
| + bool match_about_blank_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(RequestContentScript); |
| +}; |
| + |
| +// Helper for getting JS collections into C++. |
| +static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings, |
| + std::vector<std::string>* append_to) { |
| + for (base::ListValue::const_iterator it = append_strings.begin(); |
| + it != append_strings.end(); ++it) { |
| + std::string value; |
| + if ((*it)->GetAsString(&value)) { |
| + append_to->push_back(value); |
| + } else { |
| + return false; |
| + } |
| + } |
| + |
| + return true; |
| +} |
| + |
| +// static |
| +scoped_refptr<ContentAction> RequestContentScript::Create( |
| + const Extension* extension, |
| + const base::DictionaryValue* dict, |
| + std::string* error, |
| + bool* bad_message) { |
| + std::vector<std::string> css_file_names; |
| + std::vector<std::string> js_file_names; |
| + bool all_frames = false; |
| + bool match_about_blank = false; |
| + const base::ListValue* list_value; |
| + |
| + if (!dict->HasKey(keys::kCss) && !dict->HasKey(keys::kJs)) { |
| + *error = base::StringPrintf(kMissingParameter, "css or js"); |
| + *bad_message = true; |
|
not at google - send to devlin
2014/07/16 16:51:14
FYI there's not much point setting both bad_messag
Mark Dittmer
2014/07/16 19:40:45
Done. I use error instead of bad_message for "has
|
| + return scoped_refptr<ContentAction>(); |
| + } |
| + |
| + if (dict->HasKey(keys::kCss)) { |
| + if (!dict->GetList(keys::kCss, &list_value) || |
| + !AppendJSStringsToCPPStrings(*list_value, &css_file_names)) { |
| + *error = base::StringPrintf(kInvalidTypeOfParameter, |
| + keys::kCss, |
| + "Array of strings"); |
| + *bad_message = true; |
| + return scoped_refptr<ContentAction>(); |
|
not at google - send to devlin
2014/07/16 16:51:14
indentation is off here, you should run "git cl fo
Mark Dittmer
2014/07/16 19:40:45
Done.
|
| + } |
| + } |
| + |
| + if (dict->HasKey(keys::kJs)) { |
| + if (!dict->GetList(keys::kJs, &list_value) || |
| + !AppendJSStringsToCPPStrings(*list_value, &js_file_names)) { |
| + *error = base::StringPrintf(kInvalidTypeOfParameter, |
| + keys::kJs, |
| + "Array of strings"); |
| + *bad_message = true; |
| + return scoped_refptr<ContentAction>(); |
| + } |
| + } |
| + |
| + if (dict->HasKey(keys::kAllFrames) && |
| + !dict->GetBoolean(keys::kAllFrames, &all_frames)) { |
| + *error = base::StringPrintf(kInvalidTypeOfParameter, |
| + keys::kAllFrames, |
| + "Boolean"); |
| + *bad_message = true; |
| + return scoped_refptr<ContentAction>(); |
| + } |
| + |
| + if (dict->HasKey(keys::kMatchAboutBlank) && |
| + !dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank)) { |
| + *error = base::StringPrintf(kInvalidTypeOfParameter, |
| + keys::kMatchAboutBlank, |
| + "Boolean"); |
| + *bad_message = true; |
| + return scoped_refptr<ContentAction>(); |
| + } |
| + |
| + return scoped_refptr<ContentAction>(new RequestContentScript( |
| + css_file_names, |
| + js_file_names, |
| + all_frames, |
| + match_about_blank)); |
| +} |
| + |
| struct ContentActionFactory { |
| // Factory methods for ContentAction instances. |extension| is the extension |
| // for which the action is being created. |dict| contains the json dictionary |
| @@ -113,6 +244,8 @@ struct ContentActionFactory { |
| ContentActionFactory() { |
| factory_methods[keys::kShowPageAction] = |
| &ShowPageAction::Create; |
| + factory_methods[keys::kRequestContentScript] = |
| + &RequestContentScript::Create; |
| } |
| }; |