diff options
Diffstat (limited to 'src/core/renderer/user_resource_controller.cpp')
-rw-r--r-- | src/core/renderer/user_resource_controller.cpp | 138 |
1 files changed, 96 insertions, 42 deletions
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index 36125d189..f85879053 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -39,10 +39,12 @@ #include "user_resource_controller.h" +#include "base/memory/weak_ptr.h" #include "base/pending_task.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_frame_observer.h" #include "content/public/renderer/render_view_observer.h" #include "extensions/common/url_pattern.h" #include "third_party/WebKit/public/web/WebDocument.h" @@ -97,16 +99,19 @@ static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url) return true; } -class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver +class UserResourceController::RenderFrameObserverHelper : public content::RenderFrameObserver { public: - RenderViewObserverHelper(content::RenderView *); + RenderFrameObserverHelper(content::RenderFrame* render_frame); + private: - // RenderViewObserver implementation. - void DidFinishDocumentLoad(blink::WebLocalFrame* frame) override; - void DidFinishLoad(blink::WebLocalFrame* frame) override; - void DidStartProvisionalLoad(blink::WebLocalFrame* frame) override; - void FrameDetached(blink::WebFrame* frame) override; + ~RenderFrameObserverHelper() override; + + // RenderFrameObserver implementation. + void DidFinishDocumentLoad() override; + void DidFinishLoad() override; + void DidStartProvisionalLoad(blink::WebDataSource* data_source) override; + void FrameDetached() override; void OnDestruct() override; bool OnMessageReceived(const IPC::Message& message) override; @@ -115,10 +120,24 @@ private: void onScriptsCleared(); void runScripts(UserScriptData::InjectionPoint, blink::WebLocalFrame *); + + // Set of frames which are pending to get an AfterLoad invocation of runScripts, if they + // haven't gotten it already. QSet<blink::WebLocalFrame *> m_pendingFrames; + base::WeakPtrFactory<RenderFrameObserverHelper> m_weakPtrFactory; +}; + +// Used only for script cleanup on RenderView destruction. +class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver +{ +public: + RenderViewObserverHelper(content::RenderView* render_view); +private: + // RenderViewObserver implementation. + void OnDestruct() override; }; -void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) { if (p == UserScriptData::AfterLoad && !m_pendingFrames.remove(frame)) return; @@ -128,12 +147,16 @@ void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) { - content::RenderView *renderView = content::RenderView::FromWebView(frame->view()); + content::RenderFrame *renderFrame = content::RenderFrame::FromWebFrame(frame); + if (!renderFrame) + return; + const bool isMainFrame = renderFrame->IsMainFrame(); + + content::RenderView *renderView = renderFrame->GetRenderView(); if (!renderView) return; - const bool isMainFrame = (frame == renderView->GetWebView()->mainFrame()); - QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(globalScriptsIndex).toList(); + QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(0).toList(); scriptsToRun.append(m_viewUserScriptMap.value(renderView).toList()); Q_FOREACH (uint64_t id, scriptsToRun) { @@ -141,13 +164,13 @@ void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink: if (script.injectionPoint != p || (!script.injectForSubframes && !isMainFrame)) continue; - if (!scriptMatchesURL(script, frame->document().url())) + if (!scriptMatchesURL(script, frame->GetDocument().Url())) continue; - blink::WebScriptSource source(blink::WebString::fromUTF8(script.source), script.url); + blink::WebScriptSource source(blink::WebString::FromUTF8(script.source), script.url); if (script.worldId) - frame->executeScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0); + frame->ExecuteScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0); else - frame->executeScript(source); + frame->ExecuteScript(source); } } @@ -161,71 +184,96 @@ void UserResourceController::RunScriptsAtDocumentEnd(content::RenderFrame *rende runScripts(UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame()); } -UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *renderView) - : content::RenderViewObserver(renderView) +UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(content::RenderFrame *render_frame) + : content::RenderFrameObserver(render_frame), m_weakPtrFactory(this) +{ +} + +UserResourceController::RenderFrameObserverHelper::~RenderFrameObserverHelper() +{ + m_weakPtrFactory.InvalidateWeakPtrs(); +} + +UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *render_view) + : content::RenderViewObserver(render_view) { } -void UserResourceController::RenderViewObserverHelper::DidFinishDocumentLoad(blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad() { + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); m_pendingFrames.insert(frame); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame), + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderFrameObserverHelper::runScripts, + m_weakPtrFactory.GetWeakPtr(), UserScriptData::AfterLoad, frame), base::TimeDelta::FromMilliseconds(afterLoadTimeout)); } -void UserResourceController::RenderViewObserverHelper::DidFinishLoad(blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::DidFinishLoad() { + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); + // DidFinishDocumentLoad always comes before this, so frame has already been marked as pending. - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame)); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderFrameObserverHelper::runScripts, + m_weakPtrFactory.GetWeakPtr(), UserScriptData::AfterLoad, frame)); +} + +void UserResourceController::RenderFrameObserverHelper::DidStartProvisionalLoad(blink::WebDataSource *data_source) +{ + Q_UNUSED(data_source); + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); + m_pendingFrames.remove(frame); } -void UserResourceController::RenderViewObserverHelper::DidStartProvisionalLoad(blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::FrameDetached() { + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); m_pendingFrames.remove(frame); } -void UserResourceController::RenderViewObserverHelper::FrameDetached(blink::WebFrame *frame) +void UserResourceController::RenderFrameObserverHelper::OnDestruct() { - if (frame->isWebLocalFrame()) - m_pendingFrames.remove(frame->toWebLocalFrame()); + delete this; } void UserResourceController::RenderViewObserverHelper::OnDestruct() { + // Remove all scripts associated with the render view. if (content::RenderView *view = render_view()) UserResourceController::instance()->renderViewDestroyed(view); + delete this; } -bool UserResourceController::RenderViewObserverHelper::OnMessageReceived(const IPC::Message &message) +bool UserResourceController::RenderFrameObserverHelper::OnMessageReceived(const IPC::Message &message) { bool handled = true; - IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderViewObserverHelper, message) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_AddScript, onUserScriptAdded) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_RemoveScript, onUserScriptRemoved) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_ClearScripts, onScriptsCleared) + IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderFrameObserverHelper, message) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_AddScript, onUserScriptAdded) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_RemoveScript, onUserScriptRemoved) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_ClearScripts, onScriptsCleared) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; } -void UserResourceController::RenderViewObserverHelper::onUserScriptAdded(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::onUserScriptAdded(const UserScriptData &script) { - if (content::RenderView *view = render_view()) - UserResourceController::instance()->addScriptForView(script, view); + if (content::RenderFrame *frame = render_frame()) + if (content::RenderView *view = frame->GetRenderView()) + UserResourceController::instance()->addScriptForView(script, view); } -void UserResourceController::RenderViewObserverHelper::onUserScriptRemoved(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::onUserScriptRemoved(const UserScriptData &script) { - if (content::RenderView *view = render_view()) - UserResourceController::instance()->removeScriptForView(script, view); + if (content::RenderFrame *frame = render_frame()) + if (content::RenderView *view = frame->GetRenderView()) + UserResourceController::instance()->removeScriptForView(script, view); } -void UserResourceController::RenderViewObserverHelper::onScriptsCleared() +void UserResourceController::RenderFrameObserverHelper::onScriptsCleared() { - if (content::RenderView *view = render_view()) - UserResourceController::instance()->clearScriptsForView(view); + if (content::RenderFrame *frame = render_frame()) + if (content::RenderView *view = frame->GetRenderView()) + UserResourceController::instance()->clearScriptsForView(view); } UserResourceController *UserResourceController::instance() @@ -254,9 +302,15 @@ UserResourceController::UserResourceController() #endif // !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) } +void UserResourceController::renderFrameCreated(content::RenderFrame *renderFrame) +{ + // Will destroy itself when the RenderFrame is destroyed. + new RenderFrameObserverHelper(renderFrame); +} + void UserResourceController::renderViewCreated(content::RenderView *renderView) { - // Will destroy itself with their RenderView. + // Will destroy itself when the RenderView is destroyed. new RenderViewObserverHelper(renderView); } |