summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2020-10-22 09:05:50 +0200
committerMichal Klocek <michal.klocek@qt.io>2020-11-24 17:20:32 +0100
commit97b1a29c1c6db3c93dd6653d75aebcbac487b974 (patch)
tree1334d1d27caa0a77466a012f3e26ea654d1d7459 /src/core
parentb084326319f9d818a288de911df2c123af3bcda9 (diff)
Move QWebEnginePage to core
[ChangeLog] QWebEnginePage is in QtWebEngineCore Task-number: QTBUG-74585 Change-Id: Id326c89c868e9e7d53488bbd12cb321e1a0b79b7 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/api/core_api.pro10
-rw-r--r--src/core/api/qwebenginepage.cpp2453
-rw-r--r--src/core/api/qwebenginepage.h404
-rw-r--r--src/core/api/qwebenginepage_p.h233
4 files changed, 3096 insertions, 4 deletions
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 95095a2f7..e68d4bd8b 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -4,7 +4,7 @@ DESTDIR = $$OUT_PWD/$$getConfigDir()
TEMPLATE = lib
CONFIG += staticlib
-QT += network core-private webenginecoreheaders-private quick
+QT += network core-private webenginecoreheaders-private quick printsupport qml #fixme
# Don't create .prl file for this intermediate library because
# their contents get used when linking against them, breaking
@@ -64,8 +64,9 @@ HEADERS = \
qwebengineprofile_p.h \
qwebengineclientcertificateselection.h \
qwebenginehistory.h \
- qwebenginehistory_p.h
-
+ qwebenginehistory_p.h \
+ qwebenginepage.h \
+ qwebenginepage_p.h
SOURCES = \
qtwebenginecoreglobal.cpp \
@@ -90,7 +91,8 @@ SOURCES = \
qwebenginescriptcollection.cpp \
qwebengineprofile.cpp \
qwebengineclientcertificateselection.cpp \
- qwebenginehistory.cpp
+ qwebenginehistory.cpp \
+ qwebenginepage.cpp
# Chromium headers included are not remotely clean
CONFIG -= warning_clean
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
new file mode 100644
index 000000000..5e029714d
--- /dev/null
+++ b/src/core/api/qwebenginepage.cpp
@@ -0,0 +1,2453 @@
+/****************************************************************************
+**
+** 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 "qwebenginedownloadrequest_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 "printing/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 "user_notification_controller.h"
+#include "render_widget_host_view_qt_delegate.h"
+#include "web_contents_adapter.h"
+#include "web_engine_settings.h"
+#include "qwebenginescript.h"
+#include "render_view_context_menu_qt.h"
+#include "render_widget_host_view_qt_delegate_client.h"
+#include <QAction>
+#include <QGuiApplication>
+#include <QAuthenticator>
+#include <QClipboard>
+#include <QKeyEvent>
+#include <QIcon>
+#include <QLoggingCategory>
+#include <QMimeData>
+#if QT_CONFIG(webengine_printing_and_pdf)
+#include <QPrinter>
+#include <QThread>
+#endif
+#include <QTimer>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QtWebEngineCore;
+
+static const int MaxTooltipLength = 1024;
+
+// add temporary dummy code to cover the case when page is loading and there is no view
+class DummyDelegate : public QObject, public QtWebEngineCore::RenderWidgetHostViewQtDelegate
+{
+public:
+ DummyDelegate(RenderWidgetHostViewQtDelegateClient *client) : m_delegateClient(client) {};
+ ~DummyDelegate() = default;
+ void initAsPopup(const QRect &) override { Q_UNREACHABLE(); }
+ QRectF viewGeometry() const override { return QRectF(m_pos, m_size); }
+ void setKeyboardFocus() override { }
+ bool hasKeyboardFocus() override { return false; }
+ void lockMouse() override { Q_UNREACHABLE(); }
+ void unlockMouse() override { Q_UNREACHABLE(); }
+ void show() override { m_delegateClient->notifyShown(); }
+ void hide() override { m_delegateClient->notifyHidden(); }
+ bool isVisible() const override { Q_UNREACHABLE(); }
+ QWindow *window() const override { return nullptr; }
+ void updateCursor(const QCursor &cursor) override
+ { /*setCursor(cursor);*/
+ }
+ void resize(int width, int height) override
+ {
+ m_size = QSize(width, height);
+ m_delegateClient->visualPropertiesChanged();
+ }
+ void move(const QPoint &) override { Q_UNREACHABLE(); }
+ void inputMethodStateChanged(bool, bool) override { }
+ void setInputMethodHints(Qt::InputMethodHints) override { }
+ void setClearColor(const QColor &) override { }
+ void adapterClientChanged(WebContentsAdapterClient *client) override { }
+ bool copySurface(const QRect &rect, const QSize &size, QImage &image)
+ {
+ Q_UNREACHABLE();
+ return false;
+ }
+ QRect windowGeometry() const override { return QRect(m_pos, m_size); }
+ bool forwardEvent(QEvent *ev) { return m_delegateClient->forwardEvent(ev); }
+
+private:
+ RenderWidgetHostViewQtDelegateClient *m_delegateClient;
+ QPoint m_pos;
+ QSize m_size;
+};
+
+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 view ? view->CreateRenderWidgetHostViewQtDelegate(client) : new DummyDelegate(client);
+}
+
+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->viewportRect() : 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->focusContainer();
+ }
+}
+
+void QWebEnginePagePrivate::unhandledKeyEvent(QKeyEvent *event)
+{
+ if (view) {
+ view->unhandledKeyEvent(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)
+{
+ return view ? view->passOnFocus(reverse) : 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 (view)
+ view->showColorDialog(controller);
+}
+
+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 ? view->accessibilityParentObject() : nullptr;
+}
+
+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::findTextFinished(const QWebEngineFindTextResult &result)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->findTextFinished(result);
+}
+
+void QWebEnginePagePrivate::ensureInitialized() const
+{
+ if (!adapter->isInitialized())
+ adapter->loadDefault();
+}
+
+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/webview.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);
+ emit _q_aboutToDelete();
+ }
+}
+
+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();
+}
+
+/*!
+ 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;
+ switch (action) {
+ case Back:
+ text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back);
+ break;
+ case Forward:
+ text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward);
+ break;
+ case Stop:
+ text = tr("Stop");
+ break;
+ case Reload:
+ text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload);
+ break;
+ case ReloadAndBypassCache:
+ text = tr("Reload and Bypass Cache");
+ 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);
+
+ 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());
+ QGuiApplication::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());
+ QGuiApplication::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());
+ QGuiApplication::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->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:
+ accepted = view ? view->showAuthorizationDialog(controller->title(), controller->message())
+ : false;
+ 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);
+}
+
+QObject *QWebEnginePagePrivate::dragSource() const
+{
+#if !QT_CONFIG(draganddrop)
+ return view;
+#else
+ return nullptr;
+#endif // QT_CONFIG(draganddrop)
+}
+
+bool QWebEnginePagePrivate::isEnabled() const
+{
+ if (view)
+ return view->isEnabled();
+ return true;
+}
+
+void QWebEnginePagePrivate::setToolTip(const QString &toolTipText)
+{
+ if (view)
+ view->setToolTip(toolTipText);
+}
+
+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);
+ return d->view ? d->view->createPageForWindow(type) : nullptr;
+}
+
+/*!
+ \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)
+
+// TODO: remove virtuals
+QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes)
+{
+ Q_D(const QWebEnginePage);
+ return d->view ? d->view->chooseFiles(mode, oldFiles, acceptedMimeTypes) : QStringList();
+}
+
+void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
+{
+ Q_UNUSED(securityOrigin);
+ Q_D(const QWebEnginePage);
+ if (d->view)
+ d->view->javaScriptAlert(url(), msg);
+}
+
+bool QWebEnginePage::javaScriptConfirm(const QUrl &securityOrigin, const QString &msg)
+{
+ Q_UNUSED(securityOrigin);
+ Q_D(const QWebEnginePage);
+ return d->view ? d->view->javaScriptConfirm(url(), msg) : false;
+}
+
+bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString *result)
+{
+ Q_UNUSED(securityOrigin);
+ Q_D(const QWebEnginePage);
+ return d->view ? d->view->javaScriptPrompt(url(), msg, defaultValue, result) : false;
+}
+
+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);
+}
+
+QWebEnginePage* QWebEnginePage::fromDownloadRequest(QWebEngineDownloadRequest *request) {
+ return static_cast<QWebEnginePagePrivate *>(request->d_ptr->m_adapterClient)->q_ptr;
+}
+
+QDataStream &operator<<(QDataStream &stream, const QWebEngineHistory &history)
+{
+ QtWebEngineCore::WebContentsAdapter *adapter =
+ history.d_func()->m_adapter->webContentsAdapter();
+ if (!adapter->isInitialized())
+ adapter->loadDefault();
+ adapter->serializeNavigationHistory(stream);
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, QWebEngineHistory &history)
+{
+ static_cast<QWebEnginePagePrivate *>(history.d_func()->m_adapter)
+ ->recreateFromSerializedHistory(stream);
+ return stream;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginepage.cpp"
diff --git a/src/core/api/qwebenginepage.h b/src/core/api/qwebenginepage.h
new file mode 100644
index 000000000..09b7b54df
--- /dev/null
+++ b/src/core/api/qwebenginepage.h
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** 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 <QtWebEngineCore/qtwebenginecoreglobal.h>
+#include <QtWebEngineCore/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 <QtGui/qaction.h>
+#include <QtNetwork/qnetworkaccessmanager.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 Q_WEBENGINECORE_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;
+
+ 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);
+
+ static QWebEnginePage* fromDownloadRequest(QWebEngineDownloadRequest * request);
+
+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);
+
+ // TODO: fixme / rewrite bindPageToView
+ void _q_aboutToDelete();
+
+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)
+
+Q_WEBENGINECORE_EXPORT QDataStream &operator<<(QDataStream &stream,
+ const QWebEngineHistory &history);
+Q_WEBENGINECORE_EXPORT QDataStream &operator>>(QDataStream &stream, QWebEngineHistory &history);
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINEPAGE_H
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
new file mode 100644
index 000000000..d2101e49f
--- /dev/null
+++ b/src/core/api/qwebenginepage_p.h
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** 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 RenderWidgetHostViewQtDelegateClient;
+class TouchHandleDrawableClient;
+class TouchSelectionMenuController;
+class WebContentsAdapter;
+}
+
+QT_BEGIN_NAMESPACE
+class QWebEngineFindTextResult;
+class QWebEngineHistory;
+class QWebEnginePage;
+class QWebEngineProfile;
+class QWebEngineSettings;
+class QWebEngineView;
+
+class PageView
+{
+public:
+ virtual void contextMenuRequested(QWebEngineContextMenuRequest *request) = 0;
+ virtual QStringList chooseFiles(QWebEnginePage::FileSelectionMode mode,
+ const QStringList &oldFiles,
+ const QStringList &acceptedMimeTypes) = 0;
+ virtual void
+ showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController> controller) = 0;
+ virtual bool showAuthorizationDialog(const QString &title, const QString &message) = 0;
+ virtual void javaScriptAlert(const QUrl &url, const QString &msg) = 0;
+ virtual bool javaScriptConfirm(const QUrl &url, const QString &msg) = 0;
+ virtual bool javaScriptPrompt(const QUrl &url, const QString &msg, const QString &defaultValue,
+ QString *result) = 0;
+ virtual void setToolTip(const QString &toolTipText) = 0;
+ virtual QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate(
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) = 0;
+ virtual QWebEngineContextMenuRequest *lastContextMenuRequest() const = 0;
+ virtual QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) = 0;
+ virtual bool isEnabled() const = 0;
+ virtual bool isVisible() const = 0;
+ virtual QRect viewportRect() const = 0;
+ virtual void focusContainer() = 0;
+ virtual void unhandledKeyEvent(QKeyEvent *event) = 0;
+ virtual bool passOnFocus(bool reverse) = 0;
+ virtual QObject *accessibilityParentObject() = 0;
+};
+
+class Q_WEBENGINECORE_PRIVATE_EXPORT 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;
+ QObject *dragSource() 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 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;
+
+ QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter;
+ QWebEngineHistory *history;
+ QWebEngineProfile *profile;
+ QWebEngineSettings *settings;
+ PageView *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