diff options
46 files changed, 525 insertions, 306 deletions
diff --git a/chrome/browser/automation/automation_tab_helper_browsertest.cc b/chrome/browser/automation/automation_tab_helper_browsertest.cc index 75cc259..2bc1f17 100644 --- a/chrome/browser/automation/automation_tab_helper_browsertest.cc +++ b/chrome/browser/automation/automation_tab_helper_browsertest.cc @@ -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" diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 8fb5618..3626478f 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -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); } diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc index a8c67ef..a9ca9d1 100644 --- a/chrome/browser/extensions/app_background_page_apitest.cc +++ b/chrome/browser/extensions/app_background_page_apitest.cc @@ -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" diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 70c10a6..381adfb 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -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_); - - *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 + bool suppress_this_message = false; + GetJavaScriptDialogCreatorInstance()->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". - 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) { diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 516accf..408a774 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -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); }; diff --git a/chrome/browser/external_tab_container_win.cc b/chrome/browser/external_tab_container_win.cc index 7bb0755..bff1403 100644 --- a/chrome/browser/external_tab_container_win.cc +++ b/chrome/browser/external_tab_container_win.cc @@ -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(); diff --git a/chrome/browser/external_tab_container_win.h b/chrome/browser/external_tab_container_win.h index e543577..e90e6f3 100644 --- a/chrome/browser/external_tab_container_win.h +++ b/chrome/browser/external_tab_container_win.h @@ -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); diff --git a/chrome/browser/sidebar/sidebar_container.cc b/chrome/browser/sidebar/sidebar_container.cc index d1e4a33..4013537 100644 --- a/chrome/browser/sidebar/sidebar_container.cc +++ b/chrome/browser/sidebar/sidebar_container.cc @@ -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) { diff --git a/chrome/browser/sidebar/sidebar_container.h b/chrome/browser/sidebar/sidebar_container.h index 0fe1cb3..f7b527e 100644 --- a/chrome/browser/sidebar/sidebar_container.h +++ b/chrome/browser/sidebar/sidebar_container.h @@ -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, diff --git a/chrome/browser/tab_contents/background_contents.cc b/chrome/browser/tab_contents/background_contents.cc index cae94e8..6bad66f 100644 --- a/chrome/browser/tab_contents/background_contents.cc +++ b/chrome/browser/tab_contents/background_contents.cc @@ -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; } diff --git a/chrome/browser/tab_contents/background_contents.h b/chrome/browser/tab_contents/background_contents.h index b368766..93e1b43 100644 --- a/chrome/browser/tab_contents/background_contents.h +++ b/chrome/browser/tab_contents/background_contents.h @@ -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); diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc index f7a25c8..a1811f1 100644 --- a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc +++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc @@ -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. } diff --git a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc b/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc index 51f1755..257def3 100644 --- a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc +++ b/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.cc @@ -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), diff --git a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h b/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h index 39b358a..8d09d48 100644 --- a/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h +++ b/chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h @@ -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); }; diff --git a/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.cc b/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.cc index 84ae2cc..2714272 100644 --- a/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.cc +++ b/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.cc @@ -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. diff --git a/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h b/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h index 851b039..6a05b8e 100644 --- a/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h +++ b/chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h @@ -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; - - // Indicates whether additional message boxes should be suppressed. - virtual void SetSuppressMessageBoxes(bool suppress_message_boxes) = 0; - - // 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() {} + ChromeJavaScriptDialogExtraData(); + + // The time that the last JavaScript dialog was dismissed. + base::TimeTicks last_javascript_message_dismissal_; + + // 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_; diff --git a/chrome/browser/ui/app_modal_dialogs/message_box_handler.cc b/chrome/browser/ui/app_modal_dialogs/message_box_handler.cc index 0de1b9a..875024a 100644 --- a/chrome/browser/ui/app_modal_dialogs/message_box_handler.cc +++ b/chrome/browser/ui/app_modal_dialogs/message_box_handler.cc @@ -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(); } diff --git a/chrome/browser/ui/app_modal_dialogs/message_box_handler.h b/chrome/browser/ui/app_modal_dialogs/message_box_handler.h index 0acfb14..5d2642a 100644 --- a/chrome/browser/ui/app_modal_dialogs/message_box_handler.h +++ b/chrome/browser/ui/app_modal_dialogs/message_box_handler.h @@ -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_ diff --git a/chrome/browser/ui/blocked_content/blocked_content_container.cc b/chrome/browser/ui/blocked_content/blocked_content_container.cc index 09defd8..11204ea 100644 --- a/chrome/browser/ui/blocked_content/blocked_content_container.cc +++ b/chrome/browser/ui/blocked_content/blocked_content_container.cc @@ -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(); diff --git a/chrome/browser/ui/blocked_content/blocked_content_container.h b/chrome/browser/ui/blocked_content/blocked_content_container.h index fb41d22..b6ecde9 100644 --- a/chrome/browser/ui/blocked_content/blocked_content_container.h +++ b/chrome/browser/ui/blocked_content/blocked_content_container.h @@ -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. diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 2a71f6c..e6b402a 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -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: diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index f143719..2b41d9e 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -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, diff --git a/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.mm b/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.mm index 62825d5..77d8149 100644 --- a/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.mm +++ b/chrome/browser/ui/cocoa/js_modal_dialog_cocoa.mm @@ -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]; diff --git a/chrome/browser/ui/gtk/js_modal_dialog_gtk.cc b/chrome/browser/ui/gtk/js_modal_dialog_gtk.cc index dbad866..bb1a71b 100644 --- a/chrome/browser/ui/gtk/js_modal_dialog_gtk.cc +++ b/chrome/browser/ui/gtk/js_modal_dialog_gtk.cc @@ -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); diff --git a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc index 42ad68d..c836bf0 100644 --- a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc +++ b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.cc @@ -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: diff --git a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.h b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.h index f12e0df..5249a18 100644 --- a/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.h +++ b/chrome/browser/ui/gtk/tabs/dragged_tab_controller_gtk.h @@ -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, diff --git a/chrome/browser/ui/views/html_dialog_view_browsertest.cc b/chrome/browser/ui/views/html_dialog_view_browsertest.cc index 1d351c0..8ec8681 100644 --- a/chrome/browser/ui/views/html_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/html_dialog_view_browsertest.cc @@ -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(); diff --git a/chrome/browser/ui/views/js_modal_dialog_views.cc b/chrome/browser/ui/views/js_modal_dialog_views.cc index 6bccb5d..4f3f472 100644 --- a/chrome/browser/ui/views/js_modal_dialog_views.cc +++ b/chrome/browser/ui/views/js_modal_dialog_views.cc @@ -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; } diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector_win.cc b/chrome/browser/ui/views/ssl_client_certificate_selector_win.cc index e738d6c..bee7774 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector_win.cc +++ b/chrome/browser/ui/views/ssl_client_certificate_selector_win.cc @@ -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; diff --git a/chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc b/chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc index 2840a8b..dd8fe8c 100644 --- a/chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc +++ b/chrome/browser/ui/views/tab_contents/native_tab_contents_view_gtk.cc @@ -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" diff --git a/chrome/browser/ui/views/tabs/dragged_tab_controller.cc b/chrome/browser/ui/views/tabs/dragged_tab_controller.cc index 2ffa620..88c5086 100644 --- a/chrome/browser/ui/views/tabs/dragged_tab_controller.cc +++ b/chrome/browser/ui/views/tabs/dragged_tab_controller.cc @@ -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: diff --git a/chrome/browser/ui/views/tabs/dragged_tab_controller.h b/chrome/browser/ui/views/tabs/dragged_tab_controller.h index 55289b1..9023a2b 100644 --- a/chrome/browser/ui/views/tabs/dragged_tab_controller.h +++ b/chrome/browser/ui/views/tabs/dragged_tab_controller.h @@ -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, diff --git a/chrome/browser/ui/web_applications/web_app_ui.cc b/chrome/browser/ui/web_applications/web_app_ui.cc index b125963..b7a68b4 100644 --- a/chrome/browser/ui/web_applications/web_app_ui.cc +++ b/chrome/browser/ui/web_applications/web_app_ui.cc @@ -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" diff --git a/chrome/browser/ui/webui/flags_ui.cc b/chrome/browser/ui/webui/flags_ui.cc index 5ba870d..49dc9a6 100644 --- a/chrome/browser/ui/webui/flags_ui.cc +++ b/chrome/browser/ui/webui/flags_ui.cc @@ -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" diff --git a/chrome/browser/ui/webui/flash_ui.cc b/chrome/browser/ui/webui/flash_ui.cc index f1dbcce..644fd5a 100644 --- a/chrome/browser/ui/webui/flash_ui.cc +++ b/chrome/browser/ui/webui/flash_ui.cc @@ -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" diff --git a/chrome/browser/ui/webui/options/advanced_options_handler.cc b/chrome/browser/ui/webui/options/advanced_options_handler.cc index c85e197a..d8a6906 100644 --- a/chrome/browser/ui/webui/options/advanced_options_handler.cc +++ b/chrome/browser/ui/webui/options/advanced_options_handler.cc @@ -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( diff --git a/chrome/browser/ui/webui/textfields_ui.cc b/chrome/browser/ui/webui/textfields_ui.cc index a87f90d..2f43a0b 100644 --- a/chrome/browser/ui/webui/textfields_ui.cc +++ b/chrome/browser/ui/webui/textfields_ui.cc @@ -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" diff --git a/chrome/browser/ui/webui/web_ui_browsertest.cc b/chrome/browser/ui/webui/web_ui_browsertest.cc index 026c77d..3817612 100644 --- a/chrome/browser/ui/webui/web_ui_browsertest.cc +++ b/chrome/browser/ui/webui/web_ui_browsertest.cc @@ -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" diff --git a/content/browser/DEPS b/content/browser/DEPS index c2e7d07..2f4ed5e 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS @@ -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", diff --git a/content/browser/javascript_dialogs.h b/content/browser/javascript_dialogs.h new file mode 100644 index 0000000..caeac36 --- /dev/null +++ b/content/browser/javascript_dialogs.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_ diff --git a/content/browser/renderer_host/render_view_host_browsertest.cc b/content/browser/renderer_host/render_view_host_browsertest.cc index 2b46ab8..116dbec 100644 --- a/content/browser/renderer_host/render_view_host_browsertest.cc +++ b/content/browser/renderer_host/render_view_host_browsertest.cc @@ -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" diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc index 8aedfa7..e7dd30b 100644 --- a/content/browser/tab_contents/tab_contents.cc +++ b/content/browser/tab_contents/tab_contents.cc @@ -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 + 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". - OnMessageBoxClosed(reply_msg, false, std::wstring()); + 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() { diff --git a/content/browser/tab_contents/tab_contents.h b/content/browser/tab_contents/tab_contents.h index 8d07b29..164195f 100644 --- a/content/browser/tab_contents/tab_contents.h +++ b/content/browser/tab_contents/tab_contents.h @@ -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. diff --git a/content/browser/tab_contents/tab_contents_delegate.cc b/content/browser/tab_contents/tab_contents_delegate.cc index 0f140c8..df709a7 100644 --- a/content/browser/tab_contents/tab_contents_delegate.cc +++ b/content/browser/tab_contents/tab_contents_delegate.cc @@ -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() { } diff --git a/content/browser/tab_contents/tab_contents_delegate.h b/content/browser/tab_contents/tab_contents_delegate.h index 16d4e7a..0645128 100644 --- a/content/browser/tab_contents/tab_contents_delegate.h +++ b/content/browser/tab_contents/tab_contents_delegate.h @@ -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(); }; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index a14ad66..69f03dc 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -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', |