From 708b852a1b587e68e0ccc6999d4e04fa830689e3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 22 Sep 2015 16:14:58 +0200 Subject: External URL support Support for launching external URLs such as mailto: They are also routed through navigationRequested like they would have been in QtWebKit. [ChangeLog][QtWebEngineCore] External links such as mailto: are now handled. By default they launch using QDesktopServices. Change-Id: I83ed96e2330d54cae57f03648d471a8da9a82a30 Task-number: QTBUG-47143 Reviewed-by: Kai Koehne --- src/core/network_delegate_qt.cpp | 2 +- src/core/resource_dispatcher_host_delegate_qt.cpp | 29 +++++++++++++++++++++++ src/core/resource_dispatcher_host_delegate_qt.h | 3 +++ src/core/web_contents_delegate_qt.cpp | 15 ++++++++++++ src/core/web_contents_delegate_qt.h | 1 + 5 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp index 38fd3c710..b8f1b68d0 100644 --- a/src/core/network_delegate_qt.cpp +++ b/src/core/network_delegate_qt.cpp @@ -55,7 +55,7 @@ namespace QtWebEngineCore { -static int pageTransitionToNavigationType(ui::PageTransition transition) +int pageTransitionToNavigationType(ui::PageTransition transition) { int32 qualifier = ui::PageTransitionGetQualifier(transition); diff --git a/src/core/resource_dispatcher_host_delegate_qt.cpp b/src/core/resource_dispatcher_host_delegate_qt.cpp index b63ecd5c7..e6c513bf6 100644 --- a/src/core/resource_dispatcher_host_delegate_qt.cpp +++ b/src/core/resource_dispatcher_host_delegate_qt.cpp @@ -130,6 +130,35 @@ void ResourceDispatcherHostLoginDelegateQt::destroy() m_request = 0; } +static void LaunchURL(const GURL& url, int render_process_id, int render_view_id, + ui::PageTransition page_transition, bool is_main_frame) +{ + Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + content::RenderViewHost *render_view_host = content::RenderViewHost::FromID(render_process_id, render_view_id); + if (!render_view_host) + return; + content::WebContents* webContents = content::WebContents::FromRenderViewHost(render_view_host); + if (!webContents) + return; + WebContentsDelegateQt *contentsDelegate = static_cast(webContents->GetDelegate()); + contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame); +} + +bool ResourceDispatcherHostDelegateQt::HandleExternalProtocol(const GURL& url, int child_id, int route_id, + bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) +{ + Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); + // We don't want to launch external applications unless it is based on a user action + if (!has_user_gesture) + return false; + + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind(&LaunchURL, url, child_id, route_id, page_transition, is_main_frame)); + return true; +} + content::ResourceDispatcherHostLoginDelegate *ResourceDispatcherHostDelegateQt::CreateLoginDelegate(net::AuthChallengeInfo *authInfo, net::URLRequest *request) { // ResourceDispatcherHostLoginDelegateQt is ref-counted and will be released after we called ClearLoginDelegateForRequest. diff --git a/src/core/resource_dispatcher_host_delegate_qt.h b/src/core/resource_dispatcher_host_delegate_qt.h index d62292995..57eaa3bc5 100644 --- a/src/core/resource_dispatcher_host_delegate_qt.h +++ b/src/core/resource_dispatcher_host_delegate_qt.h @@ -86,6 +86,9 @@ private: class ResourceDispatcherHostDelegateQt : public content::ResourceDispatcherHostDelegate { public: + virtual bool HandleExternalProtocol(const GURL& url, int child_id, int route_id, + bool is_main_frame, ui::PageTransition page_transition, bool has_user_gesture) Q_DECL_OVERRIDE; + virtual content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(net::AuthChallengeInfo *authInfo, net::URLRequest *request) Q_DECL_OVERRIDE; }; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index eb9c42edc..1c37f62df 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -43,6 +43,7 @@ #include "browser_context_adapter.h" #include "file_picker_controller.h" #include "media_capture_devices_dispatcher.h" +#include "network_delegate_qt.h" #include "type_conversion.h" #include "web_contents_adapter_client.h" #include "web_contents_adapter_p.h" @@ -64,6 +65,8 @@ #include "content/public/common/web_preferences.h" #include "ui/events/latency_info.h" +#include + namespace QtWebEngineCore { // Maps the LogSeverity defines in base/logging.h to the web engines message levels. @@ -357,6 +360,18 @@ void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingO m_viewClient->runGeolocationPermissionRequest(requestingOrigin); } +extern int pageTransitionToNavigationType(ui::PageTransition transition); + +void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame) +{ + int navigationRequestAction = WebContentsAdapterClient::AcceptRequest; + m_viewClient->navigationRequested(pageTransitionToNavigationType(page_transition), url, navigationRequestAction, is_main_frame); +#ifndef QT_NO_DESKTOPSERVICES + if (navigationRequestAction == WebContentsAdapterClient::AcceptRequest) + QDesktopServices::openUrl(url); +#endif +} + void WebContentsDelegateQt::ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text) { Q_UNUSED(web_contents); diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 3fda96113..14421d060 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -107,6 +107,7 @@ public: void overrideWebPreferences(content::WebContents *, content::WebPreferences*); void allowCertificateError(const QSharedPointer &) ; void requestGeolocationPermission(const QUrl &requestingOrigin); + void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame); private: WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); -- cgit v1.2.3