0

Remove JS dialog dependency from content.

BUG=71097
TEST=all types of javascript dialogs work, onbeforeunload dialogs work too

Review URL: http://codereview.chromium.org/7096016

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87806 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
avi@chromium.org
2011-06-03 18:02:07 +00:00
parent eadd4e3164
commit 3ab9cb8173
46 changed files with 523 additions and 304 deletions

@ -7,6 +7,7 @@
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/automation/automation_tab_helper.h"
#include "chrome/browser/automation/mock_tab_event_observer.h"
#include "chrome/browser/ui/browser.h"

@ -5094,7 +5094,7 @@ void TestingAutomationProvider::GetAppModalDialogMessage(
return;
}
DictionaryValue result_dict;
result_dict.SetString("message", WideToUTF8(dialog->message_text()));
result_dict.SetString("message", UTF16ToUTF8(dialog->message_text()));
reply.SendSuccess(&result_dict);
}

@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/background_contents_service.h"
#include "chrome/browser/background_contents_service_factory.h"
#include "chrome/browser/extensions/extension_apitest.h"

@ -32,6 +32,7 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browsing_instance.h"
#include "content/browser/content_browser_client.h"
#include "content/browser/renderer_host/browser_render_process_host.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
@ -41,6 +42,7 @@
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_view.h"
#include "content/common/bindings_policy.h"
#include "content/common/content_client.h"
#include "content/common/native_web_keyboard_event.h"
#include "content/common/notification_service.h"
#include "content/common/view_messages.h"
@ -134,8 +136,7 @@ ExtensionHost::ExtensionHost(const Extension* extension,
ALLOW_THIS_IN_INITIALIZER_LIST(
extension_function_dispatcher_(profile_, this)),
extension_host_type_(host_type),
associated_tab_contents_(NULL),
suppress_javascript_messages_(false) {
associated_tab_contents_(NULL) {
render_view_host_ = new RenderViewHost(site_instance, this, MSG_ROUTING_NONE,
NULL);
if (enable_dom_automation_)
@ -157,6 +158,7 @@ ExtensionHost::~ExtensionHost() {
Source<Profile>(profile_),
Details<ExtensionHost>(this));
ProcessCreationQueue::GetInstance()->Remove(this);
GetJavaScriptDialogCreatorInstance()->ResetJavaScriptState(this);
render_view_host_->Shutdown(); // deletes render_view_host
}
@ -416,38 +418,27 @@ void ExtensionHost::RunJavaScriptMessage(const RenderViewHost* rvh,
const int flags,
IPC::Message* reply_msg,
bool* did_suppress_message) {
base::TimeDelta time_since_last_message(
base::TimeTicks::Now() - last_javascript_message_dismissal_);
bool suppress_this_message = false;
GetJavaScriptDialogCreatorInstance()->RunJavaScriptDialog(
this,
frame_url,
flags,
message,
default_prompt,
reply_msg,
&suppress_this_message,
profile());
*did_suppress_message = suppress_javascript_messages_;
if (!suppress_javascript_messages_) {
bool show_suppress_checkbox = false;
// Show a checkbox offering to suppress further messages if this message is
// being displayed within kJavascriptMessageExpectedDelay of the last one.
if (time_since_last_message <
base::TimeDelta::FromMilliseconds(
chrome::kJavascriptMessageExpectedDelay))
show_suppress_checkbox = true;
// Unlike for page alerts, navigations aren't a good signal for when to
// resume showing alerts, so we can't reasonably stop showing them even if
// the extension is spammy.
RunJavascriptMessageBox(profile_,
this,
frame_url,
flags,
UTF16ToWideHack(message),
UTF16ToWideHack(default_prompt),
show_suppress_checkbox,
reply_msg);
} else {
// If we are suppressing messages, just reply as is if the user immediately
if (suppress_this_message) {
// If we are suppressing messages, just reply as if the user immediately
// pressed "Cancel".
OnMessageBoxClosed(reply_msg, false, std::wstring());
OnDialogClosed(reply_msg, false, string16());
}
*did_suppress_message = suppress_this_message;
}
gfx::NativeWindow ExtensionHost::GetMessageBoxRootWindow() {
gfx::NativeWindow ExtensionHost::GetDialogRootWindow() {
// If we have a view, use that.
gfx::NativeView native_view = GetNativeViewOfHost();
if (native_view)
@ -473,17 +464,12 @@ ExtensionHost* ExtensionHost::AsExtensionHost() {
return this;
}
void ExtensionHost::OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& user_input) {
last_javascript_message_dismissal_ = base::TimeTicks::Now();
void ExtensionHost::OnDialogClosed(IPC::Message* reply_msg,
bool success,
const string16& user_input) {
render_view_host()->JavaScriptDialogClosed(reply_msg,
success,
WideToUTF16Hack(user_input));
}
void ExtensionHost::SetSuppressMessageBoxes(bool suppress_message_boxes) {
suppress_javascript_messages_ = suppress_message_boxes;
user_input);
}
void ExtensionHost::Close(RenderViewHost* render_view_host) {

@ -13,8 +13,9 @@
#include "base/perftimer.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h"
#include "content/browser/javascript_dialogs.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#if defined(TOOLKIT_VIEWS)
@ -42,7 +43,7 @@ class ExtensionHost : public RenderViewHostDelegate,
public RenderViewHostDelegate::View,
public ExtensionFunctionDispatcher::Delegate,
public NotificationObserver,
public JavaScriptAppModalDialogDelegate {
public content::JavaScriptDialogDelegate {
public:
class ProcessCreationQueue;
@ -187,14 +188,13 @@ class ExtensionHost : public RenderViewHostDelegate,
const NotificationSource& source,
const NotificationDetails& details);
// Overridden from JavaScriptAppModalDialogDelegate:
virtual void OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& user_input);
virtual void SetSuppressMessageBoxes(bool suppress_message_boxes);
virtual gfx::NativeWindow GetMessageBoxRootWindow();
virtual TabContents* AsTabContents();
virtual ExtensionHost* AsExtensionHost();
// Overridden from content::JavaScriptDialogDelegate:
virtual void OnDialogClosed(IPC::Message* reply_msg,
bool success,
const string16& user_input) OVERRIDE;
virtual gfx::NativeWindow GetDialogRootWindow() OVERRIDE;
virtual TabContents* AsTabContents() OVERRIDE;
virtual ExtensionHost* AsExtensionHost() OVERRIDE;
protected:
// Internal functions used to support the CreateNewWidget() method. If a
@ -291,12 +291,6 @@ class ExtensionHost : public RenderViewHostDelegate,
// FileSelectHelper, lazily created.
scoped_ptr<FileSelectHelper> file_select_helper_;
// The time that the last javascript message was dismissed.
base::TimeTicks last_javascript_message_dismissal_;
// Whether to suppress all javascript messages.
bool suppress_javascript_messages_;
DISALLOW_COPY_AND_ASSIGN(ExtensionHost);
};

@ -21,6 +21,7 @@
#include "chrome/browser/history/history_tab_helper.h"
#include "chrome/browser/page_info_window.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
@ -593,6 +594,11 @@ void ExternalTabContainer::UnregisterRenderViewHost(
}
}
content::JavaScriptDialogCreator*
ExternalTabContainer::GetJavaScriptDialogCreator() {
return GetJavaScriptDialogCreatorInstance();
}
bool ExternalTabContainer::HandleContextMenu(const ContextMenuParams& params) {
if (!automation_) {
NOTREACHED();

@ -165,11 +165,15 @@ class ExternalTabContainer : public TabContentsDelegate,
bool proceed,
bool* proceed_to_fire_unload);
virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator()
OVERRIDE;
void ShowRepostFormWarningDialog(TabContents* tab_contents);
void RegisterRenderViewHost(RenderViewHost* render_view_host);
void UnregisterRenderViewHost(RenderViewHost* render_view_host);
// Overridden from TabContentsObserver:
// IPC::Channel::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& message);

@ -6,6 +6,7 @@
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_resource.h"
#include "chrome/common/extensions/extension_sidebar_defaults.h"
@ -108,6 +109,11 @@ bool SidebarContainer::IsPopup(const TabContents* source) const {
return false;
}
content::JavaScriptDialogCreator*
SidebarContainer::GetJavaScriptDialogCreator() {
return GetJavaScriptDialogCreatorInstance();
}
void SidebarContainer::OnImageLoaded(SkBitmap* image,
const ExtensionResource& resource,
int index) {

@ -113,6 +113,8 @@ class SidebarContainer
virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {}
virtual bool IsPopup(const TabContents* source) const;
virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator()
OVERRIDE;
// Overridden from ImageLoadingTracker::Observer.
virtual void OnImageLoaded(SkBitmap* image,

@ -109,8 +109,12 @@ void BackgroundContents::RunJavaScriptMessage(
const int flags,
IPC::Message* reply_msg,
bool* did_suppress_message) {
// TODO(rafaelw): Implement, The JavaScriptModalDialog needs to learn about
// BackgroundContents.
// TODO(rafaelw): Implement.
// Since we are suppressing messages, just reply as if the user immediately
// pressed "Cancel".
OnDialogClosed(reply_msg, false, string16());
*did_suppress_message = true;
}
@ -137,15 +141,15 @@ void BackgroundContents::Observe(NotificationType type,
}
}
void BackgroundContents::OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& user_input) {
void BackgroundContents::OnDialogClosed(IPC::Message* reply_msg,
bool success,
const string16& user_input) {
render_view_host()->JavaScriptDialogClosed(reply_msg,
success,
WideToUTF16Hack(user_input));
user_input);
}
gfx::NativeWindow BackgroundContents::GetMessageBoxRootWindow() {
gfx::NativeWindow BackgroundContents::GetDialogRootWindow() {
NOTIMPLEMENTED();
return NULL;
}

@ -11,8 +11,9 @@
#include "base/scoped_ptr.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
#include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h"
#include "content/browser/javascript_dialogs.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "content/common/window_container_type.h"
#include "webkit/glue/window_open_disposition.h"
@ -32,7 +33,7 @@ class Rect;
class BackgroundContents : public RenderViewHostDelegate,
public RenderViewHostDelegate::View,
public NotificationObserver,
public JavaScriptAppModalDialogDelegate {
public content::JavaScriptDialogDelegate {
public:
class Delegate {
public:
@ -124,14 +125,13 @@ class BackgroundContents : public RenderViewHostDelegate,
const NotificationSource& source,
const NotificationDetails& details);
// Overridden from JavaScriptAppModalDialogDelegate:
virtual void OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& user_input);
virtual void SetSuppressMessageBoxes(bool suppress_message_boxes) {}
virtual gfx::NativeWindow GetMessageBoxRootWindow();
virtual TabContents* AsTabContents();
virtual ExtensionHost* AsExtensionHost();
// Overridden from JavaScriptDialogDelegate:
virtual void OnDialogClosed(IPC::Message* reply_msg,
bool success,
const string16& user_input) OVERRIDE;
virtual gfx::NativeWindow GetDialogRootWindow() OVERRIDE;
virtual TabContents* AsTabContents() OVERRIDE;
virtual ExtensionHost* AsExtensionHost() OVERRIDE;
virtual void UpdateInspectorSetting(const std::string& key,
const std::string& value);

@ -89,7 +89,7 @@ string16 SSLCertAddedInfoBarDelegate::GetButtonLabel(
}
bool SSLCertAddedInfoBarDelegate::Accept() {
ShowCertificateViewer(tab_contents_->GetMessageBoxRootWindow(), cert_);
ShowCertificateViewer(tab_contents_->GetDialogRootWindow(), cert_);
return false; // Hiding the infobar just as the dialog opens looks weird.
}

@ -11,7 +11,7 @@
#include "content/common/notification_type.h"
AppModalDialog::AppModalDialog(TabContents* tab_contents,
const std::wstring& title)
const string16& title)
: skip_this_dialog_(false),
tab_contents_(tab_contents),
native_dialog_(NULL),

@ -9,6 +9,7 @@
#include <string>
#include "base/basictypes.h"
#include "base/string16.h"
#include "build/build_config.h"
class NativeAppModalDialog;
@ -20,7 +21,7 @@ class AppModalDialog {
// A union of data necessary to determine the type of message box to
// show. |tab_contents| parameter is optional, if provided that tab will be
// activated before the modal dialog is displayed.
AppModalDialog(TabContents* tab_contents, const std::wstring& title);
AppModalDialog(TabContents* tab_contents, const string16& title);
virtual ~AppModalDialog();
// Called by the AppModalDialogQueue to show this dialog.
@ -37,7 +38,7 @@ class AppModalDialog {
void CompleteDialog();
// Dialog window title.
std::wstring title() const { return title_; }
string16 title() const { return title_; }
NativeAppModalDialog* native_dialog() const { return native_dialog_; }
@ -76,7 +77,7 @@ class AppModalDialog {
private:
// Information about the message box is held in the following variables.
std::wstring title_;
string16 title_;
DISALLOW_COPY_AND_ASSIGN(AppModalDialog);
};

@ -48,28 +48,31 @@ void EnforceMaxPromptSize(const string16& in_string, string16* out_string) {
} // namespace
ChromeJavaScriptDialogExtraData::ChromeJavaScriptDialogExtraData()
: suppress_javascript_messages_(false) {
}
JavaScriptAppModalDialog::JavaScriptAppModalDialog(
JavaScriptAppModalDialogDelegate* delegate,
const std::wstring& title,
content::JavaScriptDialogDelegate* delegate,
ChromeJavaScriptDialogExtraData* extra_data,
const string16& title,
int dialog_flags,
const std::wstring& message_text,
const std::wstring& default_prompt_text,
const string16& message_text,
const string16& default_prompt_text,
bool display_suppress_checkbox,
bool is_before_unload_dialog,
IPC::Message* reply_msg)
: AppModalDialog(delegate->AsTabContents(), title),
delegate_(delegate),
extra_data_(extra_data),
extension_host_(delegate->AsExtensionHost()),
dialog_flags_(dialog_flags),
display_suppress_checkbox_(display_suppress_checkbox),
is_before_unload_dialog_(is_before_unload_dialog),
reply_msg_(reply_msg),
use_override_prompt_text_(false) {
string16 elided_text;
EnforceMaxTextSize(WideToUTF16(message_text), &elided_text);
message_text_ = UTF16ToWide(elided_text);
EnforceMaxPromptSize(WideToUTF16Hack(default_prompt_text),
&default_prompt_text_);
EnforceMaxTextSize(message_text, &message_text_);
EnforceMaxPromptSize(default_prompt_text, &default_prompt_text_);
DCHECK((tab_contents_ != NULL) != (extension_host_ != NULL));
InitNotifications();
@ -79,9 +82,7 @@ JavaScriptAppModalDialog::~JavaScriptAppModalDialog() {
}
NativeAppModalDialog* JavaScriptAppModalDialog::CreateNativeDialog() {
gfx::NativeWindow parent_window = tab_contents_ ?
tab_contents_->GetMessageBoxRootWindow() :
extension_host_->GetMessageBoxRootWindow();
gfx::NativeWindow parent_window = delegate_->GetDialogRootWindow();
return NativeAppModalDialog::CreateNativeJavaScriptPrompt(this,
parent_window);
}
@ -142,22 +143,22 @@ void JavaScriptAppModalDialog::OnCancel(bool suppress_js_messages) {
// is a temporary workaround.
CompleteDialog();
NotifyDelegate(false, L"", suppress_js_messages);
NotifyDelegate(false, string16(), suppress_js_messages);
}
void JavaScriptAppModalDialog::OnAccept(const std::wstring& prompt_text,
void JavaScriptAppModalDialog::OnAccept(const string16& prompt_text,
bool suppress_js_messages) {
std::wstring prompt_text_to_use = prompt_text;
string16 prompt_text_to_use = prompt_text;
// This is only for testing.
if (use_override_prompt_text_)
prompt_text_to_use = UTF16ToWideHack(override_prompt_text_);
prompt_text_to_use = override_prompt_text_;
CompleteDialog();
NotifyDelegate(true, prompt_text_to_use, suppress_js_messages);
}
void JavaScriptAppModalDialog::OnClose() {
NotifyDelegate(false, L"", false);
NotifyDelegate(false, string16(), false);
}
void JavaScriptAppModalDialog::SetOverridePromptText(
@ -167,14 +168,15 @@ void JavaScriptAppModalDialog::SetOverridePromptText(
}
void JavaScriptAppModalDialog::NotifyDelegate(bool success,
const std::wstring& prompt_text,
const string16& user_input,
bool suppress_js_messages) {
if (skip_this_dialog_)
return;
delegate_->OnMessageBoxClosed(reply_msg_, success, prompt_text);
if (suppress_js_messages)
delegate_->SetSuppressMessageBoxes(true);
delegate_->OnDialogClosed(reply_msg_, success, user_input);
extra_data_->last_javascript_message_dismissal_ = base::TimeTicks::Now();
extra_data_->suppress_javascript_messages_ = suppress_js_messages;
// On Views, we can end up coming through this code path twice :(.
// See crbug.com/63732.

@ -8,12 +8,12 @@
#include <string>
#include "base/utf_string_conversions.h"
#include "base/time.h"
#include "build/build_config.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
#include "content/browser/javascript_dialogs.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "ui/gfx/native_widget_types.h"
class ExtensionHost;
class NativeAppModalDialog;
@ -23,28 +23,16 @@ namespace IPC {
class Message;
}
class JavaScriptAppModalDialogDelegate {
// Extra data for JavaScript dialogs to add Chrome-only features.
class ChromeJavaScriptDialogExtraData {
public:
// AppModalDialog calls this when the dialog is closed.
virtual void OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& prompt) = 0;
ChromeJavaScriptDialogExtraData();
// Indicates whether additional message boxes should be suppressed.
virtual void SetSuppressMessageBoxes(bool suppress_message_boxes) = 0;
// The time that the last JavaScript dialog was dismissed.
base::TimeTicks last_javascript_message_dismissal_;
// Returns the root native window with which the message box is associated.
virtual gfx::NativeWindow GetMessageBoxRootWindow() = 0;
// Returns the TabContents or ExtensionHost associated with this message
// box -- in practice, the object implementing this interface. Exactly one
// of these must be non-NULL; behavior is undefined (read: it'll probably
// crash) if that is not the case.
virtual TabContents* AsTabContents() = 0;
virtual ExtensionHost* AsExtensionHost() = 0;
protected:
virtual ~JavaScriptAppModalDialogDelegate() {}
// True if the user has decided to block future JavaScript dialogs.
bool suppress_javascript_messages_;
};
// A controller + model class for JavaScript alert, confirm, prompt, and
@ -52,11 +40,12 @@ class JavaScriptAppModalDialogDelegate {
class JavaScriptAppModalDialog : public AppModalDialog,
public NotificationObserver {
public:
JavaScriptAppModalDialog(JavaScriptAppModalDialogDelegate* delegate,
const std::wstring& title,
JavaScriptAppModalDialog(content::JavaScriptDialogDelegate* delegate,
ChromeJavaScriptDialogExtraData* extra_data,
const string16& title,
int dialog_flags,
const std::wstring& message_text,
const std::wstring& default_prompt_text,
const string16& message_text,
const string16& default_prompt_text,
bool display_suppress_checkbox,
bool is_before_unload_dialog,
IPC::Message* reply_msg);
@ -66,11 +55,11 @@ class JavaScriptAppModalDialog : public AppModalDialog,
virtual NativeAppModalDialog* CreateNativeDialog();
virtual bool IsJavaScriptModalDialog();
JavaScriptAppModalDialogDelegate* delegate() const { return delegate_; }
content::JavaScriptDialogDelegate* delegate() const { return delegate_; }
// Callbacks from NativeDialog when the user accepts or cancels the dialog.
void OnCancel(bool suppress_js_messages);
void OnAccept(const std::wstring& prompt_text, bool suppress_js_messages);
void OnAccept(const string16& prompt_text, bool suppress_js_messages);
// NOTE: This is only called under Views, and should be removed. Any critical
// work should be done in OnCancel or OnAccept. See crbug.com/63732 for more.
@ -82,10 +71,8 @@ class JavaScriptAppModalDialog : public AppModalDialog,
// Accessors
int dialog_flags() const { return dialog_flags_; }
std::wstring message_text() const { return message_text_; }
std::wstring default_prompt_text() const {
return UTF16ToWideHack(default_prompt_text_);
}
string16 message_text() const { return message_text_; }
string16 default_prompt_text() const { return default_prompt_text_; }
bool display_suppress_checkbox() const { return display_suppress_checkbox_; }
bool is_before_unload_dialog() const { return is_before_unload_dialog_; }
@ -99,14 +86,17 @@ class JavaScriptAppModalDialog : public AppModalDialog,
void InitNotifications();
// Notifies the delegate with the result of the dialog.
void NotifyDelegate(bool success, const std::wstring& prompt_text,
void NotifyDelegate(bool success, const string16& prompt_text,
bool suppress_js_messages);
NotificationRegistrar registrar_;
// An implementation of the client interface to provide supporting methods
// and receive results.
JavaScriptAppModalDialogDelegate* delegate_;
content::JavaScriptDialogDelegate* delegate_;
// The extra Chrome-only data associated with the delegate_.
ChromeJavaScriptDialogExtraData* extra_data_;
// The client_ as an ExtensionHost, cached for use during notifications that
// may arrive after the client has entered its destructor (and is thus
@ -116,7 +106,7 @@ class JavaScriptAppModalDialog : public AppModalDialog,
// Information about the message box is held in the following variables.
int dialog_flags_;
std::wstring message_text_;
string16 message_text_;
string16 default_prompt_text_;
bool display_suppress_checkbox_;
bool is_before_unload_dialog_;

@ -1,20 +1,23 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Copyright (c) 2011 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 "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "base/i18n/rtl.h"
#include <map>
#include "base/compiler_specific.h"
#include "base/memory/singleton.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "base/i18n/rtl.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
#include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "googleurl/src/gurl.h"
#include "content/browser/javascript_dialogs.h"
#include "grit/generated_resources.h"
#include "grit/chromium_strings.h"
#include "ui/base/l10n/l10n_util.h"
@ -22,9 +25,132 @@
#include "ui/base/text/text_elider.h"
#include "ui/gfx/font.h"
static std::wstring GetTitle(Profile* profile,
bool is_alert,
const GURL& frame_url) {
class ChromeJavaScriptDialogCreator : public content::JavaScriptDialogCreator {
public:
static ChromeJavaScriptDialogCreator* GetInstance();
virtual void RunJavaScriptDialog(content::JavaScriptDialogDelegate* delegate,
const GURL& frame_url,
int dialog_flags,
const string16& message_text,
const string16& default_prompt_text,
IPC::Message* reply_message,
bool* did_suppress_message,
Profile* profile) OVERRIDE;
virtual void RunBeforeUnloadDialog(
content::JavaScriptDialogDelegate* delegate,
const string16& message_text,
IPC::Message* reply_message) OVERRIDE;
virtual void ResetJavaScriptState(
content::JavaScriptDialogDelegate* delegate) OVERRIDE;
private:
explicit ChromeJavaScriptDialogCreator();
virtual ~ChromeJavaScriptDialogCreator();
friend struct DefaultSingletonTraits<ChromeJavaScriptDialogCreator>;
string16 GetTitle(Profile* profile,
bool is_alert,
const GURL& frame_url);
// Mapping between the JavaScriptDialogDelegates and their extra data. The key
// is a void* because the pointer is just a cookie and is never dereferenced.
typedef std::map<void*, ChromeJavaScriptDialogExtraData>
JavaScriptDialogExtraDataMap;
JavaScriptDialogExtraDataMap javascript_dialog_extra_data_;
};
//------------------------------------------------------------------------------
ChromeJavaScriptDialogCreator::ChromeJavaScriptDialogCreator() {
}
ChromeJavaScriptDialogCreator::~ChromeJavaScriptDialogCreator() {
}
/* static */
ChromeJavaScriptDialogCreator* ChromeJavaScriptDialogCreator::GetInstance() {
return Singleton<ChromeJavaScriptDialogCreator>::get();
}
void ChromeJavaScriptDialogCreator::RunJavaScriptDialog(
content::JavaScriptDialogDelegate* delegate,
const GURL& frame_url,
int dialog_flags,
const string16& message_text,
const string16& default_prompt_text,
IPC::Message* reply_message,
bool* did_suppress_message,
Profile* profile) {
*did_suppress_message = false;
ChromeJavaScriptDialogExtraData* extra_data =
&javascript_dialog_extra_data_[delegate];
if (extra_data->suppress_javascript_messages_) {
*did_suppress_message = true;
return;
}
base::TimeDelta time_since_last_message = base::TimeTicks::Now() -
extra_data->last_javascript_message_dismissal_;
bool display_suppress_checkbox = false;
// Show a checkbox offering to suppress further messages if this message is
// being displayed within kJavascriptMessageExpectedDelay of the last one.
if (time_since_last_message <
base::TimeDelta::FromMilliseconds(
chrome::kJavascriptMessageExpectedDelay)) {
display_suppress_checkbox = true;
}
bool is_alert = dialog_flags == ui::MessageBoxFlags::kIsJavascriptAlert;
string16 title = GetTitle(profile, is_alert, frame_url);
AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog(
delegate,
extra_data,
title,
dialog_flags,
message_text,
default_prompt_text,
display_suppress_checkbox,
false, // is_before_unload_dialog
reply_message));
}
void ChromeJavaScriptDialogCreator::RunBeforeUnloadDialog(
content::JavaScriptDialogDelegate* delegate,
const string16& message_text,
IPC::Message* reply_message) {
ChromeJavaScriptDialogExtraData* extra_data =
&javascript_dialog_extra_data_[delegate];
string16 full_message = message_text + ASCIIToUTF16("\n\n") +
l10n_util::GetStringUTF16(IDS_BEFOREUNLOAD_MESSAGEBOX_FOOTER);
AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog(
delegate,
extra_data,
l10n_util::GetStringUTF16(IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE),
ui::MessageBoxFlags::kIsJavascriptConfirm,
full_message,
string16(), // default_prompt_text
false, // display_suppress_checkbox
true, // is_before_unload_dialog
reply_message));
}
void ChromeJavaScriptDialogCreator::ResetJavaScriptState(
content::JavaScriptDialogDelegate* delegate) {
javascript_dialog_extra_data_.erase(delegate);
}
string16 ChromeJavaScriptDialogCreator::GetTitle(Profile* profile,
bool is_alert,
const GURL& frame_url) {
ExtensionService* extensions_service = profile->GetExtensionService();
if (extensions_service) {
const Extension* extension =
@ -33,15 +159,15 @@ static std::wstring GetTitle(Profile* profile,
extension = extensions_service->GetExtensionByWebExtent(frame_url);
if (extension && (extension->location() == Extension::COMPONENT)) {
return UTF16ToWideHack(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
} else if (extension && !extension->name().empty()) {
return UTF8ToWide(extension->name());
return UTF8ToUTF16(extension->name());
}
}
if (!frame_url.has_host()) {
return UTF16ToWideHack(l10n_util::GetStringUTF16(
return l10n_util::GetStringUTF16(
is_alert ? IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE
: IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE));
: IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE);
}
// TODO(brettw) it should be easier than this to do the correct language
@ -53,40 +179,14 @@ static std::wstring GetTitle(Profile* profile,
base_address = base::i18n::GetDisplayStringInLTRDirectionality(
base_address);
return UTF16ToWide(l10n_util::GetStringFUTF16(
return l10n_util::GetStringFUTF16(
is_alert ? IDS_JAVASCRIPT_ALERT_TITLE :
IDS_JAVASCRIPT_MESSAGEBOX_TITLE,
base_address));
base_address);
}
void RunJavascriptMessageBox(Profile* profile,
JavaScriptAppModalDialogDelegate* delegate,
const GURL& frame_url,
int dialog_flags,
const std::wstring& message_text,
const std::wstring& default_prompt_text,
bool display_suppress_checkbox,
IPC::Message* reply_msg) {
bool is_alert = dialog_flags == ui::MessageBoxFlags::kIsJavascriptAlert;
std::wstring title = GetTitle(profile, is_alert, frame_url);
AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog(
delegate, title, dialog_flags, message_text, default_prompt_text,
display_suppress_checkbox, false, reply_msg));
}
//------------------------------------------------------------------------------
void RunBeforeUnloadDialog(TabContents* tab_contents,
const std::wstring& message_text,
IPC::Message* reply_msg) {
std::wstring full_message = message_text + L"\n\n" + UTF16ToWideHack(
l10n_util::GetStringUTF16(IDS_BEFOREUNLOAD_MESSAGEBOX_FOOTER));
AppModalDialogQueue::GetInstance()->AddDialog(new JavaScriptAppModalDialog(
tab_contents,
UTF16ToWideHack(
l10n_util::GetStringUTF16(IDS_BEFOREUNLOAD_MESSAGEBOX_TITLE)),
ui::MessageBoxFlags::kIsJavascriptConfirm,
message_text,
std::wstring(),
false,
true,
reply_msg));
content::JavaScriptDialogCreator* GetJavaScriptDialogCreatorInstance() {
return ChromeJavaScriptDialogCreator::GetInstance();
}

@ -1,4 +1,4 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Copyright (c) 2011 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.
@ -6,36 +6,11 @@
#define CHROME_BROWSER_UI_APP_MODAL_DIALOGS_MESSAGE_BOX_HANDLER_H_
#pragma once
#include <string>
namespace content {
class JavaScriptDialogCreator;
}
#include "ipc/ipc_message.h"
class GURL;
class JavaScriptAppModalDialogDelegate;
class TabContents;
class Profile;
// Creates and runs a Javascript Message Box dialog.
// The dialog type is specified within |dialog_flags|, the
// default static display text is in |message_text| and if the dialog box is
// a user input prompt() box, the default text for the text field is in
// |default_prompt_text|. The result of the operation is returned using
// |reply_msg|.
void RunJavascriptMessageBox(Profile* profile,
JavaScriptAppModalDialogDelegate* delegate,
const GURL& frame_url,
int dialog_flags,
const std::wstring& message_text,
const std::wstring& default_prompt_text,
bool display_suppress_checkbox,
IPC::Message* reply_msg);
// This will display a modal dialog box with a header and footer asking the
// the user if they wish to navigate away from a page, with additional text
// |message_text| between the header and footer. The users response is
// returned to the renderer using |reply_msg|.
void RunBeforeUnloadDialog(TabContents* tab_contents,
const std::wstring& message_text,
IPC::Message* reply_msg);
// Returns a JavaScriptDialogCreator that creates real dialogs.
content::JavaScriptDialogCreator* GetJavaScriptDialogCreatorInstance();
#endif // CHROME_BROWSER_UI_APP_MODAL_DIALOGS_MESSAGE_BOX_HANDLER_H_

@ -163,6 +163,12 @@ bool BlockedContentContainer::IsPopup(const TabContents* source) const {
return true;
}
bool BlockedContentContainer::ShouldSuppressDialogs() {
// Suppress JavaScript dialogs when inside a constrained popup window (because
// that activates them and breaks them out of the constrained window jail).
return true;
}
TabContents* BlockedContentContainer::GetConstrainingContents(
TabContents* source) {
return owner_->tab_contents();

@ -94,6 +94,9 @@ class BlockedContentContainer : public BlockedContentTabHelperDelegate,
// Ignored; BlockedContentContainer doesn't display a URL bar.
virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
// Always returns true.
virtual bool ShouldSuppressDialogs();
// Maximum number of blocked contents we allow. No page should really need
// this many anyway. If reached it typically means there is a compromised
// renderer.

@ -73,6 +73,7 @@
#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
#include "chrome/browser/tabs/tab_finder.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
#include "chrome/browser/ui/browser_dialogs.h"
@ -3422,6 +3423,10 @@ void Browser::DidNavigateMainFramePostCommit(
}
}
content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
return GetJavaScriptDialogCreatorInstance();
}
///////////////////////////////////////////////////////////////////////////////
// Browser, TabContentsWrapperDelegate implementation:

@ -851,6 +851,8 @@ class Browser : public TabHandlerDelegate,
virtual void DidNavigateMainFramePostCommit(
TabContents* tab,
const MainFrameCommitDetails& details);
virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator()
OVERRIDE;
// Overridden from TabContentsWrapperDelegate:
virtual void OnDidGetApplicationInfo(TabContentsWrapper* source,

@ -59,9 +59,9 @@
contextInfo:(void*)contextInfo {
scoped_ptr<JSModalDialogCocoa> native_dialog(
reinterpret_cast<JSModalDialogCocoa*>(contextInfo));
std::wstring input;
string16 input;
if (textField_)
input = base::SysNSStringToWide([textField_ stringValue]);
input = base::SysNSStringToUTF16([textField_ stringValue]);
bool shouldSuppress = false;
if ([alert showsSuppressionButton])
shouldSuppress = [[alert suppressionButton] state] == NSOnState;
@ -135,12 +135,12 @@ JSModalDialogCocoa::JSModalDialogCocoa(JavaScriptAppModalDialog* dialog)
NSTextField* field = nil;
if (text_field) {
field = [helper_ textField];
[field setStringValue:base::SysWideToNSString(
[field setStringValue:base::SysUTF16ToNSString(
dialog_->default_prompt_text())];
}
[alert_ setDelegate:helper_];
[alert_ setInformativeText:base::SysWideToNSString(dialog_->message_text())];
[alert_ setMessageText:base::SysWideToNSString(dialog_->title())];
[alert_ setInformativeText:base::SysUTF16ToNSString(dialog_->message_text())];
[alert_ setMessageText:base::SysUTF16ToNSString(dialog_->title())];
[alert_ addButtonWithTitle:default_button];
if (!one_button) {
NSButton* other = [alert_ addButtonWithTitle:other_button];

@ -24,12 +24,12 @@ const char kSuppressCheckboxId[] = "chrome_suppress_checkbox";
// If there's a text entry in the dialog, get the text from the first one and
// return it.
std::wstring GetPromptText(GtkDialog* dialog) {
string16 GetPromptText(GtkDialog* dialog) {
GtkWidget* widget = static_cast<GtkWidget*>(
g_object_get_data(G_OBJECT(dialog), kPromptTextId));
if (widget)
return UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(widget)));
return std::wstring();
return UTF8ToUTF16(gtk_entry_get_text(GTK_ENTRY(widget)));
return string16();
}
// If there's a toggle button in the dialog, return the toggled state.
@ -87,12 +87,12 @@ JSModalDialogGtk::JSModalDialogGtk(JavaScriptAppModalDialog* dialog,
gtk_dialog_ = gtk_message_dialog_new(parent_window,
GTK_DIALOG_MODAL, message_type, buttons, "%s",
WideToUTF8(dialog_->message_text()).c_str());
UTF16ToUTF8(dialog_->message_text()).c_str());
g_signal_connect(gtk_dialog_, "delete-event",
G_CALLBACK(gtk_widget_hide_on_delete), NULL);
gtk_util::ApplyMessageDialogQuirks(gtk_dialog_);
gtk_window_set_title(GTK_WINDOW(gtk_dialog_),
WideToUTF8(dialog_->title()).c_str());
UTF16ToUTF8(dialog_->title()).c_str());
// Adjust content area as needed. Set up the prompt text entry or
// suppression check box.
@ -101,7 +101,7 @@ JSModalDialogGtk::JSModalDialogGtk(JavaScriptAppModalDialog* dialog,
GtkWidget* contents_vbox = GTK_DIALOG(gtk_dialog_)->vbox;
GtkWidget* text_box = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(text_box),
WideToUTF8(dialog_->default_prompt_text()).c_str());
UTF16ToUTF8(dialog_->default_prompt_text()).c_str());
gtk_box_pack_start(GTK_BOX(contents_vbox), text_box, TRUE, TRUE, 0);
g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box);
gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE);

@ -10,6 +10,7 @@
#include "base/i18n/rtl.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
@ -180,6 +181,11 @@ void DraggedTabControllerGtk::UpdateTargetURL(TabContents* source,
// Ignored.
}
content::JavaScriptDialogCreator*
DraggedTabControllerGtk::GetJavaScriptDialogCreator() {
return GetJavaScriptDialogCreatorInstance();
}
////////////////////////////////////////////////////////////////////////////////
// DraggedTabControllerGtk, NotificationObserver implementation:

@ -89,6 +89,8 @@ class DraggedTabControllerGtk : public NotificationObserver,
virtual void MoveContents(TabContents* source, const gfx::Rect& pos);
virtual bool IsPopup(const TabContents* source) const;
virtual void UpdateTargetURL(TabContents* source, const GURL& url);
virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator()
OVERRIDE;
// Overridden from NotificationObserver:
virtual void Observe(NotificationType type,

@ -131,7 +131,7 @@ IN_PROC_BROWSER_TEST_F(HtmlDialogBrowserTest, MAYBE_SizeWindow) {
new HtmlDialogView(browser()->profile(), delegate);
TabContents* tab_contents = browser()->GetSelectedTabContents();
ASSERT_TRUE(tab_contents != NULL);
views::Window::CreateChromeWindow(tab_contents->GetMessageBoxRootWindow(),
views::Window::CreateChromeWindow(tab_contents->GetDialogRootWindow(),
gfx::Rect(), html_view);
html_view->InitDialog();
html_view->window()->Show();

@ -23,7 +23,8 @@ JSModalDialogViews::JSModalDialogViews(
: parent_(parent),
message_box_view_(new views::MessageBoxView(
parent->dialog_flags() | ui::MessageBoxFlags::kAutoDetectAlignment,
parent->message_text(), parent->default_prompt_text())) {
UTF16ToWideHack(parent->message_text()),
UTF16ToWideHack(parent->default_prompt_text()))) {
DCHECK(message_box_view_);
message_box_view_->AddAccelerator(
@ -90,7 +91,7 @@ int JSModalDialogViews::GetDialogButtons() const {
}
std::wstring JSModalDialogViews::GetWindowTitle() const {
return parent_->title();
return UTF16ToWideHack(parent_->title());
}
@ -108,7 +109,7 @@ bool JSModalDialogViews::Cancel() {
}
bool JSModalDialogViews::Accept() {
parent_->OnAccept(message_box_view_->GetInputText(),
parent_->OnAccept(WideToUTF16Hack(message_box_view_->GetInputText()),
message_box_view_->IsCheckBoxSelected());
return true;
}

@ -46,7 +46,7 @@ void ShowSSLClientCertificateSelector(
IDS_CLIENT_CERT_DIALOG_TEXT,
ASCIIToUTF16(cert_request_info->host_and_port)));
PCCERT_CONTEXT cert_context = CryptUIDlgSelectCertificateFromStore(
client_certs, parent->GetMessageBoxRootWindow(),
client_certs, parent->GetDialogRootWindow(),
title.c_str(), text.c_str(), 0, 0, NULL);
net::X509Certificate* cert = NULL;

@ -4,6 +4,7 @@
#include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
#include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
#include "chrome/browser/ui/gtk/constrained_window_gtk.h"

@ -11,6 +11,7 @@
#include "base/i18n/rtl.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/tabs/base_tab.h"
@ -488,6 +489,11 @@ bool DraggedTabController::ShouldSuppressDialogs() {
return false;
}
content::JavaScriptDialogCreator*
DraggedTabController::GetJavaScriptDialogCreator() {
return GetJavaScriptDialogCreatorInstance();
}
///////////////////////////////////////////////////////////////////////////////
// DraggedTabController, NotificationObserver implementation:

@ -148,6 +148,8 @@ class DraggedTabController : public TabContentsDelegate,
const gfx::Rect& pos) OVERRIDE;
virtual void UpdateTargetURL(TabContents* source, const GURL& url) OVERRIDE;
virtual bool ShouldSuppressDialogs() OVERRIDE;
virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator()
OVERRIDE;
// Overridden from NotificationObserver:
virtual void Observe(NotificationType type,

@ -7,6 +7,7 @@
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/task.h"
#include "base/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "chrome/browser/extensions/extension_tab_helper.h"
#include "chrome/browser/favicon/favicon_tab_helper.h"

@ -7,6 +7,7 @@
#include <string>
#include "base/memory/singleton.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/about_flags.h"
#include "chrome/browser/browser_process.h"

@ -7,6 +7,7 @@
#include "base/i18n/time_formatting.h"
#include "base/string_number_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/crash_upload_list.h"
#include "chrome/browser/platform_util.h"

@ -465,7 +465,7 @@ void AdvancedOptionsHandler::ShowCloudPrintSetupDialog(const ListValue* args) {
cloud_print_setup_handler_.reset(new CloudPrintSetupHandler(this));
CloudPrintSetupFlow::OpenDialog(
web_ui_->GetProfile(), cloud_print_setup_handler_->AsWeakPtr(),
web_ui_->tab_contents()->GetMessageBoxRootWindow());
web_ui_->tab_contents()->GetDialogRootWindow());
}
void AdvancedOptionsHandler::HandleDisableCloudPrintProxy(

@ -9,6 +9,7 @@
#include "base/memory/singleton.h"
#include "base/string_piece.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/jstemplate_builder.h"

@ -7,6 +7,7 @@
#include <vector>
#include "base/path_service.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"

@ -54,8 +54,6 @@ include_rules = [
"+chrome/browser/utility_process_host.h",
"+chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h",
"+chrome/browser/ui/app_modal_dialogs/message_box_handler.h",
"+chrome/browser/ui/crypto_module_password_dialog.h",
"+chrome/common/chrome_constants.h",

@ -0,0 +1,80 @@
// Copyright (c) 2011 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 CONTENT_BROWSER_JAVASCRIPT_DIALOG_DELEGATE_H_
#define CONTENT_BROWSER_JAVASCRIPT_DIALOG_DELEGATE_H_
#pragma once
#include "base/string16.h"
#include "ui/gfx/native_widget_types.h"
class ExtensionHost;
class GURL;
class Profile;
class TabContents;
namespace IPC {
class Message;
}
namespace content {
// A class that invokes a JavaScript dialog must implement this interface to
// allow the dialog implementation to get needed information and return results.
class JavaScriptDialogDelegate {
public:
// This callback is invoked when the dialog is closed.
virtual void OnDialogClosed(IPC::Message* reply_msg,
bool success,
const string16& user_input) = 0;
// Returns the root native window with which to associate the dialog.
virtual gfx::NativeWindow GetDialogRootWindow() = 0;
// Returns the TabContents implementing this delegate, or NULL if there is
// none. TODO(avi): This breaks encapsulation and in general sucks; figure out
// a better way of doing this.
virtual TabContents* AsTabContents() = 0;
// Returns the ExtensionHost implementing this delegate, or NULL if there is
// none. TODO(avi): This is even suckier than AsTabContents above as it breaks
// layering; figure out a better way of doing this. http://crbug.com/84604
virtual ExtensionHost* AsExtensionHost() = 0;
protected:
virtual ~JavaScriptDialogDelegate() {}
};
// An interface consisting of methods that can be called to produce JavaScript
// dialogs.
class JavaScriptDialogCreator {
public:
// Displays a JavaScript dialog. |did_suppress_message| will not be nil; if
// |true| is returned in it, the caller will handle faking the reply.
// TODO(avi): Remove Profile from this call; http://crbug.com/84601
virtual void RunJavaScriptDialog(JavaScriptDialogDelegate* delegate,
const GURL& frame_url,
int dialog_flags,
const string16& message_text,
const string16& default_prompt_text,
IPC::Message* reply_message,
bool* did_suppress_message,
Profile* profile) = 0;
// Displays a dialog asking the user if they want to leave a page.
virtual void RunBeforeUnloadDialog(JavaScriptDialogDelegate* delegate,
const string16& message_text,
IPC::Message* reply_message) = 0;
// Resets any saved JavaScript dialog state for the delegate.
virtual void ResetJavaScriptState(JavaScriptDialogDelegate* delegate) = 0;
protected:
virtual ~JavaScriptDialogCreator() {}
};
} // namespace content
#endif // CONTENT_BROWSER_JAVASCRIPT_DIALOG_DELEGATE_H_

@ -1,8 +1,9 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Copyright (c) 2011 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 "base/time.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"

@ -18,8 +18,6 @@
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/desktop_notification_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "chrome/common/chrome_constants.h"
#include "content/browser/child_process_security_policy.h"
#include "content/browser/content_browser_client.h"
#include "content/browser/host_zoom_map.h"
@ -188,7 +186,6 @@ TabContents::TabContents(Profile* profile,
#if defined(OS_WIN)
message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)),
#endif
suppress_javascript_messages_(false),
is_showing_before_unload_dialog_(false),
opener_web_ui_type_(WebUI::kNoWebUI),
closed_by_user_gesture_(false),
@ -221,6 +218,10 @@ TabContents::~TabContents() {
// We don't want any notifications while we're running our destructor.
registrar_.RemoveAll();
// Clear out any JavaScript state.
if (delegate_)
delegate_->GetJavaScriptDialogCreator()->ResetJavaScriptState(this);
NotifyDisconnected();
// First cleanly close all child windows.
@ -1089,10 +1090,11 @@ void TabContents::DidNavigateAnyFramePostCommit(
RenderViewHost* render_view_host,
const content::LoadCommittedDetails& details,
const ViewHostMsg_FrameNavigate_Params& params) {
// If we navigate, start showing messages again. This does nothing to prevent
// If we navigate, reset JavaScript state. This does nothing to prevent
// a malicious script from spamming messages, since the script could just
// reload the page to stop blocking.
suppress_javascript_messages_ = false;
if (delegate_)
delegate_->GetJavaScriptDialogCreator()->ResetJavaScriptState(this);
// Notify observers about navigation.
FOR_EACH_OBSERVER(TabContentsObserver, observers_,
@ -1559,47 +1561,34 @@ void TabContents::RunJavaScriptMessage(
const int flags,
IPC::Message* reply_msg,
bool* did_suppress_message) {
// Suppress javascript messages when requested and when inside a constrained
// popup window (because that activates them and breaks them out of the
// constrained window jail).
// Also suppress messages when showing an interstitial. The interstitial is
// shown over the previous page, we don't want the hidden page dialogs to
// interfere with the interstitial.
// Suppress JavaScript dialogs when requested. Also suppress messages when
// showing an interstitial as it's shown over the previous page and we don't
// want the hidden page's dialogs to interfere with the interstitial.
bool suppress_this_message =
rvh->is_swapped_out() ||
suppress_javascript_messages_ ||
showing_interstitial_page() ||
(delegate() && delegate()->ShouldSuppressDialogs());
if (delegate())
suppress_this_message |=
(delegate()->GetConstrainingContents(this) != this);
*did_suppress_message = suppress_this_message;
!delegate_ ||
delegate_->ShouldSuppressDialogs();
if (!suppress_this_message) {
base::TimeDelta time_since_last_message(
base::TimeTicks::Now() - last_javascript_message_dismissal_);
bool show_suppress_checkbox = false;
// Show a checkbox offering to suppress further messages if this message is
// being displayed within kJavascriptMessageExpectedDelay of the last one.
if (time_since_last_message <
base::TimeDelta::FromMilliseconds(
chrome::kJavascriptMessageExpectedDelay))
show_suppress_checkbox = true;
RunJavascriptMessageBox(profile(),
this,
frame_url,
flags,
UTF16ToWideHack(message),
UTF16ToWideHack(default_prompt),
show_suppress_checkbox,
reply_msg);
} else {
// If we are suppressing messages, just reply as is if the user immediately
// pressed "Cancel".
OnMessageBoxClosed(reply_msg, false, std::wstring());
delegate_->GetJavaScriptDialogCreator()->RunJavaScriptDialog(
this,
frame_url,
flags,
message,
default_prompt,
reply_msg,
&suppress_this_message,
profile());
}
if (suppress_this_message) {
// If we are suppressing messages, just reply as if the user immediately
// pressed "Cancel".
OnDialogClosed(reply_msg, false, string16());
}
*did_suppress_message = suppress_this_message;
}
void TabContents::RunBeforeUnloadConfirm(const RenderViewHost* rvh,
@ -1607,14 +1596,21 @@ void TabContents::RunBeforeUnloadConfirm(const RenderViewHost* rvh,
IPC::Message* reply_msg) {
if (delegate())
delegate()->WillRunBeforeUnloadConfirm();
bool suppress_this_message = rvh->is_swapped_out() ||
(delegate() && delegate()->ShouldSuppressDialogs());
bool suppress_this_message =
rvh->is_swapped_out() ||
!delegate_ ||
delegate_->ShouldSuppressDialogs();
if (suppress_this_message) {
render_view_host()->JavaScriptDialogClosed(reply_msg, true, string16());
return;
}
is_showing_before_unload_dialog_ = true;
RunBeforeUnloadDialog(this, UTF16ToWideHack(message), reply_msg);
delegate_->GetJavaScriptDialogCreator()->RunBeforeUnloadDialog(
this,
message,
reply_msg);
}
WebPreferences TabContents::GetWebkitPrefs() {
@ -1812,14 +1808,11 @@ void TabContents::Observe(NotificationType type,
}
}
gfx::NativeWindow TabContents::GetMessageBoxRootWindow() {
return view_->GetTopLevelNativeWindow();
}
// Overridden from JavaScriptDialogDelegate
void TabContents::OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& user_input) {
last_javascript_message_dismissal_ = base::TimeTicks::Now();
void TabContents::OnDialogClosed(IPC::Message* reply_msg,
bool success,
const string16& user_input) {
if (is_showing_before_unload_dialog_ && !success) {
// If a beforeunload dialog is canceled, we need to stop the throbber from
// spinning, since we forced it to start spinning in Navigate.
@ -1830,11 +1823,11 @@ void TabContents::OnMessageBoxClosed(IPC::Message* reply_msg,
is_showing_before_unload_dialog_ = false;
render_view_host()->JavaScriptDialogClosed(reply_msg,
success,
WideToUTF16Hack(user_input));
user_input);
}
void TabContents::SetSuppressMessageBoxes(bool suppress_message_boxes) {
set_suppress_javascript_messages(suppress_message_boxes);
gfx::NativeWindow TabContents::GetDialogRootWindow() {
return view_->GetTopLevelNativeWindow();
}
TabContents* TabContents::AsTabContents() {

@ -14,7 +14,7 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h"
#include "content/browser/javascript_dialogs.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/tab_contents/constrained_window.h"
#include "content/browser/tab_contents/navigation_controller.h"
@ -61,7 +61,7 @@ class TabContents : public PageNavigator,
public NotificationObserver,
public RenderViewHostDelegate,
public RenderViewHostManager::Delegate,
public JavaScriptAppModalDialogDelegate,
public content::JavaScriptDialogDelegate,
public net::NetworkChangeNotifier::OnlineStateObserver {
public:
// Flags passed to the TabContentsDelegate.NavigationStateChanged to tell it
@ -383,12 +383,6 @@ class TabContents : public PageNavigator,
// Misc state & callbacks ----------------------------------------------------
// Set whether the contents should block javascript message boxes or not.
// Default is not to block any message boxes.
void set_suppress_javascript_messages(bool suppress_javascript_messages) {
suppress_javascript_messages_ = suppress_javascript_messages;
}
// Returns true if the active NavigationEntry's page_id equals page_id.
bool IsActiveEntry(int32 page_id);
@ -445,14 +439,13 @@ class TabContents : public PageNavigator,
}
bool closed_by_user_gesture() const { return closed_by_user_gesture_; }
// Overridden from JavaScriptAppModalDialogDelegate:
virtual void OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& user_input);
virtual void SetSuppressMessageBoxes(bool suppress_message_boxes);
virtual gfx::NativeWindow GetMessageBoxRootWindow();
virtual TabContents* AsTabContents();
virtual ExtensionHost* AsExtensionHost();
// Overridden from JavaScriptDialogDelegate:
virtual void OnDialogClosed(IPC::Message* reply_msg,
bool success,
const string16& user_input) OVERRIDE;
virtual gfx::NativeWindow GetDialogRootWindow() OVERRIDE;
virtual TabContents* AsTabContents() OVERRIDE;
virtual ExtensionHost* AsExtensionHost() OVERRIDE;
// The BookmarkDragDelegate is used to forward bookmark drag and drop events
// to extensions.
@ -672,7 +665,7 @@ class TabContents : public PageNavigator,
const GURL& frame_url,
const int flags,
IPC::Message* reply_msg,
bool* did_suppress_message);
bool* did_suppress_message) OVERRIDE;
virtual void RunBeforeUnloadConfirm(const RenderViewHost* rvh,
const string16& message,
IPC::Message* reply_msg);
@ -824,13 +817,6 @@ class TabContents : public PageNavigator,
base::win::ScopedHandle message_box_active_;
#endif
// The time that the last javascript message was dismissed.
base::TimeTicks last_javascript_message_dismissal_;
// True if the user has decided to block future javascript messages. This is
// reset on navigations to false on navigations.
bool suppress_javascript_messages_;
// Set to true when there is an active "before unload" dialog. When true,
// we've forced the throbber to start in Navigate, and we need to remember to
// turn it off in OnJavaScriptMessageBoxClosed if the navigation is canceled.

@ -4,6 +4,9 @@
#include "content/browser/tab_contents/tab_contents_delegate.h"
#include "base/compiler_specific.h"
#include "base/memory/singleton.h"
#include "content/browser/javascript_dialogs.h"
#include "content/common/url_constants.h"
#include "ui/gfx/rect.h"
@ -197,5 +200,42 @@ void TabContentsDelegate::DidNavigateMainFramePostCommit(
const MainFrameCommitDetails& details) {
}
// A stubbed-out version of JavaScriptDialogCreator that doesn't do anything.
class JavaScriptDialogCreatorStub : public content::JavaScriptDialogCreator {
public:
static JavaScriptDialogCreatorStub* GetInstance() {
return Singleton<JavaScriptDialogCreatorStub>::get();
}
virtual void RunJavaScriptDialog(content::JavaScriptDialogDelegate* delegate,
const GURL& frame_url,
int dialog_flags,
const string16& message_text,
const string16& default_prompt_text,
IPC::Message* reply_message,
bool* did_suppress_message,
Profile* profile) OVERRIDE {
*did_suppress_message = true;
}
virtual void RunBeforeUnloadDialog(
content::JavaScriptDialogDelegate* delegate,
const string16& message_text,
IPC::Message* reply_message) OVERRIDE {
delegate->OnDialogClosed(reply_message, true, string16());
}
virtual void ResetJavaScriptState(
content::JavaScriptDialogDelegate* delegate) OVERRIDE {
}
private:
friend struct DefaultSingletonTraits<JavaScriptDialogCreatorStub>;
};
content::JavaScriptDialogCreator*
TabContentsDelegate::GetJavaScriptDialogCreator() {
return JavaScriptDialogCreatorStub::GetInstance();
}
TabContentsDelegate::~TabContentsDelegate() {
}

@ -15,6 +15,10 @@
#include "ui/gfx/native_widget_types.h"
#include "webkit/glue/window_open_disposition.h"
namespace content {
class JavaScriptDialogCreator;
}
namespace gfx {
class Point;
class Rect;
@ -299,6 +303,11 @@ class TabContentsDelegate {
TabContents* tab,
const MainFrameCommitDetails& details);
// Returns a pointer to a service to create JavaScript dialogs. The default
// pointer returned is to a stub service that marks all dialogs as suppressed
// and displays nothing.
virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator();
protected:
virtual ~TabContentsDelegate();
};

@ -165,6 +165,7 @@
'browser/in_process_webkit/webkit_context.h',
'browser/in_process_webkit/webkit_thread.cc',
'browser/in_process_webkit/webkit_thread.h',
'browser/javascript_dialogs.h',
'browser/load_notification_details.h',
'browser/media_stream/media_stream_provider.cc',
'browser/media_stream/media_stream_provider.h',