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

Side by Side Diff: extensions/renderer/user_script_injector.cc

Issue 2278003002: Stop copying script contents for each RenderFrames. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 3 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 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"
11 #include "content/public/common/url_constants.h" 11 #include "content/public/common/url_constants.h"
12 #include "content/public/renderer/render_thread.h" 12 #include "content/public/renderer/render_thread.h"
13 #include "content/public/renderer/render_frame.h" 13 #include "content/public/renderer/render_frame.h"
14 #include "content/public/renderer/render_view.h" 14 #include "content/public/renderer/render_view.h"
15 #include "extensions/common/extension.h" 15 #include "extensions/common/extension.h"
16 #include "extensions/common/guest_view/extensions_guest_view_messages.h" 16 #include "extensions/common/guest_view/extensions_guest_view_messages.h"
17 #include "extensions/common/permissions/permissions_data.h" 17 #include "extensions/common/permissions/permissions_data.h"
18 #include "extensions/renderer/injection_host.h" 18 #include "extensions/renderer/injection_host.h"
19 #include "extensions/renderer/script_context.h" 19 #include "extensions/renderer/script_context.h"
20 #include "extensions/renderer/scripts_run_info.h" 20 #include "extensions/renderer/scripts_run_info.h"
21 #include "grit/extensions_renderer_resources.h"
22 #include "third_party/WebKit/public/web/WebDocument.h" 21 #include "third_party/WebKit/public/web/WebDocument.h"
23 #include "third_party/WebKit/public/web/WebLocalFrame.h" 22 #include "third_party/WebKit/public/web/WebLocalFrame.h"
24 #include "third_party/WebKit/public/web/WebScriptSource.h" 23 #include "third_party/WebKit/public/web/WebScriptSource.h"
25 #include "ui/base/resource/resource_bundle.h"
26 #include "url/gurl.h" 24 #include "url/gurl.h"
27 25
28 namespace extensions { 26 namespace extensions {
29 27
30 namespace { 28 namespace {
31 29
32 struct RoutingInfoKey { 30 struct RoutingInfoKey {
33 int routing_id; 31 int routing_id;
34 int script_id; 32 int script_id;
35 33
36 RoutingInfoKey(int routing_id, int script_id) 34 RoutingInfoKey(int routing_id, int script_id)
37 : routing_id(routing_id), script_id(script_id) {} 35 : routing_id(routing_id), script_id(script_id) {}
38 36
39 bool operator<(const RoutingInfoKey& other) const { 37 bool operator<(const RoutingInfoKey& other) const {
40 return std::tie(routing_id, script_id) < 38 return std::tie(routing_id, script_id) <
41 std::tie(other.routing_id, other.script_id); 39 std::tie(other.routing_id, other.script_id);
42 } 40 }
43 }; 41 };
44 42
45 using RoutingInfoMap = std::map<RoutingInfoKey, bool>; 43 using RoutingInfoMap = std::map<RoutingInfoKey, bool>;
46 44
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 45 // 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|. 46 // 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 47 // Once a script is added, the decision of whether or not allowed to inject
55 // won't be changed. 48 // won't be changed.
56 // After removed by the webview, the user scipt will also be removed 49 // 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 50 // from the render. Therefore, there won't be any query from the same
58 // |script_id| and |routing_id| pair. 51 // |script_id| and |routing_id| pair.
59 base::LazyInstance<RoutingInfoMap> g_routing_info_map = 52 base::LazyInstance<RoutingInfoMap> g_routing_info_map =
60 LAZY_INSTANCE_INITIALIZER; 53 LAZY_INSTANCE_INITIALIZER;
61 54
62 // Greasemonkey API source that is injected with the scripts.
63 struct GreasemonkeyApiJsString {
64 GreasemonkeyApiJsString();
65 blink::WebScriptSource GetSource() const;
66
67 private:
68 blink::WebString source_;
69 };
70
71 // The below constructor, monstrous as it is, just makes a WebScriptSource from
72 // the GreasemonkeyApiJs resource.
73 GreasemonkeyApiJsString::GreasemonkeyApiJsString() {
74 base::StringPiece source_piece =
75 ResourceBundle::GetSharedInstance().GetRawDataResource(
76 IDR_GREASEMONKEY_API_JS);
77 source_ =
78 blink::WebString::fromUTF8(source_piece.data(), source_piece.length());
79 }
80
81 blink::WebScriptSource GreasemonkeyApiJsString::GetSource() const {
82 return blink::WebScriptSource(source_);
83 }
84
85 base::LazyInstance<GreasemonkeyApiJsString> g_greasemonkey_api =
86 LAZY_INSTANCE_INITIALIZER;
87
88 } // namespace 55 } // namespace
89 56
90 UserScriptInjector::UserScriptInjector(const UserScript* script, 57 UserScriptInjector::UserScriptInjector(const UserScript* script,
91 UserScriptSet* script_list, 58 UserScriptSet* script_list,
92 bool is_declarative) 59 bool is_declarative)
93 : script_(script), 60 : script_(script),
61 user_script_set_(script_list),
94 script_id_(script_->id()), 62 script_id_(script_->id()),
95 host_id_(script_->host_id()), 63 host_id_(script_->host_id()),
96 is_declarative_(is_declarative), 64 is_declarative_(is_declarative),
97 user_script_set_observer_(this) { 65 user_script_set_observer_(this) {
98 user_script_set_observer_.Add(script_list); 66 user_script_set_observer_.Add(script_list);
99 } 67 }
100 68
101 UserScriptInjector::~UserScriptInjector() { 69 UserScriptInjector::~UserScriptInjector() {
102 } 70 }
103 71
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 is_declarative_); 164 is_declarative_);
197 } 165 }
198 166
199 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources( 167 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources(
200 UserScript::RunLocation run_location) const { 168 UserScript::RunLocation run_location) const {
201 std::vector<blink::WebScriptSource> sources; 169 std::vector<blink::WebScriptSource> sources;
202 if (!script_) 170 if (!script_)
203 return sources; 171 return sources;
204 172
205 DCHECK_EQ(script_->run_location(), run_location); 173 DCHECK_EQ(script_->run_location(), run_location);
206 174 return user_script_set_->GetJsSources(script_->id());
207 const UserScript::FileList& js_scripts = script_->js_scripts();
208 sources.reserve(js_scripts.size());
209 for (const std::unique_ptr<UserScript::File>& file : js_scripts) {
210 base::StringPiece script_content = file->GetContent();
211 blink::WebString source;
212 if (script_->emulate_greasemonkey()) {
213 // We add this dumb function wrapper for user scripts to emulate what
214 // Greasemonkey does. |script_content| becomes:
215 // concat(kUserScriptHead, script_content, kUserScriptTail).
216 std::string content;
217 content.reserve(strlen(kUserScriptHead) + script_content.length() +
218 strlen(kUserScriptTail));
219 content.append(kUserScriptHead);
220 script_content.AppendToString(&content);
221 content.append(kUserScriptTail);
222 // TODO(lazyboy): |content| is copied to |source|, should be avoided.
223 // Investigate if we can leverage WebString's cheap copying mechanism
224 // somehow.
225 source = blink::WebString::fromUTF8(content);
226 } else {
227 source = blink::WebString::fromUTF8(script_content.data(),
228 script_content.length());
229 }
230 sources.push_back(blink::WebScriptSource(source, file->url()));
231 }
232
233 // Emulate Greasemonkey API for scripts that were converted to extension
234 // user scripts.
235 if (script_->emulate_greasemonkey())
236 sources.insert(sources.begin(), g_greasemonkey_api.Get().GetSource());
237
238 return sources;
239 } 175 }
240 176
241 std::vector<blink::WebString> UserScriptInjector::GetCssSources( 177 std::vector<blink::WebString> UserScriptInjector::GetCssSources(
242 UserScript::RunLocation run_location) const { 178 UserScript::RunLocation run_location) const {
243 DCHECK_EQ(UserScript::DOCUMENT_START, run_location); 179 DCHECK_EQ(UserScript::DOCUMENT_START, run_location);
244 180
245 std::vector<blink::WebString> sources;
246 if (!script_) 181 if (!script_)
247 return sources; 182 return std::vector<blink::WebString>();
248 183
249 const UserScript::FileList& css_scripts = script_->css_scripts(); 184 return user_script_set_->GetCssSources(script_->id());
250 sources.reserve(css_scripts.size());
251 for (const std::unique_ptr<UserScript::File>& file : script_->css_scripts()) {
252 // TODO(lazyboy): |css_content| string is copied into blink::WebString for
253 // every frame in the current renderer process. Avoid the copy, possibly by
254 // only performing the copy once.
255 base::StringPiece css_content = file->GetContent();
256 sources.push_back(
257 blink::WebString::fromUTF8(css_content.data(), css_content.length()));
258 }
259 return sources;
260 } 185 }
261 186
262 void UserScriptInjector::GetRunInfo( 187 void UserScriptInjector::GetRunInfo(
263 ScriptsRunInfo* scripts_run_info, 188 ScriptsRunInfo* scripts_run_info,
264 UserScript::RunLocation run_location) const { 189 UserScript::RunLocation run_location) const {
265 if (!script_) 190 if (!script_)
266 return; 191 return;
267 192
268 if (ShouldInjectJs(run_location)) { 193 if (ShouldInjectJs(run_location)) {
269 const UserScript::FileList& js_scripts = script_->js_scripts(); 194 const UserScript::FileList& js_scripts = script_->js_scripts();
(...skipping 11 matching lines...) Expand all
281 void UserScriptInjector::OnInjectionComplete( 206 void UserScriptInjector::OnInjectionComplete(
282 std::unique_ptr<base::Value> execution_result, 207 std::unique_ptr<base::Value> execution_result,
283 UserScript::RunLocation run_location, 208 UserScript::RunLocation run_location,
284 content::RenderFrame* render_frame) {} 209 content::RenderFrame* render_frame) {}
285 210
286 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason, 211 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason,
287 content::RenderFrame* render_frame) { 212 content::RenderFrame* render_frame) {
288 } 213 }
289 214
290 } // namespace extensions 215 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698