From ac99621829e6f7f589ec313842c64f74bd8e9883 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 23 Jul 2020 14:41:56 -0400 Subject: [PATCH] Fix link navigation from PDF files (fixes issue #2952) Navigations initiated from a guest view will now be routed to the OpenURLFromTab callback. --- .../alloy/alloy_content_browser_client.cc | 15 +++++- libcef/browser/browser_info_manager.cc | 54 ++++++++++++------- libcef/browser/browser_info_manager.h | 8 +++ 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/libcef/browser/alloy/alloy_content_browser_client.cc b/libcef/browser/alloy/alloy_content_browser_client.cc index 912a723bf..9cb1bb96c 100644 --- a/libcef/browser/alloy/alloy_content_browser_client.cc +++ b/libcef/browser/alloy/alloy_content_browser_client.cc @@ -450,10 +450,21 @@ bool NavigationOnUIThread( const navigation_interception::NavigationParams& params) { CEF_REQUIRE_UIT(); + content::OpenURLParams open_params( + params.url(), params.referrer(), WindowOpenDisposition::CURRENT_TAB, + params.transition_type(), params.is_renderer_initiated()); + open_params.user_gesture = params.has_user_gesture(); + open_params.initiator_origin = params.initiator_origin(); + + CefRefPtr browser; + if (!CefBrowserInfoManager::GetInstance()->MaybeAllowNavigation( + source->GetMainFrame(), open_params, browser)) { + // Cancel the navigation. + return true; + } + bool ignore_navigation = false; - CefRefPtr browser = - CefBrowserHostImpl::GetBrowserForContents(source); if (browser.get()) { CefRefPtr client = browser->GetClient(); if (client.get()) { diff --git a/libcef/browser/browser_info_manager.cc b/libcef/browser/browser_info_manager.cc index 23622dc91..90e4c96f3 100644 --- a/libcef/browser/browser_info_manager.cc +++ b/libcef/browser/browser_info_manager.cc @@ -22,6 +22,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/child_process_host.h" +#include "extensions/common/constants.h" namespace { @@ -115,26 +116,13 @@ bool CefBrowserInfoManager::CanCreateWindow( bool* no_javascript_access) { CEF_REQUIRE_UIT(); - bool is_guest_view = false; - CefRefPtr browser = - extensions::GetOwnerBrowserForHost(opener, &is_guest_view); - DCHECK(browser.get()); - if (!browser.get()) { - // Cancel the popup. - return false; - } - - if (is_guest_view) { - content::OpenURLParams params(target_url, referrer, disposition, - ui::PAGE_TRANSITION_LINK, true); - params.user_gesture = user_gesture; - - // Pass navigation to the owner browser. - CEF_POST_TASK( - CEF_UIT, - base::Bind(base::IgnoreResult(&CefBrowserHostImpl::OpenURLFromTab), - browser.get(), nullptr, params)); + content::OpenURLParams params(target_url, referrer, disposition, + ui::PAGE_TRANSITION_LINK, + /*is_renderer_initiated=*/true); + params.user_gesture = user_gesture; + CefRefPtr browser; + if (!MaybeAllowNavigation(opener, params, browser)) { // Cancel the popup. return false; } @@ -369,6 +357,34 @@ CefBrowserInfoManager::GetBrowserInfoForFrameRoute(int render_process_id, return GetBrowserInfo(render_process_id, render_routing_id, is_guest_view); } +bool CefBrowserInfoManager::MaybeAllowNavigation( + content::RenderFrameHost* opener, + const content::OpenURLParams& params, + CefRefPtr& browser_out) const { + CEF_REQUIRE_UIT(); + + bool is_guest_view = false; + CefRefPtr browser = + extensions::GetOwnerBrowserForHost(opener, &is_guest_view); + DCHECK(browser); + if (!browser) + return false; + + if (is_guest_view && !params.url.SchemeIs(extensions::kExtensionScheme)) { + // The PDF viewer will load an extension in the guest view. All other + // navigations are passed to the owner browser. + CEF_POST_TASK( + CEF_UIT, + base::Bind(base::IgnoreResult(&CefBrowserHostImpl::OpenURLFromTab), + browser.get(), nullptr, params)); + + return false; + } + + browser_out = browser; + return true; +} + scoped_refptr CefBrowserInfoManager::GetBrowserInfoForFrameTreeNode(int frame_tree_node_id, bool* is_guest_view) { diff --git a/libcef/browser/browser_info_manager.h b/libcef/browser/browser_info_manager.h index 3ff8fcc1d..e0baa6685 100644 --- a/libcef/browser/browser_info_manager.h +++ b/libcef/browser/browser_info_manager.h @@ -25,6 +25,7 @@ struct WebWindowFeatures; } namespace content { +struct OpenURLParams; struct Referrer; class RenderFrameHost; class RenderViewHostDelegateView; @@ -138,6 +139,13 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver { typedef std::list> BrowserInfoList; BrowserInfoList GetBrowserInfoList(); + // Returns true if the navigation should be allowed to proceed, or false if + // the navigation will instead be sent via OpenURLFromTab. If allowed, + // |browser| will be set to the target browser. + bool MaybeAllowNavigation(content::RenderFrameHost* opener, + const content::OpenURLParams& params, + CefRefPtr& browser) const; + private: // RenderProcessHostObserver methods: void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;