diff options
author | Jüri Valdmann <juri.valdmann@qt.io> | 2019-04-02 16:24:50 +0200 |
---|---|---|
committer | Jüri Valdmann <juri.valdmann@qt.io> | 2019-04-08 12:35:07 +0000 |
commit | 44303861fd116b3a279d26300147e89a0bf8121c (patch) | |
tree | 839282642c0ef90fc4b629fc1766e08bbd06151d | |
parent | 2b623019de45daba51ae31d16e4b05e3c30adbc3 (diff) |
Run non-MainWorld DocumentCreation scripts even if JS disabled
Fixes regression, introduced by the fix for QTBUG-66011, where setting
JavascriptEnabled to false stops all scripts from running instead of only
MainWorld scripts (as documented). Only the DocumentCreation injection point is
affected.
The original change which introduced the regression consisted of moving the
DocumentCreation injection point from
ContentRendererClient::RunScriptsAtDocumentStart
to
RenderFrameObserver::DidClearWindowObject.
The problem of scripts not working on view-source URLs was fixed by this move,
but it turns out that the call to DidClearWindowObject happens to be conditional
on Document::CanExecuteScripts and this is, of course, false if JS is disabled.
Hence the regression.
This new patch moves the injection point again to a task launched from
RenderFrameObserver::DidCommitProvisionalLoad.
DidCommitProvisionalLoad and DidClearWindowObject are both indirectly called
from DocumentLoader::InstallNewDocument, however the former is called before the
Document is opened and is therefore too early for script execution. As such, the
execution is delayed by posting a task which, in theory, should be scheduled
very soon after the normal call to DidClearWindowObject.
Fixes: QTBUG-74304
Change-Id: Iac8714bcc5651c287b73181811af26996d955af5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | src/core/renderer/user_resource_controller.cpp | 11 | ||||
-rw-r--r-- | tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp | 47 |
2 files changed, 50 insertions, 8 deletions
diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index 920fda72e..9c03cd651 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -138,7 +138,6 @@ public: private: // RenderFrameObserver implementation. void DidCommitProvisionalLoad(bool is_new_navigation, bool is_same_document_navigation) override; - void DidClearWindowObject() override; void DidFinishDocumentLoad() override; void DidFinishLoad() override; void FrameDetached() override; @@ -241,14 +240,10 @@ void UserResourceController::RenderFrameObserverHelper::DidCommitProvisionalLoad // that the WebChannelTransportHost is ready to receive messages. m_runner.reset(new Runner(render_frame()->GetWebFrame())); -} -void UserResourceController::RenderFrameObserverHelper::DidClearWindowObject() -{ - // This is called both before and after DidCommitProvisionalLoad, non-null - // m_runner means it's after. - if (m_runner) - m_runner->run(UserScriptData::DocumentElementCreation); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&Runner::run, m_runner->AsWeakPtr(), UserScriptData::DocumentElementCreation)); } void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad() diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp index 0fe0ec6cf..be9e59b8c 100644 --- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp +++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp @@ -23,6 +23,7 @@ #include <qwebengineprofile.h> #include <qwebenginescript.h> #include <qwebenginescriptcollection.h> +#include <qwebenginesettings.h> #include <qwebengineview.h> #include "../util.h" #if QT_CONFIG(webengine_webchannel) @@ -37,6 +38,8 @@ private Q_SLOTS: void loadEvents(); void scriptWorld_data(); void scriptWorld(); + void scriptDisabled(); + void viewSource(); void scriptModifications(); #if QT_CONFIG(webengine_webchannel) void webChannel_data(); @@ -218,6 +221,50 @@ void tst_QWebEngineScript::scriptWorld() QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;", worldId), QVariant::fromValue(true)); } +// Based on QTBUG-74304 +void tst_QWebEngineScript::scriptDisabled() +{ + QWebEnginePage page; + page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false); + QWebEngineScript script; + script.setInjectionPoint(QWebEngineScript::DocumentCreation); + script.setWorldId(QWebEngineScript::MainWorld); + script.setSourceCode("var foo = 42"); + page.scripts().insert(script); + page.load(QUrl("about:blank")); + QSignalSpy spy(&page, &QWebEnginePage::loadFinished); + QTRY_COMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().value(0).toBool(), true); + // MainWorld scripts are disabled by the setting... + QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::MainWorld), QVariant()); + QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::ApplicationWorld), QVariant()); + script.setWorldId(QWebEngineScript::ApplicationWorld); + page.scripts().clear(); + page.scripts().insert(script); + page.load(QUrl("about:blank")); + QTRY_COMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().value(0).toBool(), true); + // ...but ApplicationWorld scripts should still work + QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::MainWorld), QVariant()); + QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "foo", QWebEngineScript::ApplicationWorld), QVariant(42)); +} + +// Based on QTBUG-66011 +void tst_QWebEngineScript::viewSource() +{ + QWebEnginePage page; + QWebEngineScript script; + script.setInjectionPoint(QWebEngineScript::DocumentCreation); + script.setWorldId(QWebEngineScript::MainWorld); + script.setSourceCode("var foo = 42"); + page.scripts().insert(script); + page.load(QUrl("view-source:about:blank")); + QSignalSpy spy(&page, &QWebEnginePage::loadFinished); + QTRY_COMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().value(0).toBool(), true); + QCOMPARE(evaluateJavaScriptSync(&page, "foo"), QVariant(42)); +} + void tst_QWebEngineScript::scriptModifications() { QWebEnginePage page; |