Add a new CefLifeSpanHandler::CanCreatePopup() method for canceling the creation of popup windows (issue #816).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1085 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2013-02-08 00:07:41 +00:00
parent 830182196c
commit 02587eba55
13 changed files with 424 additions and 91 deletions

View File

@ -47,7 +47,8 @@ extern "C" {
///
// Implement this structure to handle events related to browser life span. The
// functions of this structure will be called on the UI thread.
// functions of this structure will be called on the UI thread unless otherwise
// indicated.
///
typedef struct _cef_life_span_handler_t {
///
@ -56,21 +57,39 @@ typedef struct _cef_life_span_handler_t {
cef_base_t base;
///
// Called before a new popup window is created. The |parentBrowser| parameter
// will point to the parent browser window. The |popupFeatures| parameter will
// contain information about the style of popup window requested. Return false
// (0) to have the framework create the new popup window based on the
// parameters in |windowInfo|. Return true (1) to cancel creation of the popup
// window. 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.
// 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 *on_before_popup)(struct _cef_life_span_handler_t* self,
struct _cef_browser_t* parentBrowser,
int (CEF_CALLBACK *can_create_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* url,
struct _cef_client_t** client,
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);
///

View File

@ -45,29 +45,53 @@ class CefClient;
///
// Implement this interface to handle events related to browser life span. The
// methods of this class will be called on the UI thread.
// methods of this class will be called on the UI thread unless otherwise
// indicated.
///
/*--cef(source=client)--*/
class CefLifeSpanHandler : public virtual CefBase {
public:
///
// Called before a new popup window is created. The |parentBrowser| parameter
// will point to the parent browser window. The |popupFeatures| parameter will
// contain information about the style of popup window requested. Return false
// to have the framework create the new popup window based on the parameters
// in |windowInfo|. Return true to cancel creation of the popup window. 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.
// 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.
///
/*--cef(optional_param=url)--*/
virtual bool OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser,
/*--cef(optional_param=target_url,optional_param=target_frame_name)--*/
virtual bool CanCreatePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> 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<CefBrowser> browser,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
const CefString& url,
const CefString& target_url,
const CefString& target_frame_name,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) { return false; }
CefBrowserSettings& settings) {}
///
// Called after a new window is created.

View File

@ -1520,12 +1520,10 @@ bool CefBrowserHostImpl::ShouldCreateWebContents(
CefRefPtr<CefLifeSpanHandler> 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(), pending_client_,
pending_settings_)) {
pending_client_ = NULL;
return false;
if (handler.get()) {
handler->OnBeforePopup(this, features, pending_window_info_,
target_url.spec(), frame_name,
pending_client_, pending_settings_);
}
}

View File

@ -16,6 +16,7 @@
#include "base/compiler_specific.h"
#include "base/bind.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_process_host.h"
CefBrowserMessageFilter::CefBrowserMessageFilter(
@ -36,11 +37,17 @@ void CefBrowserMessageFilter::OnFilterRemoved() {
bool CefBrowserMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
if (message.type() == ViewHostMsg_CreateWindow::ID) {
// Observe but don't handle this message.
handled = false;
}
IPC_BEGIN_MESSAGE_MAP(CefBrowserMessageFilter, message)
IPC_MESSAGE_HANDLER(CefProcessHostMsg_GetNewRenderThreadInfo,
OnGetNewRenderThreadInfo)
IPC_MESSAGE_HANDLER(CefProcessHostMsg_GetNewBrowserInfo,
OnGetNewBrowserInfo)
IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnCreateWindow)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@ -76,3 +83,16 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo(
params->browser_id = info->browser_id();
params->is_popup = info->is_popup();
}
void CefBrowserMessageFilter::OnCreateWindow(
const ViewHostMsg_CreateWindow_Params& params,
int* route_id,
int* surface_id,
int64* cloned_session_storage_namespace_id) {
CefContentBrowserClient::LastCreateWindowParams lcwp;
lcwp.opener_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);
}

View File

@ -15,6 +15,7 @@ class RenderProcessHost;
struct CefProcessHostMsg_GetNewBrowserInfo_Params;
struct CefProcessHostMsg_GetNewRenderThreadInfo_Params;
struct ViewHostMsg_CreateWindow_Params;
// This class sends and receives control messages on the browser process.
class CefBrowserMessageFilter : public IPC::ChannelProxy::MessageFilter {
@ -35,6 +36,10 @@ class CefBrowserMessageFilter : public IPC::ChannelProxy::MessageFilter {
CefProcessHostMsg_GetNewRenderThreadInfo_Params* params);
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);
content::RenderProcessHost* host_;
IPC::Channel* channel_;

View File

@ -252,6 +252,8 @@ CefContentBrowserClient::CefContentBrowserClient()
plugin_service_filter_.reset(new CefPluginServiceFilter);
content::PluginServiceImpl::GetInstance()->SetFilter(
plugin_service_filter_.get());
last_create_window_params_.opener_id = MSG_ROUTING_NONE;
}
CefContentBrowserClient::~CefContentBrowserClient() {
@ -455,6 +457,49 @@ content::AccessTokenStore* CefContentBrowserClient::CreateAccessTokenStore() {
return new CefAccessTokenStore;
}
bool CefContentBrowserClient::CanCreateWindow(
const GURL& opener_url,
const GURL& origin,
WindowContainerType container_type,
content::ResourceContext* context,
int render_process_id,
bool* no_javascript_access) {
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)
return false;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserByRoutingID(
render_process_id,
last_create_window_params_.opener_id);
DCHECK(browser.get());
if (!browser.get())
return false;
bool allow = true;
CefRefPtr<CefClient> client = browser->GetClient();
if (client.get()) {
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
if (handler.get()) {
CefRefPtr<CefFrame> frame =
browser->GetFrame(last_create_window_params_.opener_frame_id);
allow = handler->CanCreatePopup(browser.get(),
frame,
last_create_window_params_.target_url.spec(),
last_create_window_params_.target_frame_name,
no_javascript_access);
}
}
last_create_window_params_.opener_id = MSG_ROUTING_NONE;
return allow;
}
void CefContentBrowserClient::ResourceDispatcherHostCreated() {
resource_dispatcher_host_delegate_.reset(
new CefResourceDispatcherHostDelegate());
@ -502,3 +547,9 @@ const wchar_t* CefContentBrowserClient::GetResourceDllName() {
return file_path;
}
#endif // defined(OS_WIN)
void CefContentBrowserClient::set_last_create_window_params(
const LastCreateWindowParams& params) {
CEF_REQUIRE_IOT();
last_create_window_params_ = params;
}

View File

@ -16,6 +16,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "content/public/browser/content_browser_client.h"
#include "googleurl/src/gurl.h"
class CefBrowserInfo;
class CefBrowserMainParts;
@ -71,6 +72,12 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
CreateQuotaPermissionContext() OVERRIDE;
virtual content::MediaObserver* GetMediaObserver() OVERRIDE;
virtual content::AccessTokenStore* CreateAccessTokenStore() OVERRIDE;
virtual bool CanCreateWindow(const GURL& opener_url,
const GURL& origin,
WindowContainerType container_type,
content::ResourceContext* context,
int render_process_id,
bool* no_javascript_access) OVERRIDE;
virtual void ResourceDispatcherHostCreated() OVERRIDE;
virtual void OverrideWebkitPrefs(content::RenderViewHost* rvh,
const GURL& url,
@ -83,6 +90,16 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
const wchar_t* GetResourceDllName() OVERRIDE;
#endif
// Store additional state from the ViewHostMsg_CreateWindow message that will
// be used when CanCreateWindow() is called.
struct LastCreateWindowParams {
int opener_id;
int64 opener_frame_id;
GURL target_url;
string16 target_frame_name;
};
void set_last_create_window_params(const LastCreateWindowParams& params);
private:
CefBrowserMainParts* browser_main_parts_;
@ -97,6 +114,9 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
typedef std::list<scoped_refptr<CefBrowserInfo> > BrowserInfoList;
BrowserInfoList browser_info_list_;
int next_browser_id_;
// Only accessed on the IO thread.
LastCreateWindowParams last_create_window_params_;
};
#endif // CEF_LIBCEF_BROWSER_CONTENT_BROWSER_CLIENT_H_

View File

@ -13,41 +13,86 @@
#include "libcef_dll/cpptoc/client_cpptoc.h"
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/frame_ctocpp.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
int CEF_CALLBACK life_span_handler_on_before_popup(
struct _cef_life_span_handler_t* self, cef_browser_t* parentBrowser,
const struct _cef_popup_features_t* popupFeatures,
cef_window_info_t* windowInfo, const cef_string_t* url,
cef_client_t** client, struct _cef_browser_settings_t* settings) {
int CEF_CALLBACK life_span_handler_can_create_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) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: parentBrowser; type: refptr_diff
DCHECK(parentBrowser);
if (!parentBrowser)
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: frame; type: refptr_diff
DCHECK(frame);
if (!frame)
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 0;
return;
// Verify param: windowInfo; type: struct_byref
DCHECK(windowInfo);
if (!windowInfo)
return 0;
return;
// Verify param: client; type: refptr_same_byref
DCHECK(client);
if (!client)
return 0;
return;
// Verify param: settings; type: struct_byref
DCHECK(settings);
if (!settings)
return 0;
// Unverified params: url
return;
// Unverified params: target_url, target_frame_name
// Translate param: popupFeatures; type: struct_byref_const
CefPopupFeatures popupFeaturesObj;
@ -68,11 +113,12 @@ int CEF_CALLBACK life_span_handler_on_before_popup(
settingsObj.AttachTo(*settings);
// Execute
bool _retval = CefLifeSpanHandlerCppToC::Get(self)->OnBeforePopup(
CefBrowserCToCpp::Wrap(parentBrowser),
CefLifeSpanHandlerCppToC::Get(self)->OnBeforePopup(
CefBrowserCToCpp::Wrap(browser),
popupFeaturesObj,
windowInfoObj,
CefString(url),
CefString(target_url),
CefString(target_frame_name),
clientPtr,
settingsObj);
@ -92,9 +138,6 @@ int CEF_CALLBACK life_span_handler_on_before_popup(
// Restore param: settings; type: struct_byref
if (settings)
settingsObj.DetachTo(*settings);
// Return type: bool
return _retval;
}
void CEF_CALLBACK life_span_handler_on_after_created(
@ -177,6 +220,7 @@ void CEF_CALLBACK life_span_handler_on_before_close(
CefLifeSpanHandlerCppToC::CefLifeSpanHandlerCppToC(CefLifeSpanHandler* cls)
: CefCppToC<CefLifeSpanHandlerCppToC, CefLifeSpanHandler,
cef_life_span_handler_t>(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;

View File

@ -11,26 +11,68 @@
//
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/cpptoc/frame_cpptoc.h"
#include "libcef_dll/ctocpp/client_ctocpp.h"
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
CefRefPtr<CefBrowser> parentBrowser, const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo, const CefString& url,
CefRefPtr<CefClient>& client, CefBrowserSettings& settings) {
if (CEF_MEMBER_MISSING(struct_, on_before_popup))
bool CefLifeSpanHandlerCToCpp::CanCreatePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, const CefString& target_url,
const CefString& target_frame_name, bool* no_javascript_access) {
if (CEF_MEMBER_MISSING(struct_, can_create_popup))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: parentBrowser; type: refptr_diff
DCHECK(parentBrowser.get());
if (!parentBrowser.get())
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Unverified params: url
// Verify param: frame; type: refptr_diff
DCHECK(frame.get());
if (!frame.get())
return false;
// Verify param: no_javascript_access; type: bool_byaddr
DCHECK(no_javascript_access);
if (!no_javascript_access)
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<CefBrowser> browser,
const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo,
const CefString& target_url, const CefString& target_frame_name,
CefRefPtr<CefClient>& 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;
@ -39,11 +81,12 @@ bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
cef_client_t* clientOrig = clientStruct;
// Execute
int _retval = struct_->on_before_popup(struct_,
CefBrowserCppToC::Wrap(parentBrowser),
struct_->on_before_popup(struct_,
CefBrowserCppToC::Wrap(browser),
&popupFeatures,
&windowInfo,
url.GetStruct(),
target_url.GetStruct(),
target_frame_name.GetStruct(),
&clientStruct,
&settings);
@ -55,9 +98,6 @@ bool CefLifeSpanHandlerCToCpp::OnBeforePopup(
} else {
client = NULL;
}
// Return type: bool
return _retval?true:false;
}
void CefLifeSpanHandlerCToCpp::OnAfterCreated(CefRefPtr<CefBrowser> browser) {

View File

@ -36,10 +36,14 @@ class CefLifeSpanHandlerCToCpp
virtual ~CefLifeSpanHandlerCToCpp() {}
// CefLifeSpanHandler methods
virtual bool OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser,
virtual bool CanCreatePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, const CefString& target_url,
const CefString& target_frame_name,
bool* no_javascript_access) OVERRIDE;
virtual void OnBeforePopup(CefRefPtr<CefBrowser> browser,
const CefPopupFeatures& popupFeatures, CefWindowInfo& windowInfo,
const CefString& url, CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
const CefString& target_url, const CefString& target_frame_name,
CefRefPtr<CefClient>& client, CefBrowserSettings& settings) OVERRIDE;
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool RunModal(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;

View File

@ -232,6 +232,18 @@ bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
return false;
}
bool ClientHandler::CanCreatePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
const CefString& target_frame_name,
bool* no_javascript_access) {
if (browser->GetHost()->IsWindowRenderingDisabled()) {
// Cancel popups in off-screen rendering mode.
return false;
}
return true;
}
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
REQUIRE_UI_THREAD();
@ -243,19 +255,6 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
}
}
bool ClientHandler::OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
const CefString& url,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) {
if (parentBrowser->GetHost()->IsWindowRenderingDisabled()) {
// Cancel popups in off-screen rendering mode.
return true;
}
return false;
}
bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
REQUIRE_UI_THREAD();

View File

@ -159,16 +159,14 @@ class ClientHandler : public CefClient,
bool* is_keyboard_shortcut) OVERRIDE;
// CefLifeSpanHandler methods
virtual bool CanCreatePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
const CefString& target_frame_name,
bool* no_javascript_access) OVERRIDE;
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool OnBeforePopup(
CefRefPtr<CefBrowser> parentBrowser,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
const CefString& url,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
// CefLoadHandler methods
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,

View File

@ -4,6 +4,7 @@
#include <list>
#include "include/cef_callback.h"
#include "include/cef_runnable.h"
#include "include/cef_scheme.h"
#include "tests/cefclient/client_app.h"
#include "tests/unittests/test_handler.h"
@ -1440,6 +1441,116 @@ TEST(NavigationTest, CrossOrigin) {
}
namespace {
const char kPopupNavPageUrl[] = "http://tests-popup/page.html";
const char kPopupNavPopupUrl[] = "http://tests-popup/popup.html";
const char kPopupNavPopupName[] = "my_popup";
// Browser side.
class PopupNavTestHandler : public TestHandler {
public:
explicit PopupNavTestHandler(bool allow)
: allow_(allow) {}
virtual void RunTest() OVERRIDE {
// Add the resources that we will navigate to/from.
std::string page = "<html><script>window.open('" +
std::string(kPopupNavPopupUrl) + "', '" +
std::string(kPopupNavPopupName) +
"');</script></html>";
AddResource(kPopupNavPageUrl, page, "text/html");
AddResource(kPopupNavPopupUrl, "<html>Popup</html>", "text/html");
// Create the browser.
CreateBrowser(kPopupNavPageUrl);
}
virtual bool CanCreatePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
const CefString& target_frame_name,
bool* no_javascript_access) OVERRIDE {
got_can_create_popup_.yes();
EXPECT_TRUE(CefCurrentlyOn(TID_IO));
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
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());
EXPECT_FALSE(*no_javascript_access);
return allow_;
}
virtual void OnBeforePopup(CefRefPtr<CefBrowser> browser,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
const CefString& target_url,
const CefString& target_frame_name,
CefRefPtr<CefClient>& 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());
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE {
std::string url = frame->GetURL();
if (allow_) {
if (url == kPopupNavPopupUrl) {
got_popup_load_end_.yes();
browser->GetHost()->CloseBrowser();
DestroyTest();
}
} else {
// Wait a bit to make sure the popup window isn't created.
CefPostDelayedTask(TID_UI,
NewCefRunnableMethod(this, &PopupNavTestHandler::DestroyTest), 200);
}
}
private:
virtual void DestroyTest() {
EXPECT_TRUE(got_can_create_popup_);
if (allow_) {
EXPECT_TRUE(got_on_before_popup_);
EXPECT_TRUE(got_popup_load_end_);
} else {
EXPECT_FALSE(got_on_before_popup_);
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_;
};
} // namespace
// Test allowing popups.
TEST(NavigationTest, PopupAllow) {
CefRefPtr<PopupNavTestHandler> handler = new PopupNavTestHandler(true);
handler->ExecuteTest();
}
// Test denying popups.
TEST(NavigationTest, PopupDeny) {
CefRefPtr<PopupNavTestHandler> handler = new PopupNavTestHandler(false);
handler->ExecuteTest();
}
// Entry point for creating navigation browser test objects.
// Called from client_app_delegates.cc.
void CreateNavigationBrowserTests(ClientApp::BrowserDelegateSet& delegates) {