From 2a4a5b2ec17189d4ea8fa783cf219c65560e81f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= <juri.valdmann@qt.io> Date: Mon, 15 Jan 2018 17:57:05 +0100 Subject: [PATCH] Add support for registerProtocolHandler Extend initialization of URLRequestContextGetterQt to create a content::ProtocolHandlerRegistry for each content::BrowserContext and add the registry's URL request interceptor to the front of the interceptor chain. Implement methods in WebContentsDelegateQt to add/remove protocol handlers to/from the ProtocolHandlerRegistry. Add permission request signal and classes for core, quick and widgets. Add widgets autotest. Add signal handlers to quicknanobrowser and simplebrowser. Task-number: QTBUG-62783 Change-Id: I808e7eb9a1cb4d7216686deed4895de14fe46310 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> --- .../quicknanobrowser/BrowserWindow.qml | 5 + .../simplebrowser/webpage.cpp | 17 +++ .../webenginewidgets/simplebrowser/webpage.h | 2 + src/core/core_chromium.pri | 3 + src/core/qtwebengine_sources.gni | 6 + ...r_protocol_handler_permission_controller.h | 62 ++++++++++ ...col_handler_permission_controller_impl.cpp | 65 ++++++++++ ...tocol_handler_permission_controller_impl.h | 69 +++++++++++ src/core/url_request_context_getter_qt.cpp | 15 +++ src/core/url_request_context_getter_qt.h | 2 + src/core/web_contents_adapter_client.h | 2 + src/core/web_contents_delegate_qt.cpp | 36 ++++++ src/core/web_contents_delegate_qt.h | 2 + src/webengine/api/qquickwebengineview.cpp | 33 +++++ src/webengine/api/qquickwebengineview_p.h | 21 ++++ src/webengine/api/qquickwebengineview_p_p.h | 1 + src/webengine/doc/src/external-resources.qdoc | 5 + src/webengine/doc/src/webengineview_lgpl.qdoc | 49 ++++++++ src/webengine/plugin/plugin.cpp | 2 + src/webenginewidgets/api/qwebenginepage.cpp | 20 +++ src/webenginewidgets/api/qwebenginepage.h | 2 + src/webenginewidgets/api/qwebenginepage_p.h | 1 + ...gisterprotocolhandlerpermissionrequest.cpp | 115 ++++++++++++++++++ ...registerprotocolhandlerpermissionrequest.h | 73 +++++++++++ src/webenginewidgets/webenginewidgets.pro | 2 + tests/auto/quick/publicapi/tst_publicapi.cpp | 6 + .../widgets/qwebenginepage/qwebenginepage.pro | 1 + .../qwebenginepage/tst_qwebenginepage.cpp | 65 ++++++++++ tools/scripts/take_snapshot.py | 3 + 29 files changed, 685 insertions(+) create mode 100644 src/core/register_protocol_handler_permission_controller.h create mode 100644 src/core/register_protocol_handler_permission_controller_impl.cpp create mode 100644 src/core/register_protocol_handler_permission_controller_impl.h create mode 100644 src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.cpp create mode 100644 src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.h diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml index be1e42c73..15a8d96fe 100644 --- a/examples/webengine/quicknanobrowser/BrowserWindow.qml +++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml @@ -445,6 +445,11 @@ ApplicationWindow { request.reject(); } + onRegisterProtocolHandlerPermissionRequested: { + print("accepting registerProtocolHandler permission request for " + request.protocol + " from " + request.origin); + request.accept(); + } + onRenderProcessTerminated: { var status = ""; switch (terminationStatus) { diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp index 903956419..ef55fd33d 100644 --- a/examples/webenginewidgets/simplebrowser/webpage.cpp +++ b/examples/webenginewidgets/simplebrowser/webpage.cpp @@ -63,6 +63,7 @@ WebPage::WebPage(QWebEngineProfile *profile, QObject *parent) { connect(this, &QWebEnginePage::authenticationRequired, this, &WebPage::handleAuthenticationRequired); connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, &WebPage::handleProxyAuthenticationRequired); + connect(this, &QWebEnginePage::registerProtocolHandlerPermissionRequested, this, &WebPage::handleRegisterProtocolHandlerPermissionRequested); } bool WebPage::certificateError(const QWebEngineCertificateError &error) @@ -141,3 +142,19 @@ void WebPage::handleProxyAuthenticationRequired(const QUrl &, QAuthenticator *au *auth = QAuthenticator(); } } + +//! [registerProtocolHandlerPermissionRequested] +void WebPage::handleRegisterProtocolHandlerPermissionRequested(QWebEngineRegisterProtocolHandlerPermissionRequest request) +{ + auto answer = QMessageBox::question( + view()->window(), + tr("Permission Request"), + tr("Allow %1 to open all %2 links?") + .arg(request.origin().host()) + .arg(request.protocol())); + if (answer == QMessageBox::Yes) + request.accept(); + else + request.reject(); +} +//! [registerProtocolHandlerPermissionRequested] diff --git a/examples/webenginewidgets/simplebrowser/webpage.h b/examples/webenginewidgets/simplebrowser/webpage.h index 797943249..d44c79358 100644 --- a/examples/webenginewidgets/simplebrowser/webpage.h +++ b/examples/webenginewidgets/simplebrowser/webpage.h @@ -52,6 +52,7 @@ #define WEBPAGE_H #include <QWebEnginePage> +#include <QWebEngineRegisterProtocolHandlerPermissionRequest> class WebPage : public QWebEnginePage { @@ -66,6 +67,7 @@ protected: private slots: void handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth); void handleProxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth, const QString &proxyHost); + void handleRegisterProtocolHandlerPermissionRequested(QWebEngineRegisterProtocolHandlerPermissionRequest request); }; #endif // WEBPAGE_H diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index 1b2f2edb1..e62ffdbfb 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -79,6 +79,7 @@ SOURCES = \ qrc_protocol_handler_qt.cpp \ quota_permission_context_qt.cpp \ quota_permission_controller_impl.cpp \ + register_protocol_handler_permission_controller_impl.cpp \ render_view_context_menu_qt.cpp \ render_view_observer_host_qt.cpp \ render_widget_host_view_qt.cpp \ @@ -163,6 +164,8 @@ HEADERS = \ quota_permission_context_qt.h \ quota_permission_controller.h \ quota_permission_controller_impl.h \ + register_protocol_handler_permission_controller.h \ + register_protocol_handler_permission_controller_impl.h \ render_view_context_menu_qt.h \ render_view_observer_host_qt.h \ render_widget_host_view_qt.h \ diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni index 6d17838a6..bdedf11d3 100644 --- a/src/core/qtwebengine_sources.gni +++ b/src/core/qtwebengine_sources.gni @@ -43,6 +43,12 @@ source_set("qtwebengine_sources") { "//extensions/features:features", ] sources = [ + "//chrome/common/custom_handlers/protocol_handler.cc", + "//chrome/common/custom_handlers/protocol_handler.h", + "//chrome/browser/custom_handlers/protocol_handler_registry.cc", + "//chrome/browser/custom_handlers/protocol_handler_registry.h", + "//chrome/browser/custom_handlers/protocol_handler_registry_factory.cc", + "//chrome/browser/custom_handlers/protocol_handler_registry_factory.h", "//chrome/browser/media/webrtc/desktop_media_list.h", "//chrome/browser/media/webrtc/desktop_streams_registry.cc", "//chrome/browser/media/webrtc/desktop_streams_registry.h", diff --git a/src/core/register_protocol_handler_permission_controller.h b/src/core/register_protocol_handler_permission_controller.h new file mode 100644 index 000000000..54e16f569 --- /dev/null +++ b/src/core/register_protocol_handler_permission_controller.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +#ifndef REGISTER_PROTOCOL_HANDLER_PERMISSION_CONTROLLER_H +#define REGISTER_PROTOCOL_HANDLER_PERMISSION_CONTROLLER_H + +#include "permission_controller.h" + +namespace QtWebEngineCore { + +class QWEBENGINE_EXPORT RegisterProtocolHandlerPermissionController : public PermissionController { +public: + RegisterProtocolHandlerPermissionController(QUrl origin, QString protocol) + : PermissionController(std::move(origin)) + , m_protocol(std::move(protocol)) + {} + + QString protocol() const { return m_protocol; } + +private: + QString m_protocol; +}; + +} // namespace QtWebEngineCore + +#endif // REGISTER_PROTOCOL_HANDLER_PERMISSION_CONTROLLER_H diff --git a/src/core/register_protocol_handler_permission_controller_impl.cpp b/src/core/register_protocol_handler_permission_controller_impl.cpp new file mode 100644 index 000000000..96f2edb87 --- /dev/null +++ b/src/core/register_protocol_handler_permission_controller_impl.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "register_protocol_handler_permission_controller_impl.h" + +#include "type_conversion.h" + +namespace QtWebEngineCore { + +RegisterProtocolHandlerPermissionControllerImpl::RegisterProtocolHandlerPermissionControllerImpl( + ProtocolHandlerRegistry *registry, + ProtocolHandler handler) + : RegisterProtocolHandlerPermissionController( + toQt(handler.url()), + toQt(handler.protocol())) + , m_registry(registry) + , m_handler(handler) +{} + +void RegisterProtocolHandlerPermissionControllerImpl::accepted() +{ + m_registry->OnAcceptRegisterProtocolHandler(m_handler); +} + +void RegisterProtocolHandlerPermissionControllerImpl::rejected() +{ + m_registry->OnIgnoreRegisterProtocolHandler(m_handler); +} + +} // namespace QtWebEngineCore diff --git a/src/core/register_protocol_handler_permission_controller_impl.h b/src/core/register_protocol_handler_permission_controller_impl.h new file mode 100644 index 000000000..57a094fd9 --- /dev/null +++ b/src/core/register_protocol_handler_permission_controller_impl.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +#ifndef REGISTER_PROTOCOL_HANDLER_PERMISSION_CONTROLLER_IMPL_H +#define REGISTER_PROTOCOL_HANDLER_PERMISSION_CONTROLLER_IMPL_H + +#include "register_protocol_handler_permission_controller.h" + +#include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/common/custom_handlers/protocol_handler.h" + +class ProtocolHandlerRegistry; + +namespace QtWebEngineCore { + +class RegisterProtocolHandlerPermissionControllerImpl final : public RegisterProtocolHandlerPermissionController { +public: + RegisterProtocolHandlerPermissionControllerImpl( + ProtocolHandlerRegistry *registry, + ProtocolHandler handler); + +protected: + void accepted() override; + void rejected() override; + +private: + ProtocolHandlerRegistry *m_registry; + ProtocolHandler m_handler; +}; + +} // namespace QtWebEngineCore + +#endif // REGISTER_PROTOCOL_HANDLER_PERMISSION_CONTROLLER_IMPL_H diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index fd0f24735..2622cb09e 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -44,6 +44,7 @@ #include "base/strings/string_util.h" #include "base/task_scheduler/post_task.h" #include "base/threading/sequenced_worker_pool.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h" #include "content/network/proxy_service_mojo.h" #include "content/public/browser/browser_thread.h" @@ -81,6 +82,7 @@ #include "api/qwebengineurlschemehandler.h" #include "browser_context_adapter.h" +#include "browser_context_qt.h" #include "custom_protocol_handler.h" #include "cookie_monster_delegate_qt.h" #include "content_client_qt.h" @@ -111,6 +113,14 @@ URLRequestContextGetterQt::URLRequestContextGetterQt(QSharedPointer<BrowserConte { std::swap(m_protocolHandlers, *protocolHandlers); + // The ProtocolHandlerRegistry and it's JobInterceptorFactory need to be + // created on the UI thread: + ProtocolHandlerRegistry* protocolHandlerRegistry = + ProtocolHandlerRegistryFactory::GetForBrowserContext(browserContext->browserContext()); + DCHECK(protocolHandlerRegistry); + m_protocolHandlerInterceptor = + protocolHandlerRegistry->CreateJobInterceptorFactory(); + QMutexLocker lock(&m_mutex); m_cookieDelegate->setClient(browserContext->cookieStore()); setFullConfiguration(browserContext); @@ -583,6 +593,11 @@ void URLRequestContextGetterQt::generateJobFactory() m_requestInterceptors.clear(); + if (m_protocolHandlerInterceptor) { + m_protocolHandlerInterceptor->Chain(std::move(topJobFactory)); + topJobFactory = std::move(m_protocolHandlerInterceptor); + } + m_jobFactory = std::move(topJobFactory); m_urlRequestContext->set_job_factory(m_jobFactory.get()); diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h index 4a97a1398..fd80d62c2 100644 --- a/src/core/url_request_context_getter_qt.h +++ b/src/core/url_request_context_getter_qt.h @@ -45,6 +45,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/url_constants.h" @@ -120,6 +121,7 @@ private: std::unique_ptr<NetworkDelegateQt> m_networkDelegate; std::unique_ptr<net::URLRequestContextStorage> m_storage; std::unique_ptr<net::URLRequestJobFactory> m_jobFactory; + std::unique_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> m_protocolHandlerInterceptor; net::URLRequestJobFactoryImpl *m_baseJobFactory; std::unique_ptr<net::DhcpProxyScriptFetcherFactory> m_dhcpProxyScriptFetcherFactory; scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate; diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index dfb2dddcc..495be3d84 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -65,6 +65,7 @@ class ColorChooserController; class FilePickerController; class JavaScriptDialogController; class QuotaPermissionController; +class RegisterProtocolHandlerPermissionController; class RenderWidgetHostViewQt; class RenderWidgetHostViewQtDelegate; class RenderWidgetHostViewQtDelegateClient; @@ -437,6 +438,7 @@ public: virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0; virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0; virtual void runQuotaPermissionRequest(QSharedPointer<QuotaPermissionController>) = 0; + virtual void runRegisterProtocolHandlerPermissionRequest(QSharedPointer<RegisterProtocolHandlerPermissionController>) = 0; virtual WebEngineSettings *webEngineSettings() const = 0; virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) = 0; virtual void hideValidationMessage() = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 09cca943e..3d2337884 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -58,9 +58,12 @@ #include "web_contents_adapter_p.h" #include "web_engine_context.h" #include "web_engine_settings.h" +#include "register_protocol_handler_permission_controller_impl.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "components/web_cache/browser/web_cache_manager.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" @@ -608,6 +611,39 @@ bool WebContentsDelegateQt::CheckMediaAccessPermission(content::WebContents *web } } +void WebContentsDelegateQt::RegisterProtocolHandler(content::WebContents *webContents, const std::string &protocol, const GURL &url, bool) +{ + content::BrowserContext *context = webContents->GetBrowserContext(); + if (context->IsOffTheRecord()) + return; + + ProtocolHandler handler = + ProtocolHandler::CreateProtocolHandler(protocol, url); + + ProtocolHandlerRegistry *registry = + ProtocolHandlerRegistryFactory::GetForBrowserContext(context); + if (registry->SilentlyHandleRegisterHandlerRequest(handler)) + return; + + QSharedPointer<RegisterProtocolHandlerPermissionController> controller( + new RegisterProtocolHandlerPermissionControllerImpl(registry, handler)); + m_viewClient->runRegisterProtocolHandlerPermissionRequest(std::move(controller)); +} + +void WebContentsDelegateQt::UnregisterProtocolHandler(content::WebContents *webContents, const std::string &protocol, const GURL &url, bool) +{ + content::BrowserContext* context = webContents->GetBrowserContext(); + if (context->IsOffTheRecord()) + return; + + ProtocolHandler handler = + ProtocolHandler::CreateProtocolHandler(protocol, url); + + ProtocolHandlerRegistry* registry = + ProtocolHandlerRegistryFactory::GetForBrowserContext(context); + registry->RemoveHandler(handler); +} + FaviconManager *WebContentsDelegateQt::faviconManager() { return m_faviconManager.data(); diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 8a3331163..e649ca727 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -128,6 +128,8 @@ public: void MoveValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view) override; void BeforeUnloadFired(content::WebContents* tab, bool proceed, bool* proceed_to_fire_unload) override; bool CheckMediaAccessPermission(content::WebContents *web_contents, const GURL& security_origin, content::MediaStreamType type) override; + void RegisterProtocolHandler(content::WebContents* web_contents, const std::string& protocol, const GURL& url, bool user_gesture) override; + void UnregisterProtocolHandler(content::WebContents* web_contents, const std::string& protocol, const GURL& url, bool user_gesture) override; // WebContentsObserver overrides void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override; diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 617b999da..91ae20481 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -46,6 +46,7 @@ #include "file_picker_controller.h" #include "javascript_dialog_controller.h" #include "quota_permission_controller.h" +#include "register_protocol_handler_permission_controller.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginecertificateerror_p.h" #include "qquickwebenginecontextmenurequest_p.h" @@ -599,6 +600,13 @@ void QQuickWebEngineViewPrivate::runQuotaPermissionRequest(QSharedPointer<QtWebE Q_EMIT q->quotaPermissionRequested(request); } +void QQuickWebEngineViewPrivate::runRegisterProtocolHandlerPermissionRequest(QSharedPointer<RegisterProtocolHandlerPermissionController> controller) +{ + Q_Q(QQuickWebEngineView); + QQuickWebEngineRegisterProtocolHandlerPermissionRequest request(std::move(controller)); + Q_EMIT q->registerProtocolHandlerPermissionRequested(request); +} + QObject *QQuickWebEngineViewPrivate::accessibilityParentObject() { Q_Q(QQuickWebEngineView); @@ -1828,6 +1836,31 @@ qint64 QQuickWebEngineQuotaPermissionRequest::requestedSize() const return d_ptr->requestedSize(); } +QQuickWebEngineRegisterProtocolHandlerPermissionRequest::QQuickWebEngineRegisterProtocolHandlerPermissionRequest( + QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController> d_ptr) + : d_ptr(std::move(d_ptr)) +{} + +void QQuickWebEngineRegisterProtocolHandlerPermissionRequest::accept() +{ + d_ptr->accept(); +} + +void QQuickWebEngineRegisterProtocolHandlerPermissionRequest::reject() +{ + d_ptr->reject(); +} + +QUrl QQuickWebEngineRegisterProtocolHandlerPermissionRequest::origin() const +{ + return d_ptr->origin(); +} + +QString QQuickWebEngineRegisterProtocolHandlerPermissionRequest::protocol() const +{ + return d_ptr->protocol(); +} + QQuickContextMenuBuilder::QQuickContextMenuBuilder(const QtWebEngineCore::WebEngineContextMenuData &data, QQuickWebEngineView *view, QObject *menu) diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 8bda609c0..5b018b8a8 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -59,6 +59,7 @@ namespace QtWebEngineCore { class QuotaPermissionController; + class RegisterProtocolHandlerPermissionController; } @@ -123,6 +124,24 @@ private: QSharedPointer<QtWebEngineCore::QuotaPermissionController> d_ptr; }; +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineRegisterProtocolHandlerPermissionRequest { + Q_GADGET + Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL) + Q_PROPERTY(QString protocol READ protocol CONSTANT FINAL) +public: + QQuickWebEngineRegisterProtocolHandlerPermissionRequest() {} + QQuickWebEngineRegisterProtocolHandlerPermissionRequest( + QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController>); + + Q_INVOKABLE void accept(); + Q_INVOKABLE void reject(); + QUrl origin() const; + QString protocol() const; + +private: + QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController> d_ptr; +}; + #define LATEST_WEBENGINEVIEW_REVISION 7 class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { @@ -567,6 +586,7 @@ Q_SIGNALS: Q_REVISION(7) void geometryChangeRequested(const QRect &geometry, const QRect &frameGeometry); Q_REVISION(7) void inspectedViewChanged(); Q_REVISION(7) void devToolsViewChanged(); + Q_REVISION(7) void registerProtocolHandlerPermissionRequested(const QQuickWebEngineRegisterProtocolHandlerPermissionRequest &request); #ifdef ENABLE_QML_TESTSUPPORT_API void testSupportChanged(); @@ -597,5 +617,6 @@ QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickWebEngineView) Q_DECLARE_METATYPE(QQuickWebEngineFullScreenRequest) Q_DECLARE_METATYPE(QQuickWebEngineQuotaPermissionRequest) +Q_DECLARE_METATYPE(QQuickWebEngineRegisterProtocolHandlerPermissionRequest) #endif // QQUICKWEBENGINEVIEW_P_H diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index cfe99a0d4..1b718a3da 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -132,6 +132,7 @@ public: void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override; void runMouseLockPermissionRequest(const QUrl &securityOrigin) override; void runQuotaPermissionRequest(QSharedPointer<QtWebEngineCore::QuotaPermissionController>) override; + void runRegisterProtocolHandlerPermissionRequest(QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController>) override; QObject *accessibilityParentObject() override; QtWebEngineCore::WebEngineSettings *webEngineSettings() const override; void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) override; diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc index c2faaa8d4..7ff6eea6b 100644 --- a/src/webengine/doc/src/external-resources.qdoc +++ b/src/webengine/doc/src/external-resources.qdoc @@ -141,3 +141,8 @@ \externalpage https://wiki.greasespot.net/Metadata_Block#.40name \title Metadata Block */ + +/*! + \externalpage https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler + \title registerProtocolHandler +*/ diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc index c6985b082..104397bf7 100644 --- a/src/webengine/doc/src/webengineview_lgpl.qdoc +++ b/src/webengine/doc/src/webengineview_lgpl.qdoc @@ -1356,6 +1356,55 @@ Rejects a quota permission request. */ +/*! + \qmlsignal WebEngineView::registerProtocolHandlerPermissionRequested(RegisterProtocolHandlerPermissionRequest request) + \since QtWebEngine 1.7 + + This signal is emitted when the web page tries to register a custom protocol + using the \l registerProtocolHandler API. + + \sa RegisterProtocolHandlerPermissionRequest +*/ + +/*! + \qmltype RegisterProtocolHandlerPermissionRequest + \instantiates QQuickWebEngineRegisterProtocolHandlerPermissionRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.7 + \brief The RegisterProtocolHandlerPermissionRequest type enables accepting + or rejecting requests from the \l registerProtocolHandler API. + + \sa WebEngineView::registerProtocolHandlerPermissionRequested() +*/ + +/*! + \qmlproperty url RegisterProtocolHandlerPermissionRequest::origin + \brief The URL template for the protocol handler. + + This is the second parameter from the \l registerProtocolHandler call. +*/ + +/*! + \qmlproperty string RegisterProtocolHandlerPermissionRequest::protocol + \brief The URL scheme for the protocol handler. + + This is the first parameter from the \l registerProtocolHandler call. +*/ + +/*! + \qmlmethod void RegisterProtocolHandlerPermissionRequest::accept() + \brief Accepts the request. + + Subsequent calls to accept() and reject() are ignored. +*/ + +/*! + \qmlmethod void RegisterProtocolHandlerPermissionRequest::reject() + \brief Accepts the request. + + Subsequent calls to accept() and reject() are ignored. +*/ + /*! \qmlsignal WebEngineView::geometryChangeRequested(rect geometry, rect frameGeometry) \since QtWebEngine 1.7 diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index 5f9d16158..a9f406d49 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -139,6 +139,8 @@ public: msgUncreatableType("FormValidationMessageRequest")); qmlRegisterUncreatableType<QQuickWebEngineQuotaPermissionRequest>(uri, 1, 7, "QuotaPermissionRequest", tr("Cannot create a separate instance of QuotaPermissionRequest")); + qmlRegisterUncreatableType<QQuickWebEngineRegisterProtocolHandlerPermissionRequest>(uri, 1, 7, "RegisterProtocolHandlerPermissionRequest", + tr("Cannot create a separate instance of RegisterProtocolHandlerPermissionRequest")); } private: diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 67d55b20f..ec35ea6ce 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -54,6 +54,7 @@ #include "qwebengineprofile.h" #include "qwebengineprofile_p.h" #include "qwebenginequotapermissionrequest.h" +#include "qwebengineregisterprotocolhandlerpermissionrequest.h" #include "qwebenginescriptcollection_p.h" #include "qwebenginesettings.h" #include "qwebengineview.h" @@ -578,6 +579,13 @@ void QWebEnginePagePrivate::runQuotaPermissionRequest(QSharedPointer<QtWebEngine Q_EMIT q->quotaPermissionRequested(request); } +void QWebEnginePagePrivate::runRegisterProtocolHandlerPermissionRequest(QSharedPointer<RegisterProtocolHandlerPermissionController> controller) +{ + Q_Q(QWebEnginePage); + QWebEngineRegisterProtocolHandlerPermissionRequest request(std::move(controller)); + Q_EMIT q->registerProtocolHandlerPermissionRequested(request); +} + QObject *QWebEnginePagePrivate::accessibilityParentObject() { return view; @@ -749,6 +757,18 @@ QWebEnginePage::QWebEnginePage(QObject* parent) The request object \a request can be used to accept or reject the request. */ +/*! + \fn QWebEnginePage::registerProtocolHandlerPermissionRequested(QWebEngineRegisterProtocolHandlerPermissionRequest request) + \since 5.11 + + This signal is emitted when the web page tries to register a custom protocol + using the \l registerProtocolHandler API. + + The request object \a request can be used to accept or reject the request: + + \snippet webenginewidgets/simplebrowser/webpage.cpp registerProtocolHandlerPermissionRequested +*/ + /*! \fn void QWebEnginePage::pdfPrintingFinished(const QString &filePath, bool success) \since 5.9 diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index 7ce72258b..d716765fe 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -66,6 +66,7 @@ class QWebEnginePage; class QWebEnginePagePrivate; class QWebEngineProfile; class QWebEngineQuotaPermissionRequest; +class QWebEngineRegisterProtocolHandlerPermissionRequest; class QWebEngineScriptCollection; class QWebEngineSettings; @@ -338,6 +339,7 @@ Q_SIGNALS: void featurePermissionRequestCanceled(const QUrl &securityOrigin, QWebEnginePage::Feature feature); void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest); void quotaPermissionRequested(QWebEngineQuotaPermissionRequest quotaPermissionRequest); + void registerProtocolHandlerPermissionRequested(QWebEngineRegisterProtocolHandlerPermissionRequest request); void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator); void proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost); diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 301028e39..61092fa6a 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -130,6 +130,7 @@ public: void runGeolocationPermissionRequest(const QUrl &securityOrigin) override; void runMouseLockPermissionRequest(const QUrl &securityOrigin) override; void runQuotaPermissionRequest(QSharedPointer<QtWebEngineCore::QuotaPermissionController>) override; + void runRegisterProtocolHandlerPermissionRequest(QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController>) override; QObject *accessibilityParentObject() override; QtWebEngineCore::WebEngineSettings *webEngineSettings() const override; void allowCertificateError(const QSharedPointer<CertificateErrorController> &controller) override; diff --git a/src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.cpp b/src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.cpp new file mode 100644 index 000000000..ad1398daf --- /dev/null +++ b/src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "qwebengineregisterprotocolhandlerpermissionrequest.h" + +#include "register_protocol_handler_permission_controller.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QWebEngineRegisterProtocolHandlerPermissionRequest + \inmodule QtWebEngineWidgets + \since 5.11 + \brief The QWebEngineRegisterProtocolHandlerPermissionRequest type enables + accepting or rejecting requests from the \l registerProtocolHandler API. + + \sa QWebEnginePage::registerProtocolHandlerPermissionRequested +*/ + +static void registerMetaTypes() +{ + qRegisterMetaType<QWebEngineRegisterProtocolHandlerPermissionRequest>(); +} + +Q_CONSTRUCTOR_FUNCTION(registerMetaTypes) + +/*! \fn QWebEngineRegisterProtocolHandlerPermissionRequest::QWebEngineRegisterProtocolHandlerPermissionRequest() + \internal +*/ + +/*! \internal */ +QWebEngineRegisterProtocolHandlerPermissionRequest::QWebEngineRegisterProtocolHandlerPermissionRequest( + QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController> d_ptr) + : d_ptr(std::move(d_ptr)) +{} + +/*! + Rejects the request. + + Subsequent calls to accept() and reject() are ignored. +*/ +void QWebEngineRegisterProtocolHandlerPermissionRequest::reject() +{ + d_ptr->reject(); +} + +/*! + Accepts the request + + Subsequent calls to accept() and reject() are ignored. +*/ +void QWebEngineRegisterProtocolHandlerPermissionRequest::accept() +{ + d_ptr->accept(); +} + +/*! + \property QWebEngineRegisterProtocolHandlerPermissionRequest::origin + \brief The URL template for the protocol handler. + + This is the second parameter from the \l registerProtocolHandler call. +*/ +QUrl QWebEngineRegisterProtocolHandlerPermissionRequest::origin() const +{ + return d_ptr->origin(); +} + +/*! + \property QWebEngineRegisterProtocolHandlerPermissionRequest::protocol + \brief The URL scheme for the protocol handler. + + This is the first parameter from the \l registerProtocolHandler call. +*/ +QString QWebEngineRegisterProtocolHandlerPermissionRequest::protocol() const +{ + return d_ptr->protocol(); +} + +QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.h b/src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.h new file mode 100644 index 000000000..592eabb34 --- /dev/null +++ b/src/webenginewidgets/api/qwebengineregisterprotocolhandlerpermissionrequest.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +#ifndef QWEBENGINEREGISTERPROTOCOLHANDLERPERMISSIONREQUEST_H +#define QWEBENGINEREGISTERPROTOCOLHANDLERPERMISSIONREQUEST_H + +#include <QtCore/qsharedpointer.h> +#include <QtCore/qurl.h> +#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> + +namespace QtWebEngineCore { + class RegisterProtocolHandlerPermissionController; +} + +QT_BEGIN_NAMESPACE + +class QWEBENGINEWIDGETS_EXPORT QWebEngineRegisterProtocolHandlerPermissionRequest { + Q_GADGET + Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL) + Q_PROPERTY(QString protocol READ protocol CONSTANT FINAL) +public: + QWebEngineRegisterProtocolHandlerPermissionRequest() {} + QWebEngineRegisterProtocolHandlerPermissionRequest( + QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController>); + Q_INVOKABLE void accept(); + Q_INVOKABLE void reject(); + QUrl origin() const; + QString protocol() const; + +private: + QSharedPointer<QtWebEngineCore::RegisterProtocolHandlerPermissionController> d_ptr; +}; + +QT_END_NAMESPACE +Q_DECLARE_METATYPE(QWebEngineRegisterProtocolHandlerPermissionRequest) + +#endif // QWEBENGINEREGISTERPROTOCOLHANDLERPERMISSIONREQUEST_H diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro index 37cb7a1f0..c3132b640 100644 --- a/src/webenginewidgets/webenginewidgets.pro +++ b/src/webenginewidgets/webenginewidgets.pro @@ -20,6 +20,7 @@ SOURCES = \ api/qwebenginepage.cpp \ api/qwebengineprofile.cpp \ api/qwebenginequotapermissionrequest.cpp \ + api/qwebengineregisterprotocolhandlerpermissionrequest.cpp \ api/qwebenginescript.cpp \ api/qwebenginescriptcollection.cpp \ api/qwebenginesettings.cpp \ @@ -39,6 +40,7 @@ HEADERS = \ api/qwebengineprofile.h \ api/qwebengineprofile_p.h \ api/qwebenginequotapermissionrequest.h \ + api/qwebengineregisterprotocolhandlerpermissionrequest.h \ api/qwebenginescriptcollection.h \ api/qwebenginescriptcollection_p.h \ api/qwebenginesettings.h \ diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index 032324e45..52d8a0b41 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -67,6 +67,7 @@ static QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *>() << &QQuickWebEngineSettings::staticMetaObject << &QQuickWebEngineFullScreenRequest::staticMetaObject << &QQuickWebEngineQuotaPermissionRequest::staticMetaObject + << &QQuickWebEngineRegisterProtocolHandlerPermissionRequest::staticMetaObject << &QQuickWebEngineSingleton::staticMetaObject << &QQuickWebEngineAuthenticationDialogRequest::staticMetaObject << &QQuickWebEngineJavaScriptDialogRequest::staticMetaObject @@ -295,6 +296,10 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineQuotaPermissionRequest.origin --> QUrl" << "QQuickWebEngineQuotaPermissionRequest.reject() --> void" << "QQuickWebEngineQuotaPermissionRequest.requestedSize --> qlonglong" + << "QQuickWebEngineRegisterProtocolHandlerPermissionRequest.accept() --> void" + << "QQuickWebEngineRegisterProtocolHandlerPermissionRequest.origin --> QUrl" + << "QQuickWebEngineRegisterProtocolHandlerPermissionRequest.protocol --> QString" + << "QQuickWebEngineRegisterProtocolHandlerPermissionRequest.reject() --> void" << "QQuickWebEngineScript.ApplicationWorld --> ScriptWorldId" << "QQuickWebEngineScript.Deferred --> InjectionPoint" << "QQuickWebEngineScript.DocumentCreation --> InjectionPoint" @@ -653,6 +658,7 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineView.quotaPermissionRequested(QQuickWebEngineQuotaPermissionRequest) --> void" << "QQuickWebEngineView.recentlyAudible --> bool" << "QQuickWebEngineView.recentlyAudibleChanged(bool) --> void" + << "QQuickWebEngineView.registerProtocolHandlerPermissionRequested(QQuickWebEngineRegisterProtocolHandlerPermissionRequest) --> void" << "QQuickWebEngineView.reload() --> void" << "QQuickWebEngineView.reloadAndBypassCache() --> void" << "QQuickWebEngineView.renderProcessTerminated(RenderProcessTerminationStatus,int) --> void" diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro index 47c09e1ce..8e7453827 100644 --- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro +++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro @@ -1,4 +1,5 @@ include(../tests.pri) +include(../../shared/http.pri) QT *= core-private qtConfig(webengine-printing-and-pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index a32d96b3a..fbed89dd3 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -40,6 +40,7 @@ #include <QtTest/QtTest> #include <QTextCharFormat> #include <QWebChannel> +#include <httpserver.h> #include <qnetworkcookiejar.h> #include <qnetworkreply.h> #include <qnetworkrequest.h> @@ -49,6 +50,7 @@ #include <qwebenginepage.h> #include <qwebengineprofile.h> #include <qwebenginequotapermissionrequest.h> +#include <qwebengineregisterprotocolhandlerpermissionrequest.h> #include <qwebenginescript.h> #include <qwebenginescriptcollection.h> #include <qwebenginesettings.h> @@ -210,6 +212,8 @@ private Q_SLOTS: void viewSourceURL_data(); void viewSourceURL(); void proxyConfigWithUnexpectedHostPortPair(); + void registerProtocolHandler_data(); + void registerProtocolHandler(); private: static QPoint elementCenter(QWebEnginePage *page, const QString &id); @@ -4202,6 +4206,67 @@ void tst_QWebEnginePage::proxyConfigWithUnexpectedHostPortPair() QTRY_COMPARE(loadFinishedSpy.count(), 1); } +void tst_QWebEnginePage::registerProtocolHandler_data() +{ + QTest::addColumn<bool>("permission"); + QTest::newRow("accept") << true; + QTest::newRow("reject") << false; +} + +void tst_QWebEnginePage::registerProtocolHandler() +{ + QFETCH(bool, permission); + + HttpServer server; + QWebEnginePage page; + QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished); + QSignalSpy permissionSpy(&page, &QWebEnginePage::registerProtocolHandlerPermissionRequested); + + page.setUrl(server.url("/")); + auto rr1 = waitForRequest(&server); + QVERIFY(rr1); + rr1->setResponseBody(QByteArrayLiteral("<html><body><a id=\"link\" href=\"mailto:foo@bar.com\">some text here</a></body></html>")); + rr1->sendResponse(); + auto rr2 = waitForRequest(&server); + QVERIFY(rr2); + QCOMPARE(rr2->requestMethod(), QByteArrayLiteral("GET")); + QCOMPARE(rr2->requestPath(), QByteArrayLiteral("/favicon.ico")); + rr2->setResponseStatus(404); + rr2->sendResponse(); + QTRY_COMPARE(loadSpy.count(), 1); + QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true); + + QString callFormat = QStringLiteral("window.navigator.registerProtocolHandler(\"%1\", \"%2\", \"%3\")"); + QString protocol = QStringLiteral("mailto"); + QString url = server.url("/mail").toString() + QStringLiteral("?uri=%s"); + QString title; + QString call = callFormat.arg(protocol).arg(url).arg(title); + page.runJavaScript(call); + + QTRY_COMPARE(permissionSpy.count(), 1); + auto request = permissionSpy.takeFirst().value(0).value<QWebEngineRegisterProtocolHandlerPermissionRequest>(); + QCOMPARE(request.origin(), QUrl(url)); + QCOMPARE(request.protocol(), protocol); + if (permission) + request.accept(); + else + request.reject(); + + page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()")); + + std::unique_ptr<HttpReqRep> rr3; + if (permission) { + rr3 = waitForRequest(&server); + QVERIFY(rr3); + QCOMPARE(rr3->requestMethod(), QByteArrayLiteral("GET")); + QCOMPARE(rr3->requestPath(), QByteArrayLiteral("/mail?uri=mailto%3Afoo%40bar.com")); + rr3->sendResponse(); + } + + QTRY_COMPARE(loadSpy.count(), 1); + QCOMPARE(loadSpy.takeFirst().value(0).toBool(), permission); +} + static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")}; W_QTEST_MAIN(tst_QWebEnginePage, params) diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py index 69e22d5a6..a6274f0aa 100755 --- a/tools/scripts/take_snapshot.py +++ b/tools/scripts/take_snapshot.py @@ -92,6 +92,8 @@ def isInChromiumBlacklist(file_path): not 'third_party/chromevox' in file_path and not 'media/webrtc/desktop_media_list.h' in file_path and not 'media/webrtc/desktop_streams_registry.' in file_path and + not 'browser/custom_handlers/protocol_handler_registry.' in file_path and + not 'browser/custom_handlers/protocol_handler_registry_factory.' in file_path and not 'browser/net/chrome_mojo_proxy_resolver_factory.' in file_path and not '/browser/devtools/' in file_path and not '/browser/ui/webui/' in file_path and @@ -99,6 +101,7 @@ def isInChromiumBlacklist(file_path): not 'common/chrome_paths' in file_path and not 'common/chrome_switches.' in file_path and not 'common/content_restriction.h' in file_path and + not 'common/custom_handlers/protocol_handler.' in file_path and not 'common/spellcheck_' in file_path and not 'common/url_constants' in file_path and not '/extensions/api/' in file_path and -- GitLab