diff options
Diffstat (limited to 'src/webengine/api')
18 files changed, 1868 insertions, 494 deletions
diff --git a/src/webengine/api/qquickwebenginecertificateerror.cpp b/src/webengine/api/qquickwebenginecertificateerror.cpp index 51a942abe..855e61817 100644 --- a/src/webengine/api/qquickwebenginecertificateerror.cpp +++ b/src/webengine/api/qquickwebenginecertificateerror.cpp @@ -93,7 +93,9 @@ QQuickWebEngineCertificateError::QQuickWebEngineCertificateError(const QSharedPo QQuickWebEngineCertificateError::~QQuickWebEngineCertificateError() { - rejectCertificate(); + Q_D(QQuickWebEngineCertificateError); + if (!d->answered) + rejectCertificate(); } @@ -195,6 +197,9 @@ QUrl QQuickWebEngineCertificateError::url() const \value WebEngineCertificateError.CertificateValidityTooLong The certificate has a validity period that is too long. (Added in 5.7) + \value WebEngineCertificateError.CertificateTransparencyRequired + Certificate Transparency was required for this connection, but the server + did not provide CT information that complied with the policy. (Added in 5.8) */ QQuickWebEngineCertificateError::Error QQuickWebEngineCertificateError::error() const { diff --git a/src/webengine/api/qquickwebenginecertificateerror_p.h b/src/webengine/api/qquickwebenginecertificateerror_p.h index d04dc2c62..27b2efa14 100644 --- a/src/webengine/api/qquickwebenginecertificateerror_p.h +++ b/src/webengine/api/qquickwebenginecertificateerror_p.h @@ -84,6 +84,7 @@ public: CertificateWeakKey = -211, CertificateNameConstraintViolation = -212, CertificateValidityTooLong = -213, + CertificateTransparencyRequired = -214, }; Q_ENUM(Error) diff --git a/src/webengine/api/qquickwebenginecontextmenudata.cpp b/src/webengine/api/qquickwebenginecontextmenudata.cpp deleted file mode 100644 index 2cc6eaf4b..000000000 --- a/src/webengine/api/qquickwebenginecontextmenudata.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "qquickwebenginecontextmenudata_p.h" - -#include "web_contents_adapter_client.h" - -QT_BEGIN_NAMESPACE - -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeNone, QQuickWebEngineContextMenuData::MediaTypeNone) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeImage, QQuickWebEngineContextMenuData::MediaTypeImage) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeAudio, QQuickWebEngineContextMenuData::MediaTypeAudio) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeVideo, QQuickWebEngineContextMenuData::MediaTypeVideo) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeCanvas, QQuickWebEngineContextMenuData::MediaTypeCanvas) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeFile, QQuickWebEngineContextMenuData::MediaTypeFile) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypePlugin, QQuickWebEngineContextMenuData::MediaTypePlugin) - -/*! - \qmltype WebEngineContextMenuData - \instantiates QQuickWebEngineContextMenuData - \inqmlmodule QtWebEngine - \since QtWebEngine 1.3 - \brief Provides context data for populating or extending a context menu with actions. - - - WebEngineContextMenuData is returned by WebEngineView::contextMenuData() after a context menu event, - and contains information about where the context menu event took place. This is also in the context - in which any context specific WebEngineView::WebAction will be performed. -*/ - -QQuickWebEngineContextMenuData::QQuickWebEngineContextMenuData() : d(nullptr) -{ -} - -QQuickWebEngineContextMenuData::~QQuickWebEngineContextMenuData() -{ - delete d; -} - -/*! - \qmlproperty bool WebEngineContextMenuData::isValid - - Is \c true if the context data is valid; otherwise \c false. -*/ -bool QQuickWebEngineContextMenuData::isValid() const -{ - return d; -} - -/*! - \qmlproperty point WebEngineContextMenuData::position - - - Returns the position of the context, usually the mouse position where the context menu event was triggered. -*/ -QPoint QQuickWebEngineContextMenuData::position() const -{ - return d ? d->pos : QPoint(); -} - -/*! - \qmlproperty string WebEngineContextMenuData::linkText - - Returns the text of a link if the context is a link. -*/ -QString QQuickWebEngineContextMenuData::linkText() const -{ - return d ? d->linkText : QString(); -} - -/*! - \qmlproperty url WebEngineContextMenuData::linkUrl - - Returns the URL of a link if the context is a link. -*/ -QUrl QQuickWebEngineContextMenuData::linkUrl() const -{ - return d ? d->linkUrl : QUrl(); -} - -/*! - \qmlproperty string WebEngineContextMenuData::selectedText - - Returns the selected text of the context. -*/ -QString QQuickWebEngineContextMenuData::selectedText() const -{ - return d ? d->selectedText : QString(); -} - -/*! - \qmlproperty url WebEngineContextMenuData::mediaUrl - - If the context is a media element, returns the URL of that media. -*/ -QUrl QQuickWebEngineContextMenuData::mediaUrl() const -{ - return d ? d->mediaUrl : QUrl(); -} - -/*! - \qmlproperty enumeration WebEngineContextMenuData::mediaType - - Returns the type of the media element or \c MediaTypeNone if the context is not a media element. - - \value WebEngineContextMenuData.MediaTypeNone - The context is not a media element. - \value WebEngineContextMenuData.MediaTypeImage - The context is an image element - \value WebEngineContextMenuData.MediaTypeVideo - The context is a video element - \value WebEngineContextMenuData.MediaTypeAudio - The context is an audio element - \value WebEngineContextMenuData.MediaTypeCanvas - The context is a canvas element - \value WebEngineContextMenuData.MediaTypeFile - The context is a file - \value WebEngineContextMenuData.MediaTypePlugin - The context is a plugin -*/ - -QQuickWebEngineContextMenuData::MediaType QQuickWebEngineContextMenuData::mediaType() const -{ - return d ? static_cast<QQuickWebEngineContextMenuData::MediaType>(d->mediaType) : MediaTypeNone; -} - -/*! - \qmlproperty bool WebEngineContextMenuData::isContentEditable - - Returns \c true if the content is editable by the user; otherwise returns \c false. -*/ -bool QQuickWebEngineContextMenuData::isContentEditable() const -{ - return d ? d->isEditable : false; -} - -void QQuickWebEngineContextMenuData::update(const QtWebEngineCore::WebEngineContextMenuData &update) -{ - const QQuickWebEngineContextMenuData old(d); - d = new QtWebEngineCore::WebEngineContextMenuData(update); - - if (isValid() != old.isValid()) - Q_EMIT isValidChanged(); - - if (position() != old.position()) - Q_EMIT positionChanged(); - - if (selectedText() != old.selectedText()) - Q_EMIT selectedTextChanged(); - - if (linkText() != old.linkText()) - Q_EMIT linkTextChanged(); - - if (linkUrl() != old.linkUrl()) - Q_EMIT linkUrlChanged(); - - if (mediaUrl() != old.mediaUrl()) - Q_EMIT mediaUrlChanged(); - - if (mediaType() != old.mediaType()) - Q_EMIT mediaTypeChanged(); - - if (isContentEditable() != old.isContentEditable()) - Q_EMIT isContentEditableChanged(); -} - -QQuickWebEngineContextMenuData::QQuickWebEngineContextMenuData(const QQuickWebEngineContextMenuDataPrivate *p, QObject *parent) - : QObject(parent) - , d(p) -{ -} - -QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginecontextmenurequest.cpp b/src/webengine/api/qquickwebenginecontextmenurequest.cpp new file mode 100644 index 000000000..df57442a1 --- /dev/null +++ b/src/webengine/api/qquickwebenginecontextmenurequest.cpp @@ -0,0 +1,274 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 "qquickwebenginecontextmenurequest_p.h" +#include "web_contents_adapter_client.h" + +QT_BEGIN_NAMESPACE + +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeNone, + QQuickWebEngineContextMenuRequest::MediaTypeNone) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeImage, + QQuickWebEngineContextMenuRequest::MediaTypeImage) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeAudio, + QQuickWebEngineContextMenuRequest::MediaTypeAudio) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeVideo, + QQuickWebEngineContextMenuRequest::MediaTypeVideo) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeCanvas, + QQuickWebEngineContextMenuRequest::MediaTypeCanvas) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeFile, + QQuickWebEngineContextMenuRequest::MediaTypeFile) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypePlugin, + QQuickWebEngineContextMenuRequest::MediaTypePlugin) + +/*! + \qmltype ContextMenuRequest + \instantiates QQuickWebEngineContextMenuRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for showing a context menu. + + A ContextMenuRequest is passed as an argument of the + WebEngineView::contextMenuRequested signal. It provides further + information about the context of the request. The position of the + request origin can be found via the \l x and \l y properties. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default context menu should + be displayed. + + The following code uses a custom menu to handle the request: + + \code + WebEngineView { + id: view + // ... + onContextMenuRequested: function(request) { + request.accepted = true; + myMenu.x = request.x; + myMenu.y = request.y; + myMenu.trigger.connect(view.triggerWebAction); + myMenu.popup(); + } + // ... + } + \endcode +*/ + +QQuickWebEngineContextMenuRequest::QQuickWebEngineContextMenuRequest( + const QtWebEngineCore::WebEngineContextMenuData &data, QObject *parent): + QObject(parent) + , m_data(new QtWebEngineCore::WebEngineContextMenuData(data)) + , m_accepted(false) +{ +} + +QQuickWebEngineContextMenuRequest::~QQuickWebEngineContextMenuRequest() +{ +} + +/*! + \qmlproperty int ContextMenuRequest::x + \readonly + + The x coordinate of the user action from where the context + menu request originates. +*/ + +int QQuickWebEngineContextMenuRequest::x() const +{ + return m_data->position().x(); +} + +/*! + \qmlproperty int ContextMenuRequest::y + \readonly + + The y coordinate of the user action from where the context + menu request originates. +*/ + +int QQuickWebEngineContextMenuRequest::y() const +{ + return m_data->position().y(); +} + +/*! + \qmlproperty string ContextMenuRequest::selectedText + \readonly + + The selected text the context menu was created for. +*/ + +QString QQuickWebEngineContextMenuRequest::selectedText() const +{ + return m_data->selectedText(); +} + +/*! + \qmlproperty string ContextMenuRequest::linkText + \readonly + + The text of the link if the context menu was requested for a link. +*/ + +QString QQuickWebEngineContextMenuRequest::linkText() const +{ + return m_data->linkText(); +} + +/*! + \qmlproperty url ContextMenuRequest::linkUrl + \readonly + + The URL of the link if the selected web page content is a link. +*/ + +QUrl QQuickWebEngineContextMenuRequest::linkUrl() const +{ + return m_data->linkUrl(); +} + +/*! + \qmlproperty url ContextMenuRequest::mediaUrl + \readonly + + The URL of media if the selected web content is a media element. +*/ + +QUrl QQuickWebEngineContextMenuRequest::mediaUrl() const +{ + return m_data->mediaUrl(); +} + +/*! + \qmlproperty enumeration ContextMenuRequest::mediaType + \readonly + + The type of the media element or \c MediaTypeNone if + the selected web page content is not a media element. + + \value ContextMenuRequest.MediaTypeNone + Not a media. + \value ContextMenuRequest.MediaTypeImage + An image. + \value ContextMenuRequest.MediaTypeVideo + A video. + \value ContextMenuRequest.MediaTypeAudio + An audio element. + \value ContextMenuRequest.MediaTypeCanvas + A canvas. + \value ContextMenuRequest.MediaTypeFile + A file. + \value ContextMenuRequest.MediaTypePlugin + A plugin. +*/ + +QQuickWebEngineContextMenuRequest::MediaType QQuickWebEngineContextMenuRequest::mediaType() const +{ + return static_cast<QQuickWebEngineContextMenuRequest::MediaType>(m_data->mediaType()); +} + +/*! + \qmlproperty bool ContextMenuRequest::isContentEditable + \readonly + + Indicates whether the selected web content is editable. +*/ + +bool QQuickWebEngineContextMenuRequest::isContentEditable() const +{ + return m_data->isEditable(); +} + +/*! + \qmlproperty string ContextMenuRequest::misspelledWord + \readonly + + If the context is a word considered misspelled by the spell-checker, + returns the misspelled word. +*/ + +QString QQuickWebEngineContextMenuRequest::misspelledWord() const +{ + return m_data->misspelledWord(); +} + +/*! + \qmlproperty stringlist ContextMenuRequest::spellCheckerSuggestions + \readonly + + If the context is a word considered misspelled by the spell-checker, + returns a list of suggested replacements. +*/ + +QStringList QQuickWebEngineContextMenuRequest::spellCheckerSuggestions() const +{ + return m_data->spellCheckerSuggestions(); +} + +/*! + \qmlproperty bool ContextMenuRequest::accepted + + Indicates whether the context menu request has been + handled by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::contextMenuRequested have been executed, + a default context menu will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. + + \note The default content of the context menu depends on the + web element for which the request was actually generated. +*/ + +bool QQuickWebEngineContextMenuRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineContextMenuRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginecontextmenudata_p.h b/src/webengine/api/qquickwebenginecontextmenurequest_p.h index aa081cbe6..3d2de14a2 100644 --- a/src/webengine/api/qquickwebenginecontextmenudata_p.h +++ b/src/webengine/api/qquickwebenginecontextmenurequest_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QQUICKWEBENGINECONTEXTMENUDATA_P_H -#define QQUICKWEBENGINECONTEXTMENUDATA_P_H +#ifndef QQUICKWEBENGINECONTEXTMENUREQUEST_H +#define QQUICKWEBENGINECONTEXTMENUREQUEST_H // // W A R N I N G @@ -49,30 +49,21 @@ // version without notice, or even be removed. // // We mean it. -// #include <private/qtwebengineglobal_p.h> +#include <QtCore/QScopedPointer> #include <QtCore/QObject> -#include <QtCore/QPoint> -#include <QtCore/QString> #include <QtCore/QUrl> -#include <QtQuick/QQuickItem> namespace QtWebEngineCore { -class WebEngineContextMenuData; + class WebEngineContextMenuData; } QT_BEGIN_NAMESPACE -class QQuickWebEngineView; -class QQuickWebEngineViewPrivate; - -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineContextMenuData : public QObject { +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineContextMenuRequest: public QObject { Q_OBJECT public: - QQuickWebEngineContextMenuData(); - ~QQuickWebEngineContextMenuData(); - enum MediaType { MediaTypeNone, MediaTypeImage, @@ -84,49 +75,41 @@ public: }; Q_ENUM(MediaType) - Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged) - Q_PROPERTY(QPoint position READ position NOTIFY positionChanged) - Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectedTextChanged) - Q_PROPERTY(QString linkText READ linkText NOTIFY linkTextChanged) - Q_PROPERTY(QUrl linkUrl READ linkUrl NOTIFY linkUrlChanged) - Q_PROPERTY(QUrl mediaUrl READ mediaUrl NOTIFY mediaUrlChanged) - Q_PROPERTY(MediaType mediaType READ mediaType NOTIFY mediaTypeChanged) - Q_PROPERTY(bool isContentEditable READ isContentEditable NOTIFY isContentEditableChanged) - - bool isValid() const; - - QPoint position() const; + Q_PROPERTY(int x READ x CONSTANT FINAL) + Q_PROPERTY(int y READ y CONSTANT FINAL) + Q_PROPERTY(QString selectedText READ selectedText CONSTANT FINAL) + Q_PROPERTY(QString linkText READ linkText CONSTANT FINAL) + Q_PROPERTY(QUrl linkUrl READ linkUrl CONSTANT FINAL) + Q_PROPERTY(QUrl mediaUrl READ mediaUrl CONSTANT FINAL) + Q_PROPERTY(MediaType mediaType READ mediaType CONSTANT FINAL) + Q_PROPERTY(bool isContentEditable READ isContentEditable CONSTANT FINAL) + Q_PROPERTY(QString misspelledWord READ misspelledWord CONSTANT FINAL) + Q_PROPERTY(QStringList spellCheckerSuggestions READ spellCheckerSuggestions CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineContextMenuRequest(); + int x() const; + int y() const; QString selectedText() const; QString linkText() const; QUrl linkUrl() const; QUrl mediaUrl() const; MediaType mediaType() const; bool isContentEditable() const; - -Q_SIGNALS: - void isValidChanged(); - void positionChanged(); - void selectedTextChanged(); - void linkTextChanged(); - void linkUrlChanged(); - void mediaUrlChanged(); - void mediaTypeChanged(); - void isContentEditableChanged(); + QString misspelledWord() const; + QStringList spellCheckerSuggestions() const; + bool isAccepted() const; + void setAccepted(bool accepted); private: - void update(const QtWebEngineCore::WebEngineContextMenuData &update); - + QQuickWebEngineContextMenuRequest(const QtWebEngineCore::WebEngineContextMenuData &data, QObject *parent = nullptr); + QScopedPointer<QtWebEngineCore::WebEngineContextMenuData> m_data; + bool m_accepted; friend class QQuickWebEngineView; friend class QQuickWebEngineViewPrivate; - Q_DISABLE_COPY(QQuickWebEngineContextMenuData) - typedef QtWebEngineCore::WebEngineContextMenuData QQuickWebEngineContextMenuDataPrivate; - QQuickWebEngineContextMenuData(const QQuickWebEngineContextMenuDataPrivate *priv, QObject *parent = 0); - QQuickWebEngineContextMenuData &operator=(const QQuickWebEngineContextMenuDataPrivate *priv); - const QQuickWebEngineContextMenuDataPrivate *d; + Q_DISABLE_COPY(QQuickWebEngineContextMenuRequest) }; QT_END_NAMESPACE -QML_DECLARE_TYPE(const QQuickWebEngineContextMenuData); - -#endif // QQUICKWEBENGINECONTEXTMENUDATA_P_H +#endif // QQUICKWEBENGINECONTEXTMENUREQUEST_H diff --git a/src/webengine/api/qquickwebenginedialogrequests.cpp b/src/webengine/api/qquickwebenginedialogrequests.cpp new file mode 100644 index 000000000..641793e12 --- /dev/null +++ b/src/webengine/api/qquickwebenginedialogrequests.cpp @@ -0,0 +1,856 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 "qquickwebenginedialogrequests_p.h" +#include "authentication_dialog_controller.h" +#include "javascript_dialog_controller.h" +#include "color_chooser_controller.h" +#include "file_picker_controller.h" +#include "web_contents_adapter_client.h" + +QT_BEGIN_NAMESPACE + +using namespace QtWebEngineCore; + +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::AlertDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypeAlert) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::ConfirmDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypeConfirm) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::PromptDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypePrompt) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::UnloadDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypeBeforeUnload) + +ASSERT_ENUMS_MATCH(FilePickerController::Open, + QQuickWebEngineFileDialogRequest::FileModeOpen) +ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, + QQuickWebEngineFileDialogRequest::FileModeOpenMultiple) +ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, + QQuickWebEngineFileDialogRequest::FileModeUploadFolder) +ASSERT_ENUMS_MATCH(FilePickerController::Save, + QQuickWebEngineFileDialogRequest::FileModeSave) + +/*! + \qmltype AuthenticationDialogRequest + \instantiates QQuickWebEngineAuthenticationDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for providing authentication credentials required + by proxies or HTTP servers. + + An AuthenticationDialogRequest is passed as an argument of the + WebEngineView::authenticationDialogRequested signal. It is generated + when basic HTTP or proxy authentication is required. The type + of authentication can be checked with the \l type property. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call + either \l dialogAccept() or \l dialogReject() afterwards. + + The following code uses a custom dialog to handle the request: + \code + + WebEngineView { + // ... + onAuthenticationDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + + \endcode +*/ + +QQuickWebEngineAuthenticationDialogRequest::QQuickWebEngineAuthenticationDialogRequest( + QSharedPointer<AuthenticationDialogController> controller, + QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_url(controller->url()) + , m_realm(controller->realm()) + , m_type(controller->isProxy() ? AuthenticationTypeProxy + : AuthenticationTypeHTTP) + , m_host(controller->host()) + , m_accepted(false) +{ + +} + +QQuickWebEngineAuthenticationDialogRequest::~QQuickWebEngineAuthenticationDialogRequest() +{ +} + +/*! + \qmlproperty url AuthenticationDialogRequest::url + \readonly + + The URL of the HTTP request for which authentication was requested. + In case of proxy authentication, this is a request URL which is proxied + via host. + + \sa proxyHost +*/ + +QUrl QQuickWebEngineAuthenticationDialogRequest::url() const +{ + return m_url; +} + +/*! + \qmlproperty string AuthenticationDialogRequest::realm + \readonly + + The HTTP authentication realm attribute value of the \c WWW-Authenticate + header. Empty if \l type is AuthenticationTypeProxy. +*/ + +QString QQuickWebEngineAuthenticationDialogRequest::realm() const +{ + return m_realm; +} + +/*! + \qmlproperty string AuthenticationDialogRequest::proxyHost + \readonly + + The hostname of the authentication proxy. + Empty if \l type is AuthenticationTypeHTTP. +*/ + +QString QQuickWebEngineAuthenticationDialogRequest::proxyHost() const +{ + return m_host; +} + +/*! + \qmlproperty enumeration AuthenticationDialogRequest::type + \readonly + + The type of the authentication request. + + \value WebEngineAuthenticationDialogRequest.AuthenticationTypeHTTP + HTTP authentication. + \value WebEngineAuthenticationDialogRequest.AuthenticationTypeProxy + Proxy authentication. +*/ + +QQuickWebEngineAuthenticationDialogRequest::AuthenticationType +QQuickWebEngineAuthenticationDialogRequest::type() const +{ + return m_type; +} + +/*! + \qmlproperty bool AuthenticationDialogRequest::accepted + + Indicates whether the authentication dialog request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::authenticationDialogRequested have been executed, + a default authentication dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineAuthenticationDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineAuthenticationDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +/*! + \qmlmethod void AuthenticationDialogRequest::dialogAccept(string username, string password) + + This function notifies the engine that the user accepted the dialog, + providing the \a username and the \a password required for authentication. +*/ + +void QQuickWebEngineAuthenticationDialogRequest::dialogAccept(const QString &user, + const QString &password) +{ + m_accepted = true; + QSharedPointer<AuthenticationDialogController> controller + = m_controller.toStrongRef(); + if (controller) + controller->accept(user,password); +} + +/*! + \qmlmethod void AuthenticationDialogRequest::dialogReject() + + This function notifies the engine that the user rejected the dialog and the + authentication shall not proceed. +*/ + +void QQuickWebEngineAuthenticationDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<AuthenticationDialogController> controller + = m_controller.toStrongRef(); + if (controller) + controller->reject(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype JavaScriptDialogRequest + \instantiates QQuickWebEngineJavaScriptDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for showing an alert, a confirmation, or a prompt dialog + from within JavaScript to the user. + + A JavaScriptDialogRequest is passed as an argument of the + WebEngineView::javaScriptDialogRequested signal. The request is emitted + if JavaScript on the page calls HTML5's + \l{https://www.w3.org/TR/html5/webappapis.html#simple-dialogs}{Simple Dialogs} + API, or in response to HTML5's + \l {https://www.w3.org/TR/html5/browsers.html#beforeunloadevent}{BeforeUnloadEvent}. + The type of a particular dialog can be checked with the \l type property. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call either + \l dialogAccept() or \l dialogReject() afterwards. The JavaScript call + causing the request will be blocked until then. + + The following code uses a custom dialog to handle the request: + + \code + WebEngineView { + // ... + onJavaScriptDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + \endcode +*/ + +QQuickWebEngineJavaScriptDialogRequest::QQuickWebEngineJavaScriptDialogRequest( + QSharedPointer<JavaScriptDialogController> controller, QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_message(controller->message()) + , m_defaultPrompt(controller->defaultPrompt()) + , m_title(controller->title()) + , m_type(static_cast<QQuickWebEngineJavaScriptDialogRequest::DialogType>(controller->type())) + , m_securityOrigin(controller->securityOrigin()) + , m_accepted(false) +{ +} + +QQuickWebEngineJavaScriptDialogRequest::~QQuickWebEngineJavaScriptDialogRequest() +{ + +} + +/*! + \qmlproperty string JavaScriptDialogRequest::message + \readonly + + The message to be shown to the user. +*/ + +QString QQuickWebEngineJavaScriptDialogRequest::message() const +{ + return m_message; +} + +/*! + \qmlproperty string JavaScriptDialogRequest::defaultPrompt + \readonly + + The default text if the requested dialog box is of + the \l type PromptDialog. +*/ + + +QString QQuickWebEngineJavaScriptDialogRequest::defaultText() const +{ + return m_defaultPrompt; +} + +/*! + \qmlproperty string JavaScriptDialogRequest::title + \readonly + + A default title for the dialog. +*/ + +QString QQuickWebEngineJavaScriptDialogRequest::title() const +{ + return m_title; +} + +/*! + \qmlproperty enumeration JavaScriptDialogRequest::type + \readonly + + Returns the type of the requested dialog box, see HTML5's + + \l{https://www.w3.org/TR/html5/webappapis.html#simple-dialogs}{Simple Dialogs}. + + \value JavaScriptDialogRequest.DialogTypeAlert + A JavaScript alert dialog. + \value JavaScriptDialogRequest.DialogTypeConfirm + A JavaScript confirmation dialog. + \value JavaScriptDialogRequest.DialogTypePrompt + A JavaScript prompt dialog. + \value JavaScriptDialogRequest.DialogTypeUnload + The users should be asked if they want to leave the page. +*/ + +QQuickWebEngineJavaScriptDialogRequest::DialogType QQuickWebEngineJavaScriptDialogRequest::type() const +{ + return m_type; +} + +/*! + \qmlproperty url JavaScriptDialogRequest::securityOrigin + \readonly + + The URL of the security origin. +*/ + +QUrl QQuickWebEngineJavaScriptDialogRequest::securityOrigin() const +{ + return m_securityOrigin; +} + +/*! + \qmlproperty bool JavaScriptDialogRequest::accepted + + Indicates whether the JavaScript dialog request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::javaScriptDialogRequested have been executed, + a default dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineJavaScriptDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineJavaScriptDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +/*! + \qmlmethod void JavaScriptDialogRequest::dialogAccept() + + This function notifies the engine that the user accepted the dialog. +*/ + +/*! + \qmlmethod void JavaScriptDialogRequest::dialogAccept(string text) + + This function notifies the engine that the user accepted the dialog, + providing the \a text in case of a prompt message box. +*/ + +void QQuickWebEngineJavaScriptDialogRequest::dialogAccept(const QString& text) +{ + m_accepted = true; + QSharedPointer<JavaScriptDialogController> controller + = m_controller.toStrongRef(); + if (controller) { + controller->textProvided(text); + controller->accept(); + } +} + +/*! + \qmlmethod void JavaScriptDialogRequest::dialogReject() + + This function notifies the engine that the user rejected the dialog. +*/ + +void QQuickWebEngineJavaScriptDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<JavaScriptDialogController> controller + = m_controller.toStrongRef(); + if (controller) + controller->reject(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype ColorDialogRequest + \instantiates QQuickWebEngineColorDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for selecting a color by the user. + + A ColorDialogRequest is passed as an argument of the + WebEngineView::colorDialogRequested signal. It is generated when + a color picker dialog is requested. See + \l { https://www.w3.org/TR/html5/forms.html#color-state-(type=color)} + {HTML5 Color State}. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call either + \l dialogAccept() or \l dialogReject() afterwards. + + The following code uses a custom dialog to handle the request: + + \code + WebEngineView { + // ... + onColorDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + \endcode +*/ + +QQuickWebEngineColorDialogRequest::QQuickWebEngineColorDialogRequest( + QSharedPointer<ColorChooserController> controller, QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_color(controller->initialColor()) + , m_accepted(false) +{ + +} + +QQuickWebEngineColorDialogRequest::~QQuickWebEngineColorDialogRequest() +{ + +} + +/*! + \qmlproperty color ColorDialogRequest::color + \readonly + + The default color to be selected in the dialog. +*/ + +QColor QQuickWebEngineColorDialogRequest::color() const +{ + return m_color; +} + +/*! + \qmlproperty bool ColorDialogRequest::accepted + + Indicates whether the color picker dialog request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::colorDialogRequested have been executed, + a default color picker dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineColorDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineColorDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + + +/*! + \qmlmethod void ColorDialogRequest::dialogAccept(color color) + + This function notifies the engine that the user accepted the dialog, + providing the \a color. +*/ + +void QQuickWebEngineColorDialogRequest::dialogAccept(const QColor &color) +{ + m_accepted = true; + QSharedPointer<ColorChooserController> controller = m_controller.toStrongRef(); + if (controller) + controller->accept(color); +} + +/*! + \qmlmethod void ColorDialogRequest::dialogReject() + + This function notifies the engine that the user rejected the dialog. +*/ + +void QQuickWebEngineColorDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<ColorChooserController> controller = m_controller.toStrongRef(); + if (controller) + controller->reject(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype FileDialogRequest + \instantiates QQuickWebEngineFileDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for letting the user choose a (new or existing) file or + directory. + + A FileDialogRequest is passed as an argument of the + WebEngineView::fileDialogRequested signal. It is generated + when the file dialog is requested by the input element. + See \l {https://www.w3.org/TR/html5/forms.html#file-upload-state-(type=file)}{File Upload state}. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call either + \l dialogAccept() or \l dialogReject() afterwards. + + The following code uses a custom dialog to handle the request: + + \code + WebEngineView { + // ... + onFileDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + \endcode +*/ + +QQuickWebEngineFileDialogRequest::QQuickWebEngineFileDialogRequest( + QSharedPointer<FilePickerController> controller, QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_filename(controller->defaultFileName()) + , m_acceptedMimeTypes(controller->acceptedMimeTypes()) + , m_mode(static_cast<QQuickWebEngineFileDialogRequest::FileMode>(controller->mode())) + , m_accepted(false) +{ + +} + +QQuickWebEngineFileDialogRequest::~QQuickWebEngineFileDialogRequest() +{ + +} + +/*! + \qmlproperty stringlist FileDialogRequest::acceptedMimeTypes + \readonly + + A list of MIME types specified in the input element. The selection + should be restricted to only these types of files. +*/ + +QStringList QQuickWebEngineFileDialogRequest::acceptedMimeTypes() const +{ + return m_acceptedMimeTypes; +} + +/*! + \qmlproperty string FileDialogRequest::defaultFileName + \readonly + + The default name of the file to be selected in the dialog. +*/ + +QString QQuickWebEngineFileDialogRequest::defaultFileName() const +{ + return m_filename; +} + +/*! + \qmlproperty enumeration FileDialogRequest::mode + \readonly + + The mode of the file dialog. + + \value FileDialogRequest.FileModeOpen + Allows users to specify a single existing file. + \value FileDialogRequest.FileModeOpenMultiple + Allows users to specify multiple existing files. + \value FileDialogRequest.FileModeUploadFolder + Allows users to specify a single existing folder for upload. + \value FileDialogRequest.FileModeSave + Allows users to specify a non-existing file. If an existing file + is selected, the users should be informed that the file is going + to be overwritten. +*/ + +QQuickWebEngineFileDialogRequest::FileMode QQuickWebEngineFileDialogRequest::mode() const +{ + return m_mode; +} + +/*! + \qmlproperty bool FileDialogRequest::accepted + + Indicates whether the file picker dialog request has been + handled by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::fileDialogRequested have been executed, + a default file picker dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineFileDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineFileDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +/*! + \qmlmethod void FileDialogRequest::dialogAccept(stringlist files) + + This function needs to be called when the user accepted the dialog with + \a files. +*/ + +void QQuickWebEngineFileDialogRequest::dialogAccept(const QStringList &files) +{ + m_accepted = true; + QSharedPointer<FilePickerController> controller = m_controller.toStrongRef(); + if (controller) + controller->accepted(files); +} + +/*! + \qmlmethod void FileDialogRequest::dialogReject() + + This function needs to be called when the user did not accepted the dialog. +*/ + +void QQuickWebEngineFileDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<FilePickerController> controller = m_controller.toStrongRef(); + if (controller) + controller->rejected(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype FormValidationMessageRequest + \instantiates QQuickWebEngineFormValidationMessageRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for showing a HTML5 form validation message to the user. + + A FormValidationMessageRequest is passed as an argument of the + WebEngineView::formValidationMessageRequested signal. It is generated when + the handling of the validation message is requested. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default message should be displayed. + + The following code uses a custom message to handle the request: + + \code + WebEngineView { + // ... + onFormValidationMessageRequested: function(request) { + request.accepted = true; + switch (request.type) { + case FormValidationMessageRequest.Show: + validationMessage.text = request.text; + validationMessage.x = request.x; + validationMessage.y = request.y + validationMessage.visible = true; + break; + case FormValidationMessageRequest.Move: + break; + case FormValidationMessageRequest.Hide: + validationMessage.visible = false; + break; + } + } + // ... + } + \endcode +*/ + +QQuickWebEngineFormValidationMessageRequest::QQuickWebEngineFormValidationMessageRequest( + QQuickWebEngineFormValidationMessageRequest::RequestType type, const QRect& anchor, + const QString &mainText, const QString &subText, QObject *parent): + QObject(parent) + , m_anchor(anchor) + , m_mainText(mainText) + , m_subText(subText) + , m_type(type) + , m_accepted(false) +{ + +} + +QQuickWebEngineFormValidationMessageRequest::~QQuickWebEngineFormValidationMessageRequest() +{ + +} + +/*! + \qmlproperty rectangle FormValidationMessageRequest::anchor + \readonly + + An anchor of an element in the viewport for which the form + validation message should be displayed. +*/ + +QRect QQuickWebEngineFormValidationMessageRequest::anchor() const +{ + return m_anchor; +} + +/*! + \qmlproperty bool FormValidationMessageRequest::text + \readonly + + The text of the form validation message. +*/ + + +QString QQuickWebEngineFormValidationMessageRequest::text() const +{ + return m_mainText; +} + +/*! + \qmlproperty bool FormValidationMessageRequest::subText + \readonly + + The subtext of the form validation message. +*/ + + +QString QQuickWebEngineFormValidationMessageRequest::subText() const +{ + return m_subText; +} + +/*! + \qmlproperty enumeration ValidationMessageRequest::type + \readonly + + The type of the form validation message request. + + \value ValidationMessageRequest.Show + The form validation message should be shown. + \value ValidationMessageRequest.Hide + The form validation message should be hidden. + \value ValidationMessageRequest.Move + The form validation message should be moved. +*/ + +QQuickWebEngineFormValidationMessageRequest::RequestType QQuickWebEngineFormValidationMessageRequest::type() const +{ + return m_type; +} + +/*! + \qmlproperty bool FormValidationMessageRequest::accepted + + Indicates whether the form validation request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::validationMessageRequested have been executed, + a default file validation message will be shown. + To prevent this, set \c {request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineFormValidationMessageRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineFormValidationMessageRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginedialogrequests_p.h b/src/webengine/api/qquickwebenginedialogrequests_p.h new file mode 100644 index 000000000..d8a0e004c --- /dev/null +++ b/src/webengine/api/qquickwebenginedialogrequests_p.h @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 QQUICKWEBENGINDIALOGREQUESTS_H +#define QQUICKWEBENGINDIALOGREQUESTS_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 <private/qtwebengineglobal_p.h> +#include <QtCore/QUrl> +#include <QtCore/QWeakPointer> +#include <QtCore/QRect> +#include <QtGui/QColor> + +namespace QtWebEngineCore { + class AuthenticationDialogController; + class ColorChooserController; + class FilePickerController; + class JavaScriptDialogController; +} + +QT_BEGIN_NAMESPACE + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineAuthenticationDialogRequest : public QObject { + Q_OBJECT +public: + + enum AuthenticationType { + AuthenticationTypeHTTP, + AuthenticationTypeProxy + }; + + Q_ENUM(AuthenticationType) + + Q_PROPERTY(QUrl url READ url CONSTANT FINAL) + Q_PROPERTY(QString realm READ realm CONSTANT FINAL) + Q_PROPERTY(QString proxyHost READ proxyHost CONSTANT FINAL) + Q_PROPERTY(AuthenticationType type READ type CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineAuthenticationDialogRequest(); + + QUrl url() const; + QString realm() const; + QString proxyHost() const; + AuthenticationType type() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QString &user, const QString &password); + void dialogReject(); + +private: + QQuickWebEngineAuthenticationDialogRequest(QSharedPointer<QtWebEngineCore::AuthenticationDialogController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::AuthenticationDialogController> m_controller; + QUrl m_url; + QString m_realm; + AuthenticationType m_type; + QString m_host; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineAuthenticationDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineJavaScriptDialogRequest : public QObject { + Q_OBJECT +public: + + enum DialogType { + DialogTypeAlert, + DialogTypeConfirm, + DialogTypePrompt, + DialogTypeBeforeUnload, + }; + Q_ENUM(DialogType) + + Q_PROPERTY(QString message READ message CONSTANT FINAL) + Q_PROPERTY(QString defaultText READ defaultText CONSTANT FINAL) + Q_PROPERTY(QString title READ title CONSTANT FINAL) + Q_PROPERTY(DialogType type READ type CONSTANT FINAL) + Q_PROPERTY(QUrl securityOrigin READ securityOrigin CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineJavaScriptDialogRequest(); + + QString message() const; + QString defaultText() const; + QString title() const; + DialogType type() const; + QUrl securityOrigin() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QString& text = QString()); + void dialogReject(); + +private: + QQuickWebEngineJavaScriptDialogRequest(QSharedPointer<QtWebEngineCore::JavaScriptDialogController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::JavaScriptDialogController> m_controller; + QString m_message; + QString m_defaultPrompt; + QString m_title; + DialogType m_type; + QUrl m_securityOrigin; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineJavaScriptDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineColorDialogRequest : public QObject { + Q_OBJECT +public: + + Q_PROPERTY(QColor color READ color CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineColorDialogRequest(); + + QColor color() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QColor &color); + void dialogReject(); + +private: + QQuickWebEngineColorDialogRequest(QSharedPointer<QtWebEngineCore::ColorChooserController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::ColorChooserController> m_controller; + QColor m_color; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineColorDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFileDialogRequest : public QObject { + Q_OBJECT +public: + + enum FileMode { + FileModeOpen, + FileModeOpenMultiple, + FileModeUploadFolder, + FileModeSave + }; + Q_ENUM(FileMode) + + Q_PROPERTY(QString defaultFileName READ defaultFileName CONSTANT FINAL) + Q_PROPERTY(QStringList acceptedMimeTypes READ acceptedMimeTypes CONSTANT FINAL) + Q_PROPERTY(FileMode mode READ mode CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineFileDialogRequest(); + + QStringList acceptedMimeTypes() const; + QString defaultFileName() const; + FileMode mode() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QStringList &files); + void dialogReject(); + +private: + QQuickWebEngineFileDialogRequest(QSharedPointer<QtWebEngineCore::FilePickerController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::FilePickerController> m_controller; + QString m_filename; + QStringList m_acceptedMimeTypes; + FileMode m_mode; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineFileDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFormValidationMessageRequest : public QObject { + Q_OBJECT +public: + enum RequestType { + Show, + Hide, + Move, + }; + Q_ENUM(RequestType) + Q_PROPERTY(QRect anchor READ anchor CONSTANT FINAL) + Q_PROPERTY(QString text READ text CONSTANT FINAL) + Q_PROPERTY(QString subText READ subText CONSTANT FINAL) + Q_PROPERTY(RequestType type READ type CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineFormValidationMessageRequest(); + QRect anchor() const; + QString text() const; + QString subText() const; + RequestType type() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +private: + QQuickWebEngineFormValidationMessageRequest(RequestType type, const QRect &anchor = QRect(), + const QString &mainText = QString(), + const QString &subText = QString(), + QObject *parent = nullptr); + QRect m_anchor; + QString m_mainText; + QString m_subText; + RequestType m_type; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; +}; + +QT_END_NAMESPACE + +#endif // QQUICKWEBENGINDIALOGREQUESTS_H diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp index 9f0c747f9..8bf319b85 100644 --- a/src/webengine/api/qquickwebenginedownloaditem.cpp +++ b/src/webengine/api/qquickwebenginedownloaditem.cpp @@ -66,6 +66,7 @@ QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWeb , downloadId(-1) , downloadState(QQuickWebEngineDownloadItem::DownloadCancelled) , savePageFormat(QQuickWebEngineDownloadItem::UnknownSaveFormat) + , type(QQuickWebEngineDownloadItem::Attachment) , totalBytes(-1) , receivedBytes(0) { @@ -299,6 +300,32 @@ void QQuickWebEngineDownloadItem::setSavePageFormat(QQuickWebEngineDownloadItem: } } +/*! + \qmlproperty enumeration WebEngineDownloadItem::type + \readonly + \since QtWebEngine 1.4 + + Describes the requested download's type. + + \value WebEngineDownloadItem.Attachment The web server's response includes a + \c Content-Disposition header with the \c attachment directive. If \c Content-Disposition + is present in the reply, the web server is indicating that the client should prompt the + user to save the content regardless of the content type. + See \l {RFC 2616 section 19.5.1} for details. + \value WebEngineDownloadItem.DownloadAttribute The user clicked a link with the \c download + attribute. See \l {HTML download attribute} for details. + \value WebEngineDownloadItem.UserRequested The user initiated the download, for example by + selecting a web action. + \value WebEngineDownloadItem.SavePage Saving of the current page was requested (for example by + the \l{WebEngineView::WebAction}{WebEngineView.SavePage} web action). + */ + +QQuickWebEngineDownloadItem::DownloadType QQuickWebEngineDownloadItem::type() const +{ + Q_D(const QQuickWebEngineDownloadItem); + return d->type; +} + QQuickWebEngineDownloadItem::QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate *p, QObject *parent) : QObject(parent) , d_ptr(p) diff --git a/src/webengine/api/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h index 0b01fe6fc..61e019b9e 100644 --- a/src/webengine/api/qquickwebenginedownloaditem_p.h +++ b/src/webengine/api/qquickwebenginedownloaditem_p.h @@ -82,6 +82,14 @@ public: }; Q_ENUM(SavePageFormat) + enum DownloadType { + Attachment = 0, + DownloadAttribute, + UserRequested, + SavePage + }; + Q_ENUM(DownloadType) + Q_PROPERTY(quint32 id READ id CONSTANT FINAL) Q_PROPERTY(DownloadState state READ state NOTIFY stateChanged) Q_PROPERTY(SavePageFormat savePageFormat READ savePageFormat WRITE setSavePageFormat NOTIFY savePageFormatChanged REVISION 2 FINAL) @@ -89,6 +97,7 @@ public: Q_PROPERTY(qint64 receivedBytes READ receivedBytes NOTIFY receivedBytesChanged) Q_PROPERTY(QString mimeType READ mimeType NOTIFY mimeTypeChanged REVISION 1) Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) + Q_PROPERTY(DownloadType type READ type NOTIFY typeChanged REVISION 3 FINAL) Q_INVOKABLE void accept(); Q_INVOKABLE void cancel(); @@ -102,6 +111,7 @@ public: void setPath(QString path); SavePageFormat savePageFormat() const; void setSavePageFormat(SavePageFormat format); + DownloadType type() const; Q_SIGNALS: void stateChanged(); @@ -110,6 +120,7 @@ Q_SIGNALS: void totalBytesChanged(); Q_REVISION(1) void mimeTypeChanged(); void pathChanged(); + Q_REVISION(3) void typeChanged(); private: QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate*, QObject *parent = 0); diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h index bdae54ca4..1789af462 100644 --- a/src/webengine/api/qquickwebenginedownloaditem_p_p.h +++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h @@ -73,6 +73,7 @@ public: quint32 downloadId; QQuickWebEngineDownloadItem::DownloadState downloadState; QQuickWebEngineDownloadItem::SavePageFormat savePageFormat; + QQuickWebEngineDownloadItem::DownloadType type; qint64 totalBytes; qint64 receivedBytes; QString mimeType; diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index d660f639d..871428f33 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -85,6 +85,10 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineDownloadItem::MimeHtmlSaveFormat, QtWebEngineC QQuickWebEngineProfile class, which exposes further functionality in C++. This allows Qt Quick applications to intercept URL requests (QQuickWebEngineProfile::setRequestInterceptor), or register custom URL schemes (QQuickWebEngineProfile::installUrlSchemeHandler). + + Spellchecking HTML form fields can be enabled per profile by setting the \l spellCheckEnabled + property and the current languages used for spellchecking can be set by using the + \l spellCheckLanguages property. */ /*! @@ -180,6 +184,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) itemPrivate->downloadPath = info.path; itemPrivate->savePageFormat = static_cast<QQuickWebEngineDownloadItem::SavePageFormat>( info.savePageFormat); + itemPrivate->type = static_cast<QQuickWebEngineDownloadItem::DownloadType>(info.downloadType); QQuickWebEngineDownloadItem *download = new QQuickWebEngineDownloadItem(itemPrivate, q); @@ -613,6 +618,105 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() } /*! + \property QQuickWebEngineProfile::spellCheckLanguages + \brief The languages used by the spell checker. + + \since QtWebEngine 1.4 +*/ + +/*! + \qmlproperty list<string> WebEngineProfile::spellCheckLanguages + + This property holds the list of languages used by the spell checker. + Each language should match the name of the \c .bdic dictionary. + For example, the language \c en-US will load the \c en-US.bdic + dictionary file. + + Qt WebEngine checks for the \c qtwebengine_dictionaries subdirectory + first in the local directory and if it is not found, in the Qt + installation directory. + + On macOS, depending on how Qt WebEngine is configured at build time, there are two possibilities + how spellchecking data is found: + + \list + \li Hunspell dictionaries (default) - .bdic dictionaries are used, just like on other + platforms + \li Native dictionaries - the macOS spellchecking APIs are used (which means the results + will depend on the installed OS dictionaries) + \endlist + + Thus, in the macOS Hunspell case, Qt WebEngine will look in the \e qtwebengine_dictionaries + subdirectory located inside the application bundle \c Resources directory, and also in the + \c Resources directory located inside the Qt framework bundle. + + To summarize, in case of Hunspell usage, the following paths are considered: + + \list + \li QCoreApplication::applicationDirPath()/qtwebengine_dictionaries + or QCoreApplication::applicationDirPath()/../Contents/Resources/qtwebengine_dictionaries + (on macOS) + \li [QLibraryInfo::DataPath]/qtwebengine_dictionaries + or path/to/QtWebEngineCore.framework/Resources/qtwebengine_dictionaries (Qt framework + bundle on macOS) + \endlist + + For more information about how to compile \c .bdic dictionaries, see the + \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}. + + \since QtWebEngine 1.4 +*/ +void QQuickWebEngineProfile::setSpellCheckLanguages(const QStringList &languages) +{ + Q_D(QQuickWebEngineProfile); + if (languages != d->browserContext()->spellCheckLanguages()) { + d->browserContext()->setSpellCheckLanguages(languages); + emit spellCheckLanguagesChanged(); + } +} + +/*! + \since 5.8 + + Returns the list of languages used by the spell checker. +*/ +QStringList QQuickWebEngineProfile::spellCheckLanguages() const +{ + const Q_D(QQuickWebEngineProfile); + return d->browserContext()->spellCheckLanguages(); +} + +/*! + \property QQuickWebEngineProfile::spellCheckEnabled + \brief whether the web engine spell checker is enabled. + + \since QtWebEngine 1.4 +*/ + +/*! + \qmlproperty bool WebEngineProfile::spellCheckEnabled + + This property holds whether the web engine spell checker is enabled. + + \since QtWebEngine 1.4 +*/ +void QQuickWebEngineProfile::setSpellCheckEnabled(bool enable) +{ + Q_D(QQuickWebEngineProfile); + if (enable != isSpellCheckEnabled()) { + d->browserContext()->setSpellCheckEnabled(enable); + emit spellCheckEnabledChanged(); + } +} + +bool QQuickWebEngineProfile::isSpellCheckEnabled() const +{ + const Q_D(QQuickWebEngineProfile); + return d->browserContext()->isSpellCheckEnabled(); +} + +/*! + Returns the cookie store for this profile. */ QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h index dc5aa7df8..d0d925930 100644 --- a/src/webengine/api/qquickwebengineprofile.h +++ b/src/webengine/api/qquickwebengineprofile.h @@ -71,6 +71,8 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL REVISION 1) Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL) Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL) + 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) public: QQuickWebEngineProfile(QObject *parent = Q_NULLPTR); @@ -129,6 +131,11 @@ public: Q_REVISION(2) Q_INVOKABLE void clearHttpCache(); + void setSpellCheckLanguages(const QStringList &languages); + QStringList spellCheckLanguages() const; + void setSpellCheckEnabled(bool enabled); + bool isSpellCheckEnabled() const; + static QQuickWebEngineProfile *defaultProfile(); Q_SIGNALS: @@ -141,6 +148,8 @@ Q_SIGNALS: void persistentCookiesPolicyChanged(); void httpCacheMaximumSizeChanged(); Q_REVISION(1) void httpAcceptLanguageChanged(); + Q_REVISION(3) void spellCheckLanguagesChanged(); + Q_REVISION(3) void spellCheckEnabledChanged(); void downloadRequested(QQuickWebEngineDownloadItem *download); void downloadFinished(QQuickWebEngineDownloadItem *download); diff --git a/src/webengine/api/qquickwebenginescript.cpp b/src/webengine/api/qquickwebenginescript.cpp index 7e08e2fd5..5d5173144 100644 --- a/src/webengine/api/qquickwebenginescript.cpp +++ b/src/webengine/api/qquickwebenginescript.cpp @@ -44,7 +44,7 @@ #include <QtCore/QDebug> #include <QtCore/QFile> #include <QtCore/QTimerEvent> -#include "user_resource_controller_host.h" +#include "renderer_host/user_resource_controller_host.h" using QtWebEngineCore::UserScript; @@ -65,7 +65,8 @@ using QtWebEngineCore::UserScript; not accessible from a different one. The worldId property provides some predefined IDs for this purpose. - \note Chromium extensions, such as \c @include, \c @match, and \c @exclude, are not supported. + The following \l Greasemonkey attributes are supported since Qt 5.8: + \c @exclude, \c @include, \c @name, \c @match, and \c @run-at. Use \l{WebEngineView::userScripts}{WebEngineView.userScripts} to access a list of scripts attached to the web view. diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp index b12e59576..09bf2708e 100644 --- a/src/webengine/api/qquickwebenginesettings.cpp +++ b/src/webengine/api/qquickwebenginesettings.cpp @@ -304,6 +304,49 @@ bool QQuickWebEngineSettings::touchIconsEnabled() const } /*! + \qmlproperty bool WebEngineSettings::focusOnNavigationEnabled + \since QtWebEngine 1.4 + + Focus is given to the view whenever a navigation operation occurs + (load, stop, reload, reload and bypass cache, forward, backward, set content, and so on). + + Enabled by default. See \l{WebEngine Recipe Browser} for an example where + this property is disabled. +*/ +bool QQuickWebEngineSettings::focusOnNavigationEnabled() const +{ + return d_ptr->testAttribute(WebEngineSettings::FocusOnNavigationEnabled); +} + +/*! + \qmlproperty bool WebEngineSettings::printElementBackgrounds + \since QtWebEngine 1.4 + + Turns on printing of CSS backgrounds when printing a web page. + + Enabled by default. +*/ +bool QQuickWebEngineSettings::printElementBackgrounds() const +{ + return d_ptr->testAttribute(WebEngineSettings::PrintElementBackgrounds); +} + +/*! + \qmlproperty bool WebEngineSettings::allowRunningInsecureContent + \since QtWebEngine 1.4 + + By default, HTTPS pages cannot run JavaScript, CSS, plugins or + web-sockets from HTTP URLs. This used to be possible and this + provides an override to get the old behavior. + + Disabled by default. +*/ +bool QQuickWebEngineSettings::allowRunningInsecureContent() const +{ + return d_ptr->testAttribute(WebEngineSettings::AllowRunningInsecureContent); +} + +/*! \qmlproperty string WebEngineSettings::defaultTextEncoding \since QtWebEngine 1.2 @@ -464,6 +507,14 @@ void QQuickWebEngineSettings::setTouchIconsEnabled(bool on) Q_EMIT touchIconsEnabledChanged(); } +void QQuickWebEngineSettings::setPrintElementBackgrounds(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::PrintElementBackgrounds); + d_ptr->setAttribute(WebEngineSettings::PrintElementBackgrounds, on); + if (wasOn != on) + Q_EMIT printElementBackgroundsChanged(); +} + void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding) { const QString oldDefaultTextEncoding = d_ptr->defaultTextEncoding(); @@ -472,6 +523,23 @@ void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding) Q_EMIT defaultTextEncodingChanged(); } +void QQuickWebEngineSettings::setFocusOnNavigationEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::FocusOnNavigationEnabled); + d_ptr->setAttribute(WebEngineSettings::FocusOnNavigationEnabled, on); + if (wasOn != on) + Q_EMIT focusOnNavigationEnabledChanged(); +} + + +void QQuickWebEngineSettings::setAllowRunningInsecureContent(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::AllowRunningInsecureContent); + d_ptr->setAttribute(WebEngineSettings::AllowRunningInsecureContent, on); + if (wasOn != on) + Q_EMIT allowRunningInsecureContentChanged(); +} + void QQuickWebEngineSettings::setParentSettings(QQuickWebEngineSettings *parentSettings) { d_ptr->setParentSettings(parentSettings->d_ptr.data()); diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h index 584027260..a53c7cdb3 100644 --- a/src/webengine/api/qquickwebenginesettings_p.h +++ b/src/webengine/api/qquickwebenginesettings_p.h @@ -82,6 +82,9 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject { Q_PROPERTY(bool accelerated2dCanvasEnabled READ accelerated2dCanvasEnabled WRITE setAccelerated2dCanvasEnabled NOTIFY accelerated2dCanvasEnabledChanged REVISION 2) Q_PROPERTY(bool autoLoadIconsForPage READ autoLoadIconsForPage WRITE setAutoLoadIconsForPage NOTIFY autoLoadIconsForPageChanged REVISION 2) Q_PROPERTY(bool touchIconsEnabled READ touchIconsEnabled WRITE setTouchIconsEnabled NOTIFY touchIconsEnabledChanged REVISION 2) + Q_PROPERTY(bool focusOnNavigationEnabled READ focusOnNavigationEnabled WRITE setFocusOnNavigationEnabled NOTIFY focusOnNavigationEnabledChanged REVISION 3) + Q_PROPERTY(bool printElementBackgrounds READ printElementBackgrounds WRITE setPrintElementBackgrounds NOTIFY printElementBackgroundsChanged REVISION 3) + Q_PROPERTY(bool allowRunningInsecureContent READ allowRunningInsecureContent WRITE setAllowRunningInsecureContent NOTIFY allowRunningInsecureContentChanged REVISION 3) public: ~QQuickWebEngineSettings(); @@ -105,6 +108,9 @@ public: bool accelerated2dCanvasEnabled() const; bool autoLoadIconsForPage() const; bool touchIconsEnabled() const; + bool focusOnNavigationEnabled() const; + bool printElementBackgrounds() const; + bool allowRunningInsecureContent() const; void setAutoLoadImages(bool on); void setJavascriptEnabled(bool on); @@ -125,6 +131,9 @@ public: void setAccelerated2dCanvasEnabled(bool on); void setAutoLoadIconsForPage(bool on); void setTouchIconsEnabled(bool on); + void setFocusOnNavigationEnabled(bool on); + void setPrintElementBackgrounds(bool on); + void setAllowRunningInsecureContent(bool on); signals: void autoLoadImagesChanged(); @@ -146,6 +155,9 @@ signals: Q_REVISION(2) void accelerated2dCanvasEnabledChanged(); Q_REVISION(2) void autoLoadIconsForPageChanged(); Q_REVISION(2) void touchIconsEnabledChanged(); + Q_REVISION(3) void focusOnNavigationEnabledChanged(); + Q_REVISION(3) void printElementBackgroundsChanged(); + Q_REVISION(3) void allowRunningInsecureContentChanged(); private: explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = 0); diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 31a258b0c..6ca9954cf 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -47,6 +47,8 @@ #include "javascript_dialog_controller.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginecertificateerror_p.h" +#include "qquickwebenginecontextmenurequest_p.h" +#include "qquickwebenginedialogrequests_p.h" #include "qquickwebenginefaviconprovider_p_p.h" #include "qquickwebengineloadrequest_p.h" #include "qquickwebenginenavigationrequest_p.h" @@ -61,8 +63,8 @@ #include "render_widget_host_view_qt_delegate_quick.h" #include "render_widget_host_view_qt_delegate_quickwindow.h" +#include "renderer_host/user_resource_controller_host.h" #include "ui_delegates_manager.h" -#include "user_resource_controller_host.h" #include "web_contents_adapter.h" #include "web_engine_error.h" #include "web_engine_settings.h" @@ -125,8 +127,6 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() : adapter(0) - , e(new QQuickWebEngineViewExperimental(this)) - , v(new QQuickWebEngineViewport(this)) , m_history(new QQuickWebEngineHistory(this)) , m_profile(QQuickWebEngineProfile::defaultProfile()) , m_settings(new QQuickWebEngineSettings(m_profile->settings())) @@ -145,27 +145,28 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_dpiScale(1.0) , m_backgroundColor(Qt::white) , m_defaultZoomFactor(1.0) - // QTBUG-53467 - , m_menuEnabled(true) -{ - // The gold standard for mobile web content is 160 dpi, and the devicePixelRatio expected - // is the (possibly quantized) ratio of device dpi to 160 dpi. - // However GUI toolkits on non-iOS platforms may be using different criteria than relative - // DPI (depending on the history of that platform), dictating the choice of - // QScreen::devicePixelRatio(). - // Where applicable (i.e. non-iOS mobile platforms), override QScreen::devicePixelRatio - // and instead use a reasonable default value for viewport.devicePixelRatio to avoid every - // app having to use this experimental API. + , m_ui2Enabled(false) +{ QString platform = qApp->platformName().toLower(); - if (platform == QLatin1String("qnx")) { - qreal webPixelRatio = QGuiApplication::primaryScreen()->physicalDotsPerInch() / 160; - - // Quantize devicePixelRatio to increments of 1 to allow JS and media queries to select - // 1x, 2x, 3x etc assets that fit an integral number of pixels. - setDevicePixelRatio(qMax(1, qRound(webPixelRatio))); - } if (platform == QLatin1Literal("eglfs")) - m_menuEnabled = false; + m_ui2Enabled = true; + + const QByteArray dialogSet = qgetenv("QTWEBENGINE_DIALOG_SET"); + + if (!dialogSet.isEmpty()) { + if (dialogSet == QByteArrayLiteral("QtQuickControls2")) { + m_ui2Enabled = true; + } else if (dialogSet == QByteArrayLiteral("QtQuickControls1") + && m_ui2Enabled) { + m_ui2Enabled = false; + qWarning("QTWEBENGINE_DIALOG_SET=QtQuickControls1 forces use of Qt Quick Controls 1 " + "on an eglfs backend. This can crash your application!"); + } else { + qWarning("Ignoring QTWEBENGINE_DIALOG_SET environment variable set to %s. Accepted " + "values are \"QtQuickControls1\" and \"QtQuickControls2\"", dialogSet.data()); + } + } + #ifndef QT_NO_ACCESSIBILITY QAccessible::installFactory(&webAccessibleFactory); #endif // QT_NO_ACCESSIBILITY @@ -175,21 +176,11 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate() { } -QQuickWebEngineViewExperimental *QQuickWebEngineViewPrivate::experimental() const -{ - return e.data(); -} - -QQuickWebEngineViewport *QQuickWebEngineViewPrivate::viewport() const -{ - return v.data(); -} - UIDelegatesManager *QQuickWebEngineViewPrivate::ui() { Q_Q(QQuickWebEngineView); if (m_uIDelegatesManager.isNull()) - m_uIDelegatesManager.reset(new UIDelegatesManager(q)); + m_uIDelegatesManager.reset(m_ui2Enabled ? new UI2DelegatesManager(q) : new UIDelegatesManager(q)); return m_uIDelegatesManager.data(); } @@ -216,31 +207,41 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu { Q_Q(QQuickWebEngineView); - if (!m_menuEnabled) { - qWarning("You are trying to open context menu on eglfs backend, which is not currently supported\n" - "See QTBUG-53467."); - return false; - } + m_contextMenuData = data; + + QQuickWebEngineContextMenuRequest *request = new QQuickWebEngineContextMenuRequest(data); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->contextMenuRequested(request); + + if (request->isAccepted()) + return true; // Assign the WebEngineView as the parent of the menu, so mouse events are properly propagated // on OSX. - QObject *menu = ui()->addMenu(q, QString(), data.pos); + QObject *menu = ui()->addMenu(q, QString(), data.position()); if (!menu) return false; - contextMenuData.update(data); - Q_EMIT q->experimental()->contextMenuDataChanged(); - // Populate our menu MenuItemHandler *item = 0; - - if (!data.linkText.isEmpty() && data.linkUrl.isValid()) { + if (data.isEditable() && !data.spellCheckerSuggestions().isEmpty()) { + const QPointer<QQuickWebEngineView> qRef(q); + for (int i=0; i < data.spellCheckerSuggestions().count() && i < 4; i++) { + item = new MenuItemHandler(menu); + QString replacement = data.spellCheckerSuggestions().at(i); + QObject::connect(item, &MenuItemHandler::triggered, [qRef, replacement] { qRef->replaceMisspelledWord(replacement); }); + ui()->addMenuItem(item, replacement); + } + ui()->addMenuSeparator(menu); + } + if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::OpenLinkInThisWindow); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Follow Link")); } - if (data.selectedText.isEmpty()) { + if (data.selectedText().isEmpty()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goBack); ui()->addMenuItem(item, QQuickWebEngineView::tr("Back"), QStringLiteral("go-previous"), q->canGoBack()); @@ -252,6 +253,10 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::reload); ui()->addMenuItem(item, QQuickWebEngineView::tr("Reload"), QStringLiteral("view-refresh")); + + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ViewSource); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("View Page Source"), QStringLiteral("view-source"), adapter->canViewSource()); } else { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::Copy); }); @@ -261,7 +266,7 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu ui()->addMenuItem(item, QQuickWebEngineView::tr("Unselect")); } - if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) { + if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL")); @@ -269,9 +274,9 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Link")); } - if (contextMenuData.mediaUrl().isValid()) { - switch (contextMenuData.mediaType()) { - case QQuickWebEngineContextMenuData::MediaTypeImage: + if (data.mediaUrl().isValid()) { + switch (data.mediaType()) { + case WebEngineContextMenuData::MediaTypeImage: item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image URL")); @@ -282,11 +287,11 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadImageToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Image")); break; - case QQuickWebEngineContextMenuData::MediaTypeCanvas: + case WebEngineContextMenuData::MediaTypeCanvas: Q_UNREACHABLE(); // mediaUrl is invalid for canvases break; - case QQuickWebEngineContextMenuData::MediaTypeAudio: - case QQuickWebEngineContextMenuData::MediaTypeVideo: + case WebEngineContextMenuData::MediaTypeAudio: + case WebEngineContextMenuData::MediaTypeVideo: item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyMediaUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Media URL")); @@ -299,12 +304,12 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaLoop); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Looping")); - if (data.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + if (data.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaMute); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Mute")); } - if (data.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { + if (data.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaControls); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Media Controls")); @@ -313,7 +318,7 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu default: break; } - } else if (contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeCanvas) { + } else if (data.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); @@ -341,7 +346,7 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu } // Now fire the popup() method on the top level menu - QMetaObject::invokeMethod(menu, "popup"); + ui()->showMenu(menu); return true; } @@ -356,7 +361,13 @@ void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const Q void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> dialog) { - ui()->showDialog(dialog); + Q_Q(QQuickWebEngineView); + QQuickWebEngineJavaScriptDialogRequest *request = new QQuickWebEngineJavaScriptDialogRequest(dialog); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->javaScriptDialogRequested(request); + if (!request->isAccepted()) + ui()->showDialog(dialog); } void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) @@ -381,12 +392,24 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller) { - ui()->showColorDialog(controller); + Q_Q(QQuickWebEngineView); + QQuickWebEngineColorDialogRequest *request = new QQuickWebEngineColorDialogRequest(controller); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->colorDialogRequested(request); + if (!request->isAccepted()) + ui()->showColorDialog(controller); } -void QQuickWebEngineViewPrivate::runFileChooser(FilePickerController* controller) +void QQuickWebEngineViewPrivate::runFileChooser(QSharedPointer<FilePickerController> controller) { - ui()->showFilePicker(controller); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFileDialogRequest *request = new QQuickWebEngineFileDialogRequest(controller); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->fileDialogRequested(request); + if (!request->isAccepted()) + ui()->showFilePicker(controller); } void QQuickWebEngineViewPrivate::passOnFocus(bool reverse) @@ -654,7 +677,13 @@ void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessa void QQuickWebEngineViewPrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller) { - ui()->showDialog(controller); + Q_Q(QQuickWebEngineView); + QQuickWebEngineAuthenticationDialogRequest *request = new QQuickWebEngineAuthenticationDialogRequest(controller); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->authenticationDialogRequested(request); + if (!request->isAccepted()) + ui()->showDialog(controller); } void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags) @@ -836,7 +865,7 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent) , d_ptr(new QQuickWebEngineViewPrivate) { Q_D(QQuickWebEngineView); - d->e->q_ptr = d->q_ptr = this; + d->q_ptr = this; this->setActiveFocusOnTab(true); this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsInputMethod | QQuickItem::ItemAcceptsDrops); @@ -1078,18 +1107,40 @@ void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, cons if (m_testSupport) Q_EMIT m_testSupport->validationMessageShown(mainText, subText); #endif - - ui()->showMessageBubble(anchor, mainText, subText); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFormValidationMessageRequest *request; + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Show, + anchor,mainText,subText); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->formValidationMessageRequested(request); + if (!request->isAccepted()) + ui()->showMessageBubble(anchor, mainText, subText); } void QQuickWebEngineViewPrivate::hideValidationMessage() { - ui()->hideMessageBubble(); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFormValidationMessageRequest *request; + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Hide); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->formValidationMessageRequested(request); + if (!request->isAccepted()) + ui()->hideMessageBubble(); } void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor) { - ui()->moveMessageBubble(anchor); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFormValidationMessageRequest *request; + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::Move, + anchor); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->formValidationMessageRequested(request); + if (!request->isAccepted()) + ui()->moveMessageBubble(anchor); } void QQuickWebEngineViewPrivate::updateScrollPosition(const QPointF &position) @@ -1125,6 +1176,11 @@ bool QQuickWebEngineViewPrivate::isEnabled() const return q->isEnabled(); } +void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText) +{ + ui()->showToolTip(toolTipText); +} + bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); @@ -1184,12 +1240,6 @@ void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId, d->adapter->runJavaScript(script, worldId); } -QQuickWebEngineViewExperimental *QQuickWebEngineView::experimental() const -{ - Q_D(const QQuickWebEngineView); - return d->e.data(); -} - qreal QQuickWebEngineView::zoomFactor() const { Q_D(const QQuickWebEngineView); @@ -1274,23 +1324,16 @@ void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId d->m_callbacks.insert(requestId, callback); } -bool QQuickWebEngineView::isFullScreen() const -{ - Q_D(const QQuickWebEngineView); - return d->m_fullscreenMode; -} - -void QQuickWebEngineViewExperimental::setExtraContextMenuEntriesComponent(QQmlComponent *contextMenuExtras) +void QQuickWebEngineView::replaceMisspelledWord(const QString &replacement) { - if (d_ptr->contextMenuExtraItems == contextMenuExtras) - return; - d_ptr->contextMenuExtraItems = contextMenuExtras; - emit extraContextMenuEntriesComponentChanged(); + Q_D(QQuickWebEngineView); + d->adapter->replaceMisspelling(replacement); } -QQmlComponent *QQuickWebEngineViewExperimental::extraContextMenuEntriesComponent() const +bool QQuickWebEngineView::isFullScreen() const { - return d_ptr->contextMenuExtraItems; + Q_D(const QQuickWebEngineView); + return d->m_fullscreenMode; } void QQuickWebEngineView::findText(const QString &subString, FindFlags options, const QJSValue &callback) @@ -1514,118 +1557,118 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) d->adapter->unselect(); break; case OpenLinkInThisWindow: - if (d->contextMenuData.linkUrl().isValid()) - setUrl(d->contextMenuData.linkUrl()); + if (d->m_contextMenuData.linkUrl().isValid()) + setUrl(d->m_contextMenuData.linkUrl()); break; case OpenLinkInNewWindow: - if (d->contextMenuData.linkUrl().isValid()) { + if (d->m_contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; - request.m_requestedUrl = d->contextMenuData.linkUrl(); + request.m_requestedUrl = d->m_contextMenuData.linkUrl(); request.m_isUserInitiated = true; request.m_destination = NewViewInWindow; Q_EMIT newViewRequested(&request); } break; case OpenLinkInNewTab: - if (d->contextMenuData.linkUrl().isValid()) { + if (d->m_contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; - request.m_requestedUrl = d->contextMenuData.linkUrl(); + request.m_requestedUrl = d->m_contextMenuData.linkUrl(); request.m_isUserInitiated = true; request.m_destination = NewViewInBackgroundTab; Q_EMIT newViewRequested(&request); } break; case CopyLinkToClipboard: - if (d->contextMenuData.linkUrl().isValid()) { - QString urlString = d->contextMenuData.linkUrl().toString(QUrl::FullyEncoded); - QString title = d->contextMenuData.linkText().toHtmlEscaped(); + if (d->m_contextMenuData.linkUrl().isValid()) { + QString urlString = d->m_contextMenuData.linkUrl().toString(QUrl::FullyEncoded); + QString title = d->m_contextMenuData.linkText().toHtmlEscaped(); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>"); data->setHtml(html); - data->setUrls(QList<QUrl>() << d->contextMenuData.linkUrl()); + data->setUrls(QList<QUrl>() << d->m_contextMenuData.linkUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadLinkToDisk: - if (d->contextMenuData.linkUrl().isValid()) - d->adapter->download(d->contextMenuData.linkUrl(), d->contextMenuData.d->suggestedFileName); + if (d->m_contextMenuData.linkUrl().isValid()) + d->adapter->download(d->m_contextMenuData.linkUrl(), d->m_contextMenuData.suggestedFileName()); break; case CopyImageToClipboard: - if (d->contextMenuData.d->hasImageContent && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeImage || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeCanvas)) + if (d->m_contextMenuData.hasImageContent() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeImage || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas)) { - d->adapter->copyImageAt(d->contextMenuData.position()); + d->adapter->copyImageAt(d->m_contextMenuData.position()); } break; case CopyImageUrlToClipboard: - if (d->contextMenuData.mediaUrl().isValid() && d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeImage) { - QString urlString = d->contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); - QString title = d->contextMenuData.linkText(); + if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeImage) { + QString urlString = d->m_contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); + QString title = d->m_contextMenuData.linkText(); if (!title.isEmpty()) title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>"); data->setHtml(html); - data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl()); + data->setUrls(QList<QUrl>() << d->m_contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadImageToDisk: case DownloadMediaToDisk: - if (d->contextMenuData.mediaUrl().isValid()) - d->adapter->download(d->contextMenuData.mediaUrl(), d->contextMenuData.d->suggestedFileName); + if (d->m_contextMenuData.mediaUrl().isValid()) + d->adapter->download(d->m_contextMenuData.mediaUrl(), d->m_contextMenuData.suggestedFileName()); break; case CopyMediaUrlToClipboard: - if (d->contextMenuData.mediaUrl().isValid() && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) + if (d->m_contextMenuData.mediaUrl().isValid() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - QString urlString = d->contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); + QString urlString = d->m_contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); QMimeData *data = new QMimeData(); data->setText(urlString); - if (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio) + if (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio) data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>")); else data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>")); - data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl()); + data->setUrls(QList<QUrl>() << d->m_contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case ToggleMediaControls: - if (d->contextMenuData.mediaUrl().isValid() && d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { - bool enable = !(d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaControls); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerControls, enable); + if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { + bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaControls); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerControls, enable); } break; case ToggleMediaLoop: - if (d->contextMenuData.mediaUrl().isValid() && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) + if (d->m_contextMenuData.mediaUrl().isValid() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = !(d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaLoop); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); + bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaLoop); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); } break; case ToggleMediaPlayPause: - if (d->contextMenuData.mediaUrl().isValid() && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) + if (d->m_contextMenuData.mediaUrl().isValid() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = (d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaPaused); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); + bool enable = (d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaPaused); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); } break; case ToggleMediaMute: - if (d->contextMenuData.mediaUrl().isValid() && d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaHasAudio) { - bool enable = !(d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaMuted); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerMute, enable); + if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { + bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaMuted); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerMute, enable); } break; case InspectElement: - d->adapter->inspectElementAt(d->contextMenuData.position()); + d->adapter->inspectElementAt(d->m_contextMenuData.position()); break; case ExitFullScreen: d->adapter->exitFullScreen(); @@ -1636,17 +1679,14 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) case SavePage: d->adapter->save(); break; + case ViewSource: + d->adapter->viewSource(); + break; default: Q_UNREACHABLE(); } } -const QQuickWebEngineContextMenuData *QQuickWebEngineViewExperimental::contextMenuData() const -{ - Q_D(const QQuickWebEngineView); - return &d->contextMenuData; -} - QSizeF QQuickWebEngineView::contentsSize() const { Q_D(const QQuickWebEngineView); @@ -1731,42 +1771,5 @@ void QQuickWebEngineFullScreenRequest::reject() m_viewPrivate->setFullScreenMode(!m_toggleOn); } -QQuickWebEngineViewExperimental::QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate *viewPrivate) - : q_ptr(0) - , d_ptr(viewPrivate) -{ -} - -QQuickWebEngineViewport *QQuickWebEngineViewExperimental::viewport() const -{ - Q_D(const QQuickWebEngineView); - return d->viewport(); -} - -QQuickWebEngineViewport::QQuickWebEngineViewport(QQuickWebEngineViewPrivate *viewPrivate) - : d_ptr(viewPrivate) -{ -} - -qreal QQuickWebEngineViewport::devicePixelRatio() const -{ - Q_D(const QQuickWebEngineView); - return d->devicePixelRatio; -} - -void QQuickWebEngineViewport::setDevicePixelRatio(qreal devicePixelRatio) -{ - Q_D(QQuickWebEngineView); - // Valid range is [1, inf) - devicePixelRatio = qMax(qreal(1.0), devicePixelRatio); - if (d->devicePixelRatio == devicePixelRatio) - return; - d->setDevicePixelRatio(devicePixelRatio); - if (!d->adapter) - return; - d->adapter->dpiScaleChanged(); - Q_EMIT devicePixelRatioChanged(); -} - QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index b9555d2d9..16c4799b5 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -59,16 +59,20 @@ QT_BEGIN_NAMESPACE class QQmlWebChannel; +class QQuickWebEngineAuthenticationDialogRequest; class QQuickWebEngineCertificateError; -class QQuickWebEngineContextMenuData; +class QQuickWebEngineColorDialogRequest; +class QQuickWebEngineContextMenuRequest; class QQuickWebEngineFaviconProvider; +class QQuickWebEngineFileDialogRequest; class QQuickWebEngineHistory; +class QQuickWebEngineJavaScriptDialogRequest; class QQuickWebEngineLoadRequest; class QQuickWebEngineNavigationRequest; class QQuickWebEngineNewViewRequest; class QQuickWebEngineProfile; class QQuickWebEngineSettings; -class QQuickWebEngineViewExperimental; +class QQuickWebEngineFormValidationMessageRequest; class QQuickWebEngineViewPrivate; #ifdef ENABLE_QML_TESTSUPPORT_API @@ -94,7 +98,7 @@ private: const bool m_toggleOn; }; -#define LATEST_WEBENGINEVIEW_REVISION 3 +#define LATEST_WEBENGINEVIEW_REVISION 4 class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_OBJECT @@ -146,13 +150,11 @@ public: QSizeF contentsSize() const; QPointF scrollPosition() const; - QQuickWebEngineViewExperimental *experimental() const; - // must match WebContentsAdapterClient::NavigationRequestAction enum NavigationRequestAction { AcceptRequest, // Make room in the valid range of the enum so - // we can expose extra actions in experimental. + // we can expose extra actions. IgnoreRequest = 0xFF }; Q_ENUM(NavigationRequestAction) @@ -243,6 +245,7 @@ public: RequestClose, Unselect, SavePage, + ViewSource, WebActionCount }; Q_ENUM(WebAction) @@ -472,6 +475,8 @@ public Q_SLOTS: Q_REVISION(2) void triggerWebAction(WebAction action); Q_REVISION(3) void printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait); Q_REVISION(3) void printToPdf(const QJSValue &callback, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait); + Q_REVISION(4) void replaceMisspelledWord(const QString &replacement); + private Q_SLOTS: void lazyInitialize(); @@ -501,6 +506,12 @@ Q_SIGNALS: Q_REVISION(3) void audioMutedChanged(bool muted); Q_REVISION(3) void recentlyAudibleChanged(bool recentlyAudible); Q_REVISION(3) void webChannelWorldChanged(uint); + Q_REVISION(4) void contextMenuRequested(QQuickWebEngineContextMenuRequest *request); + Q_REVISION(4) void authenticationDialogRequested(QQuickWebEngineAuthenticationDialogRequest *request); + Q_REVISION(4) void javaScriptDialogRequested(QQuickWebEngineJavaScriptDialogRequest *request); + Q_REVISION(4) void colorDialogRequested(QQuickWebEngineColorDialogRequest *request); + Q_REVISION(4) void fileDialogRequested(QQuickWebEngineFileDialogRequest *request); + Q_REVISION(4) void formValidationMessageRequested(QQuickWebEngineFormValidationMessageRequest *request); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; @@ -514,8 +525,6 @@ private: Q_DECLARE_PRIVATE(QQuickWebEngineView) QScopedPointer<QQuickWebEngineViewPrivate> d_ptr; - friend class QQuickWebEngineViewExperimental; - friend class QQuickWebEngineViewExperimentalExtension; friend class QQuickWebEngineNewViewRequest; friend class QQuickWebEngineFaviconProvider; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 769e41a44..b111e92cd 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -52,7 +52,6 @@ // #include "qquickwebengineview_p.h" -#include "qquickwebenginecontextmenudata_p.h" #include "web_contents_adapter_client.h" #include <QScopedPointer> @@ -70,6 +69,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineView; class QQmlComponent; class QQmlContext; +class QQuickWebEngineContextMenuRequest; class QQuickWebEngineSettings; class QQuickWebEngineFaviconProvider; @@ -79,49 +79,6 @@ QQuickWebEngineView::WebAction editorActionForKeyEvent(QKeyEvent* event); class QQuickWebEngineTestSupport; #endif -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewport : public QObject { - Q_OBJECT - Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged) -public: - QQuickWebEngineViewport(QQuickWebEngineViewPrivate *viewPrivate); - - qreal devicePixelRatio() const; - void setDevicePixelRatio(qreal); - -Q_SIGNALS: - void devicePixelRatioChanged(); - -private: - QQuickWebEngineViewPrivate *d_ptr; - - Q_DECLARE_PRIVATE(QQuickWebEngineView) -}; - -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewExperimental : public QObject { - Q_OBJECT - Q_PROPERTY(QQuickWebEngineViewport *viewport READ viewport) - Q_PROPERTY(QQmlComponent *extraContextMenuEntriesComponent READ extraContextMenuEntriesComponent WRITE setExtraContextMenuEntriesComponent NOTIFY extraContextMenuEntriesComponentChanged) - Q_PROPERTY(const QQuickWebEngineContextMenuData *contextMenuData READ contextMenuData NOTIFY contextMenuDataChanged) - - QQuickWebEngineViewport *viewport() const; - void setExtraContextMenuEntriesComponent(QQmlComponent *); - QQmlComponent *extraContextMenuEntriesComponent() const; - - const QQuickWebEngineContextMenuData *contextMenuData() const; - -Q_SIGNALS: - void extraContextMenuEntriesComponentChanged(); - void contextMenuDataChanged(); - -private: - QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate* viewPrivate); - QQuickWebEngineView *q_ptr; - QQuickWebEngineViewPrivate *d_ptr; - - Q_DECLARE_PRIVATE(QQuickWebEngineView) - Q_DECLARE_PUBLIC(QQuickWebEngineView) -}; - class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCore::WebContentsAdapterClient { public: @@ -130,8 +87,6 @@ public: QQuickWebEngineViewPrivate(); ~QQuickWebEngineViewPrivate(); - QQuickWebEngineViewExperimental *experimental() const; - QQuickWebEngineViewport *viewport() const; QtWebEngineCore::UIDelegatesManager *ui(); virtual QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) Q_DECL_OVERRIDE; @@ -161,13 +116,16 @@ public: virtual bool contextMenuRequested(const QtWebEngineCore::WebEngineContextMenuData &) Q_DECL_OVERRIDE; virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE; virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE; - virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE; + virtual void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) Q_DECL_OVERRIDE; virtual void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) Q_DECL_OVERRIDE; virtual void didRunJavaScript(quint64, const QVariant&) Q_DECL_OVERRIDE; virtual void didFetchDocumentMarkup(quint64, const QString&) Q_DECL_OVERRIDE { } virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { } virtual void didFindText(quint64, int) Q_DECL_OVERRIDE; virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE; +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) + virtual void didPrintPageOnPrinter(quint64, bool) Q_DECL_OVERRIDE { } +#endif virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE; virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE; @@ -190,6 +148,7 @@ public: void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE; virtual bool isEnabled() const Q_DECL_OVERRIDE; + virtual void setToolTip(const QString &toolTipText) Q_DECL_OVERRIDE; const QObject *holdingQObject() const Q_DECL_OVERRIDE; virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE; @@ -208,8 +167,6 @@ public: static void userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p); QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter; - QScopedPointer<QQuickWebEngineViewExperimental> e; - QScopedPointer<QQuickWebEngineViewport> v; QScopedPointer<QQuickWebEngineHistory> m_history; QQuickWebEngineProfile *m_profile; QScopedPointer<QQuickWebEngineSettings> m_settings; @@ -217,7 +174,7 @@ public: QQuickWebEngineTestSupport *m_testSupport; #endif QQmlComponent *contextMenuExtraItems; - QQuickWebEngineContextMenuData contextMenuData; + QtWebEngineCore::WebEngineContextMenuData m_contextMenuData; QUrl explicitUrl; QUrl iconUrl; QQuickWebEngineFaviconProvider *faviconProvider; @@ -225,6 +182,7 @@ public: bool m_fullscreenMode; bool isLoading; bool m_activeFocusOnPress; + bool m_navigationActionTriggered; qreal devicePixelRatio; QMap<quint64, QJSValue> m_callbacks; QList<QSharedPointer<CertificateErrorController> > m_certificateErrorControllers; @@ -237,8 +195,7 @@ private: qreal m_dpiScale; QColor m_backgroundColor; qreal m_defaultZoomFactor; - // QTBUG-53467 - bool m_menuEnabled; + bool m_ui2Enabled; }; #ifndef QT_NO_ACCESSIBILITY @@ -260,7 +217,4 @@ private: #endif // QT_NO_ACCESSIBILITY QT_END_NAMESPACE -QML_DECLARE_TYPE(QQuickWebEngineViewExperimental) -QML_DECLARE_TYPE(QQuickWebEngineViewport) - #endif // QQUICKWEBENGINEVIEW_P_P_H |