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 11 matching lines...) Expand all Loading... |
22 namespace extensions { | 22 namespace extensions { |
23 | 23 |
24 namespace keys = declarative_content_constants; | 24 namespace keys = declarative_content_constants; |
25 | 25 |
26 namespace { | 26 namespace { |
27 // Error messages. | 27 // Error messages. |
28 const char kInvalidInstanceTypeError[] = | 28 const char kInvalidInstanceTypeError[] = |
29 "An action has an invalid instanceType: %s"; | 29 "An action has an invalid instanceType: %s"; |
30 const char kNoPageAction[] = | 30 const char kNoPageAction[] = |
31 "Can't use declarativeContent.ShowPageAction without a page action"; | 31 "Can't use declarativeContent.ShowPageAction without a page action"; |
| 32 const char kMissingParameter[] = "Missing parameter is required: %s"; |
32 | 33 |
33 #define INPUT_FORMAT_VALIDATE(test) do { \ | 34 #define INPUT_FORMAT_VALIDATE(test) do { \ |
34 if (!(test)) { \ | 35 if (!(test)) { \ |
35 *bad_message = true; \ | 36 *bad_message = true; \ |
36 return scoped_refptr<ContentAction>(NULL); \ | 37 return scoped_refptr<ContentAction>(NULL); \ |
37 } \ | 38 } \ |
38 } while (0) | 39 } while (0) |
39 | 40 |
40 // | 41 // |
41 // The following are concrete actions. | 42 // The following are concrete actions. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); | 88 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); |
88 if (!extension) | 89 if (!extension) |
89 return NULL; | 90 return NULL; |
90 return ExtensionActionManager::Get(profile)->GetPageAction(*extension); | 91 return ExtensionActionManager::Get(profile)->GetPageAction(*extension); |
91 } | 92 } |
92 virtual ~ShowPageAction() {} | 93 virtual ~ShowPageAction() {} |
93 | 94 |
94 DISALLOW_COPY_AND_ASSIGN(ShowPageAction); | 95 DISALLOW_COPY_AND_ASSIGN(ShowPageAction); |
95 }; | 96 }; |
96 | 97 |
| 98 // Action that injects a content script. |
| 99 class RequestContentScript : public ContentAction { |
| 100 public: |
| 101 RequestContentScript(const std::vector<std::string>& css_file_names, |
| 102 const std::vector<std::string>& js_file_names, |
| 103 bool all_frames, |
| 104 bool match_about_blank) |
| 105 : css_file_names_(css_file_names), |
| 106 js_file_names_(js_file_names), |
| 107 all_frames_(all_frames), |
| 108 match_about_blank_(match_about_blank) {} |
| 109 |
| 110 static scoped_refptr<ContentAction> Create(const Extension* extension, |
| 111 const base::DictionaryValue* dict, |
| 112 std::string* error, |
| 113 bool* bad_message); |
| 114 |
| 115 // Implementation of ContentAction: |
| 116 virtual Type GetType() const OVERRIDE { |
| 117 return ACTION_REQUEST_CONTENT_SCRIPT; |
| 118 } |
| 119 |
| 120 virtual void Apply(const std::string& extension_id, |
| 121 const base::Time& extension_install_time, |
| 122 ApplyInfo* apply_info) const OVERRIDE { |
| 123 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: |
| 124 // load new user script. |
| 125 } |
| 126 |
| 127 virtual void Revert(const std::string& extension_id, |
| 128 const base::Time& extension_install_time, |
| 129 ApplyInfo* apply_info) const OVERRIDE { |
| 130 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: |
| 131 // do not load user script if Apply() runs again on the same page. |
| 132 } |
| 133 |
| 134 private: |
| 135 virtual ~RequestContentScript() {} |
| 136 |
| 137 std::vector<std::string> css_file_names_; |
| 138 std::vector<std::string> js_file_names_; |
| 139 bool all_frames_; |
| 140 bool match_about_blank_; |
| 141 |
| 142 DISALLOW_COPY_AND_ASSIGN(RequestContentScript); |
| 143 }; |
| 144 |
| 145 // Helper for getting JS collections into C++. |
| 146 static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings, |
| 147 std::vector<std::string>* append_to) { |
| 148 for (base::ListValue::const_iterator it = append_strings.begin(); |
| 149 it != append_strings.end(); |
| 150 ++it) { |
| 151 std::string value; |
| 152 if ((*it)->GetAsString(&value)) { |
| 153 append_to->push_back(value); |
| 154 } else { |
| 155 return false; |
| 156 } |
| 157 } |
| 158 |
| 159 return true; |
| 160 } |
| 161 |
| 162 // static |
| 163 scoped_refptr<ContentAction> RequestContentScript::Create( |
| 164 const Extension* extension, |
| 165 const base::DictionaryValue* dict, |
| 166 std::string* error, |
| 167 bool* bad_message) { |
| 168 std::vector<std::string> css_file_names; |
| 169 std::vector<std::string> js_file_names; |
| 170 bool all_frames = false; |
| 171 bool match_about_blank = false; |
| 172 const base::ListValue* list_value; |
| 173 |
| 174 if (!dict->HasKey(keys::kCss) && !dict->HasKey(keys::kJs)) { |
| 175 *error = base::StringPrintf(kMissingParameter, "css or js"); |
| 176 return scoped_refptr<ContentAction>(); |
| 177 } |
| 178 if (dict->HasKey(keys::kCss)) { |
| 179 INPUT_FORMAT_VALIDATE(dict->GetList(keys::kCss, &list_value)); |
| 180 INPUT_FORMAT_VALIDATE( |
| 181 AppendJSStringsToCPPStrings(*list_value, &css_file_names)); |
| 182 } |
| 183 if (dict->HasKey(keys::kJs)) { |
| 184 INPUT_FORMAT_VALIDATE(dict->GetList(keys::kJs, &list_value)); |
| 185 INPUT_FORMAT_VALIDATE( |
| 186 AppendJSStringsToCPPStrings(*list_value, &js_file_names)); |
| 187 } |
| 188 if (dict->HasKey(keys::kAllFrames)) { |
| 189 INPUT_FORMAT_VALIDATE(dict->GetBoolean(keys::kAllFrames, &all_frames)); |
| 190 } |
| 191 if (dict->HasKey(keys::kMatchAboutBlank)) { |
| 192 INPUT_FORMAT_VALIDATE( |
| 193 dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank)); |
| 194 } |
| 195 |
| 196 return scoped_refptr<ContentAction>(new RequestContentScript( |
| 197 css_file_names, js_file_names, all_frames, match_about_blank)); |
| 198 } |
| 199 |
97 struct ContentActionFactory { | 200 struct ContentActionFactory { |
98 // Factory methods for ContentAction instances. |extension| is the extension | 201 // Factory methods for ContentAction instances. |extension| is the extension |
99 // for which the action is being created. |dict| contains the json dictionary | 202 // for which the action is being created. |dict| contains the json dictionary |
100 // that describes the action. |error| is used to return error messages in case | 203 // that describes the action. |error| is used to return error messages in case |
101 // the extension passed an action that was syntactically correct but | 204 // the extension passed an action that was syntactically correct but |
102 // semantically incorrect. |bad_message| is set to true in case |dict| does | 205 // semantically incorrect. |bad_message| is set to true in case |dict| does |
103 // not confirm to the validated JSON specification. | 206 // not confirm to the validated JSON specification. |
104 typedef scoped_refptr<ContentAction>(*FactoryMethod)( | 207 typedef scoped_refptr<ContentAction>(*FactoryMethod)( |
105 const Extension* /* extension */, | 208 const Extension* /* extension */, |
106 const base::DictionaryValue* /* dict */, | 209 const base::DictionaryValue* /* dict */, |
107 std::string* /* error */, | 210 std::string* /* error */, |
108 bool* /* bad_message */); | 211 bool* /* bad_message */); |
109 // Maps the name of a declarativeContent action type to the factory | 212 // Maps the name of a declarativeContent action type to the factory |
110 // function creating it. | 213 // function creating it. |
111 std::map<std::string, FactoryMethod> factory_methods; | 214 std::map<std::string, FactoryMethod> factory_methods; |
112 | 215 |
113 ContentActionFactory() { | 216 ContentActionFactory() { |
114 factory_methods[keys::kShowPageAction] = | 217 factory_methods[keys::kShowPageAction] = |
115 &ShowPageAction::Create; | 218 &ShowPageAction::Create; |
| 219 factory_methods[keys::kRequestContentScript] = |
| 220 &RequestContentScript::Create; |
116 } | 221 } |
117 }; | 222 }; |
118 | 223 |
119 base::LazyInstance<ContentActionFactory>::Leaky | 224 base::LazyInstance<ContentActionFactory>::Leaky |
120 g_content_action_factory = LAZY_INSTANCE_INITIALIZER; | 225 g_content_action_factory = LAZY_INSTANCE_INITIALIZER; |
121 | 226 |
122 } // namespace | 227 } // namespace |
123 | 228 |
124 // | 229 // |
125 // ContentAction | 230 // ContentAction |
(...skipping 24 matching lines...) Expand all Loading... |
150 factory_method_iter = factory.factory_methods.find(instance_type); | 255 factory_method_iter = factory.factory_methods.find(instance_type); |
151 if (factory_method_iter != factory.factory_methods.end()) | 256 if (factory_method_iter != factory.factory_methods.end()) |
152 return (*factory_method_iter->second)( | 257 return (*factory_method_iter->second)( |
153 extension, action_dict, error, bad_message); | 258 extension, action_dict, error, bad_message); |
154 | 259 |
155 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); | 260 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); |
156 return scoped_refptr<ContentAction>(); | 261 return scoped_refptr<ContentAction>(); |
157 } | 262 } |
158 | 263 |
159 } // namespace extensions | 264 } // namespace extensions |
OLD | NEW |