summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-03-04 13:46:30 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2019-03-04 13:46:30 +0000
commit24eb36abbf1420e56238229645e1a5e36b3de145 (patch)
tree930107d884614204f6100bee0317a94b79491ddd
parent4d7c8f3455be2d275dca7e1ecd63fed175b0f3e1 (diff)
parent2b3f5b66af4f06a57216575a44f54c1d20fb12a0 (diff)
Merge "Merge remote-tracking branch 'origin/5.12' into 5.13" into refs/staging/5.13
-rw-r--r--dist/changes-5.12.273
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml15
-rw-r--r--src/core/api/core_api.pro2
-rw-r--r--src/core/api/qwebenginecookiestore.cpp2
-rw-r--r--src/core/api/qwebenginemessagepumpscheduler.cpp72
-rw-r--r--src/core/api/qwebenginemessagepumpscheduler_p.h80
-rw-r--r--src/core/api/qwebengineurlschemehandler.cpp2
-rw-r--r--src/core/browser_accessibility_manager_qt.cpp6
-rw-r--r--src/core/browser_accessibility_manager_qt.h3
-rw-r--r--src/core/browser_accessibility_qt.cpp3
-rw-r--r--src/core/browser_main_parts_qt.cpp48
-rw-r--r--src/core/favicon_manager.cpp20
-rw-r--r--src/core/favicon_manager.h15
-rw-r--r--src/core/profile_adapter.cpp17
-rw-r--r--src/core/profile_adapter.h5
-rw-r--r--src/core/profile_adapter_client.h2
-rw-r--r--src/core/type_conversion.cpp2
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/core/web_engine_settings.cpp34
-rw-r--r--src/core/web_engine_settings.h5
-rw-r--r--src/webengine/api/qquickwebenginedialogrequests.cpp6
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem.cpp26
-rw-r--r--src/webengine/api/qquickwebenginedownloaditem_p_p.h1
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp45
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h9
-rw-r--r--src/webengine/api/qquickwebengineview.cpp4
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h2
-rw-r--r--src/webengine/doc/src/qtwebengine-examples.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc16
-rw-r--r--src/webengine/doc/src/qtwebengine-qmlmodule.qdoc2
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem.cpp23
-rw-r--r--src/webenginewidgets/api/qwebenginedownloaditem_p.h4
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp34
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h1
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp40
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h5
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp2
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc2
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc20
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc14
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp46
-rw-r--r--tests/auto/quick/qmltests/data/tst_favicon.qml33
-rw-r--r--tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp38
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp32
44 files changed, 633 insertions, 181 deletions
diff --git a/dist/changes-5.12.2 b/dist/changes-5.12.2
new file mode 100644
index 00000000..ad427ecc
--- /dev/null
+++ b/dist/changes-5.12.2
@@ -0,0 +1,73 @@
+Qt 5.12.2 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.12.0 through 5.12.1.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Qt 5.12.2 Changes *
+****************************************************************************
+
+Behavior Changes
+----------------
+
+ - Deleting a download item will now also cancel the download if it is
+ still in progress.
+
+
+Chromium
+--------
+
+ - Security fixes from Chromium up to version 72.0.3626.96, including:
+ * CVE-2019-5754
+ * CVE-2019-5755
+ * CVE-2019-5756
+ * CVE-2019-5757
+ * CVE-2019-5758
+ * CVE-2019-5759
+ * CVE-2019-5760
+ * CVE-2019-5762
+ * CVE-2019-5763
+ * CVE-2019-5764
+ * CVE-2019-5769
+ * CVE-2019-5770
+ * CVE-2019-5775
+ * CVE-2019-5776
+ * CVE-2019-5777
+ * CVE-2019-5779
+ * CVE-2019-5781
+ * CVE-2019-5782
+ * CVE-2019-5783
+ * CVE-2019-5784
+ * Security issue 895117
+ * Security issue 895970
+ * Security issue 899689
+ * Security issue 901677
+ * Security issue 903500
+ * Security issue 907047
+ * Security issue 908358
+ * Security issue 911253
+ * Security issue 912508
+ * Security issue 912520
+ * Security issue 922677
+
+General
+-------
+
+ - [QTBUG-72021] Improved tooltip wrapping to match other browsers.
+ - [QTBUG-72714] Fixed clipboard API not being permitted when settings allowed it.
+ - [QTBUG-73839] Fixed minor memory leak per download.
+ - Fixed regression in certificate transparency checking.
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index 94e7ac37..d3d597e2 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -387,11 +387,12 @@ ApplicationWindow {
focus: true
onLinkHovered: function(hoveredUrl) {
- if (hoveredUrl === "")
- resetStatusText.start();
+ if (hoveredUrl == "")
+ hideStatusText.start();
else {
- resetStatusText.stop();
statusText.text = hoveredUrl;
+ statusBubble.visible = true;
+ hideStatusText.stop();
}
}
@@ -578,6 +579,7 @@ ApplicationWindow {
id: statusBubble
color: "oldlace"
property int padding: 8
+ visible: false
anchors.left: parent.left
anchors.bottom: parent.bottom
@@ -590,9 +592,12 @@ ApplicationWindow {
elide: Qt.ElideMiddle
Timer {
- id: resetStatusText
+ id: hideStatusText
interval: 750
- onTriggered: statusText.text = ""
+ onTriggered: {
+ statusText.text = "";
+ statusBubble.visible = false;
+ }
}
}
}
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 4d3ddcc8..326d4481 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -38,6 +38,7 @@ HEADERS = \
qwebenginecookiestore.h \
qwebenginecookiestore_p.h \
qwebenginehttprequest.h \
+ qwebenginemessagepumpscheduler_p.h \
qwebenginenotification.h \
qwebenginequotarequest.h \
qwebengineregisterprotocolhandlerrequest.h \
@@ -53,6 +54,7 @@ SOURCES = \
qwebengineclientcertificatestore.cpp \
qwebenginecookiestore.cpp \
qwebenginehttprequest.cpp \
+ qwebenginemessagepumpscheduler.cpp \
qwebenginenotification.cpp \
qwebenginequotarequest.cpp \
qwebengineregisterprotocolhandlerrequest.cpp \
diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp
index 035c9834..3897fb12 100644
--- a/src/core/api/qwebenginecookiestore.cpp
+++ b/src/core/api/qwebenginecookiestore.cpp
@@ -382,7 +382,7 @@ void QWebEngineCookieStore::setCookieFilter(std::function<bool(const FilterReque
\inmodule QtWebEngineCore
\since 5.11
- \brief This struct is used in conjunction with QWebEngineCookieStore::setCookieFilter() and is
+ \brief The QWebEngineCookieStore::FilterRequest struct is used in conjunction with QWebEngineCookieStore::setCookieFilter() and is
the type \a filterCallback operates on.
\sa QWebEngineCookieStore::setCookieFilter()
diff --git a/src/core/api/qwebenginemessagepumpscheduler.cpp b/src/core/api/qwebenginemessagepumpscheduler.cpp
new file mode 100644
index 00000000..34cbc49b
--- /dev/null
+++ b/src/core/api/qwebenginemessagepumpscheduler.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginemessagepumpscheduler_p.h"
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QTimerEvent>
+
+QWebEngineMessagePumpScheduler::QWebEngineMessagePumpScheduler(std::function<void()> callback)
+ : m_callback(std::move(callback))
+{}
+
+void QWebEngineMessagePumpScheduler::scheduleWork()
+{
+ QCoreApplication::postEvent(this, new QTimerEvent(0));
+}
+
+void QWebEngineMessagePumpScheduler::scheduleDelayedWork(int delay)
+{
+ if (delay < 0) {
+ killTimer(m_timerId);
+ m_timerId = 0;
+ } else if (!m_timerId || delay < QAbstractEventDispatcher::instance()->remainingTime(m_timerId)) {
+ killTimer(m_timerId);
+ m_timerId = startTimer(delay);
+ }
+}
+
+void QWebEngineMessagePumpScheduler::timerEvent(QTimerEvent *ev)
+{
+ Q_ASSERT(!ev->timerId() || m_timerId == ev->timerId());
+ killTimer(m_timerId);
+ m_timerId = 0;
+ m_callback();
+}
diff --git a/src/core/api/qwebenginemessagepumpscheduler_p.h b/src/core/api/qwebenginemessagepumpscheduler_p.h
new file mode 100644
index 00000000..4c9e4d60
--- /dev/null
+++ b/src/core/api/qwebenginemessagepumpscheduler_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINEMESSAGEPUMPSCHEDULER_P_H
+#define QWEBENGINEMESSAGEPUMPSCHEDULER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtwebenginecoreglobal_p.h"
+
+#include <QtCore/qobject.h>
+
+#include <functional>
+
+QT_BEGIN_NAMESPACE
+
+class QWEBENGINECORE_PRIVATE_EXPORT QWebEngineMessagePumpScheduler : public QObject
+{
+ Q_OBJECT
+public:
+ QWebEngineMessagePumpScheduler(std::function<void()> callback);
+ void scheduleWork();
+ void scheduleDelayedWork(int delay);
+
+protected:
+ void timerEvent(QTimerEvent *ev) override;
+
+private:
+ int m_timerId = 0;
+ std::function<void()> m_callback;
+};
+
+QT_END_NAMESPACE
+
+#endif // !QWEBENGINEMESSAGEPUMPSCHEDULER_P_H
diff --git a/src/core/api/qwebengineurlschemehandler.cpp b/src/core/api/qwebengineurlschemehandler.cpp
index 2e93f4b7..aecee504 100644
--- a/src/core/api/qwebengineurlschemehandler.cpp
+++ b/src/core/api/qwebengineurlschemehandler.cpp
@@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
\class QWebEngineUrlSchemeHandler
- \brief The QWebEngineUrlSchemeHandler is a base class for handling custom URL schemes.
+ \brief The QWebEngineUrlSchemeHandler class is a base class for handling custom URL schemes.
\since 5.6
To implement a custom URL scheme for QtWebEngine, you first have to create an instance of
diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp
index 644a0a9f..7fb1386c 100644
--- a/src/core/browser_accessibility_manager_qt.cpp
+++ b/src/core/browser_accessibility_manager_qt.cpp
@@ -76,6 +76,12 @@ BrowserAccessibilityManagerQt::BrowserAccessibilityManagerQt(
, m_parentObject(parentObject)
{
Initialize(initialTree);
+ m_valid = true; // BrowserAccessibilityQt can start using the AXTree
+}
+
+BrowserAccessibilityManagerQt::~BrowserAccessibilityManagerQt()
+{
+ m_valid = false; // BrowserAccessibilityQt should stop using the AXTree
}
QAccessibleInterface *BrowserAccessibilityManagerQt::rootParentAccessible()
diff --git a/src/core/browser_accessibility_manager_qt.h b/src/core/browser_accessibility_manager_qt.h
index a2d6db45..87c8875b 100644
--- a/src/core/browser_accessibility_manager_qt.h
+++ b/src/core/browser_accessibility_manager_qt.h
@@ -57,14 +57,17 @@ public:
const ui::AXTreeUpdate& initialTree,
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
+ ~BrowserAccessibilityManagerQt() override;
void FireBlinkEvent(ax::mojom::Event event_type,
BrowserAccessibility* node) override;
QAccessibleInterface *rootParentAccessible();
+ bool isValid() const { return m_valid; }
private:
Q_DISABLE_COPY(BrowserAccessibilityManagerQt)
QObject *m_parentObject;
+ bool m_valid = false;
};
}
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index c906071f..75527ea9 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -73,7 +73,8 @@ BrowserAccessibilityQt::BrowserAccessibilityQt()
bool BrowserAccessibilityQt::isValid() const
{
- return true;
+ auto managerQt = static_cast<BrowserAccessibilityManagerQt *>(manager_);
+ return managerQt && managerQt->isValid();
}
QObject *BrowserAccessibilityQt::object() const
diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp
index e6c76fb4..4dbff086 100644
--- a/src/core/browser_main_parts_qt.cpp
+++ b/src/core/browser_main_parts_qt.cpp
@@ -39,6 +39,8 @@
#include "browser_main_parts_qt.h"
+#include "api/qwebenginemessagepumpscheduler_p.h"
+
#include "base/message_loop/message_loop.h"
#include "base/process/process.h"
#include "base/threading/thread_restrictions.h"
@@ -63,11 +65,7 @@
#include "service/service_qt.h"
#include "web_engine_context.h"
-#include <QCoreApplication>
-#include <QEvent>
#include <QEventLoop>
-#include <QObject>
-#include <QTimerEvent>
#include <QtGui/qtgui-config.h>
#if QT_CONFIG(opengl)
@@ -106,16 +104,12 @@ int GetTimeIntervalMilliseconds(const base::TimeTicks &from)
return delay < 0 ? 0 : delay;
}
-class MessagePumpForUIQt : public QObject,
- public base::MessagePump
+class MessagePumpForUIQt : public base::MessagePump
{
public:
MessagePumpForUIQt()
- : m_delegate(nullptr)
- , m_explicitLoop(nullptr)
- , m_timerId(0)
- {
- }
+ : m_scheduler([this]() { handleScheduledWork(); })
+ {}
void Run(Delegate *delegate) override
{
@@ -138,36 +132,17 @@ public:
void ScheduleWork() override
{
+ // NOTE: This method may called from any thread at any time.
if (!m_delegate)
m_delegate = base::MessageLoopForUI::current();
- QCoreApplication::postEvent(this, new QTimerEvent(0));
- m_timerScheduledTime = base::TimeTicks::Now();
+ m_scheduler.scheduleWork();
}
void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override
{
if (!m_delegate)
m_delegate = base::MessageLoopForUI::current();
- if (delayed_work_time.is_null()) {
- killTimer(m_timerId);
- m_timerId = 0;
- m_timerScheduledTime = base::TimeTicks();
- } else if (!m_timerId || delayed_work_time < m_timerScheduledTime) {
- killTimer(m_timerId);
- m_timerId = startTimer(GetTimeIntervalMilliseconds(delayed_work_time));
- m_timerScheduledTime = delayed_work_time;
- }
- }
-
-protected:
- void timerEvent(QTimerEvent *ev) override
- {
- Q_ASSERT(!ev->timerId() || m_timerId == ev->timerId());
- killTimer(m_timerId);
- m_timerId = 0;
- m_timerScheduledTime = base::TimeTicks();
-
- handleScheduledWork();
+ m_scheduler.scheduleDelayedWork(GetTimeIntervalMilliseconds(delayed_work_time));
}
private:
@@ -235,10 +210,9 @@ private:
ScheduleDelayedWork(delayed_work_time);
}
- Delegate *m_delegate;
- QEventLoop *m_explicitLoop;
- int m_timerId;
- base::TimeTicks m_timerScheduledTime;
+ Delegate *m_delegate = nullptr;
+ QEventLoop *m_explicitLoop = nullptr;
+ QWebEngineMessagePumpScheduler m_scheduler;
};
} // anonymous namespace
diff --git a/src/core/favicon_manager.cpp b/src/core/favicon_manager.cpp
index de6a0f18..f7ba858c 100644
--- a/src/core/favicon_manager.cpp
+++ b/src/core/favicon_manager.cpp
@@ -253,7 +253,7 @@ void FaviconManager::update(const QList<FaviconInfo> &candidates)
const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
- if (!touchIconsEnabled && it->type != FaviconInfo::Favicon)
+ if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon))
continue;
if (it->isValid())
@@ -272,6 +272,14 @@ void FaviconManager::update(const QList<FaviconInfo> &candidates)
void FaviconManager::updateCandidates(const QList<FaviconInfo> &candidates)
{
+ // Invalidate types of the already stored candidate icons because it might differ
+ // among pages.
+ for (FaviconInfo candidateFaviconInfo : candidates) {
+ const QUrl &candidateUrl = candidateFaviconInfo.url;
+ if (m_faviconInfoMap.contains(candidateUrl))
+ m_faviconInfoMap[candidateUrl].type = FaviconInfo::InvalidIcon;
+ }
+
m_candidateCount = candidates.count();
for (FaviconInfo candidateFaviconInfo : candidates) {
const QUrl &candidateUrl = candidateFaviconInfo.url;
@@ -279,8 +287,8 @@ void FaviconManager::updateCandidates(const QList<FaviconInfo> &candidates)
if (!m_faviconInfoMap.contains(candidateUrl))
m_faviconInfoMap.insert(candidateUrl, candidateFaviconInfo);
else {
- // The same icon can be used for more than one page with different types.
- m_faviconInfoMap[candidateUrl].type = candidateFaviconInfo.type;
+ // The same icon URL can be used for different types.
+ m_faviconInfoMap[candidateUrl].type |= candidateFaviconInfo.type;
}
m_faviconInfoMap[candidateUrl].candidate = true;
@@ -311,7 +319,7 @@ QUrl FaviconManager::candidateIconUrl(bool touchIconsEnabled) const
unsigned bestArea = 0;
for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
- if (!touchIconsEnabled && it->type != FaviconInfo::Favicon)
+ if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon))
continue;
if (it->isValid() && bestArea < area(it->size)) {
@@ -331,7 +339,7 @@ void FaviconManager::generateCandidateIcon(bool touchIconsEnabled)
const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
- if (!touchIconsEnabled && it->type != FaviconInfo::Favicon)
+ if (!touchIconsEnabled && !(it->type & FaviconInfo::Favicon))
continue;
if (!it->isValid() || !it->isDownloaded())
@@ -373,7 +381,7 @@ FaviconInfo::FaviconInfo(const FaviconInfo &other)
{
}
-FaviconInfo::FaviconInfo(const QUrl &url, FaviconInfo::FaviconType type)
+FaviconInfo::FaviconInfo(const QUrl &url, FaviconInfo::FaviconTypeFlags type)
: url(url)
, type(type)
, size(QSize(0, 0))
diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h
index f9758d0f..60d194c4 100644
--- a/src/core/favicon_manager.h
+++ b/src/core/favicon_manager.h
@@ -84,23 +84,24 @@ class WebContentsAdapterClient;
// Based on src/3rdparty/chromium/content/public/common/favicon_url.h
class QWEBENGINECORE_PRIVATE_EXPORT FaviconInfo {
public:
- enum FaviconType {
- InvalidIcon,
- Favicon,
- TouchIcon,
- TouchPrecomposedIcon
+ enum FaviconTypeFlag {
+ InvalidIcon = 0,
+ Favicon = 1 << 0,
+ TouchIcon = 1 << 1,
+ TouchPrecomposedIcon = 1 << 2
};
+ Q_DECLARE_FLAGS(FaviconTypeFlags, FaviconTypeFlag);
FaviconInfo();
FaviconInfo(const FaviconInfo &);
- FaviconInfo(const QUrl &, FaviconInfo::FaviconType);
+ FaviconInfo(const QUrl &, FaviconInfo::FaviconTypeFlags);
~FaviconInfo();
bool isValid() const;
bool isDownloaded() const;
QUrl url;
- FaviconType type;
+ FaviconTypeFlags type;
// Stores the largest size in case of multi-size icon
QSize size;
bool candidate;
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 4625d238..7070292d 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -55,6 +55,7 @@
#include "type_conversion.h"
#include "visited_links_manager_qt.h"
#include "web_engine_context.h"
+#include "web_contents_adapter_client.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
@@ -105,6 +106,9 @@ ProfileAdapter::ProfileAdapter(const QString &storageName):
ProfileAdapter::~ProfileAdapter()
{
+ while (!m_webContentsAdapterClients.isEmpty()) {
+ m_webContentsAdapterClients.first()->releaseProfile();
+ }
WebEngineContext::current()->removeProfileAdapter(this);
if (m_downloadManagerDelegate) {
m_profile->GetDownloadManager(m_profile.data())->Shutdown();
@@ -231,7 +235,8 @@ ProfileAdapter *ProfileAdapter::createDefaultProfileAdapter()
ProfileAdapter *ProfileAdapter::defaultProfileAdapter()
{
- return WebEngineContext::current()->defaultProfileAdapter();
+ WebEngineContext *context = WebEngineContext::current();
+ return context ? context->defaultProfileAdapter() : nullptr;
}
QObject* ProfileAdapter::globalQObjectRoot()
@@ -618,6 +623,16 @@ bool ProfileAdapter::isSpellCheckEnabled() const
#endif
}
+void ProfileAdapter::addWebContentsAdapterClient(WebContentsAdapterClient *client)
+{
+ m_webContentsAdapterClients.append(client);
+}
+
+void ProfileAdapter::removeWebContentsAdapterClient(WebContentsAdapterClient *client)
+{
+ m_webContentsAdapterClients.removeAll(client);
+}
+
void ProfileAdapter::resetVisitedLinksManager()
{
m_visitedLinksManager.reset(new VisitedLinksManagerQt(m_profile.data(), persistVisitedLinks()));
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 480ca61f..1aff145b 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -76,6 +76,7 @@ class ProfileAdapterClient;
class ProfileQt;
class UserResourceControllerHost;
class VisitedLinksManagerQt;
+class WebContentsAdapterClient;
class QWEBENGINECORE_PRIVATE_EXPORT ProfileAdapter : public QObject
{
@@ -133,6 +134,9 @@ public:
void setSpellCheckEnabled(bool enabled);
bool isSpellCheckEnabled() const;
+ void addWebContentsAdapterClient(WebContentsAdapterClient *client);
+ void removeWebContentsAdapterClient(WebContentsAdapterClient *client);
+
// KEEP IN SYNC with API or add mapping layer
enum HttpCacheType {
MemoryHttpCache = 0,
@@ -237,6 +241,7 @@ private:
QHash<QByteArray, QSharedPointer<UserNotificationController>> m_persistentNotifications;
QList<ProfileAdapterClient*> m_clients;
+ QVector<WebContentsAdapterClient *> m_webContentsAdapterClients;
int m_httpCacheMaxSize;
int m_pageRequestInterceptors;
QrcUrlSchemeHandler m_qrcHandler;
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index 0309200b..8ee9d240 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -147,6 +147,8 @@ public:
virtual void useForGlobalCertificateVerificationChanged() {}
virtual void showNotification(QSharedPointer<UserNotificationController> &) { }
+ virtual void addWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
+ virtual void removeWebContentsAdapterClient(WebContentsAdapterClient *adapter) = 0;
static QString downloadInterruptReasonToString(DownloadInterruptReason reason);
};
diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp
index ef16e2ad..02d2db44 100644
--- a/src/core/type_conversion.cpp
+++ b/src/core/type_conversion.cpp
@@ -218,7 +218,7 @@ int flagsFromModifiers(Qt::KeyboardModifiers modifiers)
return modifierFlags;
}
-FaviconInfo::FaviconType toQt(content::FaviconURL::IconType type)
+FaviconInfo::FaviconTypeFlags toQt(content::FaviconURL::IconType type)
{
switch (type) {
case content::FaviconURL::IconType::kFavicon:
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index d155ed39..cdfcae45 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -485,6 +485,7 @@ public:
virtual ProfileAdapter *profileAdapter() = 0;
virtual WebContentsAdapter* webContentsAdapter() = 0;
+ virtual void releaseProfile() = 0;
};
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index a652469c..705c0c10 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -67,27 +67,6 @@ QHash<WebEngineSettings::FontSize, int> WebEngineSettings::s_defaultFontSizes;
static const int batchTimerTimeout = 0;
-class BatchTimer : public QTimer {
- Q_OBJECT
-public:
- BatchTimer(WebEngineSettings *settings)
- : m_settings(settings)
- {
- setSingleShot(true);
- setInterval(batchTimerTimeout);
- connect(this, SIGNAL(timeout()), SLOT(onTimeout()));
- }
-
-private Q_SLOTS:
- void onTimeout()
- {
- m_settings->doApply();
- }
-
-private:
- WebEngineSettings *m_settings;
-};
-
static inline bool isTouchEventsAPIEnabled() {
static bool initialized = false;
static bool touchEventsAPIEnabled = false;
@@ -113,12 +92,17 @@ static inline bool isTouchEventsAPIEnabled() {
WebEngineSettings::WebEngineSettings(WebEngineSettings *_parentSettings)
: m_adapter(0)
- , m_batchTimer(new BatchTimer(this))
, parentSettings(_parentSettings)
, m_unknownUrlSchemePolicy(WebEngineSettings::InheritedUnknownUrlSchemePolicy)
{
if (parentSettings)
parentSettings->childSettings.insert(this);
+
+ m_batchTimer.setSingleShot(true);
+ m_batchTimer.setInterval(batchTimerTimeout);
+ QObject::connect(&m_batchTimer, &QTimer::timeout, [this]() {
+ doApply();
+ });
}
WebEngineSettings::~WebEngineSettings()
@@ -340,8 +324,8 @@ void WebEngineSettings::initDefaults()
void WebEngineSettings::scheduleApply()
{
- if (!m_batchTimer->isActive())
- m_batchTimer->start();
+ if (!m_batchTimer.isActive())
+ m_batchTimer.start();
}
void WebEngineSettings::doApply()
@@ -453,5 +437,3 @@ void WebEngineSettings::setParentSettings(WebEngineSettings *_parentSettings)
}
} // namespace QtWebEngineCore
-
-#include "web_engine_settings.moc"
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index 8ed72752..8e1bb741 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -57,6 +57,7 @@
#include <QHash>
#include <QUrl>
#include <QSet>
+#include <QTimer>
namespace content {
struct RendererPreferences;
@@ -65,7 +66,6 @@ struct WebPreferences;
}
namespace QtWebEngineCore {
-class BatchTimer;
class WebContentsAdapter;
class QWEBENGINECORE_PRIVATE_EXPORT WebEngineSettings {
@@ -178,7 +178,7 @@ private:
QHash<FontSize, int> m_fontSizes;
QString m_defaultEncoding;
QScopedPointer<content::WebPreferences> webPreferences;
- QScopedPointer<BatchTimer> m_batchTimer;
+ QTimer m_batchTimer;
WebEngineSettings *parentSettings;
QSet<WebEngineSettings *> childSettings;
@@ -188,7 +188,6 @@ private:
static QHash<FontSize, int> s_defaultFontSizes;
UnknownUrlSchemePolicy m_unknownUrlSchemePolicy;
- friend class BatchTimer;
friend class WebContentsAdapter;
};
diff --git a/src/webengine/api/qquickwebenginedialogrequests.cpp b/src/webengine/api/qquickwebenginedialogrequests.cpp
index b1f52a6b..d6bba9a9 100644
--- a/src/webengine/api/qquickwebenginedialogrequests.cpp
+++ b/src/webengine/api/qquickwebenginedialogrequests.cpp
@@ -340,8 +340,8 @@ QString QQuickWebEngineJavaScriptDialogRequest::title() const
\qmlproperty enumeration JavaScriptDialogRequest::type
\readonly
- Returns the type of the requested dialog box, see HTML5's
-
+ Returns the type of the requested dialog box. For more information, see
+ HTML5's
\l{https://www.w3.org/TR/html5/webappapis.html#simple-dialogs}{Simple Dialogs}.
\value JavaScriptDialogRequest.DialogTypeAlert
@@ -350,7 +350,7 @@ QString QQuickWebEngineJavaScriptDialogRequest::title() const
A JavaScript confirmation dialog.
\value JavaScriptDialogRequest.DialogTypePrompt
A JavaScript prompt dialog.
- \value JavaScriptDialogRequest.DialogTypeUnload
+ \value JavaScriptDialogRequest.DialogTypeBeforeUnload
The users should be asked if they want to leave the page.
*/
diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp
index a80f163d..981d1163 100644
--- a/src/webengine/api/qquickwebenginedownloaditem.cpp
+++ b/src/webengine/api/qquickwebenginedownloaditem.cpp
@@ -185,10 +185,8 @@ void QQuickWebEngineDownloadItemPrivate::update(const ProfileAdapterClient::Down
Q_EMIT q->totalBytesChanged();
}
- if (info.done != downloadFinished) {
- downloadFinished = info.done;
- Q_EMIT q->isFinishedChanged();
- }
+ if (info.done)
+ setFinished();
if (info.paused != downloadPaused) {
downloadPaused = info.paused;
@@ -206,6 +204,17 @@ void QQuickWebEngineDownloadItemPrivate::updateState(QQuickWebEngineDownloadItem
}
}
+void QQuickWebEngineDownloadItemPrivate::setFinished()
+{
+ Q_Q(QQuickWebEngineDownloadItem);
+
+ if (downloadFinished)
+ return;
+
+ downloadFinished = true;
+ Q_EMIT q->isFinishedChanged();
+}
+
/*!
\qmlmethod void WebEngineDownloadItem::accept()
@@ -255,6 +264,7 @@ void QQuickWebEngineDownloadItem::cancel()
return;
d->updateState(QQuickWebEngineDownloadItem::DownloadCancelled);
+ d->setFinished();
// We directly cancel the download if the user cancels before
// it even started, so no need to notify the profile here.
@@ -593,12 +603,14 @@ bool QQuickWebEngineDownloadItem::isPaused() const
}
/*!
- \qmlproperty bool WebEngineDownloadItem::view
+ \qmlproperty WebEngineView WebEngineDownloadItem::view
\readonly
\since QtWebEngine 1.8
Returns the view the download was requested on. If the download was not triggered by content in a view,
\c nullptr is returned.
+
+ \sa WebEngineView
*/
QQuickWebEngineView *QQuickWebEngineDownloadItem::view() const
{
@@ -615,8 +627,8 @@ QQuickWebEngineDownloadItem::QQuickWebEngineDownloadItem(QQuickWebEngineDownload
QQuickWebEngineDownloadItem::~QQuickWebEngineDownloadItem()
{
- if (d_ptr->profile)
- d_ptr->profile->d_ptr->profileAdapter()->removeDownload(d_ptr->downloadId);
+ if (!isFinished())
+ cancel();
}
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
index 4b89335b..f444c04a 100644
--- a/src/webengine/api/qquickwebenginedownloaditem_p_p.h
+++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h
@@ -85,6 +85,7 @@ public:
void update(const QtWebEngineCore::ProfileAdapterClient::DownloadItemInfo &info);
void updateState(QQuickWebEngineDownloadItem::DownloadState newState);
+ void setFinished();
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 0ec4b19c..3c4ec059 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -171,11 +171,6 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *pro
QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
{
-
- while (!m_webContentsAdapterClients.isEmpty()) {
- m_webContentsAdapterClients.first()->destroy();
- }
-
if (m_profileAdapter) {
// In the case the user sets this profile as the parent of the interceptor
// it can be deleted before the browser-context still referencing it is.
@@ -183,25 +178,20 @@ QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
m_profileAdapter->removeClient(this);
}
- for (QQuickWebEngineDownloadItem *download : qAsConst(m_ongoingDownloads)) {
- if (download)
- download->cancel();
- }
-
- m_ongoingDownloads.clear();
-
if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter())
delete m_profileAdapter;
}
-void QQuickWebEngineProfilePrivate::addWebContentsAdapterClient(QQuickWebEngineViewPrivate *adapter)
+void QQuickWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
{
- m_webContentsAdapterClients.append(adapter);
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->addWebContentsAdapterClient(adapter);
}
-void QQuickWebEngineProfilePrivate::removeWebContentsAdapterClient(QQuickWebEngineViewPrivate*adapter)
+void QQuickWebEngineProfilePrivate::removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient*adapter)
{
- m_webContentsAdapterClients.removeAll(adapter);
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->removeWebContentsAdapterClient(adapter);
}
QtWebEngineCore::ProfileAdapter *QQuickWebEngineProfilePrivate::profileAdapter() const
@@ -223,6 +213,23 @@ void QQuickWebEngineProfilePrivate::cancelDownload(quint32 downloadId)
void QQuickWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId)
{
m_ongoingDownloads.remove(downloadId);
+ if (m_profileAdapter)
+ m_profileAdapter->removeDownload(downloadId);
+}
+
+void QQuickWebEngineProfilePrivate::cleanDownloads()
+{
+ for (auto download : m_ongoingDownloads.values()) {
+ if (!download)
+ continue;
+
+ if (!download->isFinished())
+ download->cancel();
+
+ if (m_profileAdapter)
+ m_profileAdapter->removeDownload(download->id());
+ }
+ m_ongoingDownloads.clear();
}
void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
@@ -247,6 +254,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
QQuickWebEngineDownloadItem *download = new QQuickWebEngineDownloadItem(itemPrivate, q);
m_ongoingDownloads.insert(info.id, download);
+ QObject::connect(download, &QQuickWebEngineDownloadItem::destroyed, q, [id = info.id, this] () { downloadDestroyed(id); });
QQmlEngine::setObjectOwnership(download, QQmlEngine::JavaScriptOwnership);
Q_EMIT q->downloadRequested(download);
@@ -260,7 +268,6 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
if (state == QQuickWebEngineDownloadItem::DownloadRequested) {
// Delete unaccepted downloads.
info.accepted = false;
- m_ongoingDownloads.remove(info.id);
delete download;
}
}
@@ -283,7 +290,6 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info
if (info.state != ProfileAdapterClient::DownloadInProgress) {
Q_EMIT q->downloadFinished(download);
- m_ongoingDownloads.remove(info.id);
}
}
@@ -410,6 +416,7 @@ QQuickWebEngineProfile::QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *pr
*/
QQuickWebEngineProfile::~QQuickWebEngineProfile()
{
+ d_ptr->cleanDownloads();
}
/*!
@@ -1057,7 +1064,7 @@ QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
\property QQuickWebEngineProfile::userScripts
\since 5.9
- \brief the collection of scripts that are injected into all pages that share
+ \brief The collection of scripts that are injected into all pages that share
this profile.
\sa QQuickWebEngineScript, QQmlListReference
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 322ec010..c6d412ab 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -53,7 +53,7 @@
#include "profile_adapter_client.h"
#include "profile_adapter.h"
-#include "qquickwebengineprofile_p.h"
+#include "qquickwebengineprofile.h"
#include <QExplicitlySharedDataPointer>
#include <QMap>
@@ -71,8 +71,8 @@ public:
Q_DECLARE_PUBLIC(QQuickWebEngineProfile)
QQuickWebEngineProfilePrivate(QtWebEngineCore::ProfileAdapter *profileAdapter);
~QQuickWebEngineProfilePrivate();
- void addWebContentsAdapterClient(QQuickWebEngineViewPrivate *adapter);
- void removeWebContentsAdapterClient(QQuickWebEngineViewPrivate *adapter);
+ void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
+ void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
QtWebEngineCore::ProfileAdapter* profileAdapter() const;
QQuickWebEngineSettings *settings() const;
@@ -80,6 +80,8 @@ public:
void cancelDownload(quint32 downloadId);
void downloadDestroyed(quint32 downloadId);
+ void cleanDownloads();
+
void downloadRequested(DownloadItemInfo &info) override;
void downloadUpdated(const DownloadItemInfo &info) override;
@@ -100,7 +102,6 @@ private:
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
QList<QQuickWebEngineScript *> m_userScripts;
- QVector<QQuickWebEngineViewPrivate *> m_webContentsAdapterClients;
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index e7b2d8c9..3290fe44 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -190,7 +190,7 @@ bool QQuickWebEngineViewPrivate::profileInitialized() const
return m_profileInitialized;
}
-void QQuickWebEngineViewPrivate::destroy()
+void QQuickWebEngineViewPrivate::releaseProfile()
{
// The profile for this web contents is about to be
// garbage collected, delete WebContents first and
@@ -1320,7 +1320,7 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color)
/*!
\property QQuickWebEngineView::audioMuted
- \brief the state of whether the current page audio is muted.
+ \brief The state of whether the current page audio is muted.
\since 5.7
The default value is false.
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 543d7b11..e625e0cc 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -94,7 +94,7 @@ public:
QQuickWebEngineView *q_ptr;
QQuickWebEngineViewPrivate();
~QQuickWebEngineViewPrivate();
- void destroy();
+ void releaseProfile() override;
void initializeProfile();
QtWebEngineCore::UIDelegatesManager *ui();
diff --git a/src/webengine/doc/src/qtwebengine-examples.qdoc b/src/webengine/doc/src/qtwebengine-examples.qdoc
index 1f178076..24604e3d 100644
--- a/src/webengine/doc/src/qtwebengine-examples.qdoc
+++ b/src/webengine/doc/src/qtwebengine-examples.qdoc
@@ -28,7 +28,7 @@
/*!
\group webengine-examples
\title Qt WebEngine Examples
- \brief Examples demonstrating the Qt WebEngine usage
+ \brief Examples demonstrating the Qt WebEngine usage.
\ingroup all-examples
These examples and demonstrations show a range of different uses for \l{Qt WebEngine},
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index 4ac5108b..58c0708c 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -149,9 +149,19 @@
engine must be initialized by using \l QtWebEngine::initialize in the application main source
file, as illustrated by the following code snippet:
- \quotefromfile webengine/minimal/main.cpp
- \skipto main
- \printuntil }
+ \code
+ int main(int argc, char *argv[])
+ {
+ QGuiApplication app(argc, argv);
+
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl("qrc:/main.qml"));
+
+ return app.exec();
+ }
+ \endcode
An application can load pages into the WebEngineView, using either an URL or HTML string, and
navigate within session history. By default, links to different pages load within the same
diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
index 51e0613d..540d7403 100644
--- a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
+++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
@@ -28,7 +28,7 @@
/*!
\qmlmodule QtWebEngine 1.9
\title Qt WebEngine QML Types
- \brief Provides QML types for rendering web content within a QML application
+ \brief Provides QML types for rendering web content within a QML application.
\ingroup qtwebengine-modules
\ingroup qmlmodules
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index 55d4fcca..deb92bfd 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -197,11 +197,8 @@ void QWebEngineDownloadItemPrivate::update(const ProfileAdapterClient::DownloadI
Q_EMIT q->downloadProgress(receivedBytes, totalBytes);
}
- if (info.done != downloadFinished) {
- downloadFinished = info.done;
- if (downloadFinished)
- Q_EMIT q->finished();
- }
+ if (info.done)
+ setFinished();
if (downloadPaused != info.paused) {
downloadPaused = info.paused;
@@ -209,6 +206,15 @@ void QWebEngineDownloadItemPrivate::update(const ProfileAdapterClient::DownloadI
}
}
+void QWebEngineDownloadItemPrivate::setFinished()
+{
+ if (downloadFinished)
+ return;
+
+ downloadFinished = true;
+ Q_EMIT q_ptr->finished();
+}
+
/*!
Accepts the current download request, which will start the download.
@@ -262,6 +268,7 @@ void QWebEngineDownloadItem::cancel()
} else {
d->downloadState = QWebEngineDownloadItem::DownloadCancelled;
Q_EMIT stateChanged(d->downloadState);
+ d->setFinished();
}
}
@@ -653,8 +660,10 @@ QWebEngineDownloadItem::QWebEngineDownloadItem(QWebEngineDownloadItemPrivate *p,
*/
QWebEngineDownloadItem::~QWebEngineDownloadItem()
{
- if (auto profileAdapter = d_ptr->profile->profileAdapter())
- profileAdapter->removeDownload(d_ptr->downloadId);
+ // MEMO Items are owned by profile by default and will be destroyed on profile's destruction
+ // It's not safe to access profile in that case, so we rely on profile to clean up items
+ if (!isFinished())
+ cancel();
}
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem_p.h b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
index bdcda5be..b3bc8a3f 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem_p.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem_p.h
@@ -53,7 +53,7 @@
#include "qtwebenginewidgetsglobal.h"
-#include "qwebenginedownloaditem_p.h"
+#include "qwebenginedownloaditem.h"
#include "qwebengineprofile_p.h"
#include <QString>
@@ -84,6 +84,8 @@ public:
QWebEnginePage *page;
void update(const QtWebEngineCore::ProfileAdapterClient::DownloadItemInfo &info);
+
+ void setFinished();
};
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index b1e7cce4..696b6723 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -177,6 +177,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
ensureInitialized();
wasShown();
});
+
+ profile->d_ptr->addWebContentsAdapterClient(this);
}
QWebEnginePagePrivate::~QWebEnginePagePrivate()
@@ -185,6 +187,7 @@ QWebEnginePagePrivate::~QWebEnginePagePrivate()
profile->d_ptr->profileAdapter()->removePageRequestInterceptor();
delete history;
delete settings;
+ profile->d_ptr->removeWebContentsAdapterClient(this);
}
RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
@@ -479,6 +482,13 @@ void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<Authentication
controller->accept(networkAuth.user(), networkAuth.password());
}
+void QWebEnginePagePrivate::releaseProfile()
+{
+ qDebug("Release of profile requested but WebEnginePage still not deleted. Expect troubles !");
+ // this is not the way to go, but might avoid the crash if user code does not make any calls to page.
+ delete q_ptr->d_ptr.take();
+}
+
void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
{
#if QT_CONFIG(colordialog)
@@ -845,7 +855,7 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
\property QWebEnginePage::contentsSize
\since 5.7
- The size of the page contents.
+ \brief The size of the page contents.
*/
/*!
@@ -907,11 +917,13 @@ QWebEnginePage::QWebEnginePage(QWebEngineProfile *profile, QObject* parent)
QWebEnginePage::~QWebEnginePage()
{
- Q_D(QWebEnginePage);
- setDevToolsPage(nullptr);
- d->adapter->stopFinding();
- QWebEnginePagePrivate::bindPageAndView(this, nullptr);
- QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
+ if (d_ptr) {
+ // d_ptr might be exceptionally null if profile adapter got deleted first
+ setDevToolsPage(nullptr);
+ d_ptr->adapter->stopFinding();
+ QWebEnginePagePrivate::bindPageAndView(this, nullptr);
+ QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
+ }
}
QWebEngineHistory *QWebEnginePage::history() const
@@ -994,7 +1006,7 @@ void QWebEnginePage::setWebChannel(QWebChannel *channel, uint worldId)
/*!
\property QWebEnginePage::backgroundColor
- \brief the page's background color behind the document's body.
+ \brief The page's background color behind the document's body.
\since 5.6
You can set the background color to Qt::transparent or to a translucent
@@ -1045,7 +1057,7 @@ void QWebEnginePage::save(const QString &filePath,
/*!
\property QWebEnginePage::audioMuted
- \brief whether the current page audio is muted.
+ \brief Whether the current page audio is muted.
\since 5.7
The default value is \c false.
@@ -1067,7 +1079,7 @@ void QWebEnginePage::setAudioMuted(bool muted) {
/*!
\property QWebEnginePage::recentlyAudible
- \brief the current page's \e {audible state}, that is, whether audio was recently played
+ \brief The current page's \e {audible state}, that is, whether audio was recently played
or not.
\since 5.7
@@ -2022,7 +2034,7 @@ QUrl QWebEnginePage::requestedUrl() const
/*!
\property QWebEnginePage::iconUrl
- \brief the URL of the icon associated with the page currently viewed
+ \brief The URL of the icon associated with the page currently viewed.
By default, this property contains an empty URL.
@@ -2036,7 +2048,7 @@ QUrl QWebEnginePage::iconUrl() const
/*!
\property QWebEnginePage::icon
- \brief the icon associated with the page currently viewed
+ \brief The icon associated with the page currently viewed.
\since 5.7
By default, this property contains a null icon. If the web page specifies more than one icon,
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index d597383e..0db462a0 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -130,6 +130,7 @@ public:
void passOnFocus(bool reverse) override;
void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override;
void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override;
+ void releaseProfile() override;
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runGeolocationPermissionRequest(const QUrl &securityOrigin) override;
void runUserNotificationPermissionRequest(const QUrl &securityOrigin) override;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index e183a66e..50de63e9 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -182,13 +182,6 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate()
m_profileAdapter->removeClient(this);
}
- for (QWebEngineDownloadItem *download : qAsConst(m_ongoingDownloads)) {
- if (download)
- download->cancel();
- }
-
- m_ongoingDownloads.clear();
-
if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter())
delete m_profileAdapter;
@@ -203,6 +196,23 @@ ProfileAdapter* QWebEngineProfilePrivate::profileAdapter() const
void QWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId)
{
m_ongoingDownloads.remove(downloadId);
+ if (m_profileAdapter)
+ m_profileAdapter->removeDownload(downloadId);
+}
+
+void QWebEngineProfilePrivate::cleanDownloads()
+{
+ for (auto download : m_ongoingDownloads.values()) {
+ if (!download)
+ continue;
+
+ if (!download->isFinished())
+ download->cancel();
+
+ if (m_profileAdapter)
+ m_profileAdapter->removeDownload(download->id());
+ }
+ m_ongoingDownloads.clear();
}
void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
@@ -226,6 +236,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
QWebEngineDownloadItem *download = new QWebEngineDownloadItem(itemPrivate, q);
m_ongoingDownloads.insert(info.id, download);
+ QObject::connect(download, &QWebEngineDownloadItem::destroyed, q, [id = info.id, this] () { downloadDestroyed(id); });
Q_EMIT q->downloadRequested(download);
@@ -239,7 +250,6 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
if (state == QWebEngineDownloadItem::DownloadRequested) {
// Delete unaccepted downloads.
info.accepted = false;
- m_ongoingDownloads.remove(info.id);
delete download;
}
}
@@ -257,9 +267,18 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
}
download->d_func()->update(info);
+}
- if (download->isFinished())
- m_ongoingDownloads.remove(info.id);
+void QWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
+{
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->addWebContentsAdapterClient(adapter);
+}
+
+void QWebEngineProfilePrivate::removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter)
+{
+ Q_ASSERT(m_profileAdapter);
+ m_profileAdapter->removeWebContentsAdapterClient(adapter);
}
/*!
@@ -308,6 +327,7 @@ QWebEngineProfile::QWebEngineProfile(QWebEngineProfilePrivate *privatePtr, QObje
*/
QWebEngineProfile::~QWebEngineProfile()
{
+ d_ptr->cleanDownloads();
}
/*!
diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h
index 3dd024ff..91c43cf0 100644
--- a/src/webenginewidgets/api/qwebengineprofile_p.h
+++ b/src/webenginewidgets/api/qwebengineprofile_p.h
@@ -84,11 +84,16 @@ public:
void downloadDestroyed(quint32 downloadId);
+ void cleanDownloads();
+
void downloadRequested(DownloadItemInfo &info) override;
void downloadUpdated(const DownloadItemInfo &info) override;
void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &) override;
+ void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
+ void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override;
+
private:
QWebEngineProfile *q_ptr;
QWebEngineSettings *m_settings;
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 576baad1..966b3010 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -238,7 +238,7 @@ QUrl QWebEngineView::iconUrl() const
/*!
\property QWebEngineView::icon
- \brief the icon associated with the page currently viewed
+ \brief The icon associated with the page currently viewed.
\since 5.7
By default, this property contains a null icon.
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
index 8accdf06..b6c5cb49 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc
@@ -28,7 +28,7 @@
/*!
\group webengine-widgetexamples
\title Qt WebEngine Widgets Examples
- \brief Examples demonstrating the Qt WebEngine Widgets usage
+ \brief Examples demonstrating the Qt WebEngine Widgets usage.
\ingroup all-examples
Qt provides an integrated Web browser component based on Chromium, the popular
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 877bf717..f9ab710d 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -451,14 +451,14 @@
/*!
\property QWebEnginePage::hasSelection
- \brief whether this page contains selected content or not.
+ \brief Whether this page contains selected content or not.
\sa selectionChanged()
*/
/*!
\property QWebEnginePage::selectedText
- \brief the text currently selected
+ \brief The text currently selected.
By default, this property contains an empty string.
@@ -643,14 +643,20 @@
/*!
\property QWebEnginePage::title
- \brief the title of the page as defined by the HTML \c <title> element
+ \brief The title of the page as defined by the HTML \c <title> element.
+
+ If the page has no \c <title> element, then the URL is used instead. For \c
+ file:// URLs only the filename is used and not the full path.
+
+ By default, before any content has been loaded, this property contains an
+ empty string.
\sa titleChanged()
*/
/*!
\property QWebEnginePage::url
- \brief the URL of the page currently viewed
+ \brief The URL of the page currently viewed.
Setting this property clears the view and loads the URL.
@@ -661,8 +667,8 @@
/*!
\property QWebEnginePage::requestedUrl
- \brief the URL that was originally requested to be loaded by the page
- that is currently viewed
+ \brief The URL that was originally requested to be loaded by the page
+ that is currently viewed.
\note The URL may differ from the one returned by url(), which is the actual
URL that results from DNS resolution or redirection.
@@ -729,7 +735,7 @@
/*!
\property QWebEnginePage::zoomFactor
- \brief the zoom factor for the page content
+ \brief The zoom factor for the page content.
Valid values are within the range from \c{0.25} to \c{5.0}. The default factor is \c{1.0}.
*/
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 501959ab..568e7a63 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -173,16 +173,16 @@
/*!
\property QWebEngineView::title
- \brief the title of the web page currently viewed
+ \brief The title of the page as defined by the HTML \c <title> element.
- By default, this property contains an empty string.
+ Equivalent to \l {QWebEnginePage::title()}.
\sa titleChanged()
*/
/*!
\property QWebEngineView::url
- \brief the URL of the web page currently viewed
+ \brief The URL of the web page currently viewed.
Setting this property clears the view and loads the URL.
@@ -193,7 +193,7 @@
/*!
\property QWebEngineView::iconUrl
- \brief the URL of the icon associated with the page currently viewed
+ \brief The URL of the icon associated with the page currently viewed.
By default, this property contains an empty URL.
@@ -202,7 +202,7 @@
/*!
\property QWebEngineView::hasSelection
- \brief whether this page contains selected content or not.
+ \brief Whether this page contains selected content or not.
By default, this property is \c false.
@@ -211,7 +211,7 @@
/*!
\property QWebEngineView::selectedText
- \brief the text currently selected
+ \brief The text currently selected.
By default, this property contains an empty string.
@@ -238,7 +238,7 @@
/*!
\property QWebEngineView::zoomFactor
- \brief the zoom factor for the view
+ \brief The zoom factor for the view.
Valid values are within the range from \c{0.25} to \c{5.0}. The default factor is \c{1.0}.
*/
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 993caac9..b8965262 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -152,8 +152,28 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineClientCertificateSelection.selectNone() --> void"
<< "QQuickWebEngineColorDialogRequest.accepted --> bool"
<< "QQuickWebEngineColorDialogRequest.color --> QColor"
+ << "QQuickWebEngineContextMenuRequest.CanUndo --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanRedo --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanCut --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanCopy --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanPaste --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanDelete --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanSelectAll --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanTranslate --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.CanEditRichly --> EditFlags"
<< "QQuickWebEngineColorDialogRequest.dialogAccept(QColor) --> void"
<< "QQuickWebEngineColorDialogRequest.dialogReject() --> void"
+ << "QQuickWebEngineContextMenuRequest.editFlags --> EditFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaInError --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaPaused --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaMuted --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaLoop --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaCanSave --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaHasAudio --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaCanToggleControls --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaControls --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaCanPrint --> MediaFlags"
+ << "QQuickWebEngineContextMenuRequest.MediaCanRotate --> MediaFlags"
<< "QQuickWebEngineContextMenuRequest.MediaTypeAudio --> MediaType"
<< "QQuickWebEngineContextMenuRequest.MediaTypeCanvas --> MediaType"
<< "QQuickWebEngineContextMenuRequest.MediaTypeFile --> MediaType"
@@ -165,6 +185,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineContextMenuRequest.isContentEditable --> bool"
<< "QQuickWebEngineContextMenuRequest.linkText --> QString"
<< "QQuickWebEngineContextMenuRequest.linkUrl --> QUrl"
+ << "QQuickWebEngineContextMenuRequest.mediaFlags --> MediaFlags"
<< "QQuickWebEngineContextMenuRequest.mediaType --> MediaType"
<< "QQuickWebEngineContextMenuRequest.mediaUrl --> QUrl"
<< "QQuickWebEngineContextMenuRequest.misspelledWord --> QString"
@@ -236,6 +257,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineDownloadItem.totalBytesChanged() --> void"
<< "QQuickWebEngineDownloadItem.type --> DownloadType"
<< "QQuickWebEngineDownloadItem.typeChanged() --> void"
+ << "QQuickWebEngineDownloadItem.view --> QQuickWebEngineView*"
<< "QQuickWebEngineFileDialogRequest.FileModeOpen --> FileMode"
<< "QQuickWebEngineFileDialogRequest.FileModeOpenMultiple --> FileMode"
<< "QQuickWebEngineFileDialogRequest.FileModeSave --> FileMode"
@@ -367,6 +389,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.autoLoadImagesChanged() --> void"
<< "QQuickWebEngineSettings.defaultTextEncoding --> QString"
<< "QQuickWebEngineSettings.defaultTextEncodingChanged() --> void"
+ << "QQuickWebEngineSettings.dnsPrefetchEnabled --> bool"
+ << "QQuickWebEngineSettings.dnsPrefetchEnabledChanged() --> void"
<< "QQuickWebEngineSettings.errorPageEnabled --> bool"
<< "QQuickWebEngineSettings.errorPageEnabledChanged() --> void"
<< "QQuickWebEngineSettings.focusOnNavigationEnabled --> bool"
@@ -379,6 +403,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.javascriptCanAccessClipboardChanged() --> void"
<< "QQuickWebEngineSettings.javascriptCanOpenWindows --> bool"
<< "QQuickWebEngineSettings.javascriptCanOpenWindowsChanged() --> void"
+ << "QQuickWebEngineSettings.javascriptCanPaste --> bool"
+ << "QQuickWebEngineSettings.javascriptCanPasteChanged() --> void"
<< "QQuickWebEngineSettings.javascriptEnabled --> bool"
<< "QQuickWebEngineSettings.javascriptEnabledChanged() --> void"
<< "QQuickWebEngineSettings.linksIncludedInFocusChain --> bool"
@@ -676,6 +702,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.navigationRequested(QQuickWebEngineNavigationRequest*) --> void"
<< "QQuickWebEngineView.newViewRequested(QQuickWebEngineNewViewRequest*) --> void"
<< "QQuickWebEngineView.pdfPrintingFinished(QString,bool) --> void"
+ << "QQuickWebEngineView.printRequested() --> void"
<< "QQuickWebEngineView.printToPdf(QJSValue) --> void"
<< "QQuickWebEngineView.printToPdf(QJSValue,PrintedPageSizeId) --> void"
<< "QQuickWebEngineView.printToPdf(QJSValue,PrintedPageSizeId,PrintedPageOrientation) --> void"
@@ -702,8 +729,10 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.setActiveFocusOnPress(bool) --> void"
<< "QQuickWebEngineView.settings --> QQuickWebEngineSettings*"
<< "QQuickWebEngineView.stop() --> void"
+#if QT_CONFIG(webengine_testsupport)
<< "QQuickWebEngineView.testSupport --> QQuickWebEngineTestSupport*"
<< "QQuickWebEngineView.testSupportChanged() --> void"
+#endif
<< "QQuickWebEngineView.title --> QString"
<< "QQuickWebEngineView.titleChanged() --> void"
<< "QQuickWebEngineView.triggerWebAction(WebAction) --> void"
@@ -833,18 +862,23 @@ void tst_publicapi::publicAPI()
// for (const QString &actual : qAsConst(sortedAPI))
// printf(" << \"%s\"\n", qPrintable(actual));
+ bool apiMatch = true;
// Make sure that nothing slips in the public API unintentionally.
for (const QString &actual : qAsConst(actualAPI)) {
- if (!expectedAPI.contains(actual))
- QEXPECT_FAIL("", qPrintable("Expected list is not up-to-date: " + actual), Continue);
- QVERIFY2(expectedAPI.contains(actual), qPrintable(actual));
+ if (!expectedAPI.contains(actual)) {
+ QWARN(qPrintable("Expected list is not up-to-date: " + actual));
+ apiMatch = false;
+ }
}
// Make sure that the expected list is up-to-date with intentionally added APIs.
for (const QString &expected : expectedAPI) {
- if (!actualAPI.contains(expected))
- QEXPECT_FAIL("", qPrintable("Not implemented: " + expected), Continue);
- QVERIFY2(actualAPI.contains(expected), qPrintable(expected));
+ if (!actualAPI.contains(expected)) {
+ apiMatch = false;
+ QWARN(qPrintable("Not implemented: " + expected));
+ }
}
+
+ QVERIFY2(apiMatch, "Unexpected, missing or misspelled API!");
}
QTEST_MAIN(tst_publicapi)
diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml
index 563a87c8..50a41238 100644
--- a/tests/auto/quick/qmltests/data/tst_favicon.qml
+++ b/tests/auto/quick/qmltests/data/tst_favicon.qml
@@ -375,5 +375,38 @@ TestWebEngineView {
faviconImage.destroy()
}
+
+ function test_touchIconWithSameURL()
+ {
+ WebEngine.settings.touchIconsEnabled = false;
+
+ var icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=";
+
+ webEngineView.loadHtml(
+ "<html>" +
+ "<link rel='icon' type='image/png' href='" + icon + "'/>" +
+ "<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>" +
+ "</html>"
+ );
+ verify(webEngineView.waitForLoadSucceeded());
+
+ // The default favicon has to be loaded even if its URL is also set as a touch icon while touch icons are disabled.
+ tryCompare(iconChangedSpy, "count", 1);
+ compare(webEngineView.icon.toString().replace(/^image:\/\/favicon\//, ''), icon);
+
+ iconChangedSpy.clear();
+
+ webEngineView.loadHtml(
+ "<html>" +
+ "<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>" +
+ "</html>"
+ );
+ verify(webEngineView.waitForLoadSucceeded());
+
+ // This page only has a touch icon. With disabled touch icons we don't expect any icon to be shown even if the same icon
+ // was loaded previously.
+ tryCompare(iconChangedSpy, "count", 1);
+ verify(!webEngineView.icon.toString().replace(/^image:\/\/favicon\//, ''));
+ }
}
}
diff --git a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp b/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
index 606d05d9..540c8d50 100644
--- a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
+++ b/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
@@ -62,6 +62,7 @@ private Q_SLOTS:
void downloadTouchIconsEnabled_data();
void downloadTouchIconsEnabled();
void dynamicFavicon();
+ void touchIconWithSameURL();
private:
QWebEngineView *m_view;
@@ -508,6 +509,43 @@ void tst_FaviconManager::dynamicFavicon()
}
}
+void tst_FaviconManager::touchIconWithSameURL()
+{
+ m_page->settings()->setAttribute(QWebEngineSettings::TouchIconsEnabled, false);
+
+ const QString icon("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=");
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+ QSignalSpy iconChangedSpy(m_page, SIGNAL(iconChanged(QIcon)));
+
+ m_page->setHtml("<html>"
+ "<link rel='icon' type='image/png' href='" + icon + "'/>"
+ "<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>"
+ "</html>");
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+
+ // The default favicon has to be loaded even if its URL is also set as a touch icon while touch icons are disabled.
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+ QCOMPARE(m_page->iconUrl().toString(), icon);
+ QTRY_COMPARE(iconChangedSpy.count(), 1);
+
+ loadFinishedSpy.clear();
+ iconUrlChangedSpy.clear();
+ iconChangedSpy.clear();
+
+ m_page->setHtml("<html>"
+ "<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>"
+ "</html>");
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+
+ // This page only has a touch icon. With disabled touch icons we don't expect any icon to be shown even if the same icon
+ // was loaded previously.
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+ QVERIFY(m_page->iconUrl().toString().isEmpty());
+ QTRY_COMPARE(iconChangedSpy.count(), 1);
+
+}
+
QTEST_MAIN(tst_FaviconManager)
#include "tst_faviconmanager.moc"
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index 32823d30..ee1e6ee0 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -70,6 +70,7 @@ private Q_SLOTS:
void downloadFileNot1();
void downloadFileNot2();
void downloadDeleted();
+ void downloadDeletedByProfile();
void downloadUniqueFilename_data();
void downloadUniqueFilename();
void downloadUniqueFileNameWithTimeStamp();
@@ -821,6 +822,37 @@ void tst_QWebEngineDownloadItem::downloadDeleted()
QTRY_COMPARE(finishedCount, 1);
}
+void tst_QWebEngineDownloadItem::downloadDeletedByProfile()
+{
+ m_server->setExpectError(true);
+
+ QPointer<QWebEngineProfile> profile(new QWebEngineProfile);
+ profile->setHttpCacheType(QWebEngineProfile::NoCache);
+ profile->settings()->setAttribute(QWebEngineSettings::AutoLoadIconsForPage, false);
+
+ bool downloadFinished = false;
+ QPointer<QWebEngineDownloadItem> downloadItem;
+ connect(profile, &QWebEngineProfile::downloadRequested, [&] (QWebEngineDownloadItem *item) {
+ connect(item, &QWebEngineDownloadItem::finished, [&] () {
+ downloadFinished = true;
+ });
+ downloadItem = item;
+ item->accept();
+ });
+
+ QPointer<QWebEnginePage> page(new QWebEnginePage(profile));
+ page->download(m_server->url(QByteArrayLiteral("/file")));
+
+ QTRY_COMPARE(downloadItem.isNull(), false);
+ QVERIFY(downloadItem);
+
+ page->deleteLater();
+ profile->deleteLater();
+
+ QTRY_COMPARE(downloadFinished, true);
+ QTRY_COMPARE(downloadItem.isNull(), true);
+}
+
void tst_QWebEngineDownloadItem::downloadUniqueFilename_data()
{
QTest::addColumn<QString>("baseName");