/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwebenginepage.h"
#include "qwebenginepage_p.h"

#include "authentication_dialog_controller.h"
#include "profile_adapter.h"
#include "certificate_error_controller.h"
#include "color_chooser_controller.h"
#include "favicon_manager.h"
#include "find_text_helper.h"
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printer_worker.h"
#endif
#include "qwebenginecertificateerror.h"
#include "qwebenginefindtextresult.h"
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
#include "qwebenginenotification.h"
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
#include "qwebenginequotarequest.h"
#include "qwebengineregisterprotocolhandlerrequest.h"
#include "qwebenginescriptcollection_p.h"
#include "qwebenginesettings.h"
#include "qwebengineview.h"
#include "qwebengineview_p.h"
#include "user_notification_controller.h"
#include "render_widget_host_view_qt_delegate_widget.h"
#include "web_contents_adapter.h"
#include "web_engine_settings.h"
#include "qwebenginescript.h"

#include <QAction>
#include <QApplication>
#include <QAuthenticator>
#include <QClipboard>
#if QT_CONFIG(colordialog)
#include <QColorDialog>
#endif
#include <QContextMenuEvent>
#if QT_CONFIG(filedialog)
#include <QFileDialog>
#endif
#include <QKeyEvent>
#include <QIcon>
#if QT_CONFIG(inputdialog)
#include <QInputDialog>
#endif
#include <QLayout>
#include <QLoggingCategory>
#if QT_CONFIG(menu)
#include <QMenu>
#endif
#if QT_CONFIG(messagebox)
#include <QMessageBox>
#endif
#include <QMimeData>
#if QT_CONFIG(webengine_printing_and_pdf)
#include <QPrinter>
#include <QThread>
#endif
#include <QStandardPaths>
#include <QStyle>
#include <QTimer>
#include <QUrl>

QT_BEGIN_NAMESPACE

using namespace QtWebEngineCore;

static const int MaxTooltipLength = 1024;

static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
    switch (disposition) {
    case WebContentsAdapterClient::NewForegroundTabDisposition:
        return QWebEnginePage::WebBrowserTab;
    case WebContentsAdapterClient::NewBackgroundTabDisposition:
        return QWebEnginePage::WebBrowserBackgroundTab;
    case WebContentsAdapterClient::NewPopupDisposition:
        return QWebEnginePage::WebDialog;
    case WebContentsAdapterClient::NewWindowDisposition:
        return QWebEnginePage::WebBrowserWindow;
    default:
        Q_UNREACHABLE();
    }
}

QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
    : adapter(QSharedPointer<WebContentsAdapter>::create())
    , history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this)))
    , profile(_profile ? _profile : QWebEngineProfile::defaultProfile())
    , settings(new QWebEngineSettings(profile->settings()))
    , view(0)
    , isLoading(false)
    , scriptCollection(new QWebEngineScriptCollectionPrivate(profileAdapter()->userResourceController(), adapter))
    , m_isBeingAdopted(false)
    , m_backgroundColor(Qt::white)
    , fullscreenMode(false)
    , webChannel(nullptr)
    , webChannelWorldId(QWebEngineScript::MainWorld)
    , defaultAudioMuted(false)
    , defaultZoomFactor(1.0)
#if QT_CONFIG(webengine_printing_and_pdf)
    , currentPrinter(nullptr)
#endif
{
    memset(actions, 0, sizeof(actions));

    qRegisterMetaType<QWebEngineQuotaRequest>();
    qRegisterMetaType<QWebEngineRegisterProtocolHandlerRequest>();
    qRegisterMetaType<QWebEngineFindTextResult>();

    // See setVisible().
    wasShownTimer.setSingleShot(true);
    QObject::connect(&wasShownTimer, &QTimer::timeout, [this](){
        ensureInitialized();
    });

    profile->d_ptr->addWebContentsAdapterClient(this);
}

QWebEnginePagePrivate::~QWebEnginePagePrivate()
{
    delete history;
    delete settings;
    profile->d_ptr->removeWebContentsAdapterClient(this);
}

RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
    // Set the QWebEngineView as the parent for a popup delegate, so that the new popup window
    // responds properly to clicks in case the QWebEngineView is inside a modal QDialog. Setting the
    // parent essentially notifies the OS that the popup window is part of the modal session, and
    // should allow interaction.
    // The new delegate will not be deleted by the parent view though, because we unset the parent
    // when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is
    // dismissed.
    return new RenderWidgetHostViewQtDelegateWidget(client, this->view);
}

void QWebEnginePagePrivate::initializationFinished()
{
    if (m_backgroundColor != Qt::white)
        adapter->setBackgroundColor(m_backgroundColor);
#if QT_CONFIG(webengine_webchannel)
    if (webChannel)
        adapter->setWebChannel(webChannel, webChannelWorldId);
#endif
    if (defaultAudioMuted != adapter->isAudioMuted())
        adapter->setAudioMuted(defaultAudioMuted);
    if (!qFuzzyCompare(adapter->currentZoomFactor(), defaultZoomFactor))
        adapter->setZoomFactor(defaultZoomFactor);
    if (view)
        adapter->setVisible(view->isVisible());

    scriptCollection.d->initializationFinished(adapter);

    m_isBeingAdopted = false;
}

void QWebEnginePagePrivate::titleChanged(const QString &title)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->titleChanged(title);
}

void QWebEnginePagePrivate::urlChanged()
{
    Q_Q(QWebEnginePage);
    QUrl qurl = adapter->activeUrl();
    if (url != qurl) {
        url = qurl;
        Q_EMIT q->urlChanged(qurl);
    }
}

void QWebEnginePagePrivate::iconChanged(const QUrl &url)
{
    Q_Q(QWebEnginePage);
    if (iconUrl == url)
        return;
    iconUrl = url;
    Q_EMIT q->iconUrlChanged(iconUrl);
    Q_EMIT q->iconChanged(adapter->faviconManager()->getIcon());
}

void QWebEnginePagePrivate::loadProgressChanged(int progress)
{
    Q_Q(QWebEnginePage);
    QTimer::singleShot(0, q, [q, progress] () { Q_EMIT q->loadProgress(progress); });
}

void QWebEnginePagePrivate::didUpdateTargetURL(const QUrl &hoveredUrl)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->linkHovered(hoveredUrl.toString());
}

void QWebEnginePagePrivate::selectionChanged()
{
    Q_Q(QWebEnginePage);
    QTimer::singleShot(0, q, [this, q]() {
        updateEditActions();
        Q_EMIT q->selectionChanged();
    });
}

void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->recentlyAudibleChanged(recentlyAudible);
}

void QWebEnginePagePrivate::renderProcessPidChanged(qint64 pid)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->renderProcessPidChanged(pid);
}

QRectF QWebEnginePagePrivate::viewportRect() const
{
    return view ? view->rect() : QRectF();
}

QColor QWebEnginePagePrivate::backgroundColor() const
{
    return m_backgroundColor;
}

void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage)
{
    Q_UNUSED(provisionalUrl);
    Q_Q(QWebEnginePage);

    if (isErrorPage)
        return;

    isLoading = true;
    m_certificateErrorControllers.clear();
    QTimer::singleShot(0, q, &QWebEnginePage::loadStarted);
}

void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription)
{
    Q_Q(QWebEnginePage);
    Q_UNUSED(url);
    Q_UNUSED(errorCode);
    Q_UNUSED(errorDescription);

    if (isErrorPage) {
        Q_ASSERT(settings->testAttribute(QWebEngineSettings::ErrorPageEnabled));
        QTimer::singleShot(0, q, [q](){
            emit q->loadFinished(false);
        });
        return;
    }

    isLoading = false;
    // Delay notifying failure until the error-page is done loading.
    // Error-pages are not loaded on failures due to abort.
    if (success || errorCode == -3 /* ERR_ABORTED*/ || !settings->testAttribute(QWebEngineSettings::ErrorPageEnabled)) {
        QTimer::singleShot(0, q, [q, success](){
            emit q->loadFinished(success);
        });
    }
}

void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool success)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->pdfPrintingFinished(filePath, success);
}

void QWebEnginePagePrivate::focusContainer()
{
    if (view) {
        view->activateWindow();
        view->setFocus();
    }
}

void QWebEnginePagePrivate::unhandledKeyEvent(QKeyEvent *event)
{
    if (view && view->parentWidget())
        QGuiApplication::sendEvent(view->parentWidget(), event);
}

QSharedPointer<WebContentsAdapter>
QWebEnginePagePrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents,
                                      WindowOpenDisposition disposition, bool userGesture,
                                      const QRect &initialGeometry, const QUrl &targetUrl)
{
    Q_Q(QWebEnginePage);
    Q_UNUSED(userGesture);
    Q_UNUSED(targetUrl);

    QWebEnginePage *newPage = q->createWindow(toWindowType(disposition));
    if (!newPage)
        return nullptr;

    if (!newWebContents->webContents())
        return newPage->d_func()->adapter; // Reuse existing adapter

    // Mark the new page as being in the process of being adopted, so that a second mouse move event
    // sent by newWebContents->initialize() gets filtered in RenderWidgetHostViewQt::forwardEvent.
    // The first mouse move event is being sent by q->createWindow(). This is necessary because
    // Chromium does not get a mouse move acknowledgment message between the two events, and
    // InputRouterImpl::ProcessMouseAck is not executed, thus all subsequent mouse move events
    // get coalesced together, and don't get processed at all.
    // The mouse move events are actually sent as a result of show() being called on
    // RenderWidgetHostViewQtDelegateWidget, both when creating the window and when initialize is
    // called.
    newPage->d_func()->m_isBeingAdopted = true;

    // Overwrite the new page's WebContents with ours.
    newPage->d_func()->adapter = newWebContents;
    newWebContents->setClient(newPage->d_func());

    if (!initialGeometry.isEmpty())
        emit newPage->geometryChangeRequested(initialGeometry);

    return newWebContents;
}

bool QWebEnginePagePrivate::isBeingAdopted()
{
    return m_isBeingAdopted;
}

void QWebEnginePagePrivate::close()
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->windowCloseRequested();
}

void QWebEnginePagePrivate::windowCloseRejected()
{
    // Do nothing for now.
}

void QWebEnginePagePrivate::didRunJavaScript(quint64 requestId, const QVariant& result)
{
    m_callbacks.invoke(requestId, result);
}

void QWebEnginePagePrivate::didFetchDocumentMarkup(quint64 requestId, const QString& result)
{
    m_callbacks.invoke(requestId, result);
}

void QWebEnginePagePrivate::didFetchDocumentInnerText(quint64 requestId, const QString& result)
{
    m_callbacks.invoke(requestId, result);
}

void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result)
{
#if QT_CONFIG(webengine_printing_and_pdf)
    Q_Q(QWebEnginePage);

    // If no currentPrinter is set that means that were printing to PDF only.
    if (!currentPrinter) {
        if (!result.data())
            return;
        m_callbacks.invoke(requestId, *(result.data()));
        return;
    }

    QThread *printerThread = new QThread;
    QObject::connect(printerThread, &QThread::finished, printerThread, &QThread::deleteLater);
    printerThread->start();

    PrinterWorker *printerWorker = new PrinterWorker(result, currentPrinter);
    QObject::connect(printerWorker, &PrinterWorker::resultReady, q, [requestId, this](bool success) {
        currentPrinter = nullptr;
        m_callbacks.invoke(requestId, success);
    });

    QObject::connect(printerWorker, &PrinterWorker::resultReady, printerThread, &QThread::quit);
    QObject::connect(printerThread, &QThread::finished, printerWorker, &PrinterWorker::deleteLater);

    printerWorker->moveToThread(printerThread);
    QMetaObject::invokeMethod(printerWorker, "print");

#else
    // we should never enter this branch, but just for safe-keeping...
    Q_UNUSED(result);
    m_callbacks.invoke(requestId, QByteArray());
#endif
}

bool QWebEnginePagePrivate::passOnFocus(bool reverse)
{
    if (view)
        return view->focusNextPrevChild(!reverse);
    return false;
}

void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller)
{
    Q_Q(QWebEnginePage);
    QAuthenticator networkAuth;
    networkAuth.setRealm(controller->realm());

    if (controller->isProxy())
        Q_EMIT q->proxyAuthenticationRequired(controller->url(), &networkAuth, controller->host());
    else
        Q_EMIT q->authenticationRequired(controller->url(), &networkAuth);

    // Authentication has been cancelled
    if (networkAuth.isNull()) {
        controller->reject();
        return;
    }

    controller->accept(networkAuth.user(), networkAuth.password());
}

void QWebEnginePagePrivate::releaseProfile()
{
    qWarning("Release of profile requested but WebEnginePage still not deleted. Expect troubles !");
    // this is not the way to go, but might avoid the crash if user code does not make any calls to page.
    delete q_ptr->d_ptr.take();
}

void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
{
#if QT_CONFIG(colordialog)
    QColorDialog *dialog = new QColorDialog(controller.data()->initialColor(), view);

    QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), controller.data(), SLOT(accept(QColor)));
    QColorDialog::connect(dialog, SIGNAL(rejected()), controller.data(), SLOT(reject()));

    // Delete when done
    QColorDialog::connect(dialog, SIGNAL(colorSelected(QColor)), dialog, SLOT(deleteLater()));
    QColorDialog::connect(dialog, SIGNAL(rejected()), dialog, SLOT(deleteLater()));

    dialog->open();
#else
    Q_UNUSED(controller);
#endif
}

void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
{
    Q_Q(QWebEnginePage);
    QWebEnginePage::Feature feature;
    if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) &&
        requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
        feature = QWebEnginePage::MediaAudioVideoCapture;
    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
        feature = QWebEnginePage::MediaAudioCapture;
    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
        feature = QWebEnginePage::MediaVideoCapture;
    else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) &&
             requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
        feature = QWebEnginePage::DesktopAudioVideoCapture;
    else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture))
        feature = QWebEnginePage::DesktopVideoCapture;
    Q_EMIT q->featurePermissionRequested(securityOrigin, feature);
}

static QWebEnginePage::Feature toFeature(QtWebEngineCore::ProfileAdapter::PermissionType type)
{
    switch (type) {
    case QtWebEngineCore::ProfileAdapter::NotificationPermission:
        return QWebEnginePage::Notifications;
    case QtWebEngineCore::ProfileAdapter::GeolocationPermission:
        return QWebEnginePage::Geolocation;
    default:
        break;
    }
    Q_UNREACHABLE();
    return QWebEnginePage::Feature(-1);
}

void QWebEnginePagePrivate::runFeaturePermissionRequest(QtWebEngineCore::ProfileAdapter::PermissionType permission, const QUrl &securityOrigin)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->featurePermissionRequested(securityOrigin, toFeature(permission));
}

void QWebEnginePagePrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock);
}

void QWebEnginePagePrivate::runQuotaRequest(QWebEngineQuotaRequest request)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->quotaRequested(request);
}

void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->registerProtocolHandlerRequested(request);
}

QObject *QWebEnginePagePrivate::accessibilityParentObject()
{
    return view;
}

void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
{
#ifdef QT_NO_ACTION
    Q_UNUSED(action)
#else
    QAction *a = actions[action];
    if (!a)
        return;

    bool enabled = true;

    switch (action) {
    case QWebEnginePage::Back:
        enabled = adapter->canGoToOffset(-1);
        break;
    case QWebEnginePage::Forward:
        enabled = adapter->canGoToOffset(1);
        break;
    case QWebEnginePage::Stop:
        enabled = isLoading;
        break;
    case QWebEnginePage::Reload:
    case QWebEnginePage::ReloadAndBypassCache:
        enabled = !isLoading;
        break;
    case QWebEnginePage::ViewSource:
        enabled = adapter->canViewSource();
        break;
    case QWebEnginePage::Cut:
    case QWebEnginePage::Copy:
    case QWebEnginePage::Unselect:
        enabled = adapter->hasFocusedFrame() && !adapter->selectedText().isEmpty();
        break;
    case QWebEnginePage::Paste:
    case QWebEnginePage::Undo:
    case QWebEnginePage::Redo:
    case QWebEnginePage::SelectAll:
    case QWebEnginePage::PasteAndMatchStyle:
        enabled = adapter->hasFocusedFrame();
        break;
    default:
        break;
    }

    a->setEnabled(enabled);
#endif // QT_NO_ACTION
}

void QWebEnginePagePrivate::updateNavigationActions()
{
    updateAction(QWebEnginePage::Back);
    updateAction(QWebEnginePage::Forward);
    updateAction(QWebEnginePage::Stop);
    updateAction(QWebEnginePage::Reload);
    updateAction(QWebEnginePage::ReloadAndBypassCache);
    updateAction(QWebEnginePage::ViewSource);
}

void QWebEnginePagePrivate::updateEditActions()
{
    updateAction(QWebEnginePage::Cut);
    updateAction(QWebEnginePage::Copy);
    updateAction(QWebEnginePage::Paste);
    updateAction(QWebEnginePage::Undo);
    updateAction(QWebEnginePage::Redo);
    updateAction(QWebEnginePage::SelectAll);
    updateAction(QWebEnginePage::PasteAndMatchStyle);
    updateAction(QWebEnginePage::Unselect);
}

#ifndef QT_NO_ACTION
void QWebEnginePagePrivate::_q_webActionTriggered(bool checked)
{
    Q_Q(QWebEnginePage);
    QAction *a = qobject_cast<QAction *>(q->sender());
    if (!a)
        return;
    QWebEnginePage::WebAction action = static_cast<QWebEnginePage::WebAction>(a->data().toInt());
    q->triggerAction(action, checked);
}
#endif // QT_NO_ACTION

void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
{
    QSharedPointer<WebContentsAdapter> newWebContents = WebContentsAdapter::createFromSerializedNavigationHistory(input, this);
    if (newWebContents) {
        adapter = std::move(newWebContents);
        adapter->setClient(this);
        adapter->loadDefault();
    }
}

void QWebEnginePagePrivate::updateScrollPosition(const QPointF &position)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->scrollPositionChanged(position);
}

void QWebEnginePagePrivate::updateContentsSize(const QSizeF &size)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->contentsSizeChanged(size);
}

void QWebEnginePagePrivate::setFullScreenMode(bool fullscreen)
{
    if (fullscreenMode != fullscreen) {
        fullscreenMode = fullscreen;
        adapter->changedFullScreen();
    }
}

ProfileAdapter* QWebEnginePagePrivate::profileAdapter()
{
    return profile->d_ptr->profileAdapter();
}

WebContentsAdapter *QWebEnginePagePrivate::webContentsAdapter()
{
    ensureInitialized();
    return adapter.data();
}

const QObject *QWebEnginePagePrivate::holdingQObject() const
{
    Q_Q(const QWebEnginePage);
    return q;
}

void QWebEnginePagePrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWidgetBase)
{
    Q_Q(QWebEnginePage);
    bindPageAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateWidget *>(newWidgetBase));
}

void QWebEnginePagePrivate::findTextFinished(const QWebEngineFindTextResult &result)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->findTextFinished(result);
}

void QWebEnginePagePrivate::ensureInitialized() const
{
    if (!adapter->isInitialized())
        adapter->loadDefault();
}

void QWebEnginePagePrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView *view)
{
    auto oldView = page ? page->d_func()->view : nullptr;
    auto oldPage = view ? view->d_func()->page : nullptr;

    bool ownNewPage = false;
    bool deleteOldPage = false;

    // Change pointers first.

    if (page && oldView != view) {
        if (oldView) {
            ownNewPage = oldView->d_func()->m_ownsPage;
            oldView->d_func()->page = nullptr;
            oldView->d_func()->m_ownsPage = false;
        }
        page->d_func()->view = view;
    }

    if (view && oldPage != page) {
        if (oldPage) {
            if (oldPage->d_func())
                oldPage->d_func()->view = nullptr;
            deleteOldPage = view->d_func()->m_ownsPage;
        }
        view->d_func()->m_ownsPage = ownNewPage;
        view->d_func()->page = page;
    }

    // Then notify.

    auto widget = page ? page->d_func()->widget : nullptr;
    auto oldWidget = (oldPage && oldPage->d_func()) ? oldPage->d_func()->widget : nullptr;

    if (page && oldView != view && oldView) {
        oldView->d_func()->pageChanged(page, nullptr);
        if (widget)
            oldView->d_func()->widgetChanged(widget, nullptr);
    }

    if (view && oldPage != page) {
        if (oldPage && oldPage->d_func())
            view->d_func()->pageChanged(oldPage, page);
        else
            view->d_func()->pageChanged(nullptr, page);
        if (oldWidget != widget)
            view->d_func()->widgetChanged(oldWidget, widget);
    }
    if (deleteOldPage)
        delete oldPage;
}

void QWebEnginePagePrivate::bindPageAndWidget(QWebEnginePage *page, RenderWidgetHostViewQtDelegateWidget *widget)
{
    auto oldPage = widget ? widget->m_page : nullptr;
    auto oldWidget = page ? page->d_func()->widget : nullptr;

    // Change pointers first.

    if (widget && oldPage != page) {
        if (oldPage && oldPage->d_func())
            oldPage->d_func()->widget = nullptr;
        widget->m_page = page;
    }

    if (page && oldWidget != widget) {
        if (oldWidget)
            oldWidget->m_page = nullptr;
        page->d_func()->widget = widget;
    }

    // Then notify.

    if (widget && oldPage != page && oldPage && oldPage->d_func()) {
        if (auto oldView = oldPage->d_func()->view)
            oldView->d_func()->widgetChanged(widget, nullptr);
    }

    if (page && oldWidget != widget) {
        if (auto view = page->d_func()->view)
            view->d_func()->widgetChanged(oldWidget, widget);
    }
}

QWebEnginePage::QWebEnginePage(QObject* parent)
    : QObject(parent)
    , d_ptr(new QWebEnginePagePrivate())
{
    Q_D(QWebEnginePage);
    d->q_ptr = this;
    d->adapter->setClient(d);
}

/*!
    \fn void QWebEnginePage::findTextFinished(const QWebEngineFindTextResult &result)
    \since 5.14

    This signal is emitted when a search string search on a page is completed. \a result is
    the result of the string search.

    \sa findText()
*/

/*!
    \fn void QWebEnginePage::printRequested()
    \since 5.12

    This signal is emitted when the JavaScript \c{window.print()} method is called.
    Typically, the signal handler can simply call printToPdf().

    \sa printToPdf()
*/

/*!
    \enum QWebEnginePage::RenderProcessTerminationStatus
    \since 5.6

    This enum describes the status with which the render process terminated:

    \value  NormalTerminationStatus
            The render process terminated normally.
    \value  AbnormalTerminationStatus
            The render process terminated with with a non-zero exit status.
    \value  CrashedTerminationStatus
            The render process crashed, for example because of a segmentation fault.
    \value  KilledTerminationStatus
            The render process was killed, for example by \c SIGKILL or task manager kill.
*/

/*!
    \fn QWebEnginePage::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode)
    \since 5.6

    This signal is emitted when the render process is terminated with a non-zero exit status.
    \a terminationStatus is the termination status of the process and \a exitCode is the status code
    with which the process terminated.
*/

/*!
    \fn QWebEnginePage::fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest)

    This signal is emitted when the web page issues the request to enter fullscreen mode for
    a web-element, usually a video element.

    The request object \a fullScreenRequest can be used to accept or reject the request.

    If the request is accepted the element requesting fullscreen will fill the viewport,
    but it is up to the application to make the view fullscreen or move the page to a view
    that is fullscreen.

    \sa QWebEngineSettings::FullScreenSupportEnabled
*/

/*!
    \fn QWebEnginePage::quotaRequested(QWebEngineQuotaRequest quotaRequest)
    \since 5.11

    This signal is emitted when the web page requests larger persistent storage
    than the application's current allocation in File System API. The default quota
    is 0 bytes.

    The request object \a quotaRequest can be used to accept or reject the request.
*/

/*!
    \fn QWebEnginePage::registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request)
    \since 5.11

    This signal is emitted when the web page tries to register a custom protocol
    using the \l registerProtocolHandler API.

    The request object \a request can be used to accept or reject the request:

    \snippet webenginewidgets/simplebrowser/webpage.cpp registerProtocolHandlerRequested
*/

/*!
    \fn void QWebEnginePage::pdfPrintingFinished(const QString &filePath, bool success)
    \since 5.9

    This signal is emitted when printing the web page into a PDF file has
    finished.
    \a filePath will contain the path the file was requested to be created
    at, and \a success will be \c true if the file was successfully created and
    \c false otherwise.

    \sa printToPdf()
*/

/*!
    \property QWebEnginePage::scrollPosition
    \since 5.7

    \brief The scroll position of the page contents.
*/

/*!
    \property QWebEnginePage::contentsSize
    \since 5.7

    \brief The size of the page contents.
*/

/*!
    \fn void QWebEnginePage::audioMutedChanged(bool muted)
    \since 5.7

    This signal is emitted when the page's \a muted state changes.
    \note Not to be confused with a specific HTML5 audio or video element being muted.
*/

/*!
    \fn void QWebEnginePage::recentlyAudibleChanged(bool recentlyAudible);
    \since 5.7

    This signal is emitted when the page's audible state, \a recentlyAudible, changes, because
    the audio is played or stopped.

    \note The signal is also emitted when calling the setAudioMuted() method.
    Also, if the audio is paused, this signal is emitted with an approximate \b{two-second
    delay}, from the moment the audio is paused.
*/

/*!
  \fn void QWebEnginePage::renderProcessPidChanged(qint64 pid);
  \since 5.15

  This signal is emitted when the underlying render process PID, \a renderProcessPid, changes.
*/

/*!
    \fn void QWebEnginePage::iconUrlChanged(const QUrl &url)

    This signal is emitted when the URL of the icon ("favicon") associated with the
    page is changed. The new URL is specified by \a url.

    \sa iconUrl(), icon(), iconChanged()
*/

/*!
    \fn void QWebEnginePage::iconChanged(const QIcon &icon)
    \since 5.7

    This signal is emitted when the icon ("favicon") associated with the
    page is changed. The new icon is specified by \a icon.

    \sa icon(), iconUrl(), iconUrlChanged()
*/

/*!
    Constructs an empty web engine page in the web engine profile \a profile with the parent
    \a parent.

    If the profile is not the default profile, the caller must ensure that the profile stays alive
    for as long as the page does.

    \since 5.5
*/
QWebEnginePage::QWebEnginePage(QWebEngineProfile *profile, QObject* parent)
    : QObject(parent)
    , d_ptr(new QWebEnginePagePrivate(profile))
{
    Q_D(QWebEnginePage);
    d->q_ptr = this;
    d->adapter->setClient(d);
}

QWebEnginePage::~QWebEnginePage()
{
    if (d_ptr) {
        // d_ptr might be exceptionally null if profile adapter got deleted first
        setDevToolsPage(nullptr);
        QWebEnginePagePrivate::bindPageAndView(this, nullptr);
        QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
    }
}

QWebEngineHistory *QWebEnginePage::history() const
{
    Q_D(const QWebEnginePage);
    return d->history;
}

QWebEngineSettings *QWebEnginePage::settings() const
{
    Q_D(const QWebEnginePage);
    return d->settings;
}

/*!
 * Returns a pointer to the web channel instance used by this page or a null pointer if none was set.
 * This channel automatically uses the internal web engine transport mechanism over Chromium IPC
 * that is exposed in the JavaScript context of this page as \c qt.webChannelTransport.
 *
 * \since 5.5
 * \sa setWebChannel()
 */
QWebChannel *QWebEnginePage::webChannel() const
{
#if QT_CONFIG(webengine_webchannel)
    Q_D(const QWebEnginePage);
    return d->webChannel;
#endif
    qWarning("WebEngine compiled without webchannel support");
    return nullptr;
}

/*!
 * \overload
 *
 * Sets the web channel instance to be used by this page to \a channel and installs
 * it in the main JavaScript world.
 *
 * With this method the web channel can be accessed by web page content. If the content
 * is not under your control and might be hostile, this could be a security issue and
 * you should consider installing it in a private JavaScript world.
 *
 * \since 5.5
 * \sa QWebEngineScript::MainWorld
 */

void QWebEnginePage::setWebChannel(QWebChannel *channel)
{
    setWebChannel(channel, QWebEngineScript::MainWorld);
}

/*!
 * Sets the web channel instance to be used by this page to \a channel and connects it to
 * web engine's transport using Chromium IPC messages. The transport is exposed in the JavaScript
 * world \a worldId as
 * \c qt.webChannelTransport, which should be used when using the \l{Qt WebChannel JavaScript API}.
 *
 * \note The page does not take ownership of the channel object.
 * \note Only one web channel can be installed per page, setting one even in another JavaScript
 *       world uninstalls any already installed web channel.
 *
 * \since 5.7
 * \sa QWebEngineScript::ScriptWorldId
 */
void QWebEnginePage::setWebChannel(QWebChannel *channel, uint worldId)
{
#if QT_CONFIG(webengine_webchannel)
    Q_D(QWebEnginePage);
    if (d->webChannel != channel || d->webChannelWorldId != worldId) {
        d->webChannel = channel;
        d->webChannelWorldId = worldId;
        d->adapter->setWebChannel(channel, worldId);
    }
#else
    Q_UNUSED(channel)
    Q_UNUSED(worldId)
    qWarning("WebEngine compiled without webchannel support");
#endif
}

/*!
    \property QWebEnginePage::backgroundColor
    \brief The page's background color behind the document's body.
    \since 5.6

    You can set the background color to Qt::transparent or to a translucent
    color to see through the document, or you can set it to match your
    web content in a hybrid application to prevent the white flashes that may appear
    during loading.

    The default value is white.
*/
QColor QWebEnginePage::backgroundColor() const
{
    Q_D(const QWebEnginePage);
    return d->m_backgroundColor;
}

void QWebEnginePage::setBackgroundColor(const QColor &color)
{
    Q_D(QWebEnginePage);
    if (d->m_backgroundColor == color)
        return;
    d->m_backgroundColor = color;
    d->adapter->setBackgroundColor(color);
}

/*!
 * Save the currently loaded web page to disk.
 *
 * The web page is saved to \a filePath in the specified \a{format}.
 *
 * This is a short cut for the following actions:
 * \list
 *   \li Trigger the Save web action.
 *   \li Accept the next download item and set the specified file path and save format.
 * \endlist
 *
 * This function issues an asynchronous download request for the web page and returns immediately.
 *
 * \sa QWebEngineDownloadItem::SavePageFormat
 * \since 5.8
 */
void QWebEnginePage::save(const QString &filePath,
                          QWebEngineDownloadItem::SavePageFormat format) const
{
    Q_D(const QWebEnginePage);
    d->ensureInitialized();
    d->adapter->save(filePath, format);
}

/*!
    \property QWebEnginePage::audioMuted
    \brief Whether the current page audio is muted.
    \since 5.7

    The default value is \c false.
    \sa recentlyAudible
*/
bool QWebEnginePage::isAudioMuted() const {
    Q_D(const QWebEnginePage);
    if (d->adapter->isInitialized())
        return d->adapter->isAudioMuted();
    return d->defaultAudioMuted;
}

void QWebEnginePage::setAudioMuted(bool muted) {
    Q_D(QWebEnginePage);
    bool wasAudioMuted = isAudioMuted();
    d->defaultAudioMuted = muted;
    d->adapter->setAudioMuted(muted);
    if (wasAudioMuted != isAudioMuted())
        Q_EMIT audioMutedChanged(muted);
}

/*!
    \property QWebEnginePage::recentlyAudible
    \brief The current page's \e {audible state}, that is, whether audio was recently played
    or not.
    \since 5.7

    The default value is \c false.
    \sa audioMuted
*/
bool QWebEnginePage::recentlyAudible() const
{
    Q_D(const QWebEnginePage);
    return d->adapter->isInitialized() && d->adapter->recentlyAudible();
}

/*!
  \property QWebEnginePage::renderProcessPid
  \brief The process ID (PID) of the render process assigned to the current
  page's main frame.
  \since 5.15

  If no render process is available yet, \c 0 is returned.
*/
qint64 QWebEnginePage::renderProcessPid() const
{
    Q_D(const QWebEnginePage);
    return d->adapter->renderProcessPid();
}

void QWebEnginePage::setView(QWidget *newViewBase)
{
    QWebEnginePagePrivate::bindPageAndView(this, qobject_cast<QWebEngineView *>(newViewBase));
}

QWidget *QWebEnginePage::view() const
{
    Q_D(const QWebEnginePage);
    return d->view;
}

/*!
    Returns the web engine profile the page belongs to.
    \since 5.5
*/
QWebEngineProfile *QWebEnginePage::profile() const
{
    Q_D(const QWebEnginePage);
    return d->profile;
}

bool QWebEnginePage::hasSelection() const
{
    return !selectedText().isEmpty();
}

QString QWebEnginePage::selectedText() const
{
    Q_D(const QWebEnginePage);
    return d->adapter->selectedText();
}

#ifndef QT_NO_ACTION
QAction *QWebEnginePage::action(WebAction action) const
{
    Q_D(const QWebEnginePage);
    if (action == QWebEnginePage::NoWebAction)
        return 0;
    if (d->actions[action])
        return d->actions[action];

    QString text;
    QIcon icon;
    QStyle *style = d->view ? d->view->style() : qApp->style();

    switch (action) {
    case Back:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back);
        icon = style->standardIcon(QStyle::SP_ArrowBack);
        break;
    case Forward:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward);
        icon = style->standardIcon(QStyle::SP_ArrowForward);
        break;
    case Stop:
        text = tr("Stop");
        icon = style->standardIcon(QStyle::SP_BrowserStop);
        break;
    case Reload:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload);
        icon = style->standardIcon(QStyle::SP_BrowserReload);
        break;
    case ReloadAndBypassCache:
        text = tr("Reload and Bypass Cache");
        icon = style->standardIcon(QStyle::SP_BrowserReload);
        break;
    case Cut:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut);
        break;
    case Copy:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy);
        break;
    case Paste:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste);
        break;
    case Undo:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo);
        break;
    case Redo:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo);
        break;
    case SelectAll:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll);
        break;
    case PasteAndMatchStyle:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle);
        break;
    case OpenLinkInThisWindow:
        text = tr("Open link in this window");
        break;
    case OpenLinkInNewWindow:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewWindow);
        break;
    case OpenLinkInNewTab:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewTab);
        break;
    case OpenLinkInNewBackgroundTab:
        text = tr("Open link in new background tab");
        break;
    case CopyLinkToClipboard:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyLinkToClipboard);
        break;
    case DownloadLinkToDisk:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadLinkToDisk);
        break;
    case CopyImageToClipboard:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageToClipboard);
        break;
    case CopyImageUrlToClipboard:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageUrlToClipboard);
        break;
    case DownloadImageToDisk:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadImageToDisk);
        break;
    case CopyMediaUrlToClipboard:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyMediaUrlToClipboard);
        break;
    case ToggleMediaControls:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaControls);
        break;
    case ToggleMediaLoop:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaLoop);
        break;
    case ToggleMediaPlayPause:
        text = tr("Toggle Play/Pause");
        break;
    case ToggleMediaMute:
        text = tr("Toggle Mute");
        break;
    case DownloadMediaToDisk:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk);
        break;
    case InspectElement:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::InspectElement);
        break;
    case ExitFullScreen:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen);
        break;
    case RequestClose:
        text = tr("Close Page");
        break;
    case Unselect:
        text = tr("Unselect");
        break;
    case SavePage:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage);
        break;
    case ViewSource:
        text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource);
        break;
    case ToggleBold:
        text = tr("&Bold");
        break;
    case ToggleItalic:
        text = tr("&Italic");
        break;
    case ToggleUnderline:
        text = tr("&Underline");
        break;
    case ToggleStrikethrough:
        text = tr("&Strikethrough");
        break;
    case AlignLeft:
        text = tr("Align &Left");
        break;
    case AlignCenter:
        text = tr("Align &Center");
        break;
    case AlignRight:
        text = tr("Align &Right");
        break;
    case AlignJustified:
        text = tr("Align &Justified");
        break;
    case Indent:
        text = tr("&Indent");
        break;
    case Outdent:
        text = tr("&Outdent");
        break;
    case InsertOrderedList:
        text = tr("Insert &Ordered List");
        break;
    case InsertUnorderedList:
        text = tr("Insert &Unordered List");
        break;
    case NoWebAction:
    case WebActionCount:
        Q_UNREACHABLE();
        break;
    }

    QAction *a = new QAction(const_cast<QWebEnginePage*>(this));
    a->setText(text);
    a->setData(action);
    a->setIcon(icon);

    connect(a, SIGNAL(triggered(bool)), this, SLOT(_q_webActionTriggered(bool)));

    d->actions[action] = a;
    d->updateAction(action);
    return a;
}
#endif // QT_NO_ACTION

void QWebEnginePage::triggerAction(WebAction action, bool)
{
    Q_D(QWebEnginePage);
    d->ensureInitialized();
    const QtWebEngineCore::WebEngineContextMenuData *menuData = d->contextData.d;
    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 (menuData && menuData->linkUrl().isValid())
            setUrl(menuData->linkUrl());
        break;
    case OpenLinkInNewWindow:
        if (menuData && menuData->linkUrl().isValid()) {
            QWebEnginePage *newPage = createWindow(WebBrowserWindow);
            if (newPage)
                newPage->setUrl(menuData->linkUrl());
        }
        break;
    case OpenLinkInNewTab:
        if (menuData && menuData->linkUrl().isValid()) {
            QWebEnginePage *newPage = createWindow(WebBrowserTab);
            if (newPage)
                newPage->setUrl(menuData->linkUrl());
        }
        break;
    case OpenLinkInNewBackgroundTab:
        if (menuData && menuData->linkUrl().isValid()) {
            QWebEnginePage *newPage = createWindow(WebBrowserBackgroundTab);
            if (newPage)
                newPage->setUrl(menuData->linkUrl());
        }
        break;
    case CopyLinkToClipboard:
        if (menuData && !menuData->unfilteredLinkUrl().isEmpty()) {
            QString urlString = menuData->unfilteredLinkUrl().toString(QUrl::FullyEncoded);
            QString linkText = menuData->linkText().toHtmlEscaped();
            QString title = menuData->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>() << menuData->unfilteredLinkUrl());
            qApp->clipboard()->setMimeData(data);
        }
        break;
    case DownloadLinkToDisk:
        if (menuData && menuData->linkUrl().isValid())
            d->adapter->download(menuData->linkUrl(), menuData->suggestedFileName(),
                                 menuData->referrerUrl(), menuData->referrerPolicy());

        break;
    case CopyImageToClipboard:
        if (menuData && menuData->hasImageContent() &&
                (menuData->mediaType() == WebEngineContextMenuData::MediaTypeImage ||
                 menuData->mediaType() == WebEngineContextMenuData::MediaTypeCanvas))
        {
            d->adapter->copyImageAt(menuData->position());
        }
        break;
    case CopyImageUrlToClipboard:
        if (menuData && menuData->mediaUrl().isValid() && menuData->mediaType() == WebEngineContextMenuData::MediaTypeImage) {
            QString urlString = menuData->mediaUrl().toString(QUrl::FullyEncoded);
            QString alt = menuData->altText();
            if (!alt.isEmpty())
                alt = QStringLiteral(" alt=\"%1\"").arg(alt.toHtmlEscaped());
            QString title = menuData->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>() << menuData->mediaUrl());
            qApp->clipboard()->setMimeData(data);
        }
        break;
    case DownloadImageToDisk:
    case DownloadMediaToDisk:
        if (menuData && menuData->mediaUrl().isValid())
            d->adapter->download(menuData->mediaUrl(), menuData->suggestedFileName(),
                                 menuData->referrerUrl(), menuData->referrerPolicy());
        break;
    case CopyMediaUrlToClipboard:
        if (menuData && menuData->mediaUrl().isValid() &&
                (menuData->mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
                 menuData->mediaType() == WebEngineContextMenuData::MediaTypeVideo))
        {
            QString urlString = menuData->mediaUrl().toString(QUrl::FullyEncoded);
            QString title = menuData->titleText();
            if (!title.isEmpty())
                title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped());
            QMimeData *data = new QMimeData();
            data->setText(urlString);
            if (menuData->mediaType() == WebEngineContextMenuData::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>() << menuData->mediaUrl());
            qApp->clipboard()->setMimeData(data);
        }
        break;
    case ToggleMediaControls:
        if (menuData && menuData->mediaUrl().isValid() && menuData->mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) {
            bool enable = !(menuData->mediaFlags() & WebEngineContextMenuData::MediaControls);
            d->adapter->executeMediaPlayerActionAt(menuData->position(), WebContentsAdapter::MediaPlayerControls, enable);
        }
        break;
    case ToggleMediaLoop:
        if (menuData && menuData->mediaUrl().isValid() &&
                (menuData->mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
                 menuData->mediaType() == WebEngineContextMenuData::MediaTypeVideo))
        {
            bool enable = !(menuData->mediaFlags() & WebEngineContextMenuData::MediaLoop);
            d->adapter->executeMediaPlayerActionAt(menuData->position(), WebContentsAdapter::MediaPlayerLoop, enable);
        }
        break;
    case ToggleMediaPlayPause:
        if (menuData && menuData->mediaUrl().isValid() &&
                (menuData->mediaType() == WebEngineContextMenuData::MediaTypeAudio ||
                 menuData->mediaType() == WebEngineContextMenuData::MediaTypeVideo))
        {
            bool enable = (menuData->mediaFlags() & WebEngineContextMenuData::MediaPaused);
            d->adapter->executeMediaPlayerActionAt(menuData->position(), WebContentsAdapter::MediaPlayerPlay, enable);
        }
        break;
    case ToggleMediaMute:
        if (menuData && menuData->mediaUrl().isValid() && menuData->mediaFlags() & WebEngineContextMenuData::MediaHasAudio) {
            // Make sure to negate the value, so that toggling actually works.
            bool enable = !(menuData->mediaFlags() & WebEngineContextMenuData::MediaMuted);
            d->adapter->executeMediaPlayerActionAt(menuData->position(), WebContentsAdapter::MediaPlayerMute, enable);
        }
        break;
    case InspectElement:
        if (menuData)
            d->adapter->inspectElementAt(menuData->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 QWebEngineContextMenuData::misspelledWord(),
 * and suggested replacements in QWebEngineContextMenuData::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(const WebEngineContextMenuData &data)
{
#if QT_CONFIG(action)
    if (!view)
        return;

    contextData.reset();
    switch (view->contextMenuPolicy()) {
    case Qt::DefaultContextMenu:
    {
        contextData = data;
        QContextMenuEvent event(QContextMenuEvent::Mouse, data.position(), view->mapToGlobal(data.position()));
        view->contextMenuEvent(&event);
        return;
    }
    case Qt::CustomContextMenu:
        contextData = data;
        Q_EMIT view->customContextMenuRequested(data.position());
        return;
    case Qt::ActionsContextMenu:
        if (view->actions().count()) {
            QContextMenuEvent event(QContextMenuEvent::Mouse, data.position(), view->mapToGlobal(data.position()));
            QMenu::exec(view->actions(), event.globalPos(), 0, view);
        }
        return;
    case Qt::PreventContextMenu:
    case Qt::NoContextMenu:
        return;
    }

    Q_UNREACHABLE();
#else
    Q_UNUSED(data);
#endif // QT_CONFIG(action)
}

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(q, origin, fullscreen);
    Q_EMIT q->fullScreenRequested(request);
}

bool QWebEnginePagePrivate::isFullScreenMode() const
{
    return fullscreenMode;
}

void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller)
{
    Q_Q(QWebEnginePage);
    bool accepted = false;
    QString promptResult;
    switch (controller->type()) {
    case AlertDialog:
        q->javaScriptAlert(controller->securityOrigin(), controller->message());
        accepted = true;
        break;
    case ConfirmDialog:
        accepted = q->javaScriptConfirm(controller->securityOrigin(), controller->message());
        break;
    case PromptDialog:
        accepted = q->javaScriptPrompt(controller->securityOrigin(), controller->message(), controller->defaultPrompt(), &promptResult);
        if (accepted)
            controller->textProvided(promptResult);
        break;
    case UnloadDialog:
        accepted = q->javaScriptConfirm(controller->securityOrigin(), QCoreApplication::translate("QWebEnginePage", "Are you sure you want to leave this page? Changes that you made may not be saved."));
        break;
    case InternalAuthorizationDialog:
#if QT_CONFIG(messagebox)
        accepted = (QMessageBox::question(view, controller->title(), controller->message(), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes);
#endif // QT_CONFIG(messagebox)
        break;
    }
    if (accepted)
        controller->accept();
    else
        controller->reject();
}

void QWebEnginePagePrivate::allowCertificateError(const QSharedPointer<CertificateErrorController> &controller)
{
    Q_Q(QWebEnginePage);
    bool accepted = false;

    QWebEngineCertificateError error(controller);
    accepted = q->certificateError(error);
    if (error.deferred() && !error.answered())
        m_certificateErrorControllers.append(controller);
    else if (!error.answered())
        controller->accept(error.isOverridable() && accepted);
}

void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &controller)
{
#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
    Q_Q(QWebEnginePage);
    QWebEngineClientCertificateSelection certSelection(controller);

    Q_EMIT q->selectClientCertificate(certSelection);
#else
    Q_UNUSED(controller);
#endif
}

#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
/*!
    \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
*/
#endif

void QWebEnginePagePrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID)
{
    Q_Q(QWebEnginePage);
    q->javaScriptConsoleMessage(static_cast<QWebEnginePage::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
}

void QWebEnginePagePrivate::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus,
                                                int exitCode)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->renderProcessTerminated(static_cast<QWebEnginePage::RenderProcessTerminationStatus>(
                                      terminationStatus), exitCode);
}

void QWebEnginePagePrivate::requestGeometryChange(const QRect &geometry, const QRect &frameGeometry)
{
    Q_UNUSED(geometry);
    Q_Q(QWebEnginePage);
    Q_EMIT q->geometryChangeRequested(frameGeometry);
}

void QWebEnginePagePrivate::startDragging(const content::DropData &dropData,
                                          Qt::DropActions allowedActions, const QPixmap &pixmap,
                                          const QPoint &offset)
{
#if !QT_CONFIG(draganddrop)
    Q_UNUSED(dropData);
    Q_UNUSED(allowedActions);
    Q_UNUSED(pixmap);
    Q_UNUSED(offset);
#else
    adapter->startDragging(view, dropData, allowedActions, pixmap, offset);
#endif // QT_CONFIG(draganddrop)
}

bool QWebEnginePagePrivate::supportsDragging() const
{
    return true;
}

bool QWebEnginePagePrivate::isEnabled() const
{
    const Q_Q(QWebEnginePage);
    const QWidget *view = q->view();
    if (view)
        return view->isEnabled();
    return true;
}

void QWebEnginePagePrivate::setToolTip(const QString &toolTipText)
{
    if (!view)
        return;

    // Hide tooltip if shown.
    if (toolTipText.isEmpty()) {
        if (!view->toolTip().isEmpty())
            view->setToolTip(QString());

        return;
    }

    // Update tooltip if text was changed.
    QString wrappedTip = QLatin1String("<p style=\"white-space:pre-wrap\">")
            % toolTipText.toHtmlEscaped().left(MaxTooltipLength)
            % QLatin1String("</p>");
    if (view->toolTip() != wrappedTip)
        view->setToolTip(wrappedTip);
}

void QWebEnginePagePrivate::printRequested()
{
    Q_Q(QWebEnginePage);
    QTimer::singleShot(0, q, [q](){
        Q_EMIT q->printRequested();
    });
}

void QWebEnginePagePrivate::lifecycleStateChanged(LifecycleState state)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->lifecycleStateChanged(static_cast<QWebEnginePage::LifecycleState>(state));
}

void QWebEnginePagePrivate::recommendedStateChanged(LifecycleState state)
{
    Q_Q(QWebEnginePage);
    QTimer::singleShot(0, q, [q, state]() {
        Q_EMIT q->recommendedStateChanged(static_cast<QWebEnginePage::LifecycleState>(state));
    });
}

void QWebEnginePagePrivate::visibleChanged(bool visible)
{
    Q_Q(QWebEnginePage);
    Q_EMIT q->visibleChanged(visible);
}

/*!
    \since 5.13

    Registers the request interceptor \a interceptor to intercept URL requests.

    The page does not take ownership of the pointer. This interceptor is called
    after any interceptors on the profile, and unlike profile interceptors, only
    URL requests from this page are intercepted.

    To unset the request interceptor, set a \c nullptr.

    \sa QWebEngineUrlRequestInfo, QWebEngineProfile::setUrlRequestInterceptor()
*/

void QWebEnginePage::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
    Q_D(QWebEnginePage);
    d->adapter->setRequestInterceptor(interceptor);
}

#if QT_CONFIG(menu)
QMenu *QWebEnginePage::createStandardContextMenu()
{
    Q_D(QWebEnginePage);
    if (!d->contextData.d)
        return nullptr;
    d->ensureInitialized();

    QMenu *menu = new QMenu(d->view);
    const WebEngineContextMenuData &contextMenuData = *d->contextData.d;

    QContextMenuBuilder contextMenuBuilder(contextMenuData, this, menu);

    contextMenuBuilder.initMenu();

    menu->setAttribute(Qt::WA_DeleteOnClose, true);

    return menu;
}
#endif // QT_CONFIG(menu)

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();
}

WebEngineSettings *QWebEnginePagePrivate::webEngineSettings() const
{
    return settings->d_func();
}

/*!
    \since 5.10
    Downloads the resource from the location given by \a url to a local file.

    If \a filename is given, it is used as the suggested file name.
    If it is relative, the file is saved in the standard download location with
    the given name.
    If it is a null or empty QString, the default file name is used.

    This will emit QWebEngineProfile::downloadRequested() after the download
    has started.
*/

void QWebEnginePage::download(const QUrl& url, const QString& filename)
{
    Q_D(QWebEnginePage);
    d->ensureInitialized();
    d->adapter->download(url, filename);
}

void QWebEnginePage::load(const QUrl& url)
{
    Q_D(QWebEnginePage);
    d->adapter->load(url);
}

/*!
    \since 5.9
    Issues the specified \a request and loads the response.

    \sa load(), setUrl(), url(), urlChanged(), QUrl::fromUserInput()
*/
void QWebEnginePage::load(const QWebEngineHttpRequest& request)
{
    Q_D(QWebEnginePage);
    d->adapter->load(request);
}

void QWebEnginePage::toHtml(const QWebEngineCallback<const QString &> &resultCallback) const
{
    Q_D(const QWebEnginePage);
    d->ensureInitialized();
    quint64 requestId = d->adapter->fetchDocumentMarkup();
    d->m_callbacks.registerCallback(requestId, resultCallback);
}

void QWebEnginePage::toPlainText(const QWebEngineCallback<const QString &> &resultCallback) const
{
    Q_D(const QWebEnginePage);
    d->ensureInitialized();
    quint64 requestId = d->adapter->fetchDocumentInnerText();
    d->m_callbacks.registerCallback(requestId, resultCallback);
}

void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl)
{
    setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
}

void QWebEnginePage::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
{
    Q_D(QWebEnginePage);
    d->adapter->setContent(data, mimeType, baseUrl);
}

QString QWebEnginePage::title() const
{
    Q_D(const QWebEnginePage);
    return d->adapter->pageTitle();
}

void QWebEnginePage::setUrl(const QUrl &url)
{
    Q_D(QWebEnginePage);
    if (d->url != url) {
        d->url = url;
        emit urlChanged(url);
    }
    load(url);
}

QUrl QWebEnginePage::url() const
{
    Q_D(const QWebEnginePage);
    return d->url;
}

QUrl QWebEnginePage::requestedUrl() const
{
    Q_D(const QWebEnginePage);
    return d->adapter->requestedUrl();
}

/*!
    \property QWebEnginePage::iconUrl
    \brief The URL of the icon associated with the page currently viewed.

    By default, this property contains an empty URL.

    \sa iconUrlChanged(), icon(), iconChanged()
*/
QUrl QWebEnginePage::iconUrl() const
{
    Q_D(const QWebEnginePage);
    return d->iconUrl;
}

/*!
    \property QWebEnginePage::icon
    \brief The icon associated with the page currently viewed.
    \since 5.7

    By default, this property contains a null icon. If the web page specifies more than one icon,
    the \c{icon} property encapsulates the available candidate icons in a single,
    scalable \c{QIcon}.

    \sa iconChanged(), iconUrl(), iconUrlChanged()
*/
QIcon QWebEnginePage::icon() const
{
    Q_D(const QWebEnginePage);

    if (d->iconUrl.isEmpty() || !d->adapter->isInitialized())
        return QIcon();

    return d->adapter->faviconManager()->getIcon();
}

qreal QWebEnginePage::zoomFactor() const
{
    Q_D(const QWebEnginePage);
    if (d->adapter->isInitialized())
        return d->adapter->currentZoomFactor();
    return d->defaultZoomFactor;
}

void QWebEnginePage::setZoomFactor(qreal factor)
{
    Q_D(QWebEnginePage);
    d->defaultZoomFactor = factor;
    if (d->adapter->isInitialized())
        d->adapter->setZoomFactor(factor);
}

void QWebEnginePage::runJavaScript(const QString &scriptSource)
{
    Q_D(QWebEnginePage);
    d->ensureInitialized();
    if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) {
        qWarning("runJavaScript: disabled in Discarded state");
        return;
    }
    d->adapter->runJavaScript(scriptSource, QWebEngineScript::MainWorld);
}

void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngineCallback<const QVariant &> &resultCallback)
{
    Q_D(QWebEnginePage);
    d->ensureInitialized();
    if (d->adapter->lifecycleState() == WebContentsAdapter::LifecycleState::Discarded) {
        qWarning("runJavaScript: disabled in Discarded state");
        d->m_callbacks.invokeEmpty(resultCallback);
        return;
    }
    quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, QWebEngineScript::MainWorld);
    d->m_callbacks.registerCallback(requestId, resultCallback);
}

void QWebEnginePage::runJavaScript(const QString &scriptSource, quint32 worldId)
{
    Q_D(QWebEnginePage);
    d->ensureInitialized();
    d->adapter->runJavaScript(scriptSource, worldId);
}

void QWebEnginePage::runJavaScript(const QString& scriptSource, quint32 worldId, const QWebEngineCallback<const QVariant &> &resultCallback)
{
    Q_D(QWebEnginePage);
    d->ensureInitialized();
    quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource, worldId);
    d->m_callbacks.registerCallback(requestId, resultCallback);
}

/*!
    Returns the collection of scripts that are injected into the page.

    In addition, a page might also execute scripts
    added through QWebEngineProfile::scripts().

    \sa QWebEngineScriptCollection, QWebEngineScript, {Script Injection}
*/

QWebEngineScriptCollection &QWebEnginePage::scripts()
{
    Q_D(QWebEnginePage);
    return d->scriptCollection;
}

QWebEnginePage *QWebEnginePage::createWindow(WebWindowType type)
{
    Q_D(QWebEnginePage);
    if (d->view) {
        QWebEngineView *newView = d->view->createWindow(type);
        if (newView)
            return newView->page();
    }
    return 0;
}

/*!
    \since 5.11
    Returns the page this page is inspecting, if any.

    Returns \c nullptr if this page is not a developer tools page.

    \sa setInspectedPage(), devToolsPage()
*/

QWebEnginePage *QWebEnginePage::inspectedPage() const
{
    Q_D(const QWebEnginePage);
    return d->inspectedPage;
}

/*!
    \since 5.11
    Navigates this page to an internal URL that is the developer
    tools of \a page.

    This is the same as calling setDevToolsPage() on \a page
    with \c this as argument.

    \sa inspectedPage(), setDevToolsPage()
*/

void QWebEnginePage::setInspectedPage(QWebEnginePage *page)
{
    Q_D(QWebEnginePage);
    if (d->inspectedPage == page)
        return;
    QWebEnginePage *oldPage = d->inspectedPage;
    d->inspectedPage = nullptr;
    if (oldPage)
        oldPage->setDevToolsPage(nullptr);
    d->inspectedPage = page;
    if (page)
        page->setDevToolsPage(this);
}

/*!
    \since 5.11
    Returns the page that is hosting the developer tools
    of this page, if any.

    Returns \c nullptr if no developer tools page is set.

    \sa setDevToolsPage(), inspectedPage()
*/

QWebEnginePage *QWebEnginePage::devToolsPage() const
{
    Q_D(const QWebEnginePage);
    return d->devToolsPage;
}

/*!
    \since 5.11
    Binds \a devToolsPage to be the developer tools of this page.
    Triggers \a devToolsPage to navigate to an internal URL
    with the developer tools.

    This is the same as calling setInspectedPage() on \a devToolsPage
    with \c this as argument.

    \sa devToolsPage(), setInspectedPage()
*/

void QWebEnginePage::setDevToolsPage(QWebEnginePage *devToolsPage)
{
    Q_D(QWebEnginePage);
    if (d->devToolsPage == devToolsPage)
        return;
    d->ensureInitialized();
    QWebEnginePage *oldDevTools = d->devToolsPage;
    d->devToolsPage = nullptr;
    if (oldDevTools)
        oldDevTools->setInspectedPage(nullptr);
    d->devToolsPage = devToolsPage;
    if (devToolsPage)
        devToolsPage->setInspectedPage(this);
    if (d->adapter) {
        if (devToolsPage)
            d->adapter->openDevToolsFrontend(devToolsPage->d_ptr->adapter);
        else
            d->adapter->closeDevToolsFrontend();
    }
}

ASSERT_ENUMS_MATCH(FilePickerController::Open, QWebEnginePage::FileSelectOpen)
ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, QWebEnginePage::FileSelectOpenMultiple)

QStringList QWebEnginePage::chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes)
{
#if QT_CONFIG(filedialog)
    const QStringList &filter = FilePickerController::nameFilters(acceptedMimeTypes);
    QStringList ret;
    QString str;
    switch (static_cast<FilePickerController::FileChooserMode>(mode)) {
    case FilePickerController::OpenMultiple:
        ret = QFileDialog::getOpenFileNames(view(), QString(), QString(), filter.join(QStringLiteral(";;")), nullptr, QFileDialog::HideNameFilterDetails);
        break;
    // Chromium extension, not exposed as part of the public API for now.
    case FilePickerController::UploadFolder:
        str = QFileDialog::getExistingDirectory(view(), tr("Select folder to upload"));
        if (!str.isNull())
            ret << str;
        break;
    case FilePickerController::Save:
        str = QFileDialog::getSaveFileName(view(), QString(), (QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + oldFiles.first()));
        if (!str.isNull())
            ret << str;
        break;
    case FilePickerController::Open:
        str = QFileDialog::getOpenFileName(view(), QString(), oldFiles.first(), filter.join(QStringLiteral(";;")), nullptr, QFileDialog::HideNameFilterDetails);
        if (!str.isNull())
            ret << str;
        break;
    }
    return ret;
#else
    Q_UNUSED(mode);
    Q_UNUSED(oldFiles);
    Q_UNUSED(acceptedMimeTypes);

    return QStringList();
#endif // QT_CONFIG(filedialog)
}

void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
{
    Q_UNUSED(securityOrigin);
#if QT_CONFIG(messagebox)
    QMessageBox::information(view(),
                             QStringLiteral("Javascript Alert - %1").arg(url().toString()),
                             msg.toHtmlEscaped());
#else
    Q_UNUSED(msg);
#endif // QT_CONFIG(messagebox)
}

bool QWebEnginePage::javaScriptConfirm(const QUrl &securityOrigin, const QString &msg)
{
    Q_UNUSED(securityOrigin);
#if QT_CONFIG(messagebox)
    return (QMessageBox::information(view(),
                                     QStringLiteral("Javascript Confirm - %1").arg(url().toString()),
                                     msg.toHtmlEscaped(),
                                     QMessageBox::Ok,
                                     QMessageBox::Cancel) == QMessageBox::Ok);
#else
    Q_UNUSED(msg);
    return false;
#endif // QT_CONFIG(messagebox)
}

bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString *result)
{
    Q_UNUSED(securityOrigin);
#if QT_CONFIG(inputdialog)
    bool ret = false;
    if (result)
        *result = QInputDialog::getText(view(),
                                        QStringLiteral("Javascript Prompt - %1").arg(url().toString()),
                                        msg.toHtmlEscaped(),
                                        QLineEdit::Normal,
                                        defaultValue.toHtmlEscaped(),
                                        &ret);
    return ret;
#else
    Q_UNUSED(msg);
    Q_UNUSED(defaultValue);
    Q_UNUSED(result);
    return false;
#endif // QT_CONFIG(inputdialog)
}

void QWebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID)
{
    static QLoggingCategory loggingCategory("js", QtWarningMsg);
    static QByteArray file = sourceID.toUtf8();
    QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName());

    switch (level) {
    case JavaScriptConsoleMessageLevel::InfoMessageLevel:
        if (loggingCategory.isInfoEnabled())
            logger.info().noquote() << message;
        break;
    case JavaScriptConsoleMessageLevel::WarningMessageLevel:
        if (loggingCategory.isWarningEnabled())
            logger.warning().noquote() << message;
        break;
    case JavaScriptConsoleMessageLevel::ErrorMessageLevel:
        if (loggingCategory.isCriticalEnabled())
            logger.critical().noquote() << message;
        break;
    }
}

bool QWebEnginePage::certificateError(const QWebEngineCertificateError &)
{
    return false;
}

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
}

/*!
    \since 5.7

    Returns additional data about the current context menu. It is only guaranteed to be valid during the call to the QWebEngineView::contextMenuEvent()
    handler of the associated QWebEngineView.

    \sa createStandardContextMenu()
*/
const QWebEngineContextMenuData &QWebEnginePage::contextMenuData() const
{
    Q_D(const QWebEnginePage);
    return d->contextData;
}

/*!
  \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);
}

#if QT_CONFIG(action)
QContextMenuBuilder::QContextMenuBuilder(const QtWebEngineCore::WebEngineContextMenuData &data,
                                         QWebEnginePage *page,
                                         QMenu *menu)
    : QtWebEngineCore::RenderViewContextMenuQt(data)
    , m_page(page)
    , m_menu(menu)
{
}

bool QContextMenuBuilder::hasInspector()
{
    return m_page->d_ptr->adapter->hasInspector();
}

bool QContextMenuBuilder::isFullScreenMode()
{
    return m_page->d_ptr->isFullScreenMode();
}

void QContextMenuBuilder::addMenuItem(ContextMenuItem menuItem)
{
    QPointer<QWebEnginePage> thisRef(m_page);
    QAction *action = 0;

    switch (menuItem) {
    case ContextMenuItem::Back:
        action = thisRef->action(QWebEnginePage::Back);
        break;
    case ContextMenuItem::Forward:
        action = thisRef->action(QWebEnginePage::Forward);
        break;
    case ContextMenuItem::Reload:
        action = thisRef->action(QWebEnginePage::Reload);
        break;
    case ContextMenuItem::Cut:
        action = thisRef->action(QWebEnginePage::Cut);
        break;
    case ContextMenuItem::Copy:
        action = thisRef->action(QWebEnginePage::Copy);
        break;
    case ContextMenuItem::Paste:
        action = thisRef->action(QWebEnginePage::Paste);
        break;
    case ContextMenuItem::Undo:
        action = thisRef->action(QWebEnginePage::Undo);
        break;
    case ContextMenuItem::Redo:
        action = thisRef->action(QWebEnginePage::Redo);
        break;
    case ContextMenuItem::SelectAll:
        action = thisRef->action(QWebEnginePage::SelectAll);
        break;
    case ContextMenuItem::PasteAndMatchStyle:
        action = thisRef->action(QWebEnginePage::PasteAndMatchStyle);
        break;
    case ContextMenuItem::OpenLinkInNewWindow:
        action = thisRef->action(QWebEnginePage::OpenLinkInNewWindow);
        break;
    case ContextMenuItem::OpenLinkInNewTab:
        action = thisRef->action(QWebEnginePage::OpenLinkInNewTab);
        break;
    case ContextMenuItem::CopyLinkToClipboard:
        action = thisRef->action(QWebEnginePage::CopyLinkToClipboard);
        break;
    case ContextMenuItem::DownloadLinkToDisk:
        action = thisRef->action(QWebEnginePage::DownloadLinkToDisk);
        break;
    case ContextMenuItem::CopyImageToClipboard:
        action = thisRef->action(QWebEnginePage::CopyImageToClipboard);
        break;
    case ContextMenuItem::CopyImageUrlToClipboard:
        action = thisRef->action(QWebEnginePage::CopyImageUrlToClipboard);
        break;
    case ContextMenuItem::DownloadImageToDisk:
        action = thisRef->action(QWebEnginePage::DownloadImageToDisk);
        break;
    case ContextMenuItem::CopyMediaUrlToClipboard:
        action = thisRef->action(QWebEnginePage::CopyMediaUrlToClipboard);
        break;
    case ContextMenuItem::ToggleMediaControls:
        action = thisRef->action(QWebEnginePage::ToggleMediaControls);
        break;
    case ContextMenuItem::ToggleMediaLoop:
        action = thisRef->action(QWebEnginePage::ToggleMediaLoop);
        break;
    case ContextMenuItem::DownloadMediaToDisk:
        action = thisRef->action(QWebEnginePage::DownloadMediaToDisk);
        break;
    case ContextMenuItem::InspectElement:
        action = thisRef->action(QWebEnginePage::InspectElement);
        break;
    case ContextMenuItem::ExitFullScreen:
        action = thisRef->action(QWebEnginePage::ExitFullScreen);
        break;
    case ContextMenuItem::SavePage:
        action = thisRef->action(QWebEnginePage::SavePage);
        break;
    case ContextMenuItem::ViewSource:
        action = thisRef->action(QWebEnginePage::ViewSource);
        break;
    case ContextMenuItem::SpellingSuggestions:
        for (int i=0; i < m_contextData.spellCheckerSuggestions().count() && i < 4; i++) {
            action = new QAction(m_menu);
            QString replacement = m_contextData.spellCheckerSuggestions().at(i);
            QObject::connect(action, &QAction::triggered, [thisRef, replacement] { if (thisRef) thisRef->replaceMisspelledWord(replacement); });
            action->setText(replacement);
            m_menu->addAction(action);
        }
        return;
    case ContextMenuItem::Separator:
        if (!m_menu->isEmpty())
            m_menu->addSeparator();
        return;
    }
    action->setEnabled(isMenuItemEnabled(menuItem));
    m_menu->addAction(action);
}

bool QContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem)
{
    switch (menuItem) {
    case ContextMenuItem::Back:
        return m_page->d_ptr->adapter->canGoBack();
    case ContextMenuItem::Forward:
        return m_page->d_ptr->adapter->canGoForward();
    case ContextMenuItem::Reload:
        return true;
    case ContextMenuItem::Cut:
        return m_contextData.editFlags() & QtWebEngineCore::WebEngineContextMenuData::CanCut;
    case ContextMenuItem::Copy:
        return m_contextData.editFlags() & QtWebEngineCore::WebEngineContextMenuData::CanCopy;
    case ContextMenuItem::Paste:
        return m_contextData.editFlags() & QtWebEngineCore::WebEngineContextMenuData::CanPaste;
    case ContextMenuItem::Undo:
        return m_contextData.editFlags() & QtWebEngineCore::WebEngineContextMenuData::CanUndo;
    case ContextMenuItem::Redo:
        return m_contextData.editFlags() & QtWebEngineCore::WebEngineContextMenuData::CanRedo;
    case ContextMenuItem::SelectAll:
        return m_contextData.editFlags() & QtWebEngineCore::WebEngineContextMenuData::CanSelectAll;
    case ContextMenuItem::PasteAndMatchStyle:
        return m_contextData.editFlags() & QtWebEngineCore::WebEngineContextMenuData::CanPaste;
    case ContextMenuItem::OpenLinkInNewWindow:
    case ContextMenuItem::OpenLinkInNewTab:
    case ContextMenuItem::CopyLinkToClipboard:
    case ContextMenuItem::DownloadLinkToDisk:
    case ContextMenuItem::CopyImageToClipboard:
    case ContextMenuItem::CopyImageUrlToClipboard:
    case ContextMenuItem::DownloadImageToDisk:
    case ContextMenuItem::CopyMediaUrlToClipboard:
    case ContextMenuItem::ToggleMediaControls:
    case ContextMenuItem::ToggleMediaLoop:
    case ContextMenuItem::DownloadMediaToDisk:
    case ContextMenuItem::InspectElement:
    case ContextMenuItem::ExitFullScreen:
    case ContextMenuItem::SavePage:
        return true;
    case ContextMenuItem::ViewSource:
        return m_page->d_ptr->adapter->canViewSource();
    case ContextMenuItem::SpellingSuggestions:
    case ContextMenuItem::Separator:
        return true;
    }
    Q_UNREACHABLE();
}
#endif // QT_CONFIG(action)

QT_END_NAMESPACE

#include "moc_qwebenginepage.cpp"
