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 |