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"; | |
33 const char kInvalidTypeOfParameter[] = "Attribute '%s' has an invalid type. " | |
34 "Expected type: %s"; | |
32 | 35 |
33 #define INPUT_FORMAT_VALIDATE(test) do { \ | 36 #define INPUT_FORMAT_VALIDATE(test) do { \ |
34 if (!(test)) { \ | 37 if (!(test)) { \ |
35 *bad_message = true; \ | 38 *bad_message = true; \ |
36 return scoped_refptr<ContentAction>(NULL); \ | 39 return scoped_refptr<ContentAction>(NULL); \ |
37 } \ | 40 } \ |
38 } while (0) | 41 } while (0) |
39 | 42 |
40 // | 43 // |
41 // The following are concrete actions. | 44 // The following are concrete actions. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); | 90 ->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); |
88 if (!extension) | 91 if (!extension) |
89 return NULL; | 92 return NULL; |
90 return ExtensionActionManager::Get(profile)->GetPageAction(*extension); | 93 return ExtensionActionManager::Get(profile)->GetPageAction(*extension); |
91 } | 94 } |
92 virtual ~ShowPageAction() {} | 95 virtual ~ShowPageAction() {} |
93 | 96 |
94 DISALLOW_COPY_AND_ASSIGN(ShowPageAction); | 97 DISALLOW_COPY_AND_ASSIGN(ShowPageAction); |
95 }; | 98 }; |
96 | 99 |
100 // Action that injects a content script. | |
101 class RequestContentScript : public ContentAction { | |
102 public: | |
103 RequestContentScript(const std::vector<std::string>& css_file_names, | |
104 const std::vector<std::string>& js_file_names, | |
105 const bool& all_frames, | |
Jeffrey Yasskin
2014/07/15 20:44:59
You can pass bools by value.
Mark Dittmer
2014/07/16 12:26:13
Done.
not at google - send to devlin
2014/07/16 16:51:14
there's no point having them as "const" when they'
Mark Dittmer
2014/07/16 19:40:45
Done.
| |
106 const bool& match_about_blank) | |
107 : css_file_names_(css_file_names), | |
108 js_file_names_(js_file_names), | |
109 all_frames_(all_frames), | |
110 match_about_blank_(match_about_blank) {} | |
111 | |
112 static scoped_refptr<ContentAction> Create(const Extension* extension, | |
113 const base::DictionaryValue* dict, | |
114 std::string* error, | |
115 bool* bad_message); | |
116 // friend scoped_refptr<ContentAction> RequestContentScript::Create( | |
Jeffrey Yasskin
2014/07/15 20:44:59
Remember to delete this before submitting.
Mark Dittmer
2014/07/16 12:26:13
Done. Thanks!
| |
117 // const Extension* extension, | |
118 // const base::DictionaryValue* dict, | |
119 // std::string* error, | |
120 // bool* bad_message); | |
121 | |
122 // Implementation of ContentAction: | |
123 virtual Type GetType() const OVERRIDE { | |
124 return ACTION_REQUEST_CONTENT_SCRIPT; | |
125 } | |
126 | |
127 virtual void Apply(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 // load new user script. | |
132 } | |
133 | |
134 virtual void Revert(const std::string& extension_id, | |
135 const base::Time& extension_install_time, | |
136 ApplyInfo* apply_info) const OVERRIDE { | |
137 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: | |
138 // do not load user script if Apply() runs again on the same page. | |
139 } | |
140 | |
141 private: | |
142 std::vector<std::string> css_file_names_; | |
143 std::vector<std::string> js_file_names_; | |
144 bool all_frames_; | |
145 bool match_about_blank_; | |
146 | |
147 virtual ~RequestContentScript() {} | |
Jeffrey Yasskin
2014/07/15 20:44:59
The destructor would go first in this private sect
Mark Dittmer
2014/07/16 12:26:13
Moved it to the beginning of the section. Without
| |
148 | |
149 DISALLOW_COPY_AND_ASSIGN(RequestContentScript); | |
150 }; | |
151 | |
152 // Helper for getting JS collections into C++. | |
153 static bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings, | |
154 std::vector<std::string>* append_to) { | |
155 for (base::ListValue::const_iterator it = append_strings.begin(); | |
156 it != append_strings.end(); ++it) { | |
157 std::string value; | |
158 if ((*it)->GetAsString(&value)) { | |
159 append_to->push_back(value); | |
160 } else { | |
161 return false; | |
162 } | |
163 } | |
164 | |
165 return true; | |
166 } | |
167 | |
168 // static | |
169 scoped_refptr<ContentAction> RequestContentScript::Create( | |
170 const Extension* extension, | |
171 const base::DictionaryValue* dict, | |
172 std::string* error, | |
173 bool* bad_message) { | |
174 std::vector<std::string> css_file_names; | |
175 std::vector<std::string> js_file_names; | |
176 bool all_frames(false); | |
Jeffrey Yasskin
2014/07/15 20:44:59
We usually initialize simple values with = instead
Mark Dittmer
2014/07/16 12:26:13
Done.
| |
177 bool match_about_blank(false); | |
178 const base::ListValue* list_value; | |
179 | |
180 if (!dict->HasKey(keys::kCss) && !dict->HasKey(keys::kJs)) { | |
181 *error = base::StringPrintf(kMissingParameter, "css or js"); | |
182 return scoped_refptr<ContentAction>(); | |
183 } | |
184 | |
185 if (dict->HasKey(keys::kCss) && dict->GetList(keys::kCss, &list_value)) { | |
186 AppendJSStringsToCPPStrings(*list_value, &css_file_names); | |
Jeffrey Yasskin
2014/07/15 20:44:59
You should use the return value of this function,
Mark Dittmer
2014/07/16 12:26:13
Done.
| |
187 } else { | |
188 *error = base::StringPrintf(kInvalidTypeOfParameter, | |
Jeffrey Yasskin
2014/07/15 20:44:59
This looks like it's going to give an error if som
Mark Dittmer
2014/07/16 12:26:13
Done.
| |
189 keys::kCss, | |
190 "Array of strings"); | |
191 return scoped_refptr<ContentAction>(); | |
192 } | |
193 | |
194 if (dict->HasKey(keys::kJs) && dict->GetList(keys::kJs, &list_value)) { | |
195 AppendJSStringsToCPPStrings(*list_value, &js_file_names); | |
196 } else { | |
197 *error = base::StringPrintf(kInvalidTypeOfParameter, | |
198 keys::kJs, | |
199 "Array of strings"); | |
200 return scoped_refptr<ContentAction>(); | |
201 } | |
202 | |
203 if (dict->HasKey(keys::kAllFrames) && | |
204 !dict->GetBoolean(keys::kAllFrames, &all_frames)) { | |
205 *error = base::StringPrintf(kInvalidTypeOfParameter, | |
206 keys::kAllFrames, | |
207 "Boolean"); | |
208 return scoped_refptr<ContentAction>(); | |
209 } | |
210 | |
211 if (dict->HasKey(keys::kMatchAboutBlank) && | |
212 !dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank)) { | |
213 *error = base::StringPrintf(kInvalidTypeOfParameter, | |
214 keys::kMatchAboutBlank, | |
215 "Boolean"); | |
216 return scoped_refptr<ContentAction>(); | |
217 } | |
218 | |
219 return scoped_refptr<ContentAction>(new RequestContentScript( | |
220 css_file_names, | |
221 js_file_names, | |
222 all_frames, | |
223 match_about_blank)); | |
224 } | |
225 | |
97 struct ContentActionFactory { | 226 struct ContentActionFactory { |
98 // Factory methods for ContentAction instances. |extension| is the extension | 227 // Factory methods for ContentAction instances. |extension| is the extension |
99 // for which the action is being created. |dict| contains the json dictionary | 228 // 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 | 229 // that describes the action. |error| is used to return error messages in case |
101 // the extension passed an action that was syntactically correct but | 230 // the extension passed an action that was syntactically correct but |
102 // semantically incorrect. |bad_message| is set to true in case |dict| does | 231 // semantically incorrect. |bad_message| is set to true in case |dict| does |
103 // not confirm to the validated JSON specification. | 232 // not confirm to the validated JSON specification. |
104 typedef scoped_refptr<ContentAction>(*FactoryMethod)( | 233 typedef scoped_refptr<ContentAction>(*FactoryMethod)( |
105 const Extension* /* extension */, | 234 const Extension* /* extension */, |
106 const base::DictionaryValue* /* dict */, | 235 const base::DictionaryValue* /* dict */, |
107 std::string* /* error */, | 236 std::string* /* error */, |
108 bool* /* bad_message */); | 237 bool* /* bad_message */); |
109 // Maps the name of a declarativeContent action type to the factory | 238 // Maps the name of a declarativeContent action type to the factory |
110 // function creating it. | 239 // function creating it. |
111 std::map<std::string, FactoryMethod> factory_methods; | 240 std::map<std::string, FactoryMethod> factory_methods; |
112 | 241 |
113 ContentActionFactory() { | 242 ContentActionFactory() { |
114 factory_methods[keys::kShowPageAction] = | 243 factory_methods[keys::kShowPageAction] = |
115 &ShowPageAction::Create; | 244 &ShowPageAction::Create; |
245 factory_methods[keys::kRequestContentScript] = | |
246 &RequestContentScript::Create; | |
116 } | 247 } |
117 }; | 248 }; |
118 | 249 |
119 base::LazyInstance<ContentActionFactory>::Leaky | 250 base::LazyInstance<ContentActionFactory>::Leaky |
120 g_content_action_factory = LAZY_INSTANCE_INITIALIZER; | 251 g_content_action_factory = LAZY_INSTANCE_INITIALIZER; |
121 | 252 |
122 } // namespace | 253 } // namespace |
123 | 254 |
124 // | 255 // |
125 // ContentAction | 256 // ContentAction |
(...skipping 24 matching lines...) Expand all Loading... | |
150 factory_method_iter = factory.factory_methods.find(instance_type); | 281 factory_method_iter = factory.factory_methods.find(instance_type); |
151 if (factory_method_iter != factory.factory_methods.end()) | 282 if (factory_method_iter != factory.factory_methods.end()) |
152 return (*factory_method_iter->second)( | 283 return (*factory_method_iter->second)( |
153 extension, action_dict, error, bad_message); | 284 extension, action_dict, error, bad_message); |
154 | 285 |
155 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); | 286 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); |
156 return scoped_refptr<ContentAction>(); | 287 return scoped_refptr<ContentAction>(); |
157 } | 288 } |
158 | 289 |
159 } // namespace extensions | 290 } // namespace extensions |
OLD | NEW |