// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qquickwebengineaction_p.h" #include "qquickwebengineaction_p_p.h" #include "qquickwebengineclientcertificateselection_p.h" #include "qquickwebenginedialogrequests_p.h" #include "qquickwebenginefaviconprovider_p_p.h" #include "qquickwebenginenewwindowrequest_p.h" #include "qquickwebengineprofile.h" #include "qquickwebengineprofile_p.h" #include "qquickwebenginescriptcollection_p.h" #include "qquickwebenginescriptcollection_p_p.h" #include "qquickwebenginesettings_p.h" #include "qquickwebenginetouchhandleprovider_p_p.h" #include "qquickwebenginetouchhandle_p.h" #include "qquickwebenginetouchselectionmenurequest_p.h" #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" #include "authentication_dialog_controller.h" #include "autofill_popup_controller.h" #include "profile_adapter.h" #include "file_picker_controller.h" #include "find_text_helper.h" #include "javascript_dialog_controller.h" #include "render_widget_host_view_qt_delegate_item.h" #include "render_widget_host_view_qt_delegate_quickwindow_p.h" #include "touch_selection_menu_controller.h" #include "ui_delegates_manager_p.h" #include "web_contents_adapter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_CONFIG(accessibility) #include "qquickwebengine_accessible_p.h" #include #endif #if QT_CONFIG(webengine_printing_and_pdf) #include #include #include #include #endif #if QT_CONFIG(webengine_webchannel) #include #endif QT_BEGIN_NAMESPACE using namespace QtWebEngineCore; Q_STATIC_ASSERT(int(QQuickWebEngineView::WebActionCount) == int(QWebEnginePage::WebActionCount)); using LoadStatus = QWebEngineLoadingInfo::LoadStatus; using ErrorDomain = QWebEngineLoadingInfo::ErrorDomain; #if QT_DEPRECATED_SINCE(6, 2) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::AcceptRequest) == static_cast(QWebEngineNavigationRequest::AcceptRequest)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::IgnoreRequest) == static_cast(QWebEngineNavigationRequest::IgnoreRequest)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::LinkClickedNavigation) == static_cast(QWebEngineNavigationRequest::LinkClickedNavigation)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::TypedNavigation) == static_cast(QWebEngineNavigationRequest::TypedNavigation)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::FormSubmittedNavigation) == static_cast(QWebEngineNavigationRequest::FormSubmittedNavigation)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::BackForwardNavigation) == static_cast(QWebEngineNavigationRequest::BackForwardNavigation)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::ReloadNavigation) == static_cast(QWebEngineNavigationRequest::ReloadNavigation)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::OtherNavigation) == static_cast(QWebEngineNavigationRequest::OtherNavigation)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::RedirectNavigation) == static_cast(QWebEngineNavigationRequest::RedirectNavigation)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::NewViewInWindow) == static_cast(QWebEngineNewWindowRequest::InNewWindow)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::NewViewInTab) == static_cast(QWebEngineNewWindowRequest::InNewTab)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::NewViewInDialog) == static_cast(QWebEngineNewWindowRequest::InNewDialog)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::NewViewInBackgroundTab) == static_cast(QWebEngineNewWindowRequest::InNewBackgroundTab)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::NoErrorDomain) == static_cast(ErrorDomain::NoErrorDomain)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::InternalErrorDomain) == static_cast(ErrorDomain::InternalErrorDomain)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::ConnectionErrorDomain) == static_cast(ErrorDomain::ConnectionErrorDomain)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::CertificateErrorDomain) == static_cast(ErrorDomain::CertificateErrorDomain)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::HttpErrorDomain) == static_cast(ErrorDomain::HttpErrorDomain)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::FtpErrorDomain) == static_cast(ErrorDomain::FtpErrorDomain)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::DnsErrorDomain) == static_cast(ErrorDomain::DnsErrorDomain)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::LoadStartedStatus) == static_cast(LoadStatus::LoadStartedStatus)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::LoadStoppedStatus) == static_cast(LoadStatus::LoadStoppedStatus)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::LoadFailedStatus) == static_cast(LoadStatus::LoadFailedStatus)); Q_STATIC_ASSERT(static_cast(QQuickWebEngineView::LoadSucceededStatus) == static_cast(LoadStatus::LoadSucceededStatus)); QT_WARNING_POP #endif #if QT_CONFIG(webengine_printing_and_pdf) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Letter, QQuickWebEngineView::PrintedPageSizeId::Letter) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Legal, QQuickWebEngineView::PrintedPageSizeId::Legal) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Executive, QQuickWebEngineView::PrintedPageSizeId::Executive) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A0, QQuickWebEngineView::PrintedPageSizeId::A0) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A1, QQuickWebEngineView::PrintedPageSizeId::A1) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A2, QQuickWebEngineView::PrintedPageSizeId::A2) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A3, QQuickWebEngineView::PrintedPageSizeId::A3) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4, QQuickWebEngineView::PrintedPageSizeId::A4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A5, QQuickWebEngineView::PrintedPageSizeId::A5) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A6, QQuickWebEngineView::PrintedPageSizeId::A6) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A7, QQuickWebEngineView::PrintedPageSizeId::A7) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A8, QQuickWebEngineView::PrintedPageSizeId::A8) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A9, QQuickWebEngineView::PrintedPageSizeId::A9) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A10, QQuickWebEngineView::PrintedPageSizeId::A10) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B0, QQuickWebEngineView::PrintedPageSizeId::B0) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B1, QQuickWebEngineView::PrintedPageSizeId::B1) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B2, QQuickWebEngineView::PrintedPageSizeId::B2) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B3, QQuickWebEngineView::PrintedPageSizeId::B3) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B4, QQuickWebEngineView::PrintedPageSizeId::B4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B5, QQuickWebEngineView::PrintedPageSizeId::B5) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B6, QQuickWebEngineView::PrintedPageSizeId::B6) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B7, QQuickWebEngineView::PrintedPageSizeId::B7) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B8, QQuickWebEngineView::PrintedPageSizeId::B8) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B9, QQuickWebEngineView::PrintedPageSizeId::B9) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B10, QQuickWebEngineView::PrintedPageSizeId::B10) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::C5E, QQuickWebEngineView::PrintedPageSizeId::C5E) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Comm10E, QQuickWebEngineView::PrintedPageSizeId::Comm10E) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::DLE, QQuickWebEngineView::PrintedPageSizeId::DLE) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Folio, QQuickWebEngineView::PrintedPageSizeId::Folio) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Ledger, QQuickWebEngineView::PrintedPageSizeId::Ledger) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Tabloid, QQuickWebEngineView::PrintedPageSizeId::Tabloid) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Custom, QQuickWebEngineView::PrintedPageSizeId::Custom) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A3Extra, QQuickWebEngineView::PrintedPageSizeId::A3Extra) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Extra, QQuickWebEngineView::PrintedPageSizeId::A4Extra) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Plus, QQuickWebEngineView::PrintedPageSizeId::A4Plus) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Small, QQuickWebEngineView::PrintedPageSizeId::A4Small) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A5Extra, QQuickWebEngineView::PrintedPageSizeId::A5Extra) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B5Extra, QQuickWebEngineView::PrintedPageSizeId::B5Extra) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB0, QQuickWebEngineView::PrintedPageSizeId::JisB0) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB1, QQuickWebEngineView::PrintedPageSizeId::JisB1) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB2, QQuickWebEngineView::PrintedPageSizeId::JisB2) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB3, QQuickWebEngineView::PrintedPageSizeId::JisB3) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB4, QQuickWebEngineView::PrintedPageSizeId::JisB4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB5, QQuickWebEngineView::PrintedPageSizeId::JisB5) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB6, QQuickWebEngineView::PrintedPageSizeId::JisB6) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB7, QQuickWebEngineView::PrintedPageSizeId::JisB7) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB8, QQuickWebEngineView::PrintedPageSizeId::JisB8) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB9, QQuickWebEngineView::PrintedPageSizeId::JisB9) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB10, QQuickWebEngineView::PrintedPageSizeId::JisB10) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiC, QQuickWebEngineView::PrintedPageSizeId::AnsiC) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiD, QQuickWebEngineView::PrintedPageSizeId::AnsiD) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiE, QQuickWebEngineView::PrintedPageSizeId::AnsiE) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LegalExtra, QQuickWebEngineView::PrintedPageSizeId::LegalExtra) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterExtra, QQuickWebEngineView::PrintedPageSizeId::LetterExtra) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterPlus, QQuickWebEngineView::PrintedPageSizeId::LetterPlus) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterSmall, QQuickWebEngineView::PrintedPageSizeId::LetterSmall) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::TabloidExtra, QQuickWebEngineView::PrintedPageSizeId::TabloidExtra) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchA, QQuickWebEngineView::PrintedPageSizeId::ArchA) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchB, QQuickWebEngineView::PrintedPageSizeId::ArchB) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchC, QQuickWebEngineView::PrintedPageSizeId::ArchC) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchD, QQuickWebEngineView::PrintedPageSizeId::ArchD) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchE, QQuickWebEngineView::PrintedPageSizeId::ArchE) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial7x9, QQuickWebEngineView::PrintedPageSizeId::Imperial7x9) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial8x10, QQuickWebEngineView::PrintedPageSizeId::Imperial8x10) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial9x11, QQuickWebEngineView::PrintedPageSizeId::Imperial9x11) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial9x12, QQuickWebEngineView::PrintedPageSizeId::Imperial9x12) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x11, QQuickWebEngineView::PrintedPageSizeId::Imperial10x11) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x13, QQuickWebEngineView::PrintedPageSizeId::Imperial10x13) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x14, QQuickWebEngineView::PrintedPageSizeId::Imperial10x14) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial12x11, QQuickWebEngineView::PrintedPageSizeId::Imperial12x11) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial15x11, QQuickWebEngineView::PrintedPageSizeId::Imperial15x11) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ExecutiveStandard, QQuickWebEngineView::PrintedPageSizeId::ExecutiveStandard) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Note, QQuickWebEngineView::PrintedPageSizeId::Note) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Quarto, QQuickWebEngineView::PrintedPageSizeId::Quarto) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Statement, QQuickWebEngineView::PrintedPageSizeId::Statement) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::SuperA, QQuickWebEngineView::PrintedPageSizeId::SuperA) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::SuperB, QQuickWebEngineView::PrintedPageSizeId::SuperB) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Postcard, QQuickWebEngineView::PrintedPageSizeId::Postcard) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::DoublePostcard, QQuickWebEngineView::PrintedPageSizeId::DoublePostcard) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc16K, QQuickWebEngineView::PrintedPageSizeId::Prc16K) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc32K, QQuickWebEngineView::PrintedPageSizeId::Prc32K) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc32KBig, QQuickWebEngineView::PrintedPageSizeId::Prc32KBig) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldUS, QQuickWebEngineView::PrintedPageSizeId::FanFoldUS) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldGerman, QQuickWebEngineView::PrintedPageSizeId::FanFoldGerman) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldGermanLegal, QQuickWebEngineView::PrintedPageSizeId::FanFoldGermanLegal) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB5, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB5) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB6, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB6) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC0, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC0) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC1, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC1) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC2, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC2) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC3) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC6, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC6) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC65, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC65) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC7, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC7) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope9, QQuickWebEngineView::PrintedPageSizeId::Envelope9) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope11, QQuickWebEngineView::PrintedPageSizeId::Envelope11) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope12, QQuickWebEngineView::PrintedPageSizeId::Envelope12) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope14, QQuickWebEngineView::PrintedPageSizeId::Envelope14) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeMonarch, QQuickWebEngineView::PrintedPageSizeId::EnvelopeMonarch) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePersonal, QQuickWebEngineView::PrintedPageSizeId::EnvelopePersonal) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeChou3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeChou3) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeChou4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeChou4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeInvite, QQuickWebEngineView::PrintedPageSizeId::EnvelopeInvite) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeItalian, QQuickWebEngineView::PrintedPageSizeId::EnvelopeItalian) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeKaku2, QQuickWebEngineView::PrintedPageSizeId::EnvelopeKaku2) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeKaku3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeKaku3) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc1, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc1) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc2, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc2) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc3, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc3) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc4, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc5, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc5) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc6, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc6) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc7, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc7) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc8, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc8) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc9, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc9) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc10, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc10) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeYou4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeYou4) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LastPageSize, QQuickWebEngineView::PrintedPageSizeId::LastPageSize) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiA, QQuickWebEngineView::PrintedPageSizeId::AnsiA) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiB, QQuickWebEngineView::PrintedPageSizeId::AnsiB) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC5, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC5) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeDL, QQuickWebEngineView::PrintedPageSizeId::EnvelopeDL) ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope10, QQuickWebEngineView::PrintedPageSizeId::Envelope10) #endif class WebEngineQuickWidgetDelegate : public QtWebEngineCore::WidgetDelegate { public: WebEngineQuickWidgetDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *item, QQuickWebEngineView *parent) : m_contentItem(item) , m_parentView(parent) { } ~WebEngineQuickWidgetDelegate() override { if (m_contentItem) m_contentItem->setWidgetDelegate(nullptr); } void InitAsPopup(const QRect &screenRect) override { // note this is called when there is no windowing system // otherwsie see RenderWidgetHostViewQtDelegateQuickWindow m_contentItem->setPosition(screenRect.topLeft()); } void Bind(WebContentsAdapterClient *client) override { QQuickWebEngineViewPrivate::bindViewAndDelegateItem( static_cast(client), m_contentItem); } void Unbind() override { QQuickWebEngineViewPrivate::bindViewAndDelegateItem(nullptr, m_contentItem); } void Destroy() override { delete this; } bool ActiveFocusOnPress() override { return m_parentView->property("activeFocusOnPress").toBool() || m_parentView->hasActiveFocus(); } private: QPointer m_contentItem; // deleted by core QPointer m_parentView; }; #if QT_CONFIG(accessibility) static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object) { if (QQuickWebEngineView *v = qobject_cast(object)) return new QQuickWebEngineViewAccessible(v); return nullptr; } #endif // QT_CONFIG(accessibility) static QLatin1String defaultMimeType("text/html;charset=UTF-8"); QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() : m_profile(nullptr) , adapter(QSharedPointer::create()) , m_history(new QWebEngineHistory(new QWebEngineHistoryPrivate(this, [] (const QUrl &url) { return QQuickWebEngineFaviconProvider::faviconProviderUrl(url); }))) , contextMenuExtraItems(nullptr) , loadProgress(0) , m_fullscreenMode(false) , isLoading(false) , m_activeFocusOnPress(true) , m_webChannel(nullptr) , m_webChannelWorld(0) , m_defaultAudioMuted(false) , m_isBeingAdopted(false) , m_backgroundColor(Qt::white) , m_zoomFactor(1.0) , m_profileInitialized(false) , m_contextMenuRequest(nullptr) , m_touchHandleDelegate(nullptr) { memset(actions, 0, sizeof(actions)); #if QT_CONFIG(accessibility) QAccessible::installFactory(&webAccessibleFactory); #endif // QT_CONFIG(accessibility) } QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate() { Q_ASSERT(m_profileInitialized); m_profile->d_ptr->removeWebContentsAdapterClient(this); FaviconProviderHelper::instance()->detach(q_ptr); bindViewAndDelegateItem(this, nullptr); } void QQuickWebEngineViewPrivate::initializeProfile() { if (!m_profileInitialized) { Q_ASSERT(!adapter->isInitialized()); m_profileInitialized = true; if (!m_profile) { m_profile = QQuickWebEngineProfile::defaultProfile(); // MEMO first ever call to default profile will create one without context // it needs something to get qml engine from (and view is created in qml land) m_profile->ensureQmlContext(q_ptr); } m_profile->d_ptr->addWebContentsAdapterClient(this); m_settings.reset(new QQuickWebEngineSettings(m_profile->settings())); adapter->setClient(this); } } bool QQuickWebEngineViewPrivate::profileInitialized() const { return m_profileInitialized; } void QQuickWebEngineViewPrivate::releaseProfile() { // The profile for this web contents is about to be // garbage collected, delete WebContents first and // let the QQuickWebEngineView be collected later by gc. bindViewAndDelegateItem(this, nullptr); q_ptr->d_ptr.reset(); } UIDelegatesManager *QQuickWebEngineViewPrivate::ui() { Q_Q(QQuickWebEngineView); if (m_uIDelegatesManager.isNull()) m_uIDelegatesManager.reset(new UIDelegatesManager(q)); return m_uIDelegatesManager.data(); } RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client) { Q_Q(QQuickWebEngineView); auto *item = new RenderWidgetHostViewQtDelegateItem(client, /*isPopup = */ false); item->setWidgetDelegate(new WebEngineQuickWidgetDelegate(item, q)); return item; } RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client) { Q_Q(QQuickWebEngineView); const bool hasWindowCapability = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows); RenderWidgetHostViewQtDelegateItem *quickDelegate = new RenderWidgetHostViewQtDelegateItem(client, /*isPopup = */ true); if (hasWindowCapability) { RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow = new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate, q->window()); quickDelegate->setWidgetDelegate(wrapperWindow); wrapperWindow->setVirtualParent(q); return quickDelegate; } quickDelegate->setParentItem(q); quickDelegate->setWidgetDelegate(new WebEngineQuickWidgetDelegate(quickDelegate, q)); quickDelegate->show(); return quickDelegate; } void QQuickWebEngineViewPrivate::contextMenuRequested(QWebEngineContextMenuRequest *request) { Q_Q(QQuickWebEngineView); m_contextMenuRequest = request; QQmlEngine *engine = qmlEngine(q); // TODO: this is a workaround for QTBUG-65044 if (!engine) return; // mark the object for gc by creating temporary jsvalue // FIXME: we most likely do not need to make any copy here auto *r = new QWebEngineContextMenuRequest( new QWebEngineContextMenuRequestPrivate(*request->d.data())); engine->newQObject(r); Q_EMIT q->contextMenuRequested(r); if (r->isAccepted()) return; // Assign the WebEngineView as the parent of the menu, so mouse events are properly propagated // on OSX. QObject *menu = ui()->addMenu(q, QString(), r->position()); if (!menu) return; QQuickContextMenuBuilder contextMenuBuilder(r, q, menu); // Populate our menu contextMenuBuilder.initMenu(); // FIXME: expose the context menu data as an attached property to make this more useful if (contextMenuExtraItems) contextMenuBuilder.appendExtraItems(engine); // Now fire the popup() method on the top level menu ui()->showMenu(menu); } void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame, bool hasFrameData) { Q_Q(QQuickWebEngineView); auto request = new QWebEngineNavigationRequest(url, static_cast(navigationType), isMainFrame, hasFrameData); qmlEngine(q)->newQObject(request); Q_EMIT q->navigationRequested(request); accepted = request->isAccepted(); if (accepted && adapter->findTextHelper()->isFindTextInProgress()) adapter->findTextHelper()->stopFinding(); } void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer 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 QWebEngineCertificateError &error) { Q_Q(QQuickWebEngineView); Q_EMIT q->certificateError(error); } void QQuickWebEngineViewPrivate::selectClientCert( const QSharedPointer &controller) { Q_Q(QQuickWebEngineView); QQuickWebEngineClientCertificateSelection *certSelection = new QQuickWebEngineClientCertificateSelection(controller); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(certSelection); Q_EMIT q->selectClientCertificate(certSelection); } #if QT_DEPRECATED_SINCE(6, 8) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED static QQuickWebEngineView::Feature toDeprecatedFeature(QWebEnginePermission::PermissionType permissionType) { switch (permissionType) { case QWebEnginePermission::PermissionType::Notifications: return QQuickWebEngineView::Notifications; case QWebEnginePermission::PermissionType::Geolocation: return QQuickWebEngineView::Geolocation; case QWebEnginePermission::PermissionType::ClipboardReadWrite: return QQuickWebEngineView::ClipboardReadWrite; case QWebEnginePermission::PermissionType::LocalFontsAccess: return QQuickWebEngineView::LocalFontsAccess; case QWebEnginePermission::PermissionType::MediaAudioCapture: return QQuickWebEngineView::MediaAudioCapture; case QWebEnginePermission::PermissionType::MediaVideoCapture: return QQuickWebEngineView::MediaVideoCapture; case QWebEnginePermission::PermissionType::MediaAudioVideoCapture: return QQuickWebEngineView::MediaAudioVideoCapture; case QWebEnginePermission::PermissionType::DesktopVideoCapture: return QQuickWebEngineView::DesktopVideoCapture; case QWebEnginePermission::PermissionType::DesktopAudioVideoCapture: return QQuickWebEngineView::DesktopAudioVideoCapture; case QWebEnginePermission::PermissionType::MouseLock: case QWebEnginePermission::PermissionType::Unsupported: break; } Q_UNREACHABLE_RETURN(QQuickWebEngineView::Feature(-1)); } QT_WARNING_POP #endif // QT_DEPRECATED_SINCE(6, 8) void QQuickWebEngineViewPrivate::runFeaturePermissionRequest(QWebEnginePermission::PermissionType permissionType, const QUrl &securityOrigin) { Q_Q(QQuickWebEngineView); if (QWebEnginePermission::isPersistent(permissionType)) { Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, permissionType)); #if QT_DEPRECATED_SINCE(6, 8) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED Q_EMIT q->featurePermissionRequested(securityOrigin, toDeprecatedFeature(permissionType)); QT_WARNING_POP #endif // QT_DEPRECATED_SINCE(6, 8) return; } Q_UNREACHABLE(); } void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer 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 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); } bool 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); if (next) { next->forceActiveFocus(reverse ? Qt::BacktabFocusReason : Qt::TabFocusReason); return true; } return false; } void QQuickWebEngineViewPrivate::titleChanged(const QString &title) { Q_Q(QQuickWebEngineView); Q_UNUSED(title); Q_EMIT q->titleChanged(); } void QQuickWebEngineViewPrivate::urlChanged() { Q_Q(QQuickWebEngineView); QUrl url = adapter->activeUrl(); if (m_url != url) { m_url = url; Q_EMIT q->urlChanged(); } } void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url) { Q_Q(QQuickWebEngineView); if (iconUrl == QQuickWebEngineFaviconProvider::faviconProviderUrl(url)) return; iconUrl = QQuickWebEngineFaviconProvider::faviconProviderUrl(url); m_history->reset(); QTimer::singleShot(0, q, &QQuickWebEngineView::iconChanged); } void QQuickWebEngineViewPrivate::zoomFactorChanged(qreal factor) { Q_Q(QQuickWebEngineView); Q_EMIT q->zoomFactorChanged(factor); } void QQuickWebEngineViewPrivate::loadProgressChanged(int progress) { Q_Q(QQuickWebEngineView); loadProgress = progress; QTimer::singleShot(0, q, &QQuickWebEngineView::loadProgressChanged); } void QQuickWebEngineViewPrivate::didUpdateTargetURL(const QUrl &hoveredUrl) { Q_Q(QQuickWebEngineView); Q_EMIT q->linkHovered(hoveredUrl); } void QQuickWebEngineViewPrivate::selectionChanged() { updateEditActions(); } void QQuickWebEngineViewPrivate::zoomUpdateIsNeeded() { Q_Q(QQuickWebEngineView); q->setZoomFactor(m_zoomFactor); } void QQuickWebEngineViewPrivate::recentlyAudibleChanged(bool recentlyAudible) { Q_Q(QQuickWebEngineView); Q_EMIT q->recentlyAudibleChanged(recentlyAudible); } void QQuickWebEngineViewPrivate::renderProcessPidChanged(qint64 pid) { Q_Q(QQuickWebEngineView); Q_EMIT q->renderProcessPidChanged(pid); } QRectF QQuickWebEngineViewPrivate::viewportRect() const { Q_Q(const QQuickWebEngineView); return QRectF(q->x(), q->y(), q->width(), q->height()); } QColor QQuickWebEngineViewPrivate::backgroundColor() const { return m_backgroundColor; } void QQuickWebEngineViewPrivate::loadStarted(QWebEngineLoadingInfo info) { Q_Q(QQuickWebEngineView); isLoading = true; m_history->reset(); QTimer::singleShot(0, q, [q, info] () { emit q->loadingChanged(info); }); } void QQuickWebEngineViewPrivate::loadCommitted() { m_history->reset(); } void QQuickWebEngineViewPrivate::loadFinished(QWebEngineLoadingInfo info) { Q_Q(QQuickWebEngineView); isLoading = false; m_history->reset(); QTimer::singleShot(0, q, [q, info] () { emit q->loadingChanged(info); }); return; } void QQuickWebEngineViewPrivate::focusContainer() { Q_Q(QQuickWebEngineView); QQuickWindow *window = q->window(); if (window) window->requestActivate(); q->forceActiveFocus(); } void QQuickWebEngineViewPrivate::unhandledKeyEvent(QKeyEvent *event) { Q_Q(QQuickWebEngineView); if (q->parentItem()) QCoreApplication::sendEvent(q->parentItem(), event); } static QWebEngineNewWindowRequest::DestinationType toDestinationType(WebContentsAdapterClient::WindowOpenDisposition disposition) { switch (disposition) { case WebContentsAdapterClient::NewForegroundTabDisposition: return QWebEngineNewWindowRequest::InNewTab; case WebContentsAdapterClient::NewBackgroundTabDisposition: return QWebEngineNewWindowRequest::InNewBackgroundTab; case WebContentsAdapterClient::NewPopupDisposition: return QWebEngineNewWindowRequest::InNewDialog; case WebContentsAdapterClient::NewWindowDisposition: return QWebEngineNewWindowRequest::InNewWindow; default: Q_UNREACHABLE(); } } QSharedPointer QQuickWebEngineViewPrivate::adoptNewWindow(QSharedPointer newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect &geometry, const QUrl &targetUrl) { Q_Q(QQuickWebEngineView); Q_ASSERT(newWebContents); QQuickWebEngineNewWindowRequest request(toDestinationType(disposition), geometry, targetUrl, userGesture, newWebContents); Q_EMIT q->newWindowRequested(&request); if (request.d_ptr->isRequestHandled) return newWebContents; return nullptr; } bool QQuickWebEngineViewPrivate::isBeingAdopted() { return false; } void QQuickWebEngineViewPrivate::close() { Q_Q(QQuickWebEngineView); emit q->windowCloseRequested(); } void QQuickWebEngineViewPrivate::windowCloseRejected() { Q_Q(QQuickWebEngineView); if (Q_UNLIKELY(q->metaObject()->indexOfMethod("windowCloseRejected()") != -1)) QMetaObject::invokeMethod(q, "windowCloseRejected"); } void QQuickWebEngineViewPrivate::desktopMediaRequested( QtWebEngineCore::DesktopMediaController *controller) { Q_Q(QQuickWebEngineView); QTimer::singleShot(0, q, [q, controller]() { Q_EMIT q->desktopMediaRequested(QWebEngineDesktopMediaRequest(controller)); }); } void QQuickWebEngineViewPrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen) { Q_Q(QQuickWebEngineView); QWebEngineFullScreenRequest request(origin, fullscreen, [q = QPointer(q)] (bool toggleOn) { if (q) q->d_ptr->setFullScreenMode(toggleOn); }); 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(QQuickWebEngineView::JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) { Q_EMIT q->javaScriptConsoleMessage(static_cast(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 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; QWebEnginePermission::PermissionType permissionType; if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) permissionType = QWebEnginePermission::PermissionType::MediaAudioVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)) permissionType = QWebEnginePermission::PermissionType::MediaAudioCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) permissionType = QWebEnginePermission::PermissionType::MediaVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) permissionType = QWebEnginePermission::PermissionType::DesktopAudioVideoCapture; else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) permissionType = QWebEnginePermission::PermissionType::DesktopVideoCapture; Q_EMIT q->permissionRequested(createFeaturePermissionObject(securityOrigin, permissionType)); #if QT_DEPRECATED_SINCE(6, 8) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED QQuickWebEngineView::Feature deprecatedFeature; if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) deprecatedFeature = QQuickWebEngineView::MediaAudioVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaAudioCapture)) deprecatedFeature = QQuickWebEngineView::MediaAudioCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaVideoCapture)) deprecatedFeature = QQuickWebEngineView::MediaVideoCapture; else if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopAudioCapture) && requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) deprecatedFeature = QQuickWebEngineView::DesktopAudioVideoCapture; else // if (requestFlags.testFlag(WebContentsAdapterClient::MediaDesktopVideoCapture)) deprecatedFeature = QQuickWebEngineView::DesktopVideoCapture; Q_EMIT q->featurePermissionRequested(securityOrigin, deprecatedFeature); QT_WARNING_POP #endif // QT_DEPRECATED_SINCE(6, 8) } void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &securityOrigin) { // TODO: Add mouse lock support adapter->grantMouseLockPermission(securityOrigin, false); } void QQuickWebEngineViewPrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request) { Q_Q(QQuickWebEngineView); Q_EMIT q->registerProtocolHandlerRequested(request); } void QQuickWebEngineViewPrivate::runFileSystemAccessRequest( QWebEngineFileSystemAccessRequest request) { Q_Q(QQuickWebEngineView); Q_EMIT q->fileSystemAccessRequested(request); } QObject *QQuickWebEngineViewPrivate::accessibilityParentObject() { Q_Q(QQuickWebEngineView); return q; } ProfileAdapter *QQuickWebEngineViewPrivate::profileAdapter() { initializeProfile(); return m_profile->d_ptr->profileAdapter(); } WebContentsAdapter *QQuickWebEngineViewPrivate::webContentsAdapter() { return adapter.data(); } void QQuickWebEngineViewPrivate::printRequested() { Q_Q(QQuickWebEngineView); QTimer::singleShot(0, q, [q]() { Q_EMIT q->printRequested(); }); } void QQuickWebEngineViewPrivate::printRequestedByFrame(quint64 frameId) { Q_Q(QQuickWebEngineView); QTimer::singleShot(0, q, [this, q, frameId]() { Q_EMIT q->printRequestedByFrame(QWebEngineFrame(this->adapter, frameId)); }); } void QQuickWebEngineViewPrivate::findTextFinished(const QWebEngineFindTextResult &result) { Q_Q(QQuickWebEngineView); Q_EMIT q->findTextFinished(result); } void QQuickWebEngineViewPrivate::showAutofillPopup( QtWebEngineCore::AutofillPopupController *controller, const QRect &bounds, bool autoselectFirstSuggestion) { ui()->showAutofillPopup(controller, bounds.bottomLeft(), bounds.width() + 2, autoselectFirstSuggestion); } void QQuickWebEngineViewPrivate::hideAutofillPopup() { ui()->hideAutofillPopup(); } QWebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const { return m_settings->d_ptr.data(); } const QObject *QQuickWebEngineViewPrivate::holdingQObject() const { Q_Q(const QQuickWebEngineView); return q; } void QQuickWebEngineViewPrivate::lifecycleStateChanged(LifecycleState state) { Q_Q(QQuickWebEngineView); Q_EMIT q->lifecycleStateChanged(static_cast(state)); } void QQuickWebEngineViewPrivate::recommendedStateChanged(LifecycleState state) { Q_Q(QQuickWebEngineView); QTimer::singleShot(0, q, [q, state]() { Q_EMIT q->recommendedStateChanged(static_cast(state)); }); } void QQuickWebEngineViewPrivate::visibleChanged(bool visible) { Q_UNUSED(visible); } class WebContentsAdapterOwner : public QObject { public: typedef QSharedPointer AdapterPtr; WebContentsAdapterOwner(const AdapterPtr &ptr) : adapter(ptr) {} private: AdapterPtr adapter; }; bool QQuickWebEngineViewPrivate::adoptWebContents(WebContentsAdapter *webContents) { Q_ASSERT(webContents); if (webContents->profileAdapter() && profileAdapter() != webContents->profileAdapter()) { qWarning("Can not adopt content from a different WebEngineProfile."); return false; } m_isBeingAdopted = true; // 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->setClient(this); return true; } 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::ItemAcceptsDrops); connect(action(WebAction::Back), &QQuickWebEngineAction::enabledChanged, this, &QQuickWebEngineView::canGoBackChanged); connect(action(WebAction::Forward), &QQuickWebEngineAction::enabledChanged, this, &QQuickWebEngineView::canGoForwardChanged); } QQuickWebEngineView::~QQuickWebEngineView() { if (hasFocus()) setFocus(false); } void QQuickWebEngineViewPrivate::ensureContentsAdapter() { initializeProfile(); if (!adapter->isInitialized()) { if (!m_html.isEmpty()) adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url); else if (m_url.isValid()) adapter->load(m_url); else adapter->loadDefault(); } FaviconProviderHelper::instance()->attach(q_ptr); } void QQuickWebEngineViewPrivate::initializationFinished() { Q_Q(QQuickWebEngineView); Q_ASSERT(m_profileInitialized); if (m_backgroundColor != Qt::white) { adapter->setBackgroundColor(m_backgroundColor); emit q->backgroundColorChanged(); } // apply if it was set before first ever navigation already q->setZoomFactor(m_zoomFactor); #if QT_CONFIG(webengine_webchannel) if (m_webChannel) adapter->setWebChannel(m_webChannel, m_webChannelWorld); #endif if (m_defaultAudioMuted != adapter->isAudioMuted()) adapter->setAudioMuted(m_defaultAudioMuted); if (devToolsView && devToolsView->d_ptr->adapter) adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter); if (m_scriptCollection) m_scriptCollection->d->d->initializationFinished(adapter); if (q->window()) adapter->setVisible(q->isVisible()); if (!m_isBeingAdopted) return; // Ideally these would only be emitted if something actually changed. emit q->titleChanged(); emit q->urlChanged(); emit q->iconChanged(); emit q->loadingChanged(QWebEngineLoadingInfo(m_url, LoadStatus::LoadSucceededStatus)); emit q->loadProgressChanged(); m_isBeingAdopted = false; } void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen) { Q_Q(QQuickWebEngineView); if (m_fullscreenMode != fullscreen) { m_fullscreenMode = fullscreen; adapter->changedFullScreen(); Q_EMIT q->isFullScreenChanged(); } } // static void QQuickWebEngineViewPrivate::bindViewAndDelegateItem(QQuickWebEngineViewPrivate *viewPrivate, RenderWidgetHostViewQtDelegateItem *delegateItem) { auto oldDelegateItem = viewPrivate ? viewPrivate->delegateItem : nullptr; auto oldAdapterClient = delegateItem ? delegateItem->m_adapterClient : nullptr; auto *oldViewPrivate = static_cast(oldAdapterClient); // Change pointers first. if (delegateItem && oldViewPrivate != viewPrivate) { if (oldViewPrivate) oldViewPrivate->delegateItem = nullptr; delegateItem->m_adapterClient = viewPrivate; } if (viewPrivate && oldDelegateItem != delegateItem) { if (oldDelegateItem) oldDelegateItem->m_adapterClient = nullptr; viewPrivate->delegateItem = delegateItem; } // Then notify. if (oldViewPrivate && oldViewPrivate != viewPrivate) oldViewPrivate->delegateItemChanged(delegateItem, nullptr); if (viewPrivate && oldDelegateItem != delegateItem) viewPrivate->delegateItemChanged(oldDelegateItem, delegateItem); } void QQuickWebEngineViewPrivate::delegateItemChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *oldDelegateItem, QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *newDelegateItem) { Q_Q(QQuickWebEngineView); if (oldDelegateItem) { oldDelegateItem->setParentItem(nullptr); #if QT_CONFIG(accessibility) if (!QtWebEngineCore::closingDown()) { if (auto iface = QAccessible::queryAccessibleInterface(oldDelegateItem)) QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(iface)); } #endif } if (newDelegateItem) { Q_ASSERT(!QtWebEngineCore::closingDown()); #if QT_CONFIG(accessibility) QAccessible::registerAccessibleInterface(new QtWebEngineCore::RenderWidgetHostViewQtDelegateQuickAccessible(newDelegateItem, q)); #endif newDelegateItem->setParentItem(q); newDelegateItem->setSize(q->boundingRect().size()); // Focus on creation if the view accepts it if (q->activeFocusOnPress()) newDelegateItem->setFocus(true); } } void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction action) const { QQuickWebEngineAction *a = actions[action]; if (!a) return; bool enabled = true; switch (action) { case QQuickWebEngineView::Back: enabled = adapter->canGoBack(); break; case QQuickWebEngineView::Forward: enabled = adapter->canGoForward(); break; case QQuickWebEngineView::Stop: enabled = isLoading; break; case QQuickWebEngineView::Reload: case QQuickWebEngineView::ReloadAndBypassCache: enabled = !isLoading; break; case QQuickWebEngineView::ViewSource: enabled = adapter->canViewSource(); break; case QQuickWebEngineView::Cut: case QQuickWebEngineView::Copy: case QQuickWebEngineView::Unselect: enabled = adapter->hasFocusedFrame() && !adapter->selectedText().isEmpty(); break; case QQuickWebEngineView::Paste: case QQuickWebEngineView::Undo: case QQuickWebEngineView::Redo: case QQuickWebEngineView::SelectAll: case QQuickWebEngineView::PasteAndMatchStyle: enabled = adapter->hasFocusedFrame(); break; default: break; } a->d_ptr->setEnabled(enabled); } void QQuickWebEngineViewPrivate::updateNavigationActions() { updateAction(QQuickWebEngineView::Back); updateAction(QQuickWebEngineView::Forward); updateAction(QQuickWebEngineView::Stop); updateAction(QQuickWebEngineView::Reload); updateAction(QQuickWebEngineView::ReloadAndBypassCache); updateAction(QQuickWebEngineView::ViewSource); } void QQuickWebEngineViewPrivate::updateEditActions() { updateAction(QQuickWebEngineView::Cut); updateAction(QQuickWebEngineView::Copy); updateAction(QQuickWebEngineView::Paste); updateAction(QQuickWebEngineView::Undo); updateAction(QQuickWebEngineView::Redo); updateAction(QQuickWebEngineView::SelectAll); updateAction(QQuickWebEngineView::PasteAndMatchStyle); updateAction(QQuickWebEngineView::Unselect); } QQuickWebEngineScriptCollection *QQuickWebEngineViewPrivate::getUserScripts() { Q_Q(QQuickWebEngineView); if (!m_scriptCollection) m_scriptCollection.reset( new QQuickWebEngineScriptCollection( new QQuickWebEngineScriptCollectionPrivate( new QWebEngineScriptCollectionPrivate( profileAdapter()->userResourceController(), adapter)))); if (!m_scriptCollection->qmlEngine()) m_scriptCollection->setQmlEngine(qmlEngine(q)); return m_scriptCollection.data(); } QUrl QQuickWebEngineView::url() const { Q_D(const QQuickWebEngineView); return d->m_url; } void QQuickWebEngineView::setUrl(const QUrl& url) { Q_D(QQuickWebEngineView); if (url.isEmpty()) return; if (d->m_url != url) { d->m_url = url; d->m_html.clear(); emit urlChanged(); } if (d->adapter->isInitialized()) { d->adapter->load(url); } } QUrl QQuickWebEngineView::icon() const { Q_D(const QQuickWebEngineView); return d->iconUrl; } void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl) { Q_D(QQuickWebEngineView); d->m_url = baseUrl; d->m_html = html; if (d->adapter->isInitialized()) { d->adapter->setContent(html.toUtf8(), defaultMimeType, baseUrl); return; } } void QQuickWebEngineView::goBack() { Q_D(QQuickWebEngineView); d->adapter->navigateBack(); } void QQuickWebEngineView::goForward() { Q_D(QQuickWebEngineView); d->adapter->navigateForward(); } void QQuickWebEngineView::reload() { Q_D(QQuickWebEngineView); d->adapter->reload(); } void QQuickWebEngineView::reloadAndBypassCache() { Q_D(QQuickWebEngineView); d->adapter->reloadAndBypassCache(); } void QQuickWebEngineView::stop() { Q_D(QQuickWebEngineView); d->adapter->stop(); } void QQuickWebEngineView::setZoomFactor(qreal arg) { Q_D(QQuickWebEngineView); if (d->adapter->isInitialized() && !qFuzzyCompare(arg, zoomFactor())) { d->adapter->setZoomFactor(arg); // MEMO: should reset if factor was not applied due to being invalid d->m_zoomFactor = zoomFactor(); } else { d->m_zoomFactor = arg; } } QQuickWebEngineProfile *QQuickWebEngineView::profile() { Q_D(QQuickWebEngineView); d->initializeProfile(); return d->m_profile; } void QQuickWebEngineView::setProfile(QQuickWebEngineProfile *profile) { Q_D(QQuickWebEngineView); if (d->m_profile == profile) return; if (!d->profileInitialized()) { d->m_profile = profile; return; } if (d->m_profile) d->m_profile->d_ptr->removeWebContentsAdapterClient(d); d->m_profile = profile; d->m_profile->d_ptr->addWebContentsAdapterClient(d); d->m_settings->setParentSettings(profile->settings()); d->updateAdapter(); Q_EMIT profileChanged(); } QQuickWebEngineSettings *QQuickWebEngineView::settings() { Q_D(QQuickWebEngineView); d->initializeProfile(); return d->m_settings.data(); } QQuickWebEngineScriptCollection *QQuickWebEngineView::userScripts() { Q_D(QQuickWebEngineView); return d->getUserScripts(); } void QQuickWebEngineViewPrivate::updateAdapter() { // When the profile changes we need to create a new WebContentAdapter and reload the active URL. bool wasInitialized = adapter->isInitialized(); adapter = QSharedPointer::create(); adapter->setClient(this); if (wasInitialized) { if (!m_html.isEmpty()) adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url); else if (m_url.isValid()) adapter->load(m_url); else adapter->loadDefault(); } } bool QQuickWebEngineView::activeFocusOnPress() const { Q_D(const QQuickWebEngineView); return d->m_activeFocusOnPress; } void QQuickWebEngineViewPrivate::runJavaScript( const QString &script, quint32 worldId, quint64 frameId, const std::function &callback) { ensureContentsAdapter(); adapter->runJavaScript(script, worldId, frameId, callback); } void QQuickWebEngineViewPrivate::printToPdf(const QString &filePath, const QPageLayout &layout, const QPageRanges &ranges, quint64 frameId) { adapter->printToPDF(layout, ranges, filePath, frameId); } void QQuickWebEngineViewPrivate::printToPdf( std::function)> &&callback, const QPageLayout &layout, const QPageRanges &ranges, quint64 frameId) { adapter->printToPDFCallbackResult(std::move(callback), layout, ranges, /*colorMode*/ true, frameId); } void QQuickWebEngineViewPrivate::didPrintPageToPdf(const QString &filePath, bool success) { Q_Q(QQuickWebEngineView); Q_EMIT q->pdfPrintingFinished(filePath, success); } 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( renderProcessExitStatus(terminationStatus)), exitCode); } void QQuickWebEngineViewPrivate::requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) { Q_Q(QQuickWebEngineView); Q_EMIT q->geometryChangeRequested(geometry, frameGeometry); } QObject *QQuickWebEngineViewPrivate::dragSource() const { // QTBUG-57516 // Fixme: This is just a band-aid workaround. #if QT_CONFIG(draganddrop) return QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows) ? q_ptr : nullptr; #else return nullptr; #endif } bool QQuickWebEngineViewPrivate::isEnabled() const { const Q_Q(QQuickWebEngineView); return q->isEnabled(); } void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText) { Q_Q(QQuickWebEngineView); QQuickWebEngineTooltipRequest *request = new QQuickWebEngineTooltipRequest(toolTipText, q); // mark the object for gc by creating temporary jsvalue qmlEngine(q)->newQObject(request); Q_EMIT q->tooltipRequested(request); if (!request->isAccepted()) ui()->showToolTip(toolTipText); } QtWebEngineCore::TouchHandleDrawableDelegate * QQuickWebEngineViewPrivate::createTouchHandleDelegate(const QMap &images) { Q_Q(QQuickWebEngineView); // lifecycle managed by Chromium's TouchHandleDrawable QQuickWebEngineTouchHandle *handle = new QQuickWebEngineTouchHandle(); if (m_touchHandleDelegate) { QQmlContext *qmlContext = QQmlEngine::contextForObject(q); QQmlContext *context = new QQmlContext(qmlContext, handle); context->setContextObject(handle); QObject *delegate = m_touchHandleDelegate->create(context); Q_ASSERT(delegate); QQuickItem *item = qobject_cast(delegate); item->setParentItem(q); handle->setItem(item, false); } else { QQuickItem *item = ui()->createTouchHandle(); Q_ASSERT(item); QQmlEngine *engine = qmlEngine(item); Q_ASSERT(engine); QQuickWebEngineTouchHandleProvider *touchHandleProvider = static_cast( engine->imageProvider(QQuickWebEngineTouchHandleProvider::identifier())); Q_ASSERT(touchHandleProvider); touchHandleProvider->init(images); handle->setItem(item, true); } return handle; } void QQuickWebEngineViewPrivate::showTouchSelectionMenu(QtWebEngineCore::TouchSelectionMenuController *menuController, const QRect &selectionBounds, const QSize &handleSize) { Q_UNUSED(handleSize); Q_Q(QQuickWebEngineView); const int kSpacingBetweenButtons = 2; const int kMenuButtonMinWidth = 63; const int kMenuButtonMinHeight = 38; QQuickWebEngineTouchSelectionMenuRequest *request = new QQuickWebEngineTouchSelectionMenuRequest( selectionBounds, menuController); qmlEngine(q)->newQObject(request); Q_EMIT q->touchSelectionMenuRequested(request); if (request->isAccepted()) { return; } int buttonCount = menuController->buttonCount(); if (buttonCount == 1) { menuController->runContextMenu(); return; } int width = (kSpacingBetweenButtons * (buttonCount + 1)) + (kMenuButtonMinWidth * buttonCount); int height = kMenuButtonMinHeight + kSpacingBetweenButtons; int x = (selectionBounds.x() + selectionBounds.x() + selectionBounds.width() - width) / 2; int y = selectionBounds.y() - height - 2; QRect bounds(x, y, width, height); ui()->showTouchSelectionMenu(menuController, bounds, kSpacingBetweenButtons); } void QQuickWebEngineViewPrivate::hideTouchSelectionMenu() { ui()->hideTouchSelectionMenu(); } void QQuickWebEngineViewPrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *request) { Q_Q(QQuickWebEngineView); Q_EMIT q->webAuthUxRequested(request); } QWebEnginePermission QQuickWebEngineViewPrivate::createFeaturePermissionObject(const QUrl &securityOrigin, QWebEnginePermission::PermissionType permissionType) { auto *returnPrivate = new QWebEnginePermissionPrivate(securityOrigin, permissionType, adapter, profileAdapter()); return QWebEnginePermission(returnPrivate); } bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); return d->isLoading; } int QQuickWebEngineView::loadProgress() const { Q_D(const QQuickWebEngineView); return d->loadProgress; } QString QQuickWebEngineView::title() const { Q_D(const QQuickWebEngineView); return d->adapter->pageTitle(); } bool QQuickWebEngineView::canGoBack() const { Q_D(const QQuickWebEngineView); return d->adapter->canGoBack(); } bool QQuickWebEngineView::canGoForward() const { Q_D(const QQuickWebEngineView); return d->adapter->canGoForward(); } void QQuickWebEngineView::runJavaScript(const QString &script, const QJSValue &callback) { runJavaScript(script, QWebEngineScript::MainWorld, callback); } void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId, const QJSValue &callback) { Q_D(QQuickWebEngineView); std::function wrappedCallback; if (!callback.isUndefined()) { wrappedCallback = [this, callback](const QVariant &result) { QJSValueList args; args.append(qmlEngine(this)->toScriptValue(result)); callback.call(args); }; } d->runJavaScript(script, worldId, WebContentsAdapter::kUseMainFrameId, wrappedCallback); } qreal QQuickWebEngineView::zoomFactor() const { Q_D(const QQuickWebEngineView); if (!d->adapter->isInitialized()) return d->m_zoomFactor; 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; if (d->adapter->isInitialized()) { d->adapter->setBackgroundColor(color); 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->isInitialized()) return d->adapter->isAudioMuted(); return d->m_defaultAudioMuted; } void QQuickWebEngineView::setAudioMuted(bool muted) { Q_D(QQuickWebEngineView); bool wasAudioMuted = isAudioMuted(); d->m_defaultAudioMuted = muted; d->adapter->setAudioMuted(muted); if (wasAudioMuted != isAudioMuted()) Q_EMIT audioMutedChanged(muted); } bool QQuickWebEngineView::recentlyAudible() const { const Q_D(QQuickWebEngineView); return d->adapter->recentlyAudible(); } qint64 QQuickWebEngineView::renderProcessPid() const { const Q_D(QQuickWebEngineView); return d->adapter->renderProcessPid(); } void QQuickWebEngineView::printToPdf(const QString& filePath, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation) { #if QT_CONFIG(webengine_printing_and_pdf) Q_D(QQuickWebEngineView); QPageSize layoutSize(static_cast(pageSizeId)); QPageLayout::Orientation layoutOrientation = static_cast(orientation); QPageLayout pageLayout(layoutSize, layoutOrientation, QMarginsF(0.0, 0.0, 0.0, 0.0)); QPageRanges ranges; d->ensureContentsAdapter(); d->printToPdf(filePath, pageLayout, ranges, WebContentsAdapter::kUseMainFrameId); #else Q_UNUSED(filePath); Q_UNUSED(pageSizeId); Q_UNUSED(orientation); #endif } void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId pageSizeId, PrintedPageOrientation orientation) { #if QT_CONFIG(webengine_printing_and_pdf) Q_D(QQuickWebEngineView); QPageSize layoutSize(static_cast(pageSizeId)); QPageLayout::Orientation layoutOrientation = static_cast(orientation); QPageLayout pageLayout(layoutSize, layoutOrientation, QMarginsF(0.0, 0.0, 0.0, 0.0)); QPageRanges ranges; if (callback.isUndefined()) return; d->ensureContentsAdapter(); std::function wrappedCallback = [this, callback](QSharedPointer result) { QJSValueList args; args.append(qmlEngine(this)->toScriptValue(*result)); callback.call(args); }; d->printToPdf(std::move(wrappedCallback), pageLayout, ranges, WebContentsAdapter::kUseMainFrameId); #else Q_UNUSED(pageSizeId); Q_UNUSED(orientation); // Call back with null result. QJSValueList args; args.append(QJSValue(QLatin1String(""))); QJSValue callbackCopy = callback; callbackCopy.call(args); #endif } void QQuickWebEngineView::replaceMisspelledWord(const QString &replacement) { Q_D(QQuickWebEngineView); d->adapter->replaceMisspelling(replacement); } 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->isInitialized()) return; d->adapter->findTextHelper()->startFinding(subString, options & FindCaseSensitively, options & FindBackward, callback); } QWebEngineHistory *QQuickWebEngineView::history() const { Q_D(const QQuickWebEngineView); return d->m_history.data(); } QQmlWebChannel *QQuickWebEngineView::webChannel() { #if QT_CONFIG(webengine_webchannel) Q_D(QQuickWebEngineView); if (!d->m_webChannel) { d->m_webChannel = new QQmlWebChannel(this); } return d->m_webChannel; #endif qWarning("WebEngine compiled without webchannel support"); return nullptr; } void QQuickWebEngineView::setWebChannel(QQmlWebChannel *webChannel) { #if QT_CONFIG(webengine_webchannel) Q_D(QQuickWebEngineView); if (d->m_webChannel == webChannel) return; d->m_webChannel = webChannel; if (d->profileInitialized()) d->adapter->setWebChannel(webChannel, d->m_webChannelWorld); Q_EMIT webChannelChanged(); #else Q_UNUSED(webChannel); qWarning("WebEngine compiled without webchannel support"); #endif } uint QQuickWebEngineView::webChannelWorld() const { Q_D(const QQuickWebEngineView); return d->m_webChannelWorld; } void QQuickWebEngineView::setWebChannelWorld(uint webChannelWorld) { #if QT_CONFIG(webengine_webchannel) Q_D(QQuickWebEngineView); if (d->m_webChannelWorld == webChannelWorld) return; d->m_webChannelWorld = webChannelWorld; if (d->profileInitialized()) d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld); Q_EMIT webChannelWorldChanged(webChannelWorld); #else Q_UNUSED(webChannelWorld); qWarning("WebEngine compiled without webchannel support"); #endif } QQuickWebEngineView *QQuickWebEngineView::inspectedView() const { Q_D(const QQuickWebEngineView); return d->inspectedView; } void QQuickWebEngineView::setInspectedView(QQuickWebEngineView *view) { Q_D(QQuickWebEngineView); if (d->inspectedView == view) return; QQuickWebEngineView *oldView = d->inspectedView; d->inspectedView = nullptr; if (oldView) oldView->setDevToolsView(nullptr); d->inspectedView = view; if (view) view->setDevToolsView(this); Q_EMIT inspectedViewChanged(); } QQuickWebEngineView *QQuickWebEngineView::devToolsView() const { Q_D(const QQuickWebEngineView); return d->devToolsView; } QString QQuickWebEngineView::devToolsId() { Q_D(QQuickWebEngineView); d->ensureContentsAdapter(); return d->adapter->devToolsId(); } void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView) { Q_D(QQuickWebEngineView); if (d->devToolsView == devToolsView) return; QQuickWebEngineView *oldView = d->devToolsView; d->devToolsView = nullptr; if (oldView) oldView->setInspectedView(nullptr); d->devToolsView = devToolsView; if (devToolsView) devToolsView->setInspectedView(this); if (d->profileInitialized() && d->adapter->isInitialized()) { if (devToolsView) d->adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter); else d->adapter->closeDevToolsFrontend(); } Q_EMIT devToolsViewChanged(); } #if QT_DEPRECATED_SINCE(6, 8) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature feature, bool granted) { Q_D(QQuickWebEngineView); QWebEnginePermission::PermissionType permissionType; switch (feature) { case QQuickWebEngineView::Notifications: permissionType = QWebEnginePermission::PermissionType::Notifications; break; case QQuickWebEngineView::Geolocation: permissionType = QWebEnginePermission::PermissionType::Geolocation; break; case QQuickWebEngineView::MediaAudioCapture: permissionType = QWebEnginePermission::PermissionType::MediaAudioCapture; break; case QQuickWebEngineView::MediaVideoCapture: permissionType = QWebEnginePermission::PermissionType::MediaVideoCapture; break; case QQuickWebEngineView::MediaAudioVideoCapture: permissionType = QWebEnginePermission::PermissionType::MediaAudioVideoCapture; break; case QQuickWebEngineView::DesktopVideoCapture: permissionType = QWebEnginePermission::PermissionType::DesktopVideoCapture; break; case QQuickWebEngineView::DesktopAudioVideoCapture: permissionType = QWebEnginePermission::PermissionType::DesktopAudioVideoCapture; break; case QQuickWebEngineView::ClipboardReadWrite: permissionType = QWebEnginePermission::PermissionType::ClipboardReadWrite; break; case QQuickWebEngineView::LocalFontsAccess: permissionType = QWebEnginePermission::PermissionType::LocalFontsAccess; break; default: Q_UNREACHABLE(); } d->adapter->setPermission(securityOrigin, permissionType, granted ? QWebEnginePermission::State::Granted : QWebEnginePermission::State::Denied); } QT_WARNING_POP #endif // QT_DEPRECATED_SINCE(6, 8) 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); 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::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) { QQuickItem::geometryChange(newGeometry, oldGeometry); Q_D(QQuickWebEngineView); if (d->delegateItem) d->delegateItem->setSize(newGeometry.size()); } void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value) { Q_D(QQuickWebEngineView); if (d && d->profileInitialized() && d->adapter->isInitialized() && (change == ItemSceneChange || change == ItemVisibleHasChanged)) { if (window()) d->adapter->setVisible(isVisible()); } QQuickItem::itemChange(change, value); } void QQuickWebEngineView::acceptAsNewWindow(QWebEngineNewWindowRequest *request) { Q_D(QQuickWebEngineView); if (!request || (!request->d_ptr->adapter && !request->requestedUrl().isValid()) || request->d_ptr->isRequestHandled) { qWarning("Trying to open an empty request, it was either already used or was invalidated." "\nYou must complete the request synchronously within the newWindowRequested signal handler." " If a view hasn't been adopted before returning, the request will be invalidated."); return; } auto adapter = request->d_ptr->adapter; if (!adapter) setUrl(request->requestedUrl()); else if (!d->adoptWebContents(adapter.data())) return; request->d_ptr->setHandled(); } #if QT_CONFIG(draganddrop) static QPointF mapToScreen(const QQuickItem *item, const QPointF &clientPos) { return item->window()->position() + item->mapToScene(clientPos); } void QQuickWebEngineView::dragEnterEvent(QDragEnterEvent *e) { Q_D(QQuickWebEngineView); e->accept(); d->adapter->enterDrag(e, mapToScreen(this, e->position())); } void QQuickWebEngineView::dragLeaveEvent(QDragLeaveEvent *e) { Q_D(QQuickWebEngineView); e->accept(); d->adapter->leaveDrag(); } void QQuickWebEngineView::dragMoveEvent(QDragMoveEvent *e) { Q_D(QQuickWebEngineView); Qt::DropAction dropAction = d->adapter->updateDragPosition(e, mapToScreen(this, e->position())); if (Qt::IgnoreAction == dropAction) { e->ignore(); } else { e->setDropAction(dropAction); e->accept(); } } void QQuickWebEngineView::dropEvent(QDropEvent *e) { Q_D(QQuickWebEngineView); e->accept(); d->adapter->endDragging(e, mapToScreen(this, e->position())); } #endif // QT_CONFIG(draganddrop) void QQuickWebEngineView::triggerWebAction(WebAction action) { Q_D(QQuickWebEngineView); switch (action) { case Back: d->adapter->navigateBack(); break; case Forward: d->adapter->navigateForward(); break; case Stop: d->adapter->stop(); break; case Reload: d->adapter->reload(); break; case ReloadAndBypassCache: d->adapter->reloadAndBypassCache(); break; case Cut: d->adapter->cut(); break; case Copy: d->adapter->copy(); break; case Paste: d->adapter->paste(); break; case Undo: d->adapter->undo(); break; case Redo: d->adapter->redo(); break; case SelectAll: d->adapter->selectAll(); break; case PasteAndMatchStyle: d->adapter->pasteAndMatchStyle(); break; case Unselect: d->adapter->unselect(); break; case OpenLinkInThisWindow: if (d->m_contextMenuRequest->filteredLinkUrl().isValid()) setUrl(d->m_contextMenuRequest->filteredLinkUrl()); break; case OpenLinkInNewWindow: if (d->m_contextMenuRequest->filteredLinkUrl().isValid()) { QQuickWebEngineNewWindowRequest request(QWebEngineNewWindowRequest::InNewWindow, QRect(), d->m_contextMenuRequest->filteredLinkUrl(), true, nullptr); Q_EMIT newWindowRequested(&request); } break; case OpenLinkInNewTab: if (d->m_contextMenuRequest->filteredLinkUrl().isValid()) { QQuickWebEngineNewWindowRequest request(QWebEngineNewWindowRequest::InNewBackgroundTab, QRect(), d->m_contextMenuRequest->filteredLinkUrl(), true, nullptr); Q_EMIT newWindowRequested(&request); } break; case CopyLinkToClipboard: if (!d->m_contextMenuRequest->linkUrl().isEmpty()) { QString urlString = d->m_contextMenuRequest->linkUrl().toString(QUrl::FullyEncoded); QString linkText = d->m_contextMenuRequest->linkText().toHtmlEscaped(); QString title = d->m_contextMenuRequest->titleText(); if (!title.isEmpty()) title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral("") + linkText + QStringLiteral(""); data->setHtml(html); data->setUrls(QList() << d->m_contextMenuRequest->linkUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadLinkToDisk: if (d->m_contextMenuRequest->filteredLinkUrl().isValid()) d->adapter->download(d->m_contextMenuRequest->filteredLinkUrl(), d->m_contextMenuRequest->suggestedFileName(), d->m_contextMenuRequest->referrerUrl(), d->m_contextMenuRequest->referrerPolicy()); break; case CopyImageToClipboard: if (d->m_contextMenuRequest->hasImageContent() && (d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeImage || d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeCanvas)) { d->adapter->copyImageAt(d->m_contextMenuRequest->position()); } break; case CopyImageUrlToClipboard: if (d->m_contextMenuRequest->mediaUrl().isValid() && d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeImage) { QString urlString = d->m_contextMenuRequest->mediaUrl().toString(QUrl::FullyEncoded); QString alt = d->m_contextMenuRequest->altText(); if (!alt.isEmpty()) alt = QStringLiteral(" alt=\"%1\"").arg(alt.toHtmlEscaped()); QString title = d->m_contextMenuRequest->titleText(); if (!title.isEmpty()) title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral(""); data->setHtml(html); data->setUrls(QList() << d->m_contextMenuRequest->mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadImageToDisk: case DownloadMediaToDisk: if (d->m_contextMenuRequest->mediaUrl().isValid()) d->adapter->download(d->m_contextMenuRequest->mediaUrl(), d->m_contextMenuRequest->suggestedFileName(), d->m_contextMenuRequest->referrerUrl(), d->m_contextMenuRequest->referrerPolicy()); break; case CopyMediaUrlToClipboard: if (d->m_contextMenuRequest->mediaUrl().isValid() && (d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeAudio || d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeVideo)) { QString urlString = d->m_contextMenuRequest->mediaUrl().toString(QUrl::FullyEncoded); QString title = d->m_contextMenuRequest->titleText(); if (!title.isEmpty()) title = QStringLiteral(" title=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString); if (d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeAudio) data->setHtml(QStringLiteral("")); else data->setHtml(QStringLiteral("")); data->setUrls(QList() << d->m_contextMenuRequest->mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case ToggleMediaControls: if (d->m_contextMenuRequest->mediaUrl().isValid() && d->m_contextMenuRequest->mediaFlags() & QWebEngineContextMenuRequest::MediaCanToggleControls) { bool enable = !(d->m_contextMenuRequest->mediaFlags() & QWebEngineContextMenuRequest::MediaControls); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuRequest->position(), WebContentsAdapter::MediaPlayerControls, enable); } break; case ToggleMediaLoop: if (d->m_contextMenuRequest->mediaUrl().isValid() && (d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeAudio || d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeVideo)) { bool enable = !(d->m_contextMenuRequest->mediaFlags() & QWebEngineContextMenuRequest::MediaLoop); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuRequest->position(), WebContentsAdapter::MediaPlayerLoop, enable); } break; case ToggleMediaPlayPause: if (d->m_contextMenuRequest->mediaUrl().isValid() && (d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeAudio || d->m_contextMenuRequest->mediaType() == QWebEngineContextMenuRequest::MediaTypeVideo)) { bool enable = (d->m_contextMenuRequest->mediaFlags() & QWebEngineContextMenuRequest::MediaPaused); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuRequest->position(), WebContentsAdapter::MediaPlayerPlay, enable); } break; case ToggleMediaMute: if (d->m_contextMenuRequest->mediaUrl().isValid() && d->m_contextMenuRequest->mediaFlags() & QWebEngineContextMenuRequest::MediaHasAudio) { bool enable = !(d->m_contextMenuRequest->mediaFlags() & QWebEngineContextMenuRequest::MediaMuted); d->adapter->executeMediaPlayerActionAt(d->m_contextMenuRequest->position(), WebContentsAdapter::MediaPlayerMute, enable); } break; case InspectElement: d->adapter->inspectElementAt(d->m_contextMenuRequest->position()); break; case ExitFullScreen: d->adapter->exitFullScreen(); break; case RequestClose: d->adapter->requestClose(); break; case SavePage: d->adapter->save(); break; case ViewSource: d->adapter->viewSource(); break; case ToggleBold: runJavaScript(QStringLiteral("document.execCommand('bold');"), QWebEngineScript::ApplicationWorld); break; case ToggleItalic: runJavaScript(QStringLiteral("document.execCommand('italic');"), QWebEngineScript::ApplicationWorld); break; case ToggleUnderline: runJavaScript(QStringLiteral("document.execCommand('underline');"), QWebEngineScript::ApplicationWorld); break; case ToggleStrikethrough: runJavaScript(QStringLiteral("document.execCommand('strikethrough');"), QWebEngineScript::ApplicationWorld); break; case AlignLeft: runJavaScript(QStringLiteral("document.execCommand('justifyLeft');"), QWebEngineScript::ApplicationWorld); break; case AlignCenter: runJavaScript(QStringLiteral("document.execCommand('justifyCenter');"), QWebEngineScript::ApplicationWorld); break; case AlignRight: runJavaScript(QStringLiteral("document.execCommand('justifyRight');"), QWebEngineScript::ApplicationWorld); break; case AlignJustified: runJavaScript(QStringLiteral("document.execCommand('justifyFull');"), QWebEngineScript::ApplicationWorld); break; case Indent: runJavaScript(QStringLiteral("document.execCommand('indent');"), QWebEngineScript::ApplicationWorld); break; case Outdent: runJavaScript(QStringLiteral("document.execCommand('outdent');"), QWebEngineScript::ApplicationWorld); break; case InsertOrderedList: runJavaScript(QStringLiteral("document.execCommand('insertOrderedList');"), QWebEngineScript::ApplicationWorld); break; case InsertUnorderedList: runJavaScript(QStringLiteral("document.execCommand('insertUnorderedList');"), QWebEngineScript::ApplicationWorld); break; case ChangeTextDirectionLTR: d->adapter->changeTextDirection(true /*left to right*/); break; case ChangeTextDirectionRTL: d->adapter->changeTextDirection(false /*left to right*/); break; default: // Reachable when a spell checker replacement word has been selected break; } } QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) { Q_D(QQuickWebEngineView); if (action == QQuickWebEngineView::NoWebAction) return nullptr; if (d->actions[action]) { d->updateAction(action); return d->actions[action]; } const QString text = QWebEnginePagePrivate::actionText(action); QString iconName; switch (action) { case Back: iconName = QStringLiteral("go-previous"); break; case Forward: iconName = QStringLiteral("go-next"); break; case Stop: iconName = QStringLiteral("process-stop"); break; case Reload: iconName = QStringLiteral("view-refresh"); break; case ReloadAndBypassCache: iconName = QStringLiteral("view-refresh"); break; case Cut: iconName = QStringLiteral("edit-cut"); break; case Copy: iconName = QStringLiteral("edit-copy"); break; case Paste: iconName = QStringLiteral("edit-paste"); break; case Undo: iconName = QStringLiteral("edit-undo"); break; case Redo: iconName = QStringLiteral("edit-redo"); break; case SelectAll: iconName = QStringLiteral("edit-select-all"); break; case PasteAndMatchStyle: iconName = QStringLiteral("edit-paste"); break; case OpenLinkInThisWindow: case OpenLinkInNewWindow: case OpenLinkInNewTab: case CopyLinkToClipboard: case DownloadLinkToDisk: case CopyImageToClipboard: case CopyImageUrlToClipboard: case DownloadImageToDisk: case CopyMediaUrlToClipboard: case ToggleMediaControls: case ToggleMediaLoop: break; case ToggleMediaPlayPause: iconName = QStringLiteral("media-playback-start"); break; case ToggleMediaMute: iconName = QStringLiteral("audio-volume-muted"); break; case DownloadMediaToDisk: case InspectElement: break; case ExitFullScreen: iconName = QStringLiteral("view-fullscreen"); break; case RequestClose: iconName = QStringLiteral("window-close"); break; case Unselect: iconName = QStringLiteral("edit-select-none"); break; case SavePage: iconName = QStringLiteral("document-save"); break; case OpenLinkInNewBackgroundTab: break; case ViewSource: break; case ToggleBold: iconName = QStringLiteral("format-text-bold"); break; case ToggleItalic: iconName = QStringLiteral("format-text-italic"); break; case ToggleUnderline: iconName = QStringLiteral("format-text-underline"); break; case ToggleStrikethrough: iconName = QStringLiteral("format-text-strikethrough"); break; case AlignLeft: break; case AlignCenter: break; case AlignRight: break; case AlignJustified: break; case Indent: iconName = QStringLiteral("format-indent-more"); break; case Outdent: iconName = QStringLiteral("format-indent-less"); break; case InsertOrderedList: case InsertUnorderedList: case ChangeTextDirectionLTR: case ChangeTextDirectionRTL: break; case NoWebAction: case WebActionCount: Q_UNREACHABLE(); break; } QQuickWebEngineAction *retVal = new QQuickWebEngineAction(action, text, iconName, false, this); d->actions[action] = retVal; d->updateAction(action); return retVal; } 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 QQuickWebEngineView::componentComplete() { QQuickItem::componentComplete(); Q_D(QQuickWebEngineView); d->initializeProfile(); #if QT_CONFIG(accessibility) // Enable accessibility via a dynamic QQmlProperty, instead of using private API call // QQuickAccessibleAttached::qmlAttachedProperties(this). The qmlContext is required, otherwise // it is not possible to reference attached properties. QQmlContext *qmlContext = QQmlEngine::contextForObject(this); QQmlProperty role(this, QStringLiteral("Accessible.role"), qmlContext); role.write(QAccessible::Grouping); #endif // QT_CONFIG(accessibility) QTimer::singleShot(0, this, &QQuickWebEngineView::lazyInitialize); } void QQuickWebEngineView::lazyInitialize() { Q_D(QQuickWebEngineView); d->ensureContentsAdapter(); } QQuickWebEngineView::LifecycleState QQuickWebEngineView::lifecycleState() const { Q_D(const QQuickWebEngineView); return static_cast(d->adapter->lifecycleState()); } void QQuickWebEngineView::setLifecycleState(LifecycleState state) { Q_D(QQuickWebEngineView); d->adapter->setLifecycleState(static_cast(state)); } QQuickWebEngineView::LifecycleState QQuickWebEngineView::recommendedState() const { Q_D(const QQuickWebEngineView); return static_cast(d->adapter->recommendedState()); } QQuickContextMenuBuilder::QQuickContextMenuBuilder(QWebEngineContextMenuRequest *request, QQuickWebEngineView *view, QObject *menu) : QtWebEngineCore::RenderViewContextMenuQt(request), m_view(view), m_menu(menu) { } void QQuickContextMenuBuilder::appendExtraItems(QQmlEngine *engine) { Q_UNUSED(engine); m_view->d_ptr->ui()->addMenuSeparator(m_menu); if (QObject *menuExtras = m_view->d_ptr->contextMenuExtraItems->create(qmlContext(m_view))) { menuExtras->setParent(m_menu); QQmlListReference entries(m_menu, defaultPropertyName(m_menu)); if (entries.isValid()) entries.append(menuExtras); } } bool QQuickContextMenuBuilder::hasInspector() { return m_view->d_ptr->adapter->hasInspector(); } bool QQuickContextMenuBuilder::isFullScreenMode() { return m_view->d_ptr->isFullScreenMode(); } void QQuickContextMenuBuilder::addMenuItem(ContextMenuItem menuItem) { QQuickWebEngineAction *action = nullptr; switch (menuItem) { case ContextMenuItem::Back: action = m_view->action(QQuickWebEngineView::Back); break; case ContextMenuItem::Forward: action = m_view->action(QQuickWebEngineView::Forward); break; case ContextMenuItem::Reload: action = m_view->action(QQuickWebEngineView::Reload); break; case ContextMenuItem::Cut: action = m_view->action(QQuickWebEngineView::Cut); break; case ContextMenuItem::Copy: action = m_view->action(QQuickWebEngineView::Copy); break; case ContextMenuItem::Paste: action = m_view->action(QQuickWebEngineView::Paste); break; case ContextMenuItem::Undo: action = m_view->action(QQuickWebEngineView::Undo); break; case ContextMenuItem::Redo: action = m_view->action(QQuickWebEngineView::Redo); break; case ContextMenuItem::SelectAll: action = m_view->action(QQuickWebEngineView::SelectAll); break; case ContextMenuItem::PasteAndMatchStyle: action = m_view->action(QQuickWebEngineView::PasteAndMatchStyle); break; case ContextMenuItem::OpenLinkInNewWindow: action = m_view->action(QQuickWebEngineView::OpenLinkInNewWindow); break; case ContextMenuItem::OpenLinkInNewTab: action = m_view->action(QQuickWebEngineView::OpenLinkInNewTab); break; case ContextMenuItem::CopyLinkToClipboard: action = m_view->action(QQuickWebEngineView::CopyLinkToClipboard); break; case ContextMenuItem::DownloadLinkToDisk: action = m_view->action(QQuickWebEngineView::DownloadLinkToDisk); break; case ContextMenuItem::CopyImageToClipboard: action = m_view->action(QQuickWebEngineView::CopyImageToClipboard); break; case ContextMenuItem::CopyImageUrlToClipboard: action = m_view->action(QQuickWebEngineView::CopyImageUrlToClipboard); break; case ContextMenuItem::DownloadImageToDisk: action = m_view->action(QQuickWebEngineView::DownloadImageToDisk); break; case ContextMenuItem::CopyMediaUrlToClipboard: action = m_view->action(QQuickWebEngineView::CopyMediaUrlToClipboard); break; case ContextMenuItem::ToggleMediaControls: action = m_view->action(QQuickWebEngineView::ToggleMediaControls); break; case ContextMenuItem::ToggleMediaLoop: action = m_view->action(QQuickWebEngineView::ToggleMediaLoop); break; case ContextMenuItem::DownloadMediaToDisk: action = m_view->action(QQuickWebEngineView::DownloadMediaToDisk); break; case ContextMenuItem::InspectElement: action = m_view->action(QQuickWebEngineView::InspectElement); break; case ContextMenuItem::ExitFullScreen: action = m_view->action(QQuickWebEngineView::ExitFullScreen); break; case ContextMenuItem::SavePage: action = m_view->action(QQuickWebEngineView::SavePage); break; case ContextMenuItem::ViewSource: action = m_view->action(QQuickWebEngineView::ViewSource); break; case ContextMenuItem::SpellingSuggestions: { QPointer thisRef(m_view); for (int i = 0; i < m_contextData->spellCheckerSuggestions().size() && i < 4; i++) { action = new QQuickWebEngineAction(m_menu); QString replacement = m_contextData->spellCheckerSuggestions().at(i); QObject::connect(action, &QQuickWebEngineAction::triggered, [thisRef, replacement] { thisRef->replaceMisspelledWord(replacement); }); action->d_ptr->m_text = replacement; action->d_ptr->m_enabled = true; m_view->d_ptr->ui()->addMenuItem(action, m_menu); } return; } case ContextMenuItem::Separator: m_view->d_ptr->ui()->addMenuSeparator(m_menu); return; } // Set enabled property directly with avoiding binding loops caused by its notifier signal. action->d_ptr->m_enabled = isMenuItemEnabled(menuItem); m_view->d_ptr->ui()->addMenuItem(action, m_menu); } bool QQuickContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem) { switch (menuItem) { case ContextMenuItem::Back: return m_view->canGoBack(); case ContextMenuItem::Forward: return m_view->canGoForward(); case ContextMenuItem::Reload: return true; case ContextMenuItem::Cut: return m_contextData->editFlags() & QWebEngineContextMenuRequest::CanCut; case ContextMenuItem::Copy: return m_contextData->editFlags() & QWebEngineContextMenuRequest::CanCopy; case ContextMenuItem::Paste: return m_contextData->editFlags() & QWebEngineContextMenuRequest::CanPaste; case ContextMenuItem::Undo: return m_contextData->editFlags() & QWebEngineContextMenuRequest::CanUndo; case ContextMenuItem::Redo: return m_contextData->editFlags() & QWebEngineContextMenuRequest::CanRedo; case ContextMenuItem::SelectAll: return m_contextData->editFlags() & QWebEngineContextMenuRequest::CanSelectAll; case ContextMenuItem::PasteAndMatchStyle: return m_contextData->editFlags() & QWebEngineContextMenuRequest::CanPaste; case ContextMenuItem::OpenLinkInNewWindow: case ContextMenuItem::OpenLinkInNewTab: case ContextMenuItem::CopyLinkToClipboard: case ContextMenuItem::DownloadLinkToDisk: case ContextMenuItem::CopyImageToClipboard: case ContextMenuItem::CopyImageUrlToClipboard: case ContextMenuItem::DownloadImageToDisk: case ContextMenuItem::CopyMediaUrlToClipboard: case ContextMenuItem::ToggleMediaControls: case ContextMenuItem::ToggleMediaLoop: case ContextMenuItem::DownloadMediaToDisk: case ContextMenuItem::InspectElement: case ContextMenuItem::ExitFullScreen: case ContextMenuItem::SavePage: return true; case ContextMenuItem::ViewSource: return m_view->d_ptr->adapter->canViewSource(); case ContextMenuItem::SpellingSuggestions: case ContextMenuItem::Separator: return true; } Q_UNREACHABLE(); } void QQuickWebEngineView::setTouchHandleDelegate(QQmlComponent *delegate) { if (d_ptr->m_touchHandleDelegate != delegate) { d_ptr->m_touchHandleDelegate = delegate; d_ptr->webContentsAdapter()->resetTouchSelectionController(); emit touchHandleDelegateChanged(); } } QQmlComponent *QQuickWebEngineView::touchHandleDelegate() const { return d_ptr->m_touchHandleDelegate; } QWebEngineFrame QQuickWebEngineView::mainFrame() { Q_D(QQuickWebEngineView); return QWebEngineFrame(d->adapter, d->adapter->mainFrameId()); } QWebEngineFrame QQuickWebEngineView::findFrameByName(const QString &name) { Q_D(QQuickWebEngineView); auto maybeId = d->adapter->findFrameIdByName(name); return QWebEngineFrame(d->adapter, maybeId.value_or(WebContentsAdapter::kInvalidFrameId)); } void QQuickWebEngineView::save(const QString &filePath, QWebEngineDownloadRequest::SavePageFormat format) const { Q_D(const QQuickWebEngineView); d->adapter->save(filePath, format); } QT_END_NAMESPACE #include "moc_qquickwebengineview_p.cpp" #include "moc_qquickwebengineforeigntypes_p.cpp"