diff --git a/include/capi/cef_life_span_handler_capi.h b/include/capi/cef_life_span_handler_capi.h index fa39f5553..0aebcf980 100644 --- a/include/capi/cef_life_span_handler_capi.h +++ b/include/capi/cef_life_span_handler_capi.h @@ -59,38 +59,21 @@ typedef struct _cef_life_span_handler_t { /// // Called on the IO thread before a new popup window is created. The |browser| // and |frame| parameters represent the source of the popup request. The - // |target_url| and |target_frame_name| values may be NULL if none was - // specified with the request. Return true (1) to allow creation of the popup - // window or false (0) to cancel creation. If true (1) is returned, - // |no_javascript_access| will indicate whether the window that is created - // should be scriptable/in the same process as the source browser. Do not - // perform blocking work in this callback as it will block the associated - // render process. To completely disable popup windows for a browser set - // cef_browser_tSettings.javascript_open_windows to STATE_DISABLED. - /// - int (CEF_CALLBACK *can_create_popup)(struct _cef_life_span_handler_t* self, + // |target_url| and |target_frame_name| values may be NULL if none were + // specified with the request. The |popupFeatures| structure contains + // information about the requested popup window. To allow creation of the + // popup window optionally modify |windowInfo|, |client|, |settings| and + // |no_javascript_access| and return false (0). To cancel creation of the + // popup window return true (1). The |client| and |settings| values will + // default to the source browser's values. The |no_javascript_access| value + // indicates whether the new browser window should be scriptable and in the + // same process as the source browser. + int (CEF_CALLBACK *on_before_popup)(struct _cef_life_span_handler_t* self, struct _cef_browser_t* browser, struct _cef_frame_t* frame, const cef_string_t* target_url, const cef_string_t* target_frame_name, - int* no_javascript_access); - - /// - // Called before the cef_browser_host_t object associated with a new popup - // window is created. This function will only be called in can_create_popup() - // returns true (1). The |browser| parameter represents the source of the - // popup request. The |popupFeatures| parameter will contain information about - // the style of popup window requested. The framework will create the new - // popup window based on the parameters in |windowInfo|. By default, a newly - // created popup window will have the same client and settings as the parent - // window. To change the client for the new window modify the object that - // |client| points to. To change the settings for the new window modify the - // |settings| structure. - /// - void (CEF_CALLBACK *on_before_popup)(struct _cef_life_span_handler_t* self, - struct _cef_browser_t* browser, const struct _cef_popup_features_t* popupFeatures, - struct _cef_window_info_t* windowInfo, const cef_string_t* target_url, - const cef_string_t* target_frame_name, struct _cef_client_t** client, - struct _cef_browser_settings_t* settings); + struct _cef_window_info_t* windowInfo, struct _cef_client_t** client, + struct _cef_browser_settings_t* settings, int* no_javascript_access); /// // Called after a new window is created. diff --git a/include/cef_life_span_handler.h b/include/cef_life_span_handler.h index f94dc959e..eed9caf4f 100644 --- a/include/cef_life_span_handler.h +++ b/include/cef_life_span_handler.h @@ -54,44 +54,27 @@ class CefLifeSpanHandler : public virtual CefBase { /// // Called on the IO thread before a new popup window is created. The |browser| // and |frame| parameters represent the source of the popup request. The - // |target_url| and |target_frame_name| values may be empty if none was - // specified with the request. Return true to allow creation of the popup - // window or false to cancel creation. If true is returned, - // |no_javascript_access| will indicate whether the window that is created - // should be scriptable/in the same process as the source browser. Do not - // perform blocking work in this callback as it will block the associated - // render process. To completely disable popup windows for a browser set - // CefBrowserSettings.javascript_open_windows to STATE_DISABLED. - /// + // |target_url| and |target_frame_name| values may be empty if none were + // specified with the request. The |popupFeatures| structure contains + // information about the requested popup window. To allow creation of the + // popup window optionally modify |windowInfo|, |client|, |settings| and + // |no_javascript_access| and return false. To cancel creation of the popup + // window return true. The |client| and |settings| values will default to the + // source browser's values. The |no_javascript_access| value indicates whether + // the new browser window should be scriptable and in the same process as the + // source browser. /*--cef(optional_param=target_url,optional_param=target_frame_name)--*/ - virtual bool CanCreatePopup(CefRefPtr browser, - CefRefPtr frame, - const CefString& target_url, - const CefString& target_frame_name, - bool* no_javascript_access) { - return true; - } - - /// - // Called before the CefBrowserHost object associated with a new popup window - // is created. This method will only be called in CanCreatePopup() returns - // true. The |browser| parameter represents the source of the popup request. - // The |popupFeatures| parameter will contain information about the style of - // popup window requested. The framework will create the new popup window - // based on the parameters in |windowInfo|. By default, a newly created popup - // window will have the same client and settings as the parent window. To - // change the client for the new window modify the object that |client| points - // to. To change the settings for the new window modify the |settings| - // structure. - /// - /*--cef(optional_param=target_url,optional_param=target_frame_name)--*/ - virtual void OnBeforePopup(CefRefPtr browser, - const CefPopupFeatures& popupFeatures, - CefWindowInfo& windowInfo, + virtual bool OnBeforePopup(CefRefPtr browser, + CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, CefRefPtr& client, - CefBrowserSettings& settings) {} + CefBrowserSettings& settings, + bool* no_javascript_access) { + return false; + } /// // Called after a new window is created. diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index e523ffd43..eb4abaed3 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -1071,7 +1071,7 @@ void CefBrowserHostImpl::Navigate(const CefNavigateParams& params) { CefMsg_LoadRequest_Params request; request.url = params.url; if (!request.url.is_valid()) { - DLOG(ERROR) << "Invalid URL passed to CefBrowserHostImpl::Navigate: " << + LOG(ERROR) << "Invalid URL passed to CefBrowserHostImpl::Navigate: " << params.url; return; } @@ -1130,7 +1130,7 @@ void CefBrowserHostImpl::LoadURL(int64 frame_id, const std::string& url) { } if (!gurl.is_valid()) { - DLOG(ERROR) << + LOG(ERROR) << "Invalid URL passed to CefBrowserHostImpl::LoadURL: " << url; return; } @@ -1491,56 +1491,13 @@ bool CefBrowserHostImpl::ShouldCreateWebContents( WindowContainerType window_container_type, const string16& frame_name, const GURL& target_url) { - // Start with the current browser window's client and settings. - pending_client_ = client_; - pending_settings_ = settings_; - - // TODO(cef): Figure out how to populate these values. - // See: http://crbug.com/110510 - CefPopupFeatures features; - - pending_window_info_ = CefWindowInfo(); -#if defined(OS_WIN) - pending_window_info_.SetAsPopup(NULL, CefString()); -#endif - -#if (defined(OS_WIN) || defined(OS_MACOSX)) - // Default to the size from the popup features. - if (features.xSet) - pending_window_info_.x = features.x; - if (features.ySet) - pending_window_info_.y = features.y; - if (features.widthSet) - pending_window_info_.width = features.width; - if (features.heightSet) - pending_window_info_.height = features.height; -#endif - - if (client_.get()) { - CefRefPtr handler = client_->GetLifeSpanHandler(); - // Give the handler an opportunity to modify window attributes, handler, - // or cancel the window creation. - if (handler.get()) { - handler->OnBeforePopup(this, features, pending_window_info_, - target_url.spec(), frame_name, - pending_client_, pending_settings_); - } - } - - if (IsWindowRenderingDisabled(pending_window_info_)) { - if (!pending_client_->GetRenderHandler().get()) { - NOTREACHED() << "CefRenderHandler implementation is required"; - return false; - } - if (pending_settings_.accelerated_compositing != STATE_DISABLED) { - // Accelerated compositing is not supported when window rendering is - // disabled. - pending_settings_.accelerated_compositing = STATE_DISABLED; - } - } + CefContentBrowserClient::Get()->GetOrCreateBrowserInfo( + web_contents->GetRenderProcessHost()->GetID(), route_id); + base::AutoLock lock_scope(pending_popup_info_lock_); + DCHECK(pending_popup_info_.get()); _Context->browser_context()->set_use_osr_next_contents_view( - IsWindowRenderingDisabled(pending_window_info_)); + IsWindowRenderingDisabled(pending_popup_info_->window_info)); return true; } @@ -1550,28 +1507,29 @@ void CefBrowserHostImpl::WebContentsCreated( int64 source_frame_id, const GURL& target_url, content::WebContents* new_contents) { - CefWindowHandle opener = NULL; - scoped_refptr info; - if (source_contents) { - opener = GetBrowserForContents(source_contents)->GetWindowHandle(); + scoped_ptr pending_popup_info; + { + base::AutoLock lock_scope(pending_popup_info_lock_); + pending_popup_info.reset(pending_popup_info_.release()); + } + DCHECK(pending_popup_info.get()); - // Popup windows may not have info yet. - info = CefContentBrowserClient::Get()->GetOrCreateBrowserInfo( - new_contents->GetRenderProcessHost()->GetID(), - new_contents->GetRoutingID()); + CefWindowHandle opener = NULL; + scoped_refptr info = + CefContentBrowserClient::Get()->GetBrowserInfo( + new_contents->GetRenderProcessHost()->GetID(), + new_contents->GetRoutingID()); + + if (source_contents) { DCHECK(info->is_popup()); + opener = GetBrowserForContents(source_contents)->GetWindowHandle(); } else { - info = CefContentBrowserClient::Get()->GetBrowserInfo( - new_contents->GetRenderProcessHost()->GetID(), - new_contents->GetRoutingID()); DCHECK(!info->is_popup()); } CefRefPtr browser = CefBrowserHostImpl::Create( - pending_window_info_, pending_settings_, pending_client_, new_contents, - info, opener); - - pending_client_ = NULL; + pending_popup_info->window_info, pending_popup_info->settings, + pending_popup_info->client, new_contents, info, opener); } void CefBrowserHostImpl::DidNavigateMainFramePostCommit( @@ -1599,6 +1557,15 @@ void CefBrowserHostImpl::RunFileChooser( tab)); } +bool CefBrowserHostImpl::SetPendingPopupInfo( + scoped_ptr info) { + base::AutoLock lock_scope(pending_popup_info_lock_); + if (pending_popup_info_.get()) + return false; + pending_popup_info_.reset(info.release()); + return true; +} + void CefBrowserHostImpl::UpdatePreferredSize(content::WebContents* source, const gfx::Size& pref_size) { PlatformSizeTo(pref_size.width(), pref_size.height()); diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index 0a90f7b14..56a08ad26 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -243,6 +243,15 @@ class CefBrowserHostImpl : public CefBrowserHost, void RunFileChooser(const content::FileChooserParams& params, const RunFileChooserCallback& callback); + // Used when creating a new popup window. + struct PendingPopupInfo { + CefWindowInfo window_info; + CefBrowserSettings settings; + CefRefPtr client; + }; + // Returns false if a popup is already pending. + bool SetPendingPopupInfo(scoped_ptr info); + private: // content::WebContentsDelegate methods. virtual content::WebContents* OpenURLFromTab( @@ -442,10 +451,10 @@ class CefBrowserHostImpl : public CefBrowserHost, scoped_refptr browser_info_; CefWindowHandle opener_; - // Used when creating a new popup window. - CefWindowInfo pending_window_info_; - CefBrowserSettings pending_settings_; - CefRefPtr pending_client_; + // Pending popup information. Access must be protected by + // |pending_popup_info_lock_|. + base::Lock pending_popup_info_lock_; + scoped_ptr pending_popup_info_; // Volatile state information. All access must be protected by the state lock. base::Lock state_lock_; diff --git a/libcef/browser/browser_main.cc b/libcef/browser/browser_main.cc index e875f3069..c2fca57dc 100644 --- a/libcef/browser/browser_main.cc +++ b/libcef/browser/browser_main.cc @@ -85,7 +85,7 @@ void CefBrowserMainParts::PreMainMessageLoopRun() { if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) { devtools_delegate_ = new CefDevToolsDelegate(port); } else { - DLOG(WARNING) << "Invalid http debugger port number " << port; + LOG(WARNING) << "Invalid http debugger port number " << port; } } } diff --git a/libcef/browser/browser_message_filter.cc b/libcef/browser/browser_message_filter.cc index e54a8c2bd..057bee82e 100644 --- a/libcef/browser/browser_message_filter.cc +++ b/libcef/browser/browser_message_filter.cc @@ -47,7 +47,7 @@ bool CefBrowserMessageFilter::OnMessageReceived(const IPC::Message& message) { OnGetNewRenderThreadInfo) IPC_MESSAGE_HANDLER(CefProcessHostMsg_GetNewBrowserInfo, OnGetNewBrowserInfo) - IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_CreateWindow, OnCreateWindow) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -86,13 +86,15 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo( void CefBrowserMessageFilter::OnCreateWindow( const ViewHostMsg_CreateWindow_Params& params, - int* route_id, - int* surface_id, - int64* cloned_session_storage_namespace_id) { + IPC::Message* reply_msg) { CefContentBrowserClient::LastCreateWindowParams lcwp; - lcwp.opener_id = params.opener_id; + lcwp.opener_process_id = host_->GetID(); + lcwp.opener_view_id = params.opener_id; lcwp.opener_frame_id = params.opener_frame_id; lcwp.target_url = params.target_url; lcwp.target_frame_name = params.frame_name; CefContentBrowserClient::Get()->set_last_create_window_params(lcwp); + + // Reply message is not used. + delete reply_msg; } diff --git a/libcef/browser/browser_message_filter.h b/libcef/browser/browser_message_filter.h index 8e017e497..490723165 100644 --- a/libcef/browser/browser_message_filter.h +++ b/libcef/browser/browser_message_filter.h @@ -37,9 +37,7 @@ class CefBrowserMessageFilter : public IPC::ChannelProxy::MessageFilter { void OnGetNewBrowserInfo(int routing_id, CefProcessHostMsg_GetNewBrowserInfo_Params* params); void OnCreateWindow(const ViewHostMsg_CreateWindow_Params& params, - int* route_id, - int* surface_id, - int64* cloned_session_storage_namespace_id); + IPC::Message* reply_msg); content::RenderProcessHost* host_; IPC::Channel* channel_; diff --git a/libcef/browser/chrome_scheme_handler.cc b/libcef/browser/chrome_scheme_handler.cc index 516cb5bf8..c5e15e1ff 100644 --- a/libcef/browser/chrome_scheme_handler.cc +++ b/libcef/browser/chrome_scheme_handler.cc @@ -210,7 +210,7 @@ class Delegate : public InternalHandlerDelegate { } if (!handled && domain != CHROME_VERSION) { - DLOG(INFO) << "Reguest for unknown chrome resource: " << + LOG(INFO) << "Reguest for unknown chrome resource: " << url.spec().c_str(); action->redirect_url = GURL(std::string(kChromeURL) + kChromeVersionDomain); diff --git a/libcef/browser/content_browser_client.cc b/libcef/browser/content_browser_client.cc index f8339185e..44c52a13f 100644 --- a/libcef/browser/content_browser_client.cc +++ b/libcef/browser/content_browser_client.cc @@ -253,7 +253,7 @@ CefContentBrowserClient::CefContentBrowserClient() content::PluginServiceImpl::GetInstance()->SetFilter( plugin_service_filter_.get()); - last_create_window_params_.opener_id = MSG_ROUTING_NONE; + last_create_window_params_.opener_process_id = MSG_ROUTING_NONE; } CefContentBrowserClient::~CefContentBrowserClient() { @@ -354,8 +354,8 @@ scoped_refptr CefContentBrowserClient::GetBrowserInfo( return browser_info; } - DLOG(WARNING) << "No browser info matching process id " << - render_process_id << " and view id " << render_view_id; + LOG(WARNING) << "No browser info matching process id " << + render_process_id << " and view id " << render_view_id; return scoped_refptr(); } @@ -467,35 +467,92 @@ bool CefContentBrowserClient::CanCreateWindow( CEF_REQUIRE_IOT(); *no_javascript_access = false; - DCHECK_NE(last_create_window_params_.opener_id, MSG_ROUTING_NONE); - if (last_create_window_params_.opener_id == MSG_ROUTING_NONE) + DCHECK_NE(last_create_window_params_.opener_process_id, MSG_ROUTING_NONE); + if (last_create_window_params_.opener_process_id == MSG_ROUTING_NONE) return false; CefRefPtr browser = CefBrowserHostImpl::GetBrowserByRoutingID( - render_process_id, - last_create_window_params_.opener_id); + last_create_window_params_.opener_process_id, + last_create_window_params_.opener_view_id); DCHECK(browser.get()); - if (!browser.get()) + if (!browser.get()) { + LOG(WARNING) << "CanCreateWindow called before browser was created"; return false; - - bool allow = true; + } CefRefPtr client = browser->GetClient(); + bool allow = true; + + scoped_ptr pending_info; + pending_info.reset(new CefBrowserHostImpl::PendingPopupInfo); + +#if defined(OS_WIN) + pending_info->window_info.SetAsPopup(NULL, CefString()); +#endif + + // Start with the current browser's settings. + pending_info->client = client; + pending_info->settings = browser->settings(); + if (client.get()) { CefRefPtr handler = client->GetLifeSpanHandler(); if (handler.get()) { CefRefPtr frame = browser->GetFrame(last_create_window_params_.opener_frame_id); - allow = handler->CanCreatePopup(browser.get(), + + // TODO(cef): Figure out how to populate CefPopupFeatures. + // See: http://crbug.com/110510 + CefPopupFeatures features; + +#if (defined(OS_WIN) || defined(OS_MACOSX)) + // Default to the size from the popup features. + if (features.xSet) + pending_info->window_info.x = features.x; + if (features.ySet) + pending_info->window_info.y = features.y; + if (features.widthSet) + pending_info->window_info.width = features.width; + if (features.heightSet) + pending_info->window_info.height = features.height; +#endif + + allow = !handler->OnBeforePopup(browser.get(), frame, last_create_window_params_.target_url.spec(), last_create_window_params_.target_frame_name, + features, + pending_info->window_info, + pending_info->client, + pending_info->settings, no_javascript_access); + if (allow) { + if (CefBrowserHostImpl::IsWindowRenderingDisabled( + pending_info->window_info)) { + if (!pending_info->client->GetRenderHandler().get()) { + NOTREACHED() << "CefRenderHandler implementation is required"; + allow = false; + } + if (pending_info->settings.accelerated_compositing != STATE_DISABLED) { + // Accelerated compositing is not supported when window rendering is + // disabled. + pending_info->settings.accelerated_compositing = STATE_DISABLED; + } + } + } } } - last_create_window_params_.opener_id = MSG_ROUTING_NONE; + if (allow) { + CefRefPtr pending_client = pending_info->client; + allow = browser->SetPendingPopupInfo(pending_info.Pass()); + if (!allow) { + LOG(WARNING) << "Creation of popup window denied because one is already " + "pending."; + } + } + + last_create_window_params_.opener_process_id = MSG_ROUTING_NONE; return allow; } diff --git a/libcef/browser/content_browser_client.h b/libcef/browser/content_browser_client.h index d62b4d255..04624e6fe 100644 --- a/libcef/browser/content_browser_client.h +++ b/libcef/browser/content_browser_client.h @@ -44,9 +44,9 @@ class CefContentBrowserClient : public content::ContentBrowserClient { // these methods. // During popup window creation there is a race between the call to // CefBrowserMessageFilter::OnGetNewBrowserInfo on the IO thread and the call - // to CefBrowserHostImpl::WebContentsCreated on the UI thread. To resolve this - // race CefBrowserInfo may be created when requested for the first time and - // before the associated CefBrowserHostImpl is created. + // to CefBrowserHostImpl::ShouldCreateWebContents on the UI thread. To resolve + // this race CefBrowserInfo may be created when requested for the first time + // and before the associated CefBrowserHostImpl is created. scoped_refptr CreateBrowserInfo(); scoped_refptr GetOrCreateBrowserInfo(int render_process_id, int render_view_id); @@ -93,7 +93,8 @@ class CefContentBrowserClient : public content::ContentBrowserClient { // Store additional state from the ViewHostMsg_CreateWindow message that will // be used when CanCreateWindow() is called. struct LastCreateWindowParams { - int opener_id; + int opener_process_id; + int opener_view_id; int64 opener_frame_id; GURL target_url; string16 target_frame_name; diff --git a/libcef/browser/context.cc b/libcef/browser/context.cc index 1c056edce..12775dddf 100644 --- a/libcef/browser/context.cc +++ b/libcef/browser/context.cc @@ -281,9 +281,9 @@ CefRefPtr CefContext::GetBrowserByRoutingID( if (info.get()) { CefRefPtr browser = info->browser(); if (!browser.get()) { - DLOG(WARNING) << "Found browser id " << info->browser_id() << - " but no browser object matching process id " << - render_process_id << " and view id " << render_view_id; + LOG(WARNING) << "Found browser id " << info->browser_id() << + " but no browser object matching process id " << + render_process_id << " and view id " << render_view_id; } return browser; } diff --git a/libcef/common/task_runner_impl.cc b/libcef/common/task_runner_impl.cc index 1ba8bf405..da3e06041 100644 --- a/libcef/common/task_runner_impl.cc +++ b/libcef/common/task_runner_impl.cc @@ -32,7 +32,7 @@ CefRefPtr CefTaskRunner::GetForThread(CefThreadId threadId) { if (task_runner.get()) return new CefTaskRunnerImpl(task_runner); - DLOG(WARNING) << "Invalid thread id " << threadId; + LOG(WARNING) << "Invalid thread id " << threadId; return NULL; } diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index 30f0bc917..f4a82b458 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -109,7 +109,7 @@ class CefWebWorkerTaskRunner : public base::SequencedTaskRunner, const base::Closure& task, base::TimeDelta delay) OVERRIDE { if (delay != base::TimeDelta()) - DLOG(WARNING) << "Delayed tasks are not supported on WebWorker threads"; + LOG(WARNING) << "Delayed tasks are not supported on WebWorker threads"; runner_->PostTask(worker_id_, task); return true; } diff --git a/libcef_dll/cpptoc/life_span_handler_cpptoc.cc b/libcef_dll/cpptoc/life_span_handler_cpptoc.cc index 477590956..09a02fdef 100644 --- a/libcef_dll/cpptoc/life_span_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/life_span_handler_cpptoc.cc @@ -18,10 +18,13 @@ // MEMBER FUNCTIONS - Body may be edited by hand. -int CEF_CALLBACK life_span_handler_can_create_popup( +int CEF_CALLBACK life_span_handler_on_before_popup( struct _cef_life_span_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, const cef_string_t* target_url, - const cef_string_t* target_frame_name, int* no_javascript_access) { + const cef_string_t* target_frame_name, + const struct _cef_popup_features_t* popupFeatures, + cef_window_info_t* windowInfo, cef_client_t** client, + struct _cef_browser_settings_t* settings, int* no_javascript_access) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); @@ -35,65 +38,28 @@ int CEF_CALLBACK life_span_handler_can_create_popup( DCHECK(frame); if (!frame) return 0; + // Verify param: popupFeatures; type: struct_byref_const + DCHECK(popupFeatures); + if (!popupFeatures) + return 0; + // Verify param: windowInfo; type: struct_byref + DCHECK(windowInfo); + if (!windowInfo) + return 0; + // Verify param: client; type: refptr_same_byref + DCHECK(client); + if (!client) + return 0; + // Verify param: settings; type: struct_byref + DCHECK(settings); + if (!settings) + return 0; // Verify param: no_javascript_access; type: bool_byaddr DCHECK(no_javascript_access); if (!no_javascript_access) return 0; // Unverified params: target_url, target_frame_name - // Translate param: no_javascript_access; type: bool_byaddr - bool no_javascript_accessBool = ( - no_javascript_access && *no_javascript_access)?true:false; - - // Execute - bool _retval = CefLifeSpanHandlerCppToC::Get(self)->CanCreatePopup( - CefBrowserCToCpp::Wrap(browser), - CefFrameCToCpp::Wrap(frame), - CefString(target_url), - CefString(target_frame_name), - &no_javascript_accessBool); - - // Restore param: no_javascript_access; type: bool_byaddr - if (no_javascript_access) - *no_javascript_access = no_javascript_accessBool?true:false; - - // Return type: bool - return _retval; -} - -void CEF_CALLBACK life_span_handler_on_before_popup( - struct _cef_life_span_handler_t* self, cef_browser_t* browser, - const struct _cef_popup_features_t* popupFeatures, - cef_window_info_t* windowInfo, const cef_string_t* target_url, - const cef_string_t* target_frame_name, cef_client_t** client, - struct _cef_browser_settings_t* settings) { - // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING - - DCHECK(self); - if (!self) - return; - // Verify param: browser; type: refptr_diff - DCHECK(browser); - if (!browser) - return; - // Verify param: popupFeatures; type: struct_byref_const - DCHECK(popupFeatures); - if (!popupFeatures) - return; - // Verify param: windowInfo; type: struct_byref - DCHECK(windowInfo); - if (!windowInfo) - return; - // Verify param: client; type: refptr_same_byref - DCHECK(client); - if (!client) - return; - // Verify param: settings; type: struct_byref - DCHECK(settings); - if (!settings) - return; - // Unverified params: target_url, target_frame_name - // Translate param: popupFeatures; type: struct_byref_const CefPopupFeatures popupFeaturesObj; if (popupFeatures) @@ -111,16 +77,21 @@ void CEF_CALLBACK life_span_handler_on_before_popup( CefBrowserSettings settingsObj; if (settings) settingsObj.AttachTo(*settings); + // Translate param: no_javascript_access; type: bool_byaddr + bool no_javascript_accessBool = ( + no_javascript_access && *no_javascript_access)?true:false; // Execute - CefLifeSpanHandlerCppToC::Get(self)->OnBeforePopup( + bool _retval = CefLifeSpanHandlerCppToC::Get(self)->OnBeforePopup( CefBrowserCToCpp::Wrap(browser), - popupFeaturesObj, - windowInfoObj, + CefFrameCToCpp::Wrap(frame), CefString(target_url), CefString(target_frame_name), + popupFeaturesObj, + windowInfoObj, clientPtr, - settingsObj); + settingsObj, + &no_javascript_accessBool); // Restore param: windowInfo; type: struct_byref if (windowInfo) @@ -138,6 +109,12 @@ void CEF_CALLBACK life_span_handler_on_before_popup( // Restore param: settings; type: struct_byref if (settings) settingsObj.DetachTo(*settings); + // Restore param: no_javascript_access; type: bool_byaddr + if (no_javascript_access) + *no_javascript_access = no_javascript_accessBool?true:false; + + // Return type: bool + return _retval; } void CEF_CALLBACK life_span_handler_on_after_created( @@ -220,7 +197,6 @@ void CEF_CALLBACK life_span_handler_on_before_close( CefLifeSpanHandlerCppToC::CefLifeSpanHandlerCppToC(CefLifeSpanHandler* cls) : CefCppToC(cls) { - struct_.struct_.can_create_popup = life_span_handler_can_create_popup; struct_.struct_.on_before_popup = life_span_handler_on_before_popup; struct_.struct_.on_after_created = life_span_handler_on_after_created; struct_.struct_.run_modal = life_span_handler_run_modal; diff --git a/libcef_dll/ctocpp/life_span_handler_ctocpp.cc b/libcef_dll/ctocpp/life_span_handler_ctocpp.cc index 01f9bc45c..48c6285d8 100644 --- a/libcef_dll/ctocpp/life_span_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/life_span_handler_ctocpp.cc @@ -18,10 +18,12 @@ // VIRTUAL METHODS - Body may be edited by hand. -bool CefLifeSpanHandlerCToCpp::CanCreatePopup(CefRefPtr browser, +bool CefLifeSpanHandlerCToCpp::OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, - const CefString& target_frame_name, bool* no_javascript_access) { - if (CEF_MEMBER_MISSING(struct_, can_create_popup)) + const CefString& target_frame_name, const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, CefRefPtr& client, + CefBrowserSettings& settings, bool* no_javascript_access) { + if (CEF_MEMBER_MISSING(struct_, on_before_popup)) return false; // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -40,55 +42,25 @@ bool CefLifeSpanHandlerCToCpp::CanCreatePopup(CefRefPtr browser, return false; // Unverified params: target_url, target_frame_name - // Translate param: no_javascript_access; type: bool_byaddr - int no_javascript_accessInt = no_javascript_access?*no_javascript_access:0; - - // Execute - int _retval = struct_->can_create_popup(struct_, - CefBrowserCppToC::Wrap(browser), - CefFrameCppToC::Wrap(frame), - target_url.GetStruct(), - target_frame_name.GetStruct(), - &no_javascript_accessInt); - - // Restore param:no_javascript_access; type: bool_byaddr - if (no_javascript_access) - *no_javascript_access = no_javascript_accessInt?true:false; - - // Return type: bool - return _retval?true:false; -} - -void CefLifeSpanHandlerCToCpp::OnBeforePopup(CefRefPtr browser, - const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, - const CefString& target_url, const CefString& target_frame_name, - CefRefPtr& client, CefBrowserSettings& settings) { - if (CEF_MEMBER_MISSING(struct_, on_before_popup)) - return; - - // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING - - // Verify param: browser; type: refptr_diff - DCHECK(browser.get()); - if (!browser.get()) - return; - // Unverified params: target_url, target_frame_name - // Translate param: client; type: refptr_same_byref cef_client_t* clientStruct = NULL; if (client.get()) clientStruct = CefClientCToCpp::Unwrap(client); cef_client_t* clientOrig = clientStruct; + // Translate param: no_javascript_access; type: bool_byaddr + int no_javascript_accessInt = no_javascript_access?*no_javascript_access:0; // Execute - struct_->on_before_popup(struct_, + int _retval = struct_->on_before_popup(struct_, CefBrowserCppToC::Wrap(browser), - &popupFeatures, - &windowInfo, + CefFrameCppToC::Wrap(frame), target_url.GetStruct(), target_frame_name.GetStruct(), + &popupFeatures, + &windowInfo, &clientStruct, - &settings); + &settings, + &no_javascript_accessInt); // Restore param:client; type: refptr_same_byref if (clientStruct) { @@ -98,6 +70,12 @@ void CefLifeSpanHandlerCToCpp::OnBeforePopup(CefRefPtr browser, } else { client = NULL; } + // Restore param:no_javascript_access; type: bool_byaddr + if (no_javascript_access) + *no_javascript_access = no_javascript_accessInt?true:false; + + // Return type: bool + return _retval?true:false; } void CefLifeSpanHandlerCToCpp::OnAfterCreated(CefRefPtr browser) { diff --git a/libcef_dll/ctocpp/life_span_handler_ctocpp.h b/libcef_dll/ctocpp/life_span_handler_ctocpp.h index 3d069ede6..72cd6ef9b 100644 --- a/libcef_dll/ctocpp/life_span_handler_ctocpp.h +++ b/libcef_dll/ctocpp/life_span_handler_ctocpp.h @@ -36,14 +36,12 @@ class CefLifeSpanHandlerCToCpp virtual ~CefLifeSpanHandlerCToCpp() {} // CefLifeSpanHandler methods - virtual bool CanCreatePopup(CefRefPtr browser, + virtual bool OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString& target_url, const CefString& target_frame_name, - bool* no_javascript_access) OVERRIDE; - virtual void OnBeforePopup(CefRefPtr browser, const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo, - const CefString& target_url, const CefString& target_frame_name, - CefRefPtr& client, CefBrowserSettings& settings) OVERRIDE; + CefRefPtr& client, CefBrowserSettings& settings, + bool* no_javascript_access) OVERRIDE; virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; virtual bool RunModal(CefRefPtr browser) OVERRIDE; virtual bool DoClose(CefRefPtr browser) OVERRIDE; diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index 8ea5cf6cd..f9024fc8b 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -232,16 +232,20 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr browser, return false; } -bool ClientHandler::CanCreatePopup(CefRefPtr browser, - CefRefPtr frame, - const CefString& target_url, - const CefString& target_frame_name, - bool* no_javascript_access) { +bool ClientHandler::OnBeforePopup(CefRefPtr browser, + CefRefPtr frame, + const CefString& target_url, + const CefString& target_frame_name, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + CefRefPtr& client, + CefBrowserSettings& settings, + bool* no_javascript_access) { if (browser->GetHost()->IsWindowRenderingDisabled()) { // Cancel popups in off-screen rendering mode. - return false; + return true; } - return true; + return false; } void ClientHandler::OnAfterCreated(CefRefPtr browser) { diff --git a/tests/cefclient/client_handler.h b/tests/cefclient/client_handler.h index 1a39ee1f2..980b01d17 100644 --- a/tests/cefclient/client_handler.h +++ b/tests/cefclient/client_handler.h @@ -159,11 +159,15 @@ class ClientHandler : public CefClient, bool* is_keyboard_shortcut) OVERRIDE; // CefLifeSpanHandler methods - virtual bool CanCreatePopup(CefRefPtr browser, - CefRefPtr frame, - const CefString& target_url, - const CefString& target_frame_name, - bool* no_javascript_access) OVERRIDE; + virtual bool OnBeforePopup(CefRefPtr browser, + CefRefPtr frame, + const CefString& target_url, + const CefString& target_frame_name, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + CefRefPtr& client, + CefBrowserSettings& settings, + bool* no_javascript_access) OVERRIDE; virtual void OnAfterCreated(CefRefPtr browser) OVERRIDE; virtual bool DoClose(CefRefPtr browser) OVERRIDE; virtual void OnBeforeClose(CefRefPtr browser) OVERRIDE; diff --git a/tests/unittests/navigation_unittest.cc b/tests/unittests/navigation_unittest.cc index 3e02726a9..b3d2ef184 100644 --- a/tests/unittests/navigation_unittest.cc +++ b/tests/unittests/navigation_unittest.cc @@ -1455,10 +1455,10 @@ class PopupNavTestHandler : public TestHandler { virtual void RunTest() OVERRIDE { // Add the resources that we will navigate to/from. - std::string page = ""; + "'); }Page"; AddResource(kPopupNavPageUrl, page, "text/html"); AddResource(kPopupNavPopupUrl, "Popup", "text/html"); @@ -1466,12 +1466,16 @@ class PopupNavTestHandler : public TestHandler { CreateBrowser(kPopupNavPageUrl); } - virtual bool CanCreatePopup(CefRefPtr browser, - CefRefPtr frame, - const CefString& target_url, - const CefString& target_frame_name, - bool* no_javascript_access) OVERRIDE { - got_can_create_popup_.yes(); + virtual bool OnBeforePopup(CefRefPtr browser, + CefRefPtr frame, + const CefString& target_url, + const CefString& target_frame_name, + const CefPopupFeatures& popupFeatures, + CefWindowInfo& windowInfo, + CefRefPtr& client, + CefBrowserSettings& settings, + bool* no_javascript_access) OVERRIDE { + got_on_before_popup_.yes(); EXPECT_TRUE(CefCurrentlyOn(TID_IO)); EXPECT_EQ(GetBrowserId(), browser->GetIdentifier()); @@ -1480,58 +1484,47 @@ class PopupNavTestHandler : public TestHandler { EXPECT_STREQ(kPopupNavPopupName, target_frame_name.ToString().c_str()); EXPECT_FALSE(*no_javascript_access); - return allow_; - } - - virtual void OnBeforePopup(CefRefPtr browser, - const CefPopupFeatures& popupFeatures, - CefWindowInfo& windowInfo, - const CefString& target_url, - const CefString& target_frame_name, - CefRefPtr& client, - CefBrowserSettings& settings) OVERRIDE { - got_on_before_popup_.yes(); - - EXPECT_TRUE(CefCurrentlyOn(TID_UI)); - EXPECT_EQ(GetBrowserId(), browser->GetIdentifier()); - EXPECT_STREQ(kPopupNavPopupUrl, target_url.ToString().c_str()); - EXPECT_STREQ(kPopupNavPopupName, target_frame_name.ToString().c_str()); + return !allow_; } virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) OVERRIDE { std::string url = frame->GetURL(); - if (allow_) { - if (url == kPopupNavPopupUrl) { + if (url == kPopupNavPageUrl) { + frame->ExecuteJavaScript("doPopup()", kPopupNavPageUrl, 0); + + if (!allow_) { + // Wait a bit to make sure the popup window isn't created. + CefPostDelayedTask(TID_UI, + NewCefRunnableMethod(this, &PopupNavTestHandler::DestroyTest), 200); + } + } else if (url == kPopupNavPopupUrl) { + if (allow_) { got_popup_load_end_.yes(); browser->GetHost()->CloseBrowser(); DestroyTest(); + } else { + EXPECT_FALSE(true); // Not reached. } } else { - // Wait a bit to make sure the popup window isn't created. - CefPostDelayedTask(TID_UI, - NewCefRunnableMethod(this, &PopupNavTestHandler::DestroyTest), 200); + EXPECT_FALSE(true); // Not reached. } } private: virtual void DestroyTest() { - EXPECT_TRUE(got_can_create_popup_); - if (allow_) { - EXPECT_TRUE(got_on_before_popup_); + EXPECT_TRUE(got_on_before_popup_); + if (allow_) EXPECT_TRUE(got_popup_load_end_); - } else { - EXPECT_FALSE(got_on_before_popup_); + else EXPECT_FALSE(got_popup_load_end_); - } TestHandler::DestroyTest(); } bool allow_; - TrackCallback got_can_create_popup_; TrackCallback got_on_before_popup_; TrackCallback got_popup_load_end_; };