diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/app_modal_dialog.cc | 50 | ||||
-rw-r--r-- | chrome/browser/app_modal_dialog.h | 17 | ||||
-rw-r--r-- | chrome/browser/app_modal_dialog_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 40 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.h | 14 | ||||
-rw-r--r-- | chrome/browser/jsmessage_box_client.h | 50 | ||||
-rw-r--r-- | chrome/browser/jsmessage_box_handler.cc | 40 | ||||
-rw-r--r-- | chrome/browser/jsmessage_box_handler.h | 3 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 70 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.h | 20 | ||||
-rw-r--r-- | chrome/browser/views/jsmessage_box_dialog.cc | 16 | ||||
-rw-r--r-- | chrome/browser/views/jsmessage_box_dialog.h | 6 |
12 files changed, 225 insertions, 103 deletions
diff --git a/chrome/browser/app_modal_dialog.cc b/chrome/browser/app_modal_dialog.cc index 8abf78e..4da37d7 100644 --- a/chrome/browser/app_modal_dialog.cc +++ b/chrome/browser/app_modal_dialog.cc @@ -10,7 +10,7 @@ #include "chrome/common/notification_type.h" #include "ipc/ipc_message.h" -AppModalDialog::AppModalDialog(TabContents* tab_contents, +AppModalDialog::AppModalDialog(JavaScriptMessageBoxClient* client, const std::wstring& title, int dialog_flags, const std::wstring& message_text, @@ -19,7 +19,8 @@ AppModalDialog::AppModalDialog(TabContents* tab_contents, bool is_before_unload_dialog, IPC::Message* reply_msg) : dialog_(NULL), - tab_contents_(tab_contents), + client_(client), + skip_this_dialog_(false), title_(title), dialog_flags_(dialog_flags), message_text_(message_text), @@ -33,20 +34,20 @@ AppModalDialog::AppModalDialog(TabContents* tab_contents, void AppModalDialog::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { - if (!tab_contents_) + const TabContents* tab_contents = client_->AsTabContents(); + if (!tab_contents) return; if (type == NotificationType::NAV_ENTRY_COMMITTED && Source<NavigationController>(source).ptr() == - &tab_contents_->controller()) - tab_contents_ = NULL; + &tab_contents->controller()) + skip_this_dialog_ = true; if (type == NotificationType::TAB_CONTENTS_DESTROYED && - Source<TabContents>(source).ptr() == - static_cast<TabContents*>(tab_contents_)) - tab_contents_ = NULL; + Source<TabContents>(source).ptr() == tab_contents) + skip_this_dialog_ = true; - if (!tab_contents_) + if (skip_this_dialog_) CloseModalDialog(); } @@ -60,22 +61,26 @@ void AppModalDialog::SendCloseNotification() { void AppModalDialog::InitNotifications() { // Make sure we get navigation notifications so we know when our parent // contents will disappear or navigate to a different page. - registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, - NotificationService::AllSources()); - registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, - NotificationService::AllSources()); + if (client_->AsTabContents()) { + registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, + NotificationService::AllSources()); + } } void AppModalDialog::ShowModalDialog() { // If the TabContents that created this dialog navigated away before this // dialog became visible, simply show the next dialog if any. - if (!tab_contents_) { + if (skip_this_dialog_) { Singleton<AppModalDialogQueue>()->ShowNextDialog(); delete this; return; } + TabContents* tab_contents = client_->AsTabContents(); + if (tab_contents) + tab_contents->Activate(); - tab_contents_->Activate(); CreateAndShowDialog(); NotificationService::current()->Notify( @@ -86,16 +91,15 @@ void AppModalDialog::ShowModalDialog() { void AppModalDialog::OnCancel() { // We need to do this before WM_DESTROY (WindowClosing()) as any parent frame - // will receive it's activation messages before this dialog receives + // will receive its activation messages before this dialog receives // WM_DESTROY. The parent frame would then try to activate any modal dialogs // that were still open in the ModalDialogQueue, which would send activation // back to this one. The framework should be improved to handle this, so this // is a temporary workaround. Singleton<AppModalDialogQueue>()->ShowNextDialog(); - if (tab_contents_) { - tab_contents_->OnJavaScriptMessageBoxClosed(reply_msg_, false, - std::wstring()); + if (!skip_this_dialog_) { + client_->OnMessageBoxClosed(reply_msg_, false, std::wstring()); } SendCloseNotification(); @@ -105,12 +109,10 @@ void AppModalDialog::OnAccept(const std::wstring& prompt_text, bool suppress_js_messages) { Singleton<AppModalDialogQueue>()->ShowNextDialog(); - if (tab_contents_) { - tab_contents_->OnJavaScriptMessageBoxClosed(reply_msg_, true, - prompt_text); - + if (!skip_this_dialog_) { + client_->OnMessageBoxClosed(reply_msg_, true, prompt_text); if (suppress_js_messages) - tab_contents()->set_suppress_javascript_messages(true); + client_->SetSuppressMessageBoxes(true); } SendCloseNotification(); diff --git a/chrome/browser/app_modal_dialog.h b/chrome/browser/app_modal_dialog.h index 8d44d64..8263565 100644 --- a/chrome/browser/app_modal_dialog.h +++ b/chrome/browser/app_modal_dialog.h @@ -21,7 +21,7 @@ typedef GtkWidget* NativeDialog; typedef void* NativeDialog; #endif -class TabContents; +class JavaScriptMessageBoxClient; namespace IPC { class Message; } @@ -33,7 +33,7 @@ class AppModalDialog : public NotificationObserver { public: // A union of data necessary to determine the type of message box to // show. |dialog_flags| is a MessageBox flag. - AppModalDialog(TabContents* tab_contents, + AppModalDialog(JavaScriptMessageBoxClient* client, const std::wstring& title, int dialog_flags, const std::wstring& message_text, @@ -63,8 +63,8 @@ class AppModalDialog : public NotificationObserver { ///////////////////////////////////////////////////////////////////////////// // Getters so NativeDialog can get information about the message box. - TabContents* tab_contents() { - return tab_contents_; + JavaScriptMessageBoxClient* client() { + return client_; } int dialog_flags() { return dialog_flags_; @@ -103,8 +103,15 @@ class AppModalDialog : public NotificationObserver { // A reference to the platform native dialog box. NativeDialog dialog_; + // An implementation of the client interface to provide supporting methods + // and receive results. + JavaScriptMessageBoxClient* client_; + + // True if the dialog should no longer be shown, e.g. because the underlying + // tab navigated away while the dialog was queued. + bool skip_this_dialog_; + // Information about the message box is held in the following variables. - TabContents* tab_contents_; std::wstring title_; int dialog_flags_; std::wstring message_text_; diff --git a/chrome/browser/app_modal_dialog_gtk.cc b/chrome/browser/app_modal_dialog_gtk.cc index 0191e84..d3bbd48 100644 --- a/chrome/browser/app_modal_dialog_gtk.cc +++ b/chrome/browser/app_modal_dialog_gtk.cc @@ -122,7 +122,7 @@ void AppModalDialog::CreateAndShowDialog() { } g_object_unref(window_group); - GtkWindow* window = tab_contents_->view()->GetTopLevelNativeWindow(); + gfx::NativeWindow window = client_->GetMessageBoxRootWindow(); dialog_ = gtk_message_dialog_new(window, GTK_DIALOG_MODAL, message_type, buttons, "%s", WideToUTF8(message_text_).c_str()); gtk_window_set_title(GTK_WINDOW(dialog_), WideToUTF8(title_).c_str()); diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index f9d6bd1..e2cea15 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -6,6 +6,7 @@ #include <list> +#include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/message_loop.h" #include "base/singleton.h" @@ -18,6 +19,7 @@ #include "chrome/browser/dom_ui/dom_ui_factory.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extension_tabs_module.h" +#include "chrome/browser/jsmessage_box_handler.h" #include "chrome/browser/extensions/extension_popup_api.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" @@ -25,6 +27,8 @@ #include "chrome/browser/renderer_host/render_widget_host.h" #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/renderer_host/site_instance.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/common/bindings_policy.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" @@ -34,6 +38,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "grit/browser_resources.h" +#include "grit/generated_resources.h" #include "webkit/glue/context_menu.h" #if defined(TOOLKIT_VIEWS) @@ -397,10 +402,37 @@ void ExtensionHost::RunJavaScriptMessage(const std::wstring& message, const int flags, IPC::Message* reply_msg, bool* did_suppress_message) { - // Automatically cancel the javascript alert (otherwise the renderer hangs - // indefinitely). - *did_suppress_message = true; - render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true, L""); + *did_suppress_message = false; + // 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(this, frame_url, flags, message, default_prompt, + false, reply_msg); +} + +std::wstring ExtensionHost::GetMessageBoxTitle(const GURL& frame_url, + bool is_alert) { + if (extension_->name().empty()) + return l10n_util::GetString( + is_alert ? IDS_EXTENSION_ALERT_DEFAULT_TITLE + : IDS_EXTENSION_MESSAGEBOX_DEFAULT_TITLE); + + return l10n_util::GetStringF( + is_alert ? IDS_EXTENSION_ALERT_TITLE : IDS_EXTENSION_MESSAGEBOX_TITLE, + UTF8ToWide(extension_->name())); +} + +gfx::NativeWindow ExtensionHost::GetMessageBoxRootWindow() { + TabContents* active_tab = GetBrowser()->GetSelectedTabContents(); + if (active_tab) + return active_tab->view()->GetTopLevelNativeWindow(); + return NULL; +} + +void ExtensionHost::OnMessageBoxClosed(IPC::Message* reply_msg, + bool success, + const std::wstring& prompt) { + render_view_host()->JavaScriptMessageBoxClosed(reply_msg, success, prompt); } void ExtensionHost::Close(RenderViewHost* render_view_host) { diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index bf66579..22279a1 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -9,6 +9,7 @@ #include "base/scoped_ptr.h" #include "chrome/browser/extensions/extension_function_dispatcher.h" +#include "chrome/browser/jsmessage_box_client.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" #if defined(TOOLKIT_VIEWS) @@ -45,7 +46,8 @@ class ExtensionHost : // NOLINT public RenderViewHostDelegate, public RenderViewHostDelegate::View, public ExtensionFunctionDispatcher::Delegate, - public NotificationObserver { + public NotificationObserver, + public JavaScriptMessageBoxClient { public: class ProcessCreationQueue; @@ -174,6 +176,16 @@ class ExtensionHost : // NOLINT const NotificationSource& source, const NotificationDetails& details); + // JavaScriptMessageBoxClient + virtual std::wstring GetMessageBoxTitle(const GURL& frame_url, + bool is_alert); + virtual gfx::NativeWindow GetMessageBoxRootWindow(); + virtual void OnMessageBoxClosed(IPC::Message* reply_msg, + bool success, + const std::wstring& prompt); + virtual void SetSuppressMessageBoxes(bool suppress_message_boxes) {} + virtual TabContents* AsTabContents() { return NULL; } + private: friend class ProcessCreationQueue; diff --git a/chrome/browser/jsmessage_box_client.h b/chrome/browser/jsmessage_box_client.h new file mode 100644 index 0000000..5e60c5d --- /dev/null +++ b/chrome/browser/jsmessage_box_client.h @@ -0,0 +1,50 @@ +// Copyright (c) 2009 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 CHROME_BROWSER_JSMESSAGE_BOX_CLIENT_H_ +#define CHROME_BROWSER_JSMESSAGE_BOX_CLIENT_H_ + +// JavaScriptMessageBoxClient +// +// An interface implemented by an object that receives results from JavaScript +// message boxes (alert, confirm, and prompt). +// + +#include <string> + +#include "app/gfx/native_widget_types.h" + +class GURL; +class Profile; +class TabContents; +namespace IPC { +class Message; +} + +class JavaScriptMessageBoxClient { + public: + virtual ~JavaScriptMessageBoxClient() {} + + // Returns the title to use for the message box. + virtual std::wstring GetMessageBoxTitle(const GURL& frame_url, + bool is_alert) = 0; + + // Returns the root native window with which the message box is associated. + virtual gfx::NativeWindow GetMessageBoxRootWindow() = 0; + + // 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 TabContents associated with this message box -- in practice, + // the TabContents implementing this interface -- or NULL if it has no + // TabContents (e.g., it's an ExtensionHost). + virtual TabContents* AsTabContents() = 0; +}; + +# endif // CHROME_BROWSER_JSMESSAGE_BOX_CLIENT_H_ diff --git a/chrome/browser/jsmessage_box_handler.cc b/chrome/browser/jsmessage_box_handler.cc index 6ba052f..428c8a3 100644 --- a/chrome/browser/jsmessage_box_handler.cc +++ b/chrome/browser/jsmessage_box_handler.cc @@ -4,16 +4,12 @@ #include "chrome/browser/jsmessage_box_handler.h" -#include "app/gfx/text_elider.h" #include "app/l10n_util.h" #include "app/message_box_flags.h" #include "build/build_config.h" #include "chrome/browser/app_modal_dialog_queue.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/pref_service.h" #include "googleurl/src/gurl.h" #include "grit/generated_resources.h" @@ -29,47 +25,19 @@ std::wstring MakeTextSafe(const std::wstring& text) { return text; } -std::wstring GetWindowTitle(TabContents* tab_contents, const GURL& frame_url, - int dialog_flags) { - bool is_alert = (dialog_flags == MessageBoxFlags::kIsJavascriptAlert); - if (!frame_url.has_host()) - return l10n_util::GetString( - is_alert ? IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE - : IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE); - - // We really only want the scheme, hostname, and port. - GURL::Replacements replacements; - replacements.ClearUsername(); - replacements.ClearPassword(); - replacements.ClearPath(); - replacements.ClearQuery(); - replacements.ClearRef(); - GURL clean_url = frame_url.ReplaceComponents(replacements); - - // TODO(brettw) it should be easier than this to do the correct language - // handling without getting the accept language from the profile. - std::wstring base_address = gfx::ElideUrl(clean_url, gfx::Font(), 0, - tab_contents->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages)); - // Force URL to have LTR directionality. - if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) - l10n_util::WrapStringWithLTRFormatting(&base_address); - return l10n_util::GetStringF( - is_alert ? IDS_JAVASCRIPT_ALERT_TITLE : IDS_JAVASCRIPT_MESSAGEBOX_TITLE, - base_address); -} - } // namespace -void RunJavascriptMessageBox(TabContents* tab_contents, +void RunJavascriptMessageBox(JavaScriptMessageBoxClient* client, 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) { - std::wstring title = GetWindowTitle(tab_contents, frame_url, dialog_flags); + std::wstring title = client->GetMessageBoxTitle(frame_url, + (dialog_flags == MessageBoxFlags::kIsJavascriptAlert)); Singleton<AppModalDialogQueue>()->AddDialog( - new AppModalDialog(tab_contents, title, + new AppModalDialog(client, title, dialog_flags, MakeTextSafe(message_text), default_prompt_text, display_suppress_checkbox, false, reply_msg)); diff --git a/chrome/browser/jsmessage_box_handler.h b/chrome/browser/jsmessage_box_handler.h index 856c1c5..9ec6652 100644 --- a/chrome/browser/jsmessage_box_handler.h +++ b/chrome/browser/jsmessage_box_handler.h @@ -10,6 +10,7 @@ #include "ipc/ipc_message.h" class GURL; +class JavaScriptMessageBoxClient; class TabContents; // Creates and runs a Javascript Message Box dialog. @@ -18,7 +19,7 @@ class TabContents; // 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(TabContents* tab_contents, +void RunJavascriptMessageBox(JavaScriptMessageBoxClient* client, const GURL& frame_url, int dialog_flags, const std::wstring& message_text, diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index e72df68..831b13c 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -4,6 +4,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" +#include "app/gfx/text_elider.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/file_version_info.h" @@ -1114,21 +1115,6 @@ void TabContents::GetPageLanguage() { render_view_host()->GetPageLanguage(); } -void TabContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, - bool success, - const std::wstring& prompt) { - last_javascript_message_dismissal_ = base::TimeTicks::Now(); - 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. - DidStopLoading(); - - tab_close_start_time_ = base::TimeTicks(); - } - is_showing_before_unload_dialog_ = false; - render_view_host()->JavaScriptMessageBoxClosed(reply_msg, success, prompt); -} - void TabContents::OnSavePage() { // If we can not save the page, try to download it. if (!SavePackage::IsSavableContents(contents_mime_type())) { @@ -2333,7 +2319,7 @@ void TabContents::RunJavaScriptMessage( } else { // If we are suppressing messages, just reply as is if the user immediately // pressed "Cancel". - OnJavaScriptMessageBoxClosed(reply_msg, false, std::wstring()); + OnMessageBoxClosed(reply_msg, false, std::wstring()); } } @@ -2648,6 +2634,58 @@ void TabContents::Observe(NotificationType type, } } +std::wstring TabContents::GetMessageBoxTitle(const GURL& frame_url, + bool is_alert) { + if (!frame_url.has_host()) + return l10n_util::GetString( + is_alert ? IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE + : IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE); + + // We really only want the scheme, hostname, and port. + GURL::Replacements replacements; + replacements.ClearUsername(); + replacements.ClearPassword(); + replacements.ClearPath(); + replacements.ClearQuery(); + replacements.ClearRef(); + GURL clean_url = frame_url.ReplaceComponents(replacements); + + // TODO(brettw) it should be easier than this to do the correct language + // handling without getting the accept language from the profile. + std::wstring base_address = gfx::ElideUrl(clean_url, gfx::Font(), 0, + profile()->GetPrefs()->GetString(prefs::kAcceptLanguages)); + // Force URL to have LTR directionality. + if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) + l10n_util::WrapStringWithLTRFormatting(&base_address); + + return l10n_util::GetStringF( + is_alert ? IDS_JAVASCRIPT_ALERT_TITLE : IDS_JAVASCRIPT_MESSAGEBOX_TITLE, + base_address); +} + +gfx::NativeWindow TabContents::GetMessageBoxRootWindow() { + return view_->GetTopLevelNativeWindow(); +} + +void TabContents::OnMessageBoxClosed(IPC::Message* reply_msg, + bool success, + const std::wstring& prompt) { + last_javascript_message_dismissal_ = base::TimeTicks::Now(); + 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. + DidStopLoading(); + + tab_close_start_time_ = base::TimeTicks(); + } + is_showing_before_unload_dialog_ = false; + render_view_host()->JavaScriptMessageBoxClosed(reply_msg, success, prompt); +} + +void TabContents::SetSuppressMessageBoxes(bool suppress_message_boxes) { + set_suppress_javascript_messages(suppress_message_boxes); +} + void TabContents::set_encoding(const std::string& encoding) { encoding_ = CharacterEncoding::GetCanonicalEncodingNameByAliasName(encoding); } diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index c33fcc5..7cdb549 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -22,6 +22,7 @@ #include "chrome/browser/download/save_package.h" #include "chrome/browser/fav_icon_helper.h" #include "chrome/browser/find_notification_details.h" +#include "chrome/browser/jsmessage_box_client.h" #include "chrome/browser/shell_dialogs.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/tab_contents/constrained_window.h" @@ -97,7 +98,8 @@ class TabContents : public PageNavigator, public RenderViewHostDelegate::BrowserIntegration, public RenderViewHostDelegate::Resource, public RenderViewHostManager::Delegate, - public SelectFileDialog::Listener { + public SelectFileDialog::Listener, + public JavaScriptMessageBoxClient { public: // Flags passed to the TabContentsDelegate.NavigationStateChanged to tell it // what has changed. Combine them to update more than one thing. @@ -533,11 +535,6 @@ class TabContents : public PageNavigator, suppress_javascript_messages_ = suppress_javascript_messages; } - // AppModalDialog calls this when the dialog is closed. - void OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, - bool success, - const std::wstring& prompt); - // Prepare for saving the current web page to disk. void OnSavePage(); @@ -958,6 +955,17 @@ class TabContents : public PageNavigator, const NotificationSource& source, const NotificationDetails& details); + + // JavaScriptMessageBoxClient ------------------------------------------------ + virtual std::wstring GetMessageBoxTitle(const GURL& frame_url, + bool is_alert); + virtual gfx::NativeWindow GetMessageBoxRootWindow(); + virtual void OnMessageBoxClosed(IPC::Message* reply_msg, + bool success, + const std::wstring& prompt); + virtual void SetSuppressMessageBoxes(bool suppress_message_boxes); + virtual TabContents* AsTabContents() { return this; } + // Data for core operation --------------------------------------------------- // Delegate for notifying our owner about stuff. Not owned by us. diff --git a/chrome/browser/views/jsmessage_box_dialog.cc b/chrome/browser/views/jsmessage_box_dialog.cc index 3fb70e0..b83242f 100644 --- a/chrome/browser/views/jsmessage_box_dialog.cc +++ b/chrome/browser/views/jsmessage_box_dialog.cc @@ -37,10 +37,15 @@ JavascriptMessageBoxDialog::~JavascriptMessageBoxDialog() { } void JavascriptMessageBoxDialog::ShowModalDialog() { - HWND root_hwnd = GetAncestor(tab_contents()->GetNativeView(), - GA_ROOT); - dialog_ = views::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this); - dialog_->Show(); + gfx::NativeWindow root_hwnd = client()->GetMessageBoxRootWindow(); + // GetMessageBoxRootWindow() will be NULL if there's no selected tab (e.g., + // during shutdown), in which case we simply skip showing this dialog. + if (!root_hwnd) { + Cancel(); + } else { + dialog_ = views::Window::CreateChromeWindow(root_hwnd, gfx::Rect(), this); + dialog_->Show(); + } } void JavascriptMessageBoxDialog::ActivateModalDialog() { @@ -72,13 +77,12 @@ int JavascriptMessageBoxDialog::GetDialogButtons() const { } std::wstring JavascriptMessageBoxDialog::GetWindowTitle() const { - return parent_->title();; + return parent_->title(); } void JavascriptMessageBoxDialog::WindowClosing() { dialog_ = NULL; - } void JavascriptMessageBoxDialog::DeleteDelegate() { diff --git a/chrome/browser/views/jsmessage_box_dialog.h b/chrome/browser/views/jsmessage_box_dialog.h index f709a50..92a2635 100644 --- a/chrome/browser/views/jsmessage_box_dialog.h +++ b/chrome/browser/views/jsmessage_box_dialog.h @@ -11,7 +11,7 @@ #include "views/window/dialog_delegate.h" class MessageBoxView; -class TabContents; +class JavaScriptMessageBoxClient; namespace views { class Window; } @@ -47,8 +47,8 @@ class JavascriptMessageBoxDialog : public views::DialogDelegate { virtual void OnClose(); private: - TabContents* tab_contents() { - return parent_->tab_contents(); + JavaScriptMessageBoxClient* client() { + return parent_->client(); } // A pointer to the AppModalDialog that owns us. |