summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp2
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp76
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h5
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp96
4 files changed, 161 insertions, 18 deletions
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 187565a76..fbb7c1f9e 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -902,7 +902,7 @@ QWebEnginePage::~QWebEnginePage()
Q_D(QWebEnginePage);
setDevToolsPage(nullptr);
d->adapter->stopFinding();
- QWebEngineViewPrivate::bind(nullptr, this, true);
+ QWebEngineViewPrivate::removePageFromView(this);
}
QWebEngineHistory *QWebEnginePage::history() const
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index aa51e5b0e..e6f9fcb49 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -55,33 +55,77 @@
QT_BEGIN_NAMESPACE
-void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page, bool pageBeingDeleted)
+void QWebEngineViewPrivate::notify(QWebEngineView *view, QWebEnginePage *oldPage, QWebEnginePage *newPage)
+{
+ Q_ASSERT(view);
+
+ auto oldUrl = oldPage ? oldPage->url() : QUrl();
+ auto newUrl = newPage ? newPage->url() : QUrl();
+ if (oldUrl != newUrl)
+ Q_EMIT view->urlChanged(newUrl);
+
+ auto oldTitle = oldPage ? oldPage->title() : QString();
+ auto newTitle = newPage ? newPage->title() : QString();
+ if (oldTitle != newTitle)
+ Q_EMIT view->titleChanged(newTitle);
+
+ auto oldIcon = oldPage ? oldPage->iconUrl() : QUrl();
+ auto newIcon = newPage ? newPage->iconUrl() : QUrl();
+ if (oldIcon != newIcon) {
+ Q_EMIT view->iconUrlChanged(newIcon);
+ Q_EMIT view->iconChanged(newPage ? newPage->icon() : QIcon());
+ }
+
+ if ((oldPage && oldPage->hasSelection()) || (newPage && newPage->hasSelection()))
+ Q_EMIT view->selectionChanged();
+}
+
+QWebEnginePage* QWebEngineViewPrivate::removeViewFromPage(QWebEngineView *view)
+{
+ Q_ASSERT(view);
+ QWebEnginePage *oldPage = view->d_func()->page;
+
+ if (oldPage) {
+ oldPage->disconnect(view);
+ oldPage->d_func()->view = nullptr;
+ if (oldPage->parent() != view)
+ oldPage->d_func()->adapter->reattachRWHV();
+ }
+ return oldPage;
+}
+
+void QWebEngineViewPrivate::removePageFromView(QWebEnginePage *page)
+{
+ Q_ASSERT(page);
+ if (QWebEngineView *oldView = page->d_func()->view) {
+ page->disconnect(oldView);
+ page->d_func()->view = nullptr;
+ oldView->d_func()->page = nullptr;
+ notify(oldView, page, nullptr);
+ }
+}
+
+void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
{
if (view && page == view->d_func()->page)
return;
if (page) {
// Un-bind page from its current view.
- if (QWebEngineView *oldView = page->d_func()->view) {
- page->disconnect(oldView);
- oldView->d_func()->page = nullptr;
- }
+ removePageFromView(page);
page->d_func()->view = view;
- if (!pageBeingDeleted)
- page->d_func()->adapter->reattachRWHV();
+ page->d_func()->adapter->reattachRWHV();
}
if (view) {
// Un-bind view from its current page.
- if (QWebEnginePage *oldPage = view->d_func()->page) {
- oldPage->disconnect(view);
- oldPage->d_func()->view = nullptr;
- if (oldPage->parent() == view)
- delete oldPage;
- else
- oldPage->d_func()->adapter->reattachRWHV();
- }
+ QWebEnginePage *oldPage = removeViewFromPage(view);
+
view->d_func()->page = page;
+ notify(view, oldPage, page);
+
+ if (oldPage && oldPage->parent() == view)
+ delete oldPage;
}
if (view && page) {
@@ -149,7 +193,7 @@ QWebEngineView::QWebEngineView(QWidget *parent)
QWebEngineView::~QWebEngineView()
{
- QWebEngineViewPrivate::bind(this, nullptr);
+ QWebEngineViewPrivate::removeViewFromPage(this);
}
QWebEnginePage* QWebEngineView::page() const
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index bfb44bec5..1845bfb60 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -65,7 +65,10 @@ public:
Q_DECLARE_PUBLIC(QWebEngineView)
QWebEngineView *q_ptr;
- static void bind(QWebEngineView *view, QWebEnginePage *page, bool pageBeingDeleted = false);
+ static void notify(QWebEngineView *view, QWebEnginePage *oldPage, QWebEnginePage *newPage);
+ static QWebEnginePage* removeViewFromPage(QWebEngineView *view);
+ static void removePageFromView(QWebEnginePage *page);
+ static void bind(QWebEngineView *view, QWebEnginePage *page);
QWebEngineViewPrivate();
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 57f5f6def..78677e459 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -134,6 +134,8 @@ private Q_SLOTS:
void renderHints();
void getWebKitVersion();
+ void changePage_data();
+ void changePage();
void reusePage_data();
void reusePage();
void microFocusCoordinates();
@@ -260,6 +262,100 @@ void tst_QWebEngineView::getWebKitVersion()
#endif
}
+void tst_QWebEngineView::changePage_data()
+{
+ QString html = "<html><head><title>%1</title>"
+ "<link rel='icon' href='file://" TESTS_SOURCE_DIR "/resources/image2.png'></head></html>";
+ QUrl urlFrom("data:text/html," + html.arg("TitleFrom"));
+ QUrl urlTo("data:text/html," + html.arg("TitleTo"));
+ QUrl nullPage("data:text/html,<html/>");
+ QTest::addColumn<QUrl>("urlFrom");
+ QTest::addColumn<QUrl>("urlTo");
+ QTest::addColumn<bool>("fromIsNullPage");
+ QTest::addColumn<bool>("toIsNullPage");
+ QTest::newRow("From empty page to url") << nullPage << urlTo << true << false;
+ QTest::newRow("From url to empty content page") << urlFrom << nullPage << false << true;
+ QTest::newRow("From one content to another") << urlFrom << urlTo << false << false;
+}
+
+void tst_QWebEngineView::changePage()
+{
+ QScopedPointer<QWebEngineView> view(new QWebEngineView); view->resize(640, 480); view->show();
+
+ QFETCH(QUrl, urlFrom);
+ QFETCH(QUrl, urlTo);
+ QFETCH(bool, fromIsNullPage);
+ QFETCH(bool, toIsNullPage);
+
+ QSignalSpy spyUrl(view.get(), &QWebEngineView::urlChanged);
+ QSignalSpy spyTitle(view.get(), &QWebEngineView::titleChanged);
+ QSignalSpy spyIconUrl(view.get(), &QWebEngineView::iconUrlChanged);
+ QSignalSpy spyIcon(view.get(), &QWebEngineView::iconChanged);
+
+ QScopedPointer<QWebEnginePage> pageFrom(new QWebEnginePage);
+ QSignalSpy pageFromLoadSpy(pageFrom.get(), &QWebEnginePage::loadFinished);
+ QSignalSpy pageFromIconLoadSpy(pageFrom.get(), &QWebEnginePage::iconChanged);
+ pageFrom->load(urlFrom);
+ QTRY_COMPARE(pageFromLoadSpy.count(), 1);
+ QCOMPARE(pageFromLoadSpy.last().value(0).toBool(), true);
+ if (!fromIsNullPage) {
+ QTRY_COMPARE(pageFromIconLoadSpy.count(), 1);
+ QVERIFY(!pageFromIconLoadSpy.last().value(0).isNull());
+ }
+
+ view->setPage(pageFrom.get());
+
+ QTRY_COMPARE(spyUrl.count(), 1);
+ QCOMPARE(spyUrl.last().value(0).toUrl(), pageFrom->url());
+ QTRY_COMPARE(spyTitle.count(), 1);
+ QCOMPARE(spyTitle.last().value(0).toString(), pageFrom->title());
+
+ QTRY_COMPARE(spyIconUrl.count(), fromIsNullPage ? 0 : 1);
+ QTRY_COMPARE(spyIcon.count(), fromIsNullPage ? 0 : 1);
+ if (!fromIsNullPage) {
+ QVERIFY(!pageFrom->iconUrl().isEmpty());
+ QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageFrom->iconUrl());
+ QCOMPARE(spyIcon.last().value(0), QVariant::fromValue(pageFrom->icon()));
+ }
+
+ QScopedPointer<QWebEnginePage> pageTo(new QWebEnginePage);
+ QSignalSpy pageToLoadSpy(pageTo.get(), &QWebEnginePage::loadFinished);
+ QSignalSpy pageToIconLoadSpy(pageTo.get(), &QWebEnginePage::iconChanged);
+ pageTo->load(urlTo);
+ QTRY_COMPARE(pageToLoadSpy.count(), 1);
+ QCOMPARE(pageToLoadSpy.last().value(0).toBool(), true);
+ if (!toIsNullPage) {
+ QTRY_COMPARE(pageToIconLoadSpy.count(), 1);
+ QVERIFY(!pageToIconLoadSpy.last().value(0).isNull());
+ }
+
+ view->setPage(pageTo.get());
+
+ QTRY_COMPARE(spyUrl.count(), 2);
+ QCOMPARE(spyUrl.last().value(0).toUrl(), pageTo->url());
+ QTRY_COMPARE(spyTitle.count(), 2);
+ QCOMPARE(spyTitle.last().value(0).toString(), pageTo->title());
+
+ bool iconIsSame = fromIsNullPage == toIsNullPage;
+ int iconChangeNotifyCount = fromIsNullPage ? (iconIsSame ? 0 : 1) : (iconIsSame ? 1 : 2);
+
+ QTRY_COMPARE(spyIconUrl.count(), iconChangeNotifyCount);
+ QTRY_COMPARE(spyIcon.count(), iconChangeNotifyCount);
+ QCOMPARE(pageFrom->iconUrl() == pageTo->iconUrl(), iconIsSame);
+ if (!iconIsSame) {
+ QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageTo->iconUrl());
+ QCOMPARE(spyIcon.last().value(0), QVariant::fromValue(pageTo->icon()));
+ }
+
+ // verify no emits on destroy with the same number of signals in spy
+ view.reset();
+ qApp->processEvents();
+ QTRY_COMPARE(spyUrl.count(), 2);
+ QTRY_COMPARE(spyTitle.count(), 2);
+ QTRY_COMPARE(spyIconUrl.count(), iconChangeNotifyCount);
+ QTRY_COMPARE(spyIcon.count(), iconChangeNotifyCount);
+}
+
void tst_QWebEngineView::reusePage_data()
{
QTest::addColumn<QString>("html");