OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/renderer/user_script_injector.h" | 5 #include "extensions/renderer/user_script_injector.h" |
6 | 6 |
7 #include <tuple> | 7 #include <tuple> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 26 matching lines...) Expand all Loading... | |
37 : routing_id(routing_id), script_id(script_id) {} | 37 : routing_id(routing_id), script_id(script_id) {} |
38 | 38 |
39 bool operator<(const RoutingInfoKey& other) const { | 39 bool operator<(const RoutingInfoKey& other) const { |
40 return std::tie(routing_id, script_id) < | 40 return std::tie(routing_id, script_id) < |
41 std::tie(other.routing_id, other.script_id); | 41 std::tie(other.routing_id, other.script_id); |
42 } | 42 } |
43 }; | 43 }; |
44 | 44 |
45 using RoutingInfoMap = std::map<RoutingInfoKey, bool>; | 45 using RoutingInfoMap = std::map<RoutingInfoKey, bool>; |
46 | 46 |
47 // These two strings are injected before and after the Greasemonkey API and | |
48 // user script to wrap it in an anonymous scope. | |
49 const char kUserScriptHead[] = "(function (unsafeWindow) {\n"; | |
50 const char kUserScriptTail[] = "\n})(window);"; | |
51 | |
52 // A map records whether a given |script_id| from a webview-added user script | 47 // A map records whether a given |script_id| from a webview-added user script |
53 // is allowed to inject on the render of given |routing_id|. | 48 // is allowed to inject on the render of given |routing_id|. |
54 // Once a script is added, the decision of whether or not allowed to inject | 49 // Once a script is added, the decision of whether or not allowed to inject |
55 // won't be changed. | 50 // won't be changed. |
56 // After removed by the webview, the user scipt will also be removed | 51 // After removed by the webview, the user scipt will also be removed |
57 // from the render. Therefore, there won't be any query from the same | 52 // from the render. Therefore, there won't be any query from the same |
58 // |script_id| and |routing_id| pair. | 53 // |script_id| and |routing_id| pair. |
59 base::LazyInstance<RoutingInfoMap> g_routing_info_map = | 54 base::LazyInstance<RoutingInfoMap> g_routing_info_map = |
60 LAZY_INSTANCE_INITIALIZER; | 55 LAZY_INSTANCE_INITIALIZER; |
61 | 56 |
(...skipping 22 matching lines...) Expand all Loading... | |
84 | 79 |
85 base::LazyInstance<GreasemonkeyApiJsString> g_greasemonkey_api = | 80 base::LazyInstance<GreasemonkeyApiJsString> g_greasemonkey_api = |
86 LAZY_INSTANCE_INITIALIZER; | 81 LAZY_INSTANCE_INITIALIZER; |
87 | 82 |
88 } // namespace | 83 } // namespace |
89 | 84 |
90 UserScriptInjector::UserScriptInjector(const UserScript* script, | 85 UserScriptInjector::UserScriptInjector(const UserScript* script, |
91 UserScriptSet* script_list, | 86 UserScriptSet* script_list, |
92 bool is_declarative) | 87 bool is_declarative) |
93 : script_(script), | 88 : script_(script), |
89 user_script_set_(script_list), | |
94 script_id_(script_->id()), | 90 script_id_(script_->id()), |
95 host_id_(script_->host_id()), | 91 host_id_(script_->host_id()), |
96 is_declarative_(is_declarative), | 92 is_declarative_(is_declarative), |
97 user_script_set_observer_(this) { | 93 user_script_set_observer_(this) { |
98 user_script_set_observer_.Add(script_list); | 94 user_script_set_observer_.Add(script_list); |
99 } | 95 } |
100 | 96 |
101 UserScriptInjector::~UserScriptInjector() { | 97 UserScriptInjector::~UserScriptInjector() { |
102 } | 98 } |
103 | 99 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 | 195 |
200 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources( | 196 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources( |
201 UserScript::RunLocation run_location) const { | 197 UserScript::RunLocation run_location) const { |
202 std::vector<blink::WebScriptSource> sources; | 198 std::vector<blink::WebScriptSource> sources; |
203 if (!script_) | 199 if (!script_) |
204 return sources; | 200 return sources; |
205 | 201 |
206 DCHECK_EQ(script_->run_location(), run_location); | 202 DCHECK_EQ(script_->run_location(), run_location); |
207 | 203 |
208 const UserScript::FileList& js_scripts = script_->js_scripts(); | 204 const UserScript::FileList& js_scripts = script_->js_scripts(); |
209 sources.reserve(js_scripts.size()); | 205 sources.reserve(js_scripts.size() + |
206 (script_->emulate_greasemonkey() ? 1 : 0)); | |
210 for (const std::unique_ptr<UserScript::File>& file : js_scripts) { | 207 for (const std::unique_ptr<UserScript::File>& file : js_scripts) { |
211 base::StringPiece script_content = file->GetContent(); | 208 sources.push_back(blink::WebScriptSource( |
212 blink::WebString source; | 209 user_script_set_->GetJsSource(*file, script_->emulate_greasemonkey()), |
213 if (script_->emulate_greasemonkey()) { | 210 file->url())); |
214 // We add this dumb function wrapper for user scripts to emulate what | |
215 // Greasemonkey does. |script_content| becomes: | |
216 // concat(kUserScriptHead, script_content, kUserScriptTail). | |
217 std::string content; | |
218 content.reserve(strlen(kUserScriptHead) + script_content.length() + | |
219 strlen(kUserScriptTail)); | |
220 content.append(kUserScriptHead); | |
221 script_content.AppendToString(&content); | |
222 content.append(kUserScriptTail); | |
223 // TODO(lazyboy): |content| is copied to |source|, should be avoided. | |
224 // Investigate if we can leverage WebString's cheap copying mechanism | |
225 // somehow. | |
226 source = blink::WebString::fromUTF8(content); | |
227 } else { | |
228 source = blink::WebString::fromUTF8(script_content.data(), | |
229 script_content.length()); | |
230 } | |
231 sources.push_back(blink::WebScriptSource(source, file->url())); | |
232 } | 211 } |
233 | 212 |
234 // Emulate Greasemonkey API for scripts that were converted to extension | 213 // Emulate Greasemonkey API for scripts that were converted to extension |
235 // user scripts. | 214 // user scripts. |
236 if (script_->emulate_greasemonkey()) | 215 if (script_->emulate_greasemonkey()) |
237 sources.insert(sources.begin(), g_greasemonkey_api.Get().GetSource()); | 216 sources.insert(sources.begin(), g_greasemonkey_api.Get().GetSource()); |
Devlin
2016/09/07 14:29:45
nit: unrelated, but maybe put this before adding a
lazyboy
2016/09/07 16:47:35
Done.
| |
238 | 217 |
239 return sources; | 218 return sources; |
240 } | 219 } |
241 | 220 |
242 std::vector<blink::WebString> UserScriptInjector::GetCssSources( | 221 std::vector<blink::WebString> UserScriptInjector::GetCssSources( |
243 UserScript::RunLocation run_location) const { | 222 UserScript::RunLocation run_location) const { |
244 DCHECK_EQ(UserScript::DOCUMENT_START, run_location); | 223 DCHECK_EQ(UserScript::DOCUMENT_START, run_location); |
245 | 224 |
246 std::vector<blink::WebString> sources; | 225 std::vector<blink::WebString> sources; |
247 if (!script_) | 226 if (!script_) |
248 return sources; | 227 return sources; |
249 | 228 |
250 const UserScript::FileList& css_scripts = script_->css_scripts(); | 229 const UserScript::FileList& css_scripts = script_->css_scripts(); |
251 sources.reserve(css_scripts.size()); | 230 sources.reserve(css_scripts.size()); |
252 for (const std::unique_ptr<UserScript::File>& file : script_->css_scripts()) { | 231 for (const std::unique_ptr<UserScript::File>& file : script_->css_scripts()) |
253 // TODO(lazyboy): |css_content| string is copied into blink::WebString for | 232 sources.push_back(user_script_set_->GetCssSource(*file)); |
254 // every frame in the current renderer process. Avoid the copy, possibly by | |
255 // only performing the copy once. | |
256 base::StringPiece css_content = file->GetContent(); | |
257 sources.push_back( | |
258 blink::WebString::fromUTF8(css_content.data(), css_content.length())); | |
259 } | |
260 return sources; | 233 return sources; |
261 } | 234 } |
262 | 235 |
263 void UserScriptInjector::GetRunInfo( | 236 void UserScriptInjector::GetRunInfo( |
264 ScriptsRunInfo* scripts_run_info, | 237 ScriptsRunInfo* scripts_run_info, |
265 UserScript::RunLocation run_location) const { | 238 UserScript::RunLocation run_location) const { |
266 if (!script_) | 239 if (!script_) |
267 return; | 240 return; |
268 | 241 |
269 if (ShouldInjectJs(run_location)) { | 242 if (ShouldInjectJs(run_location)) { |
(...skipping 12 matching lines...) Expand all Loading... | |
282 void UserScriptInjector::OnInjectionComplete( | 255 void UserScriptInjector::OnInjectionComplete( |
283 std::unique_ptr<base::Value> execution_result, | 256 std::unique_ptr<base::Value> execution_result, |
284 UserScript::RunLocation run_location, | 257 UserScript::RunLocation run_location, |
285 content::RenderFrame* render_frame) {} | 258 content::RenderFrame* render_frame) {} |
286 | 259 |
287 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason, | 260 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason, |
288 content::RenderFrame* render_frame) { | 261 content::RenderFrame* render_frame) { |
289 } | 262 } |
290 | 263 |
291 } // namespace extensions | 264 } // namespace extensions |
OLD | NEW |