diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-01-29 15:57:18 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-01-31 21:31:45 +0000 |
commit | ef1f608f76f02f11b4bdcc8d52fa41cdf4cdf5c3 (patch) | |
tree | 047a52a007af9f835f077d5061861557296ae7a8 | |
parent | 23c652c3c1680f42adfd5c6500280b103ce1d095 (diff) |
Preserve webchannel and userscripts when restoring history
Most page-state is set in webcontentsadapter::initialize except user
scripts and webchannel. This patch ensures those are initialized too
when changing to a new adapter during history restore.
Change-Id: I4dca23ddab50480b1a72252a038834ce1802ad77
Task-number: QTBUG-50751
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Reviewed-by: David Rosca <nowrep@gmail.com>
5 files changed, 63 insertions, 2 deletions
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 511ddfb0f..b1bf33067 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -107,6 +107,7 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) , m_isBeingAdopted(false) , m_backgroundColor(Qt::white) , fullscreenMode(false) + , webChannel(nullptr) { memset(actions, 0, sizeof(actions)); } @@ -407,8 +408,14 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input) { QExplicitlySharedDataPointer<WebContentsAdapter> newWebContents = WebContentsAdapter::createFromSerializedNavigationHistory(input, this); if (newWebContents) { + // Keep the old adapter referenced so the user-scripts are not + // unregistered immediately. + QExplicitlySharedDataPointer<WebContentsAdapter> oldWebContents = adapter; adapter = newWebContents.data(); adapter->initialize(this); + if (webChannel) + adapter->setWebChannel(webChannel); + scriptCollection.d->rebindToContents(adapter.data()); } } @@ -519,7 +526,7 @@ QWebEngineSettings *QWebEnginePage::settings() const QWebChannel *QWebEnginePage::webChannel() const { Q_D(const QWebEnginePage); - return d->adapter->webChannel(); + return d->webChannel; } /*! @@ -536,7 +543,10 @@ QWebChannel *QWebEnginePage::webChannel() const void QWebEnginePage::setWebChannel(QWebChannel *channel) { Q_D(QWebEnginePage); - d->adapter->setWebChannel(channel); + if (d->webChannel != channel) { + d->webChannel = channel; + d->adapter->setWebChannel(channel); + } } /*! diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 9cc4553d1..18110d923 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -151,6 +151,7 @@ public: bool m_isBeingAdopted; QColor m_backgroundColor; bool fullscreenMode; + QWebChannel *webChannel; mutable QtWebEngineCore::CallbackDirectory m_callbacks; mutable QAction *actions[QWebEnginePage::WebActionCount]; diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp index 9967cde85..117c35b5a 100644 --- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp +++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp @@ -220,3 +220,15 @@ void QWebEngineScriptCollectionPrivate::reserve(int capacity) { m_scriptController->reserve(m_contents, capacity); } + +void QWebEngineScriptCollectionPrivate::rebindToContents(QtWebEngineCore::WebContentsAdapter *page) +{ + Q_ASSERT(m_contents); + Q_ASSERT(page); + Q_ASSERT(m_contents != page); + + Q_FOREACH (const UserScript &script, m_scriptController->registeredScripts(m_contents)) { + m_scriptController->addUserScript(script, page); + } + m_contents = page; +} diff --git a/src/webenginewidgets/api/qwebenginescriptcollection_p.h b/src/webenginewidgets/api/qwebenginescriptcollection_p.h index cc6e88445..b5ae60a2c 100644 --- a/src/webenginewidgets/api/qwebenginescriptcollection_p.h +++ b/src/webenginewidgets/api/qwebenginescriptcollection_p.h @@ -69,6 +69,8 @@ public: QList<QWebEngineScript> toList(const QString &scriptName = QString()) const; QWebEngineScript find(const QString & name) const; + void rebindToContents(QtWebEngineCore::WebContentsAdapter *contents); + void insert(const QWebEngineScript &); bool remove(const QWebEngineScript &); void clear(); diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 8fd71c701..690cf70e4 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -33,6 +33,7 @@ #include <QStyle> #include <QtTest/QtTest> #include <QTextCharFormat> +#include <QWebChannel> #include <private/qinputmethod_p.h> #include <qnetworkcookiejar.h> #include <qnetworkreply.h> @@ -42,6 +43,8 @@ #include <qwebenginehistory.h> #include <qwebenginepage.h> #include <qwebengineprofile.h> +#include <qwebenginescript.h> +#include <qwebenginescriptcollection.h> #include <qwebenginesettings.h> #include <qwebengineview.h> #include <qimagewriter.h> @@ -237,6 +240,8 @@ private Q_SLOTS: void loadInSignalHandlers_data(); void loadInSignalHandlers(); + void restoreHistory(); + private: QWebEngineView* m_view; QWebEnginePage* m_page; @@ -5079,5 +5084,36 @@ void tst_QWebEnginePage::loadInSignalHandlers() QCOMPARE(m_page->url(), urlForSetter); } +void tst_QWebEnginePage::restoreHistory() +{ + QWebChannel *channel = new QWebChannel; + QWebEnginePage *page = new QWebEnginePage; + page->setWebChannel(channel); + + QWebEngineScript script; + script.setName(QStringLiteral("script")); + page->scripts().insert(script); + + QSignalSpy spy(page, SIGNAL(loadFinished(bool))); + page->load(QUrl(QStringLiteral("qrc:/resources/test1.html"))); + QTRY_COMPARE(spy.count(), 1); + + QCOMPARE(page->webChannel(), channel); + QVERIFY(page->scripts().contains(script)); + + QByteArray data; + QDataStream out(&data, QIODevice::ReadWrite); + out << *page->history(); + QDataStream in(&data, QIODevice::ReadOnly); + in >> *page->history(); + QTRY_COMPARE(spy.count(), 2); + + QCOMPARE(page->webChannel(), channel); + QVERIFY(page->scripts().contains(script)); + + delete page; + delete channel; +} + QTEST_MAIN(tst_QWebEnginePage) #include "tst_qwebenginepage.moc" |