Chromium Code Reviews| Index: extensions/renderer/user_script_set.cc |
| diff --git a/extensions/renderer/user_script_set.cc b/extensions/renderer/user_script_set.cc |
| index 5fd7ab8b28a367829c37239294efccafd442d1e8..1f664d2ef9da2e1e35487486f927fb601f2553c2 100644 |
| --- a/extensions/renderer/user_script_set.cc |
| +++ b/extensions/renderer/user_script_set.cc |
| @@ -8,6 +8,7 @@ |
| #include <utility> |
| +#include "base/lazy_instance.h" |
| #include "base/memory/ref_counted.h" |
| #include "content/public/common/url_constants.h" |
| #include "content/public/renderer/render_frame.h" |
| @@ -23,14 +24,21 @@ |
| #include "extensions/renderer/script_injection.h" |
| #include "extensions/renderer/user_script_injector.h" |
| #include "extensions/renderer/web_ui_injection_host.h" |
| +#include "grit/extensions_renderer_resources.h" |
| #include "third_party/WebKit/public/web/WebDocument.h" |
| #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| #include "url/gurl.h" |
| namespace extensions { |
| namespace { |
| +// These two strings are injected before and after the Greasemonkey API and |
| +// user script to wrap it in an anonymous scope. |
| +const char kUserScriptHead[] = "(function (unsafeWindow) {\n"; |
| +const char kUserScriptTail[] = "\n})(window);"; |
| + |
| GURL GetDocumentUrlForFrame(blink::WebLocalFrame* frame) { |
| GURL data_source_url = ScriptContext::GetDataSourceURLForFrame(frame); |
| if (!data_source_url.is_empty() && frame->isViewSourceModeEnabled()) { |
| @@ -41,6 +49,32 @@ GURL GetDocumentUrlForFrame(blink::WebLocalFrame* frame) { |
| return data_source_url; |
| } |
| +// Greasemonkey API source that is injected with the scripts. |
| +struct GreasemonkeyApiJsString { |
| + GreasemonkeyApiJsString(); |
| + blink::WebScriptSource GetSource() const; |
| + |
| + private: |
| + blink::WebString source_; |
| +}; |
| + |
| +// The below constructor, monstrous as it is, just makes a WebScriptSource from |
| +// the GreasemonkeyApiJs resource. |
| +GreasemonkeyApiJsString::GreasemonkeyApiJsString() { |
| + base::StringPiece source_piece = |
| + ResourceBundle::GetSharedInstance().GetRawDataResource( |
| + IDR_GREASEMONKEY_API_JS); |
| + source_ = |
| + blink::WebString::fromUTF8(source_piece.data(), source_piece.length()); |
| +} |
| + |
| +blink::WebScriptSource GreasemonkeyApiJsString::GetSource() const { |
| + return blink::WebScriptSource(source_); |
| +} |
| + |
| +base::LazyInstance<GreasemonkeyApiJsString> g_greasemonkey_api = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| } // namespace |
| UserScriptSet::UserScriptSet() {} |
| @@ -113,6 +147,8 @@ bool UserScriptSet::UpdateUserScripts(base::SharedMemoryHandle shared_memory, |
| CHECK(iter.ReadUInt32(&num_scripts)); |
| scripts_.clear(); |
| + js_script_sources_.clear(); |
| + css_script_sources_.clear(); |
| scripts_.reserve(num_scripts); |
| for (uint32_t i = 0; i < num_scripts; ++i) { |
| std::unique_ptr<UserScript> script(new UserScript()); |
| @@ -226,4 +262,87 @@ std::unique_ptr<ScriptInjection> UserScriptSet::GetInjectionForScript( |
| return injection; |
| } |
| +std::vector<blink::WebScriptSource> UserScriptSet::GetJsSources(int script_id) { |
|
Devlin
2016/08/25 17:07:35
Semi-random placement: This is going to conflict w
lazyboy
2016/09/06 19:37:32
I've changed the storage to map GURL-> WebString.
|
| + UserScriptList::const_iterator script_iter = |
| + std::find_if(scripts_.begin(), scripts_.end(), |
|
Devlin
2016/08/25 17:07:35
In the past, I've found that I've been too gung-ho
lazyboy
2016/09/06 19:37:31
Acknowledged, this is no longer relevant.
|
| + [&script_id](const std::unique_ptr<UserScript>& script) { |
| + return script->id() == script_id; |
| + }); |
| + if (script_iter == scripts_.end()) |
| + return std::vector<blink::WebScriptSource>(); |
| + |
| + const UserScript& script = *script_iter->get(); |
| + std::map<int, std::vector<blink::WebScriptSource>>::iterator iter = |
| + js_script_sources_.find(script_id); |
| + if (iter != js_script_sources_.end()) { |
| + // Win, we already have the script contents in WebString-s. |
| + return iter->second; |
| + } |
| + |
| + iter = js_script_sources_.insert(iter, std::make_pair( |
| + script_id, std::vector<blink::WebScriptSource>())); |
| + std::vector<blink::WebScriptSource>& sources_vector = iter->second; |
| + |
| + for (const std::unique_ptr<UserScript::File>& js_file : |
| + script_iter->get()->js_scripts()) { |
| + base::StringPiece script_content = js_file->GetContent(); |
| + blink::WebString source; |
| + if (script.emulate_greasemonkey()) { |
| + // We add this dumb function wrapper for user scripts to emulate what |
| + // Greasemonkey does. |script_content| becomes: |
| + // concat(kUserScriptHead, script_content, kUserScriptTail). |
| + std::string content; |
| + content.reserve(strlen(kUserScriptHead) + script_content.length() + |
| + strlen(kUserScriptTail)); |
| + content.append(kUserScriptHead); |
| + script_content.AppendToString(&content); |
| + content.append(kUserScriptTail); |
| + source = blink::WebString::fromUTF8(content); |
| + } else { |
| + source = blink::WebString::fromUTF8(script_content.data(), |
| + script_content.length()); |
| + } |
| + sources_vector.push_back(blink::WebScriptSource(source)); |
| + } |
| + |
| + // Emulate Greasemonkey API for scripts that were converted to extension |
| + // user scripts. |
| + if (script.emulate_greasemonkey()) { |
| + sources_vector.insert(sources_vector.begin(), |
| + g_greasemonkey_api.Get().GetSource()); |
| + } |
| + |
| + return sources_vector; |
| +} |
| + |
| +std::vector<blink::WebString> UserScriptSet::GetCssSources(int script_id) { |
| + const auto& script_iter = |
| + std::find_if(scripts_.begin(), scripts_.end(), |
| + [&script_id](const std::unique_ptr<UserScript>& script) { |
| + return script->id() == script_id; |
| + }); |
| + if (script_iter == scripts_.end()) |
| + return std::vector<blink::WebString>(); |
| + const UserScript& script = *script_iter->get(); |
| + |
| + auto iter = css_script_sources_.find(script_id); |
| + if (iter != css_script_sources_.end()) { |
| + // Win, we already have the script contents in WebString-s. |
| + return iter->second; |
| + } |
| + |
| + iter = css_script_sources_.insert(iter, std::make_pair( |
| + script_id, std::vector<blink::WebString>())); |
| + |
| + std::vector<blink::WebString>& sources_vector = iter->second; |
| + for (const std::unique_ptr<UserScript::File>& css_file : |
| + script.css_scripts()) { |
| + base::StringPiece script_content = css_file->GetContent(); |
| + sources_vector.push_back(blink::WebString::fromUTF8( |
| + script_content.data(), script_content.length())); |
| + } |
| + |
| + return sources_vector; |
| +} |
| + |
| } // namespace extensions |