| 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 |
| 47 // A map records whether a given |script_id| from a webview-added user script | 52 // A map records whether a given |script_id| from a webview-added user script |
| 48 // is allowed to inject on the render of given |routing_id|. | 53 // is allowed to inject on the render of given |routing_id|. |
| 49 // Once a script is added, the decision of whether or not allowed to inject | 54 // Once a script is added, the decision of whether or not allowed to inject |
| 50 // won't be changed. | 55 // won't be changed. |
| 51 // After removed by the webview, the user scipt will also be removed | 56 // After removed by the webview, the user scipt will also be removed |
| 52 // from the render. Therefore, there won't be any query from the same | 57 // from the render. Therefore, there won't be any query from the same |
| 53 // |script_id| and |routing_id| pair. | 58 // |script_id| and |routing_id| pair. |
| 54 base::LazyInstance<RoutingInfoMap> g_routing_info_map = | 59 base::LazyInstance<RoutingInfoMap> g_routing_info_map = |
| 55 LAZY_INSTANCE_INITIALIZER; | 60 LAZY_INSTANCE_INITIALIZER; |
| 56 | 61 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 79 | 84 |
| 80 base::LazyInstance<GreasemonkeyApiJsString> g_greasemonkey_api = | 85 base::LazyInstance<GreasemonkeyApiJsString> g_greasemonkey_api = |
| 81 LAZY_INSTANCE_INITIALIZER; | 86 LAZY_INSTANCE_INITIALIZER; |
| 82 | 87 |
| 83 } // namespace | 88 } // namespace |
| 84 | 89 |
| 85 UserScriptInjector::UserScriptInjector(const UserScript* script, | 90 UserScriptInjector::UserScriptInjector(const UserScript* script, |
| 86 UserScriptSet* script_list, | 91 UserScriptSet* script_list, |
| 87 bool is_declarative) | 92 bool is_declarative) |
| 88 : script_(script), | 93 : script_(script), |
| 89 user_script_set_(script_list), | |
| 90 script_id_(script_->id()), | 94 script_id_(script_->id()), |
| 91 host_id_(script_->host_id()), | 95 host_id_(script_->host_id()), |
| 92 is_declarative_(is_declarative), | 96 is_declarative_(is_declarative), |
| 93 user_script_set_observer_(this) { | 97 user_script_set_observer_(this) { |
| 94 user_script_set_observer_.Add(script_list); | 98 user_script_set_observer_.Add(script_list); |
| 95 } | 99 } |
| 96 | 100 |
| 97 UserScriptInjector::~UserScriptInjector() { | 101 UserScriptInjector::~UserScriptInjector() { |
| 98 } | 102 } |
| 99 | 103 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 199 |
| 196 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources( | 200 std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources( |
| 197 UserScript::RunLocation run_location) const { | 201 UserScript::RunLocation run_location) const { |
| 198 std::vector<blink::WebScriptSource> sources; | 202 std::vector<blink::WebScriptSource> sources; |
| 199 if (!script_) | 203 if (!script_) |
| 200 return sources; | 204 return sources; |
| 201 | 205 |
| 202 DCHECK_EQ(script_->run_location(), run_location); | 206 DCHECK_EQ(script_->run_location(), run_location); |
| 203 | 207 |
| 204 const UserScript::FileList& js_scripts = script_->js_scripts(); | 208 const UserScript::FileList& js_scripts = script_->js_scripts(); |
| 205 sources.reserve(js_scripts.size() + | 209 sources.reserve(js_scripts.size()); |
| 206 (script_->emulate_greasemonkey() ? 1 : 0)); | 210 for (const std::unique_ptr<UserScript::File>& file : js_scripts) { |
| 211 base::StringPiece script_content = file->GetContent(); |
| 212 blink::WebString source; |
| 213 if (script_->emulate_greasemonkey()) { |
| 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 } |
| 207 | 233 |
| 208 // Emulate Greasemonkey API for scripts that were converted to extension | 234 // Emulate Greasemonkey API for scripts that were converted to extension |
| 209 // user scripts. | 235 // user scripts. |
| 210 if (script_->emulate_greasemonkey()) | 236 if (script_->emulate_greasemonkey()) |
| 211 sources.push_back(g_greasemonkey_api.Get().GetSource()); | 237 sources.insert(sources.begin(), g_greasemonkey_api.Get().GetSource()); |
| 212 | |
| 213 for (const std::unique_ptr<UserScript::File>& file : js_scripts) { | |
| 214 sources.push_back(blink::WebScriptSource( | |
| 215 user_script_set_->GetJsSource(*file, script_->emulate_greasemonkey()), | |
| 216 file->url())); | |
| 217 } | |
| 218 | 238 |
| 219 return sources; | 239 return sources; |
| 220 } | 240 } |
| 221 | 241 |
| 222 std::vector<blink::WebString> UserScriptInjector::GetCssSources( | 242 std::vector<blink::WebString> UserScriptInjector::GetCssSources( |
| 223 UserScript::RunLocation run_location) const { | 243 UserScript::RunLocation run_location) const { |
| 224 DCHECK_EQ(UserScript::DOCUMENT_START, run_location); | 244 DCHECK_EQ(UserScript::DOCUMENT_START, run_location); |
| 225 | 245 |
| 226 std::vector<blink::WebString> sources; | 246 std::vector<blink::WebString> sources; |
| 227 if (!script_) | 247 if (!script_) |
| 228 return sources; | 248 return sources; |
| 229 | 249 |
| 230 const UserScript::FileList& css_scripts = script_->css_scripts(); | 250 const UserScript::FileList& css_scripts = script_->css_scripts(); |
| 231 sources.reserve(css_scripts.size()); | 251 sources.reserve(css_scripts.size()); |
| 232 for (const std::unique_ptr<UserScript::File>& file : script_->css_scripts()) | 252 for (const std::unique_ptr<UserScript::File>& file : script_->css_scripts()) { |
| 233 sources.push_back(user_script_set_->GetCssSource(*file)); | 253 // TODO(lazyboy): |css_content| string is copied into blink::WebString for |
| 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 } |
| 234 return sources; | 260 return sources; |
| 235 } | 261 } |
| 236 | 262 |
| 237 void UserScriptInjector::GetRunInfo( | 263 void UserScriptInjector::GetRunInfo( |
| 238 ScriptsRunInfo* scripts_run_info, | 264 ScriptsRunInfo* scripts_run_info, |
| 239 UserScript::RunLocation run_location) const { | 265 UserScript::RunLocation run_location) const { |
| 240 if (!script_) | 266 if (!script_) |
| 241 return; | 267 return; |
| 242 | 268 |
| 243 if (ShouldInjectJs(run_location)) { | 269 if (ShouldInjectJs(run_location)) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 256 void UserScriptInjector::OnInjectionComplete( | 282 void UserScriptInjector::OnInjectionComplete( |
| 257 std::unique_ptr<base::Value> execution_result, | 283 std::unique_ptr<base::Value> execution_result, |
| 258 UserScript::RunLocation run_location, | 284 UserScript::RunLocation run_location, |
| 259 content::RenderFrame* render_frame) {} | 285 content::RenderFrame* render_frame) {} |
| 260 | 286 |
| 261 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason, | 287 void UserScriptInjector::OnWillNotInject(InjectFailureReason reason, |
| 262 content::RenderFrame* render_frame) { | 288 content::RenderFrame* render_frame) { |
| 263 } | 289 } |
| 264 | 290 |
| 265 } // namespace extensions | 291 } // namespace extensions |
| OLD | NEW |