From 70abc0b2eebc777309d372203df5ca1e785402d8 Mon Sep 17 00:00:00 2001 From: Szabolcs David Date: Mon, 20 Sep 2021 09:29:30 +0200 Subject: Fix WebChannel when JavaScript is disabled WebChannel was not working in ApplicationWorld with JavaScript disabled in MainWorld, because WebChannelIPCTransport::DidClearWindowObject() is called only when the window object was cleared in the main world. Moving the WebChannelTransport installation logic to DidCreateScriptContext() works in other worlds, so fixes the problem. Task-number: QTBUG-88875 Pick-to: 6.2 Change-Id: Ia75613b66a1e049f617f0664684b153b6875e9de Reviewed-by: Allan Sandfeld Jensen --- src/core/renderer/web_channel_ipc_transport.cpp | 16 +++++------ src/core/renderer/web_channel_ipc_transport.h | 2 +- .../qwebenginescript/tst_qwebenginescript.cpp | 31 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index fff3eb70f..8525c3619 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -259,21 +259,21 @@ void WebChannelIPCTransport::DispatchWebChannelMessage(const std::vectorCallFunctionEvenIfScriptDisabled(callback, webChannelObject, 1, argv); } -void WebChannelIPCTransport::WillReleaseScriptContext(v8::Local context, int worldId) -{ - if (static_cast(worldId) == m_worldId) - m_canUseContext = false; -} - -void WebChannelIPCTransport::DidClearWindowObject() +void WebChannelIPCTransport::DidCreateScriptContext(v8::Local context, int32_t worldId) { - if (!m_canUseContext) { + if (static_cast(worldId) == m_worldId && !m_canUseContext) { m_canUseContext = true; if (m_worldInitialized) WebChannelTransport::Install(render_frame()->GetWebFrame(), m_worldId); } } +void WebChannelIPCTransport::WillReleaseScriptContext(v8::Local context, int worldId) +{ + if (static_cast(worldId) == m_worldId) + m_canUseContext = false; +} + void WebChannelIPCTransport::OnDestruct() { delete this; diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h index 276167a67..f048a26d8 100644 --- a/src/core/renderer/web_channel_ipc_transport.h +++ b/src/core/renderer/web_channel_ipc_transport.h @@ -64,8 +64,8 @@ private: void DispatchWebChannelMessage(const std::vector &json, uint32_t worldId) override; // RenderFrameObserver + void DidCreateScriptContext(v8::Local context, int32_t worldId) override; void WillReleaseScriptContext(v8::Local context, int worldId) override; - void DidClearWindowObject() override; void OnDestruct() override; void BindReceiver(mojo::PendingAssociatedReceiver receiver); diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp index ca2f0cab9..5df9f035f 100644 --- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp +++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp @@ -70,6 +70,7 @@ private Q_SLOTS: void webChannelWithExistingQtObject(); void navigation(); void webChannelWithBadString(); + void webChannelWithJavaScriptDisabled(); #endif void noTransportWithoutWebChannel(); void scriptsInNestedIframes(); @@ -592,6 +593,36 @@ void tst_QWebEngineScript::webChannelWithBadString() QChar data(0xd800); QCOMPARE(host.text(), data); } + +void tst_QWebEngineScript::webChannelWithJavaScriptDisabled() +{ + QWebEnginePage page; + QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished); + // JavaScript disabled in main world + page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false); + + TestObject testObject; + QScopedPointer channel(new QWebChannel(this)); + channel->registerObject(QStringLiteral("object"), &testObject); + page.setWebChannel(channel.data(), QWebEngineScript::ApplicationWorld); + + QWebEngineScript script = webChannelScript(); + script.setWorldId(QWebEngineScript::ApplicationWorld); + page.scripts().insert(script); + + page.setHtml(QStringLiteral("")); + QVERIFY(spyFinished.wait()); + + QSignalSpy spyTextChanged(&testObject, &TestObject::textChanged); + page.runJavaScript(QLatin1String( + "new QWebChannel(qt.webChannelTransport," + " function(channel) {" + " channel.objects.object.text = 'test';" + " }" + ");"), QWebEngineScript::ApplicationWorld); + QVERIFY(spyTextChanged.wait()); + QCOMPARE(testObject.text(), QStringLiteral("test")); +} #endif void tst_QWebEngineScript::matchQrcUrl() -- cgit v1.2.3