-
Kai Koehne authored
Change-Id: I54a9514451c04918faf55516881c9ca720d56dc5 Reviewed-by:
Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> Reviewed-by:
Leena Miettinen <riitta-leena.miettinen@theqtcompany.com>
b3cc469e
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwebenginepage.h"
#include "qwebenginepage_p.h"
#include "authentication_dialog_controller.h"
#include "browser_context_adapter.h"
#include "certificate_error_controller.h"
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
#include "qwebenginescriptcollection_p.h"
#include "qwebenginesettings.h"
#include "qwebengineview.h"
#include "qwebengineview_p.h"
#include "render_widget_host_view_qt_delegate_widget.h"
#include "web_contents_adapter.h"
#include "web_engine_settings.h"
#ifdef QT_UI_DELEGATES
#include "ui/messagebubblewidget_p.h"
#endif
#include <QAction>
#include <QApplication>
#include <QAuthenticator>
#include <QClipboard>
#include <QContextMenuEvent>
#include <QFileDialog>
#include <QKeyEvent>
#include <QIcon>
#include <QInputDialog>
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
#include <QLayout>
#include <QLoggingCategory>
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
#include <QStandardPaths>
#include <QStyle>
#include <QUrl>
QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
case WebContentsAdapterClient::NewForegroundTabDisposition:
case WebContentsAdapterClient::NewBackgroundTabDisposition:
return QWebEnginePage::WebBrowserTab;
case WebContentsAdapterClient::NewPopupDisposition:
return QWebEnginePage::WebDialog;
case WebContentsAdapterClient::NewWindowDisposition:
return QWebEnginePage::WebBrowserWindow;
default:
Q_UNREACHABLE();
}
}
QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
: adapter(new WebContentsAdapter)
, history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this)))
, profile(_profile ? _profile : QWebEngineProfile::defaultProfile())
, settings(new QWebEngineSettings(profile->settings()))
, view(0)
, isLoading(false)
, scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
, m_isBeingAdopted(false)
, m_backgroundColor(Qt::white)
, fullscreenMode(false)
, webChannel(nullptr)
{
memset(actions, 0, sizeof(actions));
}
QWebEnginePagePrivate::~QWebEnginePagePrivate()
{
delete history;
delete settings;
}
RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
return new RenderWidgetHostViewQtDelegateWidget(client);
}
void QWebEnginePagePrivate::titleChanged(const QString &title)
{
Q_Q(QWebEnginePage);
Q_EMIT q->titleChanged(title);
}
void QWebEnginePagePrivate::urlChanged(const QUrl &url)
{
Q_Q(QWebEnginePage);
explicitUrl = QUrl();
Q_EMIT q->urlChanged(url);
}
void QWebEnginePagePrivate::iconChanged(const QUrl &url)
{
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
Q_Q(QWebEnginePage);
Q_EMIT q->iconUrlChanged(url);
}
void QWebEnginePagePrivate::loadProgressChanged(int progress)
{
Q_Q(QWebEnginePage);
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);
Q_EMIT q->selectionChanged();
}
QRectF QWebEnginePagePrivate::viewportRect() const
{
return view ? view->rect() : QRectF();
}
qreal QWebEnginePagePrivate::dpiScale() const
{
return 1.0;
}
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;
Q_EMIT q->loadStarted();
updateNavigationActions();
}
void QWebEnginePagePrivate::loadCommitted()
{
updateNavigationActions();
}
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));
Q_ASSERT(success);
Q_EMIT q->loadFinished(false);
return;
}
isLoading = false;
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
if (success)
explicitUrl = QUrl();
// 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)) {
Q_EMIT q->loadFinished(success);
}
updateNavigationActions();
}
void QWebEnginePagePrivate::focusContainer()
{
if (view)
view->setFocus();
}
void QWebEnginePagePrivate::unhandledKeyEvent(QKeyEvent *event)
{
if (view && view->parentWidget())
QGuiApplication::sendEvent(view->parentWidget(), event);
}
void QWebEnginePagePrivate::adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &initialGeometry)
{
Q_Q(QWebEnginePage);
Q_UNUSED(userGesture);
QWebEnginePage *newPage = q->createWindow(toWindowType(disposition));
if (!newPage)
return;
// 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.
if (newPage->d_func() != this) {
newPage->d_func()->adapter = newWebContents;
newWebContents->initialize(newPage->d_func());
if (!initialGeometry.isEmpty())
emit newPage->geometryChangeRequested(initialGeometry);
}
// Page has finished the adoption process.
newPage->d_func()->m_isBeingAdopted = false;
}
bool QWebEnginePagePrivate::isBeingAdopted()
{
return m_isBeingAdopted;
}
void QWebEnginePagePrivate::close()
{
Q_Q(QWebEnginePage);
Q_EMIT q->windowCloseRequested();
}
void QWebEnginePagePrivate::windowCloseRejected()
{
// Do nothing for now.
}
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
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::didFindText(quint64 requestId, int matchCount)
{
m_callbacks.invoke(requestId, matchCount > 0);
}
void QWebEnginePagePrivate::passOnFocus(bool reverse)
{
if (view)
view->focusNextPrevChild(!reverse);
}
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::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags)
{
Q_Q(QWebEnginePage);
QWebEnginePage::Feature requestedFeature;
if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
requestedFeature = QWebEnginePage::MediaAudioVideoCapture;
else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture))
requestedFeature = QWebEnginePage::MediaAudioCapture;
else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture))
requestedFeature = QWebEnginePage::MediaVideoCapture;
else
return;
Q_EMIT q->featurePermissionRequested(securityOrigin, requestedFeature);
}
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);
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::MouseLock);
}
#ifndef QT_NO_ACCESSIBILITY
QObject *QWebEnginePagePrivate::accessibilityParentObject()
{
return view;
}
#endif // QT_NO_ACCESSIBILITY
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->canGoBack();
break;
case QWebEnginePage::Forward:
enabled = adapter->canGoForward();
break;
case QWebEnginePage::Stop:
enabled = isLoading;
break;
case QWebEnginePage::Reload:
case QWebEnginePage::ReloadAndBypassCache:
enabled = !isLoading;
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);
}
#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)
{
QExplicitlySharedDataPointer<WebContentsAdapter> newWebContents = WebContentsAdapter::createFromSerializedNavigationHistory(input, this);
if (newWebContents) {
// Keep the old adapter referenced so the user-scripts are not
// unregistered immediately.
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
QExplicitlySharedDataPointer<WebContentsAdapter> oldWebContents = adapter;
adapter = newWebContents.data();
adapter->initialize(this);
if (webChannel)
adapter->setWebChannel(webChannel);
scriptCollection.d->rebindToContents(adapter.data());
}
}
void QWebEnginePagePrivate::setFullScreenMode(bool fullscreen)
{
if (fullscreenMode != fullscreen) {
fullscreenMode = fullscreen;
adapter->changedFullScreen();
}
}
BrowserContextAdapter *QWebEnginePagePrivate::browserContextAdapter()
{
return profile->d_ptr->browserContext();
}
QWebEnginePage::QWebEnginePage(QObject* parent)
: QObject(parent)
, d_ptr(new QWebEnginePagePrivate())
{
Q_D(QWebEnginePage);
d->q_ptr = this;
d->adapter->initialize(d);
}
/*!
\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 request)
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 request 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
*/
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
/*!
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->initialize(d);
}
QWebEnginePage::~QWebEnginePage()
{
Q_D(QWebEnginePage);
QWebEngineViewPrivate::bind(d->view, 0);
}
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 QWebChannel
*/
QWebChannel *QWebEnginePage::webChannel() const
{
Q_D(const QWebEnginePage);
return d->webChannel;
}
/*!
* 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
* context of this page 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.
*
* \since 5.5
*/
void QWebEnginePage::setWebChannel(QWebChannel *channel)
{
Q_D(QWebEnginePage);
if (d->webChannel != channel) {
d->webChannel = channel;
d->adapter->setWebChannel(channel);
}
}
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
/*!
\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->backgroundColorChanged();
}
void QWebEnginePage::setView(QWidget *view)
{
QWebEngineViewPrivate::bind(qobject_cast<QWebEngineView*>(view), this);
}
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;
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
QIcon icon;
QStyle *style = d->view ? d->view->style() : qApp->style();
switch (action) {
case Back:
text = tr("Back");
icon = style->standardIcon(QStyle::SP_ArrowBack);
break;
case Forward:
text = tr("Forward");
icon = style->standardIcon(QStyle::SP_ArrowForward);
break;
case Stop:
text = tr("Stop");
icon = style->standardIcon(QStyle::SP_BrowserStop);
break;
case Reload:
text = tr("Reload");
icon = style->standardIcon(QStyle::SP_BrowserReload);
break;
case Cut:
text = tr("Cut");
break;
case Copy:
text = tr("Copy");
break;
case Paste:
text = tr("Paste");
break;
case Undo:
text = tr("Undo");
break;
case Redo:
text = tr("Redo");
break;
case SelectAll:
text = tr("Select All");
break;
case PasteAndMatchStyle:
text = tr("Paste and Match Style");
break;
case OpenLinkInThisWindow:
text = tr("Open Link in This Window");
break;
case OpenLinkInNewWindow:
text = tr("Open Link in New Window");
break;
case OpenLinkInNewTab:
text = tr("Open Link in New Tab");
break;
case CopyLinkToClipboard:
text = tr("Copy Link URL");
break;
case DownloadLinkToDisk:
text = tr("Save Link");
break;
case CopyImageToClipboard:
text = tr("Copy Image");
break;
case CopyImageUrlToClipboard:
text = tr("Copy Image URL");
break;
case DownloadImageToDisk:
text = tr("Save Image");
break;
case CopyMediaUrlToClipboard:
text = tr("Copy Media URL");
break;
case ToggleMediaControls:
text = tr("Toggle Media Controls");
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
break;
case ToggleMediaLoop:
text = tr("Toggle Looping");
break;
case ToggleMediaPlayPause:
text = tr("Toggle Play/Pause");
break;
case ToggleMediaMute:
text = tr("Toggle Mute");
break;
case DownloadMediaToDisk:
text = tr("Save Media");
break;
case InspectElement:
text = tr("Inspect Element");
break;
case ExitFullScreen:
text = tr("Exit Full Screen Mode");
break;
case RequestClose:
text = tr("Close Page");
break;
default:
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);
switch (action) {
case Back:
d->adapter->navigateToOffset(-1);
break;
case Forward:
d->adapter->navigateToOffset(1);
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;
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
case Redo:
d->adapter->redo();
break;
case SelectAll:
d->adapter->selectAll();
break;
case PasteAndMatchStyle:
d->adapter->pasteAndMatchStyle();
break;
case OpenLinkInThisWindow:
if (d->m_menuData.linkUrl.isValid())
setUrl(d->m_menuData.linkUrl);
break;
case OpenLinkInNewWindow:
if (d->m_menuData.linkUrl.isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserWindow);
if (newPage)
newPage->setUrl(d->m_menuData.linkUrl);
}
break;
case OpenLinkInNewTab:
if (d->m_menuData.linkUrl.isValid()) {
QWebEnginePage *newPage = createWindow(WebBrowserTab);
if (newPage)
newPage->setUrl(d->m_menuData.linkUrl);
}
break;
case CopyLinkToClipboard:
if (d->m_menuData.linkUrl.isValid()) {
QString urlString = d->m_menuData.linkUrl.toString(QUrl::FullyEncoded);
QString title = d->m_menuData.linkText.toHtmlEscaped();
QMimeData *data = new QMimeData();
data->setText(urlString);
QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>");
data->setHtml(html);
data->setUrls(QList<QUrl>() << d->m_menuData.linkUrl);
qApp->clipboard()->setMimeData(data);
}
break;
case DownloadLinkToDisk:
if (d->m_menuData.linkUrl.isValid())
d->adapter->download(d->m_menuData.linkUrl, d->m_menuData.suggestedFileName);
break;
case CopyImageToClipboard:
if (d->m_menuData.hasImageContent &&
(d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeImage ||
d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas))
{
d->adapter->copyImageAt(d->m_menuData.pos);
}
break;
case CopyImageUrlToClipboard:
if (d->m_menuData.mediaUrl.isValid() && d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeImage) {
QString urlString = d->m_menuData.mediaUrl.toString(QUrl::FullyEncoded);
QString title = d->m_menuData.linkText;
if (!title.isEmpty())
title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped());
QMimeData *data = new QMimeData();
data->setText(urlString);
QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>");
data->setHtml(html);
data->setUrls(QList<QUrl>() << d->m_menuData.mediaUrl);
qApp->clipboard()->setMimeData(data);
}
break;
case DownloadImageToDisk:
case DownloadMediaToDisk:
if (d->m_menuData.mediaUrl.isValid())
d->adapter->download(d->m_menuData.mediaUrl, d->m_menuData.suggestedFileName);
break;
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
case CopyMediaUrlToClipboard:
if (d->m_menuData.mediaUrl.isValid() &&
(d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
{
QString urlString = d->m_menuData.mediaUrl.toString(QUrl::FullyEncoded);
QMimeData *data = new QMimeData();
data->setText(urlString);
if (d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio)
data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>"));
else
data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>"));
data->setUrls(QList<QUrl>() << d->m_menuData.mediaUrl);
qApp->clipboard()->setMimeData(data);
}
break;
case ToggleMediaControls:
if (d->m_menuData.mediaUrl.isValid() && d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) {
bool enable = !(d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaControls);
d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerControls, enable);
}
break;
case ToggleMediaLoop:
if (d->m_menuData.mediaUrl.isValid() &&
(d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
{
bool enable = !(d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaLoop);
d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerLoop, enable);
}
break;
case ToggleMediaPlayPause:
if (d->m_menuData.mediaUrl.isValid() &&
(d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio ||
d->m_menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo))
{
bool enable = (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaPaused);
d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerPlay, enable);
}
break;
case ToggleMediaMute:
if (d->m_menuData.mediaUrl.isValid() && d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) {
bool enable = !(d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaMuted);
d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerMute, enable);
}
break;
case InspectElement:
d->adapter->inspectElementAt(d->m_menuData.pos);
break;
case ExitFullScreen:
d->adapter->exitFullScreen();
break;
case RequestClose:
d->adapter->requestClose();
break;
default:
Q_UNREACHABLE();
}
}
void QWebEnginePage::findText(const QString &subString, FindFlags options, const QWebEngineCallback<bool> &resultCallback)
{
Q_D(QWebEnginePage);
if (subString.isEmpty()) {
d->adapter->stopFinding();
d->m_callbacks.invokeEmpty(resultCallback);
} else {
quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
d->m_callbacks.registerCallback(requestId, resultCallback);
}
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
}
/*!
* \reimp
*/
bool QWebEnginePage::event(QEvent *e)
{
return QObject::event(e);
}
void QWebEnginePagePrivate::wasShown()
{
adapter->wasShown();
}
void QWebEnginePagePrivate::wasHidden()
{
adapter->wasHidden();
}
bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData &data)
{
if (!view || !view->d_func()->m_pendingContextMenuEvent)
return false;
m_menuData = WebEngineContextMenuData();
QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos));
switch (view->contextMenuPolicy()) {
case Qt::PreventContextMenu:
return false;
case Qt::DefaultContextMenu:
m_menuData = data;
view->contextMenuEvent(&event);
break;
case Qt::CustomContextMenu:
Q_EMIT view->customContextMenuRequested(data.pos);
break;
case Qt::ActionsContextMenu:
if (view->actions().count()) {
QMenu::exec(view->actions(), event.globalPos(), 0, view);
break;
}
// fall through
default:
event.ignore();
return false;
break;
}
view->d_func()->m_pendingContextMenuEvent = false;
return true;
}
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);
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;
}
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
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 = (QMessageBox::information(view, QCoreApplication::translate("QWebEnginePage", "Are you sure you want to leave this page?"), controller->message(), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes);
break;
case InternalAuthorizationDialog:
accepted = (QMessageBox::question(view, controller->title(), controller->message(), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes);
break;
default:
Q_UNREACHABLE();
}
if (accepted)
controller->accept();
else
controller->reject();
}
void QWebEnginePagePrivate::allowCertificateError(const QSharedPointer<CertificateErrorController> &controller)
{
Q_Q(QWebEnginePage);
bool accepted = false;
QWebEngineCertificateError error(controller->error(), controller->url(), controller->overridable() && !controller->strictEnforcement(), controller->errorString());
accepted = q->certificateError(error);
if (error.isOverridable())
controller->accept(accepted);
}
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::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText)
{
#ifdef QT_UI_DELEGATES
QtWebEngineWidgetUI::MessageBubbleWidget::showBubble(view, anchor, mainText, subText);
#endif
}
void QWebEnginePagePrivate::hideValidationMessage()
{
#ifdef QT_UI_DELEGATES
QtWebEngineWidgetUI::MessageBubbleWidget::hideBubble();
#endif
}
void QWebEnginePagePrivate::moveValidationMessage(const QRect &anchor)
{
#ifdef QT_UI_DELEGATES
QtWebEngineWidgetUI::MessageBubbleWidget::moveBubble(view, anchor);
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
#endif
}
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)
{
Q_Q(QWebEnginePage);
Q_EMIT q->geometryChangeRequested(geometry);
}
QMenu *QWebEnginePage::createStandardContextMenu()
{
Q_D(QWebEnginePage);
QMenu *menu = new QMenu(d->view);
QAction *action = 0;
WebEngineContextMenuData contextMenuData(d->m_menuData);
if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
action = QWebEnginePage::action(OpenLinkInThisWindow);
action->setText(tr("Follow Link"));
menu->addAction(action);
menu->addAction(QWebEnginePage::action(DownloadLinkToDisk));
}
if (contextMenuData.selectedText.isEmpty()) {
action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::back);
action->setEnabled(d->adapter->canGoBack());
menu->addAction(action);
action = new QAction(QIcon::fromTheme(QStringLiteral("go-next")), tr("&Forward"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::forward);
action->setEnabled(d->adapter->canGoForward());
menu->addAction(action);
action = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), tr("&Reload"), menu);
connect(action, &QAction::triggered, d->view, &QWebEngineView::reload);
menu->addAction(action);
} else {
menu->addAction(QWebEnginePage::action(Copy));
}
if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) {
menu->addAction(QWebEnginePage::action(CopyLinkToClipboard));
}
if (contextMenuData.mediaUrl.isValid()) {
switch (contextMenuData.mediaType) {
case WebEngineContextMenuData::MediaTypeImage:
menu->addAction(QWebEnginePage::action(DownloadImageToDisk));
menu->addAction(QWebEnginePage::action(CopyImageUrlToClipboard));
menu->addAction(QWebEnginePage::action(CopyImageToClipboard));
break;
case WebEngineContextMenuData::MediaTypeCanvas:
Q_UNREACHABLE(); // mediaUrl is invalid for canvases
break;
case WebEngineContextMenuData::MediaTypeAudio:
case WebEngineContextMenuData::MediaTypeVideo:
menu->addAction(QWebEnginePage::action(DownloadMediaToDisk));
menu->addAction(QWebEnginePage::action(CopyMediaUrlToClipboard));
menu->addAction(QWebEnginePage::action(ToggleMediaPlayPause));
menu->addAction(QWebEnginePage::action(ToggleMediaLoop));
if (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio)
menu->addAction(QWebEnginePage::action(ToggleMediaMute));
if (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls)
menu->addAction(QWebEnginePage::action(ToggleMediaControls));
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
break;
default:
break;
}
} else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) {
menu->addAction(QWebEnginePage::action(CopyImageToClipboard));
}
if (d->adapter->hasInspector())
menu->addAction(QWebEnginePage::action(InspectElement));
if (d->isFullScreenMode())
menu->addAction(QWebEnginePage::action(ExitFullScreen));
return menu;
}
void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy)
{
Q_D(QWebEnginePage);
if (policy == PermissionUnknown)
return;
WebContentsAdapterClient::MediaRequestFlags flags = WebContentsAdapterClient::MediaNone;
switch (feature) {
case MediaAudioVideoCapture:
case MediaAudioCapture:
case MediaVideoCapture:
if (policy != PermissionUnknown) {
if (policy == PermissionDeniedByUser)
flags = WebContentsAdapterClient::MediaNone;
else {
if (feature == MediaAudioCapture)
flags = WebContentsAdapterClient::MediaAudioCapture;
else if (feature == MediaVideoCapture)
flags = WebContentsAdapterClient::MediaVideoCapture;
else
flags = WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaVideoCapture | WebContentsAdapterClient::MediaAudioCapture);
}
d->adapter->grantMediaAccessPermission(securityOrigin, flags);
}
d->adapter->grantMediaAccessPermission(securityOrigin, flags);
break;
case QWebEnginePage::Geolocation:
d->adapter->runGeolocationRequestCallback(securityOrigin, (policy == PermissionGrantedByUser) ? true : false);
break;
case MouseLock:
if (policy == PermissionGrantedByUser)
d->adapter->grantMouseLockPermission(true);
else
d->adapter->grantMouseLockPermission(false);
break;
default:
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(FilePickerController *controller)
{
Q_Q(QWebEnginePage);
QStringList selectedFileNames = q->chooseFiles(toPublic(controller->mode()), (QStringList() << controller->defaultFileName()), controller->acceptedMimeTypes());
if (!selectedFileNames.empty())
controller->accepted(selectedFileNames);
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
else
controller->rejected();
}
WebEngineSettings *QWebEnginePagePrivate::webEngineSettings() const
{
return settings->d_func();
}
void QWebEnginePage::load(const QUrl& url)
{
Q_D(QWebEnginePage);
d->adapter->load(url);
}
void QWebEnginePage::toHtml(const QWebEngineCallback<const QString &> &resultCallback) const
{
Q_D(const QWebEnginePage);
quint64 requestId = d->adapter->fetchDocumentMarkup();
d->m_callbacks.registerCallback(requestId, resultCallback);
}
void QWebEnginePage::toPlainText(const QWebEngineCallback<const QString &> &resultCallback) const
{
Q_D(const QWebEnginePage);
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);
d->explicitUrl = url;
load(url);
}
QUrl QWebEnginePage::url() const
{
Q_D(const QWebEnginePage);
return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
}
QUrl QWebEnginePage::requestedUrl() const
{
Q_D(const QWebEnginePage);
return d->adapter->requestedUrl();
}
QUrl QWebEnginePage::iconUrl() const
{
Q_D(const QWebEnginePage);
return d->adapter->iconUrl();
}
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
qreal QWebEnginePage::zoomFactor() const
{
Q_D(const QWebEnginePage);
return d->adapter->currentZoomFactor();
}
void QWebEnginePage::setZoomFactor(qreal factor)
{
Q_D(QWebEnginePage);
d->adapter->setZoomFactor(factor);
}
void QWebEnginePage::runJavaScript(const QString &scriptSource)
{
Q_D(QWebEnginePage);
d->adapter->runJavaScript(scriptSource);
}
void QWebEnginePage::runJavaScript(const QString& scriptSource, const QWebEngineCallback<const QVariant &> &resultCallback)
{
Q_D(QWebEnginePage);
quint64 requestId = d->adapter->runJavaScriptCallbackResult(scriptSource);
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
*/
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;
}
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)
{
// FIXME: Should we expose this in QWebPage's API ? Right now it is very open and can contain a mix and match of file extensions (which QFileDialog
// can work with) and mimetypes ranging from text/plain or images/* to application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Q_UNUSED(acceptedMimeTypes);
QStringList ret;
QString str;
switch (static_cast<FilePickerController::FileChooserMode>(mode)) {
case FilePickerController::OpenMultiple:
ret = QFileDialog::getOpenFileNames(view(), QString());
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")) + QLatin1Char('/');
if (!str.isNull())
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
ret << str;
break;
case FilePickerController::Save:
str = QFileDialog::getSaveFileName(view(), QString(), (QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + oldFiles.first()));
if (!str.isNull())
ret << str;
break;
default:
case FilePickerController::Open:
str = QFileDialog::getOpenFileName(view(), QString(), oldFiles.first());
if (!str.isNull())
ret << str;
break;
}
return ret;
}
void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
{
Q_UNUSED(securityOrigin);
QMessageBox::information(view(), QStringLiteral("Javascript Alert - %1").arg(url().toString()), msg);
}
bool QWebEnginePage::javaScriptConfirm(const QUrl &securityOrigin, const QString &msg)
{
Q_UNUSED(securityOrigin);
return (QMessageBox::information(view(), QStringLiteral("Javascript Confirm - %1").arg(url().toString()), msg, QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok);
}
bool QWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString *result)
{
Q_UNUSED(securityOrigin);
bool ret = false;
if (result)
*result = QInputDialog::getText(view(), QStringLiteral("Javascript Prompt - %1").arg(url().toString()), msg, QLineEdit::Normal, defaultValue, &ret);
return ret;
}
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);
1401140214031404140514061407
return true;
}
QT_END_NAMESPACE
#include "moc_qwebenginepage.cpp"