From 4771bb7ee4ebd4756538eef97c5fc96cf8c05025 Mon Sep 17 00:00:00 2001 From: Yuta Sekiguchi Date: Tue, 4 Jun 2024 12:19:14 -0400 Subject: [PATCH] chrome: Add CefJSDialogHandler support (fixes #3702) --- .../browser/alloy/alloy_browser_host_impl.cc | 6 +--- .../browser/alloy/alloy_browser_host_impl.h | 4 --- libcef/browser/browser_host_base.cc | 13 ++++++++ libcef/browser/browser_host_base.h | 8 +++++ .../browser/chrome/chrome_browser_delegate.cc | 10 ++++++ .../browser/chrome/chrome_browser_delegate.h | 2 ++ libcef/browser/javascript_dialog_manager.cc | 7 ---- patch/patches/chrome_browser_browser.patch | 32 ++++++++++++++----- 8 files changed, 58 insertions(+), 24 deletions(-) diff --git a/libcef/browser/alloy/alloy_browser_host_impl.cc b/libcef/browser/alloy/alloy_browser_host_impl.cc index 38b02f87a..00591b111 100644 --- a/libcef/browser/alloy/alloy_browser_host_impl.cc +++ b/libcef/browser/alloy/alloy_browser_host_impl.cc @@ -1210,11 +1210,7 @@ void AlloyBrowserHostImpl::RendererResponsive( content::JavaScriptDialogManager* AlloyBrowserHostImpl::GetJavaScriptDialogManager(content::WebContents* source) { - if (!javascript_dialog_manager_) { - javascript_dialog_manager_ = - std::make_unique(this); - } - return javascript_dialog_manager_.get(); + return CefBrowserHostBase::GetJavaScriptDialogManager(); } void AlloyBrowserHostImpl::RunFileChooser( diff --git a/libcef/browser/alloy/alloy_browser_host_impl.h b/libcef/browser/alloy/alloy_browser_host_impl.h index 1869a4272..9814b8b4e 100644 --- a/libcef/browser/alloy/alloy_browser_host_impl.h +++ b/libcef/browser/alloy/alloy_browser_host_impl.h @@ -18,7 +18,6 @@ #include "cef/libcef/browser/browser_host_base.h" #include "cef/libcef/browser/browser_info.h" #include "cef/libcef/browser/frame_host_impl.h" -#include "cef/libcef/browser/javascript_dialog_manager.h" #include "cef/libcef/browser/menu_manager.h" #include "cef/libcef/browser/request_context_impl.h" #include "content/public/browser/web_contents.h" @@ -363,9 +362,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase, // on the UI thread. bool window_destroyed_ = false; - // Used for creating and managing JavaScript dialogs. - std::unique_ptr javascript_dialog_manager_; - // Used for creating and managing context menus. std::unique_ptr menu_manager_; diff --git a/libcef/browser/browser_host_base.cc b/libcef/browser/browser_host_base.cc index d4a486d22..e757c4119 100644 --- a/libcef/browser/browser_host_base.cc +++ b/libcef/browser/browser_host_base.cc @@ -287,6 +287,10 @@ void CefBrowserHostBase::DestroyWebContents( devtools_protocol_manager_.reset(); devtools_window_runner_.reset(); context_menu_observer_ = nullptr; + if (javascript_dialog_manager_) { + javascript_dialog_manager_->Destroy(); + javascript_dialog_manager_.reset(); + } browser_info_->WebContentsDestroyed(); platform_delegate_->WebContentsDestroyed(web_contents); @@ -1283,6 +1287,15 @@ void CefBrowserHostBase::SelectFileListenerDestroyed( } } +content::JavaScriptDialogManager* +CefBrowserHostBase::GetJavaScriptDialogManager() { + if (!javascript_dialog_manager_) { + javascript_dialog_manager_ = + std::make_unique(this); + } + return javascript_dialog_manager_.get(); +} + bool CefBrowserHostBase::MaybeAllowNavigation( content::RenderFrameHost* opener, const content::OpenURLParams& params) { diff --git a/libcef/browser/browser_host_base.h b/libcef/browser/browser_host_base.h index 7dfb5aae7..eaa732602 100644 --- a/libcef/browser/browser_host_base.h +++ b/libcef/browser/browser_host_base.h @@ -20,6 +20,7 @@ #include "cef/libcef/browser/devtools/devtools_window_runner.h" #include "cef/libcef/browser/file_dialog_manager.h" #include "cef/libcef/browser/frame_host_impl.h" +#include "cef/libcef/browser/javascript_dialog_manager.h" #include "cef/libcef/browser/media_stream_registrar.h" #include "cef/libcef/browser/request_context_impl.h" #include "cef/libcef/features/features.h" @@ -357,6 +358,10 @@ class CefBrowserHostBase : public CefBrowserHost, void* params); void SelectFileListenerDestroyed(ui::SelectFileDialog::Listener* listener); + // Called from AlloyBrowserHostImpl::GetJavaScriptDialogManager and + // ChromeBrowserDelegate::GetJavaScriptDialogManager. + content::JavaScriptDialogManager* GetJavaScriptDialogManager(); + // Called from CefBrowserInfoManager::MaybeAllowNavigation. virtual bool MaybeAllowNavigation(content::RenderFrameHost* opener, const content::OpenURLParams& params); @@ -471,6 +476,9 @@ class CefBrowserHostBase : public CefBrowserHost, // Used for creating and managing file dialogs. std::unique_ptr file_dialog_manager_; + // Used for creating and managing JavaScript dialogs. + std::unique_ptr javascript_dialog_manager_; + // Volatile state accessed from multiple threads. All access must be protected // by |state_lock_|. base::Lock state_lock_; diff --git a/libcef/browser/chrome/chrome_browser_delegate.cc b/libcef/browser/chrome/chrome_browser_delegate.cc index 9da42536a..733c7bc50 100644 --- a/libcef/browser/chrome/chrome_browser_delegate.cc +++ b/libcef/browser/chrome/chrome_browser_delegate.cc @@ -619,6 +619,16 @@ void ChromeBrowserDelegate::CanDownload( std::move(callback).Run(true); } +content::JavaScriptDialogManager* +ChromeBrowserDelegate::GetJavaScriptDialogManager( + content::WebContents* source) { + auto browser_host = ChromeBrowserHostImpl::GetBrowserForContents(source); + if (browser_host) { + return browser_host->GetJavaScriptDialogManager(); + } + return nullptr; +} + KeyboardEventProcessingResult ChromeBrowserDelegate::PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) { diff --git a/libcef/browser/chrome/chrome_browser_delegate.h b/libcef/browser/chrome/chrome_browser_delegate.h index e5789e863..d7a53f564 100644 --- a/libcef/browser/chrome/chrome_browser_delegate.h +++ b/libcef/browser/chrome/chrome_browser_delegate.h @@ -118,6 +118,8 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate { void CanDownload(const GURL& url, const std::string& request_method, base::OnceCallback callback) override; + content::JavaScriptDialogManager* GetJavaScriptDialogManager( + content::WebContents* source) override; content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const content::NativeWebKeyboardEvent& event) override; diff --git a/libcef/browser/javascript_dialog_manager.cc b/libcef/browser/javascript_dialog_manager.cc index 0deec1938..afe6b822f 100644 --- a/libcef/browser/javascript_dialog_manager.cc +++ b/libcef/browser/javascript_dialog_manager.cc @@ -182,13 +182,6 @@ void CefJavaScriptDialogManager::RunBeforeUnloadDialog( content::RenderFrameHost* render_frame_host, bool is_reload, DialogClosedCallback callback) { - if (browser_->WillBeDestroyed()) { - // Currently destroying the browser. Accept the unload without showing - // the prompt. - std::move(callback).Run(true, std::u16string()); - return; - } - const std::u16string& message_text = u"Is it OK to leave/reload this page?"; // Always call DialogClosed(). diff --git a/patch/patches/chrome_browser_browser.patch b/patch/patches/chrome_browser_browser.patch index 607f7a429..1fcfc3c08 100644 --- a/patch/patches/chrome_browser_browser.patch +++ b/patch/patches/chrome_browser_browser.patch @@ -131,7 +131,7 @@ index e4c38df62e93e..6956a4a6e19ca 100644 ] } diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc -index f6302e83d3b00..c617cc4a4a640 100644 +index f6302e83d3b00..ce0d6010d4b5c 100644 --- chrome/browser/ui/browser.cc +++ chrome/browser/ui/browser.cc @@ -269,6 +269,25 @@ @@ -341,7 +341,23 @@ index f6302e83d3b00..c617cc4a4a640 100644 RenderWidgetHostView* view = render_widget_host->GetView(); if (view && !render_widget_host->GetView()->IsHTMLFormPopup()) { TabDialogs::FromWebContents(source)->HideHungRendererDialog( -@@ -2093,6 +2199,11 @@ void Browser::DraggableRegionsChanged( +@@ -2049,6 +2155,15 @@ void Browser::RendererResponsive( + + content::JavaScriptDialogManager* Browser::GetJavaScriptDialogManager( + WebContents* source) { ++#if BUILDFLAG(ENABLE_CEF) ++ if (cef_browser_delegate_) { ++ auto* cef_js_dialog_manager = ++ cef_browser_delegate_->GetJavaScriptDialogManager(source); ++ if (cef_js_dialog_manager) { ++ return cef_js_dialog_manager; ++ } ++ } ++#endif + return javascript_dialogs::TabModalDialogManager::FromWebContents(source); + } + +@@ -2093,6 +2208,11 @@ void Browser::DraggableRegionsChanged( if (app_controller_) { app_controller_->DraggableRegionsChanged(regions, contents); } @@ -353,7 +369,7 @@ index f6302e83d3b00..c617cc4a4a640 100644 } void Browser::DidFinishNavigation( -@@ -2173,11 +2284,15 @@ void Browser::EnterFullscreenModeForTab( +@@ -2173,11 +2293,15 @@ void Browser::EnterFullscreenModeForTab( const blink::mojom::FullscreenOptions& options) { exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab( requesting_frame, options.display_id); @@ -369,7 +385,7 @@ index f6302e83d3b00..c617cc4a4a640 100644 } bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) { -@@ -2377,6 +2492,15 @@ void Browser::RequestMediaAccessPermission( +@@ -2377,6 +2501,15 @@ void Browser::RequestMediaAccessPermission( content::WebContents* web_contents, const content::MediaStreamRequest& request, content::MediaResponseCallback callback) { @@ -385,7 +401,7 @@ index f6302e83d3b00..c617cc4a4a640 100644 const extensions::Extension* extension = GetExtensionForOrigin(profile_, request.security_origin); MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest( -@@ -2921,9 +3045,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) { +@@ -2921,9 +3054,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) { // Browser, Getters for UI (private): StatusBubble* Browser::GetStatusBubble() { @@ -398,7 +414,7 @@ index f6302e83d3b00..c617cc4a4a640 100644 } // We hide the status bar for web apps windows as this matches native -@@ -2931,6 +3057,12 @@ StatusBubble* Browser::GetStatusBubble() { +@@ -2931,6 +3066,12 @@ StatusBubble* Browser::GetStatusBubble() { // mode, as the minimal browser UI includes the status bar. if (web_app::AppBrowserController::IsWebApp(this) && !app_controller()->HasMinimalUiButtons()) { @@ -411,7 +427,7 @@ index f6302e83d3b00..c617cc4a4a640 100644 return nullptr; } -@@ -3080,6 +3212,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) { +@@ -3080,6 +3221,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) { BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this); web_contents_collection_.StopObserving(web_contents); } @@ -420,7 +436,7 @@ index f6302e83d3b00..c617cc4a4a640 100644 } void Browser::TabDetachedAtImpl(content::WebContents* contents, -@@ -3234,6 +3368,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature( +@@ -3234,6 +3377,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature( bool Browser::SupportsWindowFeatureImpl(WindowFeature feature, bool check_can_support) const {