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

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: Update input validation patterns 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";
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(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 INPUT_FORMAT_VALIDATE(
179 !dict->HasKey(keys::kCss) ||
Jeffrey Yasskin 2014/07/17 20:39:14 Use more if()s here. Chains of || and && that rely
Mark Dittmer 2014/07/17 23:58:14 Done.
180 (dict->GetList(keys::kCss, &list_value) &&
181 AppendJSStringsToCPPStrings(*list_value, &css_file_names)));
182 INPUT_FORMAT_VALIDATE(
183 !dict->HasKey(keys::kJs) ||
184 (dict->GetList(keys::kJs, &list_value) &&
185 AppendJSStringsToCPPStrings(*list_value, &js_file_names)));
186 INPUT_FORMAT_VALIDATE(!dict->HasKey(keys::kAllFrames) ||
187 dict->GetBoolean(keys::kAllFrames, &all_frames));
188 INPUT_FORMAT_VALIDATE(
189 !dict->HasKey(keys::kMatchAboutBlank) ||
190 dict->GetBoolean(keys::kMatchAboutBlank, &match_about_blank));
191
192 return scoped_refptr<ContentAction>(new RequestContentScript(
193 css_file_names, js_file_names, all_frames, match_about_blank));
194 }
195
97 struct ContentActionFactory { 196 struct ContentActionFactory {
98 // Factory methods for ContentAction instances. |extension| is the extension 197 // Factory methods for ContentAction instances. |extension| is the extension
99 // for which the action is being created. |dict| contains the json dictionary 198 // 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 199 // that describes the action. |error| is used to return error messages in case
101 // the extension passed an action that was syntactically correct but 200 // the extension passed an action that was syntactically correct but
102 // semantically incorrect. |bad_message| is set to true in case |dict| does 201 // semantically incorrect. |bad_message| is set to true in case |dict| does
103 // not confirm to the validated JSON specification. 202 // not confirm to the validated JSON specification.
104 typedef scoped_refptr<ContentAction>(*FactoryMethod)( 203 typedef scoped_refptr<ContentAction>(*FactoryMethod)(
105 const Extension* /* extension */, 204 const Extension* /* extension */,
106 const base::DictionaryValue* /* dict */, 205 const base::DictionaryValue* /* dict */,
107 std::string* /* error */, 206 std::string* /* error */,
108 bool* /* bad_message */); 207 bool* /* bad_message */);
109 // Maps the name of a declarativeContent action type to the factory 208 // Maps the name of a declarativeContent action type to the factory
110 // function creating it. 209 // function creating it.
111 std::map<std::string, FactoryMethod> factory_methods; 210 std::map<std::string, FactoryMethod> factory_methods;
112 211
113 ContentActionFactory() { 212 ContentActionFactory() {
114 factory_methods[keys::kShowPageAction] = 213 factory_methods[keys::kShowPageAction] =
115 &ShowPageAction::Create; 214 &ShowPageAction::Create;
215 factory_methods[keys::kRequestContentScript] =
216 &RequestContentScript::Create;
116 } 217 }
117 }; 218 };
118 219
119 base::LazyInstance<ContentActionFactory>::Leaky 220 base::LazyInstance<ContentActionFactory>::Leaky
120 g_content_action_factory = LAZY_INSTANCE_INITIALIZER; 221 g_content_action_factory = LAZY_INSTANCE_INITIALIZER;
121 222
122 } // namespace 223 } // namespace
123 224
124 // 225 //
125 // ContentAction 226 // ContentAction
(...skipping 24 matching lines...) Expand all
150 factory_method_iter = factory.factory_methods.find(instance_type); 251 factory_method_iter = factory.factory_methods.find(instance_type);
151 if (factory_method_iter != factory.factory_methods.end()) 252 if (factory_method_iter != factory.factory_methods.end())
152 return (*factory_method_iter->second)( 253 return (*factory_method_iter->second)(
153 extension, action_dict, error, bad_message); 254 extension, action_dict, error, bad_message);
154 255
155 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); 256 *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str());
156 return scoped_refptr<ContentAction>(); 257 return scoped_refptr<ContentAction>();
157 } 258 }
158 259
159 } // namespace extensions 260 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698