qquickwebengineview.cpp 61.52 KiB
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
** $QT_END_LICENSE$
****************************************************************************/
#include "qquickwebengineview_p.h"
#include "qquickwebengineview_p_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 "qquickwebenginehistory_p.h"
#include "qquickwebenginecertificateerror_p.h"
#include "qquickwebenginecontextmenurequest_p.h"
#include "qquickwebenginedialogrequests_p.h"
#include "qquickwebenginefaviconprovider_p_p.h"
#include "qquickwebengineloadrequest_p.h"
#include "qquickwebenginenavigationrequest_p.h"
#include "qquickwebenginenewviewrequest_p.h"
#include "qquickwebengineprofile_p.h"
#include "qquickwebenginesettings_p.h"
#include "qquickwebenginescript_p_p.h"
#ifdef ENABLE_QML_TESTSUPPORT_API
#include "qquickwebenginetestsupport_p.h"
#endif
#include "render_widget_host_view_qt_delegate_quick.h"
#include "render_widget_host_view_qt_delegate_quickwindow.h"
#include "renderer_host/user_resource_controller_host.h"
#include "ui_delegates_manager.h"
#include "web_contents_adapter.h"
#include "web_engine_error.h"
#include "web_engine_settings.h"
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
#include "web_engine_visited_links_manager.h" #include <QClipboard> #include <QGuiApplication> #include <QLoggingCategory> #include <QMarginsF> #include <QMimeData> #include <QPageLayout> #include <QPageSize> #include <QQmlComponent> #include <QQmlContext> #include <QQmlEngine> #include <QQmlProperty> #include <QQmlWebChannel> #include <QQuickWebEngineProfile> #include <QScreen> #include <QUrl> #include <QTimer> #include <private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> #ifndef QT_NO_ACCESSIBILITY #include <private/qquickaccessibleattached_p.h> #endif // QT_NO_ACCESSIBILITY QT_BEGIN_NAMESPACE using namespace QtWebEngineCore; QQuickWebEngineView::WebAction editorActionForKeyEvent(QKeyEvent* event) { static struct { QKeySequence::StandardKey standardKey; QQuickWebEngineView::WebAction action; } editorActions[] = { { QKeySequence::Cut, QQuickWebEngineView::Cut }, { QKeySequence::Copy, QQuickWebEngineView::Copy }, { QKeySequence::Paste, QQuickWebEngineView::Paste }, { QKeySequence::Undo, QQuickWebEngineView::Undo }, { QKeySequence::Redo, QQuickWebEngineView::Redo }, { QKeySequence::SelectAll, QQuickWebEngineView::SelectAll }, { QKeySequence::UnknownKey, QQuickWebEngineView::NoWebAction } }; for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i) if (event == editorActions[i].standardKey) return editorActions[i].action; return QQuickWebEngineView::NoWebAction; } #ifndef QT_NO_ACCESSIBILITY static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object) { if (QQuickWebEngineView *v = qobject_cast<QQuickWebEngineView*>(object)) return new QQuickWebEngineViewAccessible(v); return 0; } #endif // QT_NO_ACCESSIBILITY QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() : adapter(0) , m_history(new QQuickWebEngineHistory(this)) , m_profile(QQuickWebEngineProfile::defaultProfile()) , m_settings(new QQuickWebEngineSettings(m_profile->settings())) #ifdef ENABLE_QML_TESTSUPPORT_API , m_testSupport(0) #endif , contextMenuExtraItems(0) , faviconProvider(0) , loadProgress(0) , m_fullscreenMode(false) , isLoading(false)
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
, m_activeFocusOnPress(true) , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio()) , m_webChannel(0) , m_webChannelWorld(0) , m_dpiScale(1.0) , m_backgroundColor(Qt::white) , m_defaultZoomFactor(1.0) , m_ui2Enabled(false) { QString platform = qApp->platformName().toLower(); if (platform == QLatin1Literal("eglfs")) m_ui2Enabled = true; const QByteArray dialogSet = qgetenv("QTWEBENGINE_DIALOG_SET"); if (!dialogSet.isEmpty()) { if (dialogSet == QByteArrayLiteral("QtQuickControls2")) { m_ui2Enabled = true; } else if (dialogSet == QByteArrayLiteral("QtQuickControls1") && m_ui2Enabled) { m_ui2Enabled = false; qWarning("QTWEBENGINE_DIALOG_SET=QtQuickControls1 forces use of Qt Quick Controls 1 " "on an eglfs backend. This can crash your application!"); } else { qWarning("Ignoring QTWEBENGINE_DIALOG_SET environment variable set to %s. Accepted " "values are \"QtQuickControls1\" and \"QtQuickControls2\"", dialogSet.data()); } } #ifndef QT_NO_ACCESSIBILITY QAccessible::installFactory(&webAccessibleFactory); #endif // QT_NO_ACCESSIBILITY } QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate() { } UIDelegatesManager *QQuickWebEngineViewPrivate::ui() { Q_Q(QQuickWebEngineView); if (m_uIDelegatesManager.isNull()) m_uIDelegatesManager.reset(m_ui2Enabled ? new UI2DelegatesManager(q) : new UIDelegatesManager(q)); return m_uIDelegatesManager.data(); } RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client) { return new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ false); } RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client) { Q_Q(QQuickWebEngineView); const bool hasWindowCapability = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows); RenderWidgetHostViewQtDelegateQuick *quickDelegate = new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ true); if (hasWindowCapability) { RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow = new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate); quickDelegate->setParentItem(wrapperWindow->contentItem()); return wrapperWindow; } quickDelegate->setParentItem(q); return quickDelegate; } bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenuData &data) { Q_Q(QQuickWebEngineView); m_contextMenuData = data;
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
QQuickWebEngineContextMenuRequest *request = new QQuickWebEngineContextMenuRequest(data); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->contextMenuRequested(request); if (request->isAccepted()) return true; // Assign the WebEngineView as the parent of the menu, so mouse events are properly propagated // on OSX. QObject *menu = ui()->addMenu(q, QString(), data.position()); if (!menu) return false; // Populate our menu MenuItemHandler *item = 0; if (data.isEditable() && !data.spellCheckerSuggestions().isEmpty()) { const QPointer<QQuickWebEngineView> qRef(q); for (int i=0; i < data.spellCheckerSuggestions().count() && i < 4; i++) { item = new MenuItemHandler(menu); QString replacement = data.spellCheckerSuggestions().at(i); QObject::connect(item, &MenuItemHandler::triggered, [qRef, replacement] { qRef->replaceMisspelledWord(replacement); }); ui()->addMenuItem(item, replacement); } ui()->addMenuSeparator(menu); } if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::OpenLinkInThisWindow); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Follow Link")); } if (data.selectedText().isEmpty()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goBack); ui()->addMenuItem(item, QQuickWebEngineView::tr("Back"), QStringLiteral("go-previous"), q->canGoBack()); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goForward); ui()->addMenuItem(item, QQuickWebEngineView::tr("Forward"), QStringLiteral("go-next"), q->canGoForward()); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::reload); ui()->addMenuItem(item, QQuickWebEngineView::tr("Reload"), QStringLiteral("view-refresh")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ViewSource); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("View Page Source"), QStringLiteral("view-source"), adapter->canViewSource()); } else { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::Copy); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::Unselect); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Unselect")); } if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Link")); } if (data.mediaUrl().isValid()) { switch (data.mediaType()) { case WebEngineContextMenuData::MediaTypeImage: item = new MenuItemHandler(menu);
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image URL")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadImageToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Image")); break; case WebEngineContextMenuData::MediaTypeCanvas: Q_UNREACHABLE(); // mediaUrl is invalid for canvases break; case WebEngineContextMenuData::MediaTypeAudio: case WebEngineContextMenuData::MediaTypeVideo: item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyMediaUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Media URL")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadMediaToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Media")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaPlayPause); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Play/Pause")); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaLoop); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Looping")); if (data.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaMute); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Mute")); } if (data.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaControls); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Media Controls")); } break; default: break; } } else if (data.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); } if (adapter->hasInspector()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::InspectElement); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Inspect Element")); } if (isFullScreenMode()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ExitFullScreen); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Exit Full Screen Mode")); } // FIXME: expose the context menu data as an attached property to make this more useful if (contextMenuExtraItems) { ui()->addMenuSeparator(menu); if (QObject* menuExtras = contextMenuExtraItems->create(qmlContext(q))) { menuExtras->setParent(menu); QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(q)); if (entries.isValid()) entries.append(menuExtras); } } // Now fire the popup() method on the top level menu ui()->showMenu(menu); return true;
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
} void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) { Q_Q(QQuickWebEngineView); QQuickWebEngineNavigationRequest navigationRequest(url, static_cast<QQuickWebEngineView::NavigationType>(navigationType), isMainFrame); Q_EMIT q->navigationRequested(&navigationRequest); navigationRequestAction = navigationRequest.action(); } void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> dialog) { Q_Q(QQuickWebEngineView); QQuickWebEngineJavaScriptDialogRequest *request = new QQuickWebEngineJavaScriptDialogRequest(dialog); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->javaScriptDialogRequested(request); if (!request->isAccepted()) ui()->showDialog(dialog); } void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) { Q_Q(QQuickWebEngineView); QQuickWebEngineCertificateError *quickController = new QQuickWebEngineCertificateError(errorController); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(quickController); Q_EMIT q->certificateError(quickController); if (!quickController->deferred() && !quickController->answered()) quickController->rejectCertificate(); else m_certificateErrorControllers.append(errorController); } void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url) { Q_Q(QQuickWebEngineView); Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation); } void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller) { Q_Q(QQuickWebEngineView); QQuickWebEngineColorDialogRequest *request = new QQuickWebEngineColorDialogRequest(controller); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->colorDialogRequested(request); if (!request->isAccepted()) ui()->showColorDialog(controller); } void QQuickWebEngineViewPrivate::runFileChooser(QSharedPointer<FilePickerController> controller) { Q_Q(QQuickWebEngineView); QQuickWebEngineFileDialogRequest *request = new QQuickWebEngineFileDialogRequest(controller); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->fileDialogRequested(request); if (!request->isAccepted()) ui()->showFilePicker(controller); } void QQuickWebEngineViewPrivate::passOnFocus(bool reverse) { Q_Q(QQuickWebEngineView); // The child delegate currently has focus, find the next one from there and give it focus. QQuickItem *next = q->scopedFocusItem()->nextItemInFocusChain(!reverse); next->forceActiveFocus(reverse ? Qt::BacktabFocusReason : Qt::TabFocusReason);
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
} void QQuickWebEngineViewPrivate::titleChanged(const QString &title) { Q_Q(QQuickWebEngineView); Q_UNUSED(title); Q_EMIT q->titleChanged(); } void QQuickWebEngineViewPrivate::urlChanged(const QUrl &url) { Q_Q(QQuickWebEngineView); Q_UNUSED(url); explicitUrl = QUrl(); Q_EMIT q->urlChanged(); } void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url) { Q_Q(QQuickWebEngineView); if (iconUrl == QQuickWebEngineFaviconProvider::faviconProviderUrl(url)) return; if (!faviconProvider) { QQmlEngine *engine = qmlEngine(q); Q_ASSERT(engine); faviconProvider = static_cast<QQuickWebEngineFaviconProvider *>( engine->imageProvider(QQuickWebEngineFaviconProvider::identifier())); Q_ASSERT(faviconProvider); } iconUrl = faviconProvider->attach(q, url); m_history->reset(); Q_EMIT q->iconChanged(); } void QQuickWebEngineViewPrivate::loadProgressChanged(int progress) { Q_Q(QQuickWebEngineView); loadProgress = progress; Q_EMIT q->loadProgressChanged(); } void QQuickWebEngineViewPrivate::didUpdateTargetURL(const QUrl &hoveredUrl) { Q_Q(QQuickWebEngineView); Q_EMIT q->linkHovered(hoveredUrl); } void QQuickWebEngineViewPrivate::recentlyAudibleChanged(bool recentlyAudible) { Q_Q(QQuickWebEngineView); Q_EMIT q->recentlyAudibleChanged(recentlyAudible); } QRectF QQuickWebEngineViewPrivate::viewportRect() const { Q_Q(const QQuickWebEngineView); return QRectF(q->x(), q->y(), q->width(), q->height()); } qreal QQuickWebEngineViewPrivate::dpiScale() const { return m_dpiScale; } QColor QQuickWebEngineViewPrivate::backgroundColor() const { return m_backgroundColor;
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
} void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage) { Q_Q(QQuickWebEngineView); if (isErrorPage) { #ifdef ENABLE_QML_TESTSUPPORT_API if (m_testSupport) m_testSupport->errorPage()->loadStarted(provisionalUrl); #endif return; } isLoading = true; m_history->reset(); m_certificateErrorControllers.clear(); QQuickWebEngineLoadRequest loadRequest(provisionalUrl, QQuickWebEngineView::LoadStartedStatus); Q_EMIT q->loadingChanged(&loadRequest); } void QQuickWebEngineViewPrivate::loadCommitted() { m_history->reset(); } void QQuickWebEngineViewPrivate::loadVisuallyCommitted() { #ifdef ENABLE_QML_TESTSUPPORT_API if (m_testSupport) Q_EMIT m_testSupport->loadVisuallyCommitted(); #endif } Q_STATIC_ASSERT(static_cast<int>(WebEngineError::NoErrorDomain) == static_cast<int>(QQuickWebEngineView::NoErrorDomain)); Q_STATIC_ASSERT(static_cast<int>(WebEngineError::CertificateErrorDomain) == static_cast<int>(QQuickWebEngineView::CertificateErrorDomain)); Q_STATIC_ASSERT(static_cast<int>(WebEngineError::DnsErrorDomain) == static_cast<int>(QQuickWebEngineView::DnsErrorDomain)); void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) { Q_Q(QQuickWebEngineView); if (isErrorPage) { #ifdef ENABLE_QML_TESTSUPPORT_API if (m_testSupport) m_testSupport->errorPage()->loadFinished(success, url); #endif return; } isLoading = false; m_history->reset(); if (errorCode == WebEngineError::UserAbortedError) { QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadStoppedStatus); Q_EMIT q->loadingChanged(&loadRequest); return; } if (success) { explicitUrl = QUrl(); QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus); Q_EMIT q->loadingChanged(&loadRequest); return; } Q_ASSERT(errorCode); QQuickWebEngineLoadRequest loadRequest( url, QQuickWebEngineView::LoadFailedStatus, errorDescription, errorCode, static_cast<QQuickWebEngineView::ErrorDomain>(WebEngineError::toQtErrorDomain(errorCode)));
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
Q_EMIT q->loadingChanged(&loadRequest); return; } void QQuickWebEngineViewPrivate::focusContainer() { Q_Q(QQuickWebEngineView); q->forceActiveFocus(); } void QQuickWebEngineViewPrivate::unhandledKeyEvent(QKeyEvent *event) { Q_Q(QQuickWebEngineView); #ifdef Q_OS_OSX if (event->type() == QEvent::KeyPress) { QQuickWebEngineView::WebAction action = editorActionForKeyEvent(event); if (action != QQuickWebEngineView::NoWebAction) { // Try triggering a registered short-cut if (QGuiApplicationPrivate::instance()->shortcutMap.tryShortcut(event)) return; q->triggerWebAction(action); return; } } #endif if (q->parentItem()) q->window()->sendEvent(q->parentItem(), event); } void QQuickWebEngineViewPrivate::adoptNewWindow(QSharedPointer<WebContentsAdapter> newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &) { Q_Q(QQuickWebEngineView); QQuickWebEngineNewViewRequest request; // This increases the ref-count of newWebContents and will tell Chromium // to start loading it and possibly return it to its parent page window.open(). request.m_adapter = newWebContents; request.m_isUserInitiated = userGesture; switch (disposition) { case WebContentsAdapterClient::NewForegroundTabDisposition: request.m_destination = QQuickWebEngineView::NewViewInTab; break; case WebContentsAdapterClient::NewBackgroundTabDisposition: request.m_destination = QQuickWebEngineView::NewViewInBackgroundTab; break; case WebContentsAdapterClient::NewPopupDisposition: request.m_destination = QQuickWebEngineView::NewViewInDialog; break; case WebContentsAdapterClient::NewWindowDisposition: request.m_destination = QQuickWebEngineView::NewViewInWindow; break; default: Q_UNREACHABLE(); } Q_EMIT q->newViewRequested(&request); } bool QQuickWebEngineViewPrivate::isBeingAdopted() { return false; } void QQuickWebEngineViewPrivate::close() { Q_Q(QQuickWebEngineView); emit q->windowCloseRequested(); } void QQuickWebEngineViewPrivate::windowCloseRejected()
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
{ #ifdef ENABLE_QML_TESTSUPPORT_API if (m_testSupport) Q_EMIT m_testSupport->windowCloseRejected(); #endif } void QQuickWebEngineViewPrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen) { Q_Q(QQuickWebEngineView); QQuickWebEngineFullScreenRequest request(this, origin, fullscreen); Q_EMIT q->fullScreenRequested(request); } bool QQuickWebEngineViewPrivate::isFullScreenMode() const { return m_fullscreenMode; } void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) { Q_Q(QQuickWebEngineView); if (q->receivers(SIGNAL(javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) { Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID); return; } static QLoggingCategory loggingCategory("js", QtWarningMsg); const QByteArray file = sourceID.toUtf8(); QMessageLogger logger(file.constData(), lineNumber, nullptr, loggingCategory.categoryName()); switch (level) { case JavaScriptConsoleMessageLevel::Info: if (loggingCategory.isInfoEnabled()) logger.info().noquote() << message; break; case JavaScriptConsoleMessageLevel::Warning: if (loggingCategory.isWarningEnabled()) logger.warning().noquote() << message; break; case JavaScriptConsoleMessageLevel::Error: if (loggingCategory.isCriticalEnabled()) logger.critical().noquote() << message; break; } } void QQuickWebEngineViewPrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller) { Q_Q(QQuickWebEngineView); QQuickWebEngineAuthenticationDialogRequest *request = new QQuickWebEngineAuthenticationDialogRequest(controller); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->authenticationDialogRequested(request); if (!request->isAccepted()) ui()->showDialog(controller); } void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags) { Q_Q(QQuickWebEngineView); if (!requestFlags) return; QQuickWebEngineView::Feature feature; if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) feature = QQuickWebEngineView::MediaAudioVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)) feature = QQuickWebEngineView::MediaAudioCapture; else // WebContentsAdapterClient::MediaVideoCapture feature = QQuickWebEngineView::MediaVideoCapture;
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
Q_EMIT q->featurePermissionRequested(securityOrigin, feature); } void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin) { Q_UNUSED(securityOrigin); // TODO: Add mouse lock support adapter->grantMouseLockPermission(false); } #ifndef QT_NO_ACCESSIBILITY QObject *QQuickWebEngineViewPrivate::accessibilityParentObject() { Q_Q(QQuickWebEngineView); return q; } #endif // QT_NO_ACCESSIBILITY QSharedPointer<BrowserContextAdapter> QQuickWebEngineViewPrivate::browserContextAdapter() { return m_profile->d_ptr->browserContext(); } WebContentsAdapter *QQuickWebEngineViewPrivate::webContentsAdapter() { return adapter.data(); } WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const { return m_settings->d_ptr.data(); } const QObject *QQuickWebEngineViewPrivate::holdingQObject() const { Q_Q(const QQuickWebEngineView); return q; } void QQuickWebEngineViewPrivate::setDevicePixelRatio(qreal devicePixelRatio) { Q_Q(QQuickWebEngineView); this->devicePixelRatio = devicePixelRatio; QScreen *screen = q->window() ? q->window()->screen() : QGuiApplication::primaryScreen(); m_dpiScale = devicePixelRatio / screen->devicePixelRatio(); } #ifndef QT_NO_ACCESSIBILITY QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o) : QAccessibleObject(o) {} QAccessibleInterface *QQuickWebEngineViewAccessible::parent() const { QQuickItem *parent = engineView()->parentItem(); return QAccessible::queryAccessibleInterface(parent); } int QQuickWebEngineViewAccessible::childCount() const { if (engineView() && child(0)) return 1; return 0; } QAccessibleInterface *QQuickWebEngineViewAccessible::child(int index) const { if (index == 0)
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
return engineView()->d_func()->adapter->browserAccessible(); return 0; } int QQuickWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const { if (c == child(0)) return 0; return -1; } QString QQuickWebEngineViewAccessible::text(QAccessible::Text) const { return QString(); } QAccessible::Role QQuickWebEngineViewAccessible::role() const { return QAccessible::Document; } QAccessible::State QQuickWebEngineViewAccessible::state() const { QAccessible::State s; return s; } #endif // QT_NO_ACCESSIBILITY class WebContentsAdapterOwner : public QObject { public: typedef QSharedPointer<QtWebEngineCore::WebContentsAdapter> AdapterPtr; WebContentsAdapterOwner(const AdapterPtr &ptr) : adapter(ptr) {} private: AdapterPtr adapter; }; void QQuickWebEngineViewPrivate::adoptWebContents(WebContentsAdapter *webContents) { if (!webContents) { qWarning("Trying to open an empty request, it was either already used or was invalidated." "\nYou must complete the request synchronously within the newViewRequested signal handler." " If a view hasn't been adopted before returning, the request will be invalidated."); return; } if (webContents->browserContextAdapter() && browserContextAdapter() != webContents->browserContextAdapter()) { qWarning("Can not adopt content from a different WebEngineProfile."); return; } Q_Q(QQuickWebEngineView); // This throws away the WebContentsAdapter that has been used until now. // All its states, particularly the loading URL, are replaced by the adopted WebContentsAdapter. WebContentsAdapterOwner *adapterOwner = new WebContentsAdapterOwner(adapter->sharedFromThis()); adapterOwner->deleteLater(); adapter = webContents->sharedFromThis(); adapter->initialize(this); // associate the webChannel with the new adapter if (m_webChannel) adapter->setWebChannel(m_webChannel, m_webChannelWorld); // set initial background color if non-default if (m_backgroundColor != Qt::white) adapter->backgroundColorChanged();
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
// re-bind the userscrips to the new adapter Q_FOREACH (QQuickWebEngineScript *script, m_userScripts) script->d_func()->bind(browserContextAdapter()->userResourceController(), adapter.data()); // set the zoomFactor if it had been changed on the old adapter. if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor)) q->setZoomFactor(m_defaultZoomFactor); // Emit signals for values that might be different from the previous WebContentsAdapter. emit q->titleChanged(); emit q->urlChanged(); emit q->iconChanged(); // FIXME: The current loading state should be stored in the WebContentAdapter // and it should be checked here if the signal emission is really necessary. QQuickWebEngineLoadRequest loadRequest(adapter->activeUrl(), QQuickWebEngineView::LoadSucceededStatus); emit q->loadingChanged(&loadRequest); emit q->loadProgressChanged(); } QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent) : QQuickItem(parent) , d_ptr(new QQuickWebEngineViewPrivate) { Q_D(QQuickWebEngineView); d->q_ptr = this; this->setActiveFocusOnTab(true); this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsInputMethod | QQuickItem::ItemAcceptsDrops); #ifndef QT_NO_ACCESSIBILITY QQuickAccessibleAttached *accessible = QQuickAccessibleAttached::qmlAttachedProperties(this); accessible->setRole(QAccessible::Grouping); #endif // QT_NO_ACCESSIBILITY } QQuickWebEngineView::~QQuickWebEngineView() { Q_D(QQuickWebEngineView); if (d->faviconProvider) d->faviconProvider->detach(this); } void QQuickWebEngineViewPrivate::ensureContentsAdapter() { Q_Q(QQuickWebEngineView); if (!adapter) { adapter = QSharedPointer<WebContentsAdapter>::create(); adapter->initialize(this); if (m_backgroundColor != Qt::white) adapter->backgroundColorChanged(); if (m_webChannel) adapter->setWebChannel(m_webChannel, m_webChannelWorld); if (explicitUrl.isValid()) adapter->load(explicitUrl); // push down the page's user scripts Q_FOREACH (QQuickWebEngineScript *script, m_userScripts) script->d_func()->bind(browserContextAdapter()->userResourceController(), adapter.data()); // set the zoomFactor if it had been changed on the old adapter. if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor)) q->setZoomFactor(m_defaultZoomFactor); } } void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen) { Q_Q(QQuickWebEngineView); if (m_fullscreenMode != fullscreen) { m_fullscreenMode = fullscreen;
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
adapter->changedFullScreen(); Q_EMIT q->isFullScreenChanged(); } } QUrl QQuickWebEngineView::url() const { Q_D(const QQuickWebEngineView); return d->explicitUrl.isValid() ? d->explicitUrl : (d->adapter ? d->adapter->activeUrl() : QUrl()); } void QQuickWebEngineView::setUrl(const QUrl& url) { if (url.isEmpty()) return; Q_D(QQuickWebEngineView); d->explicitUrl = url; if (d->adapter) d->adapter->load(url); if (!qmlEngine(this) || isComponentComplete()) d->ensureContentsAdapter(); } QUrl QQuickWebEngineView::icon() const { Q_D(const QQuickWebEngineView); return d->iconUrl; } void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl) { Q_D(QQuickWebEngineView); d->explicitUrl = QUrl(); if (!qmlEngine(this) || isComponentComplete()) d->ensureContentsAdapter(); if (d->adapter) d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl); } void QQuickWebEngineView::goBack() { Q_D(QQuickWebEngineView); if (!d->adapter) return; d->adapter->navigateToOffset(-1); } void QQuickWebEngineView::goForward() { Q_D(QQuickWebEngineView); if (!d->adapter) return; d->adapter->navigateToOffset(1); } void QQuickWebEngineView::reload() { Q_D(QQuickWebEngineView); if (!d->adapter) return; d->adapter->reload(); } void QQuickWebEngineView::reloadAndBypassCache() { Q_D(QQuickWebEngineView); if (!d->adapter) return; d->adapter->reloadAndBypassCache();
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
} void QQuickWebEngineView::stop() { Q_D(QQuickWebEngineView); if (!d->adapter) return; d->adapter->stop(); } void QQuickWebEngineView::setZoomFactor(qreal arg) { Q_D(QQuickWebEngineView); d->m_defaultZoomFactor = arg; if (!d->adapter) return; qreal oldFactor = d->adapter->currentZoomFactor(); d->adapter->setZoomFactor(arg); if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor())) return; emit zoomFactorChanged(arg); } QQuickWebEngineProfile *QQuickWebEngineView::profile() const { Q_D(const QQuickWebEngineView); return d->m_profile; } void QQuickWebEngineView::setProfile(QQuickWebEngineProfile *profile) { Q_D(QQuickWebEngineView); d->setProfile(profile); } QQuickWebEngineSettings *QQuickWebEngineView::settings() const { Q_D(const QQuickWebEngineView); return d->m_settings.data(); } QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineView::userScripts() { Q_D(QQuickWebEngineView); return QQmlListProperty<QQuickWebEngineScript>(this, d, d->userScripts_append, d->userScripts_count, d->userScripts_at, d->userScripts_clear); } void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile) { Q_Q(QQuickWebEngineView); if (profile == m_profile) return; m_profile = profile; Q_EMIT q->profileChanged(); m_settings->setParentSettings(profile->settings()); if (adapter && adapter->browserContext() != browserContextAdapter()->browserContext()) { // When the profile changes we need to create a new WebContentAdapter and reload the active URL. QUrl activeUrl = adapter->activeUrl(); adapter.reset(); ensureContentsAdapter();
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
if (!explicitUrl.isValid() && activeUrl.isValid()) adapter->load(activeUrl); } } #ifdef ENABLE_QML_TESTSUPPORT_API QQuickWebEngineTestSupport *QQuickWebEngineView::testSupport() const { Q_D(const QQuickWebEngineView); return d->m_testSupport; } void QQuickWebEngineView::setTestSupport(QQuickWebEngineTestSupport *testSupport) { Q_D(QQuickWebEngineView); d->m_testSupport = testSupport; } #endif bool QQuickWebEngineView::activeFocusOnPress() const { Q_D(const QQuickWebEngineView); return d->m_activeFocusOnPress; } void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result) { Q_Q(QQuickWebEngineView); QJSValue callback = m_callbacks.take(requestId); QJSValueList args; args.append(qmlEngine(q)->toScriptValue(result)); callback.call(args); } void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount) { QJSValue callback = m_callbacks.take(requestId); QJSValueList args; args.append(QJSValue(matchCount)); callback.call(args); } void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, const QByteArray &result) { QJSValue callback = m_callbacks.take(requestId); QJSValueList args; args.append(QJSValue(result.data())); callback.call(args); } void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) { #ifdef ENABLE_QML_TESTSUPPORT_API if (m_testSupport) Q_EMIT m_testSupport->validationMessageShown(mainText, subText); #endif Q_Q(QQuickWebEngineView); QQuickWebEngineFormValidationMessageRequest *request; request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeShow, anchor,mainText,subText); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->formValidationMessageRequested(request); if (!request->isAccepted()) ui()->showMessageBubble(anchor, mainText, subText); } void QQuickWebEngineViewPrivate::hideValidationMessage() {
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
Q_Q(QQuickWebEngineView); QQuickWebEngineFormValidationMessageRequest *request; request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeHide); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->formValidationMessageRequested(request); if (!request->isAccepted()) ui()->hideMessageBubble(); } void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor) { Q_Q(QQuickWebEngineView); QQuickWebEngineFormValidationMessageRequest *request; request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeMove, anchor); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->formValidationMessageRequested(request); if (!request->isAccepted()) ui()->moveMessageBubble(anchor); } void QQuickWebEngineViewPrivate::updateScrollPosition(const QPointF &position) { Q_Q(QQuickWebEngineView); Q_EMIT q->scrollPositionChanged(position); } void QQuickWebEngineViewPrivate::updateContentsSize(const QSizeF &size) { Q_Q(QQuickWebEngineView); Q_EMIT q->contentsSizeChanged(size); } void QQuickWebEngineViewPrivate::renderProcessTerminated( RenderProcessTerminationStatus terminationStatus, int exitCode) { Q_Q(QQuickWebEngineView); Q_EMIT q->renderProcessTerminated(static_cast<QQuickWebEngineView::RenderProcessTerminationStatus>( renderProcessExitStatus(terminationStatus)), exitCode); } void QQuickWebEngineViewPrivate::startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) { adapter->startDragging(q_ptr->window(), dropData, allowedActions, pixmap, offset); } bool QQuickWebEngineViewPrivate::isEnabled() const { const Q_Q(QQuickWebEngineView); return q->isEnabled(); } void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText) { ui()->showToolTip(toolTipText); } bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); return d->isLoading; } int QQuickWebEngineView::loadProgress() const { Q_D(const QQuickWebEngineView);
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
return d->loadProgress; } QString QQuickWebEngineView::title() const { Q_D(const QQuickWebEngineView); if (!d->adapter) return QString(); return d->adapter->pageTitle(); } bool QQuickWebEngineView::canGoBack() const { Q_D(const QQuickWebEngineView); if (!d->adapter) return false; return d->adapter->canGoBack(); } bool QQuickWebEngineView::canGoForward() const { Q_D(const QQuickWebEngineView); if (!d->adapter) return false; return d->adapter->canGoForward(); } void QQuickWebEngineView::runJavaScript(const QString &script, const QJSValue &callback) { Q_D(QQuickWebEngineView); d->ensureContentsAdapter(); if (!callback.isUndefined()) { quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, QQuickWebEngineScript::MainWorld); d->m_callbacks.insert(requestId, callback); } else d->adapter->runJavaScript(script, QQuickWebEngineScript::MainWorld); } void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId, const QJSValue &callback) { Q_D(QQuickWebEngineView); if (!d->adapter) return; if (!callback.isUndefined()) { quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, worldId); d->m_callbacks.insert(requestId, callback); } else d->adapter->runJavaScript(script, worldId); } qreal QQuickWebEngineView::zoomFactor() const { Q_D(const QQuickWebEngineView); if (!d->adapter) return d->m_defaultZoomFactor; return d->adapter->currentZoomFactor(); } QColor QQuickWebEngineView::backgroundColor() const { Q_D(const QQuickWebEngineView); return d->m_backgroundColor; } void QQuickWebEngineView::setBackgroundColor(const QColor &color) { Q_D(QQuickWebEngineView); if (color == d->m_backgroundColor) return; d->m_backgroundColor = color;
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
if (d->adapter) d->adapter->backgroundColorChanged(); emit backgroundColorChanged(); } /*! \property QQuickWebEngineView::audioMuted \brief the state of whether the current page audio is muted. \since 5.7 The default value is false. */ bool QQuickWebEngineView::isAudioMuted() const { const Q_D(QQuickWebEngineView); if (d->adapter) return d->adapter->isAudioMuted(); return false; } void QQuickWebEngineView::setAudioMuted(bool muted) { Q_D(QQuickWebEngineView); bool _isAudioMuted = isAudioMuted(); if (d->adapter) { d->adapter->setAudioMuted(muted); if (_isAudioMuted != muted) { Q_EMIT audioMutedChanged(muted); } } } bool QQuickWebEngineView::recentlyAudible() const { const Q_D(QQuickWebEngineView); if (d->adapter) return d->adapter->recentlyAudible(); return false; } void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation) { Q_D(const QQuickWebEngineView); QPageSize layoutSize(static_cast<QPageSize::PageSizeId>(pageSizeId)); QPageLayout::Orientation layoutOrientation = static_cast<QPageLayout::Orientation>(orientation); QPageLayout pageLayout(layoutSize, layoutOrientation, QMarginsF(0.0, 0.0, 0.0, 0.0)); d->adapter->printToPDF(pageLayout, filePath); } void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation) { Q_D(QQuickWebEngineView); QPageSize layoutSize(static_cast<QPageSize::PageSizeId>(pageSizeId)); QPageLayout::Orientation layoutOrientation = static_cast<QPageLayout::Orientation>(orientation); QPageLayout pageLayout(layoutSize, layoutOrientation, QMarginsF(0.0, 0.0, 0.0, 0.0)); if (callback.isUndefined()) return; quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout); d->m_callbacks.insert(requestId, callback); } void QQuickWebEngineView::replaceMisspelledWord(const QString &replacement) { Q_D(QQuickWebEngineView); d->adapter->replaceMisspelling(replacement); }
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
bool QQuickWebEngineView::isFullScreen() const { Q_D(const QQuickWebEngineView); return d->m_fullscreenMode; } void QQuickWebEngineView::findText(const QString &subString, FindFlags options, const QJSValue &callback) { Q_D(QQuickWebEngineView); if (!d->adapter) return; if (subString.isEmpty()) { d->adapter->stopFinding(); if (!callback.isUndefined()) { QJSValueList args; args.append(QJSValue(0)); const_cast<QJSValue&>(callback).call(args); } } else { quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward); if (!callback.isUndefined()) d->m_callbacks.insert(requestId, callback); } } QQuickWebEngineHistory *QQuickWebEngineView::navigationHistory() const { Q_D(const QQuickWebEngineView); return d->m_history.data(); } QQmlWebChannel *QQuickWebEngineView::webChannel() { Q_D(QQuickWebEngineView); if (!d->m_webChannel) { d->m_webChannel = new QQmlWebChannel(this); if (d->adapter) d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld); } return d->m_webChannel; } void QQuickWebEngineView::setWebChannel(QQmlWebChannel *webChannel) { Q_D(QQuickWebEngineView); if (d->m_webChannel == webChannel) return; d->m_webChannel = webChannel; if (d->adapter) d->adapter->setWebChannel(webChannel, d->m_webChannelWorld); Q_EMIT webChannelChanged(); } uint QQuickWebEngineView::webChannelWorld() const { Q_D(const QQuickWebEngineView); return d->m_webChannelWorld; } void QQuickWebEngineView::setWebChannelWorld(uint webChannelWorld) { Q_D(QQuickWebEngineView); if (d->m_webChannelWorld == webChannelWorld) return; d->m_webChannelWorld = webChannelWorld; if (d->adapter) d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld); Q_EMIT webChannelWorldChanged(webChannelWorld); }
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature feature, bool granted) { if (!d_ptr->adapter) return; if (!granted && feature >= MediaAudioCapture && feature <= MediaAudioVideoCapture) { d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaNone); return; } switch (feature) { case MediaAudioCapture: d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaAudioCapture); break; case MediaVideoCapture: d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaVideoCapture); break; case MediaAudioVideoCapture: d_ptr->adapter->grantMediaAccessPermission(securityOrigin, WebContentsAdapterClient::MediaRequestFlags(WebContentsAdapterClient::MediaAudioCapture | WebContentsAdapterClient::MediaVideoCapture)); break; case Geolocation: d_ptr->adapter->runGeolocationRequestCallback(securityOrigin, granted); break; default: Q_UNREACHABLE(); } } void QQuickWebEngineView::setActiveFocusOnPress(bool arg) { Q_D(QQuickWebEngineView); if (d->m_activeFocusOnPress == arg) return; d->m_activeFocusOnPress = arg; emit activeFocusOnPressChanged(arg); } void QQuickWebEngineView::goBackOrForward(int offset) { Q_D(QQuickWebEngineView); if (!d->adapter) return; const int current = d->adapter->currentNavigationEntryIndex(); const int count = d->adapter->navigationEntryCount(); const int index = current + offset; if (index < 0 || index >= count) return; d->adapter->navigateToIndex(index); } void QQuickWebEngineView::fullScreenCancelled() { Q_D(QQuickWebEngineView); d->adapter->exitFullScreen(); } void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { QQuickItem::geometryChanged(newGeometry, oldGeometry); Q_FOREACH(QQuickItem *child, childItems()) { if (qobject_cast<RenderWidgetHostViewQtDelegateQuick *>(child)) child->setSize(newGeometry.size()); } } void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value) {
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
Q_D(QQuickWebEngineView); if (d->adapter && (change == ItemSceneChange || change == ItemVisibleHasChanged)) { if (window() && isVisible()) d->adapter->wasShown(); else d->adapter->wasHidden(); } QQuickItem::itemChange(change, value); } static QPoint mapToScreen(const QQuickItem *item, const QPoint &clientPos) { return item->window()->position() + item->mapToScene(clientPos).toPoint(); } void QQuickWebEngineView::dragEnterEvent(QDragEnterEvent *e) { Q_D(QQuickWebEngineView); e->accept(); d->adapter->enterDrag(e, mapToScreen(this, e->pos())); } void QQuickWebEngineView::dragLeaveEvent(QDragLeaveEvent *e) { Q_D(QQuickWebEngineView); e->accept(); d->adapter->leaveDrag(); } void QQuickWebEngineView::dragMoveEvent(QDragMoveEvent *e) { Q_D(QQuickWebEngineView); e->accept(); d->adapter->updateDragPosition(e, mapToScreen(this, e->pos())); } void QQuickWebEngineView::dropEvent(QDropEvent *e) { Q_D(QQuickWebEngineView); e->accept(); d->adapter->endDragging(e->pos(), mapToScreen(this, e->pos())); } void QQuickWebEngineView::triggerWebAction(WebAction action) { Q_D(QQuickWebEngineView); 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();
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
break; case Undo: d->adapter->undo(); break; case Redo: d->adapter->redo(); break; case SelectAll: d->adapter->selectAll(); break; case PasteAndMatchStyle: d->adapter->pasteAndMatchStyle(); break; case Unselect: d->adapter->unselect(); break; case OpenLinkInThisWindow: if (d->m_contextMenuData.linkUrl().isValid()) setUrl(d->m_contextMenuData.linkUrl()); break; case OpenLinkInNewWindow: if (d->m_contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; request.m_requestedUrl = d->m_contextMenuData.linkUrl(); request.m_isUserInitiated = true; request.m_destination = NewViewInWindow; Q_EMIT newViewRequested(&request); } break; case OpenLinkInNewTab: if (d->m_contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; request.m_requestedUrl = d->m_contextMenuData.linkUrl(); request.m_isUserInitiated = true; request.m_destination = NewViewInBackgroundTab; Q_EMIT newViewRequested(&request); } break; case CopyLinkToClipboard: if (d->m_contextMenuData.linkUrl().isValid()) { QString urlString = d->m_contextMenuData.linkUrl().toString(QUrl::FullyEncoded); QString title = d->m_contextMenuData.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_contextMenuData.linkUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadLinkToDisk: if (d->m_contextMenuData.linkUrl().isValid()) d->adapter->download(d->m_contextMenuData.linkUrl(), d->m_contextMenuData.suggestedFileName()); break; case CopyImageToClipboard: if (d->m_contextMenuData.hasImageContent() && (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeImage || d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas)) { d->adapter->copyImageAt(d->m_contextMenuData.position()); } break; case CopyImageUrlToClipboard: if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeImage) { QString urlString = d->m_contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); QString title = d->m_contextMenuData.linkText(); if (!title.isEmpty()) title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString);
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>"); data->setHtml(html); data->setUrls(QList<QUrl>() << d->m_contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadImageToDisk: case DownloadMediaToDisk: if (d->m_contextMenuData.mediaUrl().isValid()) d->adapter->download(d->m_contextMenuData.mediaUrl(), d->m_contextMenuData.suggestedFileName()); break; case CopyMediaUrlToClipboard: if (d->m_contextMenuData.mediaUrl().isValid() && (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { QString urlString = d->m_contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); QMimeData *data = new QMimeData(); data->setText(urlString); if (d->m_contextMenuData.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_contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case ToggleMediaControls: if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaControls); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerControls, enable); } break; case ToggleMediaLoop: if (d->m_contextMenuData.mediaUrl().isValid() && (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaLoop); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); } break; case ToggleMediaPlayPause: if (d->m_contextMenuData.mediaUrl().isValid() && (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { bool enable = (d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaPaused); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); } break; case ToggleMediaMute: if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaMuted); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerMute, enable); } break; case InspectElement: d->adapter->inspectElementAt(d->m_contextMenuData.position()); break; case ExitFullScreen: d->adapter->exitFullScreen(); break; case RequestClose: d->adapter->requestClose(); break; case SavePage: d->adapter->save(); break; case ViewSource:
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
d->adapter->viewSource(); break; default: Q_UNREACHABLE(); } } QSizeF QQuickWebEngineView::contentsSize() const { Q_D(const QQuickWebEngineView); return d->adapter->lastContentsSize(); } QPointF QQuickWebEngineView::scrollPosition() const { Q_D(const QQuickWebEngineView); return d->adapter->lastScrollOffset(); } void QQuickWebEngineViewPrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script) { Q_ASSERT(p && p->data); QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); UserResourceControllerHost *resourceController = d->browserContextAdapter()->userResourceController(); d->m_userScripts.append(script); // If the adapter hasn't been instantiated, we'll bind the scripts in ensureContentsAdapter() if (!d->adapter) return; script->d_func()->bind(resourceController, d->adapter.data()); } int QQuickWebEngineViewPrivate::userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p) { Q_ASSERT(p && p->data); QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); return d->m_userScripts.count(); } QQuickWebEngineScript *QQuickWebEngineViewPrivate::userScripts_at(QQmlListProperty<QQuickWebEngineScript> *p, int idx) { Q_ASSERT(p && p->data); QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); return d->m_userScripts.at(idx); } void QQuickWebEngineViewPrivate::userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p) { Q_ASSERT(p && p->data); QQuickWebEngineViewPrivate *d = static_cast<QQuickWebEngineViewPrivate*>(p->data); UserResourceControllerHost *resourceController = d->browserContextAdapter()->userResourceController(); resourceController->clearAllScripts(d->adapter.data()); d->m_userScripts.clear(); } void QQuickWebEngineView::componentComplete() { QQuickItem::componentComplete(); QTimer::singleShot(0, this, &QQuickWebEngineView::lazyInitialize); } void QQuickWebEngineView::lazyInitialize() { Q_D(QQuickWebEngineView); d->ensureContentsAdapter(); } QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest() : m_viewPrivate(0) , m_toggleOn(false) {
175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774
} QQuickWebEngineFullScreenRequest::QQuickWebEngineFullScreenRequest(QQuickWebEngineViewPrivate *viewPrivate, const QUrl &origin, bool toggleOn) : m_viewPrivate(viewPrivate) , m_origin(origin) , m_toggleOn(toggleOn) { } void QQuickWebEngineFullScreenRequest::accept() { if (m_viewPrivate) m_viewPrivate->setFullScreenMode(m_toggleOn); } void QQuickWebEngineFullScreenRequest::reject() { if (m_viewPrivate) m_viewPrivate->setFullScreenMode(!m_toggleOn); } QT_END_NAMESPACE