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

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: Clean up declarative_content.json and store RequestContentScript data in action object 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 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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698