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 kInvalidTypeOfParamter[] = "Attribute '%s' has an invalid type"; | |
Jeffrey Yasskin
2014/07/15 17:12:59
sp: "Paramter"
It's also more user-friendly to sa
Mark Dittmer
2014/07/15 18:32:42
Done.
| |
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() {} | |
Jeffrey Yasskin
2014/07/15 17:12:59
Give this constructor parameters matching the valu
Mark Dittmer
2014/07/15 18:32:43
Done.
| |
102 | |
103 static scoped_refptr<ContentAction> Create(const Extension* extension, | |
104 const base::DictionaryValue* dict, | |
105 std::string* error, | |
106 bool* bad_message); | |
107 friend scoped_refptr<ContentAction> RequestContentScript::Create( | |
Jeffrey Yasskin
2014/07/15 17:12:59
You don't need to friend members of the same class
Mark Dittmer
2014/07/15 18:32:43
I hit a compiler error without this. I think the f
| |
108 const Extension* extension, | |
109 const base::DictionaryValue* dict, | |
110 std::string* error, | |
111 bool* bad_message); | |
112 | |
113 // Implementation of ContentAction: | |
114 virtual Type GetType() const OVERRIDE { | |
115 return ACTION_REQUEST_CONTENT_SCRIPT; | |
116 } | |
117 | |
118 virtual void Apply(const std::string& extension_id, | |
119 const base::Time& extension_install_time, | |
120 ApplyInfo* apply_info) const OVERRIDE { | |
121 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: | |
122 // load new user script. | |
123 } | |
124 | |
125 virtual void Revert(const std::string& extension_id, | |
126 const base::Time& extension_install_time, | |
127 ApplyInfo* apply_info) const OVERRIDE { | |
128 // TODO(markdittmer): Invoke UserScriptMaster declarative script loader: | |
129 // do not load user script in the future. | |
Jeffrey Yasskin
2014/07/15 17:13:00
s/in the future/if Apply() runs again on the same
Mark Dittmer
2014/07/15 18:32:43
Done.
| |
130 } | |
131 | |
132 private: | |
133 virtual ~RequestContentScript() {} | |
134 DISALLOW_COPY_AND_ASSIGN(RequestContentScript); | |
Jeffrey Yasskin
2014/07/15 17:13:00
This goes last in the class: http://google-stylegu
Mark Dittmer
2014/07/15 18:32:42
Done.
| |
135 | |
136 std::vector<std::string> css_file_names_; | |
137 std::vector<std::string> js_file_names_; | |
138 bool all_frames_; | |
139 bool match_about_blank_; | |
140 }; | |
141 | |
142 // Helper for getting JS collections into C++. | |
143 bool AppendJSStringsToCPPStrings(const base::ListValue& append_strings, | |
Jeffrey Yasskin
2014/07/15 17:12:59
This should be static to be sure it doesn't collid
Mark Dittmer
2014/07/15 18:32:42
Done. I'm curious, doesn't living in an anonymous
Jeffrey Yasskin
2014/07/15 20:44:59
Ah, yes it does. I'd lost the anonymous namespace
| |
144 std::vector<std::string>& append_to) { | |
Jeffrey Yasskin
2014/07/15 17:12:59
Chrome doesn't use non-const reference arguments:
Mark Dittmer
2014/07/15 18:32:42
Done.
| |
145 for (base::ListValue::const_iterator it = append_strings.begin(); | |
146 it != append_strings.end(); ++it) { | |
147 std::string value; | |
148 if ((*it)->GetAsString(&value)) { | |
149 append_to.push_back(value); | |
150 } else { | |
151 return false; | |
152 } | |
153 } | |
154 | |
155 return true; | |
156 } | |
157 | |
158 // static | |
159 scoped_refptr<ContentAction> RequestContentScript::Create( | |
160 const Extension* extension, | |
161 const base::DictionaryValue* dict, | |
162 std::string* error, | |
163 bool* bad_message) { | |
164 RequestContentScript* request_content_script = new RequestContentScript(); | |
165 | |
166 for (base::DictionaryValue::Iterator iter(*dict); | |
167 !iter.IsAtEnd(); iter.Advance()) { | |
168 const std::string& attribute_name = iter.key(); | |
169 const base::Value& attribute_value = iter.value(); | |
170 if (attribute_name == "css" || attribute_name == "js") { | |
Jeffrey Yasskin
2014/07/15 17:12:59
I would probably look up the attributes I want ins
Mark Dittmer
2014/07/15 18:32:42
Done. Switched to looking up individual members. T
| |
171 std::vector<std::string>& string_list = (attribute_name == "css") ? | |
172 request_content_script->css_file_names_ : | |
173 request_content_script->js_file_names_; | |
174 const base::ListValue* list_value = NULL; | |
175 if (attribute_value.GetAsList(&list_value)) { | |
176 AppendJSStringsToCPPStrings(*list_value, string_list); | |
177 } else { | |
178 *error = base::StringPrintf(kInvalidTypeOfParamter, | |
179 attribute_name.c_str()); | |
180 break; | |
181 } | |
182 } else if (attribute_name == "allFrames" || | |
183 attribute_name == "matchAboutBlank") { | |
184 bool& bool_ref = (attribute_name == "allFrames") ? | |
185 request_content_script->all_frames_ : | |
186 request_content_script->match_about_blank_; | |
187 bool bool_read; | |
188 if (attribute_value.GetAsBoolean(&bool_read)) { | |
189 bool_ref = bool_read; | |
190 } else { | |
191 *error = base::StringPrintf(kInvalidTypeOfParamter, | |
192 attribute_name.c_str()); | |
193 break; | |
194 } | |
195 } | |
196 } | |
197 | |
198 if (error->empty()) { | |
199 delete request_content_script; | |
Jeffrey Yasskin
2014/07/15 17:12:59
Try never to have to write "delete foo" at the end
Mark Dittmer
2014/07/15 18:32:42
Done.
| |
200 return scoped_refptr<ContentAction>(); | |
201 } else { | |
202 return scoped_refptr<ContentAction>(request_content_script); | |
203 } | |
204 } | |
205 | |
97 struct ContentActionFactory { | 206 struct ContentActionFactory { |
98 // Factory methods for ContentAction instances. |extension| is the extension | 207 // Factory methods for ContentAction instances. |extension| is the extension |
99 // for which the action is being created. |dict| contains the json dictionary | 208 // 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 | 209 // that describes the action. |error| is used to return error messages in case |
101 // the extension passed an action that was syntactically correct but | 210 // the extension passed an action that was syntactically correct but |
102 // semantically incorrect. |bad_message| is set to true in case |dict| does | 211 // semantically incorrect. |bad_message| is set to true in case |dict| does |
103 // not confirm to the validated JSON specification. | 212 // not confirm to the validated JSON specification. |
104 typedef scoped_refptr<ContentAction>(*FactoryMethod)( | 213 typedef scoped_refptr<ContentAction>(*FactoryMethod)( |
105 const Extension* /* extension */, | 214 const Extension* /* extension */, |
106 const base::DictionaryValue* /* dict */, | 215 const base::DictionaryValue* /* dict */, |
107 std::string* /* error */, | 216 std::string* /* error */, |
108 bool* /* bad_message */); | 217 bool* /* bad_message */); |
109 // Maps the name of a declarativeContent action type to the factory | 218 // Maps the name of a declarativeContent action type to the factory |
110 // function creating it. | 219 // function creating it. |
111 std::map<std::string, FactoryMethod> factory_methods; | 220 std::map<std::string, FactoryMethod> factory_methods; |
112 | 221 |
113 ContentActionFactory() { | 222 ContentActionFactory() { |
114 factory_methods[keys::kShowPageAction] = | 223 factory_methods[keys::kShowPageAction] = |
115 &ShowPageAction::Create; | 224 &ShowPageAction::Create; |
225 factory_methods[keys::kRequestContentScript] = | |
226 &RequestContentScript::Create; | |
116 } | 227 } |
117 }; | 228 }; |
118 | 229 |
119 base::LazyInstance<ContentActionFactory>::Leaky | 230 base::LazyInstance<ContentActionFactory>::Leaky |
120 g_content_action_factory = LAZY_INSTANCE_INITIALIZER; | 231 g_content_action_factory = LAZY_INSTANCE_INITIALIZER; |
121 | 232 |
122 } // namespace | 233 } // namespace |
123 | 234 |
124 // | 235 // |
125 // ContentAction | 236 // ContentAction |
(...skipping 24 matching lines...) Expand all Loading... | |
150 factory_method_iter = factory.factory_methods.find(instance_type); | 261 factory_method_iter = factory.factory_methods.find(instance_type); |
151 if (factory_method_iter != factory.factory_methods.end()) | 262 if (factory_method_iter != factory.factory_methods.end()) |
152 return (*factory_method_iter->second)( | 263 return (*factory_method_iter->second)( |
153 extension, action_dict, error, bad_message); | 264 extension, action_dict, error, bad_message); |
154 | 265 |
155 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); | 266 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); |
156 return scoped_refptr<ContentAction>(); | 267 return scoped_refptr<ContentAction>(); |
157 } | 268 } |
158 | 269 |
159 } // namespace extensions | 270 } // namespace extensions |
OLD | NEW |