diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-05-23 11:24:03 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2016-06-01 16:56:23 +0000 |
commit | 4a94a13d54dbaf32e7ac34cdee6e207fe5478286 (patch) | |
tree | 107bcf735b559024bfc4121d23071cea27ac05d4 /src | |
parent | 9d94e3ad9a1f3cf215d267c4b43ce74d57c54b2b (diff) |
Fix early JavaScript injection
With the latest Chromium snapshot we can no longer install any
javascript before a new callback called RunScriptsAtDocumentStart has
been called. So we must refactor user-scripts and web-channels to
install on this call instead.
Change-Id: I440a0aa4b26100c650d5c678b454ea5beb6b59d2
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/renderer/content_renderer_client_qt.cpp | 12 | ||||
-rw-r--r-- | src/core/renderer/content_renderer_client_qt.h | 3 | ||||
-rw-r--r-- | src/core/renderer/user_resource_controller.cpp | 27 | ||||
-rw-r--r-- | src/core/renderer/user_resource_controller.h | 15 | ||||
-rw-r--r-- | src/core/renderer/web_channel_ipc_transport.cpp | 18 | ||||
-rw-r--r-- | src/core/renderer/web_channel_ipc_transport.h | 14 |
6 files changed, 77 insertions, 12 deletions
diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index b986d29de..97b0f1dca 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -134,6 +134,18 @@ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_fr new QtWebEngineCore::RenderFrameObserverQt(render_frame); } +void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame* render_frame) +{ + if (WebChannelIPCTransport *transport = WebChannelIPCTransport::Get(render_frame->GetRenderView())) + transport->RunScriptsAtDocumentStart(render_frame); + UserResourceController::instance()->RunScriptsAtDocumentStart(render_frame); +} + +void ContentRendererClientQt::RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) +{ + UserResourceController::instance()->RunScriptsAtDocumentEnd(render_frame); +} + bool ContentRendererClientQt::HasErrorPage(int httpStatusCode, std::string *errorDomain) { // Use an internal error page, if we have one for the status code. diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h index 847b09b63..b17c618c0 100644 --- a/src/core/renderer/content_renderer_client_qt.h +++ b/src/core/renderer/content_renderer_client_qt.h @@ -74,6 +74,9 @@ public: virtual bool IsLinkVisited(unsigned long long linkHash) Q_DECL_OVERRIDE; virtual void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) Q_DECL_OVERRIDE; + virtual void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) Q_DECL_OVERRIDE; + virtual void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) Q_DECL_OVERRIDE; + private: QScopedPointer<visitedlink::VisitedLinkSlave> m_visitedLinkSlave; QScopedPointer<web_cache::WebCacheRenderProcessObserver> m_webCacheObserver; diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index 30a04958f..68b5f3d40 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -39,6 +39,7 @@ #include "user_resource_controller.h" +#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view_observer.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" @@ -62,7 +63,6 @@ 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,14 +82,20 @@ 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; @@ -101,20 +107,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), diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h index bd3d0ba49..8eba12abc 100644 --- a/src/core/renderer/user_resource_controller.h +++ b/src/core/renderer/user_resource_controller.h @@ -48,11 +48,15 @@ #include <QtCore/QHash> #include <QtCore/QSet> +namespace blink { +class WebLocalFrame; +} + namespace content { +class RenderFrame; class RenderView; } - class UserResourceController : public content::RenderProcessObserver { public: @@ -64,22 +68,29 @@ public: void removeScriptForView(const UserScriptData &, content::RenderView *); void clearScriptsForView(content::RenderView *); + void RunScriptsAtDocumentStart(content::RenderFrame *render_frame); + void RunScriptsAtDocumentEnd(content::RenderFrame *render_frame); + private: Q_DISABLE_COPY(UserResourceController) class RenderViewObserverHelper; // RenderProcessObserver implementation. - virtual bool OnControlMessageReceived(const IPC::Message &message) Q_DECL_OVERRIDE; + bool OnControlMessageReceived(const IPC::Message &message) override; void onAddScript(const UserScriptData &); void onRemoveScript(const UserScriptData &); void onClearScripts(); + void runScripts(UserScriptData::InjectionPoint, blink::WebLocalFrame *); + typedef QSet<uint64_t> UserScriptSet; typedef QHash<const content::RenderView *, UserScriptSet> ViewUserScriptMap; ViewUserScriptMap m_viewUserScriptMap; QHash<uint64_t, UserScriptData> m_scripts; + + friend class RenderViewObserverHelper; }; #endif // USER_RESOURCE_CONTROLLER_H diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index d1e5f2245..f965c2cc7 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -44,6 +44,7 @@ #include "common/qt_messages.h" +#include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "gin/arguments.h" #include "gin/handle.h" @@ -153,11 +154,26 @@ content::RenderView *WebChannelTransport::GetRenderView(v8::Isolate *isolate) WebChannelIPCTransport::WebChannelIPCTransport(content::RenderView *renderView) : content::RenderViewObserver(renderView) + , content::RenderViewObserverTracker<WebChannelIPCTransport>(renderView) + , m_worldId(0) + , m_installed(false) { } +void WebChannelIPCTransport::RunScriptsAtDocumentStart(content::RenderFrame *render_frame) +{ + // JavaScript run before this point doesn't stick, and needs to be redone. + // ### FIXME: we should try no even installing before + blink::WebLocalFrame *frame = render_frame->GetWebFrame(); + if (m_installed && render_frame->IsMainFrame()) + WebChannelTransport::Install(frame, m_worldId); +} + + void WebChannelIPCTransport::installWebChannel(uint worldId) { + m_worldId = worldId; + m_installed = true; blink::WebView *webView = render_view()->GetWebView(); if (!webView) return; @@ -166,6 +182,8 @@ void WebChannelIPCTransport::installWebChannel(uint worldId) void WebChannelIPCTransport::uninstallWebChannel(uint worldId) { + Q_ASSERT(worldId = m_worldId); + m_installed = false; blink::WebView *webView = render_view()->GetWebView(); if (!webView) return; diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h index f799f47af..81e64bb0f 100644 --- a/src/core/renderer/web_channel_ipc_transport.h +++ b/src/core/renderer/web_channel_ipc_transport.h @@ -42,23 +42,35 @@ #include "base/values.h" #include "content/public/renderer/render_view_observer.h" +#include "content/public/renderer/render_view_observer_tracker.h" #include <QtCore/qcompilerdetection.h> +namespace content { +class RenderFrame; +} + namespace v8 { class Extension; } namespace QtWebEngineCore { -class WebChannelIPCTransport : public content::RenderViewObserver { +class WebChannelIPCTransport : public content::RenderViewObserver + , public content::RenderViewObserverTracker<WebChannelIPCTransport> +{ public: WebChannelIPCTransport(content::RenderView *); + void RunScriptsAtDocumentStart(content::RenderFrame *render_frame); + private: void dispatchWebChannelMessage(const std::vector<char> &binaryJSON, uint worldId); void installWebChannel(uint worldId); void uninstallWebChannel(uint worldId); virtual bool OnMessageReceived(const IPC::Message &message) Q_DECL_OVERRIDE; + + uint m_worldId; + bool m_installed; }; } // namespace |