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

QWebEnginePage::WebAction editorActionForKeyEvent(QKeyEvent* event)
{
    static struct {
        QKeySequence::StandardKey standardKey;
        QWebEnginePage::WebAction action;
    } editorActions[] = {
        { QKeySequence::Cut, QWebEnginePage::Cut },
        { QKeySequence::Copy, QWebEnginePage::Copy },
        { QKeySequence::Paste, QWebEnginePage::Paste },
        { QKeySequence::Undo, QWebEnginePage::Undo },
        { QKeySequence::Redo, QWebEnginePage::Redo },
        { QKeySequence::SelectAll, QWebEnginePage::SelectAll },
        { QKeySequence::UnknownKey, QWebEnginePage::NoWebAction }
    };
    for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i)
        if (event == editorActions[i].standardKey)
            return editorActions[i].action;

    return QWebEnginePage::NoWebAction;
}

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)
    , requestInterceptor(nullptr)
#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()
{
    if (requestInterceptor)
        profile->d_ptr->profileAdapter()->removePageRequestInterceptor();
    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);
}

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

void 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;

    if (newPage->d_func() == this) {
        // If createWindow returns /this/ we must delay the adoption.
        Q_ASSERT(q == newPage);
        // WebContents might be null if we just opened a new page for navigation, in that case
        // avoid referencing newWebContents so that it is deleted and WebContentsDelegateQt::OpenURLFromTab
        // will fall back to navigating current page.
        if (newWebContents->webContents()) {
            QTimer::singleShot(0, q, [this, newPage, newWebContents, initialGeometry] () {
                adoptNewWindowImpl(newPage, newWebContents, initialGeometry);
            });
        }
    } else {
        adoptNewWindowImpl(newPage, newWebContents, initialGeometry);
    }
}

void QWebEnginePagePrivate::adoptNewWindowImpl(QWebEnginePage *newPage,
        const QSharedPointer<WebContentsAdapter> &newWebContents, const QRect &initialGeometry)
{
    // 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);
}

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

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

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

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

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::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);
    d->defaultAudioMuted = muted;
    if (d->adapter->isInitialized())
        d->adapter->setAudioMuted(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();
}

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, is run
    on the UI thread, making it thread-safer. Only URL requests from this page are
    intercepted.

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

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

void QWebEnginePage::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
    Q_D(QWebEnginePage);
    bool hadInterceptorChanged = bool(d->requestInterceptor) != bool(interceptor);
    d->requestInterceptor = interceptor;
    if (hadInterceptorChanged) {
        if (interceptor)
            d->profile->d_ptr->profileAdapter()->addPageRequestInterceptor();
        else
            d->profile->d_ptr->profileAdapter()->removePageRequestInterceptor();
    }
}

void QWebEnginePagePrivate::interceptRequest(QWebEngineUrlRequestInfo &info)
{
    if (requestInterceptor)
        requestInterceptor->interceptRequest(info);
}

#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)
        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 Geolocation:
            d->adapter->runGeolocationRequestCallback(securityOrigin, true);
            break;
        case MouseLock:
            d->adapter->grantMouseLockPermission(true);
            break;
        case Notifications:
            d->adapter->runUserNotificationRequestCallback(securityOrigin, true);
            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->runGeolocationRequestCallback(securityOrigin, false);
            break;
        case MouseLock:
            d->adapter->grantMouseLockPermission(false);
            break;
        case Notifications:
            d->adapter->runUserNotificationRequestCallback(securityOrigin, false);
            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(";;"), 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(";;"), 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);
#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, 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, QLineEdit::Normal, defaultValue, &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"
