Add notification for aborted popups (fixes #3776)
Pass a new |popup_id| parameter to OnBeforePopup and call a new OnBeforePopupAborted callback if the popup is aborted before OnAfterCreated is called for the popup browser. Add new CefBrowserHost::GetBrowserByIdentifier and GetOpenerIdentifier methods to assist with retrieval of associated browsers. In cefclient, clean up state when a popup is aborted and close any associated popup browsers when the opener browser is closed. This also works when running with `--use-default-popup`.
This commit is contained in:
parent
b91be9fcc9
commit
1a99a3abc5
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=e9f34d90eb4af614e35cbb29da0639b62acec7fd$
|
||||
// $hash=7b8b175b96f59916c09ac0dc9f307d07c1ad7e32$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
|
||||
|
@ -380,6 +380,12 @@ typedef struct _cef_browser_host_t {
|
|||
cef_window_handle_t(CEF_CALLBACK* get_opener_window_handle)(
|
||||
struct _cef_browser_host_t* self);
|
||||
|
||||
///
|
||||
/// Retrieve the unique identifier of the browser that opened this browser.
|
||||
/// Will return 0 for non-popup browsers.
|
||||
///
|
||||
int(CEF_CALLBACK* get_opener_identifier)(struct _cef_browser_host_t* self);
|
||||
|
||||
///
|
||||
/// Returns true (1) if this browser is wrapped in a cef_browser_view_t.
|
||||
///
|
||||
|
@ -1046,6 +1052,12 @@ CEF_EXPORT cef_browser_t* cef_browser_host_create_browser_sync(
|
|||
struct _cef_dictionary_value_t* extra_info,
|
||||
struct _cef_request_context_t* request_context);
|
||||
|
||||
///
|
||||
/// Returns the browser (if any) with the specified identifier.
|
||||
///
|
||||
CEF_EXPORT cef_browser_t* cef_browser_host_get_browser_by_identifier(
|
||||
int browser_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=6aad2ccf30a6c519bbeee64d83866e82a41a48d8$
|
||||
// $hash=5a56a530920ced27e4adf06c8ff758c1a42bc6e7$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_LIFE_SPAN_HANDLER_CAPI_H_
|
||||
|
@ -62,33 +62,40 @@ typedef struct _cef_life_span_handler_t {
|
|||
|
||||
///
|
||||
/// Called on the UI thread before a new popup browser is created. The
|
||||
/// |browser| and |frame| values represent the source of the popup request.
|
||||
/// The |target_url| and |target_frame_name| values indicate where the popup
|
||||
/// browser should navigate and may be NULL if not specified with the request.
|
||||
/// The |target_disposition| value indicates where the user intended to open
|
||||
/// the popup (e.g. current tab, new tab, etc). The |user_gesture| value will
|
||||
/// be true (1) if the popup was opened via explicit user gesture (e.g.
|
||||
/// clicking a link) or false (0) if the popup opened automatically (e.g. via
|
||||
/// the DomContentLoaded event). The |popupFeatures| structure contains
|
||||
/// additional information about the requested popup window. To allow creation
|
||||
/// of the popup browser optionally modify |windowInfo|, |client|, |settings|
|
||||
/// and |no_javascript_access| and return false (0). To cancel creation of the
|
||||
/// |browser| and |frame| values represent the source of the popup request
|
||||
/// (opener browser and frame). The |popup_id| value uniquely identifies the
|
||||
/// popup in the context of the opener browser. The |target_url| and
|
||||
/// |target_frame_name| values indicate where the popup browser should
|
||||
/// navigate and may be NULL if not specified with the request. The
|
||||
/// |target_disposition| value indicates where the user intended to open the
|
||||
/// popup (e.g. current tab, new tab, etc). The |user_gesture| value will be
|
||||
/// true (1) if the popup was opened via explicit user gesture (e.g. clicking
|
||||
/// a link) or false (0) if the popup opened automatically (e.g. via the
|
||||
/// DomContentLoaded event). The |popupFeatures| structure contains additional
|
||||
/// information about the requested popup window. To allow creation of the
|
||||
/// popup browser optionally modify |windowInfo|, |client|, |settings| and
|
||||
/// |no_javascript_access| and return false (0). To cancel creation of the
|
||||
/// popup browser return true (1). The |client| and |settings| values will
|
||||
/// default to the source browser's values. If the |no_javascript_access|
|
||||
/// value is set to false (0) the new browser will not be scriptable and may
|
||||
/// not be hosted in the same renderer process as the source browser. Any
|
||||
/// modifications to |windowInfo| will be ignored if the parent browser is
|
||||
/// wrapped in a cef_browser_view_t. Popup browser creation will be canceled
|
||||
/// if the parent browser is destroyed before the popup browser creation
|
||||
/// completes (indicated by a call to OnAfterCreated for the popup browser).
|
||||
/// The |extra_info| parameter provides an opportunity to specify extra
|
||||
/// information specific to the created popup browser that will be passed to
|
||||
/// wrapped in a cef_browser_view_t. The |extra_info| parameter provides an
|
||||
/// opportunity to specify extra information specific to the created popup
|
||||
/// browser that will be passed to
|
||||
/// cef_render_process_handler_t::on_browser_created() in the render process.
|
||||
///
|
||||
/// If popup browser creation succeeds then OnAfterCreated will be called for
|
||||
/// the new popup browser. If popup browser creation fails, and if the opener
|
||||
/// browser has not yet been destroyed, then OnBeforePopupAborted will be
|
||||
/// called for the opener browser. See OnBeforePopupAborted documentation for
|
||||
/// additional details.
|
||||
///
|
||||
int(CEF_CALLBACK* on_before_popup)(
|
||||
struct _cef_life_span_handler_t* self,
|
||||
struct _cef_browser_t* browser,
|
||||
struct _cef_frame_t* frame,
|
||||
int popup_id,
|
||||
const cef_string_t* target_url,
|
||||
const cef_string_t* target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -100,6 +107,26 @@ typedef struct _cef_life_span_handler_t {
|
|||
struct _cef_dictionary_value_t** extra_info,
|
||||
int* no_javascript_access);
|
||||
|
||||
///
|
||||
/// Called on the UI thread if a new popup browser is aborted. This only
|
||||
/// occurs if the popup is allowed in OnBeforePopup and creation fails before
|
||||
/// OnAfterCreated is called for the new popup browser. The |browser| value is
|
||||
/// the source of the popup request (opener browser). The |popup_id| value
|
||||
/// uniquely identifies the popup in the context of the opener browser, and is
|
||||
/// the same value that was passed to OnBeforePopup.
|
||||
///
|
||||
/// Any client state associated with pending popups should be cleared in
|
||||
/// OnBeforePopupAborted, OnAfterCreated of the popup browser, or
|
||||
/// OnBeforeClose of the opener browser. OnBeforeClose of the opener browser
|
||||
/// may be called before this function in cases where the opener is closing
|
||||
/// during popup creation, in which case cef_browser_host_t::IsValid will
|
||||
/// return false (0) in this function.
|
||||
///
|
||||
void(CEF_CALLBACK* on_before_popup_aborted)(
|
||||
struct _cef_life_span_handler_t* self,
|
||||
struct _cef_browser_t* browser,
|
||||
int popup_id);
|
||||
|
||||
///
|
||||
/// Called on the UI thread before a new DevTools popup browser is created.
|
||||
/// The |browser| value represents the source of the popup request. Optionally
|
||||
|
@ -252,10 +279,11 @@ typedef struct _cef_life_span_handler_t {
|
|||
/// browser object and do not attempt to execute any functions on the browser
|
||||
/// object (other than IsValid, GetIdentifier or IsSame) after this callback
|
||||
/// returns. cef_frame_handler_t callbacks related to final main frame
|
||||
/// destruction will arrive after this callback and cef_browser_t::IsValid
|
||||
/// will return false (0) at that time. Any in-progress network requests
|
||||
/// associated with |browser| will be aborted when the browser is destroyed,
|
||||
/// and cef_resource_request_handler_t callbacks related to those requests may
|
||||
/// destruction, and OnBeforePopupAborted callbacks for any pending popups,
|
||||
/// will arrive after this callback and cef_browser_t::IsValid will return
|
||||
/// false (0) at that time. Any in-progress network requests associated with
|
||||
/// |browser| will be aborted when the browser is destroyed, and
|
||||
/// cef_resource_request_handler_t callbacks related to those requests may
|
||||
/// still arrive on the IO thread after this callback. See cef_frame_handler_t
|
||||
/// and do_close() documentation for additional usage information.
|
||||
///
|
||||
|
|
|
@ -42,13 +42,13 @@
|
|||
// way that may cause binary incompatibility with other builds. The universal
|
||||
// hash value will change if any platform is affected whereas the platform hash
|
||||
// values will change only if that particular platform is affected.
|
||||
#define CEF_API_HASH_UNIVERSAL "38565e673fbcfcd9e4494914bcea03609b41ec30"
|
||||
#define CEF_API_HASH_UNIVERSAL "8d6d53c5732a12b4d663665e3745a93d1cfd742d"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "df2092177211214092ab77559596adbc37edf68d"
|
||||
#define CEF_API_HASH_PLATFORM "3593cc6344b391d992421dd985c4ebcc46d8314f"
|
||||
#elif defined(OS_MAC)
|
||||
#define CEF_API_HASH_PLATFORM "aaa5bde96ceffff3de2c6fab11142c9264f44a39"
|
||||
#define CEF_API_HASH_PLATFORM "c045e75415a6abc2c29a3e1e05baea7528e2ec28"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "40de77e9ae3e071eda1f3bed7e900aedcdb354e5"
|
||||
#define CEF_API_HASH_PLATFORM "b1058e8b167cfaa2f0feaccf4b4f23a813db515a"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -324,6 +324,12 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
|
|||
CefRefPtr<CefDictionaryValue> extra_info,
|
||||
CefRefPtr<CefRequestContext> request_context);
|
||||
|
||||
///
|
||||
/// Returns the browser (if any) with the specified identifier.
|
||||
///
|
||||
/*--cef()--*/
|
||||
static CefRefPtr<CefBrowser> GetBrowserByIdentifier(int browser_id);
|
||||
|
||||
///
|
||||
/// Returns the hosted browser object.
|
||||
///
|
||||
|
@ -412,6 +418,13 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
|
|||
/*--cef()--*/
|
||||
virtual CefWindowHandle GetOpenerWindowHandle() = 0;
|
||||
|
||||
///
|
||||
/// Retrieve the unique identifier of the browser that opened this browser.
|
||||
/// Will return 0 for non-popup browsers.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual int GetOpenerIdentifier() = 0;
|
||||
|
||||
///
|
||||
/// Returns true if this browser is wrapped in a CefBrowserView.
|
||||
///
|
||||
|
|
|
@ -55,13 +55,15 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||
|
||||
///
|
||||
/// Called on the UI thread before a new popup browser is created. The
|
||||
/// |browser| and |frame| values represent the source of the popup request.
|
||||
/// The |target_url| and |target_frame_name| values indicate where the popup
|
||||
/// browser should navigate and may be empty if not specified with the
|
||||
/// request. The |target_disposition| value indicates where the user intended
|
||||
/// to open the popup (e.g. current tab, new tab, etc). The |user_gesture|
|
||||
/// value will be true if the popup was opened via explicit user gesture (e.g.
|
||||
/// clicking a link) or false if the popup opened automatically (e.g. via the
|
||||
/// |browser| and |frame| values represent the source of the popup request
|
||||
/// (opener browser and frame). The |popup_id| value uniquely identifies the
|
||||
/// popup in the context of the opener browser. The |target_url| and
|
||||
/// |target_frame_name| values indicate where the popup browser should
|
||||
/// navigate and may be empty if not specified with the request. The
|
||||
/// |target_disposition| value indicates where the user intended to open the
|
||||
/// popup (e.g. current tab, new tab, etc). The |user_gesture| value will be
|
||||
/// true if the popup was opened via explicit user gesture (e.g. clicking a
|
||||
/// link) or false if the popup opened automatically (e.g. via the
|
||||
/// DomContentLoaded event). The |popupFeatures| structure contains additional
|
||||
/// information about the requested popup window. To allow creation of the
|
||||
/// popup browser optionally modify |windowInfo|, |client|, |settings| and
|
||||
|
@ -71,16 +73,21 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||
/// false the new browser will not be scriptable and may not be hosted in the
|
||||
/// same renderer process as the source browser. Any modifications to
|
||||
/// |windowInfo| will be ignored if the parent browser is wrapped in a
|
||||
/// CefBrowserView. Popup browser creation will be canceled if the parent
|
||||
/// browser is destroyed before the popup browser creation completes
|
||||
/// (indicated by a call to OnAfterCreated for the popup browser). The
|
||||
/// |extra_info| parameter provides an opportunity to specify extra
|
||||
/// information specific to the created popup browser that will be passed to
|
||||
/// CefRenderProcessHandler::OnBrowserCreated() in the render process.
|
||||
/// CefBrowserView. The |extra_info| parameter provides an opportunity to
|
||||
/// specify extra information specific to the created popup browser that will
|
||||
/// be passed to CefRenderProcessHandler::OnBrowserCreated() in the render
|
||||
/// process.
|
||||
///
|
||||
/// If popup browser creation succeeds then OnAfterCreated will be called for
|
||||
/// the new popup browser. If popup browser creation fails, and if the opener
|
||||
/// browser has not yet been destroyed, then OnBeforePopupAborted will be
|
||||
/// called for the opener browser. See OnBeforePopupAborted documentation for
|
||||
/// additional details.
|
||||
///
|
||||
/*--cef(optional_param=target_url,optional_param=target_frame_name)--*/
|
||||
virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
WindowOpenDisposition target_disposition,
|
||||
|
@ -94,6 +101,25 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Called on the UI thread if a new popup browser is aborted. This only
|
||||
/// occurs if the popup is allowed in OnBeforePopup and creation fails before
|
||||
/// OnAfterCreated is called for the new popup browser. The |browser| value is
|
||||
/// the source of the popup request (opener browser). The |popup_id| value
|
||||
/// uniquely identifies the popup in the context of the opener browser, and is
|
||||
/// the same value that was passed to OnBeforePopup.
|
||||
///
|
||||
/// Any client state associated with pending popups should be cleared in
|
||||
/// OnBeforePopupAborted, OnAfterCreated of the popup browser, or
|
||||
/// OnBeforeClose of the opener browser. OnBeforeClose of the opener browser
|
||||
/// may be called before this method in cases where the opener is closing
|
||||
/// during popup creation, in which case CefBrowserHost::IsValid will return
|
||||
/// false in this method.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) {}
|
||||
|
||||
///
|
||||
/// Called on the UI thread before a new DevTools popup browser is created.
|
||||
/// The |browser| value represents the source of the popup request. Optionally
|
||||
|
@ -242,7 +268,8 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||
/// Called just before a browser is destroyed. Release all references to the
|
||||
/// browser object and do not attempt to execute any methods on the browser
|
||||
/// object (other than IsValid, GetIdentifier or IsSame) after this callback
|
||||
/// returns. CefFrameHandler callbacks related to final main frame destruction
|
||||
/// returns. CefFrameHandler callbacks related to final main frame
|
||||
/// destruction, and OnBeforePopupAborted callbacks for any pending popups,
|
||||
/// will arrive after this callback and CefBrowser::IsValid will return false
|
||||
/// at that time. Any in-progress network requests associated with |browser|
|
||||
/// will be aborted when the browser is destroyed, and
|
||||
|
|
|
@ -330,7 +330,7 @@ CefWindowHandle AlloyBrowserHostImpl::GetWindowHandle() {
|
|||
}
|
||||
|
||||
CefWindowHandle AlloyBrowserHostImpl::GetOpenerWindowHandle() {
|
||||
return opener_;
|
||||
return opener_window_handle_;
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::Find(const CefString& searchText,
|
||||
|
@ -1414,14 +1414,17 @@ AlloyBrowserHostImpl::AlloyBrowserHostImpl(
|
|||
browser_info,
|
||||
request_context),
|
||||
content::WebContentsObserver(web_contents),
|
||||
opener_(kNullWindowHandle),
|
||||
is_windowless_(platform_delegate_->IsWindowless()) {
|
||||
contents_delegate_.ObserveWebContents(web_contents);
|
||||
|
||||
if (opener.get() && !is_views_hosted_) {
|
||||
// GetOpenerWindowHandle() only returns a value for non-views-hosted
|
||||
// popup browsers.
|
||||
opener_ = opener->GetWindowHandle();
|
||||
if (opener.get()) {
|
||||
opener_id_ = opener->GetIdentifier();
|
||||
|
||||
if (!is_views_hosted_) {
|
||||
// GetOpenerWindowHandle() only returns a value for non-views-hosted
|
||||
// popup browsers.
|
||||
opener_window_handle_ = opener->GetWindowHandle();
|
||||
}
|
||||
}
|
||||
|
||||
// Associate the platform delegate with this browser.
|
||||
|
|
|
@ -174,7 +174,8 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
|
|||
DestructionState destruction_state() const { return destruction_state_; }
|
||||
|
||||
// content::WebContentsDelegate methods.
|
||||
void PrintCrossProcessSubframe(content::WebContents* web_contents,
|
||||
void PrintCrossProcessSubframe(
|
||||
content::WebContents* web_contents,
|
||||
const gfx::Rect& rect,
|
||||
int document_cookie,
|
||||
content::RenderFrameHost* subframe_host) const override;
|
||||
|
@ -317,7 +318,7 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
|
|||
void StartAudioCapturer();
|
||||
void OnRecentlyAudibleTimerFired();
|
||||
|
||||
CefWindowHandle opener_;
|
||||
CefWindowHandle opener_window_handle_ = kNullWindowHandle;
|
||||
const bool is_windowless_;
|
||||
CefWindowHandle host_window_handle_ = kNullWindowHandle;
|
||||
|
||||
|
|
|
@ -480,6 +480,10 @@ void CefBrowserHostBase::SetFocus(bool focus) {
|
|||
}
|
||||
}
|
||||
|
||||
int CefBrowserHostBase::GetOpenerIdentifier() {
|
||||
return opener_id_;
|
||||
}
|
||||
|
||||
void CefBrowserHostBase::RunFileDialog(
|
||||
FileDialogMode mode,
|
||||
const CefString& title,
|
||||
|
@ -1445,6 +1449,11 @@ bool CefBrowserHostBase::IsVisible() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
int CefBrowserHostBase::GetNextPopupId() {
|
||||
CEF_REQUIRE_UIT();
|
||||
return next_popup_id_++;
|
||||
}
|
||||
|
||||
bool CefBrowserHostBase::EnsureDevToolsProtocolManager() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!contents_delegate_.web_contents()) {
|
||||
|
|
|
@ -220,6 +220,7 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||
bool HasView() override;
|
||||
bool IsReadyToBeClosed() override;
|
||||
void SetFocus(bool focus) override;
|
||||
int GetOpenerIdentifier() override;
|
||||
void RunFileDialog(FileDialogMode mode,
|
||||
const CefString& title,
|
||||
const CefString& default_file_path,
|
||||
|
@ -418,6 +419,10 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||
// Returns true if this browser is currently visible.
|
||||
virtual bool IsVisible() const;
|
||||
|
||||
// Returns the next popup ID for use with OnBeforePopup. Must be called on
|
||||
// the UI thread.
|
||||
int GetNextPopupId();
|
||||
|
||||
protected:
|
||||
bool EnsureDevToolsProtocolManager();
|
||||
void InitializeDevToolsRegistrationOnUIThread(
|
||||
|
@ -439,6 +444,7 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||
scoped_refptr<CefBrowserInfo> browser_info_;
|
||||
CefRefPtr<CefRequestContextImpl> request_context_;
|
||||
const bool is_views_hosted_;
|
||||
int opener_id_ = 0;
|
||||
|
||||
// Only accessed on the UI thread.
|
||||
CefBrowserContentsDelegate contents_delegate_;
|
||||
|
@ -473,6 +479,8 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||
|
||||
std::unique_ptr<CefMediaStreamRegistrar> media_stream_registrar_;
|
||||
|
||||
int next_popup_id_ = 1;
|
||||
|
||||
private:
|
||||
IMPLEMENT_REFCOUNTING(CefBrowserHostBase);
|
||||
};
|
||||
|
|
|
@ -151,6 +151,21 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
|||
return CefBrowserHostBase::Create(create_params);
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowser> CefBrowserHost::GetBrowserByIdentifier(int browser_id) {
|
||||
// Verify that the context is in a valid state.
|
||||
if (!CONTEXT_STATE_VALID()) {
|
||||
DCHECK(false) << "context not valid";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (browser_id <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CefBrowserHostBase::GetBrowserForBrowserId(browser_id).get();
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefBrowserCreateParams::IsChromeStyle(const CefWindowInfo* window_info) {
|
||||
if (!window_info) {
|
||||
|
|
|
@ -45,6 +45,14 @@ CefBrowserInfoManager* g_info_manager = nullptr;
|
|||
|
||||
} // namespace
|
||||
|
||||
CefBrowserInfoManager::PendingPopup::~PendingPopup() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (step != CREATION_COMPLETE && !aborted_callback.is_null()) {
|
||||
// Notify of pending popup abort.
|
||||
std::move(aborted_callback).Run();
|
||||
}
|
||||
}
|
||||
|
||||
CefBrowserInfoManager::CefBrowserInfoManager() {
|
||||
DCHECK(!g_info_manager);
|
||||
g_info_manager = this;
|
||||
|
@ -167,14 +175,35 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
|||
window_info.bounds.height = cef_features.height;
|
||||
}
|
||||
|
||||
const int popup_id = browser->GetNextPopupId();
|
||||
|
||||
allow = !handler->OnBeforePopup(
|
||||
browser.get(), opener_frame, pending_popup->target_url.spec(),
|
||||
pending_popup->target_frame_name,
|
||||
browser.get(), opener_frame, popup_id,
|
||||
pending_popup->target_url.spec(), pending_popup->target_frame_name,
|
||||
static_cast<cef_window_open_disposition_t>(disposition), user_gesture,
|
||||
cef_features, window_info, pending_popup->client,
|
||||
pending_popup->settings, pending_popup->extra_info,
|
||||
no_javascript_access);
|
||||
handled = true;
|
||||
|
||||
if (allow) {
|
||||
// The parent browser may be destroyed during popup creation, so don't
|
||||
// bind a direct reference.
|
||||
pending_popup->aborted_callback = base::BindOnce(
|
||||
[](int browser_id, int popup_id) {
|
||||
LOG(WARNING) << "Pending popup " << popup_id
|
||||
<< " aborted for browser " << browser_id;
|
||||
if (auto browser =
|
||||
CefBrowserHostBase::GetBrowserForBrowserId(browser_id)) {
|
||||
if (auto client = browser->GetClient()) {
|
||||
if (auto handler = client->GetLifeSpanHandler()) {
|
||||
handler->OnBeforePopupAborted(browser.get(), popup_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
browser->GetIdentifier(), popup_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,12 +246,41 @@ bool CefBrowserInfoManager::CanCreateWindow(
|
|||
// otherwise GetCustomWebContentsView will fail to retrieve the PopupInfo.
|
||||
opener->GetProcess()->FilterURL(false, &pending_popup->target_url);
|
||||
|
||||
pending_create_popup_ = pending_popup.get();
|
||||
|
||||
// Need to Push here because WebContentsCreated may be called before
|
||||
// CreateWindowResult.
|
||||
PushPendingPopup(std::move(pending_popup));
|
||||
}
|
||||
|
||||
return allow;
|
||||
}
|
||||
|
||||
void CefBrowserInfoManager::CreateWindowResult(content::RenderFrameHost* opener,
|
||||
bool success) {
|
||||
// This method is called during RenderFrameHostImpl::CreateNewWindow execution
|
||||
// (if CanCreateWindow returns true) with three possible states:
|
||||
// 1. Before WebContentsCreated with |success=false|. This is the normal
|
||||
// failure case where the pending popup will be canceled. For example, if a
|
||||
// file select dialog is active.
|
||||
// 2. After WebContentsCreated/AddWebContents with |success=true|. This is the
|
||||
// normal success case where OnAfterCreated has already been called.
|
||||
// 3. After WebContentsCreated/AddWebContents with |success=false|. This is
|
||||
// the failure case where a WebContents won't have an opener from the
|
||||
// renderer's perspective (for example, with JavaScript access disabled or
|
||||
// no-referrer links). The WebContents is still valid, will navigate
|
||||
// normally, and OnAfterCreated has already been called.
|
||||
if (!success && pending_create_popup_) {
|
||||
const auto* popup = pending_create_popup_.get();
|
||||
pending_create_popup_ = nullptr;
|
||||
|
||||
// Cancel the pending popup.
|
||||
std::erase_if(pending_popup_list_, [popup](const auto& popup_ptr) {
|
||||
return popup_ptr.get() == popup;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserInfoManager::GetCustomWebContentsView(
|
||||
const GURL& target_url,
|
||||
const content::GlobalRenderFrameHostId& opener_global_id,
|
||||
|
@ -255,6 +313,8 @@ void CefBrowserInfoManager::WebContentsCreated(
|
|||
content::WebContents* new_contents) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
pending_create_popup_ = nullptr;
|
||||
|
||||
// GET_CUSTOM_WEB_CONTENTS_VIEW is only used with Alloy style.
|
||||
auto pending_popup = PopPendingPopup(
|
||||
PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW,
|
||||
|
@ -272,6 +332,8 @@ void CefBrowserInfoManager::WebContentsCreated(
|
|||
pending_popup->step = PendingPopup::WEB_CONTENTS_CREATED;
|
||||
pending_popup->new_contents = new_contents;
|
||||
PushPendingPopup(std::move(pending_popup));
|
||||
} else {
|
||||
pending_popup->step = PendingPopup::CREATION_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,6 +348,7 @@ bool CefBrowserInfoManager::AddWebContents(content::WebContents* new_contents) {
|
|||
PendingPopup::WEB_CONTENTS_CREATED, new_contents);
|
||||
if (pending_popup) {
|
||||
DCHECK(!pending_popup->alloy_style);
|
||||
pending_popup->step = PendingPopup::CREATION_COMPLETE;
|
||||
return !pending_popup->use_default_browser_creation;
|
||||
}
|
||||
|
||||
|
@ -589,17 +652,10 @@ void CefBrowserInfoManager::RenderProcessHostDestroyed(
|
|||
}
|
||||
|
||||
// Remove all pending popups that reference the destroyed host as the opener.
|
||||
{
|
||||
PendingPopupList::iterator it = pending_popup_list_.begin();
|
||||
while (it != pending_popup_list_.end()) {
|
||||
PendingPopup* popup = it->get();
|
||||
if (popup->opener_global_id.child_id == render_process_id) {
|
||||
it = pending_popup_list_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::erase_if(
|
||||
pending_popup_list_, [render_process_id](const auto& popup_ptr) {
|
||||
return popup_ptr->opener_global_id.child_id == render_process_id;
|
||||
});
|
||||
}
|
||||
|
||||
void CefBrowserInfoManager::PushPendingPopup(
|
||||
|
|
|
@ -82,6 +82,10 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
|
|||
bool opener_suppressed,
|
||||
bool* no_javascript_access);
|
||||
|
||||
// Called from ContentBrowserClient::CreateWindowResult if CanCreateWindow
|
||||
// returns true. See comments on PendingPopup for more information.
|
||||
void CreateWindowResult(content::RenderFrameHost* opener, bool success);
|
||||
|
||||
// Called from WebContentsDelegate::GetCustomWebContentsView (Alloy style
|
||||
// only). See comments on PendingPopup for more information.
|
||||
void GetCustomWebContentsView(
|
||||
|
@ -161,23 +165,33 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
|
|||
// RenderProcessHostObserver methods:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
||||
// Store state information about pending popups. Call order is:
|
||||
// Store state information about pending popups. The UIT callbacks occur
|
||||
// synchronously during RenderFrameHostImpl::CreateNewWindow execution. The
|
||||
// result of CreateNewWindow execution will be passed to CreateWindowResult
|
||||
// (may call OnBeforePopupAborted; see documentation in that method). Call
|
||||
// order for successful popup creation is is:
|
||||
// - CanCreateWindow (UIT):
|
||||
// Provides an opportunity to cancel the popup (calls OnBeforePopup) and
|
||||
// creates the new platform delegate for the popup. If the popup owner is
|
||||
// an extension guest view (PDF viewer) then the popup is canceled and
|
||||
// WebContentsDelegate::OpenURLFromTab is called via the
|
||||
// CefBrowserHostBase::MaybeAllowNavigation implementation.
|
||||
// And then the following calls may occur at the same time:
|
||||
// And then the following UIT and IOT calls may occur at the same time:
|
||||
// - GetCustomWebContentsView (UIT) (Alloy style only):
|
||||
// Creates the OSR views for windowless popups.
|
||||
// - WebContentsCreated (UIT):
|
||||
// Creates the CefBrowserHost representation for the popup.
|
||||
// Creates the CefBrowserHost representation for the popup (calls
|
||||
// OnAfterCreated).
|
||||
// - AddWebContents (UIT) (Chrome style only):
|
||||
// Creates the Browser or tab representation for the popup.
|
||||
// - CefBrowserManager::GetNewBrowserInfo (IOT)
|
||||
// Passes information about the popup to the renderer process.
|
||||
struct PendingPopup {
|
||||
~PendingPopup();
|
||||
|
||||
// Used to notify if popup creation is aborted.
|
||||
base::OnceClosure aborted_callback;
|
||||
|
||||
// Track the last method that modified this PendingPopup instance. There may
|
||||
// be multiple pending popups with the same identifiers and this allows us
|
||||
// to differentiate between them at different processing steps.
|
||||
|
@ -185,6 +199,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
|
|||
CAN_CREATE_WINDOW,
|
||||
GET_CUSTOM_WEB_CONTENTS_VIEW,
|
||||
WEB_CONTENTS_CREATED,
|
||||
CREATION_COMPLETE,
|
||||
} step;
|
||||
|
||||
// True if this popup is Alloy style, otherwise Chrome style.
|
||||
|
@ -286,6 +301,11 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
|
|||
using PendingPopupList = std::vector<std::unique_ptr<PendingPopup>>;
|
||||
PendingPopupList pending_popup_list_;
|
||||
|
||||
// Current popup pending creation during RenderFrameHostImpl::CreateNewWindow
|
||||
// execution (valid from CanCreateWindow returning true to WebContentsCreated
|
||||
// or CreateWindowResult being called). Only accessed on the UI thread.
|
||||
raw_ptr<PendingPopup> pending_create_popup_ = nullptr;
|
||||
|
||||
int next_timeout_id_ = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -500,6 +500,8 @@ void ChromeBrowserHostImpl::Attach(content::WebContents* web_contents,
|
|||
DCHECK(web_contents);
|
||||
|
||||
if (opener) {
|
||||
opener_id_ = opener->GetIdentifier();
|
||||
|
||||
// Give the opener browser's platform delegate an opportunity to modify the
|
||||
// new browser's platform delegate.
|
||||
opener->platform_delegate()->PopupWebContentsCreated(
|
||||
|
|
|
@ -369,6 +369,12 @@ bool ChromeContentBrowserClientCef::CanCreateWindow(
|
|||
user_gesture, opener_suppressed, no_javascript_access);
|
||||
}
|
||||
|
||||
void ChromeContentBrowserClientCef::CreateWindowResult(
|
||||
content::RenderFrameHost* opener,
|
||||
bool success) {
|
||||
CefBrowserInfoManager::GetInstance()->CreateWindowResult(opener, success);
|
||||
}
|
||||
|
||||
void ChromeContentBrowserClientCef::OverrideWebkitPrefs(
|
||||
content::WebContents* web_contents,
|
||||
blink::web_pref::WebPreferences* prefs) {
|
||||
|
|
|
@ -63,6 +63,8 @@ class ChromeContentBrowserClientCef : public ChromeContentBrowserClient {
|
|||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) override;
|
||||
void CreateWindowResult(content::RenderFrameHost* opener,
|
||||
bool success) override;
|
||||
void OverrideWebkitPrefs(content::WebContents* web_contents,
|
||||
blink::web_pref::WebPreferences* prefs) override;
|
||||
void WillCreateURLLoaderFactory(
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=8a2a8a4853c3869876ffad3e6c175945ac1c5021$
|
||||
// $hash=c7458f64a0d7c8537dbdbcf34d11e62bf781428c$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
|
||||
|
@ -136,6 +136,20 @@ CEF_EXPORT cef_browser_t* cef_browser_host_create_browser_sync(
|
|||
return CefBrowserCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_EXPORT cef_browser_t* cef_browser_host_get_browser_by_identifier(
|
||||
int browser_id) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefBrowser> _retval =
|
||||
CefBrowserHost::GetBrowserByIdentifier(browser_id);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefBrowserCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
@ -262,6 +276,24 @@ browser_host_get_opener_window_handle(struct _cef_browser_host_t* self) {
|
|||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK
|
||||
browser_host_get_opener_identifier(struct _cef_browser_host_t* self) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute
|
||||
int _retval = CefBrowserHostCppToC::Get(self)->GetOpenerIdentifier();
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK browser_host_has_view(struct _cef_browser_host_t* self) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
|
@ -1536,6 +1568,7 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() {
|
|||
GetStruct()->set_focus = browser_host_set_focus;
|
||||
GetStruct()->get_window_handle = browser_host_get_window_handle;
|
||||
GetStruct()->get_opener_window_handle = browser_host_get_opener_window_handle;
|
||||
GetStruct()->get_opener_identifier = browser_host_get_opener_identifier;
|
||||
GetStruct()->has_view = browser_host_has_view;
|
||||
GetStruct()->get_client = browser_host_get_client;
|
||||
GetStruct()->get_request_context = browser_host_get_request_context;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=3883fd2aca10df181da30759fcce351fed62d43d$
|
||||
// $hash=b3844320e2d708a582a4bc2e3d5f2f143de8f514$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
|
||||
|
@ -29,6 +29,7 @@ int CEF_CALLBACK life_span_handler_on_before_popup(
|
|||
struct _cef_life_span_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
cef_frame_t* frame,
|
||||
int popup_id,
|
||||
const cef_string_t* target_url,
|
||||
const cef_string_t* target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -128,7 +129,7 @@ int CEF_CALLBACK life_span_handler_on_before_popup(
|
|||
|
||||
// Execute
|
||||
bool _retval = CefLifeSpanHandlerCppToC::Get(self)->OnBeforePopup(
|
||||
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
|
||||
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame), popup_id,
|
||||
CefString(target_url), CefString(target_frame_name), target_disposition,
|
||||
user_gesture ? true : false, popupFeaturesVal, windowInfoObj, clientPtr,
|
||||
settingsObj, extra_infoPtr, &no_javascript_accessBool);
|
||||
|
@ -170,6 +171,29 @@ int CEF_CALLBACK life_span_handler_on_before_popup(
|
|||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK
|
||||
life_span_handler_on_before_popup_aborted(struct _cef_life_span_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
int popup_id) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return;
|
||||
}
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser);
|
||||
if (!browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefLifeSpanHandlerCppToC::Get(self)->OnBeforePopupAborted(
|
||||
CefBrowserCToCpp::Wrap(browser), popup_id);
|
||||
}
|
||||
|
||||
void CEF_CALLBACK life_span_handler_on_before_dev_tools_popup(
|
||||
struct _cef_life_span_handler_t* self,
|
||||
cef_browser_t* browser,
|
||||
|
@ -365,6 +389,8 @@ life_span_handler_on_before_close(struct _cef_life_span_handler_t* self,
|
|||
|
||||
CefLifeSpanHandlerCppToC::CefLifeSpanHandlerCppToC() {
|
||||
GetStruct()->on_before_popup = life_span_handler_on_before_popup;
|
||||
GetStruct()->on_before_popup_aborted =
|
||||
life_span_handler_on_before_popup_aborted;
|
||||
GetStruct()->on_before_dev_tools_popup =
|
||||
life_span_handler_on_before_dev_tools_popup;
|
||||
GetStruct()->on_after_created = life_span_handler_on_after_created;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=2319d794dd3a38c448908114d1b4ea37b34f89dd$
|
||||
// $hash=02fc65eec44894d136e5c5ed139927c675a84c6e$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
|
||||
|
@ -79,6 +79,20 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
|||
return CefBrowserCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
CefRefPtr<CefBrowser> CefBrowserHost::GetBrowserByIdentifier(int browser_id) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_browser_t* _retval =
|
||||
cef_browser_host_get_browser_by_identifier(browser_id);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefBrowserCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
|
@ -198,6 +212,23 @@ CefWindowHandle CefBrowserHostCToCpp::GetOpenerWindowHandle() {
|
|||
return _retval;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") int CefBrowserHostCToCpp::GetOpenerIdentifier() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_browser_host_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_opener_identifier)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->get_opener_identifier(_struct);
|
||||
|
||||
// Return type: simple
|
||||
return _retval;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::HasView() {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=73d8659f17a4ae3319b5bf20807d5c69a1759c04$
|
||||
// $hash=f3902d95b54a26c99f532f6d04ce7e8027c86830$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
|
||||
|
@ -45,6 +45,7 @@ class CefBrowserHostCToCpp : public CefCToCppRefCounted<CefBrowserHostCToCpp,
|
|||
void SetFocus(bool focus) override;
|
||||
CefWindowHandle GetWindowHandle() override;
|
||||
CefWindowHandle GetOpenerWindowHandle() override;
|
||||
int GetOpenerIdentifier() override;
|
||||
bool HasView() override;
|
||||
CefRefPtr<CefClient> GetClient() override;
|
||||
CefRefPtr<CefRequestContext> GetRequestContext() override;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=f8686b23625810a3c7ceab1097eced10acec16ce$
|
||||
// $hash=fb1397bef33af6e40385469551b2037eeed8c390$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
|
||||
|
@ -26,6 +26,7 @@ NO_SANITIZE("cfi-icall")
|
|||
bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
WindowOpenDisposition target_disposition,
|
||||
|
@ -81,9 +82,9 @@ bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
|
|||
// Execute
|
||||
int _retval = _struct->on_before_popup(
|
||||
_struct, CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
|
||||
target_url.GetStruct(), target_frame_name.GetStruct(), target_disposition,
|
||||
user_gesture, &popupFeatures, &windowInfo, &clientStruct, &settings,
|
||||
&extra_infoStruct, &no_javascript_accessInt);
|
||||
popup_id, target_url.GetStruct(), target_frame_name.GetStruct(),
|
||||
target_disposition, user_gesture, &popupFeatures, &windowInfo,
|
||||
&clientStruct, &settings, &extra_infoStruct, &no_javascript_accessInt);
|
||||
|
||||
// Restore param:client; type: refptr_same_byref
|
||||
if (clientStruct) {
|
||||
|
@ -110,6 +111,30 @@ bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
|
|||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefLifeSpanHandlerCToCpp::OnBeforePopupAborted(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_life_span_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_before_popup_aborted)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute
|
||||
_struct->on_before_popup_aborted(_struct, CefBrowserCppToC::Wrap(browser),
|
||||
popup_id);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefLifeSpanHandlerCToCpp::OnBeforeDevToolsPopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=787463118d294d6a9b1004b54fb26b05c9f0a47b$
|
||||
// $hash=2e0ae9e4f7e647e43dc4d28fde904298550349e6$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_LIFE_SPAN_HANDLER_CTOCPP_H_
|
||||
|
@ -39,6 +39,7 @@ class CefLifeSpanHandlerCToCpp
|
|||
// CefLifeSpanHandler methods.
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
WindowOpenDisposition target_disposition,
|
||||
|
@ -49,6 +50,8 @@ class CefLifeSpanHandlerCToCpp
|
|||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* no_javascript_access) override;
|
||||
void OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) override;
|
||||
void OnBeforeDevToolsPopup(CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=85864cf7616899c4d51fbaf995d8e0db55249bd7$
|
||||
// $hash=c4ecb087f15c4b73a529efc0b0715064ebb7fe2b$
|
||||
//
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
@ -152,6 +152,8 @@ struct libcef_pointers {
|
|||
decltype(&cef_browser_host_create_browser) cef_browser_host_create_browser;
|
||||
decltype(&cef_browser_host_create_browser_sync)
|
||||
cef_browser_host_create_browser_sync;
|
||||
decltype(&cef_browser_host_get_browser_by_identifier)
|
||||
cef_browser_host_get_browser_by_identifier;
|
||||
decltype(&cef_command_line_create) cef_command_line_create;
|
||||
decltype(&cef_command_line_get_global) cef_command_line_get_global;
|
||||
decltype(&cef_cookie_manager_get_global_manager)
|
||||
|
@ -397,6 +399,7 @@ int libcef_init_pointers(const char* path) {
|
|||
INIT_ENTRY(cef_is_feature_enabled_for_tests);
|
||||
INIT_ENTRY(cef_browser_host_create_browser);
|
||||
INIT_ENTRY(cef_browser_host_create_browser_sync);
|
||||
INIT_ENTRY(cef_browser_host_get_browser_by_identifier);
|
||||
INIT_ENTRY(cef_command_line_create);
|
||||
INIT_ENTRY(cef_command_line_get_global);
|
||||
INIT_ENTRY(cef_cookie_manager_get_global_manager);
|
||||
|
@ -901,6 +904,13 @@ struct _cef_browser_t* cef_browser_host_create_browser_sync(
|
|||
windowInfo, client, url, settings, extra_info, request_context);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
struct _cef_browser_t* cef_browser_host_get_browser_by_identifier(
|
||||
int browser_id) {
|
||||
return g_libcef_pointers.cef_browser_host_get_browser_by_identifier(
|
||||
browser_id);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") struct _cef_command_line_t* cef_command_line_create() {
|
||||
return g_libcef_pointers.cef_command_line_create();
|
||||
}
|
||||
|
|
|
@ -400,6 +400,9 @@ patches = [
|
|||
# Change ContentBrowserClient::ConfigureNetworkContextParams return type to
|
||||
# bool to support cancellation of NetworkContext creation during shutdown.
|
||||
# https://github.com/chromiumembedded/cef/issues/2985
|
||||
#
|
||||
# Add ContentBrowserClient::CreateWindowResult callback.
|
||||
# https://github.com/chromiumembedded/cef/issues/3776
|
||||
'name': 'content_2015',
|
||||
},
|
||||
{
|
||||
|
@ -639,6 +642,9 @@ patches = [
|
|||
# Partially reverts the below changes.
|
||||
# https://chromium-review.googlesource.com/c/chromium/src/+/4829483
|
||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=1470837#c22
|
||||
#
|
||||
# Add ContentBrowserClient::CreateWindowResult callback.
|
||||
# https://github.com/chromiumembedded/cef/issues/3776
|
||||
'name': 'rfh_navigation_4829483'
|
||||
},
|
||||
{
|
||||
|
|
|
@ -68,10 +68,23 @@ index 21967547790ca..7bdf48b830a21 100644
|
|||
|
||||
std::vector<base::FilePath>
|
||||
diff --git content/public/browser/content_browser_client.h content/public/browser/content_browser_client.h
|
||||
index 0f6781dc459e1..8d8deaba4e049 100644
|
||||
index 0f6781dc459e1..3f3095cce2ba6 100644
|
||||
--- content/public/browser/content_browser_client.h
|
||||
+++ content/public/browser/content_browser_client.h
|
||||
@@ -2188,7 +2188,7 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -1329,6 +1329,12 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access);
|
||||
|
||||
+ // Called to report the result of new window creation after CanCreateWindow()
|
||||
+ // returns true. There are cases where the new window may still be canceled.
|
||||
+ virtual void CreateWindowResult(
|
||||
+ RenderFrameHost* opener,
|
||||
+ bool success) {}
|
||||
+
|
||||
// Allows the embedder to return a delegate for the SpeechRecognitionManager.
|
||||
// The delegate will be owned by the manager. It's valid to return nullptr.
|
||||
virtual SpeechRecognitionManagerDelegate*
|
||||
@@ -2188,7 +2194,7 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
//
|
||||
// If |relative_partition_path| is the empty string, it means this needs to
|
||||
// create the default NetworkContext for the BrowserContext.
|
||||
|
@ -80,7 +93,7 @@ index 0f6781dc459e1..8d8deaba4e049 100644
|
|||
BrowserContext* context,
|
||||
bool in_memory,
|
||||
const base::FilePath& relative_partition_path,
|
||||
@@ -2412,6 +2412,22 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -2412,6 +2418,22 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
const net::IsolationInfo& isolation_info,
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory);
|
||||
|
||||
|
@ -103,7 +116,7 @@ index 0f6781dc459e1..8d8deaba4e049 100644
|
|||
// Creates an OverlayWindow to be used for video or Picture-in-Picture.
|
||||
// This window will house the content shown when in Picture-in-Picture mode.
|
||||
// This will return a new OverlayWindow.
|
||||
@@ -2472,6 +2488,10 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -2472,6 +2494,10 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
// Used as part of the user agent string.
|
||||
virtual std::string GetProduct();
|
||||
|
||||
|
|
|
@ -1,8 +1,25 @@
|
|||
diff --git content/browser/renderer_host/render_frame_host_impl.cc content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 98c865765c57d..7694cd4516dc9 100644
|
||||
index 98c865765c57d..f31210f9c3070 100644
|
||||
--- content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -11466,6 +11466,7 @@ void RenderFrameHostImpl::CommitNavigation(
|
||||
@@ -9125,6 +9125,16 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
return;
|
||||
}
|
||||
|
||||
+ callback = base::BindOnce(
|
||||
+ [](RenderFrameHostImpl* self,
|
||||
+ CreateNewWindowCallback callback,
|
||||
+ mojom::CreateNewWindowStatus status,
|
||||
+ mojom::CreateNewWindowReplyPtr reply) {
|
||||
+ GetContentClient()->browser()->CreateWindowResult(
|
||||
+ self, status == mojom::CreateNewWindowStatus::kSuccess);
|
||||
+ std::move(callback).Run(status, std::move(reply));
|
||||
+ }, base::Unretained(this), std::move(callback));
|
||||
+
|
||||
// Otherwise, consume user activation before we proceed. In particular, it is
|
||||
// important to do this before we return from the |opener_suppressed| case
|
||||
// below.
|
||||
@@ -11466,6 +11476,7 @@ void RenderFrameHostImpl::CommitNavigation(
|
||||
auto browser_calc_origin_to_commit =
|
||||
navigation_request->GetOriginToCommitWithDebugInfo();
|
||||
if (!process_lock.is_error_page() && !is_mhtml_subframe &&
|
||||
|
|
|
@ -61,7 +61,8 @@ void BaseClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
|||
}
|
||||
|
||||
if (track_as_other_browser_) {
|
||||
MainContext::Get()->GetRootWindowManager()->OtherBrowserCreated();
|
||||
MainContext::Get()->GetRootWindowManager()->OtherBrowserCreated(
|
||||
browser->GetIdentifier(), browser->GetHost()->GetOpenerIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +80,8 @@ void BaseClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
|||
}
|
||||
|
||||
if (track_as_other_browser_) {
|
||||
MainContext::Get()->GetRootWindowManager()->OtherBrowserClosed();
|
||||
MainContext::Get()->GetRootWindowManager()->OtherBrowserClosed(
|
||||
browser->GetIdentifier(), browser->GetHost()->GetOpenerIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -924,6 +924,7 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
|
|||
bool ClientHandler::OnBeforePopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||
|
@ -944,13 +945,20 @@ bool ClientHandler::OnBeforePopup(
|
|||
|
||||
// Potentially create a new RootWindow for the popup browser that will be
|
||||
// created asynchronously.
|
||||
CreatePopupWindow(browser, /*is_devtools=*/false, popupFeatures, windowInfo,
|
||||
client, settings);
|
||||
CreatePopupWindow(browser, popup_id, /*is_devtools=*/false, popupFeatures,
|
||||
windowInfo, client, settings);
|
||||
|
||||
// Allow popup creation.
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientHandler::OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
MainContext::Get()->GetRootWindowManager()->AbortOrClosePopup(
|
||||
browser->GetIdentifier(), popup_id);
|
||||
}
|
||||
|
||||
void ClientHandler::OnBeforeDevToolsPopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
|
@ -962,8 +970,8 @@ void ClientHandler::OnBeforeDevToolsPopup(
|
|||
|
||||
// Potentially create a new RootWindow for the DevTools popup browser that
|
||||
// will be created immediately after this method returns.
|
||||
if (!CreatePopupWindow(browser, /*is_devtools=*/true, CefPopupFeatures(),
|
||||
windowInfo, client, settings)) {
|
||||
if (!CreatePopupWindow(browser, /*popup_id=*/-1, /*is_devtools=*/true,
|
||||
CefPopupFeatures(), windowInfo, client, settings)) {
|
||||
*use_default_window = true;
|
||||
}
|
||||
}
|
||||
|
@ -998,6 +1006,10 @@ bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
|
|||
|
||||
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Close all popups that have this browser as the opener.
|
||||
OnBeforePopupAborted(browser, /*popup_id=*/-1);
|
||||
|
||||
BaseClientHandler::OnBeforeClose(browser);
|
||||
NotifyBrowserClosed(browser);
|
||||
}
|
||||
|
@ -1308,6 +1320,7 @@ void ClientHandler::ShowSSLInformation(CefRefPtr<CefBrowser> browser) {
|
|||
}
|
||||
|
||||
bool ClientHandler::CreatePopupWindow(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
|
@ -1320,7 +1333,8 @@ bool ClientHandler::CreatePopupWindow(CefRefPtr<CefBrowser> browser,
|
|||
// May return nullptr if UseDefaultPopup() returns true.
|
||||
return !!MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
|
||||
use_views_, use_alloy_style_, with_controls_ && !is_devtools, is_osr_,
|
||||
is_devtools, popupFeatures, windowInfo, client, settings);
|
||||
browser->GetIdentifier(), popup_id, is_devtools, popupFeatures,
|
||||
windowInfo, client, settings);
|
||||
}
|
||||
|
||||
void ClientHandler::NotifyBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
|
|
|
@ -212,6 +212,7 @@ class ClientHandler : public BaseClientHandler,
|
|||
bool OnBeforePopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||
|
@ -222,6 +223,8 @@ class ClientHandler : public BaseClientHandler,
|
|||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* no_javascript_access) override;
|
||||
void OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) override;
|
||||
void OnBeforeDevToolsPopup(CefRefPtr<CefBrowser> browser,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
|
@ -331,6 +334,7 @@ class ClientHandler : public BaseClientHandler,
|
|||
// will be true if the window will be used for DevTools. Returns true if a
|
||||
// RootWindow was created for the popup.
|
||||
bool CreatePopupWindow(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
|
|
|
@ -27,6 +27,7 @@ CefRefPtr<DefaultClientHandler> DefaultClientHandler::GetForClient(
|
|||
bool DefaultClientHandler::OnBeforePopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||
|
@ -52,11 +53,27 @@ bool DefaultClientHandler::OnBeforePopup(
|
|||
// created asynchronously.
|
||||
MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
|
||||
config.use_views, use_alloy_style_, config.with_controls,
|
||||
/*is_osr=*/false, /*is_devtools=*/false, popupFeatures, windowInfo,
|
||||
client, settings);
|
||||
/*is_osr=*/false, browser->GetIdentifier(), popup_id,
|
||||
/*is_devtools=*/false, popupFeatures, windowInfo, client, settings);
|
||||
|
||||
// Allow popup creation.
|
||||
return false;
|
||||
}
|
||||
|
||||
void DefaultClientHandler::OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
MainContext::Get()->GetRootWindowManager()->AbortOrClosePopup(
|
||||
browser->GetIdentifier(), popup_id);
|
||||
}
|
||||
|
||||
void DefaultClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Close all popups that have this browser as the opener.
|
||||
OnBeforePopupAborted(browser, /*popup_id=*/-1);
|
||||
|
||||
BaseClientHandler::OnBeforeClose(browser);
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
|
|
@ -29,6 +29,7 @@ class DefaultClientHandler : public BaseClientHandler {
|
|||
bool OnBeforePopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||
|
@ -39,6 +40,9 @@ class DefaultClientHandler : public BaseClientHandler {
|
|||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* no_javascript_access) override;
|
||||
void OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) override;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||
|
||||
private:
|
||||
// Used to determine the object type.
|
||||
|
|
|
@ -29,4 +29,28 @@ scoped_refptr<RootWindow> RootWindow::GetForBrowser(int browser_id) {
|
|||
browser_id);
|
||||
}
|
||||
|
||||
bool RootWindow::IsWindowCreated() const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return window_created_;
|
||||
}
|
||||
|
||||
void RootWindow::SetPopupId(int opener_browser_id, int popup_id) {
|
||||
DCHECK_GT(opener_browser_id, 0);
|
||||
DCHECK_GT(popup_id, 0);
|
||||
opener_browser_id_ = opener_browser_id;
|
||||
popup_id_ = popup_id;
|
||||
}
|
||||
|
||||
bool RootWindow::IsPopupIdMatch(int opener_browser_id, int popup_id) const {
|
||||
if (opener_browser_id_ == 0 || popup_id_ == 0) {
|
||||
// Not a popup.
|
||||
return false;
|
||||
}
|
||||
if (popup_id < 0) {
|
||||
// Only checking the opener.
|
||||
return opener_browser_id == opener_browser_id_;
|
||||
}
|
||||
return opener_browser_id == opener_browser_id_ && popup_id == popup_id_;
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
|
|
@ -209,6 +209,19 @@ class RootWindow
|
|||
// Returns true if this window is using windowless rendering (osr).
|
||||
virtual bool WithWindowlessRendering() const = 0;
|
||||
|
||||
// Returns true if this object has been initialized.
|
||||
bool IsInitialized() const { return initialized_; }
|
||||
|
||||
// Returns true if the platform window has been created.
|
||||
bool IsWindowCreated() const;
|
||||
|
||||
// Used to uniquely identify popup windows.
|
||||
void SetPopupId(int opener_browser_id, int popup_id);
|
||||
// If |popup_id| is -1 only match |opener_browser_id|.
|
||||
bool IsPopupIdMatch(int opener_browser_id, int popup_id) const;
|
||||
int opener_browser_id() const { return opener_browser_id_; }
|
||||
int popup_id() const { return popup_id_; }
|
||||
|
||||
protected:
|
||||
// Allow deletion via scoped_refptr only.
|
||||
friend struct DeleteOnMainThread;
|
||||
|
@ -217,10 +230,19 @@ class RootWindow
|
|||
explicit RootWindow(bool use_alloy_style);
|
||||
virtual ~RootWindow();
|
||||
|
||||
// Members set during initialization. Safe to access from any thread.
|
||||
Delegate* delegate_ = nullptr;
|
||||
bool initialized_ = false;
|
||||
|
||||
// Only accessed on the main thread.
|
||||
bool window_created_ = false;
|
||||
|
||||
private:
|
||||
const bool use_alloy_style_;
|
||||
|
||||
// Members set during initialization. Safe to access from any thread.
|
||||
int opener_browser_id_ = 0;
|
||||
int popup_id_ = 0;
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
|
|
@ -86,7 +86,6 @@ RootWindowGtk::RootWindowGtk(bool use_alloy_style)
|
|||
always_on_top_(false),
|
||||
with_osr_(false),
|
||||
is_popup_(false),
|
||||
initialized_(false),
|
||||
window_(nullptr),
|
||||
back_button_(nullptr),
|
||||
forward_button_(nullptr),
|
||||
|
@ -443,6 +442,8 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings,
|
|||
browser_window_->ShowPopup(parent, browser_bounds_.x, browser_bounds_.y,
|
||||
browser_bounds_.width, browser_bounds_.height);
|
||||
}
|
||||
|
||||
window_created_ = true;
|
||||
}
|
||||
|
||||
void RootWindowGtk::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
|
|
|
@ -131,7 +131,6 @@ class RootWindowGtk : public RootWindow, public BrowserWindow::Delegate {
|
|||
bool is_popup_;
|
||||
CefRect start_rect_;
|
||||
std::unique_ptr<BrowserWindow> browser_window_;
|
||||
bool initialized_;
|
||||
|
||||
// Main window.
|
||||
GtkWidget* window_;
|
||||
|
|
|
@ -240,7 +240,6 @@ class RootWindowMacImpl
|
|||
CefRect initial_bounds_;
|
||||
cef_show_state_t initial_show_state_ = CEF_SHOW_STATE_NORMAL;
|
||||
std::unique_ptr<BrowserWindow> browser_window_;
|
||||
bool initialized_ = false;
|
||||
|
||||
// Main window.
|
||||
NSWindow* window_ = nil;
|
||||
|
@ -273,7 +272,7 @@ RootWindowMacImpl::~RootWindowMacImpl() {
|
|||
void RootWindowMacImpl::Init(RootWindow::Delegate* delegate,
|
||||
std::unique_ptr<RootWindowConfig> config,
|
||||
const CefBrowserSettings& settings) {
|
||||
DCHECK(!initialized_);
|
||||
DCHECK(!root_window_.initialized_);
|
||||
|
||||
with_controls_ = config->with_controls;
|
||||
with_osr_ = config->with_osr;
|
||||
|
@ -294,7 +293,7 @@ void RootWindowMacImpl::Init(RootWindow::Delegate* delegate,
|
|||
|
||||
CreateBrowserWindow(config->url);
|
||||
|
||||
initialized_ = true;
|
||||
root_window_.initialized_ = true;
|
||||
|
||||
CreateRootWindow(settings, config->initially_hidden);
|
||||
}
|
||||
|
@ -307,7 +306,7 @@ void RootWindowMacImpl::InitAsPopup(RootWindow::Delegate* delegate,
|
|||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings) {
|
||||
DCHECK(delegate);
|
||||
DCHECK(!initialized_);
|
||||
DCHECK(!root_window_.initialized_);
|
||||
|
||||
with_controls_ = with_controls;
|
||||
with_osr_ = with_osr;
|
||||
|
@ -328,7 +327,7 @@ void RootWindowMacImpl::InitAsPopup(RootWindow::Delegate* delegate,
|
|||
|
||||
CreateBrowserWindow(std::string());
|
||||
|
||||
initialized_ = true;
|
||||
root_window_.initialized_ = true;
|
||||
|
||||
// The new popup is initially parented to a temporary window. The native root
|
||||
// window will be created after the browser is created and the popup window
|
||||
|
@ -632,6 +631,8 @@ void RootWindowMacImpl::CreateRootWindow(const CefBrowserSettings& settings,
|
|||
// Show the window.
|
||||
Show(mode);
|
||||
}
|
||||
|
||||
root_window_.window_created_ = true;
|
||||
}
|
||||
|
||||
void RootWindowMacImpl::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
|
|
|
@ -125,6 +125,8 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
|||
bool use_alloy_style,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
int opener_browser_id,
|
||||
int popup_id,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
|
@ -142,6 +144,9 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
CHECK_GT(opener_browser_id, 0);
|
||||
CHECK(popup_id > 0 || is_devtools);
|
||||
|
||||
SanityCheckWindowConfig(is_devtools, use_views, use_alloy_style, with_osr);
|
||||
|
||||
if (!temp_window_ && !use_views) {
|
||||
|
@ -154,6 +159,9 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
|||
|
||||
scoped_refptr<RootWindow> root_window =
|
||||
RootWindow::Create(use_views, use_alloy_style);
|
||||
if (!is_devtools) {
|
||||
root_window->SetPopupId(opener_browser_id, popup_id);
|
||||
}
|
||||
root_window->InitAsPopup(this, with_controls, with_osr, popupFeatures,
|
||||
windowInfo, client, settings);
|
||||
|
||||
|
@ -163,6 +171,12 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
|||
return root_window;
|
||||
}
|
||||
|
||||
void RootWindowManager::AbortOrClosePopup(int opener_browser_id, int popup_id) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// Continue on the main thread.
|
||||
OnAbortOrClosePopup(opener_browser_id, popup_id);
|
||||
}
|
||||
|
||||
scoped_refptr<RootWindow> RootWindowManager::GetWindowForBrowser(
|
||||
int browser_id) const {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
@ -202,28 +216,48 @@ void RootWindowManager::CloseAllWindows(bool force) {
|
|||
}
|
||||
}
|
||||
|
||||
void RootWindowManager::OtherBrowserCreated() {
|
||||
void RootWindowManager::OtherBrowserCreated(int browser_id,
|
||||
int opener_browser_id) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(base::BindOnce(&RootWindowManager::OtherBrowserCreated,
|
||||
base::Unretained(this)));
|
||||
base::Unretained(this), browser_id,
|
||||
opener_browser_id));
|
||||
return;
|
||||
}
|
||||
|
||||
other_browser_ct_++;
|
||||
|
||||
// Track ownership of popup browsers that don't have a RootWindow.
|
||||
if (opener_browser_id > 0) {
|
||||
other_browser_owners_[opener_browser_id].insert(browser_id);
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowManager::OtherBrowserClosed() {
|
||||
void RootWindowManager::OtherBrowserClosed(int browser_id,
|
||||
int opener_browser_id) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(base::BindOnce(&RootWindowManager::OtherBrowserClosed,
|
||||
base::Unretained(this)));
|
||||
base::Unretained(this), browser_id,
|
||||
opener_browser_id));
|
||||
return;
|
||||
}
|
||||
|
||||
DCHECK_GT(other_browser_ct_, 0);
|
||||
other_browser_ct_--;
|
||||
|
||||
// Track ownership of popup browsers that don't have a RootWindow.
|
||||
if (opener_browser_id > 0) {
|
||||
DCHECK(other_browser_owners_.contains(opener_browser_id));
|
||||
auto& child_set = other_browser_owners_[opener_browser_id];
|
||||
DCHECK(child_set.contains(browser_id));
|
||||
child_set.erase(browser_id);
|
||||
if (child_set.empty()) {
|
||||
other_browser_owners_.erase(opener_browser_id);
|
||||
}
|
||||
}
|
||||
|
||||
MaybeCleanup();
|
||||
}
|
||||
|
||||
|
@ -244,6 +278,55 @@ void RootWindowManager::OnRootWindowCreated(
|
|||
}
|
||||
}
|
||||
|
||||
void RootWindowManager::OnAbortOrClosePopup(int opener_browser_id,
|
||||
int popup_id) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(base::BindOnce(&RootWindowManager::OnAbortOrClosePopup,
|
||||
base::Unretained(this), opener_browser_id,
|
||||
popup_id));
|
||||
return;
|
||||
}
|
||||
|
||||
// Use a copy of |root_windows_| because the original set may be modified
|
||||
// in OnRootWindowDestroyed while iterating.
|
||||
RootWindowSet root_windows = root_windows_;
|
||||
|
||||
// Close or destroy the associated RootWindow(s). This may be a specific popup
|
||||
// (|popup_id| > 0), or all popups if the opener is closing (|popup_id| < 0).
|
||||
for (auto root_window : root_windows) {
|
||||
if (root_window->IsPopupIdMatch(opener_browser_id, popup_id)) {
|
||||
const bool window_created = root_window->IsWindowCreated();
|
||||
LOG(INFO) << (window_created ? "Closing" : "Aborting") << " popup "
|
||||
<< root_window->popup_id() << " of browser "
|
||||
<< opener_browser_id;
|
||||
if (window_created) {
|
||||
// Close the window in the usual way. Will result in a call to
|
||||
// OnRootWindowDestroyed.
|
||||
root_window->Close(/*force=*/false);
|
||||
} else {
|
||||
// The window was not created, so destroy directly.
|
||||
OnRootWindowDestroyed(root_window.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close all other associated popups if the opener is closing. These popups
|
||||
// don't have a RootWindow (e.g. when running with `--use-default-popup`).
|
||||
if (popup_id < 0 && other_browser_owners_.contains(opener_browser_id)) {
|
||||
// Use a copy as the original set may be modified in OtherBrowserClosed
|
||||
// while iterating.
|
||||
auto set = other_browser_owners_[opener_browser_id];
|
||||
for (auto browser_id : set) {
|
||||
if (auto browser = CefBrowserHost::GetBrowserByIdentifier(browser_id)) {
|
||||
LOG(INFO) << "Closing popup browser " << browser_id << " of browser "
|
||||
<< opener_browser_id;
|
||||
browser->GetHost()->CloseBrowser(/*force=*/false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return CreateRequestContext(RequestContextCallback());
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define CEF_TESTS_CEFCLIENT_BROWSER_ROOT_WINDOW_MANAGER_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
|
@ -40,12 +41,18 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||
bool use_alloy_style,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
int opener_browser_id,
|
||||
int popup_id,
|
||||
bool is_devtools,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
CefWindowInfo& windowInfo,
|
||||
CefRefPtr<CefClient>& client,
|
||||
CefBrowserSettings& settings);
|
||||
|
||||
// Abort or close the popup matching the specified identifiers. If |popup_id|
|
||||
// is -1 then all popups for |opener_browser_id| will be impacted.
|
||||
void AbortOrClosePopup(int opener_browser_id, int popup_id);
|
||||
|
||||
// Returns the RootWindow associated with the specified browser ID. Must be
|
||||
// called on the main thread.
|
||||
scoped_refptr<RootWindow> GetWindowForBrowser(int browser_id) const;
|
||||
|
@ -63,8 +70,11 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||
}
|
||||
|
||||
// Track other browsers that are not directly associated with a RootWindow.
|
||||
void OtherBrowserCreated();
|
||||
void OtherBrowserClosed();
|
||||
// This may be an overlay browser, a popup created with `--use-default-popup`,
|
||||
// or a browser using default Chrome UI. |opener_browser_id| will be > 0 for
|
||||
// popup browsers.
|
||||
void OtherBrowserCreated(int browser_id, int opener_browser_id);
|
||||
void OtherBrowserClosed(int browser_id, int opener_browser_id);
|
||||
|
||||
private:
|
||||
// Allow deletion via std::unique_ptr only.
|
||||
|
@ -73,6 +83,7 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||
~RootWindowManager() override;
|
||||
|
||||
void OnRootWindowCreated(scoped_refptr<RootWindow> root_window);
|
||||
void OnAbortOrClosePopup(int opener_browser_id, int popup_id);
|
||||
|
||||
// RootWindow::Delegate methods.
|
||||
CefRefPtr<CefRequestContext> GetRequestContext() override;
|
||||
|
@ -95,12 +106,19 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||
bool request_context_shared_cache_;
|
||||
|
||||
// Existing root windows. Only accessed on the main thread.
|
||||
typedef std::set<scoped_refptr<RootWindow>> RootWindowSet;
|
||||
using RootWindowSet = std::set<scoped_refptr<RootWindow>>;
|
||||
RootWindowSet root_windows_;
|
||||
|
||||
// Count of other browsers. Only accessed on the main thread.
|
||||
// Count of browsers that are not directly associated with a RootWindow. Only
|
||||
// accessed on the main thread.
|
||||
int other_browser_ct_ = 0;
|
||||
|
||||
// Map of owner browser ID to popup browser IDs for popups that don't have a
|
||||
// RootWindow. Only accessed on the main thread.
|
||||
using BrowserIdSet = std::set<int>;
|
||||
using BrowserOwnerMap = std::map<int, BrowserIdSet>;
|
||||
BrowserOwnerMap other_browser_owners_;
|
||||
|
||||
// The currently active/foreground RootWindow. Only accessed on the main
|
||||
// thread.
|
||||
scoped_refptr<RootWindow> active_root_window_;
|
||||
|
|
|
@ -235,6 +235,17 @@ void RootWindowViews::OnViewsWindowCreated(CefRefPtr<ViewsWindow> window) {
|
|||
DCHECK(!window_);
|
||||
window_ = window;
|
||||
window_->SetAlwaysOnTop(config_->always_on_top);
|
||||
|
||||
if (CURRENTLY_ON_MAIN_THREAD()) {
|
||||
window_created_ = true;
|
||||
} else {
|
||||
// Execute on the main thread.
|
||||
MAIN_POST_CLOSURE(base::BindOnce(
|
||||
[](scoped_refptr<RootWindowViews> self) {
|
||||
self->window_created_ = true;
|
||||
},
|
||||
scoped_refptr<RootWindowViews>(this)));
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowViews::OnViewsWindowClosing(CefRefPtr<ViewsWindow> window) {
|
||||
|
|
|
@ -105,7 +105,6 @@ class RootWindowViews : public RootWindow,
|
|||
// Members set during initialization. Safe to access from any thread.
|
||||
std::unique_ptr<RootWindowConfig> config_;
|
||||
CefRefPtr<ClientHandler> client_handler_;
|
||||
bool initialized_ = false;
|
||||
|
||||
// Only accessed on the main thread.
|
||||
CefRefPtr<CefBrowser> browser_;
|
||||
|
|
|
@ -1017,6 +1017,8 @@ void RootWindowWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {
|
|||
browser_window_->ShowPopup(hwnd_, rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
window_created_ = true;
|
||||
}
|
||||
|
||||
bool RootWindowWin::OnClose() {
|
||||
|
|
|
@ -126,7 +126,6 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
|
|||
cef_show_state_t initial_show_state_ = CEF_SHOW_STATE_NORMAL;
|
||||
std::unique_ptr<BrowserWindow> browser_window_;
|
||||
CefBrowserSettings browser_settings_;
|
||||
bool initialized_ = false;
|
||||
|
||||
// Main window.
|
||||
HWND hwnd_ = nullptr;
|
||||
|
|
|
@ -412,6 +412,11 @@ struct FrameStatus {
|
|||
EXPECT_FALSE(browser->IsValid()) << func;
|
||||
}
|
||||
|
||||
const auto browser_id = browser->GetIdentifier();
|
||||
EXPECT_GT(browser_id, 0) << func;
|
||||
auto get_browser = CefBrowserHost::GetBrowserByIdentifier(browser_id);
|
||||
EXPECT_TRUE(get_browser && get_browser->IsSame(browser)) << func;
|
||||
|
||||
// Note that this might not be the same main frame as us when navigating
|
||||
// cross-origin, because the new main frame object is assigned to the
|
||||
// browser before the CefFrameHandler callbacks related to main frame change
|
||||
|
@ -1641,6 +1646,7 @@ class ParentOrderMainTestHandler : public OrderMainTestHandler {
|
|||
bool OnBeforePopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||
|
|
|
@ -1480,6 +1480,7 @@ class OrderNavTestHandler : public TestHandler {
|
|||
bool OnBeforePopup(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||
|
@ -2270,6 +2271,7 @@ class PopupSimultaneousTestHandler : public TestHandler {
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -2429,6 +2431,7 @@ class PopupJSWindowOpenTestHandler : public TestHandler {
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -2576,6 +2579,7 @@ class PopupJSWindowEmptyTestHandler : public TestHandler {
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -3602,6 +3606,7 @@ class ExtraInfoNavTestHandler : public TestHandler {
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
|
|
@ -213,6 +213,7 @@ class OsrPopupJSOtherClientTestHandler : public TestHandler,
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -346,6 +347,7 @@ class OsrPopupJSOtherCefClient : public CefClient,
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
|
|
@ -203,6 +203,8 @@ class PopupTestHandler : public TestHandler {
|
|||
enum Mode {
|
||||
MODE_WINDOW_OPEN,
|
||||
MODE_TARGETED_LINK,
|
||||
// The no-referrer popup won't have an opener from the renderer's
|
||||
// perspective, but we still track it from the browser's perspective.
|
||||
MODE_NOREFERRER_LINK,
|
||||
};
|
||||
|
||||
|
@ -284,6 +286,7 @@ class PopupTestHandler : public TestHandler {
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -294,8 +297,14 @@ class PopupTestHandler : public TestHandler {
|
|||
CefBrowserSettings& settings,
|
||||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* no_javascript_access) override {
|
||||
EXPECT_FALSE(got_on_before_popup_);
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
EXPECT_FALSE(got_on_after_created_popup_);
|
||||
got_on_before_popup_.yes();
|
||||
|
||||
// Only ever a single popup with this test.
|
||||
EXPECT_EQ(1, popup_id);
|
||||
|
||||
const std::string& url = target_url;
|
||||
EXPECT_STREQ(url.c_str(), popup_url_.c_str());
|
||||
|
||||
|
@ -310,6 +319,30 @@ class PopupTestHandler : public TestHandler {
|
|||
return false;
|
||||
}
|
||||
|
||||
void OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) override {
|
||||
EXPECT_TRUE(got_on_before_popup_);
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
EXPECT_FALSE(got_on_after_created_popup_);
|
||||
got_on_before_popup_aborted_.yes();
|
||||
|
||||
// Only ever a single popup with this test.
|
||||
EXPECT_EQ(1, popup_id);
|
||||
}
|
||||
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
||||
if (browser->IsPopup()) {
|
||||
EXPECT_TRUE(got_on_before_popup_);
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
got_on_after_created_popup_.yes();
|
||||
// Opener is the main browser.
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetHost()->GetOpenerIdentifier());
|
||||
} else {
|
||||
EXPECT_EQ(0, browser->GetHost()->GetOpenerIdentifier());
|
||||
}
|
||||
TestHandler::OnAfterCreated(browser);
|
||||
}
|
||||
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
|
||||
TestHandler::OnBeforeClose(browser);
|
||||
|
||||
|
@ -372,6 +405,8 @@ class PopupTestHandler : public TestHandler {
|
|||
// Verify test expectations.
|
||||
EXPECT_TRUE(got_load_end1_);
|
||||
EXPECT_TRUE(got_on_before_popup_);
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
EXPECT_TRUE(got_on_after_created_popup_);
|
||||
EXPECT_TRUE(got_load_end2_);
|
||||
EXPECT_TRUE(got_cookie1_);
|
||||
EXPECT_TRUE(got_cookie2_);
|
||||
|
@ -389,6 +424,8 @@ class PopupTestHandler : public TestHandler {
|
|||
|
||||
TrackCallback got_load_end1_;
|
||||
TrackCallback got_on_before_popup_;
|
||||
TrackCallback got_on_before_popup_aborted_;
|
||||
TrackCallback got_on_after_created_popup_;
|
||||
TrackCallback got_load_end2_;
|
||||
TrackCallback got_cookie1_;
|
||||
TrackCallback got_cookie2_;
|
||||
|
@ -516,6 +553,7 @@ class PopupNavTestHandler : public TestHandler {
|
|||
|
||||
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int popup_id,
|
||||
const CefString& target_url,
|
||||
const CefString& target_frame_name,
|
||||
cef_window_open_disposition_t target_disposition,
|
||||
|
@ -527,10 +565,16 @@ class PopupNavTestHandler : public TestHandler {
|
|||
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||
bool* no_javascript_access) override {
|
||||
EXPECT_FALSE(got_on_before_popup_);
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
got_on_before_popup_.yes();
|
||||
|
||||
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
|
||||
// Only ever a single popup with this test.
|
||||
EXPECT_EQ(1, popup_id);
|
||||
opener_browser_id_ = browser->GetIdentifier();
|
||||
EXPECT_EQ(GetBrowserId(), opener_browser_id_);
|
||||
|
||||
EXPECT_STREQ(kPopupNavPageUrl, frame->GetURL().ToString().c_str());
|
||||
EXPECT_STREQ(kPopupNavPopupUrl, target_url.ToString().c_str());
|
||||
EXPECT_STREQ(kPopupNavPopupName, target_frame_name.ToString().c_str());
|
||||
|
@ -547,8 +591,32 @@ class PopupNavTestHandler : public TestHandler {
|
|||
return (mode_ == DENY); // Return true to cancel the popup.
|
||||
}
|
||||
|
||||
void OnBeforePopupAborted(CefRefPtr<CefBrowser> browser,
|
||||
int popup_id) override {
|
||||
EXPECT_TRUE(got_on_before_popup_);
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
got_on_before_popup_aborted_.yes();
|
||||
|
||||
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
|
||||
|
||||
// Can't use GetBrowserId() here because the opener is already closing.
|
||||
EXPECT_EQ(opener_browser_id_, browser->GetIdentifier());
|
||||
EXPECT_FALSE(browser->IsValid());
|
||||
|
||||
// Only ever a single popup with this test.
|
||||
EXPECT_EQ(1, popup_id);
|
||||
}
|
||||
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
||||
TestHandler::OnAfterCreated(browser);
|
||||
if (browser->IsPopup()) {
|
||||
EXPECT_TRUE(got_on_before_popup_);
|
||||
EXPECT_EQ(opener_browser_id_, browser->GetHost()->GetOpenerIdentifier());
|
||||
} else {
|
||||
EXPECT_FALSE(got_on_before_popup_);
|
||||
EXPECT_EQ(0, browser->GetHost()->GetOpenerIdentifier());
|
||||
}
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
|
||||
if (browser->IsPopup() && (mode_ == DESTROY_PARENT_AFTER_CREATION ||
|
||||
mode_ == DESTROY_PARENT_AFTER_CREATION_FORCE)) {
|
||||
|
@ -684,10 +752,24 @@ class PopupNavTestHandler : public TestHandler {
|
|||
EXPECT_TRUE(got_load_end_);
|
||||
|
||||
// OnBeforePopup may come before or after browser destruction with the
|
||||
// DESTROY_PARENT_BEFORE_CREATION* tests.
|
||||
// DESTROY_PARENT_BEFORE_CREATION* tests and Alloy style browsers.
|
||||
if (mode_ != DESTROY_PARENT_BEFORE_CREATION &&
|
||||
mode_ != DESTROY_PARENT_BEFORE_CREATION_FORCE) {
|
||||
EXPECT_TRUE(got_on_before_popup_);
|
||||
} else if (!use_alloy_style_browser()) {
|
||||
EXPECT_FALSE(got_on_before_popup_);
|
||||
}
|
||||
|
||||
if (mode_ == DESTROY_PARENT_DURING_CREATION ||
|
||||
mode_ == DESTROY_PARENT_DURING_CREATION_FORCE ||
|
||||
mode_ == DESTROY_PARENT_AFTER_CREATION ||
|
||||
mode_ == DESTROY_PARENT_AFTER_CREATION_FORCE) {
|
||||
// Timing of Alloy style browsers may not result in abort.
|
||||
if (!use_alloy_style_browser()) {
|
||||
EXPECT_TRUE(got_on_before_popup_aborted_);
|
||||
}
|
||||
} else {
|
||||
EXPECT_FALSE(got_on_before_popup_aborted_);
|
||||
}
|
||||
|
||||
if (mode_ == ALLOW_CLOSE_POPUP_FIRST || mode_ == ALLOW_CLOSE_POPUP_LAST) {
|
||||
|
@ -737,6 +819,8 @@ class PopupNavTestHandler : public TestHandler {
|
|||
const std::string rc_cache_path_;
|
||||
|
||||
TrackCallback got_on_before_popup_;
|
||||
int opener_browser_id_ = 0;
|
||||
TrackCallback got_on_before_popup_aborted_;
|
||||
TrackCallback got_load_start_;
|
||||
TrackCallback got_load_error_;
|
||||
TrackCallback got_load_end_;
|
||||
|
|
Loading…
Reference in New Issue