Add support for JavaScript alert, confirm, prompt and onbeforeunload dialogs (issue #507).

- Add CefJSDialogHandler and CefJSDialogCallback interfaces.
- Add default dialog implementations for Windows and Mac OS-X.
- Add "JavaScript Dialogs" example to cefclient.
- Change TestHandler::AddResource to ignore the query component when matching URLs.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@594 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2012-04-16 21:15:27 +00:00
parent 7ce5e9924e
commit 07bba96106
43 changed files with 2107 additions and 17 deletions

View File

@ -227,6 +227,7 @@
'tests/cefclient/client_switches.h',
'tests/unittests/command_line_unittest.cc',
'tests/unittests/cookie_unittest.cc',
'tests/unittests/jsdialog_unittest.cc',
'tests/unittests/navigation_unittest.cc',
'tests/unittests/process_message_unittest.cc',
'tests/unittests/request_unittest.cc',
@ -716,6 +717,9 @@
'libcef/browser/download_manager_delegate.h',
'libcef/browser/frame_host_impl.cc',
'libcef/browser/frame_host_impl.h',
'libcef/browser/javascript_dialog.h',
'libcef/browser/javascript_dialog_creator.cc',
'libcef/browser/javascript_dialog_creator.h',
'libcef/browser/navigate_params.cc',
'libcef/browser/navigate_params.h',
'libcef/browser/origin_whitelist_impl.cc',
@ -805,6 +809,7 @@
'<@(includes_win)',
'libcef/browser/browser_host_impl_win.cc',
'libcef/browser/browser_main_win.cc',
'libcef/browser/javascript_dialog_win.cc',
],
}],
[ 'OS=="mac"', {
@ -814,6 +819,7 @@
'libcef/browser/application_mac.mm',
'libcef/browser/browser_host_impl_mac.mm',
'libcef/browser/browser_main_mac.mm',
'libcef/browser/javascript_dialog_mac.mm',
# Include necessary Mozilla sources. Remove these lines once they're
# included by content_browser.gypi. See crbug.com/120719.
'<(DEPTH)/third_party/mozilla/NSString+Utils.h',

View File

@ -21,6 +21,7 @@
'include/cef_display_handler.h',
'include/cef_frame.h',
'include/cef_geolocation_handler.h',
'include/cef_jsdialog_handler.h',
'include/cef_life_span_handler.h',
'include/cef_load_handler.h',
'include/cef_origin_whitelist.h',
@ -52,6 +53,7 @@
'include/capi/cef_display_handler_capi.h',
'include/capi/cef_frame_capi.h',
'include/capi/cef_geolocation_handler_capi.h',
'include/capi/cef_jsdialog_handler_capi.h',
'include/capi/cef_life_span_handler_capi.h',
'include/capi/cef_load_handler_capi.h',
'include/capi/cef_origin_whitelist_capi.h',
@ -104,6 +106,10 @@
'libcef_dll/cpptoc/geolocation_callback_cpptoc.h',
'libcef_dll/ctocpp/geolocation_handler_ctocpp.cc',
'libcef_dll/ctocpp/geolocation_handler_ctocpp.h',
'libcef_dll/cpptoc/jsdialog_callback_cpptoc.cc',
'libcef_dll/cpptoc/jsdialog_callback_cpptoc.h',
'libcef_dll/ctocpp/jsdialog_handler_ctocpp.cc',
'libcef_dll/ctocpp/jsdialog_handler_ctocpp.h',
'libcef_dll/ctocpp/life_span_handler_ctocpp.cc',
'libcef_dll/ctocpp/life_span_handler_ctocpp.h',
'libcef_dll/cpptoc/list_value_cpptoc.cc',
@ -190,6 +196,10 @@
'libcef_dll/ctocpp/geolocation_callback_ctocpp.h',
'libcef_dll/cpptoc/geolocation_handler_cpptoc.cc',
'libcef_dll/cpptoc/geolocation_handler_cpptoc.h',
'libcef_dll/ctocpp/jsdialog_callback_ctocpp.cc',
'libcef_dll/ctocpp/jsdialog_callback_ctocpp.h',
'libcef_dll/cpptoc/jsdialog_handler_cpptoc.cc',
'libcef_dll/cpptoc/jsdialog_handler_cpptoc.h',
'libcef_dll/cpptoc/life_span_handler_cpptoc.cc',
'libcef_dll/cpptoc/life_span_handler_cpptoc.h',
'libcef_dll/ctocpp/list_value_ctocpp.cc',

View File

@ -90,6 +90,7 @@
'tests/cefclient/client_switches.cpp',
'tests/cefclient/client_switches.h',
'tests/cefclient/res/binding.html',
'tests/cefclient/res/dialogs.html',
'tests/cefclient/res/localstorage.html',
'tests/cefclient/res/logo.png',
'tests/cefclient/res/xmlhttprequest.html',
@ -104,7 +105,7 @@
'tests/cefclient/cefclient.rc',
'tests/cefclient/cefclient_win.cpp',
'tests/cefclient/client_handler_win.cpp',
'tests/cefclient/Resource.h',
'tests/cefclient/resource.h',
'tests/cefclient/res/cefclient.ico',
'tests/cefclient/res/logoball.png',
'tests/cefclient/res/small.ico',
@ -139,6 +140,7 @@
'tests/cefclient/mac/English.lproj/MainMenu.xib',
'tests/cefclient/mac/Info.plist',
'tests/cefclient/res/binding.html',
'tests/cefclient/res/dialogs.html',
'tests/cefclient/res/localstorage.html',
'tests/cefclient/res/logo.png',
'tests/cefclient/res/xmlhttprequest.html',

View File

@ -85,6 +85,13 @@ typedef struct _cef_client_t {
struct _cef_geolocation_handler_t* (CEF_CALLBACK *get_geolocation_handler)(
struct _cef_client_t* self);
///
// Return the handler for JavaScript dialogs. If no handler is provided the
// default implementation will be used.
///
struct _cef_jsdialog_handler_t* (CEF_CALLBACK *get_jsdialog_handler)(
struct _cef_client_t* self);
///
// Called when a new message is received from a different process. Return true
// (1) if the message was handled or false (0) otherwise. Do not keep a

View File

@ -0,0 +1,126 @@
// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
#ifndef CEF_INCLUDE_CAPI_CEF_JSDIALOG_HANDLER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_JSDIALOG_HANDLER_CAPI_H_
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "include/capi/cef_base_capi.h"
///
// Callback structure used for asynchronous continuation of JavaScript dialog
// requests.
///
typedef struct _cef_jsdialog_callback_t {
///
// Base structure.
///
cef_base_t base;
///
// Continue the JS dialog request. Set |success| to true (1) if the OK button
// was pressed. The |user_input| value should be specified for prompt dialogs.
///
void (CEF_CALLBACK *cont)(struct _cef_jsdialog_callback_t* self, int success,
const cef_string_t* user_input);
} cef_jsdialog_callback_t;
///
// Implement this structure to handle events related to JavaScript dialogs. The
// functions of this structure will be called on the UI thread.
///
typedef struct _cef_jsdialog_handler_t {
///
// Base structure.
///
cef_base_t base;
///
// Called to run a JavaScript dialog. The |default_prompt_text| value will be
// specified for prompt dialogs only. Set |suppress_message| to true (1) and
// return false (0) to suppress the message (suppressing messages is
// preferable to immediately executing the callback as this is used to detect
// presumably malicious behavior like spamming alert messages in
// onbeforeunload). Set |suppress_message| to false (0) and return false (0)
// to use the default implementation (the default implementation will show one
// modal dialog at a time and suppress any additional dialog requests until
// the displayed dialog is dismissed). Return true (1) if the application will
// use a custom dialog or if the callback has been executed immediately.
// Custom dialogs may be either modal or modeless. If a custom dialog is used
// the application must execute |callback| once the custom dialog is
// dismissed.
///
int (CEF_CALLBACK *on_jsdialog)(struct _cef_jsdialog_handler_t* self,
struct _cef_browser_t* browser, const cef_string_t* origin_url,
const cef_string_t* accept_lang, enum cef_jsdialog_type_t dialog_type,
const cef_string_t* message_text,
const cef_string_t* default_prompt_text,
struct _cef_jsdialog_callback_t* callback, int* suppress_message);
///
// Called to run a dialog asking the user if they want to leave a page. Return
// false (0) to use the default dialog implementation. Return true (1) if the
// application will use a custom dialog or if the callback has been executed
// immediately. Custom dialogs may be either modal or modeless. If a custom
// dialog is used the application must execute |callback| once the custom
// dialog is dismissed.
///
int (CEF_CALLBACK *on_before_unload_dialog)(
struct _cef_jsdialog_handler_t* self, struct _cef_browser_t* browser,
const cef_string_t* message_text, int is_reload,
struct _cef_jsdialog_callback_t* callback);
///
// Called to cancel any pending dialogs and reset any saved dialog state. Will
// be called due to events like page navigation irregardless of whether any
// dialogs are currently pending.
///
void (CEF_CALLBACK *on_reset_dialog_state)(
struct _cef_jsdialog_handler_t* self, struct _cef_browser_t* browser);
} cef_jsdialog_handler_t;
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_JSDIALOG_HANDLER_CAPI_H_

View File

@ -41,6 +41,7 @@
#include "include/cef_base.h"
#include "include/cef_display_handler.h"
#include "include/cef_geolocation_handler.h"
#include "include/cef_jsdialog_handler.h"
#include "include/cef_life_span_handler.h"
#include "include/cef_load_handler.h"
#include "include/cef_process_message.h"
@ -93,6 +94,15 @@ class CefClient : public virtual CefBase {
return NULL;
}
///
// Return the handler for JavaScript dialogs. If no handler is provided the
// default implementation will be used.
///
/*--cef()--*/
virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() {
return NULL;
}
///
// Called when a new message is received from a different process. Return true
// if the message was handled or false otherwise. Do not keep a reference to

View File

@ -0,0 +1,122 @@
// Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_
#define CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_
#pragma once
#include "include/cef_base.h"
#include "include/cef_browser.h"
///
// Callback interface used for asynchronous continuation of JavaScript dialog
// requests.
///
/*--cef(source=library)--*/
class CefJSDialogCallback : public virtual CefBase {
public:
///
// Continue the JS dialog request. Set |success| to true if the OK button was
// pressed. The |user_input| value should be specified for prompt dialogs.
///
/*--cef(capi_name=cont,optional_param=user_input)--*/
virtual void Continue(bool success,
const CefString& user_input) =0;
};
///
// Implement this interface to handle events related to JavaScript dialogs. The
// methods of this class will be called on the UI thread.
///
/*--cef(source=client)--*/
class CefJSDialogHandler : public virtual CefBase {
public:
typedef cef_jsdialog_type_t JSDialogType;
///
// Called to run a JavaScript dialog. The |default_prompt_text| value will be
// specified for prompt dialogs only. Set |suppress_message| to true and
// return false to suppress the message (suppressing messages is preferable
// to immediately executing the callback as this is used to detect presumably
// malicious behavior like spamming alert messages in onbeforeunload). Set
// |suppress_message| to false and return false to use the default
// implementation (the default implementation will show one modal dialog at a
// time and suppress any additional dialog requests until the displayed dialog
// is dismissed). Return true if the application will use a custom dialog or
// if the callback has been executed immediately. Custom dialogs may be either
// modal or modeless. If a custom dialog is used the application must execute
// |callback| once the custom dialog is dismissed.
///
/*--cef(optional_param=accept_lang,optional_param=message_text,
optional_param=default_prompt_text)--*/
virtual bool OnJSDialog(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
const CefString& accept_lang,
JSDialogType dialog_type,
const CefString& message_text,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback,
bool& suppress_message) {
return false;
}
///
// Called to run a dialog asking the user if they want to leave a page. Return
// false to use the default dialog implementation. Return true if the
// application will use a custom dialog or if the callback has been executed
// immediately. Custom dialogs may be either modal or modeless. If a custom
// dialog is used the application must execute |callback| once the custom
// dialog is dismissed.
///
/*--cef(optional_param=message_text)--*/
virtual bool OnBeforeUnloadDialog(CefRefPtr<CefBrowser> browser,
const CefString& message_text,
bool is_reload,
CefRefPtr<CefJSDialogCallback> callback) {
return false;
}
///
// Called to cancel any pending dialogs and reset any saved dialog state. Will
// be called due to events like page navigation irregardless of whether any
// dialogs are currently pending.
///
/*--cef()--*/
virtual void OnResetDialogState(CefRefPtr<CefBrowser> browser) {}
};
#endif // CEF_INCLUDE_CEF_JSDIALOG_HANDLER_H_

View File

@ -769,6 +769,15 @@ enum cef_value_type_t {
VTYPE_LIST,
};
///
// Supported JavaScript dialog types.
///
enum cef_jsdialog_type_t {
JSDIALOGTYPE_ALERT = 0,
JSDIALOGTYPE_CONFIRM,
JSDIALOGTYPE_PROMPT,
};
///
// Supported XML encoding types. The parser supports ASCII, ISO-8859-1, and
// UTF16 (LE and BE) by default. All other types must be translated to UTF8

View File

@ -852,10 +852,10 @@ void CefBrowserHostImpl::DidNavigateMainFramePostCommit(
}
content::JavaScriptDialogCreator*
CefBrowserHostImpl::GetJavaScriptDialogCreator() {
// TODO(cef): Provide a custom JavaScriptDialogCreator implementation to
// support JavaScript alerts, prompts, etc.
return content::WebContentsDelegate::GetJavaScriptDialogCreator();
CefBrowserHostImpl::GetJavaScriptDialogCreator() {
if (!dialog_creator_.get())
dialog_creator_.reset(new CefJavaScriptDialogCreator(this));
return dialog_creator_.get();
}
void CefBrowserHostImpl::RunFileChooser(

View File

@ -16,6 +16,7 @@
#include "include/cef_client.h"
#include "include/cef_frame.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/javascript_dialog_creator.h"
#include "libcef/browser/url_request_context_getter_proxy.h"
#include "libcef/common/response_manager.h"
@ -353,6 +354,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Used for proxying cookie requests.
scoped_refptr<CefURLRequestContextGetterProxy> request_context_proxy_;
// Used for creating and managing JavaScript dialogs.
scoped_ptr<CefJavaScriptDialogCreator> dialog_creator_;
IMPLEMENT_REFCOUNTING(CefBrowserHostImpl);
DISALLOW_EVIL_CONSTRUCTORS(CefBrowserHostImpl);
};

View File

@ -0,0 +1,66 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_H_
#define CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_H_
#pragma once
#include "content/public/browser/javascript_dialogs.h"
#if defined(OS_MACOSX)
#if __OBJC__
@class CefJavaScriptDialogHelper;
#else
class CefJavaScriptDialogHelper;
#endif // __OBJC__
#endif // defined(OS_MACOSX)
class CefJavaScriptDialogCreator;
class CefJavaScriptDialog {
public:
CefJavaScriptDialog(
CefJavaScriptDialogCreator* creator,
ui::JavascriptMessageType javascript_message_type,
const string16& display_url,
const string16& message_text,
const string16& default_prompt_text,
const content::JavaScriptDialogCreator::DialogClosedCallback& callback);
~CefJavaScriptDialog();
// Called to cancel a dialog mid-flight.
void Cancel();
// Activate the dialog.
void Activate();
private:
CefJavaScriptDialogCreator* creator_;
content::JavaScriptDialogCreator::DialogClosedCallback callback_;
#if defined(OS_MACOSX)
CefJavaScriptDialogHelper* helper_; // owned
#elif defined(OS_WIN)
ui::JavascriptMessageType message_type_;
HWND dialog_win_;
HWND parent_win_;
string16 message_text_;
string16 default_prompt_text_;
static INT_PTR CALLBACK DialogProc(HWND dialog, UINT message, WPARAM wparam,
LPARAM lparam);
// Since the message loop we expect to run in isn't going to be nicely
// calling IsDialogMessage(), we need to hook the wnd proc and call it
// ourselves. See http://support.microsoft.com/kb/q187988/
static bool InstallMessageHook();
static bool UninstallMessageHook();
static LRESULT CALLBACK GetMsgProc(int code, WPARAM wparam, LPARAM lparam);
static HHOOK msg_hook_;
#endif
DISALLOW_COPY_AND_ASSIGN(CefJavaScriptDialog);
};
#endif // CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_H_

View File

@ -0,0 +1,204 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/javascript_dialog_creator.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/javascript_dialog.h"
#include "libcef/browser/thread_util.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "net/base/net_util.h"
namespace {
class CefJSDialogCallbackImpl : public CefJSDialogCallback {
public:
CefJSDialogCallbackImpl(
const content::JavaScriptDialogCreator::DialogClosedCallback& callback)
: callback_(callback) {
}
~CefJSDialogCallbackImpl() {
if (!callback_.is_null()) {
// The callback is still pending. Cancel it now.
if (CEF_CURRENTLY_ON_UIT()) {
CancelNow(callback_);
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefJSDialogCallbackImpl::CancelNow, callback_));
}
}
}
virtual void Continue(bool success,
const CefString& user_input) OVERRIDE {
if (CEF_CURRENTLY_ON_UIT()) {
if (!callback_.is_null()) {
callback_.Run(success, user_input);
callback_.Reset();
}
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefJSDialogCallbackImpl::Continue, this, success,
user_input));
}
}
void Disconnect() {
callback_.Reset();
}
private:
static void CancelNow(
const content::JavaScriptDialogCreator::DialogClosedCallback& callback) {
CEF_REQUIRE_UIT();
callback.Run(false, string16());
}
content::JavaScriptDialogCreator::DialogClosedCallback callback_;
IMPLEMENT_REFCOUNTING(CefJSDialogCallbackImpl);
};
} // namespace
CefJavaScriptDialogCreator::CefJavaScriptDialogCreator(
CefBrowserHostImpl* browser)
: browser_(browser) {
}
CefJavaScriptDialogCreator::~CefJavaScriptDialogCreator() {
}
void CefJavaScriptDialogCreator::RunJavaScriptDialog(
content::WebContents* web_contents,
const GURL& origin_url,
const std::string& accept_lang,
ui::JavascriptMessageType javascript_message_type,
const string16& message_text,
const string16& default_prompt_text,
const DialogClosedCallback& callback,
bool* did_suppress_message) {
CefRefPtr<CefClient> client = browser_->GetClient();
if (client.get()) {
CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
if (handler.get()) {
*did_suppress_message = false;
CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
new CefJSDialogCallbackImpl(callback));
// Execute the user callback.
bool handled = handler->OnJSDialog(browser_, origin_url.spec(),
accept_lang,
static_cast<cef_jsdialog_type_t>(javascript_message_type),
message_text, default_prompt_text, callbackPtr.get(),
*did_suppress_message);
if (handled)
return;
callbackPtr->Disconnect();
if (*did_suppress_message)
return;
}
}
#if defined(OS_MACOSX) || defined(OS_WIN)
*did_suppress_message = false;
if (dialog_.get()) {
// One dialog at a time, please.
*did_suppress_message = true;
return;
}
string16 display_url = net::FormatUrl(origin_url, accept_lang);
dialog_.reset(new CefJavaScriptDialog(this,
javascript_message_type,
display_url,
message_text,
default_prompt_text,
callback));
#else
// TODO(port): implement CefJavaScriptDialog for other platforms.
*did_suppress_message = true;
return;
#endif
}
void CefJavaScriptDialogCreator::RunBeforeUnloadDialog(
content::WebContents* web_contents,
const string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) {
CefRefPtr<CefClient> client = browser_->GetClient();
if (client.get()) {
CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
if (handler.get()) {
CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
new CefJSDialogCallbackImpl(callback));
// Execute the user callback.
bool handled = handler->OnBeforeUnloadDialog(browser_, message_text,
is_reload, callbackPtr.get());
if (handled)
return;
callbackPtr->Disconnect();
}
}
#if defined(OS_MACOSX) || defined(OS_WIN)
if (dialog_.get()) {
// Seriously!?
callback.Run(true, string16());
return;
}
string16 new_message_text =
message_text +
ASCIIToUTF16("\n\nIs it OK to leave/reload this page?");
dialog_.reset(new CefJavaScriptDialog(this,
ui::JAVASCRIPT_MESSAGE_TYPE_CONFIRM,
string16(), // display_url
new_message_text,
string16(), // default_prompt_text
callback));
#else
// TODO(port): implement CefJavaScriptDialog for other platforms.
callback.Run(true, string16());
return;
#endif
}
void CefJavaScriptDialogCreator::ResetJavaScriptState(
content::WebContents* web_contents) {
CefRefPtr<CefClient> client = browser_->GetClient();
if (client.get()) {
CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
if (handler.get()) {
// Execute the user callback.
handler->OnResetDialogState(browser_);
}
}
#if defined(OS_MACOSX) || defined(OS_WIN)
if (dialog_.get()) {
dialog_->Cancel();
dialog_.reset();
}
#endif
}
void CefJavaScriptDialogCreator::DialogClosed(CefJavaScriptDialog* dialog) {
#if defined(OS_MACOSX) || defined(OS_WIN)
DCHECK_EQ(dialog, dialog_.get());
dialog_.reset();
#endif
}

View File

@ -0,0 +1,61 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_CREATOR_H_
#define CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_CREATOR_H_
#pragma once
#include <string>
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/javascript_dialogs.h"
class CefBrowserHostImpl;
class CefJavaScriptDialog;
class CefJavaScriptDialogCreator : public content::JavaScriptDialogCreator {
public:
explicit CefJavaScriptDialogCreator(CefBrowserHostImpl* browser);
virtual ~CefJavaScriptDialogCreator();
// JavaScriptDialogCreator methods.
virtual void RunJavaScriptDialog(
content::WebContents* web_contents,
const GURL& origin_url,
const std::string& accept_lang,
ui::JavascriptMessageType javascript_message_type,
const string16& message_text,
const string16& default_prompt_text,
const DialogClosedCallback& callback,
bool* did_suppress_message) OVERRIDE;
virtual void RunBeforeUnloadDialog(
content::WebContents* web_contents,
const string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) OVERRIDE;
virtual void ResetJavaScriptState(
content::WebContents* web_contents) OVERRIDE;
// Called by the CefJavaScriptDialog when it closes.
void DialogClosed(CefJavaScriptDialog* dialog);
CefBrowserHostImpl* browser() const { return browser_; }
private:
// This pointer is guaranteed to outlive the CefJavaScriptDialogCreator.
CefBrowserHostImpl* browser_;
#if defined(OS_MACOSX) || defined(OS_WIN)
// The dialog being shown. No queueing.
scoped_ptr<CefJavaScriptDialog> dialog_;
#endif
DISALLOW_COPY_AND_ASSIGN(CefJavaScriptDialogCreator);
};
#endif // CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_CREATOR_H_

View File

@ -0,0 +1,156 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/javascript_dialog.h"
#include "libcef/browser/javascript_dialog_creator.h"
#import <Cocoa/Cocoa.h>
#import "base/mac/cocoa_protocols.h"
#import "base/memory/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
// Helper object that receives the notification that the dialog/sheet is
// going away. Is responsible for cleaning itself up.
@interface CefJavaScriptDialogHelper : NSObject<NSAlertDelegate> {
@private
scoped_nsobject<NSAlert> alert_;
NSTextField* textField_; // WEAK; owned by alert_
// Copies of the fields in CefJavaScriptDialog because they're private.
CefJavaScriptDialogCreator* creator_;
content::JavaScriptDialogCreator::DialogClosedCallback callback_;
}
- (id)initHelperWithCreator:(CefJavaScriptDialogCreator*)creator
andCallback:(content::JavaScriptDialogCreator::DialogClosedCallback)callback;
- (NSAlert*)alert;
- (NSTextField*)textField;
- (void)alertDidEnd:(NSAlert*)alert
returnCode:(int)returnCode
contextInfo:(void*)contextInfo;
- (void)cancel;
@end
@implementation CefJavaScriptDialogHelper
- (id)initHelperWithCreator:(CefJavaScriptDialogCreator*)creator
andCallback:(content::JavaScriptDialogCreator::DialogClosedCallback)callback {
if (self = [super init]) {
creator_ = creator;
callback_ = callback;
}
return self;
}
- (NSAlert*)alert {
alert_.reset([[NSAlert alloc] init]);
return alert_;
}
- (NSTextField*)textField {
textField_ = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 22)];
[[textField_ cell] setLineBreakMode:NSLineBreakByTruncatingTail];
[alert_ setAccessoryView:textField_];
[textField_ release];
return textField_;
}
- (void)alertDidEnd:(NSAlert*)alert
returnCode:(int)returnCode
contextInfo:(void*)contextInfo {
if (returnCode == NSRunStoppedResponse)
return;
bool success = returnCode == NSAlertFirstButtonReturn;
string16 input;
if (textField_)
input = base::SysNSStringToUTF16([textField_ stringValue]);
CefJavaScriptDialog* native_dialog =
reinterpret_cast<CefJavaScriptDialog*>(contextInfo);
callback_.Run(success, input);
creator_->DialogClosed(native_dialog);
}
- (void)cancel {
[NSApp endSheet:[alert_ window]];
alert_.reset();
}
@end
CefJavaScriptDialog::CefJavaScriptDialog(
CefJavaScriptDialogCreator* creator,
ui::JavascriptMessageType javascript_message_type,
const string16& display_url,
const string16& message_text,
const string16& default_prompt_text,
const content::JavaScriptDialogCreator::DialogClosedCallback& callback)
: creator_(creator),
callback_(callback) {
bool text_field =
javascript_message_type == ui::JAVASCRIPT_MESSAGE_TYPE_PROMPT;
bool one_button =
javascript_message_type == ui::JAVASCRIPT_MESSAGE_TYPE_ALERT;
helper_ =
[[CefJavaScriptDialogHelper alloc] initHelperWithCreator:creator
andCallback:callback];
// Show the modal dialog.
NSAlert* alert = [helper_ alert];
NSTextField* field = nil;
if (text_field) {
field = [helper_ textField];
[field setStringValue:base::SysUTF16ToNSString(default_prompt_text)];
}
[alert setDelegate:helper_];
[alert setInformativeText:base::SysUTF16ToNSString(message_text)];
string16 label;
switch (javascript_message_type) {
case ui::JAVASCRIPT_MESSAGE_TYPE_ALERT:
label = ASCIIToUTF16("JavaScript Alert");
break;
case ui::JAVASCRIPT_MESSAGE_TYPE_PROMPT:
label = ASCIIToUTF16("JavaScript Prompt");
break;
case ui::JAVASCRIPT_MESSAGE_TYPE_CONFIRM:
label = ASCIIToUTF16("JavaScript Confirm");
break;
}
if (!display_url.empty())
label += ASCIIToUTF16(" - ") + display_url;
[alert setMessageText:base::SysUTF16ToNSString(label)];
[alert addButtonWithTitle:@"OK"];
if (!one_button) {
NSButton* other = [alert addButtonWithTitle:@"Cancel"];
[other setKeyEquivalent:@"\e"];
}
[alert
beginSheetModalForWindow:nil // nil here makes it app-modal
modalDelegate:helper_
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:this];
if ([alert accessoryView])
[[alert window] makeFirstResponder:[alert accessoryView]];
}
CefJavaScriptDialog::~CefJavaScriptDialog() {
[helper_ release];
}
void CefJavaScriptDialog::Cancel() {
[helper_ cancel];
}

View File

@ -0,0 +1,213 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libcef/browser/javascript_dialog.h"
#include "libcef/browser/javascript_dialog_creator.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef_dll/resource.h"
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
class CefJavaScriptDialog;
HHOOK CefJavaScriptDialog::msg_hook_ = NULL;
INT_PTR CALLBACK CefJavaScriptDialog::DialogProc(HWND dialog, UINT message,
WPARAM wparam,
LPARAM lparam) {
switch (message) {
case WM_INITDIALOG: {
SetWindowLongPtr(dialog, DWL_USER, static_cast<LONG_PTR>(lparam));
CefJavaScriptDialog* owner =
reinterpret_cast<CefJavaScriptDialog*>(lparam);
owner->dialog_win_ = dialog;
SetDlgItemText(dialog, IDC_DIALOGTEXT, owner->message_text_.c_str());
if (owner->message_type_ == ui::JAVASCRIPT_MESSAGE_TYPE_PROMPT)
SetDlgItemText(dialog, IDC_PROMPTEDIT,
owner->default_prompt_text_.c_str());
break;
}
case WM_CLOSE: {
CefJavaScriptDialog* owner = reinterpret_cast<CefJavaScriptDialog*>(
GetWindowLongPtr(dialog, DWL_USER));
if (owner) {
owner->Cancel();
owner->callback_.Run(false, string16());
owner->creator_->DialogClosed(owner);
// No need for the system to call DestroyWindow() because it will be
// called by the Cancel() method.
return 0;
}
break;
}
case WM_COMMAND: {
CefJavaScriptDialog* owner = reinterpret_cast<CefJavaScriptDialog*>(
GetWindowLongPtr(dialog, DWL_USER));
string16 user_input;
bool finish = false;
bool result;
switch (LOWORD(wparam)) {
case IDOK:
finish = true;
result = true;
if (owner->message_type_ == ui::JAVASCRIPT_MESSAGE_TYPE_PROMPT) {
size_t length =
GetWindowTextLength(GetDlgItem(dialog, IDC_PROMPTEDIT)) + 1;
GetDlgItemText(dialog, IDC_PROMPTEDIT,
WriteInto(&user_input, length), length);
}
break;
case IDCANCEL:
finish = true;
result = false;
break;
}
if (finish) {
owner->Cancel();
owner->callback_.Run(result, user_input);
owner->creator_->DialogClosed(owner);
}
break;
}
default:
return DefWindowProc(dialog, message, wparam, lparam);
}
return 0;
}
CefJavaScriptDialog::CefJavaScriptDialog(
CefJavaScriptDialogCreator* creator,
ui::JavascriptMessageType javascript_message_type,
const string16& display_url,
const string16& message_text,
const string16& default_prompt_text,
const content::JavaScriptDialogCreator::DialogClosedCallback& callback)
: creator_(creator),
callback_(callback),
message_text_(message_text),
default_prompt_text_(default_prompt_text),
message_type_(javascript_message_type) {
InstallMessageHook();
int dialog_type;
if (javascript_message_type == ui::JAVASCRIPT_MESSAGE_TYPE_ALERT)
dialog_type = IDD_ALERT;
else if (javascript_message_type == ui::JAVASCRIPT_MESSAGE_TYPE_CONFIRM)
dialog_type = IDD_CONFIRM;
else // JAVASCRIPT_MESSAGE_TYPE_PROMPT
dialog_type = IDD_PROMPT;
FilePath file_path;
HMODULE hModule = NULL;
// Try to load the dialog from the DLL.
if (PathService::Get(base::FILE_MODULE, &file_path))
hModule = ::GetModuleHandle(file_path.value().c_str());
if (!hModule)
hModule = ::GetModuleHandle(NULL);
DCHECK(hModule);
parent_win_ = GetAncestor(creator->browser()->GetWindowHandle(), GA_ROOT);
dialog_win_ = CreateDialogParam(hModule,
MAKEINTRESOURCE(dialog_type),
parent_win_,
DialogProc,
reinterpret_cast<LPARAM>(this));
DCHECK(dialog_win_);
if (!display_url.empty()) {
// Add the display URL to the window title.
TCHAR text[64];
GetWindowText(dialog_win_, text, sizeof(text)/sizeof(TCHAR));
string16 new_window_text = text + ASCIIToUTF16(" - ") + display_url;
SetWindowText(dialog_win_, new_window_text.c_str());
}
// Disable the parent window so the user can't interact with it.
if (IsWindowEnabled(parent_win_))
EnableWindow(parent_win_, FALSE);
ShowWindow(dialog_win_, SW_SHOWNORMAL);
}
CefJavaScriptDialog::~CefJavaScriptDialog() {
Cancel();
UninstallMessageHook();
}
void CefJavaScriptDialog::Cancel() {
HWND parent = NULL;
// Re-enable the parent before closing the popup to avoid focus/activation/
// z-order issues.
if (parent_win_ && IsWindow(parent_win_) && !IsWindowEnabled(parent_win_)) {
parent = parent_win_;
EnableWindow(parent_win_, TRUE);
parent_win_ = NULL;
}
if (dialog_win_ && IsWindow(dialog_win_)) {
SetWindowLongPtr(dialog_win_, DWL_USER, NULL);
DestroyWindow(dialog_win_);
dialog_win_ = NULL;
}
// Return focus to the parent window.
if (parent)
SetFocus(parent);
}
// static
LRESULT CALLBACK CefJavaScriptDialog::GetMsgProc(int code, WPARAM wparam,
LPARAM lparam) {
// Mostly borrowed from http://support.microsoft.com/kb/q187988/
// and http://www.codeproject.com/KB/atl/cdialogmessagehook.aspx.
LPMSG msg = reinterpret_cast<LPMSG>(lparam);
if (code >= 0 && wparam == PM_REMOVE &&
msg->message >= WM_KEYFIRST && msg->message <= WM_KEYLAST) {
HWND hwnd = GetActiveWindow();
if (::IsWindow(hwnd) && ::IsDialogMessage(hwnd, msg)) {
// The value returned from this hookproc is ignored, and it cannot
// be used to tell Windows the message has been handled. To avoid
// further processing, convert the message to WM_NULL before
// returning.
msg->hwnd = NULL;
msg->message = WM_NULL;
msg->lParam = 0L;
msg->wParam = 0;
}
}
// Passes the hook information to the next hook procedure in
// the current hook chain.
return ::CallNextHookEx(msg_hook_, code, wparam, lparam);
}
// static
bool CefJavaScriptDialog::InstallMessageHook() {
// Make sure we only call this once.
DCHECK(msg_hook_ == NULL);
msg_hook_ = ::SetWindowsHookEx(WH_GETMESSAGE,
&CefJavaScriptDialog::GetMsgProc,
NULL,
GetCurrentThreadId());
DCHECK(msg_hook_ != NULL);
return msg_hook_ != NULL;
}
// static
bool CefJavaScriptDialog::UninstallMessageHook() {
DCHECK(msg_hook_ != NULL);
BOOL result = ::UnhookWindowsHookEx(msg_hook_);
DCHECK(result);
msg_hook_ = NULL;
return result != FALSE;
}

View File

@ -29,7 +29,7 @@ class CefAuthCallbackImpl : public CefAuthCallback {
CancelNow(callback_);
} else {
CEF_POST_TASK(CEF_IOT,
base::Bind(&CefAuthCallbackImpl::CancelNow, callback_));
base::Bind(&CefAuthCallbackImpl::CancelNow, callback_));
}
}
}

View File

@ -13,6 +13,7 @@
#include "libcef_dll/cpptoc/client_cpptoc.h"
#include "libcef_dll/cpptoc/display_handler_cpptoc.h"
#include "libcef_dll/cpptoc/geolocation_handler_cpptoc.h"
#include "libcef_dll/cpptoc/jsdialog_handler_cpptoc.h"
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
#include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/request_handler_cpptoc.h"
@ -102,6 +103,22 @@ struct _cef_geolocation_handler_t* CEF_CALLBACK client_get_geolocation_handler(
return CefGeolocationHandlerCppToC::Wrap(_retval);
}
struct _cef_jsdialog_handler_t* CEF_CALLBACK client_get_jsdialog_handler(
struct _cef_client_t* self) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return NULL;
// Execute
CefRefPtr<CefJSDialogHandler> _retval = CefClientCppToC::Get(
self)->GetJSDialogHandler();
// Return type: refptr_same
return CefJSDialogHandlerCppToC::Wrap(_retval);
}
int CEF_CALLBACK client_on_process_message_recieved(struct _cef_client_t* self,
cef_browser_t* browser, enum cef_process_id_t source_process,
struct _cef_process_message_t* message) {
@ -139,6 +156,7 @@ CefClientCppToC::CefClientCppToC(CefClient* cls)
struct_.struct_.get_request_handler = client_get_request_handler;
struct_.struct_.get_display_handler = client_get_display_handler;
struct_.struct_.get_geolocation_handler = client_get_geolocation_handler;
struct_.struct_.get_jsdialog_handler = client_get_jsdialog_handler;
struct_.struct_.on_process_message_recieved =
client_on_process_message_recieved;
}

View File

@ -0,0 +1,46 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/jsdialog_callback_cpptoc.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
void CEF_CALLBACK jsdialog_callback_cont(struct _cef_jsdialog_callback_t* self,
int success, const cef_string_t* user_input) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Unverified params: user_input
// Execute
CefJSDialogCallbackCppToC::Get(self)->Continue(
success?true:false,
CefString(user_input));
}
// CONSTRUCTOR - Do not edit by hand.
CefJSDialogCallbackCppToC::CefJSDialogCallbackCppToC(CefJSDialogCallback* cls)
: CefCppToC<CefJSDialogCallbackCppToC, CefJSDialogCallback,
cef_jsdialog_callback_t>(cls) {
struct_.struct_.cont = jsdialog_callback_cont;
}
#ifndef NDEBUG
template<> long CefCppToC<CefJSDialogCallbackCppToC, CefJSDialogCallback,
cef_jsdialog_callback_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,37 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_JSDIALOG_CALLBACK_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_JSDIALOG_CALLBACK_CPPTOC_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_jsdialog_handler.h"
#include "include/capi/cef_jsdialog_handler_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed DLL-side only.
class CefJSDialogCallbackCppToC
: public CefCppToC<CefJSDialogCallbackCppToC, CefJSDialogCallback,
cef_jsdialog_callback_t> {
public:
explicit CefJSDialogCallbackCppToC(CefJSDialogCallback* cls);
virtual ~CefJSDialogCallbackCppToC() {}
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_JSDIALOG_CALLBACK_CPPTOC_H_

View File

@ -0,0 +1,136 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/jsdialog_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/jsdialog_callback_ctocpp.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
int CEF_CALLBACK jsdialog_handler_on_jsdialog(
struct _cef_jsdialog_handler_t* self, cef_browser_t* browser,
const cef_string_t* origin_url, const cef_string_t* accept_lang,
enum cef_jsdialog_type_t dialog_type, const cef_string_t* message_text,
const cef_string_t* default_prompt_text, cef_jsdialog_callback_t* callback,
int* suppress_message) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: origin_url; type: string_byref_const
DCHECK(origin_url);
if (!origin_url)
return 0;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return 0;
// Verify param: suppress_message; type: bool_byref
DCHECK(suppress_message);
if (!suppress_message)
return 0;
// Unverified params: accept_lang, message_text, default_prompt_text
// Translate param: suppress_message; type: bool_byref
bool suppress_messageBool = (
suppress_message && *suppress_message)?true:false;
// Execute
bool _retval = CefJSDialogHandlerCppToC::Get(self)->OnJSDialog(
CefBrowserCToCpp::Wrap(browser),
CefString(origin_url),
CefString(accept_lang),
dialog_type,
CefString(message_text),
CefString(default_prompt_text),
CefJSDialogCallbackCToCpp::Wrap(callback),
suppress_messageBool);
// Restore param: suppress_message; type: bool_byref
if (suppress_message)
*suppress_message = suppress_messageBool?true:false;
// Return type: bool
return _retval;
}
int CEF_CALLBACK jsdialog_handler_on_before_unload_dialog(
struct _cef_jsdialog_handler_t* self, cef_browser_t* browser,
const cef_string_t* message_text, int is_reload,
cef_jsdialog_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return 0;
// Verify param: browser; type: refptr_diff
DCHECK(browser);
if (!browser)
return 0;
// Verify param: callback; type: refptr_diff
DCHECK(callback);
if (!callback)
return 0;
// Unverified params: message_text
// Execute
bool _retval = CefJSDialogHandlerCppToC::Get(self)->OnBeforeUnloadDialog(
CefBrowserCToCpp::Wrap(browser),
CefString(message_text),
is_reload?true:false,
CefJSDialogCallbackCToCpp::Wrap(callback));
// Return type: bool
return _retval;
}
void CEF_CALLBACK jsdialog_handler_on_reset_dialog_state(
struct _cef_jsdialog_handler_t* self, cef_browser_t* browser) {
// 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
CefJSDialogHandlerCppToC::Get(self)->OnResetDialogState(
CefBrowserCToCpp::Wrap(browser));
}
// CONSTRUCTOR - Do not edit by hand.
CefJSDialogHandlerCppToC::CefJSDialogHandlerCppToC(CefJSDialogHandler* cls)
: CefCppToC<CefJSDialogHandlerCppToC, CefJSDialogHandler,
cef_jsdialog_handler_t>(cls) {
struct_.struct_.on_jsdialog = jsdialog_handler_on_jsdialog;
struct_.struct_.on_before_unload_dialog =
jsdialog_handler_on_before_unload_dialog;
struct_.struct_.on_reset_dialog_state =
jsdialog_handler_on_reset_dialog_state;
}
#ifndef NDEBUG
template<> long CefCppToC<CefJSDialogHandlerCppToC, CefJSDialogHandler,
cef_jsdialog_handler_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,37 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_JSDIALOG_HANDLER_CPPTOC_H_
#define CEF_LIBCEF_DLL_CPPTOC_JSDIALOG_HANDLER_CPPTOC_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_jsdialog_handler.h"
#include "include/capi/cef_jsdialog_handler_capi.h"
#include "libcef_dll/cpptoc/cpptoc.h"
// Wrap a C++ class with a C structure.
// This class may be instantiated and accessed wrapper-side only.
class CefJSDialogHandlerCppToC
: public CefCppToC<CefJSDialogHandlerCppToC, CefJSDialogHandler,
cef_jsdialog_handler_t> {
public:
explicit CefJSDialogHandlerCppToC(CefJSDialogHandler* cls);
virtual ~CefJSDialogHandlerCppToC() {}
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CPPTOC_JSDIALOG_HANDLER_CPPTOC_H_

View File

@ -15,6 +15,7 @@
#include "libcef_dll/ctocpp/client_ctocpp.h"
#include "libcef_dll/ctocpp/display_handler_ctocpp.h"
#include "libcef_dll/ctocpp/geolocation_handler_ctocpp.h"
#include "libcef_dll/ctocpp/jsdialog_handler_ctocpp.h"
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
#include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/request_handler_ctocpp.h"
@ -88,6 +89,19 @@ CefRefPtr<CefGeolocationHandler> CefClientCToCpp::GetGeolocationHandler() {
return CefGeolocationHandlerCToCpp::Wrap(_retval);
}
CefRefPtr<CefJSDialogHandler> CefClientCToCpp::GetJSDialogHandler() {
if (CEF_MEMBER_MISSING(struct_, get_jsdialog_handler))
return NULL;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_jsdialog_handler_t* _retval = struct_->get_jsdialog_handler(struct_);
// Return type: refptr_same
return CefJSDialogHandlerCToCpp::Wrap(_retval);
}
bool CefClientCToCpp::OnProcessMessageRecieved(CefRefPtr<CefBrowser> browser,
CefProcessId source_process, CefRefPtr<CefProcessMessage> message) {
if (CEF_MEMBER_MISSING(struct_, on_process_message_recieved))

View File

@ -37,6 +37,7 @@ class CefClientCToCpp
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE;
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE;
virtual CefRefPtr<CefGeolocationHandler> GetGeolocationHandler() OVERRIDE;
virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() OVERRIDE;
virtual bool OnProcessMessageRecieved(CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) OVERRIDE;

View File

@ -0,0 +1,38 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/ctocpp/jsdialog_callback_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
void CefJSDialogCallbackCToCpp::Continue(bool success,
const CefString& user_input) {
if (CEF_MEMBER_MISSING(struct_, cont))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: user_input
// Execute
struct_->cont(struct_,
success,
user_input.GetStruct());
}
#ifndef NDEBUG
template<> long CefCToCpp<CefJSDialogCallbackCToCpp, CefJSDialogCallback,
cef_jsdialog_callback_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,42 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_JSDIALOG_CALLBACK_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_JSDIALOG_CALLBACK_CTOCPP_H_
#pragma once
#ifndef USING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed wrapper-side only")
#else // USING_CEF_SHARED
#include "include/cef_jsdialog_handler.h"
#include "include/capi/cef_jsdialog_handler_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed wrapper-side only.
class CefJSDialogCallbackCToCpp
: public CefCToCpp<CefJSDialogCallbackCToCpp, CefJSDialogCallback,
cef_jsdialog_callback_t> {
public:
explicit CefJSDialogCallbackCToCpp(cef_jsdialog_callback_t* str)
: CefCToCpp<CefJSDialogCallbackCToCpp, CefJSDialogCallback,
cef_jsdialog_callback_t>(str) {}
virtual ~CefJSDialogCallbackCToCpp() {}
// CefJSDialogCallback methods
virtual void Continue(bool success, const CefString& user_input) OVERRIDE;
};
#endif // USING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_JSDIALOG_CALLBACK_CTOCPP_H_

View File

@ -0,0 +1,116 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/cpptoc/jsdialog_callback_cpptoc.h"
#include "libcef_dll/ctocpp/jsdialog_handler_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
bool CefJSDialogHandlerCToCpp::OnJSDialog(CefRefPtr<CefBrowser> browser,
const CefString& origin_url, const CefString& accept_lang,
JSDialogType dialog_type, const CefString& message_text,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback, bool& suppress_message) {
if (CEF_MEMBER_MISSING(struct_, on_jsdialog))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Verify param: origin_url; type: string_byref_const
DCHECK(!origin_url.empty());
if (origin_url.empty())
return false;
// Verify param: callback; type: refptr_diff
DCHECK(callback.get());
if (!callback.get())
return false;
// Unverified params: accept_lang, message_text, default_prompt_text
// Translate param: suppress_message; type: bool_byref
int suppress_messageInt = suppress_message;
// Execute
int _retval = struct_->on_jsdialog(struct_,
CefBrowserCppToC::Wrap(browser),
origin_url.GetStruct(),
accept_lang.GetStruct(),
dialog_type,
message_text.GetStruct(),
default_prompt_text.GetStruct(),
CefJSDialogCallbackCppToC::Wrap(callback),
&suppress_messageInt);
// Restore param:suppress_message; type: bool_byref
suppress_message = suppress_messageInt?true:false;
// Return type: bool
return _retval?true:false;
}
bool CefJSDialogHandlerCToCpp::OnBeforeUnloadDialog(
CefRefPtr<CefBrowser> browser, const CefString& message_text,
bool is_reload, CefRefPtr<CefJSDialogCallback> callback) {
if (CEF_MEMBER_MISSING(struct_, on_before_unload_dialog))
return false;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser; type: refptr_diff
DCHECK(browser.get());
if (!browser.get())
return false;
// Verify param: callback; type: refptr_diff
DCHECK(callback.get());
if (!callback.get())
return false;
// Unverified params: message_text
// Execute
int _retval = struct_->on_before_unload_dialog(struct_,
CefBrowserCppToC::Wrap(browser),
message_text.GetStruct(),
is_reload,
CefJSDialogCallbackCppToC::Wrap(callback));
// Return type: bool
return _retval?true:false;
}
void CefJSDialogHandlerCToCpp::OnResetDialogState(
CefRefPtr<CefBrowser> browser) {
if (CEF_MEMBER_MISSING(struct_, on_reset_dialog_state))
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_reset_dialog_state(struct_,
CefBrowserCppToC::Wrap(browser));
}
#ifndef NDEBUG
template<> long CefCToCpp<CefJSDialogHandlerCToCpp, CefJSDialogHandler,
cef_jsdialog_handler_t>::DebugObjCt = 0;
#endif

View File

@ -0,0 +1,51 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool. If making changes by
// hand only do so within the body of existing method and function
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_JSDIALOG_HANDLER_CTOCPP_H_
#define CEF_LIBCEF_DLL_CTOCPP_JSDIALOG_HANDLER_CTOCPP_H_
#pragma once
#ifndef BUILDING_CEF_SHARED
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
#else // BUILDING_CEF_SHARED
#include "include/cef_jsdialog_handler.h"
#include "include/capi/cef_jsdialog_handler_capi.h"
#include "libcef_dll/ctocpp/ctocpp.h"
// Wrap a C structure with a C++ class.
// This class may be instantiated and accessed DLL-side only.
class CefJSDialogHandlerCToCpp
: public CefCToCpp<CefJSDialogHandlerCToCpp, CefJSDialogHandler,
cef_jsdialog_handler_t> {
public:
explicit CefJSDialogHandlerCToCpp(cef_jsdialog_handler_t* str)
: CefCToCpp<CefJSDialogHandlerCToCpp, CefJSDialogHandler,
cef_jsdialog_handler_t>(str) {}
virtual ~CefJSDialogHandlerCToCpp() {}
// CefJSDialogHandler methods
virtual bool OnJSDialog(CefRefPtr<CefBrowser> browser,
const CefString& origin_url, const CefString& accept_lang,
JSDialogType dialog_type, const CefString& message_text,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback,
bool& suppress_message) OVERRIDE;
virtual bool OnBeforeUnloadDialog(CefRefPtr<CefBrowser> browser,
const CefString& message_text, bool is_reload,
CefRefPtr<CefJSDialogCallback> callback) OVERRIDE;
virtual void OnResetDialogState(CefRefPtr<CefBrowser> browser) OVERRIDE;
};
#endif // BUILDING_CEF_SHARED
#endif // CEF_LIBCEF_DLL_CTOCPP_JSDIALOG_HANDLER_CTOCPP_H_

View File

@ -31,6 +31,7 @@
#include "libcef_dll/cpptoc/dictionary_value_cpptoc.h"
#include "libcef_dll/cpptoc/frame_cpptoc.h"
#include "libcef_dll/cpptoc/geolocation_callback_cpptoc.h"
#include "libcef_dll/cpptoc/jsdialog_callback_cpptoc.h"
#include "libcef_dll/cpptoc/list_value_cpptoc.h"
#include "libcef_dll/cpptoc/post_data_cpptoc.h"
#include "libcef_dll/cpptoc/post_data_element_cpptoc.h"
@ -48,6 +49,7 @@
#include "libcef_dll/ctocpp/cookie_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/display_handler_ctocpp.h"
#include "libcef_dll/ctocpp/geolocation_handler_ctocpp.h"
#include "libcef_dll/ctocpp/jsdialog_handler_ctocpp.h"
#include "libcef_dll/ctocpp/life_span_handler_ctocpp.h"
#include "libcef_dll/ctocpp/load_handler_ctocpp.h"
#include "libcef_dll/ctocpp/proxy_handler_ctocpp.h"
@ -143,6 +145,8 @@ CEF_EXPORT void cef_shutdown() {
DCHECK_EQ(CefFrameCppToC::DebugObjCt, 0);
DCHECK_EQ(CefGeolocationCallbackCppToC::DebugObjCt, 0);
DCHECK_EQ(CefGeolocationHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefJSDialogCallbackCppToC::DebugObjCt, 0);
DCHECK_EQ(CefJSDialogHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefLifeSpanHandlerCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefListValueCppToC::DebugObjCt, 0);
DCHECK_EQ(CefLoadHandlerCToCpp::DebugObjCt, 0);

View File

@ -53,6 +53,42 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ALERT DIALOGEX 0, 0, 241, 76
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "JavaScript Alert"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,184,55,50,14
LTEXT "",IDC_DIALOGTEXT,16,17,210,30
END
IDD_CONFIRM DIALOGEX 0, 0, 241, 76
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "JavaScript Confirm"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
PUSHBUTTON "Cancel",IDCANCEL,184,55,50,14
DEFPUSHBUTTON "OK",IDOK,131,55,50,14
LTEXT "",IDC_DIALOGTEXT,16,17,210,30
END
IDD_PROMPT DIALOGEX 0, 0, 241, 76
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "JavaScript Prompt"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,131,55,50,14
LTEXT "",IDC_DIALOGTEXT,16,17,210,18
PUSHBUTTON "Cancel",IDCANCEL,184,55,50,14
EDITTEXT IDC_PROMPTEDIT,15,33,210,14,ES_AUTOHSCROLL
END
/////////////////////////////////////////////////////////////////////////////
//
// Version

View File

@ -6,6 +6,13 @@
// Avoid files associated with MacOS
#define _X86_
#define IDD_ALERT 130
#define IDD_CONFIRM 131
#define IDD_PROMPT 132
#define IDC_PROMPTEDIT 1000
#define IDC_DIALOGTEXT 1001
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED

View File

@ -27,6 +27,7 @@
#include "libcef_dll/cpptoc/cookie_visitor_cpptoc.h"
#include "libcef_dll/cpptoc/display_handler_cpptoc.h"
#include "libcef_dll/cpptoc/geolocation_handler_cpptoc.h"
#include "libcef_dll/cpptoc/jsdialog_handler_cpptoc.h"
#include "libcef_dll/cpptoc/life_span_handler_cpptoc.h"
#include "libcef_dll/cpptoc/load_handler_cpptoc.h"
#include "libcef_dll/cpptoc/proxy_handler_cpptoc.h"
@ -50,6 +51,7 @@
#include "libcef_dll/ctocpp/dictionary_value_ctocpp.h"
#include "libcef_dll/ctocpp/frame_ctocpp.h"
#include "libcef_dll/ctocpp/geolocation_callback_ctocpp.h"
#include "libcef_dll/ctocpp/jsdialog_callback_ctocpp.h"
#include "libcef_dll/ctocpp/list_value_ctocpp.h"
#include "libcef_dll/ctocpp/post_data_ctocpp.h"
#include "libcef_dll/ctocpp/post_data_element_ctocpp.h"
@ -135,6 +137,8 @@ CEF_GLOBAL void CefShutdown() {
DCHECK_EQ(CefFrameCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefGeolocationCallbackCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefGeolocationHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefJSDialogCallbackCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefJSDialogHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefLifeSpanHandlerCppToC::DebugObjCt, 0);
DCHECK_EQ(CefListValueCToCpp::DebugObjCt, 0);
DCHECK_EQ(CefLoadHandlerCppToC::DebugObjCt, 0);

View File

@ -322,6 +322,10 @@ void RunPopupTest(CefRefPtr<CefBrowser> browser) {
"window.open('http://www.google.com');", "about:blank", 0);
}
void RunDialogTest(CefRefPtr<CefBrowser> browser) {
browser->GetMainFrame()->LoadURL("http://tests/dialogs");
}
void RunLocalStorageTest(CefRefPtr<CefBrowser> browser) {
browser->GetMainFrame()->LoadURL("http://tests/localstorage");
}

View File

@ -40,6 +40,7 @@ void RunGetSourceTest(CefRefPtr<CefBrowser> browser);
void RunGetTextTest(CefRefPtr<CefBrowser> browser);
void RunRequestTest(CefRefPtr<CefBrowser> browser);
void RunPopupTest(CefRefPtr<CefBrowser> browser);
void RunDialogTest(CefRefPtr<CefBrowser> browser);
void RunLocalStorageTest(CefRefPtr<CefBrowser> browser);
void RunAccelerated2DCanvasTest(CefRefPtr<CefBrowser> browser);
void RunAcceleratedLayersTest(CefRefPtr<CefBrowser> browser);

View File

@ -29,6 +29,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
IDS_BINDING BINARY "res\\binding.html"
IDS_DIALOGS BINARY "res\\dialogs.html"
IDS_LOGO BINARY "res\\logo.png"
IDS_LOGOBALL BINARY "res\\logoball.png"
IDS_LOCALSTORAGE BINARY "res\\localstorage.html"
@ -67,6 +68,7 @@ BEGIN
MENUITEM "Request", ID_TESTS_REQUEST
MENUITEM "Scheme Handler", ID_TESTS_SCHEME_HANDLER
MENUITEM "JavaScript Binding", ID_TESTS_BINDING
MENUITEM "JavaScript Dialogs", ID_TESTS_DIALOGS
MENUITEM "Local Storage", ID_TESTS_LOCALSTORAGE
MENUITEM "XMLHttpRequest", ID_TESTS_XMLHTTPREQUEST
MENUITEM "Accelerated 2D Canvas", ID_TESTS_ACCELERATED2DCANVAS

View File

@ -230,6 +230,7 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
- (IBAction)testXMLHttpRequest:(id)sender;
- (IBAction)testSchemeHandler:(id)sender;
- (IBAction)testBinding:(id)sender;
- (IBAction)testDialogs:(id)sender;
- (IBAction)testPopupWindow:(id)sender;
- (IBAction)testAccelerated2DCanvas:(id)sender;
- (IBAction)testAcceleratedLayers:(id)sender;
@ -272,6 +273,9 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
[testMenu addItemWithTitle:@"JavaScript Binding"
action:@selector(testBinding:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"JavaScript Dialogs"
action:@selector(testDialogs:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Local Storage"
action:@selector(testLocalStorage:)
keyEquivalent:@""];
@ -419,6 +423,11 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
binding_test::RunTest(g_handler->GetBrowser());
}
- (IBAction)testDialogs:(id)sender {
if (g_handler.get() && g_handler->GetBrowserId())
RunDialogTest(g_handler->GetBrowser());
}
- (IBAction)testPopupWindow:(id)sender {
if (g_handler.get() && g_handler->GetBrowserId())
RunPopupTest(g_handler->GetBrowser());

View File

@ -377,6 +377,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
if (browser.get())
binding_test::RunTest(browser);
return 0;
case ID_TESTS_DIALOGS: // Test JavaScript dialofs
if (browser.get())
RunDialogTest(browser);
return 0;
case ID_TESTS_LOCALSTORAGE: // Test localStorage
if (browser.get())
RunLocalStorageTest(browser);

View File

@ -137,6 +137,12 @@ CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
dump.size());
ASSERT(stream.get());
return new CefStreamResourceHandler("text/plain", stream);
} else if (url == "http://tests/dialogs") {
// Show the dialogs contents
CefRefPtr<CefStreamReader> stream =
GetBinaryResourceReader("dialogs.html");
ASSERT(stream.get());
return new CefStreamResourceHandler("text/html", stream);
} else if (url == "http://tests/localstorage") {
// Show the localstorage contents
CefRefPtr<CefStreamReader> stream =

View File

@ -0,0 +1,45 @@
<html>
<head>
<title>Dialog Test</title>
<script>
function show_alert() {
alert("I am an alert box!");
}
function show_confirm() {
var r = confirm("Press a button");
var msg = r ? "You pressed OK!" : "You pressed Cancel!";
document.getElementById('cm').innerText = msg;
}
function show_prompt() {
var name = prompt("Please enter your name" ,"Harry Potter");
if (name != null && name != "")
document.getElementById('pm').innerText = "Hello " + name + "!";
}
window.onbeforeunload = function() {
return 'This is an onbeforeunload message.';
}
function update_time() {
document.getElementById('time').innerText = new Date().toLocaleString();
}
function setup() {
setInterval(update_time, 1000);
}
window.addEventListener('load', setup, false);
</script>
</head>
<body>
<form>
Click a button to show the associated dialog type.
<br/><input type="button" onclick="show_alert();" value="Show Alert">
<br/><input type="button" onclick="show_confirm();" value="Show Confirm"> <span id="cm"></span>
<br/><input type="button" onclick="show_prompt();" value="Show Prompt"> <span id="pm"></span>
<p id="time"></p>
</form>
</body>
</html>

View File

@ -38,12 +38,14 @@
#define ID_TESTS_DRAGDROP 32771
#define ID_TESTS_GEOLOCATION 32772
#define ID_TESTS_BINDING 32773
#define ID_TESTS_DIALOGS 32774
#define IDC_STATIC -1
#define IDS_BINDING 1000
#define IDS_LOGO 1001
#define IDS_LOGOBALL 1002
#define IDS_LOCALSTORAGE 1003
#define IDS_XMLHTTPREQUEST 1004
#define IDS_DIALOGS 1001
#define IDS_LOGO 1002
#define IDS_LOGOBALL 1003
#define IDS_LOCALSTORAGE 1004
#define IDS_XMLHTTPREQUEST 1005
// Avoid files associated with MacOS
#define _X86_

View File

@ -35,6 +35,7 @@ CefRefPtr<CefStreamReader> GetBinaryResourceReader(int binaryId) {
new CefByteReadHandler(pBytes, dwSize, NULL));
}
ASSERT(FALSE); // The resource should be found.
return NULL;
}
@ -45,6 +46,7 @@ CefRefPtr<CefStreamReader> GetBinaryResourceReader(const char* resource_name) {
int id;
} resource_map[] = {
{"binding.html", IDS_BINDING},
{"dialogs.html", IDS_DIALOGS},
{"localstorage.html", IDS_LOCALSTORAGE},
{"xmlhttprequest.html", IDS_XMLHTTPREQUEST},
};

View File

@ -0,0 +1,413 @@
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "include/cef_runnable.h"
#include "tests/unittests/test_handler.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char* kStartUrl = "http://tests/JSDialogTestHandler.Start";
const char* kEndUrl = "http://tests/JSDialogTestHandler.End?r=";
class JSDialogTestHandler : public TestHandler {
public:
enum TestType {
TYPE_ALERT,
TYPE_CONFIRM,
TYPE_PROMPT,
TYPE_ONBEFOREUNLOAD,
};
enum TestMode {
MODE_SUPPRESS,
MODE_RUN_IMMEDIATE,
MODE_RUN_DELAYED,
};
JSDialogTestHandler(TestType type,
TestMode mode,
bool success,
const std::string& user_input,
const std::string& result)
: type_(type),
mode_(mode),
success_(success),
user_input_(user_input),
result_(result) {
}
virtual void RunTest() OVERRIDE {
std::string content = "<html><head><body>START<script>";
if (type_ == TYPE_ALERT) {
content += "alert('My alert message'); "
"document.location='"+std::string(kEndUrl)+"';";
} else if (type_ == TYPE_CONFIRM) {
content += "var r = confirm('My confirm message')?'ok':'cancel'; "
"document.location='"+std::string(kEndUrl)+"'+r;";
} else if (type_ == TYPE_PROMPT) {
content += "var r = prompt('My prompt message','my default'); "
"document.location='"+std::string(kEndUrl)+"'+r;";
} else if (type_ == TYPE_ONBEFOREUNLOAD) {
content += "window.onbeforeunload=function() {"
" return 'My unload message'; };";
}
content += "</script></body></html>";
AddResource(kStartUrl, content, "text/html");
AddResource(kEndUrl, "<html><body>END</body></html>", "text/html");
// Create the browser
CreateBrowser(kStartUrl);
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE {
if (!frame->IsMain())
return;
std::string url = frame->GetURL();
if (url.find(kEndUrl) == 0) {
got_onloadend_.yes();
std::string result = url.substr(strlen(kEndUrl));
EXPECT_STREQ(result_.c_str(), result.c_str());
DestroyTest();
} else if (type_ == TYPE_ONBEFOREUNLOAD) {
// Trigger the onunload handler.
frame->LoadURL(kEndUrl);
}
}
virtual void Continue(CefRefPtr<CefJSDialogCallback> callback) {
callback->Continue(success_, user_input_);
}
virtual bool OnJSDialog(CefRefPtr<CefBrowser> browser,
const CefString& origin_url,
const CefString& accept_lang,
JSDialogType dialog_type,
const CefString& message_text,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback,
bool& suppress_message) OVERRIDE {
got_onjsdialog_.yes();
EXPECT_STREQ("http://tests/", origin_url.ToString().c_str());
EXPECT_TRUE(accept_lang.empty());
if (type_ == TYPE_ALERT) {
EXPECT_EQ(JSDIALOGTYPE_ALERT, dialog_type);
EXPECT_STREQ("My alert message", message_text.ToString().c_str());
EXPECT_TRUE(default_prompt_text.empty());
} else if (type_ == TYPE_CONFIRM) {
EXPECT_EQ(JSDIALOGTYPE_CONFIRM, dialog_type);
EXPECT_STREQ("My confirm message", message_text.ToString().c_str());
EXPECT_TRUE(default_prompt_text.empty());
} else if (type_ == TYPE_PROMPT) {
EXPECT_EQ(JSDIALOGTYPE_PROMPT, dialog_type);
EXPECT_STREQ("My prompt message", message_text.ToString().c_str());
EXPECT_STREQ("my default", default_prompt_text.ToString().c_str());
}
EXPECT_FALSE(suppress_message);
if (mode_ == MODE_SUPPRESS) {
// Suppress the dialog.
suppress_message = true;
return false;
} else if (mode_ == MODE_RUN_IMMEDIATE) {
// Continue immediately.
callback->Continue(success_, user_input_);
} else if (mode_ == MODE_RUN_DELAYED) {
// Continue asynchronously.
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &JSDialogTestHandler::Continue, callback));
}
return true;
}
virtual bool OnBeforeUnloadDialog(CefRefPtr<CefBrowser> browser,
const CefString& message_text,
bool is_reload,
CefRefPtr<CefJSDialogCallback> callback)
OVERRIDE {
got_onbeforeunloaddialog_.yes();
if (type_ == TYPE_ONBEFOREUNLOAD) {
EXPECT_STREQ("My unload message", message_text.ToString().c_str());
EXPECT_FALSE(is_reload);
}
if (mode_ == MODE_RUN_IMMEDIATE) {
// Continue immediately.
callback->Continue(success_, user_input_);
} else if (mode_ == MODE_RUN_DELAYED) {
// Continue asynchronously.
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &JSDialogTestHandler::Continue, callback));
}
return true;
}
virtual void OnResetDialogState(CefRefPtr<CefBrowser> browser) OVERRIDE {
got_onresetdialogstate_.yes();
}
TestType type_;
TestMode mode_;
bool success_;
std::string user_input_;
std::string result_;
TrackCallback got_onjsdialog_;
TrackCallback got_onbeforeunloaddialog_;
TrackCallback got_onresetdialogstate_;
TrackCallback got_onloadend_;
};
} // namespace
// Alert dialog with suppression.
TEST(JSDialogTest, AlertSuppress) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_ALERT,
JSDialogTestHandler::MODE_SUPPRESS,
true, // success
"", // user_input
""); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Alert dialog with immediate callback.
TEST(JSDialogTest, AlertRunImmediate) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_ALERT,
JSDialogTestHandler::MODE_RUN_IMMEDIATE,
true, // success
"", // user_input
""); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Alert dialog with delayed callback.
TEST(JSDialogTest, AlertRunDelayed) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_ALERT,
JSDialogTestHandler::MODE_RUN_DELAYED,
true, // success
"", // user_input
""); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Confirm dialog with suppression.
TEST(JSDialogTest, ConfirmSuppress) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_CONFIRM,
JSDialogTestHandler::MODE_SUPPRESS,
true, // success
"", // user_input
"cancel"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Confirm dialog run immediately return OK.
TEST(JSDialogTest, ConfirmRunImmediateOk) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_CONFIRM,
JSDialogTestHandler::MODE_RUN_IMMEDIATE,
true, // success
"", // user_input
"ok"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Confirm dialog run immediately return Cancel.
TEST(JSDialogTest, ConfirmRunImmediateCancel) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_CONFIRM,
JSDialogTestHandler::MODE_RUN_IMMEDIATE,
false, // success
"", // user_input
"cancel"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Confirm dialog run delayed return OK.
TEST(JSDialogTest, ConfirmRunDelayedOk) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_CONFIRM,
JSDialogTestHandler::MODE_RUN_DELAYED,
true, // success
"", // user_input
"ok"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Confirm dialog run delayed return Cancel.
TEST(JSDialogTest, ConfirmRunDelayedCancel) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_CONFIRM,
JSDialogTestHandler::MODE_RUN_DELAYED,
false, // success
"", // user_input
"cancel"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Prompt dialog with suppression.
TEST(JSDialogTest, PromptSuppress) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_PROMPT,
JSDialogTestHandler::MODE_SUPPRESS,
true, // success
"some_value", // user_input
"null"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Prompt dialog run immediately return OK.
TEST(JSDialogTest, PromptRunImmediateOk) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_PROMPT,
JSDialogTestHandler::MODE_RUN_IMMEDIATE,
true, // success
"some_value", // user_input
"some_value"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Prompt dialog run immediately return Cancel.
TEST(JSDialogTest, PromptRunImmediateCancel) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_PROMPT,
JSDialogTestHandler::MODE_RUN_IMMEDIATE,
false, // success
"some_value", // user_input
"null"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Prompt dialog run delayed return OK.
TEST(JSDialogTest, PromptRunDelayedOk) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_PROMPT,
JSDialogTestHandler::MODE_RUN_DELAYED,
true, // success
"some_value", // user_input
"some_value"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// Prompt dialog run delayed return Cancel.
TEST(JSDialogTest, PromptRunDelayedCancel) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_PROMPT,
JSDialogTestHandler::MODE_RUN_DELAYED,
false, // success
"some_value", // user_input
"null"); // result
handler->ExecuteTest();
EXPECT_TRUE(handler->got_onjsdialog_);
EXPECT_FALSE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// OnBeforeUnload dialog with immediate callback.
TEST(JSDialogTest, OnBeforeUnloadRunImmediate) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_ONBEFOREUNLOAD,
JSDialogTestHandler::MODE_RUN_IMMEDIATE,
true, // success
"", // user_input
""); // result
handler->ExecuteTest();
EXPECT_FALSE(handler->got_onjsdialog_);
EXPECT_TRUE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}
// OnBeforeUnload dialog with delayed callback.
TEST(JSDialogTest, OnBeforeUnloadRunDelayed) {
CefRefPtr<JSDialogTestHandler> handler =
new JSDialogTestHandler(JSDialogTestHandler::TYPE_ONBEFOREUNLOAD,
JSDialogTestHandler::MODE_RUN_DELAYED,
true, // success
"", // user_input
""); // result
handler->ExecuteTest();
EXPECT_FALSE(handler->got_onjsdialog_);
EXPECT_TRUE(handler->got_onbeforeunloaddialog_);
EXPECT_TRUE(handler->got_onresetdialogstate_);
EXPECT_TRUE(handler->got_onloadend_);
}

View File

@ -56,7 +56,14 @@ CefRefPtr<CefResourceHandler> TestHandler::GetResourceHandler(
if (resource_map_.size() > 0) {
CefString url = request->GetURL();
ResourceMap::const_iterator it = resource_map_.find(url);
// Ignore the query component, if any.
std::string urlStr = url;
int idx = urlStr.find('?');
if (idx > 0)
urlStr = urlStr.substr(0, idx);
ResourceMap::const_iterator it = resource_map_.find(urlStr);
if (it != resource_map_.end()) {
// Return the previously mapped resource
CefRefPtr<CefStreamReader> stream =
@ -97,10 +104,17 @@ void TestHandler::CreateBrowser(const CefString& url) {
CefBrowserHost::CreateBrowser(windowInfo, this, url, settings);
}
void TestHandler::AddResource(const CefString& url,
void TestHandler::AddResource(const std::string& url,
const std::string& content,
const CefString& mimeType) {
resource_map_.insert(std::make_pair(url, std::make_pair(content, mimeType)));
const std::string& mimeType) {
// Ignore the query component, if any.
std::string urlStr = url;
int idx = urlStr.find('?');
if (idx > 0)
urlStr = urlStr.substr(0, idx);
resource_map_.insert(
std::make_pair(urlStr, std::make_pair(content, mimeType)));
}
void TestHandler::ClearResources() {

View File

@ -32,6 +32,7 @@ class TrackCallback {
// by test cases.
class TestHandler : public CefClient,
public CefDisplayHandler,
public CefJSDialogHandler,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRequestHandler {
@ -46,6 +47,9 @@ class TestHandler : public CefClient,
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE {
return this;
}
@ -81,9 +85,9 @@ class TestHandler : public CefClient,
void CreateBrowser(const CefString& url);
void AddResource(const CefString& url,
void AddResource(const std::string& url,
const std::string& content,
const CefString& mimeType);
const std::string& mimeType);
void ClearResources();
private:
@ -97,7 +101,8 @@ class TestHandler : public CefClient,
base::WaitableEvent completion_event_;
// Map of resources that can be automatically loaded
typedef std::map<CefString, std::pair<std::string, CefString> > ResourceMap;
typedef std::map<std::string, std::pair<std::string, std::string> >
ResourceMap;
ResourceMap resource_map_;
// Include the default reference counting implementation.