diff options
Diffstat (limited to 'src/webenginewidgets/api')
18 files changed, 1248 insertions, 5544 deletions
diff --git a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp b/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp deleted file mode 100644 index 76f422e9d..000000000 --- a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp +++ /dev/null @@ -1,77 +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 "qtwebenginewidgetsglobal.h" - -#include <QCoreApplication> -#include <QOpenGLContext> -#include <QQuickWindow> - -namespace QtWebEngineCore -{ - extern void initialize(); -} - -QT_BEGIN_NAMESPACE - -#if QT_CONFIG(opengl) -Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); -#endif - -static void initialize() -{ -#if QT_CONFIG(opengl) - if (QCoreApplication::instance()) { - //On window/ANGLE, calling QtWebEngine::initialize from DllMain will result in a crash. - if (!qt_gl_global_share_context()) { - qWarning("Qt WebEngine seems to be initialized from a plugin. Please " - "set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute " - "before constructing QGuiApplication."); - } - return; - } - //QCoreApplication is not yet instantiated, ensuring the call will be deferred - qAddPreRoutine(QtWebEngineCore::initialize); - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); -#endif // QT_CONFIG(opengl) -} - -Q_CONSTRUCTOR_FUNCTION(initialize) - -QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qtwebenginewidgetsglobal.h b/src/webenginewidgets/api/qtwebenginewidgetsglobal.h index 128704578..58b9c7a2b 100644 --- a/src/webenginewidgets/api/qtwebenginewidgetsglobal.h +++ b/src/webenginewidgets/api/qtwebenginewidgetsglobal.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QTWEBENGINEWIDGETSGLOBAL_H #define QTWEBENGINEWIDGETSGLOBAL_H diff --git a/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp b/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp deleted file mode 100644 index febfe0a21..000000000 --- a/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwebengineclientcertificateselection.h" -#include "client_cert_select_controller.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QWebEngineClientCertificateSelection - \brief The QWebEngineClientCertSelection class wraps a client certificate selection. - \since 5.12 - \inmodule QtWebEngineWidgets - - When a web site requests an SSL client certificate, and one or more certificates - are found in the system's client certificate store, this class provides access to - the certificates to choose from, as well as a method for selecting one. - - The selection is asynchronous. If no certificate is selected and no copy of the - object is kept alive, loading will continue without a certificate. - - \sa QWebEnginePage::selectClientCertificate() -*/ - -/*! \internal -*/ -QWebEngineClientCertificateSelection::QWebEngineClientCertificateSelection( - QSharedPointer<QtWebEngineCore::ClientCertSelectController> selectController) - : d_ptr(selectController) -{} - -QWebEngineClientCertificateSelection::QWebEngineClientCertificateSelection(const QWebEngineClientCertificateSelection &other) - : d_ptr(other.d_ptr) -{} - -QWebEngineClientCertificateSelection &QWebEngineClientCertificateSelection::operator=(const QWebEngineClientCertificateSelection &other) -{ - d_ptr = other.d_ptr; - return *this; -} - -QWebEngineClientCertificateSelection::~QWebEngineClientCertificateSelection() -{ -} - -/*! - Returns the client certificates available to choose from. - - \sa select() -*/ -QList<QSslCertificate> QWebEngineClientCertificateSelection::certificates() const -{ - return d_ptr->certificates(); -} - -/*! - Selects the client certificate \a certificate. The certificate must be one - of those offered in certificates(). - - \sa certificates(), selectNone() -*/ -void QWebEngineClientCertificateSelection::select(const QSslCertificate &certificate) -{ - d_ptr->select(certificate); -} - -/*! - Continue without using any of the offered certificates. This is the same - action as taken when destroying the last copy of this object if no - selection has been made. - - \sa select() -*/ -void QWebEngineClientCertificateSelection::selectNone() -{ - d_ptr->selectNone(); -} - -/*! - Returns the host and port of the server requesting the client certificate. -*/ -QUrl QWebEngineClientCertificateSelection::host() const -{ - return d_ptr->hostAndPort(); -} - -QT_END_NAMESPACE - diff --git a/src/webenginewidgets/api/qwebengineclientcertificateselection.h b/src/webenginewidgets/api/qwebengineclientcertificateselection.h deleted file mode 100644 index 165194aac..000000000 --- a/src/webenginewidgets/api/qwebengineclientcertificateselection.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWEBENGINECLIENTCERTSELECTION_H -#define QWEBENGINECLIENTCERTSELECTION_H - -#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> -#include <QtNetwork/qtnetwork-config.h> -#include <QtCore/qlist.h> -#include <QtCore/qscopedpointer.h> -#include <QtNetwork/qsslcertificate.h> - -namespace QtWebEngineCore { -class ClientCertSelectController; -} - -QT_BEGIN_NAMESPACE - -class QWEBENGINEWIDGETS_EXPORT QWebEngineClientCertificateSelection { -public: - QWebEngineClientCertificateSelection(const QWebEngineClientCertificateSelection &); - ~QWebEngineClientCertificateSelection(); - - QWebEngineClientCertificateSelection &operator=(const QWebEngineClientCertificateSelection &); - - QUrl host() const; - - void select(const QSslCertificate &certificate); - void selectNone(); - QList<QSslCertificate> certificates() const; - -private: - friend class QWebEnginePagePrivate; - - QWebEngineClientCertificateSelection( - QSharedPointer<QtWebEngineCore::ClientCertSelectController>); - - QSharedPointer<QtWebEngineCore::ClientCertSelectController> d_ptr; -}; - -QT_END_NAMESPACE - -#endif // QWEBENGINECLIENTCERTSELECTION_H diff --git a/src/webenginewidgets/api/qwebenginehistory.cpp b/src/webenginewidgets/api/qwebenginehistory.cpp deleted file mode 100644 index 6a85b984e..000000000 --- a/src/webenginewidgets/api/qwebenginehistory.cpp +++ /dev/null @@ -1,280 +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 "qwebenginehistory.h" -#include "qwebenginehistory_p.h" - -#include "qwebenginepage_p.h" -#include "web_contents_adapter.h" - -QT_BEGIN_NAMESPACE - -/*! - \fn QWebEngineHistoryItem::swap(QWebEngineHistoryItem &other) - Swaps the history item with the \a other item. -*/ - -QWebEngineHistoryItemPrivate::QWebEngineHistoryItemPrivate(QWebEnginePagePrivate *page, int index) - : page(page) - , index(index) -{ -} - -QWebEngineHistoryItem::QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *d) - : d(d) -{ -} - -QWebEngineHistoryItem::QWebEngineHistoryItem(const QWebEngineHistoryItem &other) - : d(other.d) -{ -} - -QWebEngineHistoryItem &QWebEngineHistoryItem::operator=(const QWebEngineHistoryItem &other) -{ - d = other.d; - return *this; -} - -QWebEngineHistoryItem::~QWebEngineHistoryItem() -{ -} - -QUrl QWebEngineHistoryItem::originalUrl() const -{ - Q_D(const QWebEngineHistoryItem); - return d->page ? d->page->webContents()->getNavigationEntryOriginalUrl(d->index) : QUrl(); -} - -QUrl QWebEngineHistoryItem::url() const -{ - Q_D(const QWebEngineHistoryItem); - return d->page ? d->page->webContents()->getNavigationEntryUrl(d->index) : QUrl(); -} - -QString QWebEngineHistoryItem::title() const -{ - Q_D(const QWebEngineHistoryItem); - return d->page ? d->page->webContents()->getNavigationEntryTitle(d->index) : QString(); -} - -QDateTime QWebEngineHistoryItem::lastVisited() const -{ - Q_D(const QWebEngineHistoryItem); - return d->page ? d->page->webContents()->getNavigationEntryTimestamp(d->index) : QDateTime(); -} - -/*! - Returns the URL of the icon associated with the history item. - - \sa url(), originalUrl(), title() -*/ -QUrl QWebEngineHistoryItem::iconUrl() const -{ - Q_D(const QWebEngineHistoryItem); - return d->page ? d->page->webContents()->getNavigationEntryIconUrl(d->index) : QUrl(); -} - -bool QWebEngineHistoryItem::isValid() const -{ - Q_D(const QWebEngineHistoryItem); - if (!d->page) - return false; - return d->index >= 0 && d->index < d->page->webContents()->navigationEntryCount(); -} - -QWebEngineHistoryPrivate::QWebEngineHistoryPrivate(QWebEnginePagePrivate *page) - : page(page) -{ -} - -QWebEngineHistoryPrivate::~QWebEngineHistoryPrivate() -{ - // Invalidate shared item references possibly still out there. - QList<QWebEngineHistoryItem>::iterator it, end; - for (it = items.begin(), end = items.end(); it != end; ++it) - it->d->page = 0; -} - -void QWebEngineHistoryPrivate::updateItems() const -{ - // Keep track of items we return to be able to invalidate them - // and avoid dangling references to our page. - int entryCount = page->webContents()->navigationEntryCount(); - while (items.size() > entryCount) { - items.last().d->page = 0; - items.removeLast(); - } - while (items.size() < entryCount) { - int nextIndex = items.size(); - items.append(QWebEngineHistoryItem(new QWebEngineHistoryItemPrivate(page, nextIndex))); - } -} - -QWebEngineHistory::QWebEngineHistory(QWebEngineHistoryPrivate *d) - : d_ptr(d) -{ -} - -QWebEngineHistory::~QWebEngineHistory() -{ -} - -void QWebEngineHistory::clear() -{ - Q_D(const QWebEngineHistory); - d->page->webContents()->clearNavigationHistory(); - d->page->updateNavigationActions(); -} - -QList<QWebEngineHistoryItem> QWebEngineHistory::items() const -{ - Q_D(const QWebEngineHistory); - d->updateItems(); - return d->items; -} - -QList<QWebEngineHistoryItem> QWebEngineHistory::backItems(int maxItems) const -{ - Q_D(const QWebEngineHistory); - d->updateItems(); - const int end = currentItemIndex(); - const int start = std::max(0, end - maxItems); - return d->items.mid(start, end - start); -} - -QList<QWebEngineHistoryItem> QWebEngineHistory::forwardItems(int maxItems) const -{ - Q_D(const QWebEngineHistory); - d->updateItems(); - const int start = currentItemIndex() + 1; - const int end = std::min(count(), start + maxItems); - return d->items.mid(start, end - start); -} - -bool QWebEngineHistory::canGoBack() const -{ - Q_D(const QWebEngineHistory); - return d->page->webContents()->canGoToOffset(-1); -} - -bool QWebEngineHistory::canGoForward() const -{ - Q_D(const QWebEngineHistory); - return d->page->webContents()->canGoToOffset(1); -} - -void QWebEngineHistory::back() -{ - Q_D(const QWebEngineHistory); - d->page->webContents()->navigateToOffset(-1); -} - -void QWebEngineHistory::forward() -{ - Q_D(const QWebEngineHistory); - d->page->webContents()->navigateToOffset(1); -} - -void QWebEngineHistory::goToItem(const QWebEngineHistoryItem &item) -{ - Q_D(const QWebEngineHistory); - Q_ASSERT(item.d->page == d->page); - d->page->webContents()->navigateToIndex(item.d->index); -} - -QWebEngineHistoryItem QWebEngineHistory::backItem() const -{ - return itemAt(currentItemIndex() - 1); -} - -QWebEngineHistoryItem QWebEngineHistory::currentItem() const -{ - return itemAt(currentItemIndex()); -} - -QWebEngineHistoryItem QWebEngineHistory::forwardItem() const -{ - return itemAt(currentItemIndex() + 1); -} - -QWebEngineHistoryItem QWebEngineHistory::itemAt(int i) const -{ - Q_D(const QWebEngineHistory); - if (i >= 0 && i < count()) { - d->updateItems(); - return d->items[i]; - } else { - // Return an invalid item right away. - QWebEngineHistoryItem item(new QWebEngineHistoryItemPrivate(0, i)); - Q_ASSERT(!item.isValid()); - return item; - } -} - -int QWebEngineHistory::currentItemIndex() const -{ - Q_D(const QWebEngineHistory); - return d->page->webContents()->currentNavigationEntryIndex(); -} - -int QWebEngineHistory::count() const -{ - Q_D(const QWebEngineHistory); - if (!d->page->webContents()->isInitialized()) - return 0; - return d->page->webContents()->navigationEntryCount(); -} - -QDataStream& operator<<(QDataStream& stream, const QWebEngineHistory& history) -{ - QtWebEngineCore::WebContentsAdapter *adapter = history.d_func()->page->webContents(); - if (!adapter->isInitialized()) - adapter->loadDefault(); - adapter->serializeNavigationHistory(stream); - return stream; -} - -QDataStream& operator>>(QDataStream& stream, QWebEngineHistory& history) -{ - history.d_func()->page->recreateFromSerializedHistory(stream); - return stream; -} - -QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qwebenginehistory.h b/src/webenginewidgets/api/qwebenginehistory.h deleted file mode 100644 index 33d91d523..000000000 --- a/src/webenginewidgets/api/qwebenginehistory.h +++ /dev/null @@ -1,128 +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$ -** -****************************************************************************/ - -#ifndef QWEBENGINEHISTORY_H -#define QWEBENGINEHISTORY_H - -#include <QtCore/qurl.h> -#include <QtCore/qstring.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qshareddata.h> -#include <QtGui/qicon.h> -#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> - -QT_BEGIN_NAMESPACE - -class QWebEngineHistory; -class QWebEngineHistoryItemPrivate; -class QWebEnginePage; -class QWebEnginePagePrivate; - -class QWEBENGINEWIDGETS_EXPORT QWebEngineHistoryItem { -public: - QWebEngineHistoryItem(const QWebEngineHistoryItem &other); - QWebEngineHistoryItem &operator=(const QWebEngineHistoryItem &other); - ~QWebEngineHistoryItem(); - - QUrl originalUrl() const; - QUrl url() const; - - QString title() const; - QDateTime lastVisited() const; - QUrl iconUrl() const; - - bool isValid() const; - - void swap(QWebEngineHistoryItem &other) Q_DECL_NOTHROW { qSwap(d, other.d); } - -private: - QWebEngineHistoryItem(QWebEngineHistoryItemPrivate *priv); - Q_DECLARE_PRIVATE_D(d.data(), QWebEngineHistoryItem) - QExplicitlySharedDataPointer<QWebEngineHistoryItemPrivate> d; - friend class QWebEngineHistory; - friend class QWebEngineHistoryPrivate; -}; - -Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineHistoryItem) - -class QWebEngineHistoryPrivate; -class QWEBENGINEWIDGETS_EXPORT QWebEngineHistory { -public: - void clear(); - - QList<QWebEngineHistoryItem> items() const; - QList<QWebEngineHistoryItem> backItems(int maxItems) const; - QList<QWebEngineHistoryItem> forwardItems(int maxItems) const; - - bool canGoBack() const; - bool canGoForward() const; - - void back(); - void forward(); - void goToItem(const QWebEngineHistoryItem &item); - - QWebEngineHistoryItem backItem() const; - QWebEngineHistoryItem currentItem() const; - QWebEngineHistoryItem forwardItem() const; - QWebEngineHistoryItem itemAt(int i) const; - - int currentItemIndex() const; - - int count() const; - -private: - QWebEngineHistory(QWebEngineHistoryPrivate *d); - ~QWebEngineHistory(); - - Q_DISABLE_COPY(QWebEngineHistory) - Q_DECLARE_PRIVATE(QWebEngineHistory) - QScopedPointer<QWebEngineHistoryPrivate> d_ptr; - - friend QWEBENGINEWIDGETS_EXPORT QDataStream& operator>>(QDataStream&, QWebEngineHistory&); - friend QWEBENGINEWIDGETS_EXPORT QDataStream& operator<<(QDataStream&, const QWebEngineHistory&); - friend class QWebEnginePage; - friend class QWebEnginePagePrivate; -}; - -QWEBENGINEWIDGETS_EXPORT QDataStream& operator<<(QDataStream& stream, const QWebEngineHistory& history); -QWEBENGINEWIDGETS_EXPORT QDataStream& operator>>(QDataStream& stream, QWebEngineHistory& history); - -QT_END_NAMESPACE - -#endif // QWEBENGINEHISTORY_H diff --git a/src/webenginewidgets/api/qwebenginehistory_p.h b/src/webenginewidgets/api/qwebenginehistory_p.h deleted file mode 100644 index 8f7001967..000000000 --- a/src/webenginewidgets/api/qwebenginehistory_p.h +++ /dev/null @@ -1,81 +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$ -** -****************************************************************************/ - -#ifndef QWEBENGINEHISTORY_P_H -#define QWEBENGINEHISTORY_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qshareddata.h> - -QT_BEGIN_NAMESPACE -class QWebEnginePagePrivate; - -class QWebEngineHistoryItemPrivate : public QSharedData -{ -public: - QWebEngineHistoryItemPrivate(QWebEnginePagePrivate *page = 0, int index = 0); - - QWebEnginePagePrivate *page; - int index; -}; - -class QWebEngineHistoryPrivate -{ -public: - QWebEngineHistoryPrivate(QWebEnginePagePrivate *page); - ~QWebEngineHistoryPrivate(); - void updateItems() const; - - QWebEnginePagePrivate *page; - mutable QList<QWebEngineHistoryItem> items; -}; - -QT_END_NAMESPACE - -#endif // QWEBENGINEHISTORY_P_H diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp index 667605c37..83814fe4a 100644 --- a/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp +++ b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qwebenginenotificationpresenter_p.h" @@ -46,7 +10,7 @@ QT_BEGIN_NAMESPACE DefaultNotificationPresenter::DefaultNotificationPresenter(QObject *parent) : QObject(parent) { -#ifndef QT_NO_SYSTEMTRAYICON +#if QT_CONFIG(systemtrayicon) m_systemTrayIcon = new QSystemTrayIcon(this); connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked, this, &DefaultNotificationPresenter::messageClicked); #endif @@ -66,7 +30,7 @@ void DefaultNotificationPresenter::show(std::unique_ptr<QWebEngineNotification> m_activeNotification = std::move(notification); -#ifndef QT_NO_SYSTEMTRAYICON +#if QT_CONFIG(systemtrayicon) if (m_activeNotification && m_systemTrayIcon) { m_systemTrayIcon->setIcon(qApp->windowIcon()); m_systemTrayIcon->show(); @@ -90,7 +54,7 @@ void DefaultNotificationPresenter::messageClicked() void DefaultNotificationPresenter::closeNotification() { -#ifndef QT_NO_SYSTEMTRAYICON +#if QT_CONFIG(systemtrayicon) const QWebEngineNotification *canceled = static_cast<const QWebEngineNotification *>(QObject::sender()); if (m_systemTrayIcon && canceled->matches(m_activeNotification.get())) m_systemTrayIcon->hide(); @@ -107,3 +71,5 @@ void defaultNotificationPresenter(std::unique_ptr<QWebEngineNotification> notifi QT_END_NAMESPACE + +#include "moc_qwebenginenotificationpresenter_p.cpp" diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h index 49d774806..61e7f9e45 100644 --- a/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h +++ b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QWEBENGINENOTIFICATIONPRESENTER_P_H #define QWEBENGINENOTIFICATIONPRESENTER_P_H @@ -62,7 +26,8 @@ QT_BEGIN_NAMESPACE class QSystemTrayIcon; -class DefaultNotificationPresenter : public QObject { +class DefaultNotificationPresenter : public QObject +{ Q_OBJECT public: DefaultNotificationPresenter(QObject *parent = nullptr); diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp deleted file mode 100644 index 46f3d610f..000000000 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ /dev/null @@ -1,2622 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 "qwebenginepage.h" -#include "qwebenginepage_p.h" - -#include "authentication_dialog_controller.h" -#include "profile_adapter.h" -#include "color_chooser_controller.h" -#include "favicon_manager.h" -#include "find_text_helper.h" -#include "file_picker_controller.h" -#include "javascript_dialog_controller.h" -#if QT_CONFIG(webengine_printing_and_pdf) -#include "printer_worker.h" -#endif -#include "qwebenginecertificateerror.h" -#include "qwebenginefindtextresult.h" -#include "qwebenginefullscreenrequest.h" -#include "qwebenginehistory.h" -#include "qwebenginehistory_p.h" -#include "qwebenginenotification.h" -#include "qwebengineprofile.h" -#include "qwebengineprofile_p.h" -#include "qwebenginequotarequest.h" -#include "qwebengineregisterprotocolhandlerrequest.h" -#include "qwebenginescriptcollection_p.h" -#include "qwebenginesettings.h" -#include "qwebengineview.h" -#include "qwebengineview_p.h" -#include "user_notification_controller.h" -#include "render_widget_host_view_qt_delegate_widget.h" -#include "web_contents_adapter.h" -#include "web_engine_settings.h" -#include "qwebenginescript.h" - -#include <QAction> -#include <QApplication> -#include <QAuthenticator> -#include <QClipboard> -#if QT_CONFIG(colordialog) -#include <QColorDialog> -#endif -#include <QContextMenuEvent> -#if QT_CONFIG(filedialog) -#include <QFileDialog> -#endif -#include <QKeyEvent> -#include <QIcon> -#if QT_CONFIG(inputdialog) -#include <QInputDialog> -#endif -#include <QLayout> -#include <QLoggingCategory> -#if QT_CONFIG(menu) -#include <QMenu> -#endif -#if QT_CONFIG(messagebox) -#include <QMessageBox> -#endif -#include <QMimeData> -#if QT_CONFIG(webengine_printing_and_pdf) -#include <QPrinter> -#include <QThread> -#endif -#include <QStandardPaths> -#include <QStyle> -#include <QTimer> -#include <QUrl> - -QT_BEGIN_NAMESPACE - -using namespace QtWebEngineCore; - -static const int MaxTooltipLength = 1024; - -static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition) -{ - switch (disposition) { - case WebContentsAdapterClient::NewForegroundTabDisposition: - return QWebEnginePage::WebBrowserTab; - case WebContentsAdapterClient::NewBackgroundTabDisposition: - return QWebEnginePage::WebBrowserBackgroundTab; - case WebContentsAdapterClient::NewPopupDisposition: - return QWebEnginePage::WebDialog; - case WebContentsAdapterClient::NewWindowDisposition: - return QWebEnginePage::WebBrowserWindow; - default: - Q_UNREACHABLE(); - } -} - -QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) - : adapter(QSharedPointer<WebContentsAdapter>::create()) - , history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this))) - , profile(_profile ? _profile : QWebEngineProfile::defaultProfile()) - , settings(new QWebEngineSettings(profile->settings())) - , view(0) - , isLoading(false) - , scriptCollection(new QWebEngineScriptCollectionPrivate(profileAdapter()->userResourceController(), adapter)) - , m_isBeingAdopted(false) - , m_backgroundColor(Qt::white) - , fullscreenMode(false) - , webChannel(nullptr) - , webChannelWorldId(QWebEngineScript::MainWorld) - , defaultAudioMuted(false) - , defaultZoomFactor(1.0) -#if QT_CONFIG(webengine_printing_and_pdf) - , currentPrinter(nullptr) -#endif -{ - memset(actions, 0, sizeof(actions)); - - qRegisterMetaType<QWebEngineQuotaRequest>(); - qRegisterMetaType<QWebEngineRegisterProtocolHandlerRequest>(); - qRegisterMetaType<QWebEngineFindTextResult>(); - - // See setVisible(). - wasShownTimer.setSingleShot(true); - QObject::connect(&wasShownTimer, &QTimer::timeout, [this](){ - ensureInitialized(); - }); - - profile->d_ptr->addWebContentsAdapterClient(this); -} - -QWebEnginePagePrivate::~QWebEnginePagePrivate() -{ - delete history; - delete settings; - profile->d_ptr->removeWebContentsAdapterClient(this); -} - -RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client) -{ - // Set the QWebEngineView as the parent for a popup delegate, so that the new popup window - // responds properly to clicks in case the QWebEngineView is inside a modal QDialog. Setting the - // parent essentially notifies the OS that the popup window is part of the modal session, and - // should allow interaction. - // The new delegate will not be deleted by the parent view though, because we unset the parent - // when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is - // dismissed. - return new RenderWidgetHostViewQtDelegateWidget(client, this->view); -} - -void QWebEnginePagePrivate::initializationFinished() -{ - if (m_backgroundColor != Qt::white) - adapter->setBackgroundColor(m_backgroundColor); -#if QT_CONFIG(webengine_webchannel) - if (webChannel) - adapter->setWebChannel(webChannel, webChannelWorldId); -#endif - if (defaultAudioMuted != adapter->isAudioMuted()) - adapter->setAudioMuted(defaultAudioMuted); - if (!qFuzzyCompare(adapter->currentZoomFactor(), defaultZoomFactor)) - adapter->setZoomFactor(defaultZoomFactor); - if (view) - adapter->setVisible(view->isVisible()); - - scriptCollection.d->initializationFinished(adapter); - - m_isBeingAdopted = false; -} - -void QWebEnginePagePrivate::titleChanged(const QString &title) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->titleChanged(title); -} - -void QWebEnginePagePrivate::urlChanged() -{ - Q_Q(QWebEnginePage); - QUrl qurl = adapter->activeUrl(); - if (url != qurl) { - url = qurl; - Q_EMIT q->urlChanged(qurl); - } -} - -void QWebEnginePagePrivate::iconChanged(const QUrl &url) -{ - Q_Q(QWebEnginePage); - if (iconUrl == url) - return; - iconUrl = url; - Q_EMIT q->iconUrlChanged(iconUrl); - Q_EMIT q->iconChanged(adapter->faviconManager()->getIcon()); -} - -void QWebEnginePagePrivate::loadProgressChanged(int progress) -{ - Q_Q(QWebEnginePage); - QTimer::singleShot(0, q, [q, progress] () { Q_EMIT q->loadProgress(progress); }); -} - -void QWebEnginePagePrivate::didUpdateTargetURL(const QUrl &hoveredUrl) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->linkHovered(hoveredUrl.toString()); -} - -void QWebEnginePagePrivate::selectionChanged() -{ - Q_Q(QWebEnginePage); - QTimer::singleShot(0, q, [this, q]() { - updateEditActions(); - Q_EMIT q->selectionChanged(); - }); -} - -void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->recentlyAudibleChanged(recentlyAudible); -} - -void QWebEnginePagePrivate::renderProcessPidChanged(qint64 pid) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->renderProcessPidChanged(pid); -} - -QRectF QWebEnginePagePrivate::viewportRect() const -{ - return view ? view->rect() : QRectF(); -} - -QColor QWebEnginePagePrivate::backgroundColor() const -{ - return m_backgroundColor; -} - -void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage) -{ - Q_UNUSED(provisionalUrl); - Q_Q(QWebEnginePage); - - if (isErrorPage) - return; - - isLoading = true; - - QTimer::singleShot(0, q, &QWebEnginePage::loadStarted); -} - -void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) -{ - Q_Q(QWebEnginePage); - Q_UNUSED(url); - Q_UNUSED(errorCode); - Q_UNUSED(errorDescription); - - if (isErrorPage) { - Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)); - QTimer::singleShot(0, q, [q](){ - emit q->loadFinished(false); - }); - return; - } - - isLoading = false; - // Delay notifying failure until the error-page is done loading. - // Error-pages are not loaded on failures due to abort. - if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) { - QTimer::singleShot(0, q, [q, success](){ - emit q->loadFinished(success); - }); - } -} - -void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool success) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->pdfPrintingFinished(filePath, success); -} - -void QWebEnginePagePrivate::focusContainer() -{ - if (view) { - view->activateWindow(); - view->setFocus(); - } -} - -void QWebEnginePagePrivate::unhandledKeyEvent(QKeyEvent *event) -{ - if (view && view->parentWidget()) - QGuiApplication::sendEvent(view->parentWidget(), event); -} - -QSharedPointer<WebContentsAdapter> -QWebEnginePagePrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, - WindowOpenDisposition disposition, bool userGesture, - const QRect &initialGeometry, const QUrl &targetUrl) -{ - Q_Q(QWebEnginePage); - Q_UNUSED(userGesture); - Q_UNUSED(targetUrl); - - QWebEnginePage *newPage = q->createWindow(toWindowType(disposition)); - if (!newPage) - return nullptr; - - if (!newWebContents->webContents()) - return newPage->d_func()->adapter; // Reuse existing adapter - - // Mark the new page as being in the process of being adopted, so that a second mouse move event - // sent by newWebContents->initialize() gets filtered in RenderWidgetHostViewQt::forwardEvent. - // The first mouse move event is being sent by q->createWindow(). This is necessary because - // Chromium does not get a mouse move acknowledgment message between the two events, and - // InputRouterImpl::ProcessMouseAck is not executed, thus all subsequent mouse move events - // get coalesced together, and don't get processed at all. - // The mouse move events are actually sent as a result of show() being called on - // RenderWidgetHostViewQtDelegateWidget, both when creating the window and when initialize is - // called. - newPage->d_func()->m_isBeingAdopted = true; - - // Overwrite the new page's WebContents with ours. - newPage->d_func()->adapter = newWebContents; - newWebContents->setClient(newPage->d_func()); - - if (!initialGeometry.isEmpty()) - emit newPage->geometryChangeRequested(initialGeometry); - - return newWebContents; -} - -bool QWebEnginePagePrivate::isBeingAdopted() -{ - return m_isBeingAdopted; -} - -void QWebEnginePagePrivate::close() -{ - Q_Q(QWebEnginePage); - Q_EMIT q->windowCloseRequested(); -} - -void QWebEnginePagePrivate::windowCloseRejected() -{ - // Do nothing for now. -} - -void QWebEnginePagePrivate::didRunJavaScript(quint64 requestId, const QVariant& result) -{ - m_callbacks.invoke(requestId, result); -} - -void QWebEnginePagePrivate::didFetchDocumentMarkup(quint64 requestId, const QString& result) -{ - m_callbacks.invoke(requestId, result); -} - -void QWebEnginePagePrivate::didFetchDocumentInnerText(quint64 requestId, const QString& result) -{ - m_callbacks.invoke(requestId, result); -} - -void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result) -{ -#if QT_CONFIG(webengine_printing_and_pdf) - Q_Q(QWebEnginePage); - - // If no currentPrinter is set that means that were printing to PDF only. - if (!currentPrinter) { - if (!result.data()) - return; - m_callbacks.invoke(requestId, *(result.data())); - return; - } - - QThread *printerThread = new QThread; - QObject::connect(printerThread, &QThread::finished, printerThread, &QThread::deleteLater); - printerThread->start(); - - PrinterWorker *printerWorker = new PrinterWorker(result, currentPrinter); - QObject::connect(printerWorker, &PrinterWorker::resultReady, q, [requestId, this](bool success) { - currentPrinter = nullptr; - m_callbacks.invoke(requestId, success); - }); - - QObject::connect(printerWorker, &PrinterWorker::resultReady, printerThread, &QThread::quit); - QObject::connect(printerThread, &QThread::finished, printerWorker, &PrinterWorker::deleteLater); - - printerWorker->moveToThread(printerThread); - QMetaObject::invokeMethod(printerWorker, "print"); - -#else - // we should never enter this branch, but just for safe-keeping... - Q_UNUSED(result); - m_callbacks.invoke(requestId, QByteArray()); -#endif -} - -bool QWebEnginePagePrivate::passOnFocus(bool reverse) -{ - if (view) - return view->focusNextPrevChild(!reverse); - return false; -} - -void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller) -{ - Q_Q(QWebEnginePage); - QAuthenticator networkAuth; - networkAuth.setRealm(controller->realm()); - - if (controller->isProxy()) - Q_EMIT q->proxyAuthenticationRequired(controller->url(), &networkAuth, controller->host()); - else - Q_EMIT q->authenticationRequired(controller->url(), &networkAuth); - - // Authentication has been cancelled - if (networkAuth.isNull()) { - controller->reject(); - return; - } - - controller->accept(networkAuth.user(), networkAuth.password()); -} - -void QWebEnginePagePrivate::releaseProfile() -{ - qWarning("Release of profile requested but WebEnginePage still not deleted. Expect troubles !"); - // this is not the way to go, but might avoid the crash if user code does not make any calls to page. - delete q_ptr->d_ptr.take(); -} - -void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserController> controller) -{ -#if QT_CONFIG(colordialog) - QColorDialog *dialog = new QColorDialog(controller.data()->initialColor(), view); - - QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), controller.data(), SLOT(accept(QColor))); - QColorDialog::connect(dialog, SIGNAL(rejected()), controller.data(), SLOT(reject())); - - // Delete when done - QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), dialog, SLOT(deleteLater())); - QColorDialog::connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater())); - - dialog->open(); -#else - Q_UNUSED(controller); -#endif -} - -void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags) -{ - Q_Q(QWebEnginePage); - QWebEnginePage::Feature feature; - if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && - requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) - feature = QWebEnginePage::MediaAudioVideoCapture; - else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)) - feature = QWebEnginePage::MediaAudioCapture; - else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) - feature = QWebEnginePage::MediaVideoCapture; - else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) && - requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) - feature = QWebEnginePage::DesktopAudioVideoCapture; - else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) - feature = QWebEnginePage::DesktopVideoCapture; - Q_EMIT q->featurePermissionRequested(securityOrigin, feature); -} - -static QWebEnginePage::Feature toFeature(QtWebEngineCore::ProfileAdapter::PermissionType type) -{ - switch (type) { - case QtWebEngineCore::ProfileAdapter::NotificationPermission: - return QWebEnginePage::Notifications; - case QtWebEngineCore::ProfileAdapter::GeolocationPermission: - return QWebEnginePage::Geolocation; - default: - break; - } - Q_UNREACHABLE(); - return QWebEnginePage::Feature(-1); -} - -void QWebEnginePagePrivate::runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->featurePermissionRequested(securityOrigin, toFeature(permission)); -} - -void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock); -} - -void QWebEnginePagePrivate::runQuotaRequest(QWebEngineQuotaRequest request) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->quotaRequested(request); -} - -void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->registerProtocolHandlerRequested(request); -} - -QObject *QWebEnginePagePrivate::accessibilityParentObject() -{ - return view; -} - -void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const -{ -#ifdef QT_NO_ACTION - Q_UNUSED(action); -#else - QAction *a = actions[action]; - if (!a) - return; - - bool enabled = true; - - switch (action) { - case QWebEnginePage::Back: - enabled = adapter->canGoToOffset(-1); - break; - case QWebEnginePage::Forward: - enabled = adapter->canGoToOffset(1); - break; - case QWebEnginePage::Stop: - enabled = isLoading; - break; - case QWebEnginePage::Reload: - case QWebEnginePage::ReloadAndBypassCache: - enabled = !isLoading; - break; - case QWebEnginePage::ViewSource: - enabled = adapter->canViewSource(); - break; - case QWebEnginePage::Cut: - case QWebEnginePage::Copy: - case QWebEnginePage::Unselect: - enabled = adapter->hasFocusedFrame() && !adapter->selectedText().isEmpty(); - break; - case QWebEnginePage::Paste: - case QWebEnginePage::Undo: - case QWebEnginePage::Redo: - case QWebEnginePage::SelectAll: - case QWebEnginePage::PasteAndMatchStyle: - enabled = adapter->hasFocusedFrame(); - break; - default: - break; - } - - a->setEnabled(enabled); -#endif // QT_NO_ACTION -} - -void QWebEnginePagePrivate::updateNavigationActions() -{ - updateAction(QWebEnginePage::Back); - updateAction(QWebEnginePage::Forward); - updateAction(QWebEnginePage::Stop); - updateAction(QWebEnginePage::Reload); - updateAction(QWebEnginePage::ReloadAndBypassCache); - updateAction(QWebEnginePage::ViewSource); -} - -void QWebEnginePagePrivate::updateEditActions() -{ - updateAction(QWebEnginePage::Cut); - updateAction(QWebEnginePage::Copy); - updateAction(QWebEnginePage::Paste); - updateAction(QWebEnginePage::Undo); - updateAction(QWebEnginePage::Redo); - updateAction(QWebEnginePage::SelectAll); - updateAction(QWebEnginePage::PasteAndMatchStyle); - updateAction(QWebEnginePage::Unselect); -} - -#ifndef QT_NO_ACTION -void QWebEnginePagePrivate::_q_webActionTriggered(bool checked) -{ - Q_Q(QWebEnginePage); - QAction *a = qobject_cast<QAction *>(q->sender()); - if (!a) - return; - QWebEnginePage::WebAction action = static_cast<QWebEnginePage::WebAction>(a->data().toInt()); - q->triggerAction(action, checked); -} -#endif // QT_NO_ACTION - -void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input) -{ - QSharedPointer<WebContentsAdapter> newWebContents = WebContentsAdapter::createFromSerializedNavigationHistory(input, this); - if (newWebContents) { - adapter = std::move(newWebContents); - adapter->setClient(this); - adapter->loadDefault(); - } -} - -void QWebEnginePagePrivate::updateScrollPosition(const QPointF &position) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->scrollPositionChanged(position); -} - -void QWebEnginePagePrivate::updateContentsSize(const QSizeF &size) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->contentsSizeChanged(size); -} - -void QWebEnginePagePrivate::setFullScreenMode(bool fullscreen) -{ - if (fullscreenMode != fullscreen) { - fullscreenMode = fullscreen; - adapter->changedFullScreen(); - } -} - -ProfileAdapter* QWebEnginePagePrivate::profileAdapter() -{ - return profile->d_ptr->profileAdapter(); -} - -WebContentsAdapter *QWebEnginePagePrivate::webContentsAdapter() -{ - ensureInitialized(); - return adapter.data(); -} - -const QObject *QWebEnginePagePrivate::holdingQObject() const -{ - Q_Q(const QWebEnginePage); - return q; -} - -void QWebEnginePagePrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWidgetBase) -{ - Q_Q(QWebEnginePage); - bindPageAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateWidget *>(newWidgetBase)); -} - -void QWebEnginePagePrivate::findTextFinished(const QWebEngineFindTextResult &result) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->findTextFinished(result); -} - -void QWebEnginePagePrivate::ensureInitialized() const -{ - if (!adapter->isInitialized()) - adapter->loadDefault(); -} - -void QWebEnginePagePrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView *view) -{ - auto oldView = page ? page->d_func()->view : nullptr; - auto oldPage = view ? view->d_func()->page : nullptr; - - bool ownNewPage = false; - bool deleteOldPage = false; - - // Change pointers first. - - if (page && oldView != view) { - if (oldView) { - ownNewPage = oldView->d_func()->m_ownsPage; - oldView->d_func()->page = nullptr; - oldView->d_func()->m_ownsPage = false; - } - page->d_func()->view = view; - } - - if (view && oldPage != page) { - if (oldPage) { - if (oldPage->d_func()) - oldPage->d_func()->view = nullptr; - deleteOldPage = view->d_func()->m_ownsPage; - } - view->d_func()->m_ownsPage = ownNewPage; - view->d_func()->page = page; - } - - // Then notify. - - auto widget = page ? page->d_func()->widget : nullptr; - auto oldWidget = (oldPage && oldPage->d_func()) ? oldPage->d_func()->widget : nullptr; - - if (page && oldView != view && oldView) { - oldView->d_func()->pageChanged(page, nullptr); - if (widget) - oldView->d_func()->widgetChanged(widget, nullptr); - } - - if (view && oldPage != page) { - if (oldPage && oldPage->d_func()) - view->d_func()->pageChanged(oldPage, page); - else - view->d_func()->pageChanged(nullptr, page); - if (oldWidget != widget) - view->d_func()->widgetChanged(oldWidget, widget); - } - if (deleteOldPage) - delete oldPage; -} - -void QWebEnginePagePrivate::bindPageAndWidget(QWebEnginePage *page, RenderWidgetHostViewQtDelegateWidget *widget) -{ - auto oldPage = widget ? widget->m_page : nullptr; - auto oldWidget = page ? page->d_func()->widget : nullptr; - - // Change pointers first. - - if (widget && oldPage != page) { - if (oldPage && oldPage->d_func()) - oldPage->d_func()->widget = nullptr; - widget->m_page = page; - } - - if (page && oldWidget != widget) { - if (oldWidget) - oldWidget->m_page = nullptr; - page->d_func()->widget = widget; - } - - // Then notify. - - if (widget && oldPage != page && oldPage && oldPage->d_func()) { - if (auto oldView = oldPage->d_func()->view) - oldView->d_func()->widgetChanged(widget, nullptr); - } - - if (page && oldWidget != widget) { - if (auto view = page->d_func()->view) - view->d_func()->widgetChanged(oldWidget, widget); - } -} - -QWebEnginePage::QWebEnginePage(QObject* parent) - : QObject(parent) - , d_ptr(new QWebEnginePagePrivate()) -{ - Q_D(QWebEnginePage); - d->q_ptr = this; - d->adapter->setClient(d); -} - -/*! - \fn void QWebEnginePage::findTextFinished(const QWebEngineFindTextResult &result) - \since 5.14 - - This signal is emitted when a search string search on a page is completed. \a result is - the result of the string search. - - \sa findText() -*/ - -/*! - \fn void QWebEnginePage::printRequested() - \since 5.12 - - This signal is emitted when the JavaScript \c{window.print()} method is called. - Typically, the signal handler can simply call printToPdf(). - - \sa printToPdf() -*/ - -/*! - \enum QWebEnginePage::RenderProcessTerminationStatus - \since 5.6 - - This enum describes the status with which the render process terminated: - - \value NormalTerminationStatus - The render process terminated normally. - \value AbnormalTerminationStatus - The render process terminated with with a non-zero exit status. - \value CrashedTerminationStatus - The render process crashed, for example because of a segmentation fault. - \value KilledTerminationStatus - The render process was killed, for example by \c SIGKILL or task manager kill. -*/ - -/*! - \fn QWebEnginePage::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) - \since 5.6 - - This signal is emitted when the render process is terminated with a non-zero exit status. - \a terminationStatus is the termination status of the process and \a exitCode is the status code - with which the process terminated. -*/ - -/*! - \fn QWebEnginePage::fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest) - - This signal is emitted when the web page issues the request to enter fullscreen mode for - a web-element, usually a video element. - - The request object \a fullScreenRequest can be used to accept or reject the request. - - If the request is accepted the element requesting fullscreen will fill the viewport, - but it is up to the application to make the view fullscreen or move the page to a view - that is fullscreen. - - \sa QWebEngineSettings::FullScreenSupportEnabled -*/ - -/*! - \fn QWebEnginePage::quotaRequested(QWebEngineQuotaRequest quotaRequest) - \since 5.11 - - This signal is emitted when the web page requests larger persistent storage - than the application's current allocation in File System API. The default quota - is 0 bytes. - - The request object \a quotaRequest can be used to accept or reject the request. -*/ - -/*! - \fn QWebEnginePage::registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request) - \since 5.11 - - This signal is emitted when the web page tries to register a custom protocol - using the \l registerProtocolHandler API. - - The request object \a request can be used to accept or reject the request: - - \snippet webenginewidgets/simplebrowser/webpage.cpp registerProtocolHandlerRequested -*/ - -/*! - \fn void QWebEnginePage::pdfPrintingFinished(const QString &filePath, bool success) - \since 5.9 - - This signal is emitted when printing the web page into a PDF file has - finished. - \a filePath will contain the path the file was requested to be created - at, and \a success will be \c true if the file was successfully created and - \c false otherwise. - - \sa printToPdf() -*/ - -/*! - \property QWebEnginePage::scrollPosition - \since 5.7 - - \brief The scroll position of the page contents. -*/ - -/*! - \property QWebEnginePage::contentsSize - \since 5.7 - - \brief The size of the page contents. -*/ - -/*! - \fn void QWebEnginePage::audioMutedChanged(bool muted) - \since 5.7 - - This signal is emitted when the page's \a muted state changes. - \note Not to be confused with a specific HTML5 audio or video element being muted. -*/ - -/*! - \fn void QWebEnginePage::recentlyAudibleChanged(bool recentlyAudible); - \since 5.7 - - This signal is emitted when the page's audible state, \a recentlyAudible, changes, because - the audio is played or stopped. - - \note The signal is also emitted when calling the setAudioMuted() method. - Also, if the audio is paused, this signal is emitted with an approximate \b{two-second - delay}, from the moment the audio is paused. -*/ - -/*! - \fn void QWebEnginePage::renderProcessPidChanged(qint64 pid); - \since 5.15 - - This signal is emitted when the underlying render process PID, \a renderProcessPid, changes. -*/ - -/*! - \fn void QWebEnginePage::iconUrlChanged(const QUrl &url) - - This signal is emitted when the URL of the icon ("favicon") associated with the - page is changed. The new URL is specified by \a url. - - \sa iconUrl(), icon(), iconChanged() -*/ - -/*! - \fn void QWebEnginePage::iconChanged(const QIcon &icon) - \since 5.7 - - This signal is emitted when the icon ("favicon") associated with the - page is changed. The new icon is specified by \a icon. - - \sa icon(), iconUrl(), iconUrlChanged() -*/ - -/*! - Constructs an empty web engine page in the web engine profile \a profile with the parent - \a parent. - - If the profile is not the default profile, the caller must ensure that the profile stays alive - for as long as the page does. - - \since 5.5 -*/ -QWebEnginePage::QWebEnginePage(QWebEngineProfile *profile, QObject* parent) - : QObject(parent) - , d_ptr(new QWebEnginePagePrivate(profile)) -{ - Q_D(QWebEnginePage); - d->q_ptr = this; - d->adapter->setClient(d); -} - -QWebEnginePage::~QWebEnginePage() -{ - if (d_ptr) { - // d_ptr might be exceptionally null if profile adapter got deleted first - setDevToolsPage(nullptr); - QWebEnginePagePrivate::bindPageAndView(this, nullptr); - QWebEnginePagePrivate::bindPageAndWidget(this, nullptr); - } -} - -QWebEngineHistory *QWebEnginePage::history() const -{ - Q_D(const QWebEnginePage); - return d->history; -} - -QWebEngineSettings *QWebEnginePage::settings() const -{ - Q_D(const QWebEnginePage); - return d->settings; -} - -/*! - * Returns a pointer to the web channel instance used by this page or a null pointer if none was set. - * This channel automatically uses the internal web engine transport mechanism over Chromium IPC - * that is exposed in the JavaScript context of this page as \c qt.webChannelTransport. - * - * \since 5.5 - * \sa setWebChannel() - */ -QWebChannel *QWebEnginePage::webChannel() const -{ -#if QT_CONFIG(webengine_webchannel) - Q_D(const QWebEnginePage); - return d->webChannel; -#endif - qWarning("WebEngine compiled without webchannel support"); - return nullptr; -} - -/*! - * \overload - * - * Sets the web channel instance to be used by this page to \a channel and installs - * it in the main JavaScript world. - * - * With this method the web channel can be accessed by web page content. If the content - * is not under your control and might be hostile, this could be a security issue and - * you should consider installing it in a private JavaScript world. - * - * \since 5.5 - * \sa QWebEngineScript::MainWorld - */ - -void QWebEnginePage::setWebChannel(QWebChannel *channel) -{ - setWebChannel(channel, QWebEngineScript::MainWorld); -} - -/*! - * Sets the web channel instance to be used by this page to \a channel and connects it to - * web engine's transport using Chromium IPC messages. The transport is exposed in the JavaScript - * world \a worldId as - * \c qt.webChannelTransport, which should be used when using the \l{Qt WebChannel JavaScript API}. - * - * \note The page does not take ownership of the channel object. - * \note Only one web channel can be installed per page, setting one even in another JavaScript - * world uninstalls any already installed web channel. - * - * \since 5.7 - * \sa QWebEngineScript::ScriptWorldId - */ -void QWebEnginePage::setWebChannel(QWebChannel *channel, uint worldId) -{ -#if QT_CONFIG(webengine_webchannel) - Q_D(QWebEnginePage); - if (d->webChannel != channel || d->webChannelWorldId != worldId) { - d->webChannel = channel; - d->webChannelWorldId = worldId; - d->adapter->setWebChannel(channel, worldId); - } -#else - Q_UNUSED(channel); - Q_UNUSED(worldId); - qWarning("WebEngine compiled without webchannel support"); -#endif -} - -/*! - \property QWebEnginePage::backgroundColor - \brief The page's background color behind the document's body. - \since 5.6 - - You can set the background color to Qt::transparent or to a translucent - color to see through the document, or you can set it to match your - web content in a hybrid application to prevent the white flashes that may appear - during loading. - - The default value is white. -*/ -QColor QWebEnginePage::backgroundColor() const -{ - Q_D(const QWebEnginePage); - return d->m_backgroundColor; -} - -void QWebEnginePage::setBackgroundColor(const QColor &color) -{ - Q_D(QWebEnginePage); - if (d->m_backgroundColor == color) - return; - d->m_backgroundColor = color; - d->adapter->setBackgroundColor(color); -} - -/*! - * Save the currently loaded web page to disk. - * - * The web page is saved to \a filePath in the specified \a{format}. - * - * This is a short cut for the following actions: - * \list - * \li Trigger the Save web action. - * \li Accept the next download item and set the specified file path and save format. - * \endlist - * - * This function issues an asynchronous download request for the web page and returns immediately. - * - * \sa QWebEngineDownloadRequest::SavePageFormat - * \since 5.8 - */ -void QWebEnginePage::save(const QString &filePath, - QWebEngineDownloadRequest::SavePageFormat format) const -{ - Q_D(const QWebEnginePage); - d->ensureInitialized(); - d->adapter->save(filePath, format); -} - -/*! - \property QWebEnginePage::audioMuted - \brief Whether the current page audio is muted. - \since 5.7 - - The default value is \c false. - \sa recentlyAudible -*/ -bool QWebEnginePage::isAudioMuted() const { - Q_D(const QWebEnginePage); - if (d->adapter->isInitialized()) - return d->adapter->isAudioMuted(); - return d->defaultAudioMuted; -} - -void QWebEnginePage::setAudioMuted(bool muted) { - Q_D(QWebEnginePage); - bool wasAudioMuted = isAudioMuted(); - d->defaultAudioMuted = muted; - d->adapter->setAudioMuted(muted); - if (wasAudioMuted != isAudioMuted()) - Q_EMIT audioMutedChanged(muted); -} - -/*! - \property QWebEnginePage::recentlyAudible - \brief The current page's \e {audible state}, that is, whether audio was recently played - or not. - \since 5.7 - - The default value is \c false. - \sa audioMuted -*/ -bool QWebEnginePage::recentlyAudible() const -{ - Q_D(const QWebEnginePage); - return d->adapter->isInitialized() && d->adapter->recentlyAudible(); -} - -/*! - \property QWebEnginePage::renderProcessPid - \brief The process ID (PID) of the render process assigned to the current - page's main frame. - \since 5.15 - - If no render process is available yet, \c 0 is returned. -*/ -qint64 QWebEnginePage::renderProcessPid() const -{ - Q_D(const QWebEnginePage); - return d->adapter->renderProcessPid(); -} - -void QWebEnginePage::setView(QWidget *newViewBase) -{ - QWebEnginePagePrivate::bindPageAndView(this, qobject_cast<QWebEngineView *>(newViewBase)); -} - -QWidget *QWebEnginePage::view() const -{ - Q_D(const QWebEnginePage); - return d->view; -} - -/*! - Returns the web engine profile the page belongs to. - \since 5.5 -*/ -QWebEngineProfile *QWebEnginePage::profile() const -{ - Q_D(const QWebEnginePage); - return d->profile; -} - -bool QWebEnginePage::hasSelection() const -{ - return !selectedText().isEmpty(); -} - -QString QWebEnginePage::selectedText() const -{ - Q_D(const QWebEnginePage); - return d->adapter->selectedText(); -} - -#ifndef QT_NO_ACTION -QAction *QWebEnginePage::action(WebAction action) const -{ - Q_D(const QWebEnginePage); - if (action == QWebEnginePage::NoWebAction) - return 0; - if (d->actions[action]) - return d->actions[action]; - - QString text; - QIcon icon; - QStyle *style = d->view ? d->view->style() : qApp->style(); - - switch (action) { - case Back: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back); - icon = style->standardIcon(QStyle::SP_ArrowBack); - break; - case Forward: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward); - icon = style->standardIcon(QStyle::SP_ArrowForward); - break; - case Stop: - text = tr("Stop"); - icon = style->standardIcon(QStyle::SP_BrowserStop); - break; - case Reload: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload); - icon = style->standardIcon(QStyle::SP_BrowserReload); - break; - case ReloadAndBypassCache: - text = tr("Reload and Bypass Cache"); - icon = style->standardIcon(QStyle::SP_BrowserReload); - break; - case Cut: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut); - break; - case Copy: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy); - break; - case Paste: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste); - break; - case Undo: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo); - break; - case Redo: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo); - break; - case SelectAll: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll); - break; - case PasteAndMatchStyle: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle); - break; - case OpenLinkInThisWindow: - text = tr("Open link in this window"); - break; - case OpenLinkInNewWindow: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewWindow); - break; - case OpenLinkInNewTab: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewTab); - break; - case OpenLinkInNewBackgroundTab: - text = tr("Open link in new background tab"); - break; - case CopyLinkToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyLinkToClipboard); - break; - case DownloadLinkToDisk: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadLinkToDisk); - break; - case CopyImageToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageToClipboard); - break; - case CopyImageUrlToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageUrlToClipboard); - break; - case DownloadImageToDisk: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadImageToDisk); - break; - case CopyMediaUrlToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyMediaUrlToClipboard); - break; - case ToggleMediaControls: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaControls); - break; - case ToggleMediaLoop: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaLoop); - break; - case ToggleMediaPlayPause: - text = tr("Toggle Play/Pause"); - break; - case ToggleMediaMute: - text = tr("Toggle Mute"); - break; - case DownloadMediaToDisk: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk); - break; - case InspectElement: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::InspectElement); - break; - case ExitFullScreen: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen); - break; - case RequestClose: - text = tr("Close Page"); - break; - case Unselect: - text = tr("Unselect"); - break; - case SavePage: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage); - break; - case ViewSource: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource); - break; - case ToggleBold: - text = tr("&Bold"); - break; - case ToggleItalic: - text = tr("&Italic"); - break; - case ToggleUnderline: - text = tr("&Underline"); - break; - case ToggleStrikethrough: - text = tr("&Strikethrough"); - break; - case AlignLeft: - text = tr("Align &Left"); - break; - case AlignCenter: - text = tr("Align &Center"); - break; - case AlignRight: - text = tr("Align &Right"); - break; - case AlignJustified: - text = tr("Align &Justified"); - break; - case Indent: - text = tr("&Indent"); - break; - case Outdent: - text = tr("&Outdent"); - break; - case InsertOrderedList: - text = tr("Insert &Ordered List"); - break; - case InsertUnorderedList: - text = tr("Insert &Unordered List"); - break; - case NoWebAction: - case WebActionCount: - Q_UNREACHABLE(); - break; - } - - QAction *a = new QAction(const_cast<QWebEnginePage*>(this)); - a->setText(text); - a->setData(action); - a->setIcon(icon); - - connect(a, SIGNAL(triggered(bool)), this, SLOT(_q_webActionTriggered(bool))); - - d->actions[action] = a; - d->updateAction(action); - return a; -} -#endif // QT_NO_ACTION - -void QWebEnginePage::triggerAction(WebAction action, bool) -{ - Q_D(QWebEnginePage); - d->ensureInitialized(); - switch (action) { - case Back: - d->adapter->navigateBack(); - break; - case Forward: - d->adapter->navigateForward(); - break; - case Stop: - d->adapter->stop(); - break; - case Reload: - d->adapter->reload(); - break; - case ReloadAndBypassCache: - d->adapter->reloadAndBypassCache(); - break; - case Cut: - d->adapter->cut(); - break; - case Copy: - d->adapter->copy(); - break; - case Paste: - d->adapter->paste(); - break; - case Undo: - d->adapter->undo(); - break; - case Redo: - d->adapter->redo(); - break; - case SelectAll: - d->adapter->selectAll(); - break; - case PasteAndMatchStyle: - d->adapter->pasteAndMatchStyle(); - break; - case Unselect: - d->adapter->unselect(); - break; - case OpenLinkInThisWindow: - if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid()) - setUrl(d->view->lastContextMenuRequest()->filteredLinkUrl()); - break; - case OpenLinkInNewWindow: - if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid()) { - QWebEnginePage *newPage = createWindow(WebBrowserWindow); - if (newPage) - newPage->setUrl(d->view->lastContextMenuRequest()->filteredLinkUrl()); - } - break; - case OpenLinkInNewTab: - if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid()) { - QWebEnginePage *newPage = createWindow(WebBrowserTab); - if (newPage) - newPage->setUrl(d->view->lastContextMenuRequest()->filteredLinkUrl()); - } - break; - case OpenLinkInNewBackgroundTab: - if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid()) { - QWebEnginePage *newPage = createWindow(WebBrowserBackgroundTab); - if (newPage) - newPage->setUrl(d->view->lastContextMenuRequest()->filteredLinkUrl()); - } - break; - case CopyLinkToClipboard: - if (d->view && !d->view->lastContextMenuRequest()->linkUrl().isEmpty()) { - QString urlString = d->view->lastContextMenuRequest()->linkUrl().toString( - QUrl::FullyEncoded); - QString linkText = d->view->lastContextMenuRequest()->linkText().toHtmlEscaped(); - QString title = d->view->lastContextMenuRequest()->titleText(); - if (!title.isEmpty()) - title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped()); - QMimeData *data = new QMimeData(); - data->setText(urlString); - QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral(">") - + linkText + QStringLiteral("</a>"); - data->setHtml(html); - data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->linkUrl()); - qApp->clipboard()->setMimeData(data); - } - break; - case DownloadLinkToDisk: - if (d->view && d->view->lastContextMenuRequest()->filteredLinkUrl().isValid()) - d->adapter->download(d->view->lastContextMenuRequest()->filteredLinkUrl(), - d->view->lastContextMenuRequest()->suggestedFileName(), - d->view->lastContextMenuRequest()->referrerUrl(), - d->view->lastContextMenuRequest()->referrerPolicy()); - - break; - case CopyImageToClipboard: - if (d->view && d->view->lastContextMenuRequest()->hasImageContent() - && (d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeImage - || d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeCanvas)) { - d->adapter->copyImageAt(d->view->lastContextMenuRequest()->position()); - } - break; - case CopyImageUrlToClipboard: - if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid() - && d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeImage) { - QString urlString = - d->view->lastContextMenuRequest()->mediaUrl().toString(QUrl::FullyEncoded); - QString alt = d->view->lastContextMenuRequest()->altText(); - if (!alt.isEmpty()) - alt = QStringLiteral(" alt=\"%1\"").arg(alt.toHtmlEscaped()); - QString title = d->view->lastContextMenuRequest()->titleText(); - if (!title.isEmpty()) - title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped()); - QMimeData *data = new QMimeData(); - data->setText(urlString); - QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + alt + QStringLiteral("></img>"); - data->setHtml(html); - data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->mediaUrl()); - qApp->clipboard()->setMimeData(data); - } - break; - case DownloadImageToDisk: - case DownloadMediaToDisk: - if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid()) - d->adapter->download(d->view->lastContextMenuRequest()->mediaUrl(), - d->view->lastContextMenuRequest()->suggestedFileName(), - d->view->lastContextMenuRequest()->referrerUrl(), - d->view->lastContextMenuRequest()->referrerPolicy()); - break; - case CopyMediaUrlToClipboard: - if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid() - && (d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeAudio - || d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeVideo)) { - QString urlString = - d->view->lastContextMenuRequest()->mediaUrl().toString(QUrl::FullyEncoded); - QString title = d->view->lastContextMenuRequest()->titleText(); - if (!title.isEmpty()) - title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped()); - QMimeData *data = new QMimeData(); - data->setText(urlString); - if (d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeAudio) - data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"") + title + - QStringLiteral("></audio>")); - else - data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"") + title + - QStringLiteral("></video>")); - data->setUrls(QList<QUrl>() << d->view->lastContextMenuRequest()->mediaUrl()); - qApp->clipboard()->setMimeData(data); - } - break; - case ToggleMediaControls: - if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid() - && d->view->lastContextMenuRequest()->mediaFlags() - & QWebEngineContextMenuRequest::MediaCanToggleControls) { - bool enable = !(d->view->lastContextMenuRequest()->mediaFlags() - & QWebEngineContextMenuRequest::MediaControls); - d->adapter->executeMediaPlayerActionAt(d->view->lastContextMenuRequest()->position(), - WebContentsAdapter::MediaPlayerControls, enable); - } - break; - case ToggleMediaLoop: - if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid() - && (d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeAudio - || d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeVideo)) { - bool enable = !(d->view->lastContextMenuRequest()->mediaFlags() - & QWebEngineContextMenuRequest::MediaLoop); - d->adapter->executeMediaPlayerActionAt(d->view->lastContextMenuRequest()->position(), - WebContentsAdapter::MediaPlayerLoop, enable); - } - break; - case ToggleMediaPlayPause: - if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid() - && (d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeAudio - || d->view->lastContextMenuRequest()->mediaType() - == QWebEngineContextMenuRequest::MediaTypeVideo)) { - bool enable = (d->view->lastContextMenuRequest()->mediaFlags() - & QWebEngineContextMenuRequest::MediaPaused); - d->adapter->executeMediaPlayerActionAt(d->view->lastContextMenuRequest()->position(), - WebContentsAdapter::MediaPlayerPlay, enable); - } - break; - case ToggleMediaMute: - if (d->view && d->view->lastContextMenuRequest()->mediaUrl().isValid() - && d->view->lastContextMenuRequest()->mediaFlags() - & QWebEngineContextMenuRequest::MediaHasAudio) { - // Make sure to negate the value, so that toggling actually works. - bool enable = !(d->view->lastContextMenuRequest()->mediaFlags() - & QWebEngineContextMenuRequest::MediaMuted); - d->adapter->executeMediaPlayerActionAt(d->view->lastContextMenuRequest()->position(), - WebContentsAdapter::MediaPlayerMute, enable); - } - break; - case InspectElement: - if (d->view) - d->adapter->inspectElementAt(d->view->lastContextMenuRequest()->position()); - break; - case ExitFullScreen: - // See under ViewSource, anything that can trigger a delete of the current view is dangerous to call directly here. - QTimer::singleShot(0, this, [d](){ d->adapter->exitFullScreen(); }); - break; - case RequestClose: - d->adapter->requestClose(); - break; - case SavePage: - d->adapter->save(); - break; - case ViewSource: - // This is a workaround to make the ViewSource action working in a context menu. - // The WebContentsAdapter::viewSource() method deletes a - // RenderWidgetHostViewQtDelegateWidget instance which passes the control to the event - // loop. If the QMenu::aboutToHide() signal is connected to the QObject::deleteLater() - // slot the QMenu is deleted by the event handler while the ViewSource action is still not - // completed. This may lead to a crash. To avoid this the WebContentsAdapter::viewSource() - // method is called indirectly via the QTimer::singleShot() function which schedules the - // the viewSource() call after the QMenu's destruction. - QTimer::singleShot(0, this, [d](){ d->adapter->viewSource(); }); - break; - case ToggleBold: - runJavaScript(QStringLiteral("document.execCommand('bold');"), QWebEngineScript::ApplicationWorld); - break; - case ToggleItalic: - runJavaScript(QStringLiteral("document.execCommand('italic');"), QWebEngineScript::ApplicationWorld); - break; - case ToggleUnderline: - runJavaScript(QStringLiteral("document.execCommand('underline');"), QWebEngineScript::ApplicationWorld); - break; - case ToggleStrikethrough: - runJavaScript(QStringLiteral("document.execCommand('strikethrough');"), QWebEngineScript::ApplicationWorld); - break; - case AlignLeft: - runJavaScript(QStringLiteral("document.execCommand('justifyLeft');"), QWebEngineScript::ApplicationWorld); - break; - case AlignCenter: - runJavaScript(QStringLiteral("document.execCommand('justifyCenter');"), QWebEngineScript::ApplicationWorld); - break; - case AlignRight: - runJavaScript(QStringLiteral("document.execCommand('justifyRight');"), QWebEngineScript::ApplicationWorld); - break; - case AlignJustified: - runJavaScript(QStringLiteral("document.execCommand('justifyFull');"), QWebEngineScript::ApplicationWorld); - break; - case Indent: - runJavaScript(QStringLiteral("document.execCommand('indent');"), QWebEngineScript::ApplicationWorld); - break; - case Outdent: - runJavaScript(QStringLiteral("document.execCommand('outdent');"), QWebEngineScript::ApplicationWorld); - break; - case InsertOrderedList: - runJavaScript(QStringLiteral("document.execCommand('insertOrderedList');"), QWebEngineScript::ApplicationWorld); - break; - case InsertUnorderedList: - runJavaScript(QStringLiteral("document.execCommand('insertUnorderedList');"), QWebEngineScript::ApplicationWorld); - break; - case NoWebAction: - break; - case WebActionCount: - Q_UNREACHABLE(); - break; - } -} - -/*! - * \since 5.8 - * Replace the current misspelled word with \a replacement. - * - * The current misspelled word can be found in QWebEngineContextMenuRequest::misspelledWord(), - * and suggested replacements in QWebEngineContextMenuRequest::spellCheckerSuggestions(). - * - * \sa contextMenuData(), - */ - -void QWebEnginePage::replaceMisspelledWord(const QString &replacement) -{ - Q_D(QWebEnginePage); - d->adapter->replaceMisspelling(replacement); -} - -void QWebEnginePage::findText(const QString &subString, FindFlags options, const QWebEngineCallback<bool> &resultCallback) -{ - Q_D(QWebEnginePage); - if (!d->adapter->isInitialized()) { - QtWebEngineCore::CallbackDirectory().invokeEmpty(resultCallback); - return; - } - - d->adapter->findTextHelper()->startFinding(subString, options & FindCaseSensitively, options & FindBackward, resultCallback); -} - -/*! - * \reimp - */ -bool QWebEnginePage::event(QEvent *e) -{ - return QObject::event(e); -} - -void QWebEnginePagePrivate::contextMenuRequested(QWebEngineContextMenuRequest *data) -{ - if (view) - view->d_ptr->contextMenuRequested(data); -} - -void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) -{ - Q_Q(QWebEnginePage); - bool accepted = q->acceptNavigationRequest(url, static_cast<QWebEnginePage::NavigationType>(navigationType), isMainFrame); - if (accepted && adapter->findTextHelper()->isFindTextInProgress()) - adapter->findTextHelper()->stopFinding(); - navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest; -} - -void QWebEnginePagePrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen) -{ - Q_Q(QWebEnginePage); - QWebEngineFullScreenRequest request(origin, fullscreen, [q = QPointer(q)] (bool toggleOn) { if (q) q->d_ptr->setFullScreenMode(toggleOn); }); - Q_EMIT q->fullScreenRequested(std::move(request)); -} - -bool QWebEnginePagePrivate::isFullScreenMode() const -{ - return fullscreenMode; -} - -void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller) -{ - Q_Q(QWebEnginePage); - bool accepted = false; - QString promptResult; - switch (controller->type()) { - case AlertDialog: - q->javaScriptAlert(controller->securityOrigin(), controller->message()); - accepted = true; - break; - case ConfirmDialog: - accepted = q->javaScriptConfirm(controller->securityOrigin(), controller->message()); - break; - case PromptDialog: - accepted = q->javaScriptPrompt(controller->securityOrigin(), controller->message(), controller->defaultPrompt(), &promptResult); - if (accepted) - controller->textProvided(promptResult); - break; - case UnloadDialog: - accepted = q->javaScriptConfirm(controller->securityOrigin(), QCoreApplication::translate("QWebEnginePage", "Are you sure you want to leave this page? Changes that you made may not be saved.")); - break; - case InternalAuthorizationDialog: -#if QT_CONFIG(messagebox) - accepted = (QMessageBox::question(view, controller->title(), controller->message(), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes); -#endif // QT_CONFIG(messagebox) - break; - } - if (accepted) - controller->accept(); - else - controller->reject(); -} - -void QWebEnginePagePrivate::allowCertificateError(const QWebEngineCertificateError &error) -{ - Q_Q(QWebEnginePage); - q->certificateError(error); -} - -void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &controller) -{ - Q_Q(QWebEnginePage); - QWebEngineClientCertificateSelection certSelection(controller); - - Q_EMIT q->selectClientCertificate(certSelection); -} - -/*! - \fn void QWebEnginePage::selectClientCertificate(QWebEngineClientCertificateSelection clientCertificateSelection) - \since 5.12 - - This signal is emitted when a web site requests an SSL client certificate, and one or more were - found in system's client certificate store. - - Handling the signal is asynchronous, and loading will be waiting until a certificate is selected, - or the last copy of \a clientCertificateSelection is destroyed. - - If the signal is not handled, \a clientCertificateSelection is automatically destroyed, and loading - will continue without a client certificate. - - \sa QWebEngineClientCertificateSelection -*/ - -void QWebEnginePagePrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) -{ - Q_Q(QWebEnginePage); - q->javaScriptConsoleMessage(static_cast<QWebEnginePage::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID); -} - -void QWebEnginePagePrivate::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, - int exitCode) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->renderProcessTerminated(static_cast<QWebEnginePage::RenderProcessTerminationStatus>( - terminationStatus), exitCode); -} - -void QWebEnginePagePrivate::requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) -{ - Q_UNUSED(geometry); - Q_Q(QWebEnginePage); - Q_EMIT q->geometryChangeRequested(frameGeometry); -} - -void QWebEnginePagePrivate::startDragging(const content::DropData &dropData, - Qt::DropActions allowedActions, const QPixmap &pixmap, - const QPoint &offset) -{ -#if !QT_CONFIG(draganddrop) - Q_UNUSED(dropData); - Q_UNUSED(allowedActions); - Q_UNUSED(pixmap); - Q_UNUSED(offset); -#else - adapter->startDragging(view, dropData, allowedActions, pixmap, offset); -#endif // QT_CONFIG(draganddrop) -} - -bool QWebEnginePagePrivate::supportsDragging() const -{ - return true; -} - -bool QWebEnginePagePrivate::isEnabled() const -{ - const Q_Q(QWebEnginePage); - const QWidget *view = q->view(); - if (view) - return view->isEnabled(); - return true; -} - -void QWebEnginePagePrivate::setToolTip(const QString &toolTipText) -{ - if (!view) - return; - - // Hide tooltip if shown. - if (toolTipText.isEmpty()) { - if (!view->toolTip().isEmpty()) - view->setToolTip(QString()); - - return; - } - - // Update tooltip if text was changed. - QString wrappedTip = QLatin1String("<p style=\"white-space:pre-wrap\">") - % toolTipText.toHtmlEscaped().left(MaxTooltipLength) - % QLatin1String("</p>"); - if (view->toolTip() != wrappedTip) - view->setToolTip(wrappedTip); -} - -void QWebEnginePagePrivate::printRequested() -{ - Q_Q(QWebEnginePage); - QTimer::singleShot(0, q, [q](){ - Q_EMIT q->printRequested(); - }); -} - -void QWebEnginePagePrivate::lifecycleStateChanged(LifecycleState state) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->lifecycleStateChanged(static_cast<QWebEnginePage::LifecycleState>(state)); -} - -void QWebEnginePagePrivate::recommendedStateChanged(LifecycleState state) -{ - Q_Q(QWebEnginePage); - QTimer::singleShot(0, q, [q, state]() { - Q_EMIT q->recommendedStateChanged(static_cast<QWebEnginePage::LifecycleState>(state)); - }); -} - -void QWebEnginePagePrivate::visibleChanged(bool visible) -{ - Q_Q(QWebEnginePage); - Q_EMIT q->visibleChanged(visible); -} - -/*! - \since 5.13 - - Registers the request interceptor \a interceptor to intercept URL requests. - - The page does not take ownership of the pointer. This interceptor is called - after any interceptors on the profile, and unlike profile interceptors, only - URL requests from this page are intercepted. - - To unset the request interceptor, set a \c nullptr. - - \sa QWebEngineUrlRequestInfo, QWebEngineProfile::setUrlRequestInterceptor() -*/ - -void QWebEnginePage::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor) -{ - Q_D(QWebEnginePage); - d->adapter->setRequestInterceptor(interceptor); -} - -void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy) -{ - Q_D(QWebEnginePage); - if (policy == PermissionUnknown) { - switch (feature) { - case MediaAudioVideoCapture: - case MediaAudioCapture: - case MediaVideoCapture: - case DesktopAudioVideoCapture: - case DesktopVideoCapture: - case MouseLock: - break; - case Geolocation: - d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::GeolocationPermission, ProfileAdapter::AskPermission); - break; - case Notifications: - d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::AskPermission); - break; - } - return; - } - - const WebContentsAdapterClient::MediaRequestFlags audioVideoCaptureFlags( - WebContentsAdapterClient::MediaVideoCapture | - WebContentsAdapterClient::MediaAudioCapture); - const WebContentsAdapterClient::MediaRequestFlags desktopAudioVideoCaptureFlags( - WebContentsAdapterClient::MediaDesktopVideoCapture | - WebContentsAdapterClient::MediaDesktopAudioCapture); - - if (policy == PermissionGrantedByUser) { - switch (feature) { - case MediaAudioVideoCapture: - d->adapter->grantMediaAccessPermission(securityOrigin, audioVideoCaptureFlags); - break; - case MediaAudioCapture: - d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture); - break; - case MediaVideoCapture: - d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture); - break; - case DesktopAudioVideoCapture: - d->adapter->grantMediaAccessPermission(securityOrigin, desktopAudioVideoCaptureFlags); - break; - case DesktopVideoCapture: - d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaDesktopVideoCapture); - break; - case MouseLock: - d->adapter->grantMouseLockPermission(securityOrigin, true); - break; - case Geolocation: - d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::GeolocationPermission, ProfileAdapter::AllowedPermission); - break; - case Notifications: - d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::AllowedPermission); - break; - } - } else { // if (policy == PermissionDeniedByUser) - switch (feature) { - case MediaAudioVideoCapture: - case MediaAudioCapture: - case MediaVideoCapture: - case DesktopAudioVideoCapture: - case DesktopVideoCapture: - d->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone); - break; - case Geolocation: - d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::GeolocationPermission, ProfileAdapter::DeniedPermission); - break; - case MouseLock: - d->adapter->grantMouseLockPermission(securityOrigin, false); - break; - case Notifications: - d->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, ProfileAdapter::DeniedPermission); - break; - } - } -} - -static inline QWebEnginePage::FileSelectionMode toPublic(FilePickerController::FileChooserMode mode) -{ - // Should the underlying values change, we'll need a switch here. - return static_cast<QWebEnginePage::FileSelectionMode>(mode); -} - -void QWebEnginePagePrivate::runFileChooser(QSharedPointer<FilePickerController> controller) -{ - Q_Q(QWebEnginePage); - - QStringList selectedFileNames = q->chooseFiles(toPublic(controller->mode()), (QStringList() << controller->defaultFileName()), controller->acceptedMimeTypes()); - - if (!selectedFileNames.empty()) - controller->accepted(selectedFileNames); - else - controller->rejected(); -} - -QWebEngineSettings *QWebEnginePagePrivate::webEngineSettings() const -{ - return settings; -} - -/*! - \since 5.10 - Downloads the resource from the location given by \a url to a local file. - - If \a filename is given, it is used as the suggested file name. - If it is relative, the file is saved in the standard download location with - the given name. - If it is a null or empty QString, the default file name is used. - - This will emit QWebEngineProfile::downloadRequested() after the download - has started. -*/ - -void QWebEnginePage::download(const QUrl& url, const QString& filename) -{ - Q_D(QWebEnginePage); - d->ensureInitialized(); - d->adapter->download(url, filename); -} - -void QWebEnginePage::load(const QUrl& url) -{ - Q_D(QWebEnginePage); - d->adapter->load(url); -} - -/*! - \since 5.9 - Issues the specified \a request and loads the response. - - \sa load(), setUrl(), url(), urlChanged(), QUrl::fromUserInput() -*/ -void QWebEnginePage::load(const QWebEngineHttpRequest& request) -{ - Q_D(QWebEnginePage); - d->adapter->load(request); -} - -void QWebEnginePage::toHtml(const QWebEngineCallback<const QString &> &resultCallback) const -{ - Q_D(const QWebEnginePage); - d->ensureInitialized(); - quint64 requestId = d->adapter->fetchDocumentMarkup(); - d->m_callbacks.registerCallback(requestId, resultCallback); -} - -void QWebEnginePage::toPlainText(const QWebEngineCallback<const QString &> &resultCallback) const -{ - Q_D(const QWebEnginePage); - d->ensureInitialized(); - quint64 requestId = d->adapter->fetchDocumentInnerText(); - d->m_callbacks.registerCallback(requestId, resultCallback); -} - -void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl) -{ - setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl); -} - -void QWebEnginePage::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl) -{ - Q_D(QWebEnginePage); - d->adapter->setContent(data, mimeType, baseUrl); -} - -QString QWebEnginePage::title() const -{ - Q_D(const QWebEnginePage); - return d->adapter->pageTitle(); -} - -void QWebEnginePage::setUrl(const QUrl &url) -{ - Q_D(QWebEnginePage); - if (d->url != url) { - d->url = url; - emit urlChanged(url); - } - load(url); -} - -QUrl QWebEnginePage::url() const -{ - Q_D(const QWebEnginePage); - return d->url; -} - -QUrl QWebEnginePage::requestedUrl() const -{ - Q_D(const QWebEnginePage); - return d->adapter->requestedUrl(); -} - -/*! - \property QWebEnginePage::iconUrl - \brief The URL of the icon associated with the page currently viewed. - - By default, this property contains an empty URL. - - \sa iconUrlChanged(), icon(), iconChanged() -*/ -QUrl QWebEnginePage::iconUrl() const -{ - Q_D(const QWebEnginePage); - return d->iconUrl; -} - -/*! - \property QWebEnginePage::icon - \brief The icon associated with the page currently viewed. - \since 5.7 - - By default, this property contains a null icon. If the web page specifies more than one icon, - the \c{icon} property encapsulates the available candidate icons in a single, - scalable \c{QIcon}. - - \sa iconChanged(), iconUrl(), iconUrlChanged() -*/ -QIcon QWebEnginePage::icon() const -{ - Q_D(const QWebEnginePage); - - if (d->iconUrl.isEmpty() || !d->adapter->isInitialized()) - return QIcon(); - - return d->adapter->faviconManager()->getIcon(); -} - -qreal QWebEnginePage::zoomFactor() const -{ - Q_D(const QWebEnginePage); - if (d->adapter->isInitialized()) - return d->adapter->currentZoomFactor(); - return d->defaultZoomFactor; -} - -void QWebEnginePage::setZoomFactor(qreal factor) -{ - Q_D(QWebEnginePage); - d->defaultZoomFactor = factor; - if (d->adapter->isInitialized()) - d->adapter->setZoomFactor(factor); -} - -void QWebEnginePage::runJavaScript(const QString &scriptSource) -{ - Q_D(QWebEnginePage); - d->ensureInitialized(); - if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) { - qWarning("runJavaScript: disabled in Discarded state"); - return; - } - d->adapter->runJavaScript(scriptSource, QWebEngineScript::MainWorld); -} - -void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngineCallback<const QVariant &> &resultCallback) -{ - Q_D(QWebEnginePage); - d->ensureInitialized(); - if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) { - qWarning("runJavaScript: disabled in Discarded state"); - d->m_callbacks.invokeEmpty(resultCallback); - return; - } - quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, QWebEngineScript::MainWorld); - d->m_callbacks.registerCallback(requestId, resultCallback); -} - -void QWebEnginePage::runJavaScript(const QString &scriptSource, quint32 worldId) -{ - Q_D(QWebEnginePage); - d->ensureInitialized(); - d->adapter->runJavaScript(scriptSource, worldId); -} - -void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId, const QWebEngineCallback<const QVariant &> &resultCallback) -{ - Q_D(QWebEnginePage); - d->ensureInitialized(); - quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, worldId); - d->m_callbacks.registerCallback(requestId, resultCallback); -} - -/*! - Returns the collection of scripts that are injected into the page. - - In addition, a page might also execute scripts - added through QWebEngineProfile::scripts(). - - \sa QWebEngineScriptCollection, QWebEngineScript, {Script Injection} -*/ - -QWebEngineScriptCollection &QWebEnginePage::scripts() -{ - Q_D(QWebEnginePage); - return d->scriptCollection; -} - -QWebEnginePage *QWebEnginePage::createWindow(WebWindowType type) -{ - Q_D(QWebEnginePage); - if (d->view) { - QWebEngineView *newView = d->view->createWindow(type); - if (newView) - return newView->page(); - } - return 0; -} - -/*! - \since 5.11 - Returns the page this page is inspecting, if any. - - Returns \c nullptr if this page is not a developer tools page. - - \sa setInspectedPage(), devToolsPage() -*/ - -QWebEnginePage *QWebEnginePage::inspectedPage() const -{ - Q_D(const QWebEnginePage); - return d->inspectedPage; -} - -/*! - \since 5.11 - Navigates this page to an internal URL that is the developer - tools of \a page. - - This is the same as calling setDevToolsPage() on \a page - with \c this as argument. - - \sa inspectedPage(), setDevToolsPage() -*/ - -void QWebEnginePage::setInspectedPage(QWebEnginePage *page) -{ - Q_D(QWebEnginePage); - if (d->inspectedPage == page) - return; - QWebEnginePage *oldPage = d->inspectedPage; - d->inspectedPage = nullptr; - if (oldPage) - oldPage->setDevToolsPage(nullptr); - d->inspectedPage = page; - if (page) - page->setDevToolsPage(this); -} - -/*! - \since 5.11 - Returns the page that is hosting the developer tools - of this page, if any. - - Returns \c nullptr if no developer tools page is set. - - \sa setDevToolsPage(), inspectedPage() -*/ - -QWebEnginePage *QWebEnginePage::devToolsPage() const -{ - Q_D(const QWebEnginePage); - return d->devToolsPage; -} - -/*! - \since 5.11 - Binds \a devToolsPage to be the developer tools of this page. - Triggers \a devToolsPage to navigate to an internal URL - with the developer tools. - - This is the same as calling setInspectedPage() on \a devToolsPage - with \c this as argument. - - \sa devToolsPage(), setInspectedPage() -*/ - -void QWebEnginePage::setDevToolsPage(QWebEnginePage *devToolsPage) -{ - Q_D(QWebEnginePage); - if (d->devToolsPage == devToolsPage) - return; - d->ensureInitialized(); - QWebEnginePage *oldDevTools = d->devToolsPage; - d->devToolsPage = nullptr; - if (oldDevTools) - oldDevTools->setInspectedPage(nullptr); - d->devToolsPage = devToolsPage; - if (devToolsPage) - devToolsPage->setInspectedPage(this); - if (d->adapter) { - if (devToolsPage) - d->adapter->openDevToolsFrontend(devToolsPage->d_ptr->adapter); - else - d->adapter->closeDevToolsFrontend(); - } -} - -ASSERT_ENUMS_MATCH(FilePickerController::Open, QWebEnginePage::FileSelectOpen) -ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, QWebEnginePage::FileSelectOpenMultiple) - -QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) -{ -#if QT_CONFIG(filedialog) - const QStringList &filter = FilePickerController::nameFilters(acceptedMimeTypes); - QStringList ret; - QString str; - switch (static_cast<FilePickerController::FileChooserMode>(mode)) { - case FilePickerController::OpenMultiple: - ret = QFileDialog::getOpenFileNames(view(), QString(), QString(), filter.join(QStringLiteral(";;")), nullptr, QFileDialog::HideNameFilterDetails); - break; - // Chromium extension, not exposed as part of the public API for now. - case FilePickerController::UploadFolder: - str = QFileDialog::getExistingDirectory(view(), tr("Select folder to upload")); - if (!str.isNull()) - ret << str; - break; - case FilePickerController::Save: - str = QFileDialog::getSaveFileName(view(), QString(), (QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + oldFiles.first())); - if (!str.isNull()) - ret << str; - break; - case FilePickerController::Open: - str = QFileDialog::getOpenFileName(view(), QString(), oldFiles.first(), filter.join(QStringLiteral(";;")), nullptr, QFileDialog::HideNameFilterDetails); - if (!str.isNull()) - ret << str; - break; - } - return ret; -#else - Q_UNUSED(mode); - Q_UNUSED(oldFiles); - Q_UNUSED(acceptedMimeTypes); - - return QStringList(); -#endif // QT_CONFIG(filedialog) -} - -void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg) -{ - Q_UNUSED(securityOrigin); -#if QT_CONFIG(messagebox) - QMessageBox::information(view(), - QStringLiteral("Javascript Alert - %1").arg(url().toString()), - msg.toHtmlEscaped()); -#else - Q_UNUSED(msg); -#endif // QT_CONFIG(messagebox) -} - -bool QWebEnginePage::javaScriptConfirm(const QUrl &securityOrigin, const QString &msg) -{ - Q_UNUSED(securityOrigin); -#if QT_CONFIG(messagebox) - return (QMessageBox::information(view(), - QStringLiteral("Javascript Confirm - %1").arg(url().toString()), - msg.toHtmlEscaped(), - QMessageBox::Ok, - QMessageBox::Cancel) == QMessageBox::Ok); -#else - Q_UNUSED(msg); - return false; -#endif // QT_CONFIG(messagebox) -} - -bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString *result) -{ - Q_UNUSED(securityOrigin); -#if QT_CONFIG(inputdialog) - bool ret = false; - if (result) - *result = QInputDialog::getText(view(), - QStringLiteral("Javascript Prompt - %1").arg(url().toString()), - msg.toHtmlEscaped(), - QLineEdit::Normal, - defaultValue.toHtmlEscaped(), - &ret); - return ret; -#else - Q_UNUSED(msg); - Q_UNUSED(defaultValue); - Q_UNUSED(result); - return false; -#endif // QT_CONFIG(inputdialog) -} - -void QWebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) -{ - static QLoggingCategory loggingCategory("js", QtWarningMsg); - static QByteArray file = sourceID.toUtf8(); - QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName()); - - switch (level) { - case JavaScriptConsoleMessageLevel::InfoMessageLevel: - if (loggingCategory.isInfoEnabled()) - logger.info().noquote() << message; - break; - case JavaScriptConsoleMessageLevel::WarningMessageLevel: - if (loggingCategory.isWarningEnabled()) - logger.warning().noquote() << message; - break; - case JavaScriptConsoleMessageLevel::ErrorMessageLevel: - if (loggingCategory.isCriticalEnabled()) - logger.critical().noquote() << message; - break; - } -} - -void QWebEnginePage::certificateError(QWebEngineCertificateError) { } - -bool QWebEnginePage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) -{ - Q_UNUSED(url); - Q_UNUSED(type); - Q_UNUSED(isMainFrame); - return true; -} - -QPointF QWebEnginePage::scrollPosition() const -{ - Q_D(const QWebEnginePage); - return d->adapter->lastScrollOffset(); -} - -QSizeF QWebEnginePage::contentsSize() const -{ - Q_D(const QWebEnginePage); - return d->adapter->lastContentsSize(); -} - -/*! - Renders the current content of the page into a PDF document and saves it - in the location specified in \a filePath. - The page size and orientation of the produced PDF document are taken from - the values specified in \a pageLayout. - - This method issues an asynchronous request for printing the web page into - a PDF and returns immediately. - To be informed about the result of the request, connect to the signal - pdfPrintingFinished(). - - If a file already exists at the provided file path, it will be overwritten. - \since 5.7 - \sa pdfPrintingFinished() -*/ -void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &pageLayout) -{ -#if QT_CONFIG(webengine_printing_and_pdf) - Q_D(const QWebEnginePage); - if (d->currentPrinter) { - qWarning("Cannot print to PDF while at the same time printing on printer %ls", qUtf16Printable(d->currentPrinter->printerName())); - return; - } - d->ensureInitialized(); - d->adapter->printToPDF(pageLayout, filePath); -#else - Q_UNUSED(filePath); - Q_UNUSED(pageLayout); -#endif -} - - -/*! - Renders the current content of the page into a PDF document and returns a byte array containing the PDF data - as parameter to \a resultCallback. - The page size and orientation of the produced PDF document are taken from the values specified in \a pageLayout. - - The \a resultCallback must take a const reference to a QByteArray as parameter. If printing was successful, this byte array - will contain the PDF data, otherwise, the byte array will be empty. - - \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done - during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid - value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it. - - \since 5.7 -*/ -void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &pageLayout) -{ - Q_D(QWebEnginePage); -#if QT_CONFIG(webengine_printing_and_pdf) - if (d->currentPrinter) { - qWarning("Cannot print to PDF while at the same time printing on printer %ls", qUtf16Printable(d->currentPrinter->printerName())); - d->m_callbacks.invokeEmpty(resultCallback); - return; - } - d->ensureInitialized(); - quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout); - d->m_callbacks.registerCallback(requestId, resultCallback); -#else - Q_UNUSED(pageLayout); - d->m_callbacks.invokeEmpty(resultCallback); -#endif -} - -/*! - Renders the current content of the page into a temporary PDF document, then prints it using \a printer. - - The settings for creating and printing the PDF document will be retrieved from the \a printer - object. - It is the users responsibility to ensure the \a printer remains valid until \a resultCallback - has been called. - - \note Printing runs on the browser process, which is by default not sandboxed. - - The \a resultCallback must take a boolean as parameter. If printing was successful, this - boolean will have the value \c true, otherwise, its value will be \c false. - - \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done - during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid - value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it. - - \since 5.8 -*/ -void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback) -{ - Q_D(QWebEnginePage); -#if QT_CONFIG(webengine_printing_and_pdf) - if (d->currentPrinter) { - qWarning("Cannot print page on printer %ls: Already printing on %ls.", qUtf16Printable(printer->printerName()), qUtf16Printable(d->currentPrinter->printerName())); - d->m_callbacks.invokeDirectly(resultCallback, false); - return; - } - d->currentPrinter = printer; - d->ensureInitialized(); - quint64 requestId = d->adapter->printToPDFCallbackResult(printer->pageLayout(), - printer->colorMode() == QPrinter::Color, - false); - d->m_callbacks.registerCallback(requestId, resultCallback); -#else - Q_UNUSED(printer); - d->m_callbacks.invokeDirectly(resultCallback, false); -#endif -} - - -/*! - \enum QWebEnginePage::LifecycleState - \since 5.14 - - This enum describes the lifecycle state of the page: - - \value Active - Normal state. - \value Frozen - Low CPU usage state where most HTML task sources are suspended. - \value Discarded - Very low resource usage state where the entire browsing context is discarded. - - \sa lifecycleState, {Page Lifecycle API}, {WebEngine Lifecycle Example} -*/ - -/*! - \property QWebEnginePage::lifecycleState - \since 5.14 - - \brief The current lifecycle state of the page. - - The following restrictions are enforced by the setter: - - \list - \li A \l{visible} page must remain in the \c{Active} state. - \li If the page is being inspected by a \l{devToolsPage} then both pages must - remain in the \c{Active} states. - \li A page in the \c{Discarded} state can only transition to the \c{Active} - state. This will cause a reload of the page. - \endlist - - These are the only hard limits on the lifecycle state, but see also - \l{recommendedState} for the recommended soft limits. - - \sa recommendedState, {Page Lifecycle API}, {WebEngine Lifecycle Example} -*/ - -QWebEnginePage::LifecycleState QWebEnginePage::lifecycleState() const -{ - Q_D(const QWebEnginePage); - return static_cast<LifecycleState>(d->adapter->lifecycleState()); -} - -void QWebEnginePage::setLifecycleState(LifecycleState state) -{ - Q_D(QWebEnginePage); - d->adapter->setLifecycleState(static_cast<WebContentsAdapterClient::LifecycleState>(state)); -} - -/*! - \property QWebEnginePage::recommendedState - \since 5.14 - - \brief The recommended limit for the lifecycle state of the page. - - Setting the lifecycle state to a lower resource usage state than the - recommended state may cause side-effects such as stopping background audio - playback or loss of HTML form input. Setting the lifecycle state to a higher - resource state is however completely safe. - - \sa lifecycleState, {Page Lifecycle API}, {WebEngine Lifecycle Example} -*/ - -QWebEnginePage::LifecycleState QWebEnginePage::recommendedState() const -{ - Q_D(const QWebEnginePage); - return static_cast<LifecycleState>(d->adapter->recommendedState()); -} - -/*! - \property QWebEnginePage::visible - \since 5.14 - - \brief Whether the page is considered visible in the Page Visibility API. - - Setting this property changes the \c{Document.hidden} and the - \c{Document.visibilityState} properties in JavaScript which web sites can use - to voluntarily reduce their resource usage if they are not visible to the - user. - - If the page is connected to a \l{view} then this property will be managed - automatically by the view according to it's own visibility. - - \sa lifecycleState -*/ - -bool QWebEnginePage::isVisible() const -{ - Q_D(const QWebEnginePage); - return d->adapter->isVisible(); -} - -void QWebEnginePage::setVisible(bool visible) -{ - Q_D(QWebEnginePage); - - if (!d->adapter->isInitialized()) { - // On the one hand, it is too early to initialize here. The application - // may call show() before load(), or it may call show() from - // createWindow(), and then we would create an unnecessary blank - // WebContents here. On the other hand, if the application calls show() - // then it expects something to be shown, so we have to initialize. - // Therefore we have to delay the initialization via the event loop. - if (visible) - d->wasShownTimer.start(); - else - d->wasShownTimer.stop(); - return; - } - - d->adapter->setVisible(visible); -} - -QT_END_NAMESPACE - -#include "moc_qwebenginepage.cpp" diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h deleted file mode 100644 index 5ac30863f..000000000 --- a/src/webenginewidgets/api/qwebenginepage.h +++ /dev/null @@ -1,399 +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$ -** -****************************************************************************/ - -#ifndef QWEBENGINEPAGE_H -#define QWEBENGINEPAGE_H - -#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> -#include <QtWebEngineWidgets/qwebengineclientcertificateselection.h> -#include <QtWebEngineCore/qwebenginedownloadrequest.h> -#include <QtWebEngineCore/qwebenginecallback.h> -#include <QtWebEngineCore/qwebenginehttprequest.h> - -#include <QtCore/qobject.h> -#include <QtCore/qurl.h> -#include <QtCore/qvariant.h> -#include <QtGui/qpagelayout.h> -#include <QtNetwork/qnetworkaccessmanager.h> -#include <QtWidgets/qwidget.h> - -QT_BEGIN_NAMESPACE -class QMenu; -class QPrinter; - -class QContextMenuBuilder; -class QWebChannel; -class QWebEngineCertificateError; -class QWebEngineClientCertificateSelection; -class QWebEngineFindTextResult; -class QWebEngineFullScreenRequest; -class QWebEngineHistory; -class QWebEnginePage; -class QWebEnginePagePrivate; -class QWebEngineProfile; -class QWebEngineQuotaRequest; -class QWebEngineRegisterProtocolHandlerRequest; -class QWebEngineScriptCollection; -class QWebEngineSettings; -class QWebEngineUrlRequestInterceptor; - -class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject { - Q_OBJECT - Q_PROPERTY(QString selectedText READ selectedText) - Q_PROPERTY(bool hasSelection READ hasSelection) - Q_PROPERTY(QUrl requestedUrl READ requestedUrl) - Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor) - Q_PROPERTY(QString title READ title) - Q_PROPERTY(QUrl url READ url WRITE setUrl) - Q_PROPERTY(QUrl iconUrl READ iconUrl NOTIFY iconUrlChanged) - Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged) - Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) - Q_PROPERTY(QSizeF contentsSize READ contentsSize NOTIFY contentsSizeChanged) - Q_PROPERTY(QPointF scrollPosition READ scrollPosition NOTIFY scrollPositionChanged) - Q_PROPERTY(bool audioMuted READ isAudioMuted WRITE setAudioMuted NOTIFY audioMutedChanged) - Q_PROPERTY(bool recentlyAudible READ recentlyAudible NOTIFY recentlyAudibleChanged) - Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) - Q_PROPERTY(LifecycleState lifecycleState READ lifecycleState WRITE setLifecycleState NOTIFY lifecycleStateChanged) - Q_PROPERTY(LifecycleState recommendedState READ recommendedState NOTIFY recommendedStateChanged) - Q_PROPERTY(qint64 renderProcessPid READ renderProcessPid NOTIFY renderProcessPidChanged) - -public: - enum WebAction { - NoWebAction = - 1, - Back, - Forward, - Stop, - Reload, - - Cut, - Copy, - Paste, - - Undo, - Redo, - SelectAll, - ReloadAndBypassCache, - - PasteAndMatchStyle, - - OpenLinkInThisWindow, - OpenLinkInNewWindow, - OpenLinkInNewTab, - CopyLinkToClipboard, - DownloadLinkToDisk, - - CopyImageToClipboard, - CopyImageUrlToClipboard, - DownloadImageToDisk, - - CopyMediaUrlToClipboard, - ToggleMediaControls, - ToggleMediaLoop, - ToggleMediaPlayPause, - ToggleMediaMute, - DownloadMediaToDisk, - - InspectElement, - ExitFullScreen, - RequestClose, - Unselect, - SavePage, - OpenLinkInNewBackgroundTab, - ViewSource, - - ToggleBold, - ToggleItalic, - ToggleUnderline, - ToggleStrikethrough, - - AlignLeft, - AlignCenter, - AlignRight, - AlignJustified, - Indent, - Outdent, - - InsertOrderedList, - InsertUnorderedList, - - WebActionCount - }; - Q_ENUM(WebAction) - - enum FindFlag { - FindBackward = 1, - FindCaseSensitively = 2, - }; - Q_DECLARE_FLAGS(FindFlags, FindFlag) - - enum WebWindowType { - WebBrowserWindow, - WebBrowserTab, - WebDialog, - WebBrowserBackgroundTab - }; - Q_ENUM(WebWindowType) - - enum PermissionPolicy { - PermissionUnknown, - PermissionGrantedByUser, - PermissionDeniedByUser - }; - Q_ENUM(PermissionPolicy) - - // must match WebContentsAdapterClient::NavigationType - enum NavigationType { - NavigationTypeLinkClicked, - NavigationTypeTyped, - NavigationTypeFormSubmitted, - NavigationTypeBackForward, - NavigationTypeReload, - NavigationTypeOther, - NavigationTypeRedirect, - }; - Q_ENUM(NavigationType) - - enum Feature { - Notifications = 0, - Geolocation = 1, - MediaAudioCapture = 2, - MediaVideoCapture, - MediaAudioVideoCapture, - MouseLock, - DesktopVideoCapture, - DesktopAudioVideoCapture - }; - Q_ENUM(Feature) - - // Ex-QWebFrame enum - - enum FileSelectionMode { - FileSelectOpen, - FileSelectOpenMultiple, - }; - Q_ENUM(FileSelectionMode) - - // must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel - enum JavaScriptConsoleMessageLevel { - InfoMessageLevel = 0, - WarningMessageLevel, - ErrorMessageLevel - }; - Q_ENUM(JavaScriptConsoleMessageLevel) - - // must match WebContentsAdapterClient::RenderProcessTerminationStatus - enum RenderProcessTerminationStatus { - NormalTerminationStatus = 0, - AbnormalTerminationStatus, - CrashedTerminationStatus, - KilledTerminationStatus - }; - Q_ENUM(RenderProcessTerminationStatus) - - // must match WebContentsAdapterClient::LifecycleState - enum class LifecycleState { - Active, - Frozen, - Discarded, - }; - Q_ENUM(LifecycleState) - - explicit QWebEnginePage(QObject *parent = Q_NULLPTR); - QWebEnginePage(QWebEngineProfile *profile, QObject *parent = Q_NULLPTR); - ~QWebEnginePage(); - QWebEngineHistory *history() const; - - void setView(QWidget *view); - QWidget *view() const; - - bool hasSelection() const; - QString selectedText() const; - - QWebEngineProfile *profile() const; - -#ifndef QT_NO_ACTION - QAction *action(WebAction action) const; -#endif - virtual void triggerAction(WebAction action, bool checked = false); - - void replaceMisspelledWord(const QString &replacement); - - bool event(QEvent*) override; - - void findText(const QString &subString, FindFlags options = FindFlags(), const QWebEngineCallback<bool> &resultCallback = QWebEngineCallback<bool>()); - - void setFeaturePermission(const QUrl &securityOrigin, Feature feature, PermissionPolicy policy); - - void load(const QUrl &url); - void load(const QWebEngineHttpRequest &request); - void download(const QUrl &url, const QString &filename = QString()); - void setHtml(const QString &html, const QUrl &baseUrl = QUrl()); - void setContent(const QByteArray &data, const QString &mimeType = QString(), const QUrl &baseUrl = QUrl()); - - void toHtml(const QWebEngineCallback<const QString &> &resultCallback) const; - void toPlainText(const QWebEngineCallback<const QString &> &resultCallback) const; - - QString title() const; - void setUrl(const QUrl &url); - QUrl url() const; - QUrl requestedUrl() const; - QUrl iconUrl() const; - QIcon icon() const; - - qreal zoomFactor() const; - void setZoomFactor(qreal factor); - - QPointF scrollPosition() const; - QSizeF contentsSize() const; - - void runJavaScript(const QString& scriptSource); - void runJavaScript(const QString& scriptSource, quint32 worldId); - void runJavaScript(const QString& scriptSource, const QWebEngineCallback<const QVariant &> &resultCallback); - void runJavaScript(const QString& scriptSource, quint32 worldId, const QWebEngineCallback<const QVariant &> &resultCallback); - QWebEngineScriptCollection &scripts(); - QWebEngineSettings *settings() const; - - QWebChannel *webChannel() const; - void setWebChannel(QWebChannel *); - void setWebChannel(QWebChannel *, uint worldId); - QColor backgroundColor() const; - void setBackgroundColor(const QColor &color); - - void save(const QString &filePath, QWebEngineDownloadRequest::SavePageFormat format - = QWebEngineDownloadRequest::MimeHtmlSaveFormat) const; - - bool isAudioMuted() const; - void setAudioMuted(bool muted); - bool recentlyAudible() const; - qint64 renderProcessPid() const; - - void printToPdf(const QString &filePath, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF())); - void printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF())); - void print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback); - - void setInspectedPage(QWebEnginePage *page); - QWebEnginePage *inspectedPage() const; - void setDevToolsPage(QWebEnginePage *page); - QWebEnginePage *devToolsPage() const; - - void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); - - LifecycleState lifecycleState() const; - void setLifecycleState(LifecycleState state); - - LifecycleState recommendedState() const; - - bool isVisible() const; - void setVisible(bool visible); - -Q_SIGNALS: - void loadStarted(); - void loadProgress(int progress); - void loadFinished(bool ok); - - void linkHovered(const QString &url); - void selectionChanged(); - void geometryChangeRequested(const QRect& geom); - void windowCloseRequested(); - - void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature); - void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature); - void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest); - void quotaRequested(QWebEngineQuotaRequest quotaRequest); - void registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request); - void selectClientCertificate(QWebEngineClientCertificateSelection clientCertSelection); - void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator); - void proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost); - - void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode); - - // Ex-QWebFrame signals - void titleChanged(const QString &title); - void urlChanged(const QUrl &url); - void iconUrlChanged(const QUrl &url); - void iconChanged(const QIcon &icon); - - void scrollPositionChanged(const QPointF &position); - void contentsSizeChanged(const QSizeF &size); - void audioMutedChanged(bool muted); - void recentlyAudibleChanged(bool recentlyAudible); - void renderProcessPidChanged(qint64 pid); - - void pdfPrintingFinished(const QString &filePath, bool success); - void printRequested(); - - void visibleChanged(bool visible); - - void lifecycleStateChanged(LifecycleState state); - void recommendedStateChanged(LifecycleState state); - - void findTextFinished(const QWebEngineFindTextResult &result); - -protected: - virtual QWebEnginePage *createWindow(WebWindowType type); - virtual QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes); - virtual void javaScriptAlert(const QUrl &securityOrigin, const QString& msg); - virtual bool javaScriptConfirm(const QUrl &securityOrigin, const QString& msg); - virtual bool javaScriptPrompt(const QUrl &securityOrigin, const QString& msg, const QString& defaultValue, QString* result); - virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID); - virtual void certificateError(QWebEngineCertificateError certificateError); - virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame); - -private: - Q_DISABLE_COPY(QWebEnginePage) - Q_DECLARE_PRIVATE(QWebEnginePage) - QScopedPointer<QWebEnginePagePrivate> d_ptr; -#ifndef QT_NO_ACTION - Q_PRIVATE_SLOT(d_func(), void _q_webActionTriggered(bool checked)) -#endif - - friend class QContextMenuBuilder; - friend class QWebEngineFullScreenRequest; - friend class QWebEngineView; - friend class QWebEngineViewPrivate; -#ifndef QT_NO_ACCESSIBILITY - friend class QWebEngineViewAccessible; -#endif // QT_NO_ACCESSIBILITY -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QWebEnginePage::FindFlags) - -QT_END_NAMESPACE - -#endif // QWEBENGINEPAGE_H diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h deleted file mode 100644 index eb021bf6d..000000000 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ /dev/null @@ -1,211 +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$ -** -****************************************************************************/ - -#ifndef QWEBENGINEPAGE_P_H -#define QWEBENGINEPAGE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qwebenginepage.h" - -#include "qwebenginecallback_p.h" -#include "qwebenginescriptcollection.h" -#include "web_contents_adapter_client.h" - -#include <QtCore/qcompilerdetection.h> -#include <QtCore/QPointer> -#include <QtCore/QTimer> - -namespace QtWebEngineCore { -class RenderWidgetHostViewQtDelegate; -class RenderWidgetHostViewQtDelegateWidget; -class TouchHandleDrawableClient; -class TouchSelectionMenuController; -class WebContentsAdapter; -} - -QT_BEGIN_NAMESPACE -class QWebEngineFindTextResult; -class QWebEngineHistory; -class QWebEnginePage; -class QWebEngineProfile; -class QWebEngineSettings; -class QWebEngineView; - -class QWebEnginePagePrivate : public QtWebEngineCore::WebContentsAdapterClient -{ -public: - Q_DECLARE_PUBLIC(QWebEnginePage) - QWebEnginePage *q_ptr; - - QWebEnginePagePrivate(QWebEngineProfile *profile = 0); - ~QWebEnginePagePrivate(); - - QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override; - QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override { return CreateRenderWidgetHostViewQtDelegate(client); } - void initializationFinished() override; - void lifecycleStateChanged(LifecycleState state) override; - void recommendedStateChanged(LifecycleState state) override; - void visibleChanged(bool visible) override; - void titleChanged(const QString&) override; - void urlChanged() override; - void iconChanged(const QUrl&) override; - void loadProgressChanged(int progress) override; - void didUpdateTargetURL(const QUrl&) override; - void selectionChanged() override; - void recentlyAudibleChanged(bool recentlyAudible) override; - void renderProcessPidChanged(qint64 pid) override; - QRectF viewportRect() const override; - QColor backgroundColor() const override; - void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override; - void loadCommitted() override { } - void didFirstVisuallyNonEmptyPaint() override { } - void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) override; - void focusContainer() override; - void unhandledKeyEvent(QKeyEvent *event) override; - QSharedPointer<QtWebEngineCore::WebContentsAdapter> - adoptNewWindow(QSharedPointer<QtWebEngineCore::WebContentsAdapter> newWebContents, - WindowOpenDisposition disposition, bool userGesture, - const QRect &initialGeometry, const QUrl &targetUrl) override; - bool isBeingAdopted() override; - void close() override; - void windowCloseRejected() override; - void contextMenuRequested(QWebEngineContextMenuRequest *request) override; - void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) override; - void requestFullScreenMode(const QUrl &origin, bool fullscreen) override; - bool isFullScreenMode() const override; - void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) override; - void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) override; - void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) override; - void didRunJavaScript(quint64 requestId, const QVariant& result) override; - void didFetchDocumentMarkup(quint64 requestId, const QString& result) override; - void didFetchDocumentInnerText(quint64 requestId, const QString& result) override; - void didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result) override; - void didPrintPageToPdf(const QString &filePath, bool success) override; - bool passOnFocus(bool reverse) override; - void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override; - void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override; - void releaseProfile() override; - void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override; - void runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin) override; - void runMouseLockPermissionRequest(const QUrl &securityOrigin) override; - void runQuotaRequest(QWebEngineQuotaRequest) override; - void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override; - QObject *accessibilityParentObject() override; - QWebEngineSettings *webEngineSettings() const override; - void allowCertificateError(const QWebEngineCertificateError &error) override; - void selectClientCert( - const QSharedPointer<QtWebEngineCore::ClientCertSelectController> &controller) override; - void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override; - void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override; - void updateScrollPosition(const QPointF &position) override; - void updateContentsSize(const QSizeF &size) override; - void updateNavigationActions() override; - void updateEditActions() override; - void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, - const QPixmap &pixmap, const QPoint &offset) override; - bool supportsDragging() const override; - bool isEnabled() const override; - void setToolTip(const QString &toolTipText) override; - void printRequested() override; - QtWebEngineCore::TouchHandleDrawableClient *createTouchHandle(const QMap<int, QImage> &) override { return nullptr; } - void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, const QRect &, const QSize &) override { } - void hideTouchSelectionMenu() override { } - const QObject *holdingQObject() const override; - ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; } - void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidget) override; - void findTextFinished(const QWebEngineFindTextResult &result) override; - - QtWebEngineCore::ProfileAdapter *profileAdapter() override; - QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override; - - void updateAction(QWebEnginePage::WebAction) const; - void _q_webActionTriggered(bool checked); - - QtWebEngineCore::WebContentsAdapter *webContents() { return adapter.data(); } - void recreateFromSerializedHistory(QDataStream &input); - - void setFullScreenMode(bool); - void ensureInitialized() const; - - static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view); - static void bindPageAndWidget(QWebEnginePage *page, - QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget); - - QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter; - QWebEngineHistory *history; - QWebEngineProfile *profile; - QWebEngineSettings *settings; - QWebEngineView *view; - QUrl url; - bool isLoading; - QWebEngineScriptCollection scriptCollection; - bool m_isBeingAdopted; - QColor m_backgroundColor; - bool fullscreenMode; - QWebChannel *webChannel; - unsigned int webChannelWorldId; - QUrl iconUrl; - bool m_navigationActionTriggered; - QPointer<QWebEnginePage> inspectedPage; - QPointer<QWebEnginePage> devToolsPage; - bool defaultAudioMuted; - qreal defaultZoomFactor; - QTimer wasShownTimer; - QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget = nullptr; - - mutable QtWebEngineCore::CallbackDirectory m_callbacks; - mutable QAction *actions[QWebEnginePage::WebActionCount]; -#if QT_CONFIG(webengine_printing_and_pdf) - QPrinter *currentPrinter; -#endif -}; - -QT_END_NAMESPACE - -#endif // QWEBENGINEPAGE_P_H diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp deleted file mode 100644 index 7aa168a6f..000000000 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ /dev/null @@ -1,891 +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 "qwebengineprofile.h" -#include "qwebengineprofile_p.h" - -#include "qwebenginecookiestore.h" -#include "qwebenginedownloadrequest.h" -#include "qwebenginedownloadrequest_p.h" -#include "qwebenginenotificationpresenter_p.h" -#include "qwebenginepage.h" -#include "qwebenginepage_p.h" -#include "qwebenginesettings.h" -#include "qwebenginescriptcollection_p.h" -#include "qtwebenginecoreglobal.h" -#include "profile_adapter.h" -#include "visited_links_manager_qt.h" -#include "web_engine_settings.h" - -#include <QDir> -#include <QtWebEngineCore/qwebengineurlscheme.h> - -QT_BEGIN_NAMESPACE - -ASSERT_ENUMS_MATCH(QWebEngineDownloadRequest::UnknownSaveFormat, QtWebEngineCore::ProfileAdapterClient::UnknownSavePageFormat) -ASSERT_ENUMS_MATCH(QWebEngineDownloadRequest::SingleHtmlSaveFormat, QtWebEngineCore::ProfileAdapterClient::SingleHtmlSaveFormat) -ASSERT_ENUMS_MATCH(QWebEngineDownloadRequest::CompleteHtmlSaveFormat, QtWebEngineCore::ProfileAdapterClient::CompleteHtmlSaveFormat) -ASSERT_ENUMS_MATCH(QWebEngineDownloadRequest::MimeHtmlSaveFormat, QtWebEngineCore::ProfileAdapterClient::MimeHtmlSaveFormat) - -using QtWebEngineCore::ProfileAdapter; - -/*! - \class QWebEngineProfile - \brief The QWebEngineProfile class provides a web engine profile shared by multiple pages. - \since 5.5 - - \inmodule QtWebEngineWidgets - - A web engine profile contains settings, scripts, persistent cookie policy, and the list of - visited links shared by all web engine pages that belong to the profile. - - All pages that belong to the profile share a common QWebEngineSettings instance, which can - be accessed with the settings() method. Likewise, the scripts() method provides access - to a common QWebEngineScriptCollection instance. - - Information about visited links is stored together with persistent cookies and other persistent - data in a storage returned by storageName(). Persistent data is stored in a subdirectory set by - calling setPersistentStoragePath(), and the cache is located in a subdirectory set by calling - setCachePath(). The cache type can be set to \e in-memory or \e on-disk by calling - setHttpCacheType(). If only the storage name is set, the subdirectories are created and named - automatically. If you set any of the values manually, you should do it before creating any - pages that belong to the profile. - - The cache can be cleared of links by calling - clearVisitedLinks() or clearAllVisitedLinks(). PersistentCookiesPolicy describes whether - session and persistent cookies are saved to and restored from memory or disk. - - Profiles can be used to isolate pages from each other. A typical use case is a dedicated - \e {off-the-record profile} for a \e {private browsing} mode. Using QWebEngineProfile() without - defining a storage name constructs a new off-the-record profile that leaves no record on the - local machine, and has no persistent data or cache. The isOffTheRecord() method can be used - to check whether a profile is off-the-record. - - The default profile can be accessed by defaultProfile(). It is a built-in profile that all - web pages not specifically created with another profile belong to. - - Implementing the QWebEngineUrlRequestInterceptor interface and registering the interceptor on a - profile by setUrlRequestInterceptor() enables intercepting, blocking, and modifying URL - requests (QWebEngineUrlRequestInfo) before they reach the networking stack of Chromium. - - A QWebEngineUrlSchemeHandler can be registered for a profile by installUrlSchemeHandler() - to add support for custom URL schemes. Requests for the scheme are then issued to - QWebEngineUrlSchemeHandler::requestStarted() as QWebEngineUrlRequestJob objects. - - Spellchecking HTML form fields can be enabled per profile by using the setSpellCheckEnabled() - method and the current languages used for spellchecking can be set by using the - setSpellCheckLanguages() method. - -*/ - -/*! - \enum QWebEngineProfile::HttpCacheType - - This enum describes the HTTP cache type: - - \value MemoryHttpCache Use an in-memory cache. This is the default if - \c off-the-record is set. - \value DiskHttpCache Use a disk cache. This is the default if the profile - is not \c off-the-record. If set on an \c off-the-record profile will instead - set \c MemoryHttpCache. - \value NoCache Disable both in-memory and disk caching. (Added in Qt 5.7) -*/ - -/*! - \enum QWebEngineProfile::PersistentCookiesPolicy - - This enum describes policy for cookie persistency: - - \value NoPersistentCookies - Both session and persistent cookies are stored in memory. This is the only setting - possible if \c off-the-record is set or no persistent data path is available. - \value AllowPersistentCookies - Cookies marked persistent are saved to and restored from disk, whereas session cookies - are only stored to disk for crash recovery. This is the default setting. - \value ForcePersistentCookies - Both session and persistent cookies are saved to and restored from disk. -*/ - -void QWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) -{ - if (m_notificationPresenter) { - std::unique_ptr<QWebEngineNotification> notification(new QWebEngineNotification(controller)); - m_notificationPresenter(std::move(notification)); - } -} - -/*! - \fn QWebEngineProfile::downloadRequested(QWebEngineDownloadRequest *download) - - \since 5.5 - - This signal is emitted whenever a download has been triggered. - The \a download argument holds the state of the download. - The download has to be explicitly accepted with QWebEngineDownloadRequest::accept() or it will be - cancelled by default. - The download item is parented by the profile. If it is not accepted, it - will be deleted immediately after the signal emission. - This signal cannot be used with a queued connection. - - \sa QWebEngineDownloadRequest, QWebEnginePage::download() -*/ - -QWebEngineProfilePrivate::QWebEngineProfilePrivate(ProfileAdapter* profileAdapter) - : m_settings(new QWebEngineSettings()) - , m_profileAdapter(profileAdapter) - , m_scriptCollection(new QWebEngineScriptCollection( - new QWebEngineScriptCollectionPrivate(profileAdapter->userResourceController()))) -{ - m_profileAdapter->addClient(this); -} - -QWebEngineProfilePrivate::~QWebEngineProfilePrivate() -{ - if (m_profileAdapter) { - // In the case the user sets this profile as the parent of the interceptor - // it can be deleted before the browser-context still referencing it is. - m_profileAdapter->setRequestInterceptor(nullptr); - m_profileAdapter->removeClient(this); - } - - if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter()) - delete m_profileAdapter; - - delete m_settings; -} - -ProfileAdapter* QWebEngineProfilePrivate::profileAdapter() const -{ - return m_profileAdapter; -} - -void QWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId) -{ - m_ongoingDownloads.remove(downloadId); - if (m_profileAdapter) - m_profileAdapter->removeDownload(downloadId); -} - -void QWebEngineProfilePrivate::cleanDownloads() -{ - for (auto download : m_ongoingDownloads.values()) { - if (!download) - continue; - - if (!download->isFinished()) - download->cancel(); - - if (m_profileAdapter) - m_profileAdapter->removeDownload(download->id()); - } - m_ongoingDownloads.clear(); -} - -void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) -{ - Q_Q(QWebEngineProfile); - - Q_ASSERT(!m_ongoingDownloads.contains(info.id)); - QWebEngineDownloadRequestPrivate *itemPrivate = new QWebEngineDownloadRequestPrivate(m_profileAdapter, info.url); - itemPrivate->downloadId = info.id; - itemPrivate->downloadState = info.accepted ? QWebEngineDownloadRequest::DownloadInProgress - : QWebEngineDownloadRequest::DownloadRequested; - itemPrivate->startTime = info.startTime; - itemPrivate->downloadDirectory = QFileInfo(info.path).path(); - itemPrivate->downloadFileName = QFileInfo(info.path).fileName(); - itemPrivate->suggestedFileName = info.suggestedFileName; - itemPrivate->mimeType = info.mimeType; - itemPrivate->savePageFormat = static_cast<QWebEngineDownloadRequest::SavePageFormat>(info.savePageFormat); - itemPrivate->isSavePageDownload = info.isSavePageDownload; - if (info.page && info.page->clientType() == QtWebEngineCore::WebContentsAdapterClient::WidgetsClient) - itemPrivate->page = static_cast<QWebEnginePagePrivate *>(info.page)->q_ptr; - else - itemPrivate->page = nullptr; - - QWebEngineDownloadRequest *download = new QWebEngineDownloadRequest(itemPrivate, q); - - m_ongoingDownloads.insert(info.id, download); - QObject::connect(download, &QWebEngineDownloadRequest::destroyed, q, [id = info.id, this] () { downloadDestroyed(id); }); - - Q_EMIT q->downloadRequested(download); - - QWebEngineDownloadRequest::DownloadState state = download->state(); - - info.path = QDir(download->downloadDirectory()).filePath(download->downloadFileName()); - info.savePageFormat = static_cast<QtWebEngineCore::ProfileAdapterClient::SavePageFormat>( - download->savePageFormat()); - info.accepted = state != QWebEngineDownloadRequest::DownloadCancelled; - - if (state == QWebEngineDownloadRequest::DownloadRequested) { - // Delete unaccepted downloads. - info.accepted = false; - delete download; - } -} - -void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info) -{ - if (!m_ongoingDownloads.contains(info.id)) - return; - - QWebEngineDownloadRequest* download = m_ongoingDownloads.value(info.id).data(); - - if (!download) { - downloadDestroyed(info.id); - return; - } - - download->d_func()->update(info); -} - -void QWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) -{ - Q_ASSERT(m_profileAdapter); - m_profileAdapter->addWebContentsAdapterClient(adapter); -} - -void QWebEngineProfilePrivate::removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) -{ - Q_ASSERT(m_profileAdapter); - m_profileAdapter->removeWebContentsAdapterClient(adapter); -} - -/*! - Constructs a new off-the-record profile with the parent \a parent. - - An off-the-record profile leaves no record on the local machine, and has no persistent data or cache. - Thus, the HTTP cache can only be in memory and the cookies can only be non-persistent. Trying to change - these settings will have no effect. - - \sa isOffTheRecord() -*/ -QWebEngineProfile::QWebEngineProfile(QObject *parent) - : QObject(parent) - , d_ptr(new QWebEngineProfilePrivate(new QtWebEngineCore::ProfileAdapter())) -{ - d_ptr->q_ptr = this; -} - -/*! - Constructs a new profile with the storage name \a storageName and parent \a parent. - - The storage name must be unique. - - A disk-based QWebEngineProfile should be destroyed on or before application exit, otherwise the cache - and persistent data may not be fully flushed to disk. - - \sa storageName() -*/ -QWebEngineProfile::QWebEngineProfile(const QString &storageName, QObject *parent) - : QObject(parent) - , d_ptr(new QWebEngineProfilePrivate(new QtWebEngineCore::ProfileAdapter(storageName))) -{ - d_ptr->q_ptr = this; -} - -/*! \internal -*/ -QWebEngineProfile::QWebEngineProfile(QWebEngineProfilePrivate *privatePtr, QObject *parent) - : QObject(parent) - , d_ptr(privatePtr) -{ - d_ptr->q_ptr = this; -} - -/*! \internal -*/ -QWebEngineProfile::~QWebEngineProfile() -{ - d_ptr->cleanDownloads(); -} - -/*! - Returns the storage name for the profile. - - The storage name is used to give each profile that uses the disk separate subdirectories for persistent data and cache. -*/ -QString QWebEngineProfile::storageName() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->storageName(); -} - -/*! - Returns \c true if this is an off-the-record profile that leaves no record on the computer. - - This will force cookies and HTTP cache to be in memory, but also force all other normally - persistent data to be stored in memory. -*/ -bool QWebEngineProfile::isOffTheRecord() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->isOffTheRecord(); -} - -/*! - Returns the path used to store persistent data for the browser and web content. - - Persistent data includes persistent cookies, HTML5 local storage, and visited links. - - By default, this is below QStandardPaths::DataLocation in a QtWebengine/StorageName specific - subdirectory. - - \note Use QStandardPaths::writableLocation(QStandardPaths::DataLocation) - to obtain the QStandardPaths::DataLocation path. - - \sa setPersistentStoragePath(), storageName(), QStandardPaths::writableLocation() -*/ -QString QWebEngineProfile::persistentStoragePath() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->dataPath(); -} - -/*! - Overrides the default path used to store persistent web engine data. - - If \a path is set to the null string, the default path is restored. - - \sa persistentStoragePath() -*/ -void QWebEngineProfile::setPersistentStoragePath(const QString &path) -{ - const Q_D(QWebEngineProfile); - d->profileAdapter()->setDataPath(path); -} - -/*! - \since 5.13 - - The path to the location where the downloaded files are stored. - - \note By default, the download path is QStandardPaths::DownloadLocation. - - \sa setDownloadPath(), QStandardPaths::writableLocation() -*/ -QString QWebEngineProfile::downloadPath() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->downloadPath(); -} - -/*! - \since 5.13 - - Overrides the default path used for download location, setting it to \a path. - - If set to the null string, the default path is restored. - - \sa downloadPath() -*/ -void QWebEngineProfile::setDownloadPath(const QString &path) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setDownloadPath(path); -} - -/*! - Returns the path used for caches. - - By default, this is below StandardPaths::CacheLocation in a QtWebengine/StorageName specific - subdirectory. - - \note Use QStandardPaths::writableLocation(QStandardPaths::CacheLocation) - to obtain the QStandardPaths::CacheLocation path. - - \sa setCachePath(), storageName(), QStandardPaths::writableLocation() -*/ -QString QWebEngineProfile::cachePath() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->cachePath(); -} - -/*! - Overrides the default path used for disk caches, setting it to \a path. - - If set to the null string, the default path is restored. - - \sa cachePath() -*/ -void QWebEngineProfile::setCachePath(const QString &path) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setCachePath(path); -} - -/*! - Returns the user-agent string sent with HTTP to identify the browser. - - \note On Windows 8.1 and newer, the default user agent will always report - "Windows NT 6.2" (Windows 8), unless the application does contain a manifest - that declares newer Windows versions as supported. - - \sa setHttpUserAgent() -*/ -QString QWebEngineProfile::httpUserAgent() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->httpUserAgent(); -} - -/*! - Overrides the default user-agent string, setting it to \a userAgent. - - \sa httpUserAgent() -*/ -void QWebEngineProfile::setHttpUserAgent(const QString &userAgent) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setHttpUserAgent(userAgent); -} - -/*! - Returns the type of HTTP cache used. - - If the profile is off-the-record, MemoryHttpCache is returned. - - \sa setHttpCacheType(), cachePath() -*/ -QWebEngineProfile::HttpCacheType QWebEngineProfile::httpCacheType() const -{ - const Q_D(QWebEngineProfile); - return QWebEngineProfile::HttpCacheType(d->profileAdapter()->httpCacheType()); -} - -/*! - Sets the HTTP cache type to \a httpCacheType. - - \sa httpCacheType(), setCachePath() -*/ -void QWebEngineProfile::setHttpCacheType(QWebEngineProfile::HttpCacheType httpCacheType) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setHttpCacheType(ProfileAdapter::HttpCacheType(httpCacheType)); -} - -/*! - Sets the value of the Accept-Language HTTP request-header field to \a httpAcceptLanguage. - - \since 5.6 - */ -void QWebEngineProfile::setHttpAcceptLanguage(const QString &httpAcceptLanguage) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setHttpAcceptLanguage(httpAcceptLanguage); -} - -/*! - Returns the value of the Accept-Language HTTP request-header field. - - \since 5.6 - */ -QString QWebEngineProfile::httpAcceptLanguage() const -{ - Q_D(const QWebEngineProfile); - return d->profileAdapter()->httpAcceptLanguage(); -} - -/*! - Returns the current policy for persistent cookies. - - If the profile is off-the-record, NoPersistentCookies is returned. - - \sa setPersistentCookiesPolicy() -*/ -QWebEngineProfile::PersistentCookiesPolicy QWebEngineProfile::persistentCookiesPolicy() const -{ - const Q_D(QWebEngineProfile); - return QWebEngineProfile::PersistentCookiesPolicy(d->profileAdapter()->persistentCookiesPolicy()); -} - -/*! - Sets the policy for persistent cookies to \a newPersistentCookiesPolicy. - - \sa persistentCookiesPolicy() -*/ -void QWebEngineProfile::setPersistentCookiesPolicy(QWebEngineProfile::PersistentCookiesPolicy newPersistentCookiesPolicy) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setPersistentCookiesPolicy(ProfileAdapter::PersistentCookiesPolicy(newPersistentCookiesPolicy)); -} - -/*! - Returns the maximum size of the HTTP cache in bytes. - - Will return \c 0 if the size is automatically controlled by QtWebEngine. - - \sa setHttpCacheMaximumSize(), httpCacheType() -*/ -int QWebEngineProfile::httpCacheMaximumSize() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->httpCacheMaxSize(); -} - -/*! - Sets the maximum size of the HTTP cache to \a maxSize bytes. - - Setting it to \c 0 means the size will be controlled automatically by QtWebEngine. - - \sa httpCacheMaximumSize(), setHttpCacheType() -*/ -void QWebEngineProfile::setHttpCacheMaximumSize(int maxSize) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setHttpCacheMaxSize(maxSize); -} - -/*! - Returns the cookie store for this profile. - - \since 5.6 -*/ - -QWebEngineCookieStore* QWebEngineProfile::cookieStore() -{ - Q_D(QWebEngineProfile); - return d->profileAdapter()->cookieStore(); -} - -#if QT_DEPRECATED_SINCE(5, 13) -/*! - Registers a request interceptor singleton \a interceptor to intercept URL requests. - - The profile does not take ownership of the pointer. - - \obsolete - - Interceptors installed with this method will call - QWebEngineUrlRequestInterceptor::interceptRequest on the I/O thread. Therefore - the user has to provide thread-safe interaction with the other user classes. - For a duration of this call ui thread is blocked. - Use setUrlRequestInterceptor instead. - - \since 5.6 - \sa QWebEngineUrlRequestInfo - -*/ -void QWebEngineProfile::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor) -{ - Q_D(QWebEngineProfile); - if (interceptor) - interceptor->setProperty("deprecated", true); - d->profileAdapter()->setRequestInterceptor(interceptor); - if (interceptor) - qDebug("Use of deprecated not thread-safe setter, use setUrlRequestInterceptor instead."); -} -#endif -/*! - Registers a request interceptor singleton \a interceptor to intercept URL requests. - - The profile does not take ownership of the pointer. - - \since 5.13 - \sa QWebEngineUrlRequestInfo QWebEngineUrlRequestInterceptor -*/ - -void QWebEngineProfile::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setRequestInterceptor(interceptor); -} - -/*! - Clears all links from the visited links database. - - \sa clearVisitedLinks() -*/ -void QWebEngineProfile::clearAllVisitedLinks() -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->visitedLinksManager()->deleteAllVisitedLinkData(); -} - -/*! - Clears the links in \a urls from the visited links database. - - \sa clearAllVisitedLinks() -*/ -void QWebEngineProfile::clearVisitedLinks(const QList<QUrl> &urls) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->visitedLinksManager()->deleteVisitedLinkDataForUrls(urls); -} - -/*! - Returns \c true if \a url is considered a visited link by this profile. -*/ -bool QWebEngineProfile::visitedLinksContainsUrl(const QUrl &url) const -{ - Q_D(const QWebEngineProfile); - return d->profileAdapter()->visitedLinksManager()->containsUrl(url); -} - -/*! - Returns the collection of scripts that are injected into all pages that share - this profile. - - \sa QWebEngineScriptCollection, QWebEngineScript, QWebEnginePage::scripts(), - {Script Injection} -*/ -QWebEngineScriptCollection *QWebEngineProfile::scripts() const -{ - Q_D(const QWebEngineProfile); - return d->m_scriptCollection.data(); -} - -/*! - Sets the function \a notificationPresenter as responsible for presenting sent notifications. - - \since 5.13 - \sa QWebEngineNotification -*/ -void QWebEngineProfile::setNotificationPresenter(std::function<void(std::unique_ptr<QWebEngineNotification>)> notificationPresenter) -{ - Q_D(QWebEngineProfile); - d->m_notificationPresenter = std::move(notificationPresenter); -} - -/*! - Returns the default profile. - - The default profile uses the storage name "Default". - - \sa storageName() -*/ -QWebEngineProfile *QWebEngineProfile::defaultProfile() -{ - static QWebEngineProfile* profile = new QWebEngineProfile( - new QWebEngineProfilePrivate(ProfileAdapter::createDefaultProfileAdapter()), - ProfileAdapter::globalQObjectRoot()); - if (!profile->d_ptr->m_notificationPresenter) - profile->setNotificationPresenter(&defaultNotificationPresenter); - return profile; -} - -/*! - \since 5.8 - - Sets the current list of \a languages for 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. - - See the \l {Spellchecker}{Spellchecker feature documentation} for how - dictionary files are searched. - - For more information about how to compile \c .bdic dictionaries, see the - \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}. - -*/ -void QWebEngineProfile::setSpellCheckLanguages(const QStringList &languages) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setSpellCheckLanguages(languages); -} - -/*! - \since 5.8 - - Returns the list of languages used by the spell checker. -*/ -QStringList QWebEngineProfile::spellCheckLanguages() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->spellCheckLanguages(); -} - -/*! - \since 5.8 - - Enables spell checker if \a enable is \c true, otherwise disables it. - \sa isSpellCheckEnabled() - */ -void QWebEngineProfile::setSpellCheckEnabled(bool enable) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setSpellCheckEnabled(enable); -} -/*! - \since 5.8 - - Returns \c true if the spell checker is enabled; otherwise returns \c false. - \sa setSpellCheckEnabled() - */ -bool QWebEngineProfile::isSpellCheckEnabled() const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->isSpellCheckEnabled(); -} - -/*! - Returns the default settings for all pages in this profile. -*/ -QWebEngineSettings *QWebEngineProfile::settings() const -{ - const Q_D(QWebEngineProfile); - return d->settings(); -} - -/*! - \since 5.6 - - Returns the custom URL scheme handler register for the URL scheme \a scheme. -*/ -const QWebEngineUrlSchemeHandler *QWebEngineProfile::urlSchemeHandler(const QByteArray &scheme) const -{ - const Q_D(QWebEngineProfile); - return d->profileAdapter()->urlSchemeHandler(scheme); -} - -/*! - \since 5.6 - - Registers a handler \a handler for custom URL scheme \a scheme in the profile. - - It is necessary to first register the scheme with \l - QWebEngineUrlScheme::registerScheme at application startup. -*/ -void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->installUrlSchemeHandler(scheme, handler); -} - -/*! - \since 5.6 - - Removes the custom URL scheme handler \a handler from the profile. - - \sa removeUrlScheme() -*/ -void QWebEngineProfile::removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->removeUrlSchemeHandler(handler); -} - -/*! - \since 5.6 - - Removes the custom URL scheme \a scheme from the profile. - - \sa removeUrlSchemeHandler() -*/ -void QWebEngineProfile::removeUrlScheme(const QByteArray &scheme) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->removeUrlScheme(scheme); -} - -/*! - \since 5.6 - - Removes all custom URL scheme handlers installed in the profile. -*/ -void QWebEngineProfile::removeAllUrlSchemeHandlers() -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->removeAllUrlSchemeHandlers(); -} - -/*! - \since 5.13 - - Sets if this profile is to be used for downloading and caching when needed - during certificate verification, for instance for OCSP, CRLs, and AIA. - - Only one QWebEngineProfile can do this at a time, and it is recommended - that the profile fullfilling this role has a disk HTTP cache to avoid - needlessly re-downloading. If you set the option on a second profile, - it will be disabled on the profile it is currently set. - - Currently only affects Linux/NSS installations where it enables OCSP. - - As long as one profile has \a enabled set to \c true, all other profiles - will be able to use it for their certificate verification. - - \sa isUsedForGlobalCertificateVerification(), httpCacheType() -*/ -void QWebEngineProfile::setUseForGlobalCertificateVerification(bool enabled) -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->setUseForGlobalCertificateVerification(enabled); -} - -/*! - \since 5.13 - - Returns \c true if this profile is currently being used for global - certificate verification. -*/ -bool QWebEngineProfile::isUsedForGlobalCertificateVerification() const -{ - Q_D(const QWebEngineProfile); - return d->profileAdapter()->isUsedForGlobalCertificateVerification(); -} - -/*! - \since 5.7 - - Removes the profile's cache entries. -*/ -void QWebEngineProfile::clearHttpCache() -{ - Q_D(QWebEngineProfile); - d->profileAdapter()->clearHttpCache(); -} - -/*! - \since 5.13 - - Returns the profile's client certificate store. -*/ -QWebEngineClientCertificateStore *QWebEngineProfile::clientCertificateStore() -{ -#if QT_CONFIG(ssl) - Q_D(QWebEngineProfile); - return d->profileAdapter()->clientCertificateStore(); -#else - return nullptr; -#endif -} - -QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h deleted file mode 100644 index a8bf70856..000000000 --- a/src/webenginewidgets/api/qwebengineprofile.h +++ /dev/null @@ -1,167 +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$ -** -****************************************************************************/ - -#ifndef QWEBENGINEPROFILE_H -#define QWEBENGINEPROFILE_H - -#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> - -#include <QtCore/qobject.h> -#include <QtCore/qscopedpointer.h> -#include <QtCore/qstring.h> - -#include <functional> -#include <memory> - -QT_BEGIN_NAMESPACE - -class QObject; -class QUrl; -class QWebEngineClientCertificateStore; -class QWebEngineCookieStore; -class QWebEngineDownloadRequest; -class QWebEngineNotification; -class QWebEnginePage; -class QWebEnginePagePrivate; -class QWebEngineProfilePrivate; -class QWebEngineSettings; -class QWebEngineScriptCollection; -class QWebEngineUrlRequestInterceptor; -class QWebEngineUrlSchemeHandler; - -class QWEBENGINEWIDGETS_EXPORT QWebEngineProfile : public QObject { - Q_OBJECT -public: - explicit QWebEngineProfile(QObject *parent = Q_NULLPTR); - explicit QWebEngineProfile(const QString &name, QObject *parent = Q_NULLPTR); - virtual ~QWebEngineProfile(); - - enum HttpCacheType { - MemoryHttpCache, - DiskHttpCache, - NoCache - }; - Q_ENUM(HttpCacheType) - - enum PersistentCookiesPolicy { - NoPersistentCookies, - AllowPersistentCookies, - ForcePersistentCookies - }; - Q_ENUM(PersistentCookiesPolicy) - - QString storageName() const; - bool isOffTheRecord() const; - - QString persistentStoragePath() const; - void setPersistentStoragePath(const QString &path); - - QString cachePath() const; - void setCachePath(const QString &path); - - QString httpUserAgent() const; - void setHttpUserAgent(const QString &userAgent); - - HttpCacheType httpCacheType() const; - void setHttpCacheType(QWebEngineProfile::HttpCacheType); - - void setHttpAcceptLanguage(const QString &httpAcceptLanguage); - QString httpAcceptLanguage() const; - - PersistentCookiesPolicy persistentCookiesPolicy() const; - void setPersistentCookiesPolicy(QWebEngineProfile::PersistentCookiesPolicy); - - int httpCacheMaximumSize() const; - void setHttpCacheMaximumSize(int maxSize); - - QWebEngineCookieStore* cookieStore(); -#if QT_DEPRECATED_SINCE(5, 13) - void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); -#endif - void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); - - void clearAllVisitedLinks(); - void clearVisitedLinks(const QList<QUrl> &urls); - bool visitedLinksContainsUrl(const QUrl &url) const; - - QWebEngineSettings *settings() const; - QWebEngineScriptCollection *scripts() const; - - const QWebEngineUrlSchemeHandler *urlSchemeHandler(const QByteArray &) const; - void installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *); - void removeUrlScheme(const QByteArray &scheme); - void removeUrlSchemeHandler(QWebEngineUrlSchemeHandler *); - void removeAllUrlSchemeHandlers(); - - void clearHttpCache(); - - void setSpellCheckLanguages(const QStringList &languages); - QStringList spellCheckLanguages() const; - void setSpellCheckEnabled(bool enabled); - bool isSpellCheckEnabled() const; - - void setUseForGlobalCertificateVerification(bool enabled = true); - bool isUsedForGlobalCertificateVerification() const; - - QString downloadPath() const; - void setDownloadPath(const QString &path); - - void setNotificationPresenter(std::function<void(std::unique_ptr<QWebEngineNotification>)> notificationPresenter); - - QWebEngineClientCertificateStore *clientCertificateStore(); - - static QWebEngineProfile *defaultProfile(); - -Q_SIGNALS: - void downloadRequested(QWebEngineDownloadRequest *download); - -private: - Q_DISABLE_COPY(QWebEngineProfile) - Q_DECLARE_PRIVATE(QWebEngineProfile) - QWebEngineProfile(QWebEngineProfilePrivate *, QObject *parent = Q_NULLPTR); - - friend class QWebEnginePage; - friend class QWebEnginePagePrivate; - friend class QWebEngineUrlSchemeHandler; - QScopedPointer<QWebEngineProfilePrivate> d_ptr; -}; - -QT_END_NAMESPACE - -#endif // QWEBENGINEPROFILE_H diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h deleted file mode 100644 index 60fa4632f..000000000 --- a/src/webenginewidgets/api/qwebengineprofile_p.h +++ /dev/null @@ -1,108 +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$ -** -****************************************************************************/ - -#ifndef QWEBENGINEPROFILE_P_H -#define QWEBENGINEPROFILE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "profile_adapter_client.h" -#include "qwebengineprofile.h" -#include "qwebenginescriptcollection.h" - -#include <QMap> -#include <QPointer> -#include <QScopedPointer> -#include <QSharedPointer> - -#include <functional> - -namespace QtWebEngineCore { -class ProfileAdapter; -} - -QT_BEGIN_NAMESPACE - -class QWebEngineBrowserContext; -class QWebEngineProfilePrivate; -class QWebEngineNotification; -class QWebEngineSettings; - -class QWebEngineProfilePrivate : public QtWebEngineCore::ProfileAdapterClient { -public: - Q_DECLARE_PUBLIC(QWebEngineProfile) - QWebEngineProfilePrivate(QtWebEngineCore::ProfileAdapter *profileAdapter); - ~QWebEngineProfilePrivate(); - - QtWebEngineCore::ProfileAdapter* profileAdapter() const; - QWebEngineSettings *settings() const { return m_settings; } - - void downloadDestroyed(quint32 downloadId); - - void cleanDownloads(); - - void downloadRequested(DownloadItemInfo &info) override; - void downloadUpdated(const DownloadItemInfo &info) override; - - void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &) override; - - void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override; - void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override; - -private: - QWebEngineProfile *q_ptr; - QWebEngineSettings *m_settings; - QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter; - QScopedPointer<QWebEngineScriptCollection> m_scriptCollection; - QMap<quint32, QPointer<QWebEngineDownloadRequest> > m_ongoingDownloads; - std::function<void(std::unique_ptr<QWebEngineNotification>)> m_notificationPresenter; -}; - -QT_END_NAMESPACE - -#endif // QWEBENGINEPROFILE_P_H diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index 203682c79..ebb818cbd 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -1,58 +1,375 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qapplication.h" +#include "qwebenginenotificationpresenter_p.h" #include "qwebengineview.h" #include "qwebengineview_p.h" - -#include "qwebenginepage_p.h" -#include "render_widget_host_view_qt_delegate_widget.h" +#include "render_widget_host_view_qt_delegate_client.h" +#include "render_widget_host_view_qt_delegate_item.h" +#include "ui/autofillpopupwidget_p.h" +#include "touchhandlewidget_p.h" +#include "touchselectionmenuwidget_p.h" + +#include <QtWebEngineCore/private/qwebenginepage_p.h> +#include <QtWebEngineCore/qwebenginecontextmenurequest.h> +#include <QtWebEngineCore/qwebenginehistory.h> +#include <QtWebEngineCore/qwebenginehttprequest.h> +#include <QtWebEngineCore/qwebengineprofile.h> + +#include "autofill_popup_controller.h" +#include "color_chooser_controller.h" +#include "touch_selection_menu_controller.h" #include "web_contents_adapter.h" +#include <QContextMenuEvent> +#include <QToolTip> +#include <QVBoxLayout> +#include <QKeyEvent> +#include <QIcon> +#include <QStyle> +#include <QGuiApplication> +#include <QQuickWidget> +#include <QtWidgets/private/qapplication_p.h> + +#if QT_CONFIG(accessibility) +#include "qwebengine_accessible_p.h" +#endif + #if QT_CONFIG(action) #include <QAction> #endif + +#if QT_CONFIG(colordialog) +#include <QColorDialog> +#endif + +#if QT_CONFIG(filedialog) +#include <QFileDialog> +#include <QStandardPaths> +#include "file_picker_controller.h" +#endif + +#if QT_CONFIG(inputdialog) +#include <QInputDialog> +#endif + #if QT_CONFIG(menu) #include <QMenu> #endif -#include <QContextMenuEvent> -#include <QToolTip> -#include <QVBoxLayout> + +#if QT_CONFIG(messagebox) +#include <QMessageBox> +#endif + +#if QT_CONFIG(webengine_printing_and_pdf) +#include "printing/printer_worker.h" + +#include <QPrintEngine> +#include <QPrinter> +#include <QThread> +#endif + +QT_BEGIN_NAMESPACE +class QSpontaneKeyEvent +{ +public: + static inline void makeSpontaneous(QEvent *ev) { ev->setSpontaneous(); } +}; +QT_END_NAMESPACE + +namespace QtWebEngineCore { +class WebEngineQuickWidget : public QQuickWidget, public WidgetDelegate +{ +public: + WebEngineQuickWidget(RenderWidgetHostViewQtDelegateItem *widget, QWidget *parent) + : QQuickWidget(parent) + , m_contentItem(widget) + { + setFocusPolicy(Qt::StrongFocus); + setMouseTracking(true); + setAttribute(Qt::WA_AcceptTouchEvents); + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_AlwaysShowToolTips); + + QQuickItem *root = new QQuickItem(); // Indirection so we don't delete m_contentItem + setContent(QUrl(), nullptr, root); + root->setFlags(QQuickItem::ItemHasContents); + root->setVisible(true); + m_contentItem->setParentItem(root); + + connectRemoveParentBeforeParentDelete(); + } + ~WebEngineQuickWidget() override + { + if (m_contentItem) { + m_contentItem->setWidgetDelegate(nullptr); + m_contentItem->setParentItem(nullptr); + } + } + + void InitAsPopup(const QRect &screenRect) override + { + setAttribute(Qt::WA_ShowWithoutActivating); + setFocusPolicy(Qt::NoFocus); + setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus); + + setGeometry(screenRect); + raise(); + m_contentItem->show(); + show(); + } + + void Bind(WebContentsAdapterClient *client) override + { + QWebEnginePagePrivate *page = static_cast<QWebEnginePagePrivate *>(client); + if (m_pageDestroyedConnection) + QObject::disconnect(m_pageDestroyedConnection); + QWebEngineViewPrivate::bindPageAndWidget(page, this); + m_pageDestroyedConnection = QObject::connect(page->q_ptr, &QObject::destroyed, this, &WebEngineQuickWidget::Unbind); + } + + void Unbind() override + { + if (m_pageDestroyedConnection) { + QObject::disconnect(m_pageDestroyedConnection); + m_pageDestroyedConnection = {}; + } + QWebEngineViewPrivate::bindPageAndWidget(nullptr, this); + } + + void Destroy() override + { + deleteLater(); + } + + bool ActiveFocusOnPress() override + { + return true; + } + + void SetInputMethodEnabled(bool enabled) override + { + QQuickWidget::setAttribute(Qt::WA_InputMethodEnabled, enabled); + } + void SetInputMethodHints(Qt::InputMethodHints hints) override + { + QQuickWidget::setInputMethodHints(hints); + } + void SetClearColor(const QColor &color) override + { + setUpdatesEnabled(false); + QQuickWidget::setClearColor(color); + // QQuickWidget is usually blended by punching holes into widgets + // above it to simulate the visual stacking order. If we want it to be + // transparent we have to throw away the proper stacking order and always + // blend the complete normal widgets backing store under it. + bool isTranslucent = color.alpha() < 255; + setAttribute(Qt::WA_AlwaysStackOnTop, isTranslucent); + setAttribute(Qt::WA_OpaquePaintEvent, !isTranslucent); + setUpdatesEnabled(true); + window()->update(); + } + void MoveWindow(const QPoint &screenPos) override + { + QQuickWidget::move(screenPos); + } + void Resize(int width, int height) override + { + QQuickWidget::resize(width, height); + } + QWindow *Window() override + { + if (const QWidget *root = QQuickWidget::window()) + return root->windowHandle(); + return nullptr; + } + void unhandledWheelEvent(QWheelEvent *ev) override + { + auto parentWidget = QQuickWidget::parentWidget(); + if (parentWidget) { + if (QApplicationPrivate::wheel_widget) + QApplicationPrivate::wheel_widget = nullptr; + QSpontaneKeyEvent::makeSpontaneous(ev); + qApp->notify(parentWidget, ev); + } + } + +protected: + void closeEvent(QCloseEvent *event) override + { + QQuickWidget::closeEvent(event); + + // If a close event was received from the window manager (e.g. when moving the parent window, + // clicking outside the popup area) + // make sure to notify the Chromium WebUI popup and its underlying + // RenderWidgetHostViewQtDelegate instance to be closed. + if (m_contentItem && m_contentItem->m_isPopup) + m_contentItem->m_client->closePopup(); + } + void showEvent(QShowEvent *event) override + { + QQuickWidget::showEvent(event); + // We don't have a way to catch a top-level window change with QWidget + // but a widget will most likely be shown again if it changes, so do + // the reconnection at this point. + for (const QMetaObject::Connection &c : std::as_const(m_windowConnections)) + disconnect(c); + m_windowConnections.clear(); + if (QWindow *w = Window()) { + m_windowConnections.append(connect(w, SIGNAL(xChanged(int)), m_contentItem, SLOT(onWindowPosChanged()))); + m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), m_contentItem, SLOT(onWindowPosChanged()))); + } + } + void resizeEvent(QResizeEvent *event) override + { + QQuickWidget::resizeEvent(event); + if (m_contentItem) { // FIXME: Not sure why we need to set m_contentItem size manually + m_contentItem->setSize(event->size()); + m_contentItem->onWindowPosChanged(); + } + } + QVariant inputMethodQuery(Qt::InputMethodQuery query) const override + { + if (m_contentItem) + return m_contentItem->inputMethodQuery(query); + return QVariant(); + } + bool event(QEvent *event) override; + + void connectRemoveParentBeforeParentDelete(); + void removeParentBeforeParentDelete(); + +private: + friend QWebEngineViewPrivate; + QPointer<RenderWidgetHostViewQtDelegateItem> m_contentItem; // deleted by core + QMetaObject::Connection m_parentDestroyedConnection; + QMetaObject::Connection m_pageDestroyedConnection; + QList<QMetaObject::Connection> m_windowConnections; +}; + +void WebEngineQuickWidget::connectRemoveParentBeforeParentDelete() +{ + disconnect(m_parentDestroyedConnection); + + if (QWidget *parent = parentWidget()) { + m_parentDestroyedConnection = connect(parent, &QObject::destroyed, + this, + &WebEngineQuickWidget::removeParentBeforeParentDelete); + } else { + m_parentDestroyedConnection = QMetaObject::Connection(); + } +} + +void WebEngineQuickWidget::removeParentBeforeParentDelete() +{ + // Unset the parent, because parent is being destroyed, but the owner of this + // WebEngineQuickWidget is actually a RenderWidgetHostViewQt instance. + setParent(nullptr); + + // If this widget represents a popup window, make sure to close it, so that if the popup was the + // last visible top level window, the application event loop can quit if it deems it necessarry. + if (m_contentItem && m_contentItem->m_isPopup) + close(); +} + +bool WebEngineQuickWidget::event(QEvent *event) +{ + bool handled = false; + + // Track parent to make sure we don't get deleted. + if (event->type() == QEvent::ParentChange) + connectRemoveParentBeforeParentDelete(); + + if (!m_contentItem) + return QQuickWidget::event(event); + + // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is + // disabled. + if (!isEnabled()) { + switch (event->type()) { + case QEvent::TabletPress: + case QEvent::TabletRelease: + case QEvent::TabletMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + case QEvent::ContextMenu: + case QEvent::KeyPress: + case QEvent::KeyRelease: +#if QT_CONFIG(wheelevent) + case QEvent::Wheel: +#endif + return false; + default: + break; + } + } + + switch (event->type()) { + case QEvent::FocusIn: + case QEvent::FocusOut: + // We forward focus events later, once they have made it to the content item. + return QQuickWidget::event(event); + case QEvent::DragEnter: + case QEvent::DragLeave: + case QEvent::DragMove: + case QEvent::Drop: + case QEvent::HoverEnter: + case QEvent::HoverLeave: + case QEvent::HoverMove: + // Let the parent handle these events. + return false; + default: + break; + } + + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + // Don't forward mouse events synthesized by the system, which are caused by genuine touch + // events. Chromium would then process for e.g. a mouse click handler twice, once due to the + // system synthesized mouse event, and another time due to a touch-to-gesture-to-mouse + // transformation done by Chromium. + // Only allow them for popup type, since QWidgetWindow will ignore them for Qt::Popup flag, + // which is expected to get input through synthesized mouse events (either by system or Qt) + if (!m_contentItem->m_isPopup && + static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem) { + Q_ASSERT(!windowFlags().testFlag(Qt::Popup)); + return true; + } + break; + default: + break; + } + + if (event->type() == QEvent::MouseButtonDblClick) { + // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event. + // QtQuick is different by sending both the Press and DblClick events for the second press + // where we can simply ignore the DblClick event. + QMouseEvent *dblClick = static_cast<QMouseEvent *>(event); + QMouseEvent press(QEvent::MouseButtonPress, dblClick->position(), dblClick->scenePosition(), + dblClick->globalPosition(), dblClick->button(), dblClick->buttons(), + dblClick->modifiers(), dblClick->source()); + press.setTimestamp(dblClick->timestamp()); + handled = m_contentItem->m_client->forwardEvent(&press); + } else + handled = m_contentItem->m_client->forwardEvent(event); + + if (!handled) + return QQuickWidget::event(event); + event->accept(); + return true; +} + +} // namespace QtWebEngineCore QT_BEGIN_NAMESPACE @@ -62,7 +379,15 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage if (oldPage) { oldPage->setVisible(false); - oldPage->disconnect(q); + QObject::disconnect(oldPage, &QWebEnginePage::titleChanged, q, &QWebEngineView::titleChanged); + QObject::disconnect(oldPage, &QWebEnginePage::urlChanged, q, &QWebEngineView::urlChanged); + QObject::disconnect(oldPage, &QWebEnginePage::iconUrlChanged, q, &QWebEngineView::iconUrlChanged); + QObject::disconnect(oldPage, &QWebEnginePage::iconChanged, q, &QWebEngineView::iconChanged); + QObject::disconnect(oldPage, &QWebEnginePage::loadStarted, q, &QWebEngineView::loadStarted); + QObject::disconnect(oldPage, &QWebEnginePage::loadProgress, q, &QWebEngineView::loadProgress); + QObject::disconnect(oldPage, &QWebEnginePage::loadFinished, q, &QWebEngineView::loadFinished); + QObject::disconnect(oldPage, &QWebEnginePage::selectionChanged, q, &QWebEngineView::selectionChanged); + QObject::disconnect(oldPage, &QWebEnginePage::renderProcessTerminated, q, &QWebEngineView::renderProcessTerminated); } if (newPage) { @@ -99,8 +424,8 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage Q_EMIT q->selectionChanged(); } -void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget, - QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget) +void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::WebEngineQuickWidget *oldWidget, + QtWebEngineCore::WebEngineQuickWidget *newWidget) { Q_Q(QWebEngineView); @@ -108,19 +433,22 @@ void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQ q->layout()->removeWidget(oldWidget); oldWidget->hide(); #if QT_CONFIG(accessibility) - QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(QAccessible::queryAccessibleInterface(oldWidget))); + if (!QtWebEngineCore::closingDown()) + QAccessible::deleteAccessibleInterface( + QAccessible::uniqueId(QAccessible::queryAccessibleInterface(oldWidget))); #endif } if (newWidget) { + Q_ASSERT(!QtWebEngineCore::closingDown()); #if QT_CONFIG(accessibility) - // An earlier QAccessible::queryAccessibleInterface() call may have already registered a default - // QAccessibleInterface for newWidget: remove it first to avoid assert in QAccessibleCache::insert(). QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(QAccessible::queryAccessibleInterface(newWidget))); QAccessible::registerAccessibleInterface(new QtWebEngineCore::RenderWidgetHostViewQtDelegateWidgetAccessible(newWidget, q)); #endif q->layout()->addWidget(newWidget); q->setFocusProxy(newWidget); + if (oldWidget && oldWidget == QApplication::focusWidget()) + newWidget->setFocus(); newWidget->show(); } } @@ -140,7 +468,7 @@ void QWebEngineViewPrivate::contextMenuRequested(QWebEngineContextMenuRequest *r Q_EMIT q_ptr->customContextMenuRequested(request->position()); return; case Qt::ActionsContextMenu: - if (q_ptr->actions().count()) { + if (q_ptr->actions().size()) { QContextMenuEvent event(QContextMenuEvent::Mouse, request->position(), q_ptr->mapToGlobal(request->position())); QMenu::exec(q_ptr->actions(), event.globalPos(), 0, q_ptr); @@ -153,25 +481,479 @@ void QWebEngineViewPrivate::contextMenuRequested(QWebEngineContextMenuRequest *r Q_UNREACHABLE(); #else - Q_UNUSED(data); + Q_UNUSED(request); #endif // QT_CONFIG(action) } -#ifndef QT_NO_ACCESSIBILITY +QStringList QWebEngineViewPrivate::chooseFiles(QWebEnginePage::FileSelectionMode mode, + const QStringList &oldFiles, + const QStringList &acceptedMimeTypes) +{ +#if QT_CONFIG(filedialog) + Q_Q(QWebEngineView); + const QStringList &filter = + QtWebEngineCore::FilePickerController::nameFilters(acceptedMimeTypes); + QStringList ret; + QString str; + switch (static_cast<QtWebEngineCore::FilePickerController::FileChooserMode>(mode)) { + case QtWebEngineCore::FilePickerController::OpenMultiple: + ret = QFileDialog::getOpenFileNames(q, QString(), QString(), + filter.join(QStringLiteral(";;")), nullptr, + QFileDialog::HideNameFilterDetails); + break; + case QtWebEngineCore::FilePickerController::UploadFolder: + str = QFileDialog::getExistingDirectory(q, QWebEngineView::tr("Select folder to upload")); + if (!str.isNull()) + ret << str; + break; + case QtWebEngineCore::FilePickerController::Save: + str = QFileDialog::getSaveFileName( + q, QString(), + (QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + + oldFiles.first())); + if (!str.isNull()) + ret << str; + break; + case QtWebEngineCore::FilePickerController::Open: + str = QFileDialog::getOpenFileName(q, QString(), oldFiles.first(), + filter.join(QStringLiteral(";;")), nullptr, + QFileDialog::HideNameFilterDetails); + if (!str.isNull()) + ret << str; + break; + } + return ret; +#else + Q_UNUSED(mode); + Q_UNUSED(oldFiles); + Q_UNUSED(acceptedMimeTypes); + + return QStringList(); +#endif // QT_CONFIG(filedialog) +} + +void QWebEngineViewPrivate::showColorDialog( + QSharedPointer<QtWebEngineCore::ColorChooserController> controller) +{ +#if QT_CONFIG(colordialog) + Q_Q(QWebEngineView); + QColorDialog *dialog = new QColorDialog(controller.data()->initialColor(), q); + + QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), controller.data(), + SLOT(accept(QColor))); + QColorDialog::connect(dialog, SIGNAL(rejected()), controller.data(), SLOT(reject())); + + // Delete when done + QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), dialog, SLOT(deleteLater())); + QColorDialog::connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater())); + +#if defined(Q_OS_MACOS) + dialog->setOption(QColorDialog::DontUseNativeDialog); +#endif + + dialog->open(); +#else + Q_UNUSED(controller); +#endif +} + +bool QWebEngineViewPrivate::showAuthorizationDialog(const QString &title, const QString &message) +{ +#if QT_CONFIG(messagebox) + Q_Q(QWebEngineView); + QMessageBox msgBox(QMessageBox::Question, title, message, QMessageBox::Yes | QMessageBox::No, + q, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); + msgBox.setTextFormat(Qt::PlainText); + return msgBox.exec() == QMessageBox::Yes; +#else + return false; +#endif // QT_CONFIG(messagebox) +} + +void QWebEngineViewPrivate::javaScriptAlert(const QUrl &url, const QString &msg) +{ +#if QT_CONFIG(messagebox) + Q_Q(QWebEngineView); + QMessageBox msgBox(QMessageBox::Information, + QStringLiteral("Javascript Alert - %1").arg(url.toString()), + msg, QMessageBox::Ok, q, + Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); + msgBox.setTextFormat(Qt::PlainText); + msgBox.exec(); +#else + Q_UNUSED(msg); +#endif // QT_CONFIG(messagebox) +} + +bool QWebEngineViewPrivate::javaScriptConfirm(const QUrl &url, const QString &msg) +{ +#if QT_CONFIG(messagebox) + Q_Q(QWebEngineView); + QMessageBox msgBox(QMessageBox::Information, + QStringLiteral("Javascript Confirm - %1").arg(url.toString()), + msg, QMessageBox::Ok | QMessageBox::Cancel, q, + Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); + msgBox.setTextFormat(Qt::PlainText); + return msgBox.exec() == QMessageBox::Ok; +#else + Q_UNUSED(msg); + return false; +#endif // QT_CONFIG(messagebox) +} + +bool QWebEngineViewPrivate::javaScriptPrompt(const QUrl &url, const QString &msg, + const QString &defaultValue, QString *result) +{ +#if QT_CONFIG(inputdialog) + Q_Q(QWebEngineView); + bool ret = false; + + // Workaround: Do not interpret text as Qt::RichText + // QInputDialog uses Qt::AutoText that interprets the text string as + // Qt::RichText if Qt::mightBeRichText() returns true, otherwise as Qt::PlainText. + const QString message = Qt::mightBeRichText(msg) ? msg.toHtmlEscaped() : msg; + + if (result) + *result = QInputDialog::getText( + q, QStringLiteral("Javascript Prompt - %1").arg(url.toString()), + message, QLineEdit::Normal, defaultValue, &ret); + return ret; +#else + Q_UNUSED(msg); + Q_UNUSED(defaultValue); + Q_UNUSED(result); + return false; +#endif // QT_CONFIG(inputdialog) +} + +void QWebEngineViewPrivate::focusContainer() +{ + Q_Q(QWebEngineView); + q->activateWindow(); + q->setFocus(); +} + +void QWebEngineViewPrivate::unhandledKeyEvent(QKeyEvent *event) +{ + Q_Q(QWebEngineView); + if (q->parentWidget()) + QGuiApplication::sendEvent(q->parentWidget(), event); +} + +bool QWebEngineViewPrivate::passOnFocus(bool reverse) +{ + Q_Q(QWebEngineView); + return q->focusNextPrevChild(!reverse); +} + +#if QT_CONFIG(accessibility) static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object) { if (QWebEngineView *v = qobject_cast<QWebEngineView*>(object)) return new QWebEngineViewAccessible(v); return nullptr; } -#endif // QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(accessibility) QWebEngineViewPrivate::QWebEngineViewPrivate() - : page(0), m_dragEntered(false), m_ownsPage(false), m_contextRequest(nullptr) + : page(nullptr) + , m_dragEntered(false) + , m_ownsPage(false) + , m_contextRequest(nullptr) { -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) QAccessible::installFactory(&webAccessibleFactory); -#endif // QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(accessibility) +} + +QWebEngineViewPrivate::~QWebEngineViewPrivate() = default; + +// static +void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView *view) +{ + QWebEngineViewPrivate *v = + page ? static_cast<QWebEngineViewPrivate *>(page->d_func()->view) : nullptr; + auto oldView = v ? v->q_func() : nullptr; + auto oldPage = view ? view->d_func()->page : nullptr; + + bool ownNewPage = false; + bool deleteOldPage = false; + + // Change pointers first. + + if (page && oldView != view) { + if (oldView) { + ownNewPage = oldView->d_func()->m_ownsPage; + oldView->d_func()->page = nullptr; + oldView->d_func()->m_ownsPage = false; + } + page->d_func()->view = view ? view->d_func() : nullptr; + } + + if (view && oldPage != page) { + if (oldPage) { + if (oldPage->d_func()) + oldPage->d_func()->view = nullptr; + deleteOldPage = view->d_func()->m_ownsPage; + } + view->d_func()->m_ownsPage = ownNewPage; + view->d_func()->page = page; + } + + // Then notify. + + auto item = page ? page->d_func()->delegateItem : nullptr; + auto oldItem = (oldPage && oldPage->d_func()) ? oldPage->d_func()->delegateItem : nullptr; + auto widget = item ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(item->m_widgetDelegate) : nullptr; + auto oldWidget = oldItem ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(oldItem->m_widgetDelegate) : nullptr; + + // New page/widget moving away from oldView + if (page && oldView != view && oldView) { + oldView->d_func()->pageChanged(page, nullptr); + if (widget) + oldView->d_func()->widgetChanged(widget, nullptr); + } + + // New page/widget moving into new view + if (view && oldPage != page) { + if (oldPage && oldPage->d_func()) + view->d_func()->pageChanged(oldPage, page); + else + view->d_func()->pageChanged(nullptr, page); + if (!widget && item) { + widget = new QtWebEngineCore::WebEngineQuickWidget(item, nullptr); + item->setWidgetDelegate(widget); + } + if (oldWidget != widget) + view->d_func()->widgetChanged(oldWidget, widget); + } + if (deleteOldPage) + delete oldPage; +} + +// static +void QWebEngineViewPrivate::bindPageAndWidget(QWebEnginePagePrivate *pagePrivate, + QtWebEngineCore::WebEngineQuickWidget *widget) +{ + auto *oldAdapterClient = (widget && widget->m_contentItem) ? widget->m_contentItem->m_adapterClient : nullptr; + auto *oldPagePrivate = static_cast<QWebEnginePagePrivate *>(oldAdapterClient); + auto *oldItem = pagePrivate ? pagePrivate->delegateItem : nullptr; + auto *oldWidget = oldItem ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(oldItem->m_widgetDelegate) : nullptr; + + // Change pointers first. + + if (widget && oldPagePrivate != pagePrivate) { + if (oldPagePrivate) + oldPagePrivate->delegateItem = nullptr; + if (widget->m_contentItem) + widget->m_contentItem->m_adapterClient = pagePrivate; + } + + if (pagePrivate && oldWidget != widget) { + if (oldWidget && oldWidget->m_contentItem) + oldWidget->m_contentItem->m_adapterClient = nullptr; + if (widget) + pagePrivate->delegateItem = widget->m_contentItem; + } + + // Then notify. + + if (oldPagePrivate && oldPagePrivate != pagePrivate) { + if (auto oldView = oldPagePrivate->view) + static_cast<QWebEngineViewPrivate *>(oldView)->widgetChanged(widget, nullptr); + } + + if (pagePrivate && oldWidget != widget) { + if (auto view = pagePrivate->view) + static_cast<QWebEngineViewPrivate *>(view)->widgetChanged(oldWidget, widget); + } +} + +QIcon QWebEngineViewPrivate::webActionIcon(QWebEnginePage::WebAction action) const +{ + Q_Q(const QWebEngineView); + QIcon icon; + QStyle *style = q->style(); + + switch (action) { + case QWebEnginePage::Back: + icon = style->standardIcon(QStyle::SP_ArrowBack); + break; + case QWebEnginePage::Forward: + icon = style->standardIcon(QStyle::SP_ArrowForward); + break; + case QWebEnginePage::Stop: + icon = style->standardIcon(QStyle::SP_BrowserStop); + break; + case QWebEnginePage::Reload: + icon = style->standardIcon(QStyle::SP_BrowserReload); + break; + case QWebEnginePage::ReloadAndBypassCache: + icon = style->standardIcon(QStyle::SP_BrowserReload); + break; + default: + break; + } + return icon; +} + +QWebEnginePage *QWebEngineViewPrivate::createPageForWindow(QWebEnginePage::WebWindowType type) +{ + Q_Q(QWebEngineView); + QWebEngineView *newView = q->createWindow(type); + if (newView) + return newView->page(); + return nullptr; +} + +void QWebEngineViewPrivate::setToolTip(const QString &toolTipText) +{ + Q_Q(QWebEngineView); + if (toolTipText.isEmpty()) { + // Avoid duplicate events. + if (!q->toolTip().isEmpty()) + q->setToolTip(QString()); + // Force to hide tooltip because QWidget's default handler + // doesn't hide on empty text. + if (!QToolTip::text().isEmpty()) + QToolTip::hideText(); + } else if (toolTipText != q->toolTip()) { + q->setToolTip(toolTipText); + } + +} + +bool QWebEngineViewPrivate::isEnabled() const +{ + Q_Q(const QWebEngineView); + return q->isEnabled(); +} + +QObject *QWebEngineViewPrivate::accessibilityParentObject() +{ + Q_Q(QWebEngineView); + return q; +} + +void QWebEngineViewPrivate::didPrintPage(QPrinter *¤tPrinter, QSharedPointer<QByteArray> result) +{ +#if QT_CONFIG(webengine_printing_and_pdf) + Q_Q(QWebEngineView); + + Q_ASSERT(currentPrinter); + + QThread *printerThread = new QThread; + QObject::connect(printerThread, &QThread::finished, printerThread, &QThread::deleteLater); + printerThread->start(); + + QtWebEngineCore::PrinterWorker *printerWorker = new QtWebEngineCore::PrinterWorker(result, currentPrinter); + printerWorker->m_deviceResolution = currentPrinter->resolution(); + printerWorker->m_firstPageFirst = currentPrinter->pageOrder() == QPrinter::FirstPageFirst; + printerWorker->m_documentCopies = currentPrinter->copyCount(); + printerWorker->m_collateCopies = currentPrinter->collateCopies(); + + int oldCopyCount = currentPrinter->copyCount(); + currentPrinter->printEngine()->setProperty(QPrintEngine::PPK_CopyCount, 1); + + QObject::connect(printerWorker, &QtWebEngineCore::PrinterWorker::resultReady, q, [q, ¤tPrinter, oldCopyCount](bool success) { + currentPrinter->printEngine()->setProperty(QPrintEngine::PPK_CopyCount, oldCopyCount); + currentPrinter = nullptr; + Q_EMIT q->printFinished(success); + }); + + QObject::connect(printerWorker, &QtWebEngineCore::PrinterWorker::resultReady, printerThread, &QThread::quit); + QObject::connect(printerThread, &QThread::finished, printerWorker, &QtWebEngineCore::PrinterWorker::deleteLater); + + printerWorker->moveToThread(printerThread); + QMetaObject::invokeMethod(printerWorker, "print"); + +#else + Q_UNUSED(currentPrinter); + Q_UNUSED(result); +#endif +} + +void QWebEngineViewPrivate::didPrintPageToPdf(const QString &filePath, bool success) +{ + Q_Q(QWebEngineView); + Q_EMIT q->pdfPrintingFinished(filePath, success); +} + +void QWebEngineViewPrivate::printRequested() +{ + Q_Q(QWebEngineView); + QTimer::singleShot(0, q, [q]() { + Q_EMIT q->printRequested(); + }); +} + +void QWebEngineViewPrivate::printRequestedByFrame(QWebEngineFrame frame) +{ + Q_Q(QWebEngineView); + QTimer::singleShot(0, q, [q, frame]() { Q_EMIT q->printRequestedByFrame(frame); }); +} + +bool QWebEngineViewPrivate::isVisible() const +{ + Q_Q(const QWebEngineView); + return q->isVisible(); +} +QRect QWebEngineViewPrivate::viewportRect() const +{ + Q_Q(const QWebEngineView); + return q->rect(); +} +QtWebEngineCore::RenderWidgetHostViewQtDelegate * +QWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate( + QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) +{ + auto *item = new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, false); + auto *widget = new QtWebEngineCore::WebEngineQuickWidget(item, nullptr); + item->setWidgetDelegate(widget); + return item; +} + +QtWebEngineCore::RenderWidgetHostViewQtDelegate * +QWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegateForPopup( + QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) +{ + Q_Q(QWebEngineView); + auto *item = new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, true); + auto *widget = new QtWebEngineCore::WebEngineQuickWidget(item, q); + item->setWidgetDelegate(widget); + return item; +} + +QWebEngineContextMenuRequest *QWebEngineViewPrivate::lastContextMenuRequest() const +{ + return m_contextRequest; +} + +void QWebEngineViewPrivate::showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller, + const QRect &bounds, bool autoselectFirstSuggestion) +{ + Q_Q(QWebEngineView); + if (!m_autofillPopupWidget) + m_autofillPopupWidget.reset(new QtWebEngineWidgetUI::AutofillPopupWidget(controller, q)); + m_autofillPopupWidget->showPopup(q->mapToGlobal(bounds.bottomLeft()), bounds.width() + 2, + autoselectFirstSuggestion); + controller->notifyPopupShown(); +} + +void QWebEngineViewPrivate::hideAutofillPopup() +{ + if (!m_autofillPopupWidget) + return; + + Q_Q(QWebEngineView); + QTimer::singleShot(0, q, [this] { + if (m_autofillPopupWidget) { + QtWebEngineCore::AutofillPopupController *controller = + m_autofillPopupWidget->m_controller; + m_autofillPopupWidget.reset(); + controller->notifyPopupHidden(); + } + }); } /*! @@ -206,10 +988,58 @@ QWebEngineView::QWebEngineView(QWidget *parent) setLayout(layout); } +/*! + \since 6.4 + + Constructs an empty web view using \a profile with the parent \a parent. + + \note The \a profile object ownership is not taken and it should outlive the view. + + \sa load() +*/ + +QWebEngineView::QWebEngineView(QWebEngineProfile *profile, QWidget *parent) + : QWebEngineView(parent) +{ + Q_D(QWebEngineView); + setPage(new QWebEnginePage(profile, this)); + d->m_ownsPage = true; +} + +/*! + \since 6.4 + + Constructs a web view containing \a page with the parent \a parent. + + \note Ownership of \a page is not taken, and it is up to the caller to ensure it is deleted. + + \sa load(), setPage() +*/ + +QWebEngineView::QWebEngineView(QWebEnginePage *page, QWidget *parent) + : QWebEngineView(parent) +{ + setPage(page); +} + QWebEngineView::~QWebEngineView() { blockSignals(true); - QWebEnginePagePrivate::bindPageAndView(nullptr, this); + QWebEngineViewPrivate::bindPageAndView(nullptr, this); +} + +/*! + \since 6.2 + + Returns the view if any, associated with the \a page. + + \sa page(), setPage() +*/ +QWebEngineView *QWebEngineView::forPage(const QWebEnginePage *page) +{ + if (!page) + return nullptr; + return qobject_cast<QWebEngineView *>(page->d_ptr->accessibilityParentObject()); } QWebEnginePage* QWebEngineView::page() const @@ -225,7 +1055,20 @@ QWebEnginePage* QWebEngineView::page() const void QWebEngineView::setPage(QWebEnginePage *newPage) { - QWebEnginePagePrivate::bindPageAndView(newPage, this); + Q_D(QWebEngineView); + if (d->page) { + disconnect(d->m_pageConnection); + d->m_pageConnection = {}; + } + + QWebEngineViewPrivate::bindPageAndView(newPage, this); + if (!newPage) + return; + d->m_pageConnection = connect(newPage, &QWebEnginePage::_q_aboutToDelete, this, + [newPage]() { QWebEngineViewPrivate::bindPageAndView(newPage, nullptr); }); + auto profile = newPage->profile(); + if (!profile->notificationPresenter()) + profile->setNotificationPresenter(&defaultNotificationPresenter); } void QWebEngineView::load(const QUrl& url) @@ -303,10 +1146,19 @@ QString QWebEngineView::selectedText() const return page()->selectedText(); } -#ifndef QT_NO_ACTION +#if QT_CONFIG(action) QAction* QWebEngineView::pageAction(QWebEnginePage::WebAction action) const { - return page()->action(action); + Q_D(const QWebEngineView); + QAction *pageAction = page()->action(action); + + if (pageAction->icon().isNull()) { + auto icon = d->webActionIcon(action); + if (!icon.isNull()) + pageAction->setIcon(icon); + } + + return pageAction; } #endif @@ -315,7 +1167,7 @@ void QWebEngineView::triggerPageAction(QWebEnginePage::WebAction action, bool ch page()->triggerAction(action, checked); } -void QWebEngineView::findText(const QString &subString, QWebEnginePage::FindFlags options, const QWebEngineCallback<bool> &resultCallback) +void QWebEngineView::findText(const QString &subString, QWebEnginePage::FindFlags options, const std::function<void(const QWebEngineFindTextResult &)> &resultCallback) { page()->findText(subString, options, resultCallback); } @@ -357,7 +1209,7 @@ void QWebEngineView::reload() QWebEngineView *QWebEngineView::createWindow(QWebEnginePage::WebWindowType type) { Q_UNUSED(type); - return 0; + return nullptr; } qreal QWebEngineView::zoomFactor() const @@ -388,17 +1240,6 @@ bool QWebEngineView::event(QEvent *ev) return true; } - // Override QWidget's default ToolTip handler since it doesn't hide tooltip on empty text. - if (ev->type() == QEvent::ToolTip) { - if (!toolTip().isEmpty()) - QToolTip::showText(static_cast<QHelpEvent *>(ev)->globalPos(), toolTip(), this, QRect(), toolTipDuration()); - else - QToolTip::hideText(); - - ev->accept(); - return true; - } - return QWidget::event(ev); } @@ -502,6 +1343,9 @@ void QWebEngineView::dropEvent(QDropEvent *e) #endif // QT_CONFIG(draganddrop) #if QT_CONFIG(menu) +/*! + Creates a standard context menu and returns a pointer to it. +*/ QMenu *QWebEngineView::createStandardContextMenu() { Q_D(QWebEngineView); @@ -517,10 +1361,10 @@ QMenu *QWebEngineView::createStandardContextMenu() #endif // QT_CONFIG(menu) /*! - \since 6.0 + \since 6.2 Returns additional data about the current context menu. It is only guaranteed to be valid during - the call to the contextMenuEvent() + the call to the contextMenuEvent(). \sa createStandardContextMenu() */ @@ -530,44 +1374,139 @@ QWebEngineContextMenuRequest *QWebEngineView::lastContextMenuRequest() const return d->m_contextRequest; } -#ifndef QT_NO_ACCESSIBILITY -bool QWebEngineViewAccessible::isValid() const -{ - if (!QAccessibleWidget::isValid()) - return false; +/*! + \fn void QWebEngineView::pdfPrintingFinished(const QString &filePath, bool success) + \since 6.2 - if (!view() || !view()->d_func() || !view()->d_func()->page || !view()->d_func()->page->d_func()) - return false; + This signal is emitted when printing the web page into a PDF file has + finished. + \a filePath will contain the path the file was requested to be created + at, and \a success will be \c true if the file was successfully created and + \c false otherwise. - return true; -} + \sa printToPdf() +*/ -QAccessibleInterface *QWebEngineViewAccessible::focusChild() const +/*! + Renders the current content of the page into a PDF document and saves it + in the location specified in \a filePath. + The page size and orientation of the produced PDF document are taken from + the values specified in \a layout, while the range of pages printed is + taken from \a ranges with the default being printing all pages. + + This method issues an asynchronous request for printing the web page into + a PDF and returns immediately. + To be informed about the result of the request, connect to the signal + pdfPrintingFinished(). + + If a file already exists at the provided file path, it will be overwritten. + \since 6.2 + \sa pdfPrintingFinished() +*/ +void QWebEngineView::printToPdf(const QString &filePath, const QPageLayout &layout, const QPageRanges &ranges) { - if (child(0) && child(0)->focusChild()) - return child(0)->focusChild(); - return const_cast<QWebEngineViewAccessible *>(this); + page()->printToPdf(filePath, layout, ranges); } -int QWebEngineViewAccessible::childCount() const -{ - return child(0) ? 1 : 0; -} +/*! + Renders the current content of the page into a PDF document and returns a byte array containing the PDF data + as parameter to \a resultCallback. + The page size and orientation of the produced PDF document are taken from the values specified in \a layout, + while the range of pages printed is taken from \a ranges with the default being printing all pages. + + The \a resultCallback must take a const reference to a QByteArray as parameter. If printing was successful, this byte array + will contain the PDF data, otherwise, the byte array will be empty. + + \warning We guarantee that the callback (\a resultCallback) is always called, but it might be done + during page destruction. When QWebEnginePage is deleted, the callback is triggered with an invalid + value and it is not safe to use the corresponding QWebEnginePage or QWebEngineView instance inside it. -QAccessibleInterface *QWebEngineViewAccessible::child(int index) const + \since 6.2 +*/ +void QWebEngineView::printToPdf(const std::function<void(const QByteArray&)> &resultCallback, const QPageLayout &layout, const QPageRanges &ranges) { - if (index == 0 && isValid()) - return view()->page()->d_func()->adapter->browserAccessible(); - return nullptr; + page()->printToPdf(resultCallback, layout, ranges); } -int QWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const +/*! + \fn void QWebEngineView::printRequested() + \since 6.2 + + This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print + button of PDF viewer plugin. + Typically, the signal handler can simply call print(). + + Since 6.8, this signal is only emitted for the main frame, instead of being emitted + for any frame that requests printing. + + \sa printRequestedByFrame(), print() +*/ + +/*! + \fn void QWebEngineView::printRequestedByFrame(QWebEngineFrame frame) + \since 6.8 + + This signal is emitted when the JavaScript \c{window.print()} method is called on \a frame. + If the frame is the main frame, \c{printRequested} is emitted instead. + + \sa printRequested(), print() +*/ + +/*! + \fn void QWebEngineView::printFinished(bool success) + \since 6.2 + + This signal is emitted when printing requested with print() has finished. + The parameter \a success is \c true for success or \c false for failure. + + \sa print() +*/ + +/*! + Renders the current content of the page into a temporary PDF document, then prints it using \a printer. + + The settings for creating and printing the PDF document will be retrieved from the \a printer + object. + + When finished the signal printFinished() is emitted with the \c true for success or \c false for failure. + + It is the users responsibility to ensure the \a printer remains valid until printFinished() + has been emitted. + + \note Printing runs on the browser process, which is by default not sandboxed. + + \note The data generation step of printing can be interrupted for a short period of time using + the \l QWebEnginePage::Stop web action. + + \note This function rasterizes the result when rendering onto \a printer. Please consider raising + the default resolution of \a printer to at least 300 DPI or using printToPdf() to produce + PDF file output more effectively. + + \since 6.2 +*/ +void QWebEngineView::print(QPrinter *printer) { - if (child(0) && c == child(0)) - return 0; - return -1; +#if QT_CONFIG(webengine_printing_and_pdf) + auto *dPage = page()->d_ptr.get(); + if (dPage->currentPrinter) { + qWarning("Cannot print page on printer %ls: Already printing on a device.", qUtf16Printable(printer->printerName())); + return; + } + + dPage->currentPrinter = printer; + dPage->ensureInitialized(); + std::function callback = [dPage](QSharedPointer<QByteArray> result) { + dPage->didPrintPage(std::move(result)); + }; + dPage->adapter->printToPDFCallbackResult(std::move(callback), printer->pageLayout(), + printer->pageRanges(), + printer->colorMode() == QPrinter::Color, false, + QtWebEngineCore::WebContentsAdapter::kUseMainFrameId); +#else + Q_UNUSED(printer); + Q_EMIT printFinished(false); +#endif } -#endif // QT_NO_ACCESSIBILITY #if QT_CONFIG(action) QContextMenuBuilder::QContextMenuBuilder(QWebEngineContextMenuRequest *request, @@ -590,86 +1529,86 @@ bool QContextMenuBuilder::isFullScreenMode() void QContextMenuBuilder::addMenuItem(ContextMenuItem menuItem) { QPointer<QWebEnginePage> thisRef(m_view->page()); - QAction *action = 0; + QAction *action = nullptr; switch (menuItem) { case ContextMenuItem::Back: - action = thisRef->action(QWebEnginePage::Back); + action = m_view->pageAction(QWebEnginePage::Back); break; case ContextMenuItem::Forward: - action = thisRef->action(QWebEnginePage::Forward); + action = m_view->pageAction(QWebEnginePage::Forward); break; case ContextMenuItem::Reload: - action = thisRef->action(QWebEnginePage::Reload); + action = m_view->pageAction(QWebEnginePage::Reload); break; case ContextMenuItem::Cut: - action = thisRef->action(QWebEnginePage::Cut); + action = m_view->pageAction(QWebEnginePage::Cut); break; case ContextMenuItem::Copy: - action = thisRef->action(QWebEnginePage::Copy); + action = m_view->pageAction(QWebEnginePage::Copy); break; case ContextMenuItem::Paste: - action = thisRef->action(QWebEnginePage::Paste); + action = m_view->pageAction(QWebEnginePage::Paste); break; case ContextMenuItem::Undo: - action = thisRef->action(QWebEnginePage::Undo); + action = m_view->pageAction(QWebEnginePage::Undo); break; case ContextMenuItem::Redo: - action = thisRef->action(QWebEnginePage::Redo); + action = m_view->pageAction(QWebEnginePage::Redo); break; case ContextMenuItem::SelectAll: - action = thisRef->action(QWebEnginePage::SelectAll); + action = m_view->pageAction(QWebEnginePage::SelectAll); break; case ContextMenuItem::PasteAndMatchStyle: - action = thisRef->action(QWebEnginePage::PasteAndMatchStyle); + action = m_view->pageAction(QWebEnginePage::PasteAndMatchStyle); break; case ContextMenuItem::OpenLinkInNewWindow: - action = thisRef->action(QWebEnginePage::OpenLinkInNewWindow); + action = m_view->pageAction(QWebEnginePage::OpenLinkInNewWindow); break; case ContextMenuItem::OpenLinkInNewTab: - action = thisRef->action(QWebEnginePage::OpenLinkInNewTab); + action = m_view->pageAction(QWebEnginePage::OpenLinkInNewTab); break; case ContextMenuItem::CopyLinkToClipboard: - action = thisRef->action(QWebEnginePage::CopyLinkToClipboard); + action = m_view->pageAction(QWebEnginePage::CopyLinkToClipboard); break; case ContextMenuItem::DownloadLinkToDisk: - action = thisRef->action(QWebEnginePage::DownloadLinkToDisk); + action = m_view->pageAction(QWebEnginePage::DownloadLinkToDisk); break; case ContextMenuItem::CopyImageToClipboard: - action = thisRef->action(QWebEnginePage::CopyImageToClipboard); + action = m_view->pageAction(QWebEnginePage::CopyImageToClipboard); break; case ContextMenuItem::CopyImageUrlToClipboard: - action = thisRef->action(QWebEnginePage::CopyImageUrlToClipboard); + action = m_view->pageAction(QWebEnginePage::CopyImageUrlToClipboard); break; case ContextMenuItem::DownloadImageToDisk: - action = thisRef->action(QWebEnginePage::DownloadImageToDisk); + action = m_view->pageAction(QWebEnginePage::DownloadImageToDisk); break; case ContextMenuItem::CopyMediaUrlToClipboard: - action = thisRef->action(QWebEnginePage::CopyMediaUrlToClipboard); + action = m_view->pageAction(QWebEnginePage::CopyMediaUrlToClipboard); break; case ContextMenuItem::ToggleMediaControls: - action = thisRef->action(QWebEnginePage::ToggleMediaControls); + action = m_view->pageAction(QWebEnginePage::ToggleMediaControls); break; case ContextMenuItem::ToggleMediaLoop: - action = thisRef->action(QWebEnginePage::ToggleMediaLoop); + action = m_view->pageAction(QWebEnginePage::ToggleMediaLoop); break; case ContextMenuItem::DownloadMediaToDisk: - action = thisRef->action(QWebEnginePage::DownloadMediaToDisk); + action = m_view->pageAction(QWebEnginePage::DownloadMediaToDisk); break; case ContextMenuItem::InspectElement: - action = thisRef->action(QWebEnginePage::InspectElement); + action = m_view->pageAction(QWebEnginePage::InspectElement); break; case ContextMenuItem::ExitFullScreen: - action = thisRef->action(QWebEnginePage::ExitFullScreen); + action = m_view->pageAction(QWebEnginePage::ExitFullScreen); break; case ContextMenuItem::SavePage: - action = thisRef->action(QWebEnginePage::SavePage); + action = m_view->pageAction(QWebEnginePage::SavePage); break; case ContextMenuItem::ViewSource: - action = thisRef->action(QWebEnginePage::ViewSource); + action = m_view->pageAction(QWebEnginePage::ViewSource); break; case ContextMenuItem::SpellingSuggestions: - for (int i = 0; i < m_contextData->spellCheckerSuggestions().count() && i < 4; i++) { + for (int i = 0; i < m_contextData->spellCheckerSuggestions().size() && i < 4; i++) { action = new QAction(m_menu); QString replacement = m_contextData->spellCheckerSuggestions().at(i); QObject::connect(action, &QAction::triggered, [thisRef, replacement] { @@ -737,6 +1676,49 @@ bool QContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem) } #endif // QT_CONFIG(action) +QtWebEngineCore::TouchHandleDrawableDelegate * +QWebEngineViewPrivate::createTouchHandleDelegate(const QMap<int, QImage> &images) +{ + Q_Q(QWebEngineView); + return new QtWebEngineWidgetUI::TouchHandleWidget(q, images); +} + +void QWebEngineViewPrivate::hideTouchSelectionMenu() +{ + if (m_touchSelectionMenu) + m_touchSelectionMenu->close(); +} + +void QWebEngineViewPrivate::showTouchSelectionMenu( + QtWebEngineCore::TouchSelectionMenuController *controller, const QRect &selectionBounds) +{ + Q_ASSERT(m_touchSelectionMenu == nullptr); + Q_Q(QWebEngineView); + + // Do not show outside of view + QSize parentSize = q->nativeParentWidget() ? q->nativeParentWidget()->size() : q->size(); + if (selectionBounds.x() < 0 || selectionBounds.x() > parentSize.width() + || selectionBounds.y() < 0 || selectionBounds.y() > parentSize.height()) + return; + + m_touchSelectionMenu = new QtWebEngineWidgetUI::TouchSelectionMenuWidget(q, controller); + + const int kSpacingBetweenButtons = 2; + const int kMenuButtonMinWidth = 80; + const int kMenuButtonMinHeight = 40; + + int buttonCount = controller->buttonCount(); + int width = (kSpacingBetweenButtons * (buttonCount + 1)) + (kMenuButtonMinWidth * buttonCount); + int height = kMenuButtonMinHeight + kSpacingBetweenButtons; + int x = (selectionBounds.x() + selectionBounds.x() + selectionBounds.width() - width) / 2; + int y = selectionBounds.y() - height - 2; + + QPoint pos = q->mapToGlobal(QPoint(x, y)); + + m_touchSelectionMenu->setGeometry(pos.x(), pos.y(), width, height); + m_touchSelectionMenu->show(); +} + QT_END_NAMESPACE #include "moc_qwebengineview.cpp" diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h index 06fbc5ddf..008aaa032 100644 --- a/src/webenginewidgets/api/qwebengineview.h +++ b/src/webenginewidgets/api/qwebengineview.h @@ -1,63 +1,34 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QWEBENGINEVIEW_H #define QWEBENGINEVIEW_H -#include <QtGui/qpainter.h> -#include <QtNetwork/qnetworkaccessmanager.h> +#include <QtGui/QPageLayout> +#include <QtGui/qpageranges.h> #include <QtWidgets/qwidget.h> #include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> -#include <QtWebEngineWidgets/qwebenginepage.h> -#include <QtWebEngineCore/qwebenginehttprequest.h> -#include <QtWebEngineCore/qwebenginecontextmenurequest.h> +#include <QtWebEngineCore/qwebenginepage.h> + +namespace QtWebEngineWidgetUI { +class AutofillPopupWidget; +} QT_BEGIN_NAMESPACE + class QContextMenuEvent; +class QPrinter; class QUrl; -class QWebEnginePage; +class QWebEngineContextMenuRequest; +class QWebEngineHistory; +class QWebEngineHttpRequest; class QWebEngineSettings; class QWebEngineViewAccessible; class QWebEngineViewPrivate; -class QWEBENGINEWIDGETS_EXPORT QWebEngineView : public QWidget { +class QWEBENGINEWIDGETS_EXPORT QWebEngineView : public QWidget +{ Q_OBJECT Q_PROPERTY(QString title READ title) Q_PROPERTY(QUrl url READ url WRITE setUrl) @@ -68,18 +39,23 @@ class QWEBENGINEWIDGETS_EXPORT QWebEngineView : public QWidget { Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor) public: - explicit QWebEngineView(QWidget* parent = Q_NULLPTR); + explicit QWebEngineView(QWidget *parent = nullptr); + explicit QWebEngineView(QWebEngineProfile *profile, QWidget *parent = nullptr); + explicit QWebEngineView(QWebEnginePage *page, QWidget *parent = nullptr); virtual ~QWebEngineView(); - QWebEnginePage* page() const; - void setPage(QWebEnginePage* page); + static QWebEngineView *forPage(const QWebEnginePage *page); + + QWebEnginePage *page() const; + void setPage(QWebEnginePage *page); void load(const QUrl &url); void load(const QWebEngineHttpRequest &request); - void setHtml(const QString& html, const QUrl& baseUrl = QUrl()); - void setContent(const QByteArray& data, const QString& mimeType = QString(), const QUrl& baseUrl = QUrl()); + void setHtml(const QString &html, const QUrl &baseUrl = QUrl()); + void setContent(const QByteArray &data, const QString &mimeType = QString(), + const QUrl &baseUrl = QUrl()); - QWebEngineHistory* history() const; + QWebEngineHistory *history() const; QString title() const; void setUrl(const QUrl &url); @@ -90,14 +66,16 @@ public: bool hasSelection() const; QString selectedText() const; -#ifndef QT_NO_ACTION - QAction* pageAction(QWebEnginePage::WebAction action) const; +#if QT_CONFIG(action) + QAction *pageAction(QWebEnginePage::WebAction action) const; #endif void triggerPageAction(QWebEnginePage::WebAction action, bool checked = false); qreal zoomFactor() const; void setZoomFactor(qreal factor); - void findText(const QString &subString, QWebEnginePage::FindFlags options = QWebEnginePage::FindFlags(), const QWebEngineCallback<bool> &resultCallback = QWebEngineCallback<bool>()); + void findText(const QString &subString, QWebEnginePage::FindFlags options = {}, + const std::function<void(const QWebEngineFindTextResult &)> &resultCallback = + std::function<void(const QWebEngineFindTextResult &)>()); QSize sizeHint() const override; QWebEngineSettings *settings() const; @@ -107,6 +85,16 @@ public: #endif QWebEngineContextMenuRequest *lastContextMenuRequest() const; + void printToPdf(const QString &filePath, + const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), + QPageLayout::Portrait, QMarginsF()), + const QPageRanges &ranges = {}); + void printToPdf(const std::function<void(const QByteArray &)> &resultCallback, + const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), + QPageLayout::Portrait, QMarginsF()), + const QPageRanges &ranges = {}); + void print(QPrinter *printer); + public Q_SLOTS: void stop(); void back(); @@ -117,20 +105,24 @@ Q_SIGNALS: void loadStarted(); void loadProgress(int progress); void loadFinished(bool); - void titleChanged(const QString& title); + void titleChanged(const QString &title); void selectionChanged(); - void urlChanged(const QUrl&); - void iconUrlChanged(const QUrl&); - void iconChanged(const QIcon&); + void urlChanged(const QUrl &); + void iconUrlChanged(const QUrl &); + void iconChanged(const QIcon &); void renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, - int exitCode); + int exitCode); + void pdfPrintingFinished(const QString &filePath, bool success); + void printRequested(); + void printRequestedByFrame(QWebEngineFrame frame); + void printFinished(bool success); protected: virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type); #if QT_CONFIG(contextmenu) - void contextMenuEvent(QContextMenuEvent*) override; + void contextMenuEvent(QContextMenuEvent *) override; #endif // QT_CONFIG(contextmenu) - bool event(QEvent*) override; + bool event(QEvent *) override; void showEvent(QShowEvent *) override; void hideEvent(QHideEvent *) override; void closeEvent(QCloseEvent *) override; @@ -146,8 +138,7 @@ private: Q_DECLARE_PRIVATE(QWebEngineView) QScopedPointer<QWebEngineViewPrivate> d_ptr; - friend class QWebEnginePage; - friend class QWebEnginePagePrivate; + friend class QtWebEngineWidgetUI::AutofillPopupWidget; #if QT_CONFIG(accessibility) friend class QWebEngineViewAccessible; #endif diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h index 29e39d081..389bc4a66 100644 --- a/src/webenginewidgets/api/qwebengineview_p.h +++ b/src/webenginewidgets/api/qwebengineview_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QWEBENGINEVIEW_P_H #define QWEBENGINEVIEW_P_H @@ -51,60 +15,99 @@ // We mean it. // -#include <QtWebEngineWidgets/qwebengineview.h> -#include "qwebenginecontextmenurequest.h" +#include <QtWebEngineCore/private/qwebenginepage_p.h> // PageView + #include "render_view_context_menu_qt.h" -#include <QtWidgets/qaccessiblewidget.h> + +#include <QtCore/qpointer.h> namespace QtWebEngineCore { -class RenderWidgetHostViewQtDelegateWidget; +class AutofillPopupController; +class QWebEngineContextMenuRequest; +class WebEngineQuickWidget; +class RenderWidgetHostViewQtDelegate; +class RenderWidgetHostViewQtDelegateClient; +class TouchSelectionMenuController; +} + +namespace QtWebEngineWidgetUI { +class AutofillPopupWidget; +class TouchHandleDrawableDelegate; +class TouchSelectionMenuWidget; } QT_BEGIN_NAMESPACE +class QMenu; +class QPrinter; class QWebEngineView; -class QWebEngineViewPrivate +class QWebEngineViewPrivate : public PageView { public: Q_DECLARE_PUBLIC(QWebEngineView) QWebEngineView *q_ptr; void pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage); - void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget, - QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget); - void contextMenuRequested(QWebEngineContextMenuRequest *request); - + void widgetChanged(QtWebEngineCore::WebEngineQuickWidget *oldWidget, + QtWebEngineCore::WebEngineQuickWidget *newWidget); + + void contextMenuRequested(QWebEngineContextMenuRequest *request) override; + QStringList chooseFiles(QWebEnginePage::FileSelectionMode mode, const QStringList &oldFiles, + const QStringList &acceptedMimeTypes) override; + void + showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController> controller) override; + bool showAuthorizationDialog(const QString &title, const QString &message) override; + void javaScriptAlert(const QUrl &url, const QString &msg) override; + bool javaScriptConfirm(const QUrl &url, const QString &msg) override; + bool javaScriptPrompt(const QUrl &url, const QString &msg, const QString &defaultValue, + QString *result) override; + void setToolTip(const QString &toolTipText) override; + QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate( + QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override; + QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegateForPopup( + QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override; + QWebEngineContextMenuRequest *lastContextMenuRequest() const override; + QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) override; + QObject *accessibilityParentObject() override; + void didPrintPage(QPrinter *&printer, QSharedPointer<QByteArray> result) override; + void didPrintPageToPdf(const QString &filePath, bool success) override; + void printRequested() override; + void printRequestedByFrame(QWebEngineFrame frame) override; + void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller, + const QRect &bounds, bool autoselectFirstSuggestion) override; + void hideAutofillPopup() override; + QtWebEngineCore::TouchHandleDrawableDelegate * + createTouchHandleDelegate(const QMap<int, QImage> &images) override; + + void showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *, + const QRect &) override; + void hideTouchSelectionMenu() override; QWebEngineViewPrivate(); - + virtual ~QWebEngineViewPrivate(); + static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view); + static void bindPageAndWidget(QWebEnginePagePrivate *pagePrivate, + QtWebEngineCore::WebEngineQuickWidget *widget); + QIcon webActionIcon(QWebEnginePage::WebAction action) const; + void unhandledKeyEvent(QKeyEvent *event) override; + void focusContainer() override; + bool passOnFocus(bool reverse) override; + bool isEnabled() const override; + bool isVisible() const override; + QRect viewportRect() const override; QWebEnginePage *page; + QMetaObject::Connection m_pageConnection; bool m_dragEntered; mutable bool m_ownsPage; QWebEngineContextMenuRequest *m_contextRequest; + QScopedPointer<QtWebEngineWidgetUI::AutofillPopupWidget> m_autofillPopupWidget; + QPointer<QtWebEngineWidgetUI::TouchSelectionMenuWidget> m_touchSelectionMenu; }; -#ifndef QT_NO_ACCESSIBILITY -class QWebEngineViewAccessible : public QAccessibleWidget -{ -public: - QWebEngineViewAccessible(QWebEngineView *o) : QAccessibleWidget(o) - {} - - bool isValid() const override; - QAccessibleInterface *focusChild() const override; - int childCount() const override; - QAccessibleInterface *child(int index) const override; - int indexOfChild(const QAccessibleInterface *child) const override; - -private: - QWebEngineView *view() const { return static_cast<QWebEngineView*>(object()); } -}; -#endif // QT_NO_ACCESSIBILITY - class QContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt { public: - QContextMenuBuilder(QWebEngineContextMenuRequest *reqeust, QWebEngineView *view, QMenu *menu); + QContextMenuBuilder(QWebEngineContextMenuRequest *request, QWebEngineView *view, QMenu *menu); private: virtual bool hasInspector() override; |