in libcef/browser/browser_info_manager.cc [106:207]
bool CefBrowserInfoManager::CanCreateWindow(
content::RenderFrameHost* opener,
const GURL& target_url,
const content::Referrer& referrer,
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
bool user_gesture,
bool opener_suppressed,
bool* no_javascript_access) {
CEF_REQUIRE_UIT();
content::OpenURLParams params(target_url, referrer, disposition,
ui::PAGE_TRANSITION_LINK,
/*is_renderer_initiated=*/true);
params.user_gesture = user_gesture;
CefRefPtr<CefBrowserHostBase> browser;
if (!MaybeAllowNavigation(opener, params, browser) || !browser) {
// Cancel the popup.
return false;
}
CefRefPtr<CefClient> client = browser->GetClient();
bool allow = true;
std::unique_ptr<CefWindowInfo> window_info(new CefWindowInfo);
#if defined(OS_WIN)
window_info->SetAsPopup(nullptr, CefString());
#endif
auto pending_popup = std::make_unique<CefBrowserInfoManager::PendingPopup>();
pending_popup->step = CefBrowserInfoManager::PendingPopup::CAN_CREATE_WINDOW;
pending_popup->opener_global_id = opener->GetGlobalId();
pending_popup->target_url = target_url;
pending_popup->target_frame_name = frame_name;
// Start with the current browser's settings.
pending_popup->client = client;
pending_popup->settings = browser->settings();
if (client.get()) {
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
if (handler.get()) {
CefRefPtr<CefFrame> opener_frame = browser->GetFrameForHost(opener);
DCHECK(opener_frame);
CefPopupFeatures cef_features;
TranslatePopupFeatures(features, cef_features);
#if (defined(OS_WIN) || defined(OS_MAC))
// Default to the size from the popup features.
if (cef_features.xSet)
window_info->bounds.x = cef_features.x;
if (cef_features.ySet)
window_info->bounds.y = cef_features.y;
if (cef_features.widthSet)
window_info->bounds.width = cef_features.width;
if (cef_features.heightSet)
window_info->bounds.height = cef_features.height;
#endif
allow = !handler->OnBeforePopup(
browser.get(), opener_frame, 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);
}
}
if (allow) {
CefBrowserCreateParams create_params;
if (browser->HasView()) {
create_params.popup_with_views_hosted_opener = true;
} else {
create_params.window_info = std::move(window_info);
}
create_params.settings = pending_popup->settings;
create_params.client = pending_popup->client;
create_params.extra_info = pending_popup->extra_info;
pending_popup->platform_delegate =
CefBrowserPlatformDelegate::Create(create_params);
CHECK(pending_popup->platform_delegate.get());
// Between the calls to CanCreateWindow and GetCustomWebContentsView
// RenderViewHostImpl::CreateNewWindow() will call
// RenderProcessHostImpl::FilterURL() which, in the case of "javascript:"
// URIs, rewrites the URL to "about:blank". We need to apply the same filter
// otherwise GetCustomWebContentsView will fail to retrieve the PopupInfo.
opener->GetProcess()->FilterURL(false, &pending_popup->target_url);
PushPendingPopup(std::move(pending_popup));
}
return allow;
}