summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorpam@chromium.org <pam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-05 18:22:35 +0000
committerpam@chromium.org <pam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-05 18:22:35 +0000
commite1d0303ebea1caddb079d71b63f39463d3944bad (patch)
tree9c9c1abb6d608889aa20d14c34036eb99ffe2c58 /chrome
parentd6b401bed87fa50d1fc0993c04ee7ee992dd6627 (diff)
downloadchromium_src-e1d0303ebea1caddb079d71b63f39463d3944bad.zip
chromium_src-e1d0303ebea1caddb079d71b63f39463d3944bad.tar.gz
chromium_src-e1d0303ebea1caddb079d71b63f39463d3944bad.tar.bz2
Implement window.alert() and its cousins for extensions.
BUG=12126 TEST=put a window.prompt() in a background page, a browser action, and a page action. Make sure it gets the result back correctly. Also make sure it still works when called from a web page. Review URL: http://codereview.chromium.org/341089 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31110 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd20
-rw-r--r--chrome/browser/app_modal_dialog.cc50
-rw-r--r--chrome/browser/app_modal_dialog.h17
-rw-r--r--chrome/browser/app_modal_dialog_gtk.cc2
-rw-r--r--chrome/browser/extensions/extension_host.cc40
-rw-r--r--chrome/browser/extensions/extension_host.h14
-rw-r--r--chrome/browser/jsmessage_box_client.h50
-rw-r--r--chrome/browser/jsmessage_box_handler.cc40
-rw-r--r--chrome/browser/jsmessage_box_handler.h3
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc70
-rw-r--r--chrome/browser/tab_contents/tab_contents.h20
-rw-r--r--chrome/browser/views/jsmessage_box_dialog.cc16
-rw-r--r--chrome/browser/views/jsmessage_box_dialog.h6
-rwxr-xr-xchrome/chrome.gyp1
14 files changed, 242 insertions, 107 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index d2f5b066..32ff803 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -2765,19 +2765,31 @@ Keep your key file in a safe place. You will need it to create new versions of y
</message>
<!-- Javascript Dialog Box strings -->
- <message name="IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE" desc="Title for Javascript alert if there is no hostname to display">
+ <message name="IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE" desc="Title for Javascript alert originating from a web page if there is no hostname to display">
Javascript Alert
</message>
- <message name="IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE" desc="Title for Javascript prompt and confirm if there is no hostname to display">
+ <message name="IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE" desc="Title for Javascript prompt and confirm originating from a web page if there is no hostname to display">
Javascript
</message>
- <message name="IDS_JAVASCRIPT_ALERT_TITLE" desc="Title for Javascript alert">
+ <message name="IDS_JAVASCRIPT_ALERT_TITLE" desc="Title for Javascript alert originating from a web page">
Alert <ph name="SITE">$1<ex>http://www.google.com</ex>
</ph>
</message>
- <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE" desc="Title for Javascript prompt and confirm">
+ <message name="IDS_JAVASCRIPT_MESSAGEBOX_TITLE" desc="Title for Javascript prompt and confirm originating from a web page">
<ph name="SITE">$1<ex>http://www.google.com</ex></ph>
</message>
+ <message name="IDS_EXTENSION_ALERT_DEFAULT_TITLE" desc="Title for Javascript alert originating from an extension if there is no extension name to display">
+ Extension Alert
+ </message>
+ <message name="IDS_EXTENSION_MESSAGEBOX_DEFAULT_TITLE" desc="Title for Javascript prompt and confirm originating from an extension if there is no extension name to display">
+ Extension
+ </message>
+ <message name="IDS_EXTENSION_ALERT_TITLE" desc="Title for Javascript alert originating from an extension">
+ Extension Alert <ph name="EXTENSION_NAME">$1<ex>Gmail Checker</ex></ph>
+ </message>
+ <message name="IDS_EXTENSION_MESSAGEBOX_TITLE" desc="Title for Javascript prompt and confirm originating from an extension">
+ Extension <ph name="EXTENSION_NAME">$1<ex>Gmail Checker</ex></ph>
+ </message>
<message name="IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION" desc="Optional UI shown on the message box, in the form of a checkbox, allowing the user to suppress additional message boxes from the page.">
Prevent this page from creating additional dialogs.
</message>
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.
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index aa8d6d1..7cc828e 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1747,6 +1747,7 @@
'browser/jankometer.h',
'browser/jumplist.cc',
'browser/jumplist.h',
+ 'browser/jsmessage_box_client.h',
'browser/jsmessage_box_handler.cc',
'browser/jsmessage_box_handler.h',
'browser/keychain_mac.cc',