diff options
Diffstat (limited to 'src/core/renderer/user_resource_controller.cpp')
-rw-r--r-- | src/core/renderer/user_resource_controller.cpp | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index 30a04958f..8c603b805 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -39,8 +39,12 @@ #include "user_resource_controller.h" +#include "base/strings/pattern.h" +#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view_observer.h" +#include "extensions/common/url_pattern.h" +#include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebScriptSource.h" #include "third_party/WebKit/public/web/WebView.h" @@ -48,6 +52,8 @@ #include "common/qt_messages.h" #include "common/user_script_data.h" +#include "type_conversion.h" +#include "user_script.h" Q_GLOBAL_STATIC(UserResourceController, qt_webengine_userResourceController) @@ -56,13 +62,46 @@ static content::RenderView * const globalScriptsIndex = 0; // Scripts meant to run after the load event will be run 500ms after DOMContentLoaded if the load event doesn't come within that delay. static const int afterLoadTimeout = 500; +static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url) { + // Logic taken from Chromium (extensions/common/user_script.cc) + bool matchFound; + if (!scriptData.urlPatterns.empty()) { + matchFound = false; + for (auto it = scriptData.urlPatterns.begin(), end = scriptData.urlPatterns.end(); it != end; ++it) { + URLPattern urlPattern(QtWebEngineCore::UserScript::validUserScriptSchemes(), *it); + if (urlPattern.MatchesURL(url)) + matchFound = true; + } + if (!matchFound) + return false; + } + + if (!scriptData.globs.empty()) { + matchFound = false; + for (auto it = scriptData.globs.begin(), end = scriptData.globs.end(); it != end; ++it) { + if (base::MatchPattern(url.spec(), *it)) + matchFound = true; + } + if (!matchFound) + return false; + } + + if (!scriptData.excludeGlobs.empty()) { + for (auto it = scriptData.excludeGlobs.begin(), end = scriptData.excludeGlobs.end(); it != end; ++it) { + if (base::MatchPattern(url.spec(), *it)) + return false; + } + } + + return true; +} + class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver { public: RenderViewObserverHelper(content::RenderView *); private: // RenderViewObserver implementation. - virtual void DidCreateDocumentElement(blink::WebLocalFrame* frame) Q_DECL_OVERRIDE; virtual void DidFinishDocumentLoad(blink::WebLocalFrame* frame) Q_DECL_OVERRIDE; virtual void DidFinishLoad(blink::WebLocalFrame* frame) Q_DECL_OVERRIDE; virtual void DidStartProvisionalLoad(blink::WebLocalFrame* frame) Q_DECL_OVERRIDE; @@ -82,17 +121,25 @@ void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData { if (p == UserScriptData::AfterLoad && !m_pendingFrames.remove(frame)) return; + + UserResourceController::instance()->runScripts(p, frame); +} + +void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) +{ content::RenderView *renderView = content::RenderView::FromWebView(frame->view()); const bool isMainFrame = (frame == renderView->GetWebView()->mainFrame()); - QList<uint64_t> scriptsToRun = UserResourceController::instance()->m_viewUserScriptMap.value(globalScriptsIndex).toList(); - scriptsToRun.append(UserResourceController::instance()->m_viewUserScriptMap.value(renderView).toList()); + QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(globalScriptsIndex).toList(); + scriptsToRun.append(m_viewUserScriptMap.value(renderView).toList()); Q_FOREACH (uint64_t id, scriptsToRun) { - const UserScriptData &script = UserResourceController::instance()->m_scripts.value(id); + const UserScriptData &script = m_scripts.value(id); if (script.injectionPoint != p || (!script.injectForSubframes && !isMainFrame)) continue; + if (!scriptMatchesURL(script, frame->document().url())) + continue; blink::WebScriptSource source(blink::WebString::fromUTF8(script.source), script.url); if (script.worldId) frame->executeScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0); @@ -101,20 +148,23 @@ void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData } } +void UserResourceController::RunScriptsAtDocumentStart(content::RenderFrame *render_frame) +{ + runScripts(UserScriptData::DocumentElementCreation, render_frame->GetWebFrame()); +} -UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *renderView) - : content::RenderViewObserver(renderView) +void UserResourceController::RunScriptsAtDocumentEnd(content::RenderFrame *render_frame) { + runScripts(UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame()); } -void UserResourceController::RenderViewObserverHelper::DidCreateDocumentElement(blink::WebLocalFrame *frame) +UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *renderView) + : content::RenderViewObserver(renderView) { - runScripts(UserScriptData::DocumentElementCreation, frame); } void UserResourceController::RenderViewObserverHelper::DidFinishDocumentLoad(blink::WebLocalFrame *frame) { - runScripts(UserScriptData::DocumentLoadFinished, frame); m_pendingFrames.insert(frame); base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, base::Unretained(this), UserScriptData::AfterLoad, frame), |