diff options
Diffstat (limited to 'src/webengine')
38 files changed, 1566 insertions, 235 deletions
diff --git a/src/webengine/api/qquickwebengineclientcertificateselection.cpp b/src/webengine/api/qquickwebengineclientcertificateselection.cpp new file mode 100644 index 000000000..c48a59887 --- /dev/null +++ b/src/webengine/api/qquickwebengineclientcertificateselection.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "qquickwebengineclientcertificateselection_p.h" + +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) + +#include "client_cert_select_controller.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype WebEngineClientCertificateOption + \instantiates QQuickWebEngineClientCertificateOption + \inqmlmodule QtWebEngine + \since QtWebEngine 1.9 + \brief Represents a client certificate option. + + \sa {WebEngineClientCertificateSelection::certificates} {WebEngineClientCertificateSelection.certificates} +*/ + +QQuickWebEngineClientCertificateOption::QQuickWebEngineClientCertificateOption(QQuickWebEngineClientCertificateSelection *selection, int index) + : QObject(selection), m_selection(selection), m_index(index) +{} + +/*! + \qmlproperty string WebEngineClientCertificateOption::issuer + \brief The issuer of the certificate. +*/ + +QString QQuickWebEngineClientCertificateOption::issuer() const +{ + return m_selection->d_ptr->certificates().at(m_index).issuerDisplayName(); +} + +/*! + \qmlproperty string WebEngineClientCertificateOption::subject + \brief The subject of the certificate. +*/ +QString QQuickWebEngineClientCertificateOption::subject() const +{ + return m_selection->d_ptr->certificates().at(m_index).subjectDisplayName(); +} + +/*! + \qmlproperty datetime WebEngineClientCertificateOption::effectiveDate + \brief The date and time when the certificate becomes valid. +*/ +QDateTime QQuickWebEngineClientCertificateOption::effectiveDate() const +{ + return m_selection->d_ptr->certificates().at(m_index).effectiveDate(); +} + +/*! + \qmlproperty datetime WebEngineClientCertificateOption::expiryDate + \brief The date and time when the certificate becomes invalid. +*/ +QDateTime QQuickWebEngineClientCertificateOption::expiryDate() const +{ + return m_selection->d_ptr->certificates().at(m_index).expiryDate(); +} + +/*! + \qmlproperty bool WebEngineClientCertificateOption::isSelfSigned + \brief Whether the certificate is only self-signed. +*/ +bool QQuickWebEngineClientCertificateOption::isSelfSigned() const +{ + return m_selection->d_ptr->certificates().at(m_index).isSelfSigned(); +} + +/*! + \qmlmethod void WebEngineClientCertificateOption::select() + + Selects this client certificate option. +*/ +void QQuickWebEngineClientCertificateOption::select() +{ + m_selection->select(m_index); +} + +/*! + \qmltype WebEngineClientCertificateSelection + \instantiates QQuickWebEngineClientCertificateSelection + \inqmlmodule QtWebEngine + \since QtWebEngine 1.9 + \brief Provides a selection of client certificates. + + When a web site requests an SSL client certificate, and one or more certificates + are found in the system's client certificate store, this type provides access to + the certificates to choose from, as well as a method for selecting one. + + The selection is asynchronous. If no certificate is selected and no copy of the + object is kept alive, loading will continue without a certificate. + + \sa {WebEngineView::selectClientCertificate}{WebEngineView.selectClientCertificate} +*/ + +QQuickWebEngineClientCertificateSelection::QQuickWebEngineClientCertificateSelection(QSharedPointer<ClientCertSelectController> selectController) + : QObject(), d_ptr(selectController) +{} + +int QQuickWebEngineClientCertificateSelection::certificates_count( + QQmlListProperty<QQuickWebEngineClientCertificateOption> *p) +{ + Q_ASSERT(p && p->object); + QQuickWebEngineClientCertificateSelection *d = static_cast<QQuickWebEngineClientCertificateSelection *>(p->object); + return d->m_certificates.size(); +} + +QQuickWebEngineClientCertificateOption *QQuickWebEngineClientCertificateSelection::certificates_at( + QQmlListProperty<QQuickWebEngineClientCertificateOption> *p, int idx) +{ + Q_ASSERT(p && p->object); + QQuickWebEngineClientCertificateSelection *d = static_cast<QQuickWebEngineClientCertificateSelection *>(p->object); + if (idx < 0 || idx >= d->m_certificates.size()) + return nullptr; + return d->m_certificates[idx]; +} + +/*! + \qmlproperty list<WebEngineClientCertificateOption> WebEngineClientCertificateSelection::certificates + \brief The client certificates available to choose from. +*/ + +QQmlListProperty<QQuickWebEngineClientCertificateOption> QQuickWebEngineClientCertificateSelection::certificates() +{ + if (m_certificates.empty()) { + QVector<QSslCertificate> certificates = d_ptr->certificates(); + for (int i = 0; i < certificates.count(); ++i) + m_certificates.push_back(new QQuickWebEngineClientCertificateOption(this, i)); + } + + return QQmlListProperty<QQuickWebEngineClientCertificateOption>( + this, nullptr, + certificates_count, + certificates_at); +} + +/*! + \qmlmethod void WebEngineClientCertificateSelection::select(WebEngineClientCertificateOption certificate) + + Selects the client certificate \a certificate. The certificate must be one + of the offered certificates. + + \sa selectNone() +*/ +void QQuickWebEngineClientCertificateSelection::select(const QQuickWebEngineClientCertificateOption *certificate) +{ + select(certificate->m_index); +} + +/*! + \qmlmethod void WebEngineClientCertificateSelection::select(int index) + + Selects the client certificate at the index \a index in the list of offered certificates. + + \sa selectNone() +*/ +void QQuickWebEngineClientCertificateSelection::select(int index) +{ + d_ptr->select(index); +} + +/*! + \qmlmethod void WebEngineClientCertificateSelection::selectNone() + + Continues without using any of the offered certificates. This is the same + action as taken when destroying the last copy of this object if no + selection has been made. + + \sa select() +*/ +void QQuickWebEngineClientCertificateSelection::selectNone() +{ + d_ptr->selectNone(); +} + +/*! + \qmlproperty url WebEngineClientCertificateSelection::host + \brief The host and port of the server requesting the client certificate. +*/ +QUrl QQuickWebEngineClientCertificateSelection::host() const +{ + return d_ptr->hostAndPort(); +} + +QT_END_NAMESPACE + +#endif // QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) diff --git a/src/webengine/api/qquickwebengineclientcertificateselection_p.h b/src/webengine/api/qquickwebengineclientcertificateselection_p.h new file mode 100644 index 000000000..adf8b5f7c --- /dev/null +++ b/src/webengine/api/qquickwebengineclientcertificateselection_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 QQUICKWEBENGINECERTSELECTION_P_H +#define QQUICKWEBENGINECERTSELECTION_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 <QtWebEngine/private/qtwebengineglobal_p.h> + +#include <QtCore/QDateTime> +#include <QtCore/QObject> +#include <QtCore/QSharedPointer> +#include <QtCore/QUrl> +#include <QtCore/QVector> +#include <QtQml/QQmlListProperty> + +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) + +QT_BEGIN_NAMESPACE + +class ClientCertSelectController; +class QQuickWebEngineClientCertificateSelection; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineClientCertificateOption : public QObject { + Q_OBJECT + Q_PROPERTY(QString issuer READ issuer CONSTANT FINAL) + Q_PROPERTY(QString subject READ subject CONSTANT FINAL) + Q_PROPERTY(QDateTime effectiveDate READ effectiveDate CONSTANT FINAL) + Q_PROPERTY(QDateTime expiryDate READ expiryDate CONSTANT FINAL) + Q_PROPERTY(bool isSelfSigned READ isSelfSigned CONSTANT FINAL) + +public: + QString issuer() const; + QString subject() const; + QDateTime effectiveDate() const; + QDateTime expiryDate() const; + bool isSelfSigned() const; + + Q_INVOKABLE void select(); + +private: + friend class QQuickWebEngineClientCertificateSelection; + QQuickWebEngineClientCertificateOption(QQuickWebEngineClientCertificateSelection *selection, int index); + + QQuickWebEngineClientCertificateSelection *m_selection; + int m_index; +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineClientCertificateSelection : public QObject { + Q_OBJECT + Q_PROPERTY(QUrl host READ host CONSTANT FINAL) + Q_PROPERTY(QQmlListProperty<QQuickWebEngineClientCertificateOption> certificates READ certificates CONSTANT FINAL) + +public: + QQuickWebEngineClientCertificateSelection() = default; + + QUrl host() const; + + Q_INVOKABLE void select(int idx); + Q_INVOKABLE void select(const QQuickWebEngineClientCertificateOption *certificate); + Q_INVOKABLE void selectNone(); + QQmlListProperty<QQuickWebEngineClientCertificateOption> certificates(); + +private: + friend class QQuickWebEngineViewPrivate; + friend class QQuickWebEngineClientCertificateOption; + + static int certificates_count(QQmlListProperty<QQuickWebEngineClientCertificateOption> *p); + static QQuickWebEngineClientCertificateOption *certificates_at(QQmlListProperty<QQuickWebEngineClientCertificateOption> *p, int idx); + + explicit QQuickWebEngineClientCertificateSelection(QSharedPointer<ClientCertSelectController>); + + mutable QVector<QQuickWebEngineClientCertificateOption *> m_certificates; + QSharedPointer<ClientCertSelectController> d_ptr; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QQuickWebEngineClientCertificateOption *) +Q_DECLARE_METATYPE(QQmlListProperty<QQuickWebEngineClientCertificateOption>) +Q_DECLARE_METATYPE(QQuickWebEngineClientCertificateSelection *) + +#endif + +#endif // QQUICKWEBENGINECERTSELECTION_P_H diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index 73577a04c..ac75b5356 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -46,6 +46,7 @@ #include "qquickwebenginesettings_p.h" #include "qquickwebengineview_p_p.h" #include "qwebenginecookiestore.h" +#include "qwebenginenotification.h" #include <QQmlEngine> @@ -150,6 +151,13 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineDownloadItem::MimeHtmlSaveFormat, QtWebEngineC The \a download argument holds the state of the finished download instance. */ +/*! + \fn QQuickWebEngineProfile::userNotification(QWebEngineNotification *notification) + + This signal is emitted whenever there is a newly created user notification. + The \a notification argument holds the notification instance to query data and interact with. +*/ + QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter) : m_settings(new QQuickWebEngineSettings()) , m_profileAdapter(profileAdapter) @@ -285,6 +293,20 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info } } +void QQuickWebEngineProfilePrivate::useForGlobalCertificateVerificationChanged() +{ + Q_Q(QQuickWebEngineProfile); + Q_EMIT q->useForGlobalCertificateVerificationChanged(); +} + +void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) +{ + Q_Q(QQuickWebEngineProfile); + auto notification = new QWebEngineNotification(controller); + QQmlEngine::setObjectOwnership(notification, QQmlEngine::JavaScriptOwnership); + Q_EMIT q->userNotification(notification); +} + void QQuickWebEngineProfilePrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script) { Q_ASSERT(p && p->data); @@ -365,6 +387,14 @@ void QQuickWebEngineProfilePrivate::userScripts_clear(QQmlListProperty<QQuickWeb */ /*! + \qmlsignal WebEngineProfile::userNotification(WebEngineNotification notification) + \since QtWebEngine 1.9 + + This signal is emitted whenever there is a newly created user notification. + The \a notification argument holds the notification instance to query data and interact with. +*/ + +/*! Constructs a new profile with the parent \a parent. */ QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent) @@ -796,6 +826,102 @@ bool QQuickWebEngineProfile::isSpellCheckEnabled() const } /*! + \property QQuickWebEngineProfile::useForGlobalCertificateVerification + \since 5.13 + + This property holds whether this profile is used for downloading and + caching during global certificate verification when using the online + certificate status protocol (OCSP), certificate revokation lists (CRLs), + and authority information access (AIA), for example. + + As long as one profile has this option enabled, all other profiles will be + able to use it for certificate verification. Only one profile at a time can + have this option enabled. It is recommended that the profile has a disk HTTP + cache to avoid needlessly re-downloading. + + By default, no profile has this property enabled. + + Currently, only affects Linux/NSS installations, where having a profile with + this role enables OCSP. +*/ + +/*! + \qmlproperty bool WebEngineProfile::useForGlobalCertificateVerification + \since QtWebEngine 1.9 + + This property holds whether this profile is used for downloading and + caching during global certificate verification when using the online + certificate status protocol (OCSP), certificate revokation lists (CRLs), + and authority information access (AIA), for example. + + As long as one profile has this option enabled, all other profiles will be + able to use it for certificate verification. Only one profile at a time can + have this option enabled. It is recommended that the profile has a disk HTTP + cache to avoid needlessly re-downloading. + + By default, no profile has this property enabled. + + Currently, only affects Linux/NSS installations, where having a profile with + this role enables OCSP. +*/ + +void QQuickWebEngineProfile::setUseForGlobalCertificateVerification(bool enable) +{ + Q_D(QQuickWebEngineProfile); + if (enable != d->profileAdapter()->isUsedForGlobalCertificateVerification()) { + d->profileAdapter()->setUseForGlobalCertificateVerification(enable); + emit useForGlobalCertificateVerificationChanged(); + } +} + +bool QQuickWebEngineProfile::isUsedForGlobalCertificateVerification() const +{ + const Q_D(QQuickWebEngineProfile); + return d->profileAdapter()->isUsedForGlobalCertificateVerification(); +} + +/*! + \qmlproperty string WebEngineProfile::downloadPath + \since QtWebEngine 1.9 + + The path to the location where the downloaded files are stored. + + Overrides the default path used for download location. + + If set to an empty string, the default path is restored. + + \note By default, the download path is QStandardPaths::DownloadLocation. +*/ + +/*! + \property QQuickWebEngineProfile::downloadPath + \since QtWebEngine 1.9 + + The path to the location where the downloaded files are stored. + + Overrides the default path used for download location, setting it to \a path. + + If set to an empty string, the default path is restored. + + \note By default, the download path is QStandardPaths::DownloadLocation. +*/ + +void QQuickWebEngineProfile::setDownloadPath(const QString &path) +{ + Q_D(QQuickWebEngineProfile); + if (downloadPath() == path) + return; + d->profileAdapter()->setDownloadPath(path); + emit downloadPathChanged(); +} + +QString QQuickWebEngineProfile::downloadPath() const +{ + const Q_D(QQuickWebEngineProfile); + return d->profileAdapter()->downloadPath(); +} + +/*! Returns the cookie store for this profile. */ @@ -827,40 +953,52 @@ void QQuickWebEngineProfile::clearHttpCache() d->profileAdapter()->clearHttpCache(); } - +#if QT_DEPRECATED_SINCE(5, 13) /*! Registers a request interceptor singleton \a interceptor to intercept URL requests. The profile does not take ownership of the pointer. + \obsolete + + Interceptors installed with this method will call + QWebEngineUrlRequestInterceptor::interceptRequest on the I/O thread. Therefore + the user has to provide thread-safe interaction with the other user classes. + Use setUrlRequestInterceptor instead. + \sa QWebEngineUrlRequestInterceptor + */ void QQuickWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor) { Q_D(QQuickWebEngineProfile); + interceptor->setProperty("deprecated", true); d->profileAdapter()->setRequestInterceptor(interceptor); + qWarning("Use of deprecated not tread-safe setter, use setUrlRequestInterceptor instead."); } +#endif /*! - Returns the custom URL scheme handler register for the URL scheme \a scheme. + Registers a request interceptor singleton \a interceptor to intercept URL requests. + + The profile does not take ownership of the pointer. + + \sa QWebEngineUrlRequestInfo QWebEngineUrlRequestInterceptor */ -const QWebEngineUrlSchemeHandler *QQuickWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const +void QQuickWebEngineProfile::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor) { - const Q_D(QQuickWebEngineProfile); - if (d->profileAdapter()->customUrlSchemeHandlers().contains(scheme)) - return d->profileAdapter()->customUrlSchemeHandlers().value(scheme); - return 0; + Q_D(QQuickWebEngineProfile); + d->profileAdapter()->setRequestInterceptor(interceptor); } -static bool checkInternalScheme(const QByteArray &scheme) + +/*! + Returns the custom URL scheme handler register for the URL scheme \a scheme. +*/ +const QWebEngineUrlSchemeHandler *QQuickWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const { - static QSet<QByteArray> internalSchemes; - if (internalSchemes.isEmpty()) { - internalSchemes << QByteArrayLiteral("qrc") << QByteArrayLiteral("data") << QByteArrayLiteral("blob") - << QByteArrayLiteral("http") << QByteArrayLiteral("https") << QByteArrayLiteral("ftp") - << QByteArrayLiteral("javascript"); - } - return internalSchemes.contains(scheme); + const Q_D(QQuickWebEngineProfile); + return d->profileAdapter()->urlSchemeHandler(scheme); } /*! @@ -872,25 +1010,7 @@ static bool checkInternalScheme(const QByteArray &scheme) void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler) { Q_D(QQuickWebEngineProfile); - Q_ASSERT(handler); - QByteArray canonicalScheme = scheme.toLower(); - if (checkInternalScheme(canonicalScheme)) { - qWarning("Cannot install a URL scheme handler overriding internal scheme: %s", scheme.constData()); - return; - } - - if (d->profileAdapter()->customUrlSchemeHandlers().contains(canonicalScheme)) { - if (d->profileAdapter()->customUrlSchemeHandlers().value(canonicalScheme) != handler) - qWarning("URL scheme handler already installed for the scheme: %s", scheme.constData()); - return; - } - - if (QWebEngineUrlScheme::schemeByName(canonicalScheme) == QWebEngineUrlScheme()) - qWarning("Please register the custom scheme '%s' via QWebEngineUrlScheme::registerScheme() " - "before installing the custom scheme handler.", scheme.constData()); - - d->profileAdapter()->addCustomUrlSchemeHandler(canonicalScheme, handler); - connect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*))); + d->profileAdapter()->installUrlSchemeHandler(scheme, handler); } /*! @@ -901,10 +1021,7 @@ void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, Q void QQuickWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler) { Q_D(QQuickWebEngineProfile); - Q_ASSERT(handler); - if (!d->profileAdapter()->removeCustomUrlSchemeHandler(handler)) - return; - disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*))); + d->profileAdapter()->removeUrlSchemeHandler(handler); } /*! @@ -915,10 +1032,7 @@ void QQuickWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler * void QQuickWebEngineProfile::removeUrlScheme(const QByteArray &scheme) { Q_D(QQuickWebEngineProfile); - QWebEngineUrlSchemeHandler *handler = d->profileAdapter()->takeCustomUrlSchemeHandler(scheme); - if (!handler) - return; - disconnect(handler, SIGNAL(_q_destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*)), this, SLOT(destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler*))); + d->profileAdapter()->removeUrlScheme(scheme); } /*! @@ -927,12 +1041,7 @@ void QQuickWebEngineProfile::removeUrlScheme(const QByteArray &scheme) void QQuickWebEngineProfile::removeAllUrlSchemeHandlers() { Q_D(QQuickWebEngineProfile); - d->profileAdapter()->clearCustomUrlSchemeHandlers(); -} - -void QQuickWebEngineProfile::destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj) -{ - removeUrlSchemeHandler(obj); + d->profileAdapter()->removeAllUrlSchemeHandlers(); } QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const @@ -970,4 +1079,19 @@ QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineProfile::userScripts() d->userScripts_clear); } +/*! + \since 5.13 + + Returns the profile's client certificate store. +*/ +QWebEngineClientCertificateStore *QQuickWebEngineProfile::clientCertificateStore() +{ +#if QT_CONFIG(ssl) + Q_D(QQuickWebEngineProfile); + return d->profileAdapter()->clientCertificateStore(); +#else + return nullptr; +#endif +} + QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h index 9fc4f9eca..e6f9fb73d 100644 --- a/src/webengine/api/qquickwebengineprofile.h +++ b/src/webengine/api/qquickwebengineprofile.h @@ -54,7 +54,9 @@ class QQuickWebEngineDownloadItem; class QQuickWebEngineProfilePrivate; class QQuickWebEngineScript; class QQuickWebEngineSettings; +class QWebEngineClientCertificateStore; class QWebEngineCookieStore; +class QWebEngineNotification; class QWebEngineUrlRequestInterceptor; class QWebEngineUrlSchemeHandler; @@ -72,6 +74,12 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(QStringList spellCheckLanguages READ spellCheckLanguages WRITE setSpellCheckLanguages NOTIFY spellCheckLanguagesChanged FINAL REVISION 3) Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION 3) Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 4) + Q_PROPERTY(bool useForGlobalCertificateVerification + READ isUsedForGlobalCertificateVerification + WRITE setUseForGlobalCertificateVerification + NOTIFY useForGlobalCertificateVerificationChanged + FINAL REVISION 5) + Q_PROPERTY(QString downloadPath READ downloadPath WRITE setDownloadPath NOTIFY downloadPathChanged FINAL REVISION 5) public: QQuickWebEngineProfile(QObject *parent = Q_NULLPTR); @@ -120,7 +128,10 @@ public: QWebEngineCookieStore *cookieStore() const; +#if QT_DEPRECATED_SINCE(5, 13) void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); +#endif + void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const; void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *); @@ -137,6 +148,14 @@ public: QQmlListProperty<QQuickWebEngineScript> userScripts(); + void setUseForGlobalCertificateVerification(bool b); + bool isUsedForGlobalCertificateVerification() const; + + QString downloadPath() const; + void setDownloadPath(const QString &path); + + QWebEngineClientCertificateStore *clientCertificateStore(); + static QQuickWebEngineProfile *defaultProfile(); Q_SIGNALS: @@ -151,12 +170,13 @@ Q_SIGNALS: Q_REVISION(1) void httpAcceptLanguageChanged(); Q_REVISION(3) void spellCheckLanguagesChanged(); Q_REVISION(3) void spellCheckEnabledChanged(); + Q_REVISION(5) void useForGlobalCertificateVerificationChanged(); + Q_REVISION(5) void downloadPathChanged(); void downloadRequested(QQuickWebEngineDownloadItem *download); void downloadFinished(QQuickWebEngineDownloadItem *download); -private Q_SLOTS: - void destroyedUrlSchemeHandler(QWebEngineUrlSchemeHandler *obj); + Q_REVISION(5) void userNotification(QWebEngineNotification *notification); private: Q_DECLARE_PRIVATE(QQuickWebEngineProfile) diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h index 41e513f4c..c6d412ab3 100644 --- a/src/webengine/api/qquickwebengineprofile_p.h +++ b/src/webengine/api/qquickwebengineprofile_p.h @@ -85,6 +85,10 @@ public: void downloadRequested(DownloadItemInfo &info) override; void downloadUpdated(const DownloadItemInfo &info) override; + void useForGlobalCertificateVerificationChanged() override; + + void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) override; + // QQmlListPropertyHelpers static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script); static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p); diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp index 6e96e76cf..93a3668ed 100644 --- a/src/webengine/api/qquickwebenginesettings.cpp +++ b/src/webengine/api/qquickwebenginesettings.cpp @@ -457,6 +457,20 @@ bool QQuickWebEngineSettings::dnsPrefetchEnabled() const } /*! + \qmlproperty bool WebEngineSettings::pdfViewerEnabled + \since QtWebEngine 1.9 + + Specifies that PDF documents will be opened in the internal PDF viewer + instead of being downloaded. + + Enabled by default. +*/ +bool QQuickWebEngineSettings::pdfViewerEnabled() const +{ + return d_ptr->testAttribute(WebEngineSettings::PdfViewerEnabled); +} + +/*! \qmlproperty string WebEngineSettings::defaultTextEncoding \since QtWebEngine 1.2 @@ -714,6 +728,14 @@ void QQuickWebEngineSettings::setDnsPrefetchEnabled(bool on) Q_EMIT dnsPrefetchEnabledChanged(); } +void QQuickWebEngineSettings::setPdfViewerEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::PdfViewerEnabled); + d_ptr->setAttribute(WebEngineSettings::PdfViewerEnabled, on); + if (wasOn != on) + Q_EMIT pdfViewerEnabledChanged(); +} + void QQuickWebEngineSettings::setUnknownUrlSchemePolicy(QQuickWebEngineSettings::UnknownUrlSchemePolicy policy) { WebEngineSettings::UnknownUrlSchemePolicy oldPolicy = d_ptr->unknownUrlSchemePolicy(); diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h index 6e1aaca39..ce43e0e9c 100644 --- a/src/webengine/api/qquickwebenginesettings_p.h +++ b/src/webengine/api/qquickwebenginesettings_p.h @@ -93,6 +93,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject { Q_PROPERTY(bool webRTCPublicInterfacesOnly READ webRTCPublicInterfacesOnly WRITE setWebRTCPublicInterfacesOnly NOTIFY webRTCPublicInterfacesOnlyChanged REVISION 6 FINAL) Q_PROPERTY(bool javascriptCanPaste READ javascriptCanPaste WRITE setJavascriptCanPaste NOTIFY javascriptCanPasteChanged REVISION 6 FINAL) Q_PROPERTY(bool dnsPrefetchEnabled READ dnsPrefetchEnabled WRITE setDnsPrefetchEnabled NOTIFY dnsPrefetchEnabledChanged REVISION 7 FINAL) + Q_PROPERTY(bool pdfViewerEnabled READ pdfViewerEnabled WRITE setPdfViewerEnabled NOTIFY pdfViewerEnabledChanged REVISION 8 FINAL) public: enum UnknownUrlSchemePolicy { @@ -135,6 +136,7 @@ public: bool webRTCPublicInterfacesOnly() const; bool javascriptCanPaste() const; bool dnsPrefetchEnabled() const; + bool pdfViewerEnabled() const; void setAutoLoadImages(bool on); void setJavascriptEnabled(bool on); @@ -166,6 +168,7 @@ public: void setWebRTCPublicInterfacesOnly(bool on); void setJavascriptCanPaste(bool on); void setDnsPrefetchEnabled(bool on); + void setPdfViewerEnabled(bool on); signals: void autoLoadImagesChanged(); @@ -198,6 +201,7 @@ signals: Q_REVISION(6) void webRTCPublicInterfacesOnlyChanged(); Q_REVISION(6) void javascriptCanPasteChanged(); Q_REVISION(7) void dnsPrefetchEnabledChanged(); + Q_REVISION(8) void pdfViewerEnabledChanged(); private: explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = 0); diff --git a/src/webengine/api/qquickwebenginetouchhandleprovider.cpp b/src/webengine/api/qquickwebenginetouchhandleprovider.cpp new file mode 100644 index 000000000..80f4727b6 --- /dev/null +++ b/src/webengine/api/qquickwebenginetouchhandleprovider.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "qquickwebenginetouchhandleprovider_p_p.h" + +// static +QString QQuickWebEngineTouchHandleProvider::identifier() +{ + return QStringLiteral("touchhandle"); +} + +// static +QUrl QQuickWebEngineTouchHandleProvider::url(int orientation) +{ + return QUrl(QStringLiteral("image://%1/%2").arg(identifier(), QString::number(orientation))); +} + +QQuickWebEngineTouchHandleProvider::QQuickWebEngineTouchHandleProvider() + : QQuickImageProvider(QQuickImageProvider::Image) +{ +} + +QQuickWebEngineTouchHandleProvider::~QQuickWebEngineTouchHandleProvider() +{ +} + +void QQuickWebEngineTouchHandleProvider::init(const QMap<int, QImage> &images) +{ + if (!m_touchHandleMap.empty()) { + Q_ASSERT(images.size() == m_touchHandleMap.size()); + return; + } + + m_touchHandleMap.unite(images); +} + +QImage QQuickWebEngineTouchHandleProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) +{ + Q_UNUSED(size); + Q_UNUSED(requestedSize); + + Q_ASSERT(m_touchHandleMap.contains(id.toInt())); + return m_touchHandleMap.value(id.toInt()); +} diff --git a/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h b/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h new file mode 100644 index 000000000..277436289 --- /dev/null +++ b/src/webengine/api/qquickwebenginetouchhandleprovider_p_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H +#define QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_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 <QtQuick/QQuickImageProvider> +#include <QtWebEngine/private/qtwebengineglobal_p.h> + +QT_BEGIN_NAMESPACE + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTouchHandleProvider : public QQuickImageProvider { +public: + static QString identifier(); + static QUrl url(int orientation); + + QQuickWebEngineTouchHandleProvider(); + ~QQuickWebEngineTouchHandleProvider(); + + void init(const QMap<int, QImage> &images); + virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize); + +private: + QMap<int, QImage> m_touchHandleMap; +}; + + +QT_END_NAMESPACE + +#endif // QQUICKWEBENGINETOUCHHANDLEPROVIDER_P_P_H diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index fd3cc8e82..9826ebfe2 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -39,17 +39,18 @@ #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" -#include "qtwebenginecoreglobal_p.h" #include "authentication_dialog_controller.h" #include "profile_adapter.h" #include "certificate_error_controller.h" #include "file_picker_controller.h" #include "javascript_dialog_controller.h" +#include "touch_selection_menu_controller.h" #include "qquickwebengineaction_p.h" #include "qquickwebengineaction_p_p.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginecertificateerror_p.h" +#include "qquickwebengineclientcertificateselection_p.h" #include "qquickwebenginecontextmenurequest_p.h" #include "qquickwebenginedialogrequests_p.h" #include "qquickwebenginefaviconprovider_p_p.h" @@ -59,6 +60,7 @@ #include "qquickwebengineprofile_p.h" #include "qquickwebenginesettings_p.h" #include "qquickwebenginescript_p.h" +#include "qquickwebenginetouchhandleprovider_p_p.h" #include "qwebenginequotarequest.h" #include "qwebengineregisterprotocolhandlerrequest.h" @@ -126,7 +128,6 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_webChannel(0) , m_webChannelWorld(0) , m_isBeingAdopted(false) - , m_dpiScale(1.0) , m_backgroundColor(Qt::white) , m_zoomFactor(1.0) , m_ui2Enabled(false) @@ -300,9 +301,17 @@ void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<Cert m_certificateErrorControllers.append(errorController); } -void QQuickWebEngineViewPrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &) +void QQuickWebEngineViewPrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &controller) { - // Doing nothing will free the select-controller and perform default continue. +#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) + Q_Q(QQuickWebEngineView); + QQuickWebEngineClientCertificateSelection *certSelection = new QQuickWebEngineClientCertificateSelection(controller); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(certSelection); + Q_EMIT q->selectClientCertificate(certSelection); +#else + Q_UNUSED(controller); +#endif } void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url) @@ -311,6 +320,12 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation); } +void QQuickWebEngineViewPrivate::runUserNotificationPermissionRequest(const QUrl &url) +{ + Q_Q(QQuickWebEngineView); + Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Notifications); +} + void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller) { Q_Q(QQuickWebEngineView); @@ -409,11 +424,6 @@ QRectF QQuickWebEngineViewPrivate::viewportRect() const return QRectF(q->x(), q->y(), q->width(), q->height()); } -qreal QQuickWebEngineViewPrivate::dpiScale() const -{ - return m_dpiScale; -} - QColor QQuickWebEngineViewPrivate::backgroundColor() const { return m_backgroundColor; @@ -1134,12 +1144,12 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount) callback.call(args); } -void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, const QByteArray &result) +void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result) { Q_Q(QQuickWebEngineView); QJSValue callback = m_callbacks.take(requestId); QJSValueList args; - args.append(qmlEngine(q)->toScriptValue(result)); + args.append(qmlEngine(q)->toScriptValue(*(result.data()))); callback.call(args); } @@ -1207,6 +1217,39 @@ void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText) ui()->showToolTip(toolTipText); } +QtWebEngineCore::TouchHandleDrawableClient *QQuickWebEngineViewPrivate::createTouchHandle(const QMap<int, QImage> &images) +{ + return new QQuickWebEngineTouchHandle(ui(), images); +} + +void QQuickWebEngineViewPrivate::showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *menuController, const QRect &selectionBounds, const QSize &handleSize) +{ + Q_UNUSED(handleSize); + + const int kSpacingBetweenButtons = 2; + const int kMenuButtonMinWidth = 63; + const int kMenuButtonMinHeight = 38; + + int buttonCount = menuController->buttonCount(); + if (buttonCount == 1) { + menuController->runContextMenu(); + return; + } + + int width = (kSpacingBetweenButtons * (buttonCount + 1)) + (kMenuButtonMinWidth * buttonCount); + int height = kMenuButtonMinHeight + kSpacingBetweenButtons; + int x = (selectionBounds.x() + selectionBounds.x() + selectionBounds.width() - width) / 2; + int y = selectionBounds.y() - height - 2; + + QRect bounds(x, y, width, height); + ui()->showTouchSelectionMenu(menuController, bounds, kSpacingBetweenButtons); +} + +void QQuickWebEngineViewPrivate::hideTouchSelectionMenu() +{ + ui()->hideTouchSelectionMenu(); +} + bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); @@ -1517,6 +1560,9 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu WebContentsAdapterClient::MediaDesktopAudioCapture | WebContentsAdapterClient::MediaDesktopVideoCapture)); break; + case Notifications: + d_ptr->adapter->runUserNotificationRequestCallback(securityOrigin, granted); + break; default: Q_UNREACHABLE(); } @@ -2281,5 +2327,43 @@ bool QQuickContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem) Q_UNREACHABLE(); } + +QQuickWebEngineTouchHandle::QQuickWebEngineTouchHandle(QtWebEngineCore::UIDelegatesManager *ui, const QMap<int, QImage> &images) +{ + Q_ASSERT(ui); + m_item.reset(ui->createTouchHandle()); + + QQmlEngine *engine = qmlEngine(m_item.data()); + Q_ASSERT(engine); + QQuickWebEngineTouchHandleProvider *touchHandleProvider = + static_cast<QQuickWebEngineTouchHandleProvider *>(engine->imageProvider(QQuickWebEngineTouchHandleProvider::identifier())); + Q_ASSERT(touchHandleProvider); + touchHandleProvider->init(images); +} + +void QQuickWebEngineTouchHandle::setImage(int orientation) +{ + QUrl url = QQuickWebEngineTouchHandleProvider::url(orientation); + m_item->setProperty("source", url); +} + +void QQuickWebEngineTouchHandle::setBounds(const QRect &bounds) +{ + m_item->setProperty("x", bounds.x()); + m_item->setProperty("y", bounds.y()); + m_item->setProperty("width", bounds.width()); + m_item->setProperty("height", bounds.height()); +} + +void QQuickWebEngineTouchHandle::setVisible(bool visible) +{ + m_item->setProperty("visible", visible); +} + +void QQuickWebEngineTouchHandle::setOpacity(float opacity) +{ + m_item->setProperty("opacity", opacity); +} + QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index ae92b6df0..c851dcb8d 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -51,12 +51,11 @@ // We mean it. // -#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h> #include <QtWebEngine/private/qtwebengineglobal_p.h> -#include "qquickwebenginescript.h" #include <QQuickItem> #include <QtGui/qcolor.h> +#include "qquickwebenginescript.h" QT_BEGIN_NAMESPACE @@ -65,6 +64,7 @@ class QQuickContextMenuBuilder; class QQuickWebEngineAction; class QQuickWebEngineAuthenticationDialogRequest; class QQuickWebEngineCertificateError; +class QQuickWebEngineClientCertificateSelection; class QQuickWebEngineColorDialogRequest; class QQuickWebEngineContextMenuRequest; class QQuickWebEngineFaviconProvider; @@ -104,7 +104,7 @@ private: const bool m_toggleOn; }; -#define LATEST_WEBENGINEVIEW_REVISION 7 +#define LATEST_WEBENGINEVIEW_REVISION 9 class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_OBJECT @@ -209,7 +209,8 @@ public: MediaAudioVideoCapture, Geolocation, DesktopVideoCapture, - DesktopAudioVideoCapture + DesktopAudioVideoCapture, + Notifications, }; Q_ENUM(Feature) @@ -550,6 +551,7 @@ Q_SIGNALS: Q_REVISION(7) void devToolsViewChanged(); Q_REVISION(7) void registerProtocolHandlerRequested(const QWebEngineRegisterProtocolHandlerRequest &request); Q_REVISION(8) void printRequested(); + Q_REVISION(9) void selectClientCertificate(QQuickWebEngineClientCertificateSelection *clientCertSelection); #if QT_CONFIG(webengine_testsupport) void testSupportChanged(); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 3c4189fd9..aa0a765f8 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -53,6 +53,7 @@ #include "qquickwebengineview_p.h" #include "render_view_context_menu_qt.h" +#include "touch_handle_drawable_client.h" #include "web_contents_adapter_client.h" #include <QPointer> @@ -64,6 +65,8 @@ namespace QtWebEngineCore { class RenderWidgetHostViewQtDelegateQuick; +class TouchHandleDrawableClient; +class TouchSelectionMenuController; class UIDelegatesManager; class WebContentsAdapter; } @@ -76,6 +79,7 @@ class QQuickWebEngineContextMenuRequest; class QQuickWebEngineSettings; class QQuickWebEngineFaviconProvider; class QQuickWebEngineProfilePrivate; +class QQuickWebEngineTouchHandleProvider; QQuickWebEngineView::WebAction editorActionForKeyEvent(QKeyEvent* event); @@ -105,7 +109,6 @@ public: void selectionChanged() override { } void recentlyAudibleChanged(bool recentlyAudible) override; QRectF viewportRect() const override; - qreal dpiScale() const override; QColor backgroundColor() const override; void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override; void loadCommitted() override; @@ -128,7 +131,7 @@ public: void didFetchDocumentMarkup(quint64, const QString&) override { } void didFetchDocumentInnerText(quint64, const QString&) override { } void didFindText(quint64, int) override; - void didPrintPage(quint64 requestId, const QByteArray &result) override; + void didPrintPage(quint64 requestId, QSharedPointer<QByteArray>) override; void didPrintPageToPdf(const QString &filePath, bool success) override; bool passOnFocus(bool reverse) override; void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override; @@ -142,6 +145,7 @@ public: void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) override; void selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController) override; void runGeolocationPermissionRequest(QUrl const&) override; + void runUserNotificationPermissionRequest(QUrl const&) override; void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override; void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override; void updateScrollPosition(const QPointF &position) override; @@ -152,6 +156,9 @@ public: bool supportsDragging() const override; bool isEnabled() const override; void setToolTip(const QString &toolTipText) override; + QtWebEngineCore::TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &images) override; + void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &, const QSize &) override; + void hideTouchSelectionMenu() override; const QObject *holdingQObject() const override; ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::QmlClient; } @@ -211,7 +218,6 @@ public: private: QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager; QList<QQuickWebEngineScript *> m_userScripts; - qreal m_dpiScale; QColor m_backgroundColor; qreal m_zoomFactor; bool m_ui2Enabled; @@ -253,6 +259,19 @@ private: QObject *m_menu; }; +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTouchHandle : public QtWebEngineCore::TouchHandleDrawableClient { +public: + QQuickWebEngineTouchHandle(QtWebEngineCore::UIDelegatesManager *ui, const QMap<int, QImage> &images); + + void setImage(int orientation) override; + void setBounds(const QRect &bounds) override; + void setVisible(bool visible) override; + void setOpacity(float opacity) override; + +private: + QScopedPointer<QQuickItem> m_item; +}; + QT_END_NAMESPACE #endif // QQUICKWEBENGINEVIEW_P_P_H diff --git a/src/webengine/api/qtwebengineglobal.h b/src/webengine/api/qtwebengineglobal.h index 2d83be674..c2b33778a 100644 --- a/src/webengine/api/qtwebengineglobal.h +++ b/src/webengine/api/qtwebengineglobal.h @@ -41,6 +41,7 @@ #define QTWEBENGINEGLOBAL_H #include <QtCore/qglobal.h> +#include <QtWebEngine/qtwebengine-config.h> QT_BEGIN_NAMESPACE diff --git a/src/webengine/api/qtwebengineglobal_p.h b/src/webengine/api/qtwebengineglobal_p.h index 7058bef09..2d30f75b0 100644 --- a/src/webengine/api/qtwebengineglobal_p.h +++ b/src/webengine/api/qtwebengineglobal_p.h @@ -51,7 +51,9 @@ // We mean it. // -#include "qtwebengineglobal.h" +#include <QtWebEngine/qtwebengineglobal.h> +#include <QtCore/private/qglobal_p.h> +#include <QtWebEngine/private/qtwebengine-config_p.h> QT_BEGIN_NAMESPACE diff --git a/src/webengine/configure.json b/src/webengine/configure.json new file mode 100644 index 000000000..ec5ad34d9 --- /dev/null +++ b/src/webengine/configure.json @@ -0,0 +1,29 @@ +{ + "module": "webengine", + "depends": [ + "webenginecore-private" + ], + "features": { + "webengine-ui-delegates": { + "label": "UI Delegates", + "section": "WebEngine", + "output": [ "privateFeature" ] + }, + "webengine-testsupport": { + "label": "Test Support", + "autoDetect": "features.private_tests || call.isTestsInBuildParts", + "output": [ "privateFeature" ] + } + }, + "summary": [ + { + "section": "Qt WebEngineQml", + "condition": "features.webengine-qml", + "entries": [ + "webengine-ui-delegates", + "webengine-testsupport" + ] + } + ] +} + diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc index 7ff6eea6b..e4fe9bba6 100644 --- a/src/webengine/doc/src/external-resources.qdoc +++ b/src/webengine/doc/src/external-resources.qdoc @@ -146,3 +146,8 @@ \externalpage https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler \title registerProtocolHandler */ + +/*! + \externalpage https://www.w3.org/TR/notifications + \title Web Notifications API +*/ diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index 1dce17e08..f53c118a8 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -50,6 +50,7 @@ \li \l{Touch} \li \l{View Source} \li \l{WebRTC} + \li \l{Web Notifications} \endlist \section1 Audio and Video Codecs @@ -511,4 +512,13 @@ This feature can be tested by setting up a webcam or microphone and then opening \c https://test.webrtc.org/ in \l{WebEngine Widgets Simple Browser Example}{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}. + + \section1 Web Notifications + + Qt WebEngine supports JavaScript \l{Web Notifications API}. + The application has to explicitly allow the feature by using + QWebEnginePage::Notifications or \l{WebEngineView::Feature} + {WebEngineView.Notifications}. + + Support for this feature was added in Qt 5.13.0. */ diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc index d83a65bdb..58c0708cc 100644 --- a/src/webengine/doc/src/qtwebengine-overview.qdoc +++ b/src/webengine/doc/src/qtwebengine-overview.qdoc @@ -238,14 +238,18 @@ are automatically retrieved from the system. Settings from an installed QNetworkProxyFactory will be ignored, though. - Not all properties of QNetworkProxy are supported by Qt WebEngine. That is, - QNetworkProxy::type(), QNetworkProxy::hostName() and QNetworkProxy::port() are taken into - account. All other proxy settings such as QNetworkProxy::rawHeader(), QNetworkProxy::user(), or - QNetworkProxy::password() are ignored. + In case QNetworkProxy::user() and QNetworkProxy::password() are set, these credentials + will be automatically used for proxy authentication. It is up to the user to provide valid + credentials, since there is no error handling callback. - If a proxy requires authentication, QWebEnginePage::proxyAuthenticationRequired is emitted. + If no credentials are set with QNetworkProxy, but the proxy requires authentication, + QWebEnginePage::proxyAuthenticationRequired is emitted. For Qt Quick, a dialog is shown. + Not all properties of QNetworkProxy are supported by Qt WebEngine. That is, + QNetworkProxy::type(), QNetworkProxy::hostName() and QNetworkProxy::port() are taken into + account. All other proxy settings such as QNetworkProxy::rawHeader() are ignored. + \section1 High DPI Support To support High DPI devices, it is recommended that the application attribute diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc index 5e172087d..540d74035 100644 --- a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc +++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \qmlmodule QtWebEngine 1.8 + \qmlmodule QtWebEngine 1.9 \title Qt WebEngine QML Types \brief Provides QML types for rendering web content within a QML application. \ingroup qtwebengine-modules @@ -36,7 +36,7 @@ your .qml file: \badcode - import QtWebEngine 1.8 + import QtWebEngine 1.9 \endcode To link against the module, add the following QT variable to your qmake .pro diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc index 0e25e16f3..a6f2af39e 100644 --- a/src/webengine/doc/src/webengineview_lgpl.qdoc +++ b/src/webengine/doc/src/webengineview_lgpl.qdoc @@ -858,6 +858,8 @@ (Added in Qt 5.10) \value DesktopAudioVideoCapture Both audio and video output capture. (Added in Qt 5.10) + \value WebEnginView.Notifications + Web notifications for the end-user. \sa featurePermissionRequested(), grantFeaturePermission() */ @@ -1475,3 +1477,19 @@ \sa printToPdf */ + +/*! + \qmlsignal WebEngineView::selectClientCertificate(WebEngineClientCertificateSelection clientCertificateSelection) + \since QtWebEngine 1.9 + + This signal is emitted when a web site requests an SSL client certificate, and one or more were + found in the system's client certificate store. + + Handling the signal is asynchronous, and loading will be waiting until a certificate is selected, + or the last copy of \a clientCertificateSelection is destroyed. + + If the signal is not handled, \a clientCertificateSelection is automatically destroyed, and loading + will continue without a client certificate. + + \sa WebEngineClientCertificateSelection +*/ diff --git a/src/webengine/module.pro b/src/webengine/module.pro new file mode 100644 index 000000000..49a1086b2 --- /dev/null +++ b/src/webengine/module.pro @@ -0,0 +1,94 @@ +include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) +QT_FOR_CONFIG += webengine-private + +TARGET = QtWebEngine +MODULE = webengine + +# For our export macros +DEFINES += QT_BUILD_WEBENGINE_LIB + +QT += qml quick webenginecore +QT_PRIVATE += quick-private gui-private core-private webenginecore-private + +QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf + +INCLUDEPATH += $$PWD api ../core ../core/api + +SOURCES = \ + api/qquickwebengineaction.cpp \ + api/qquickwebenginecertificateerror.cpp \ + api/qquickwebengineclientcertificateselection.cpp \ + api/qquickwebenginecontextmenurequest.cpp \ + api/qquickwebenginedialogrequests.cpp \ + api/qquickwebenginedownloaditem.cpp \ + api/qquickwebenginehistory.cpp \ + api/qquickwebenginefaviconprovider.cpp \ + api/qquickwebengineloadrequest.cpp \ + api/qquickwebenginenavigationrequest.cpp \ + api/qquickwebenginenewviewrequest.cpp \ + api/qquickwebengineprofile.cpp \ + api/qquickwebenginescript.cpp \ + api/qquickwebenginesettings.cpp \ + api/qquickwebenginesingleton.cpp \ + api/qquickwebenginetouchhandleprovider.cpp \ + api/qquickwebengineview.cpp \ + api/qtwebengineglobal.cpp \ + render_widget_host_view_qt_delegate_quick.cpp \ + render_widget_host_view_qt_delegate_quickwindow.cpp \ + ui_delegates_manager.cpp + +HEADERS = \ + api/qtwebengineglobal.h \ + api/qtwebengineglobal_p.h \ + api/qquickwebengineaction_p.h \ + api/qquickwebengineaction_p_p.h \ + api/qquickwebenginecertificateerror_p.h \ + api/qquickwebengineclientcertificateselection_p.h \ + api/qquickwebenginecontextmenurequest_p.h \ + api/qquickwebenginedialogrequests_p.h \ + api/qquickwebenginedownloaditem_p.h \ + api/qquickwebenginedownloaditem_p_p.h \ + api/qquickwebenginehistory_p.h \ + api/qquickwebenginefaviconprovider_p_p.h \ + api/qquickwebengineloadrequest_p.h \ + api/qquickwebenginenavigationrequest_p.h \ + api/qquickwebenginenewviewrequest_p.h \ + api/qquickwebengineprofile.h \ + api/qquickwebengineprofile_p.h \ + api/qquickwebenginescript.h \ + api/qquickwebenginescript_p.h \ + api/qquickwebenginesettings_p.h \ + api/qquickwebenginesingleton_p.h \ + api/qquickwebenginetouchhandleprovider_p_p.h \ + api/qquickwebengineview_p.h \ + api/qquickwebengineview_p_p.h \ + render_widget_host_view_qt_delegate_quick.h \ + render_widget_host_view_qt_delegate_quickwindow.h \ + ui_delegates_manager.h + +qtConfig(webengine-testsupport) { + QT_PRIVATE += testlib + SOURCES += api/qquickwebenginetestsupport.cpp + HEADERS += api/qquickwebenginetestsupport_p.h +} + +!build_pass { + python = $$pythonPathForShell() + chromium_attributions.commands = \ + cd $$shell_quote($$shell_path($$PWD/../3rdparty)) && \ + $$python chromium/tools/licenses.py \ + --file-template ../../tools/about_credits.tmpl \ + --entry-template ../../tools/about_credits_entry.tmpl credits \ + $$shell_quote($$shell_path($$OUT_PWD/chromium_attributions.qdoc)) + chromium_attributions.CONFIG += phony + + QMAKE_EXTRA_TARGETS += chromium_attributions + + prepare_docs { + prepare_docs.depends += chromium_attributions + } else { + html_docs.depends += chromium_attributions + } +} + +load(qt_module) diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index 84a12c930..56e5c5c9f 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -40,22 +40,24 @@ #include <QtQml/qqmlextensionplugin.h> #include <QtWebEngine/QQuickWebEngineProfile> -#include "qquickwebenginecertificateerror_p.h" -#include "qquickwebenginecontextmenurequest_p.h" -#include "qquickwebenginedialogrequests_p.h" -#include "qquickwebenginedownloaditem_p.h" -#include "qquickwebenginehistory_p.h" -#include "qquickwebenginefaviconprovider_p_p.h" -#include "qquickwebengineloadrequest_p.h" -#include "qquickwebenginenavigationrequest_p.h" -#include "qquickwebenginenewviewrequest_p.h" -#include "qquickwebenginesettings_p.h" -#include "qquickwebenginesingleton_p.h" -#include "qquickwebengineview_p.h" -#include "qquickwebengineaction_p.h" -#include "qwebenginequotarequest.h" -#include "qwebengineregisterprotocolhandlerrequest.h" -#include "qtwebengineversion.h" +#include <QtWebEngine/private/qquickwebenginecertificateerror_p.h> +#include <QtWebEngine/private/qquickwebengineclientcertificateselection_p.h> +#include <QtWebEngine/private/qquickwebenginecontextmenurequest_p.h> +#include <QtWebEngine/private/qquickwebenginedialogrequests_p.h> +#include <QtWebEngine/private/qquickwebenginedownloaditem_p.h> +#include <QtWebEngine/private/qquickwebenginehistory_p.h> +#include <QtWebEngine/private/qquickwebenginefaviconprovider_p_p.h> +#include <QtWebEngine/private/qquickwebengineloadrequest_p.h> +#include <QtWebEngine/private/qquickwebenginenavigationrequest_p.h> +#include <QtWebEngine/private/qquickwebenginenewviewrequest_p.h> +#include <QtWebEngine/private/qquickwebenginesettings_p.h> +#include <QtWebEngine/private/qquickwebenginesingleton_p.h> +#include <QtWebEngine/private/qquickwebenginetouchhandleprovider_p_p.h> +#include <QtWebEngine/private/qquickwebengineview_p.h> +#include <QtWebEngine/private/qquickwebengineaction_p.h> +#include <QtWebEngineCore/qwebenginenotification.h> +#include <QtWebEngineCore/qwebenginequotarequest.h> +#include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h> QT_BEGIN_NAMESPACE @@ -73,6 +75,7 @@ public: { Q_UNUSED(uri); engine->addImageProvider(QQuickWebEngineFaviconProvider::identifier(), new QQuickWebEngineFaviconProvider); + engine->addImageProvider(QQuickWebEngineTouchHandleProvider::identifier(), new QQuickWebEngineTouchHandleProvider); } void registerTypes(const char *uri) override @@ -91,11 +94,13 @@ public: qmlRegisterType<QQuickWebEngineView, 6>(uri, 1, 6, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 7>(uri, 1, 7, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 8>(uri, 1, 8, "WebEngineView"); + qmlRegisterType<QQuickWebEngineView, 9>(uri, 1, 9, "WebEngineView"); qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 3>(uri, 1, 4, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 4>(uri, 1, 5, "WebEngineProfile"); + qmlRegisterType<QQuickWebEngineProfile, 5>(uri, 1, 9, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript"); qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", msgUncreatableType("WebEngineCertificateError")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem", @@ -116,14 +121,15 @@ public: tr("Cannot create a separate instance of WebEngineDownloadItem")); qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", msgUncreatableType("WebEngineNewViewRequest")); qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest, 1>(uri, 1, 5, "WebEngineNewViewRequest", tr("Cannot create separate instance of WebEngineNewViewRequest")); - qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); - qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); - qmlRegisterUncreatableType<QQuickWebEngineSettings, 2>(uri, 1, 3, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); - qmlRegisterUncreatableType<QQuickWebEngineSettings, 3>(uri, 1, 4, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); - qmlRegisterUncreatableType<QQuickWebEngineSettings, 4>(uri, 1, 5, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); - qmlRegisterUncreatableType<QQuickWebEngineSettings, 5>(uri, 1, 6, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); - qmlRegisterUncreatableType<QQuickWebEngineSettings, 6>(uri, 1, 7, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); - qmlRegisterUncreatableType<QQuickWebEngineSettings, 7>(uri, 1, 8, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 2>(uri, 1, 3, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 3>(uri, 1, 4, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 4>(uri, 1, 5, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 5>(uri, 1, 6, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 6>(uri, 1, 7, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 7>(uri, 1, 8, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 8>(uri, 1, 9, "WebEngineSettings", msgUncreatableType("WebEngineSettings")); qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider); qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 1, "NavigationHistory", tr("Cannot create a separate instance of NavigationHistory")); @@ -153,6 +159,11 @@ public: qmlRegisterUncreatableType<QWebEngineRegisterProtocolHandlerRequest>(uri, 1, 7, "RegisterProtocolHandlerRequest", msgUncreatableType("RegisterProtocolHandlerRequest")); qmlRegisterUncreatableType<QQuickWebEngineAction>(uri, 1, 8, "WebEngineAction", msgUncreatableType("WebEngineAction")); + qmlRegisterUncreatableType<QQuickWebEngineClientCertificateSelection>(uri, 1, 9, "WebEngineClientCertificateSelection", + msgUncreatableType("WebEngineClientCertificateSelection")); + qmlRegisterUncreatableType<QQuickWebEngineClientCertificateOption>(uri, 1, 9, "WebEngineClientCertificateOption", + msgUncreatableType("WebEngineClientCertificateOption")); + qmlRegisterUncreatableType<QWebEngineNotification>(uri, 1, 9, "WebEngineNotification", msgUncreatableType("WebEngineNotification")); } private: diff --git a/src/webengine/plugin/plugin.pro b/src/webengine/plugin/plugin.pro index b6652fa26..0c1310de3 100644 --- a/src/webengine/plugin/plugin.pro +++ b/src/webengine/plugin/plugin.pro @@ -1,13 +1,12 @@ CXX_MODULE = qml TARGET = qtwebengineplugin TARGETPATH = QtWebEngine -IMPORT_VERSION = 1.8 +IMPORT_VERSION = 1.9 -QT += webengine qml quick +QT += qml quick QT_PRIVATE += core-private webenginecore-private webengine-private -INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/core/api $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api $$QTWEBENGINE_ROOT/include/QtWebEngine - SOURCES = plugin.cpp +QMAKE_QMLPLUGINDUMP_FLAGS = -defaultplatform load(qml_plugin) diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes index 1f295ac57..cc2ed502d 100644 --- a/src/webengine/plugin/plugins.qmltypes +++ b/src/webengine/plugin/plugins.qmltypes @@ -4,7 +4,7 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -defaultplatform -dependencies dependencies.json -nonrelocatable QtWebEngine 1.8' +// 'qmlplugindump -nonrelocatable -defaultplatform -dependencies dependencies.json QtWebEngine 1.9' Module { dependencies: ["QtQuick 2.8"] @@ -80,6 +80,46 @@ Module { Method { name: "rejectCertificate" } } Component { + name: "QQuickWebEngineClientCertificateOption" + prototype: "QObject" + exports: ["QtWebEngine/WebEngineClientCertificateOption 1.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + Property { name: "issuer"; type: "string"; isReadonly: true } + Property { name: "subject"; type: "string"; isReadonly: true } + Property { name: "effectiveDate"; type: "QDateTime"; isReadonly: true } + Property { name: "expiryDate"; type: "QDateTime"; isReadonly: true } + Property { name: "isSelfSigned"; type: "bool"; isReadonly: true } + Method { name: "select" } + } + Component { + name: "QQuickWebEngineClientCertificateSelection" + prototype: "QObject" + exports: ["QtWebEngine/WebEngineClientCertificateSelection 1.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + Property { name: "host"; type: "QUrl"; isReadonly: true } + Property { + name: "certificates" + type: "QQuickWebEngineClientCertificateOption" + isList: true + isReadonly: true + } + Method { + name: "select" + Parameter { name: "idx"; type: "int" } + } + Method { + name: "select" + Parameter { + name: "certificate" + type: "const QQuickWebEngineClientCertificateOption" + isPointer: true + } + } + Method { name: "selectNone" } + } + Component { name: "QQuickWebEngineColorDialogRequest" prototype: "QObject" exports: ["QtWebEngine/ColorDialogRequest 1.4"] @@ -437,9 +477,10 @@ Module { "QtWebEngine/WebEngineProfile 1.2", "QtWebEngine/WebEngineProfile 1.3", "QtWebEngine/WebEngineProfile 1.4", - "QtWebEngine/WebEngineProfile 1.5" + "QtWebEngine/WebEngineProfile 1.5", + "QtWebEngine/WebEngineProfile 1.9" ] - exportMetaObjectRevisions: [0, 1, 2, 3, 4] + exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5] Enum { name: "HttpCacheType" values: { @@ -474,9 +515,13 @@ Module { isList: true isReadonly: true } + Property { name: "useForGlobalCertificateVerification"; revision: 5; type: "bool" } + Property { name: "downloadPath"; revision: 5; type: "string" } Signal { name: "httpAcceptLanguageChanged"; revision: 1 } Signal { name: "spellCheckLanguagesChanged"; revision: 3 } Signal { name: "spellCheckEnabledChanged"; revision: 3 } + Signal { name: "useForGlobalCertificateVerificationChanged"; revision: 5 } + Signal { name: "downloadPathChanged"; revision: 5 } Signal { name: "downloadRequested" Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true } @@ -485,6 +530,11 @@ Module { name: "downloadFinished" Parameter { name: "download"; type: "QQuickWebEngineDownloadItem"; isPointer: true } } + Signal { + name: "userNotification" + revision: 5 + Parameter { name: "notification"; type: "QWebEngineNotification"; isPointer: true } + } Method { name: "clearHttpCache"; revision: 2 } } Component { @@ -617,6 +667,7 @@ Module { Property { name: "webRTCPublicInterfacesOnly"; revision: 6; type: "bool" } Property { name: "javascriptCanPaste"; revision: 6; type: "bool" } Property { name: "dnsPrefetchEnabled"; revision: 7; type: "bool" } + Property { name: "pdfViewerEnabled"; revision: 8; type: "bool" } Signal { name: "fullScreenSupportEnabledChanged"; revision: 1 } Signal { name: "screenCaptureEnabledChanged"; revision: 2 } Signal { name: "webGLEnabledChanged"; revision: 2 } @@ -634,6 +685,7 @@ Module { Signal { name: "webRTCPublicInterfacesOnlyChanged"; revision: 6 } Signal { name: "javascriptCanPasteChanged"; revision: 6 } Signal { name: "dnsPrefetchEnabledChanged"; revision: 7 } + Signal { name: "pdfViewerEnabledChanged"; revision: 8 } } Component { name: "QQuickWebEngineSingleton" @@ -664,9 +716,10 @@ Module { "QtWebEngine/WebEngineView 1.5", "QtWebEngine/WebEngineView 1.6", "QtWebEngine/WebEngineView 1.7", - "QtWebEngine/WebEngineView 1.8" + "QtWebEngine/WebEngineView 1.8", + "QtWebEngine/WebEngineView 1.9" ] - exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7, 8] + exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Enum { name: "NavigationRequestAction" values: { @@ -723,7 +776,8 @@ Module { "MediaAudioVideoCapture": 2, "Geolocation": 3, "DesktopVideoCapture": 4, - "DesktopAudioVideoCapture": 5 + "DesktopAudioVideoCapture": 5, + "Notifications": 6 } } Enum { @@ -1131,6 +1185,15 @@ Module { Parameter { name: "request"; type: "QWebEngineRegisterProtocolHandlerRequest" } } Signal { name: "printRequested"; revision: 8 } + Signal { + name: "selectClientCertificate" + revision: 9 + Parameter { + name: "clientCertSelection" + type: "QQuickWebEngineClientCertificateSelection" + isPointer: true + } + } Method { name: "runJavaScript" Parameter { type: "string" } @@ -1257,6 +1320,32 @@ Module { } } Component { + name: "QWebEngineNotification" + prototype: "QObject" + exports: ["QtWebEngine/WebEngineNotification 1.9"] + isCreatable: false + exportMetaObjectRevisions: [0] + Enum { + name: "Direction" + values: { + "LeftToRight": 0, + "RightToLeft": 1, + "DirectionAuto": 2 + } + } + Property { name: "origin"; type: "QUrl"; isReadonly: true } + Property { name: "icon"; type: "QIcon"; isReadonly: true } + Property { name: "title"; type: "string"; isReadonly: true } + Property { name: "message"; type: "string"; isReadonly: true } + Property { name: "tag"; type: "string"; isReadonly: true } + Property { name: "language"; type: "string"; isReadonly: true } + Property { name: "direction"; type: "Direction"; isReadonly: true } + Signal { name: "closed" } + Method { name: "show" } + Method { name: "click" } + Method { name: "close" } + } + Component { name: "QWebEngineQuotaRequest" exports: ["QtWebEngine/QuotaRequest 1.7"] isCreatable: false diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp index 8aaf4c714..e756ee157 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -99,19 +99,9 @@ void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r) setVisible(true); } -QRectF RenderWidgetHostViewQtDelegateQuick::screenRect() const +QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const { - QPointF pos = mapToScene(QPointF(0,0)); - return QRectF(pos.x(), pos.y(), width(), height()); -} - -QRectF RenderWidgetHostViewQtDelegateQuick::contentsRect() const -{ - QPointF scenePoint = mapToScene(QPointF(0, 0)); - QPointF screenPos; - if (window()) - screenPos = window()->mapToGlobal(scenePoint.toPoint()); - return QRectF(screenPos.x(), screenPos.y(), width(), height()); + return QRectF(mapToGlobal(QPointF(0, 0)), size()); } void RenderWidgetHostViewQtDelegateQuick::setKeyboardFocus() @@ -322,16 +312,7 @@ void RenderWidgetHostViewQtDelegateQuick::inputMethodEvent(QInputMethodEvent *ev void RenderWidgetHostViewQtDelegateQuick::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { QQuickItem::geometryChanged(newGeometry, oldGeometry); - - if (window()) { - const QPointF globalPos = QQuickItem::mapToGlobal(position()); - if (globalPos != m_lastGlobalPos) { - m_lastGlobalPos = globalPos; - m_client->windowBoundsChanged(); - } - } - - m_client->notifyResize(); + m_client->visualPropertiesChanged(); } void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const ItemChangeData &value) @@ -347,8 +328,7 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It if (!m_isPopup) m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide()))); } - - m_client->windowChanged(); + m_client->visualPropertiesChanged(); } else if (change == QQuickItem::ItemVisibleHasChanged) { if (!m_isPopup && !value.boolValue) onHide(); @@ -362,9 +342,7 @@ QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged() { - if (window()) - m_lastGlobalPos = QQuickItem::mapToGlobal(position()); - m_client->windowBoundsChanged(); + m_client->visualPropertiesChanged(); } void RenderWidgetHostViewQtDelegateQuick::onHide() diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h index d4d64804a..4edf37cff 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h @@ -59,8 +59,7 @@ public: ~RenderWidgetHostViewQtDelegateQuick(); void initAsPopup(const QRect&) override; - QRectF screenRect() const override; - QRectF contentsRect() const override; + QRectF viewGeometry() const override; void setKeyboardFocus() override; bool hasKeyboardFocus() override; void lockMouse() override; @@ -113,7 +112,6 @@ private: RenderWidgetHostViewQtDelegateClient *m_client; QList<QMetaObject::Connection> m_windowConnections; bool m_isPopup; - QPointF m_lastGlobalPos; QQuickWebEngineView *m_view = nullptr; }; diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp index d3c88148e..3c6c743e0 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp @@ -62,14 +62,9 @@ void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &screenR show(); } -QRectF RenderWidgetHostViewQtDelegateQuickWindow::screenRect() const +QRectF RenderWidgetHostViewQtDelegateQuickWindow::viewGeometry() const { - return QRectF(x(), y(), width(), height()); -} - -QRectF RenderWidgetHostViewQtDelegateQuickWindow::contentsRect() const -{ - return geometry(); + return m_realDelegate->viewGeometry(); } void RenderWidgetHostViewQtDelegateQuickWindow::show() diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h index 36e4ddd8a..039f6102a 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h @@ -56,8 +56,7 @@ public: ~RenderWidgetHostViewQtDelegateQuickWindow(); void initAsPopup(const QRect&) override; - QRectF screenRect() const override; - QRectF contentsRect() const override; + QRectF viewGeometry() const override; void setKeyboardFocus() override {} bool hasKeyboardFocus() override { return false; } void lockMouse() override {} diff --git a/src/webengine/plugin/testsupport/plugin.cpp b/src/webengine/testsupport/plugin.cpp index d5c43a859..7a1e73d8b 100644 --- a/src/webengine/plugin/testsupport/plugin.cpp +++ b/src/webengine/testsupport/plugin.cpp @@ -39,7 +39,7 @@ #include <QtQml> -#include "qquickwebenginetestsupport_p.h" +#include <QtWebEngine/private/qquickwebenginetestsupport_p.h> QT_BEGIN_NAMESPACE diff --git a/src/webengine/testsupport/plugins.qmltypes b/src/webengine/testsupport/plugins.qmltypes new file mode 100644 index 000000000..12c763724 --- /dev/null +++ b/src/webengine/testsupport/plugins.qmltypes @@ -0,0 +1,73 @@ +import QtQuick.tooling 1.2 + +// This file describes the plugin-supplied types contained in the library. +// It is used for QML tooling purposes only. +// +// This file was auto-generated by: +// 'qmlplugindump -nonrelocatable QtWebEngine.testsupport 1.0' + +Module { + dependencies: ["QtQuick 2.0"] + Component { name: "QPlatformInputContext"; prototype: "QObject" } + Component { + name: "QQuickWebEngineErrorPage" + prototype: "QObject" + exports: ["QtWebEngine.testsupport/WebEngineErrorPage 1.0"] + isCreatable: false + exportMetaObjectRevisions: [0] + Signal { + name: "loadingChanged" + Parameter { name: "loadRequest"; type: "QQuickWebEngineLoadRequest"; isPointer: true } + } + } + Component { + name: "QQuickWebEngineTestEvent" + prototype: "QObject" + exports: ["QtWebEngine.testsupport/WebEngineTestEvent 1.0"] + isCreatable: false + exportMetaObjectRevisions: [0] + Method { + name: "mouseMultiClick" + type: "bool" + Parameter { name: "item"; type: "QObject"; isPointer: true } + Parameter { name: "x"; type: "double" } + Parameter { name: "y"; type: "double" } + Parameter { name: "clickCount"; type: "int" } + } + } + Component { + name: "QQuickWebEngineTestInputContext" + prototype: "QPlatformInputContext" + exports: ["QtWebEngine.testsupport/TestInputContext 1.0"] + isCreatable: false + exportMetaObjectRevisions: [0] + Method { name: "create" } + Method { name: "release" } + } + Component { + name: "QQuickWebEngineTestSupport" + prototype: "QObject" + exports: ["QtWebEngine.testsupport/WebEngineTestSupport 1.0"] + exportMetaObjectRevisions: [0] + Property { + name: "errorPage" + type: "QQuickWebEngineErrorPage" + isReadonly: true + isPointer: true + } + Property { + name: "testInputContext" + type: "QQuickWebEngineTestInputContext" + isReadonly: true + isPointer: true + } + Property { + name: "testEvent" + type: "QQuickWebEngineTestEvent" + isReadonly: true + isPointer: true + } + Signal { name: "windowCloseRejected" } + Signal { name: "loadVisuallyCommitted" } + } +} diff --git a/src/webengine/plugin/testsupport/qmldir b/src/webengine/testsupport/qmldir index 7fff80251..7fff80251 100644 --- a/src/webengine/plugin/testsupport/qmldir +++ b/src/webengine/testsupport/qmldir diff --git a/src/webengine/plugin/testsupport/testsupport.pro b/src/webengine/testsupport/testsupport.pro index 2804635f8..a24796675 100644 --- a/src/webengine/plugin/testsupport/testsupport.pro +++ b/src/webengine/testsupport/testsupport.pro @@ -3,11 +3,9 @@ TARGET = qtwebenginetestsupportplugin TARGETPATH = QtWebEngine/testsupport IMPORT_VERSION = 1.0 -QT += webengine qml quick +QT += qml quick QT_PRIVATE += webengine-private gui-private -INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api - SOURCES = plugin.cpp load(qml_plugin) diff --git a/src/webengine/ui/TouchHandle.qml b/src/webengine/ui/TouchHandle.qml new file mode 100644 index 000000000..76a93829e --- /dev/null +++ b/src/webengine/ui/TouchHandle.qml @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.5 + +Image { } diff --git a/src/webengine/ui/TouchSelectionMenu.qml b/src/webengine/ui/TouchSelectionMenu.qml new file mode 100644 index 000000000..7cf16b554 --- /dev/null +++ b/src/webengine/ui/TouchSelectionMenu.qml @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Layouts 1.3 + +Rectangle { + id: menu + + signal cutTriggered + signal copyTriggered + signal pasteTriggered + signal contextMenuTriggered + + property bool isCutEnabled: false + property bool isCopyEnabled: false + property bool isPasteEnabled: false + + property color borderColor: "darkGray" + property color bgColor: "white" + + radius: 4 + border.color: borderColor + color: borderColor + antialiasing: true + + RowLayout { + anchors.fill: parent + spacing: parent.border.width + anchors.margins: parent.border.width + + Rectangle { + Layout.fillHeight: true + Layout.fillWidth: true + radius: menu.radius + color: bgColor + visible: isCutEnabled + + Text { + id: cutText + anchors.centerIn: parent + text: "Cut" + } + + MouseArea { + anchors.fill: parent + onPressed: { + parent.color = borderColor; + cutText.color = "white"; + } + onReleased: { + parent.color = bgColor; + cutText.color = "black"; + cutTriggered(); + } + } + } + + Rectangle { + Layout.fillHeight: true + Layout.fillWidth: true + radius: menu.radius + color: bgColor + visible: isCopyEnabled + + Text { + id: copyText + anchors.centerIn: parent + text: "Copy" + } + + MouseArea { + anchors.fill: parent + onPressed: { + parent.color = borderColor; + copyText.color = "white"; + } + onReleased: { + parent.color = bgColor; + copyText.color = "black"; + copyTriggered(); + } + } + } + + Rectangle { + Layout.fillHeight: true + Layout.fillWidth: true + radius: menu.radius + color: bgColor + visible: isPasteEnabled + + Text { + id: pasteText + anchors.centerIn: parent + text: "Paste" + } + + MouseArea { + anchors.fill: parent + onPressed: { + parent.color = borderColor; + pasteText.color = "white"; + } + onReleased: { + parent.color = bgColor; + pasteText.color = "black"; + pasteTriggered(); + } + } + } + + Rectangle { + Layout.fillHeight: true + Layout.fillWidth: true + radius: menu.radius + color: bgColor + + Text { + id: contextMenuText + anchors.centerIn: parent + text: "..." + } + + MouseArea { + anchors.fill: parent + onPressed: { + parent.color = borderColor; + contextMenuText.color = "white"; + } + onReleased: { + parent.color = bgColor; + contextMenuText.color = "black"; + contextMenuTriggered(); + } + } + } + } +} diff --git a/src/webengine/ui/ui.pro b/src/webengine/ui/ui.pro index eb6bf435c..69f754e0c 100644 --- a/src/webengine/ui/ui.pro +++ b/src/webengine/ui/ui.pro @@ -13,6 +13,8 @@ QML_FILES += \ Menu.qml \ MenuItem.qml \ MenuSeparator.qml \ - ToolTip.qml + ToolTip.qml \ + TouchHandle.qml \ + TouchSelectionMenu.qml load(qml_module) diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 7e49bc77d..da120ab69 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -44,6 +44,7 @@ #include <color_chooser_controller.h> #include <file_picker_controller.h> #include <javascript_dialog_controller.h> +#include <touch_selection_menu_controller.h> #include <web_contents_adapter_client.h> #include <QFileInfo> @@ -54,6 +55,7 @@ #include <QCursor> #include <QList> #include <QScreen> +#include <QTimer> #include <QGuiApplication> // Uncomment for QML debugging @@ -125,6 +127,7 @@ const char *defaultPropertyName(QObject *obj) UIDelegatesManager::UIDelegatesManager(QQuickWebEngineView *view) : m_view(view) , m_toolTip(nullptr) + , m_touchSelectionMenu(nullptr) FOR_EACH_COMPONENT_TYPE(COMPONENT_MEMBER_INIT, NO_SEPARATOR) { } @@ -568,6 +571,82 @@ void UIDelegatesManager::showToolTip(const QString &text) QMetaObject::invokeMethod(m_toolTip.data(), "open"); } +QQuickItem *UIDelegatesManager::createTouchHandle() +{ + if (!ensureComponentLoaded(TouchHandle)) + return nullptr; + + QQmlContext *context = qmlContext(m_view); + QObject *touchHandle = touchHandleComponent->beginCreate(context); + QQuickItem *item = qobject_cast<QQuickItem *>(touchHandle); + Q_ASSERT(item); + item->setParentItem(m_view); + touchHandleComponent->completeCreate(); + + return item; +} + +void UIDelegatesManager::showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *menuController, const QRect &bounds, const int spacing) +{ + if (!ensureComponentLoaded(TouchSelectionMenu)) + return; + + QQmlContext *context = qmlContext(m_view); + m_touchSelectionMenu.reset(touchSelectionMenuComponent->beginCreate(context)); + if (QQuickItem *item = qobject_cast<QQuickItem *>(m_touchSelectionMenu.data())) + item->setParentItem(m_view); + m_touchSelectionMenu->setParent(m_view); + + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("width")).write(bounds.width()); + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("height")).write(bounds.height()); + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("x")).write(bounds.x()); + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("y")).write(bounds.y()); + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("border.width")).write(spacing); + + // Cut button + bool cutEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Cut); + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isCutEnabled")).write(cutEnabled); + if (cutEnabled) { + QQmlProperty cutSignal(m_touchSelectionMenu.data(), QStringLiteral("onCutTriggered")); + CHECK_QML_SIGNAL_PROPERTY(cutSignal, touchSelectionMenuComponent->url()); + int cutIndex = menuController->metaObject()->indexOfSlot("cut()"); + QObject::connect(m_touchSelectionMenu.data(), cutSignal.method(), menuController, menuController->metaObject()->method(cutIndex)); + } + + // Copy button + bool copyEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Copy); + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isCopyEnabled")).write(copyEnabled); + if (copyEnabled) { + QQmlProperty copySignal(m_touchSelectionMenu.data(), QStringLiteral("onCopyTriggered")); + CHECK_QML_SIGNAL_PROPERTY(copySignal, touchSelectionMenuComponent->url()); + int copyIndex = menuController->metaObject()->indexOfSlot("copy()"); + QObject::connect(m_touchSelectionMenu.data(), copySignal.method(), menuController, menuController->metaObject()->method(copyIndex)); + } + + // Paste button + bool pasteEnabled = menuController->isCommandEnabled(TouchSelectionMenuController::Paste); + QQmlProperty(m_touchSelectionMenu.data(), QStringLiteral("isPasteEnabled")).write(pasteEnabled); + if (pasteEnabled) { + QQmlProperty pasteSignal(m_touchSelectionMenu.data(), QStringLiteral("onPasteTriggered")); + CHECK_QML_SIGNAL_PROPERTY(pasteSignal, touchSelectionMenuComponent->url()); + int pasteIndex = menuController->metaObject()->indexOfSlot("paste()"); + QObject::connect(m_touchSelectionMenu.data(), pasteSignal.method(), menuController, menuController->metaObject()->method(pasteIndex)); + } + + // Context menu button + QQmlProperty contextMenuSignal(m_touchSelectionMenu.data(), QStringLiteral("onContextMenuTriggered")); + CHECK_QML_SIGNAL_PROPERTY(contextMenuSignal, touchSelectionMenuComponent->url()); + int contextMenuIndex = menuController->metaObject()->indexOfSlot("runContextMenu()"); + QObject::connect(m_touchSelectionMenu.data(), contextMenuSignal.method(), menuController, menuController->metaObject()->method(contextMenuIndex)); + + touchSelectionMenuComponent->completeCreate(); +} + +void UIDelegatesManager::hideTouchSelectionMenu() +{ + QTimer::singleShot(0, m_view, [this] { m_touchSelectionMenu.reset(); }); +} + UI2DelegatesManager::UI2DelegatesManager(QQuickWebEngineView *view) : UIDelegatesManager(view) { diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h index 18457e4ed..4b6e291b2 100644 --- a/src/webengine/ui_delegates_manager.h +++ b/src/webengine/ui_delegates_manager.h @@ -61,6 +61,8 @@ F(FilePicker, filePicker) SEPARATOR \ F(AuthenticationDialog, authenticationDialog) SEPARATOR \ F(ToolTip, toolTip) SEPARATOR \ + F(TouchHandle, touchHandle) SEPARATOR \ + F(TouchSelectionMenu, touchSelectionMenu) SEPARATOR \ #define COMMA_SEPARATOR , #define SEMICOLON_SEPARATOR ; @@ -81,6 +83,7 @@ namespace QtWebEngineCore { class AuthenticationDialogController; class JavaScriptDialogController; class FilePickerController; +class TouchSelectionMenuController; const char *defaultPropertyName(QObject *obj); @@ -110,6 +113,9 @@ public: void showFilePicker(QSharedPointer<FilePickerController>); virtual void showMenu(QObject *menu); void showToolTip(const QString &text); + QQuickItem *createTouchHandle(); + void showTouchSelectionMenu(TouchSelectionMenuController *, const QRect &, const int spacing); + void hideTouchSelectionMenu(); protected: bool ensureComponentLoaded(ComponentType); @@ -117,6 +123,7 @@ protected: QQuickWebEngineView *m_view; QScopedPointer<QObject> m_toolTip; QStringList m_importDirs; + QScopedPointer<QObject> m_touchSelectionMenu; FOR_EACH_COMPONENT_TYPE(MEMBER_DECLARATION, SEMICOLON_SEPARATOR) diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 418ade9a8..23668229e 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -1,89 +1,19 @@ -include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) # workaround for QTBUG-68093 -QT_FOR_CONFIG += webenginecore-private +TEMPLATE = subdirs -TARGET = QtWebEngine +qml_module.file = module.pro +qml_plugin.file = plugin/plugin.pro -# For our export macros -DEFINES += QT_BUILD_WEBENGINE_LIB +qml_plugin.depends = qml_module -QT += qml quick webenginecore -QT_PRIVATE += quick-private gui-private core-private webenginecore-private - -QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf - -INCLUDEPATH += $$PWD api ../core ../core/api - -SOURCES = \ - api/qquickwebengineaction.cpp \ - api/qquickwebenginecertificateerror.cpp \ - api/qquickwebenginecontextmenurequest.cpp \ - api/qquickwebenginedialogrequests.cpp \ - api/qquickwebenginedownloaditem.cpp \ - api/qquickwebenginehistory.cpp \ - api/qquickwebenginefaviconprovider.cpp \ - api/qquickwebengineloadrequest.cpp \ - api/qquickwebenginenavigationrequest.cpp \ - api/qquickwebenginenewviewrequest.cpp \ - api/qquickwebengineprofile.cpp \ - api/qquickwebenginescript.cpp \ - api/qquickwebenginesettings.cpp \ - api/qquickwebenginesingleton.cpp \ - api/qquickwebengineview.cpp \ - api/qtwebengineglobal.cpp \ - render_widget_host_view_qt_delegate_quick.cpp \ - render_widget_host_view_qt_delegate_quickwindow.cpp \ - ui_delegates_manager.cpp - -HEADERS = \ - api/qtwebengineglobal.h \ - api/qtwebengineglobal_p.h \ - api/qquickwebengineaction_p.h \ - api/qquickwebengineaction_p_p.h \ - api/qquickwebenginecertificateerror_p.h \ - api/qquickwebenginecontextmenurequest_p.h \ - api/qquickwebenginedialogrequests_p.h \ - api/qquickwebenginedownloaditem_p.h \ - api/qquickwebenginedownloaditem_p_p.h \ - api/qquickwebenginehistory_p.h \ - api/qquickwebenginefaviconprovider_p_p.h \ - api/qquickwebengineloadrequest_p.h \ - api/qquickwebenginenavigationrequest_p.h \ - api/qquickwebenginenewviewrequest_p.h \ - api/qquickwebengineprofile.h \ - api/qquickwebengineprofile_p.h \ - api/qquickwebenginescript.h \ - api/qquickwebenginescript_p.h \ - api/qquickwebenginesettings_p.h \ - api/qquickwebenginesingleton_p.h \ - api/qquickwebengineview_p.h \ - api/qquickwebengineview_p_p.h \ - render_widget_host_view_qt_delegate_quick.h \ - render_widget_host_view_qt_delegate_quickwindow.h \ - ui_delegates_manager.h +SUBDIRS += qml_module qml_plugin qtConfig(webengine-testsupport) { - QT_PRIVATE += testlib - SOURCES += api/qquickwebenginetestsupport.cpp - HEADERS += api/qquickwebenginetestsupport_p.h + testsupport_plugin.file = testsupport/testsupport.pro + testsupport_plugin.depends = qml_module + SUBDIRS += testsupport_plugin } -!build_pass { - python = $$pythonPathForShell() - chromium_attributions.commands = \ - cd $$shell_quote($$shell_path($$PWD/../3rdparty)) && \ - $$python chromium/tools/licenses.py \ - --file-template ../../tools/about_credits.tmpl \ - --entry-template ../../tools/about_credits_entry.tmpl credits \ - $$shell_quote($$shell_path($$OUT_PWD/chromium_attributions.qdoc)) - chromium_attributions.CONFIG += phony - - QMAKE_EXTRA_TARGETS += chromium_attributions - - prepare_docs { - prepare_docs.depends += chromium_attributions - } else { - html_docs.depends += chromium_attributions - } +qtConfig(webengine-ui-delegates) { + SUBDIRS += ui \ + ui2 } - -load(qt_module) |