Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(629)

Side by Side Diff: chrome/browser/extensions/api/declarative_content/content_action.cc

Issue 344433003: Prepare declarativeContent API for new script injection feature. Added Javascript types and functio… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Undo multiplicity of registries and content watchers. Address code review comments. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698