summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-25 01:06:05 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-25 01:06:05 +0000
commitf86a07024080cd1b000105bce34ce45b2bd5159b (patch)
treed47e27fae62581ffb7f4e4209c7dd0106b88763f /chrome
parent2d42a37132679537eb9e8db9f45a6dfe92dde996 (diff)
downloadchromium_src-f86a07024080cd1b000105bce34ce45b2bd5159b.zip
chromium_src-f86a07024080cd1b000105bce34ce45b2bd5159b.tar.gz
chromium_src-f86a07024080cd1b000105bce34ce45b2bd5159b.tar.bz2
Re-land 5929 (r5882) with crash fix and also this change:
http://codereview.chromium.org/11392/show which fixes the remainder of the UI test issues apparently. http://crbug.com/4620 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5954 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/browser_init.cc53
-rw-r--r--chrome/browser/infobar_delegate.cc42
-rw-r--r--chrome/browser/infobar_delegate.h36
-rw-r--r--chrome/browser/password_manager.cc68
-rw-r--r--chrome/browser/password_manager.h43
-rw-r--r--chrome/browser/plugin_installer.cc62
-rw-r--r--chrome/browser/plugin_installer.h35
-rw-r--r--chrome/browser/session_crashed_view.cc39
-rw-r--r--chrome/browser/session_crashed_view.h30
-rw-r--r--chrome/browser/tab_contents.cc10
-rw-r--r--chrome/browser/tab_contents.h4
-rw-r--r--chrome/browser/views/frame/browser_view.cc1
-rw-r--r--chrome/browser/views/infobars/infobar_container.cc19
-rw-r--r--chrome/browser/views/infobars/infobars.cc111
-rw-r--r--chrome/browser/views/infobars/infobars.h29
-rw-r--r--chrome/browser/web_contents.cc7
-rw-r--r--chrome/common/notification_types.h14
18 files changed, 338 insertions, 273 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 447618e..7d79e5d 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -562,14 +562,6 @@
>
</File>
<File
- RelativePath=".\session_crashed_view.cc"
- >
- </File>
- <File
- RelativePath=".\session_crashed_view.h"
- >
- </File>
- <File
RelativePath=".\session_restore.cc"
>
</File>
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc
index 209ebc3..88bb11c 100644
--- a/chrome/browser/browser_init.cc
+++ b/chrome/browser/browser_init.cc
@@ -17,14 +17,15 @@
#include "base/win_util.h"
#include "chrome/app/locales/locale_settings.h"
#include "chrome/app/result_codes.h"
+#include "chrome/app/theme/theme_resources.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/browser/first_run.h"
+#include "chrome/browser/infobar_delegate.h"
#include "chrome/browser/navigation_controller.h"
#include "chrome/browser/net/dns_global.h"
-#include "chrome/browser/session_crashed_view.h"
#include "chrome/browser/session_restore.h"
#include "chrome/browser/session_startup_pref.h"
#include "chrome/browser/tabs/tab_strip_model.h"
@@ -38,6 +39,7 @@
#include "chrome/common/logging_chrome.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
+#include "chrome/common/resource_bundle.h"
#include "chrome/common/win_util.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_util.h"
@@ -48,6 +50,43 @@
namespace {
+// A delegate for the InfoBar shown when the previous session has crashed. The
+// bar deletes itself automatically after it is closed.
+class SessionCrashedInfoBarDelegate : public ConfirmInfoBarDelegate {
+ public:
+ explicit SessionCrashedInfoBarDelegate(TabContents* contents)
+ : profile_(contents->profile()),
+ ConfirmInfoBarDelegate(contents) {
+ }
+
+ // Overridden from ConfirmInfoBarDelegate:
+ virtual void InfoBarClosed() {
+ delete this;
+ }
+ virtual std::wstring GetMessageText() const {
+ return l10n_util::GetString(IDS_SESSION_CRASHED_VIEW_MESSAGE);
+ }
+ virtual SkBitmap* GetIcon() const {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_INFOBAR_RESTORE_SESSION);
+ }
+ virtual int GetButtons() const { return BUTTON_OK; }
+ virtual std::wstring GetButtonLabel(InfoBarButton button) const {
+ return l10n_util::GetString(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON);
+ }
+ virtual void Accept() {
+ // Restore the session.
+ SessionRestore::RestoreSession(profile_, NULL, false, true, false,
+ std::vector<GURL>());
+ }
+
+ private:
+ // The Profile that we restore sessions from.
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(SessionCrashedInfoBarDelegate);
+};
+
void SetOverrideHomePage(const CommandLine& command_line, PrefService* prefs) {
// If homepage is specified on the command line, canonify & store it.
if (command_line.HasSwitch(switches::kHomePage)) {
@@ -502,15 +541,11 @@ Browser* BrowserInit::LaunchWithProfile::OpenURLsInBrowser(
void BrowserInit::LaunchWithProfile::AddCrashedInfoBarIfNecessary(
TabContents* tab) {
- WebContents* web_contents = tab->AsWebContents();
- if (!profile_->DidLastSessionExitCleanly() && web_contents) {
+ if (!profile_->DidLastSessionExitCleanly()) {
// The last session didn't exit cleanly. Show an infobar to the user
- // so that they can restore if they want.
- // TODO(brettw) this should be done more cleanly, by adding a message to
- // the view and not getting the info bar from inside it directly.
- web_contents->view()->GetInfoBarView()->
- AddChildView(new SessionCrashedView(profile_));
- web_contents->view()->SetInfoBarVisible(true);
+ // so that they can restore if they want. The delegate deletes itself when
+ // it is closed.
+ tab->AddInfoBar(new SessionCrashedInfoBarDelegate(tab));
}
}
diff --git a/chrome/browser/infobar_delegate.cc b/chrome/browser/infobar_delegate.cc
index 81965be..c974948c 100644
--- a/chrome/browser/infobar_delegate.cc
+++ b/chrome/browser/infobar_delegate.cc
@@ -5,11 +5,30 @@
#include "chrome/browser/infobar_delegate.h"
#include "base/logging.h"
+#include "chrome/browser/navigation_entry.h"
+#include "chrome/browser/navigation_controller.h"
+#include "chrome/browser/tab_contents.h"
#include "chrome/common/l10n_util.h"
#include "generated_resources.h"
-// AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------
+// InfoBarDelegate: ------------------------------------------------------------
+
+bool InfoBarDelegate::ShouldExpire(
+ const NavigationController::LoadCommittedDetails& details) const {
+ bool is_reload =
+ PageTransition::StripQualifier(details.entry->transition_type()) ==
+ PageTransition::RELOAD;
+ return is_reload || (contents_unique_id_ != details.entry->unique_id());
+}
+
+InfoBarDelegate::InfoBarDelegate(TabContents* contents) {
+ // Initialize the unique id that we use to expire.
+ NavigationEntry* active_entry = contents->controller()->GetActiveEntry();
+ contents_unique_id_ = active_entry ? active_entry->unique_id() : 0;
+}
+
+// AlertInfoBarDelegate: -------------------------------------------------------
bool AlertInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
AlertInfoBarDelegate* alert_delegate = delegate->AsAlertInfoBarDelegate();
@@ -19,7 +38,11 @@ bool AlertInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
return alert_delegate->GetMessageText() == GetMessageText();
}
-// ConfirmInfoBarDelegate, public: ---------------------------------------------
+AlertInfoBarDelegate::AlertInfoBarDelegate(TabContents* contents)
+ : InfoBarDelegate(contents) {
+}
+
+// ConfirmInfoBarDelegate: -----------------------------------------------------
std::wstring ConfirmInfoBarDelegate::GetButtonLabel(
InfoBarButton button) const {
@@ -31,16 +54,21 @@ std::wstring ConfirmInfoBarDelegate::GetButtonLabel(
return std::wstring();
}
-// SimpleAlertInfoBarDelegate, public: -----------------------------------------
+ConfirmInfoBarDelegate::ConfirmInfoBarDelegate(TabContents* contents)
+ : AlertInfoBarDelegate(contents) {
+}
+
+// SimpleAlertInfoBarDelegate: -------------------------------------------------
SimpleAlertInfoBarDelegate::SimpleAlertInfoBarDelegate(
- const std::wstring& message, SkBitmap* icon)
+ TabContents* contents,
+ const std::wstring& message,
+ SkBitmap* icon)
: message_(message),
- icon_(icon) {
+ icon_(icon),
+ AlertInfoBarDelegate(contents) {
}
-// SimpleAlertInfoBarDelegate, AlertInfoBarDelegate implementation: ------------
-
std::wstring SimpleAlertInfoBarDelegate::GetMessageText() const {
return message_;
}
diff --git a/chrome/browser/infobar_delegate.h b/chrome/browser/infobar_delegate.h
index 47f2532..33b750a 100644
--- a/chrome/browser/infobar_delegate.h
+++ b/chrome/browser/infobar_delegate.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/basictypes.h"
+#include "chrome/browser/navigation_controller.h"
#include "skia/include/SkBitmap.h"
class AlertInfoBarDelegate;
@@ -32,8 +33,10 @@ class InfoBarDelegate {
}
// Returns true if the InfoBar should be closed automatically after the page
- // is navigated.
- virtual bool ShouldCloseOnNavigate() const { return true; }
+ // is navigated. The default behavior is to return true if the page is
+ // navigated somewhere else or reloaded.
+ virtual bool ShouldExpire(
+ const NavigationController::LoadCommittedDetails& details) const;
// Called after the InfoBar is closed. The delegate is free to delete itself
// at this point.
@@ -52,6 +55,21 @@ class InfoBarDelegate {
virtual ConfirmInfoBarDelegate* AsConfirmInfoBarDelegate() {
return NULL;
}
+
+ protected:
+ // Constructs the InfoBarDelegate for the specified TabContents'
+ // NavigationController.
+ explicit InfoBarDelegate(TabContents* contents);
+
+ private:
+ // The TabContents this InfoBarDelegate was added to.
+ TabContents* contents_;
+
+ // The unique id of the active NavigationEntry of the TabContents taht we were
+ // opened for. Used to help expire on navigations.
+ int contents_unique_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(InfoBarDelegate);
};
// An interface derived from InfoBarDelegate implemented by objects wishing to
@@ -69,6 +87,11 @@ class AlertInfoBarDelegate : public InfoBarDelegate {
virtual bool EqualsDelegate(InfoBarDelegate* delegate) const;
virtual InfoBar* CreateInfoBar();
virtual AlertInfoBarDelegate* AsAlertInfoBarDelegate() { return this; }
+
+ protected:
+ explicit AlertInfoBarDelegate(TabContents* contents);
+
+ DISALLOW_COPY_AND_ASSIGN(AlertInfoBarDelegate);
};
// An interface derived from InfoBarDelegate implemented by objects wishing to
@@ -101,13 +124,20 @@ class ConfirmInfoBarDelegate : public AlertInfoBarDelegate {
virtual ConfirmInfoBarDelegate* AsConfirmInfoBarDelegate() {
return this;
}
+
+ protected:
+ explicit ConfirmInfoBarDelegate(TabContents* contents);
+
+ DISALLOW_COPY_AND_ASSIGN(ConfirmInfoBarDelegate);
};
// Simple implementations for common use cases ---------------------------------
class SimpleAlertInfoBarDelegate : public AlertInfoBarDelegate {
public:
- SimpleAlertInfoBarDelegate(const std::wstring& message, SkBitmap* icon);
+ SimpleAlertInfoBarDelegate(TabContents* contents,
+ const std::wstring& message,
+ SkBitmap* icon);
// Overridden from AlertInfoBarDelegate:
virtual std::wstring GetMessageText() const;
diff --git a/chrome/browser/password_manager.cc b/chrome/browser/password_manager.cc
index f046773..2bd8cdf 100644
--- a/chrome/browser/password_manager.cc
+++ b/chrome/browser/password_manager.cc
@@ -25,15 +25,16 @@ void PasswordManager::RegisterUserPrefs(PrefService* prefs) {
PasswordManager::PasswordManager(WebContents* web_contents)
: web_contents_(web_contents),
- current_bar_(NULL),
observer_(NULL),
- login_managers_deleter_(&pending_login_managers_) {
+ login_managers_deleter_(&pending_login_managers_),
+ ConfirmInfoBarDelegate(web_contents) {
password_manager_enabled_.Init(prefs::kPasswordManagerEnabled,
web_contents->profile()->GetPrefs(), NULL);
}
PasswordManager::~PasswordManager() {
- CloseBars();
+ // Remove any InfoBars we may be showing.
+ web_contents_->RemoveInfoBar(this);
}
void PasswordManager::ProvisionallySavePassword(PasswordForm form) {
@@ -112,8 +113,7 @@ void PasswordManager::DidStopLoading() {
return;
if (pending_save_manager_->IsNewLogin()) {
- // Transfer ownership of the pending_save_manager_ to the PasswordBar.
- ReplaceInfoBar(new SavePasswordBar(pending_save_manager_.release(), this));
+ web_contents_->AddInfoBar(this);
} else {
// If the save is not a new username entry, then we just want to save this
// data (since the user already has related data saved), so don't prompt.
@@ -182,45 +182,41 @@ void PasswordManager::Autofill(const PasswordForm& form_for_autofill,
}
}
-void PasswordManager::CloseBars() {
- if (current_bar_)
- current_bar_->Close();
+// PasswordManager, ConfirmInfoBarDelegate implementation: ---------------------
+
+void PasswordManager::InfoBarClosed() {
+ pending_save_manager_.reset(NULL);
+}
+
+std::wstring PasswordManager::GetMessageText() const {
+ return l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT);
}
-void PasswordManager::ReplaceInfoBar(InfoBarItemView* bar) {
- // TODO(brettw) The password manager should not have to know about info bars.
- CloseBars();
- InfoBarView* view = web_contents_->view()->GetInfoBarView();
- view->AddChildView(bar);
- current_bar_ = bar;
+SkBitmap* PasswordManager::GetIcon() const {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_INFOBAR_SAVE_PASSWORD);
}
-PasswordManager::SavePasswordBar
- ::SavePasswordBar(PasswordFormManager* form_manager,
- PasswordManager* password_manager)
- : form_manager_(form_manager),
- password_manager_(password_manager),
- InfoBarConfirmView(
- l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT)) {
- SetOKButtonLabel(l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_BUTTON));
- SetCancelButtonLabel(l10n_util::GetString(
- IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON));
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
- SetIcon(*rb.GetBitmapNamed(IDR_INFOBAR_SAVE_PASSWORD));
+int PasswordManager::GetButtons() const {
+ return BUTTON_OK | BUTTON_CANCEL;
}
-PasswordManager::SavePasswordBar::~SavePasswordBar() {
- password_manager_->current_bar_ = NULL;
- if (form_manager_)
- delete form_manager_;
+std::wstring PasswordManager::GetButtonLabel(InfoBarButton button) const {
+ if (button == BUTTON_OK)
+ return l10n_util::GetString(IDS_PASSWORD_MANAGER_SAVE_BUTTON);
+ if (button == BUTTON_CANCEL)
+ return l10n_util::GetString(IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON);
+ NOTREACHED();
+ return std::wstring();
}
-void PasswordManager::SavePasswordBar::OKButtonPressed() {
- form_manager_->Save();
- BeginClose();
+void PasswordManager::Accept() {
+ pending_save_manager_->Save();
+ web_contents_->RemoveInfoBar(this);
}
-void PasswordManager::SavePasswordBar::CancelButtonPressed() {
- form_manager_->PermanentlyBlacklist();
- BeginClose();
+void PasswordManager::Cancel() {
+ pending_save_manager_->PermanentlyBlacklist();
+ web_contents_->RemoveInfoBar(this);
}
+
diff --git a/chrome/browser/password_manager.h b/chrome/browser/password_manager.h
index ecdac61..584ffff 100644
--- a/chrome/browser/password_manager.h
+++ b/chrome/browser/password_manager.h
@@ -6,7 +6,7 @@
#define CHROME_BROWSER_PASSWORD_MANAGER_H__
#include "base/scoped_ptr.h"
-#include "chrome/browser/views/info_bar_confirm_view.h"
+#include "chrome/browser/infobar_delegate.h"
#include "chrome/browser/password_form_manager.h"
#include "chrome/browser/views/login_view.h"
#include "chrome/common/pref_member.h"
@@ -21,7 +21,8 @@ class WebContents;
// receiving password form data from the renderer and managing the password
// database through the WebDataService. The PasswordManager is a LoginModel
// for purposes of supporting HTTP authentication dialogs.
-class PasswordManager : public views::LoginModel {
+class PasswordManager : public views::LoginModel,
+ public ConfirmInfoBarDelegate {
public:
static void RegisterUserPrefs(PrefService* prefs);
@@ -34,9 +35,6 @@ class PasswordManager : public views::LoginModel {
const PasswordFormMap& best_matches,
const PasswordForm* const preferred_match) const;
- // Closes any visible password manager UI
- void CloseBars();
-
// Notification that the user navigated away from the current page.
// Unless this is a password form submission, for our purposes this
// means we're done with the current page, so we can clean-up.
@@ -63,32 +61,15 @@ class PasswordManager : public views::LoginModel {
}
private:
- // The Info Bar UI that prompts the user to save a password.
- friend class SavePasswordBar;
- class SavePasswordBar : public InfoBarConfirmView {
- public:
- SavePasswordBar(PasswordFormManager* form_manager,
- PasswordManager* password_manager);
- virtual ~SavePasswordBar();
-
- // InfoBarConfirmView overrides.
- virtual void OKButtonPressed();
- virtual void CancelButtonPressed();
-
- private:
- PasswordFormManager* form_manager_;
- PasswordManager* password_manager_;
-
- DISALLOW_EVIL_CONSTRUCTORS(SavePasswordBar);
- };
-
- // Replace the current InfoBar with a new one. Just adds if there is no
- // visible InfoBars.
- void ReplaceInfoBar(InfoBarItemView* view);
-
- // The currently visible InfoBar (NULL if none)
- InfoBarItemView* current_bar_;
-
+ // Overridden from ConfirmInfoBarDelegate:
+ virtual void InfoBarClosed();
+ virtual std::wstring GetMessageText() const;
+ virtual SkBitmap* GetIcon() const;
+ virtual int GetButtons() const;
+ virtual std::wstring GetButtonLabel(InfoBarButton button) const;
+ virtual void Accept();
+ virtual void Cancel();
+
// When a form is "seen" on a page, a PasswordFormManager is created
// and stored in this collection until user navigates away from page.
typedef std::vector<PasswordFormManager*> LoginManagers;
diff --git a/chrome/browser/plugin_installer.cc b/chrome/browser/plugin_installer.cc
index 1d42d80..afd0314 100644
--- a/chrome/browser/plugin_installer.cc
+++ b/chrome/browser/plugin_installer.cc
@@ -4,9 +4,9 @@
#include "chrome/browser/plugin_installer.h"
-#include "chrome/app/theme/theme_resources.h"
-#include "chrome/browser/web_contents_view.h"
#include "base/string_util.h"
+#include "chrome/app/theme/theme_resources.h"
+#include "chrome/browser/web_contents.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/resource_bundle.h"
#include "webkit/default_plugin/default_plugin_shared.h"
@@ -15,33 +15,24 @@
PluginInstaller::PluginInstaller(WebContents* web_contents)
: web_contents_(web_contents),
- current_bar_(NULL) {
+ ConfirmInfoBarDelegate(web_contents) {
}
PluginInstaller::~PluginInstaller() {
- if (current_bar_)
- current_bar_->Close();
+ // Remove any InfoBars we may be showing.
+ web_contents_->RemoveInfoBar(this);
}
void PluginInstaller::OnMissingPluginStatus(int status) {
switch(status) {
case default_plugin::MISSING_PLUGIN_AVAILABLE: {
- // Display missing plugin InfoBar if a missing plugin is available.
- if (current_bar_)
- return;
-
- // TODO(brettw) have a more general way to add to the info bar rather
- // than mucking with it directly.
- InfoBarView* view = web_contents_->view()->GetInfoBarView();
- current_bar_ = new PluginInstallerBar(this);
- view->AddChildView(current_bar_);
+ web_contents_->AddInfoBar(this);
break;
}
case default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD: {
// Hide the InfoBar if user already started download/install of the
// missing plugin.
- if (current_bar_)
- current_bar_->Close();
+ web_contents_->RemoveInfoBar(this);
break;
}
default: {
@@ -51,38 +42,25 @@ void PluginInstaller::OnMissingPluginStatus(int status) {
}
}
-void PluginInstaller::OnStartLoading() {
- if (current_bar_)
- current_bar_->BeginClose();
-}
-
-void PluginInstaller::OnBarDestroy(InfoBarConfirmView* bar) {
- if (current_bar_ == bar)
- current_bar_ = NULL;
+std::wstring PluginInstaller::GetMessageText() const {
+ return l10n_util::GetString(IDS_PLUGININSTALLER_MISSINGPLUGIN_PROMPT);
}
-void PluginInstaller::OnOKButtonPressed() {
- current_bar_->BeginClose();
- web_contents_->render_view_host()->InstallMissingPlugin();
+SkBitmap* PluginInstaller::GetIcon() const {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_INFOBAR_PLUGIN_INSTALL);
}
-PluginInstaller::PluginInstallerBar
- ::PluginInstallerBar(PluginInstaller* plugin_installer)
- : plugin_installer_(plugin_installer),
- InfoBarConfirmView(
- l10n_util::GetString(IDS_PLUGININSTALLER_MISSINGPLUGIN_PROMPT)) {
- SetOKButtonLabel(
- l10n_util::GetString(IDS_PLUGININSTALLER_INSTALLPLUGIN_BUTTON));
- RemoveCancelButton();
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
- SetIcon(*rb.GetBitmapNamed(IDR_INFOBAR_PLUGIN_INSTALL));
+int PluginInstaller::GetButtons() const {
+ return BUTTON_OK;
}
-PluginInstaller::PluginInstallerBar::~PluginInstallerBar() {
- plugin_installer_->OnBarDestroy(this);
+std::wstring PluginInstaller::GetButtonLabel(InfoBarButton button) const {
+ if (button == BUTTON_OK)
+ return l10n_util::GetString(IDS_PLUGININSTALLER_INSTALLPLUGIN_BUTTON);
+ return ConfirmInfoBarDelegate::GetButtonLabel(button);
}
-void PluginInstaller::PluginInstallerBar::OKButtonPressed() {
- plugin_installer_->OnOKButtonPressed();
+void PluginInstaller::Accept() {
+ web_contents_->render_view_host()->InstallMissingPlugin();
}
-
diff --git a/chrome/browser/plugin_installer.h b/chrome/browser/plugin_installer.h
index e2d21e9..a3b479a 100644
--- a/chrome/browser/plugin_installer.h
+++ b/chrome/browser/plugin_installer.h
@@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_PLUGIN_INSTALLER_H__
-#define CHROME_BROWSER_PLUGIN_INSTALLER_H__
+#ifndef CHROME_BROWSER_PLUGIN_INSTALLER_H_
+#define CHROME_BROWSER_PLUGIN_INSTALLER_H_
-#include "base/scoped_ptr.h"
-#include "chrome/browser/views/info_bar_confirm_view.h"
-#include "chrome/browser/web_contents.h"
-#include "chrome/browser/webdata/web_data_service.h"
+#include "chrome/browser/infobar_delegate.h"
+
+class WebContents;
// The main purpose for this class is to popup/close the infobar when there is
// a missing plugin.
-class PluginInstaller {
+class PluginInstaller : public ConfirmInfoBarDelegate {
public:
explicit PluginInstaller(WebContents* web_contents);
~PluginInstaller();
@@ -20,26 +19,16 @@ class PluginInstaller {
void OnMissingPluginStatus(int status);
// A new page starts loading. This is the perfect time to close the info bar.
void OnStartLoading();
- void OnBarDestroy(InfoBarConfirmView* bar);
- void OnOKButtonPressed();
private:
- class PluginInstallerBar : public InfoBarConfirmView {
- public:
- PluginInstallerBar(PluginInstaller* plugin_installer);
- virtual ~PluginInstallerBar();
-
- // InfoBarConfirmView overrides.
- virtual void OKButtonPressed();
-
- private:
- PluginInstaller* plugin_installer_;
-
- DISALLOW_EVIL_CONSTRUCTORS(PluginInstallerBar);
- };
+ // Overridden from ConfirmInfoBarDelegate:
+ virtual std::wstring GetMessageText() const;
+ virtual SkBitmap* GetIcon() const;
+ virtual int GetButtons() const;
+ virtual std::wstring GetButtonLabel(InfoBarButton button) const;
+ virtual void Accept();
// The containing WebContents
WebContents* web_contents_;
- InfoBarItemView* current_bar_;
DISALLOW_EVIL_CONSTRUCTORS(PluginInstaller);
};
diff --git a/chrome/browser/session_crashed_view.cc b/chrome/browser/session_crashed_view.cc
index 6fa81e3d..e69de29 100644
--- a/chrome/browser/session_crashed_view.cc
+++ b/chrome/browser/session_crashed_view.cc
@@ -1,39 +0,0 @@
-// Copyright (c) 2006-2008 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/session_crashed_view.h"
-
-#include "chrome/app/theme/theme_resources.h"
-#include "chrome/browser/session_restore.h"
-#include "chrome/common/l10n_util.h"
-#include "chrome/common/resource_bundle.h"
-
-#include "chromium_strings.h"
-#include "generated_resources.h"
-
-SessionCrashedView::SessionCrashedView(Profile* profile)
- : InfoBarConfirmView(
- l10n_util::GetString(IDS_SESSION_CRASHED_VIEW_MESSAGE)),
- profile_(profile) {
- DCHECK(profile_);
- SetOKButtonLabel(
- l10n_util::GetString(IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON));
- RemoveCancelButton();
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
- SetIcon(*rb.GetBitmapNamed(IDR_INFOBAR_RESTORE_SESSION));
-}
-
-SessionCrashedView::~SessionCrashedView() {
-}
-
-void SessionCrashedView::OKButtonPressed() {
- // Restore the session.
- SessionRestore::RestoreSession(profile_, NULL, false, true, false,
- std::vector<GURL>());
-
- // Close the info bar.
- InfoBarConfirmView::OKButtonPressed();
- // NOTE: OKButtonPressed eventually results in deleting us.
-}
-
diff --git a/chrome/browser/session_crashed_view.h b/chrome/browser/session_crashed_view.h
index 3a09e86..e69de29 100644
--- a/chrome/browser/session_crashed_view.h
+++ b/chrome/browser/session_crashed_view.h
@@ -1,30 +0,0 @@
-// Copyright (c) 2006-2008 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_SESSION_CRASHED_VIEW_H__
-#define CHROME_BROWSER_SESSION_CRASHED_VIEW_H__
-
-#include "chrome/browser/views/info_bar_confirm_view.h"
-
-class Profile;
-
-// SessionCrashedView is used on startup when the last session didn't exit
-// cleanly. The user is given the option of restoring the last session.
-class SessionCrashedView : public InfoBarConfirmView {
- public:
- explicit SessionCrashedView(Profile* profile);
- virtual ~SessionCrashedView();
-
- virtual void SessionCrashedView::OKButtonPressed();
-
- private:
- void Init();
-
- Profile* profile_;
-
- DISALLOW_EVIL_CONSTRUCTORS(SessionCrashedView);
-};
-
-#endif // CHROME_BROWSER_SESSION_CRASHED_VIEW_H__
-
diff --git a/chrome/browser/tab_contents.cc b/chrome/browser/tab_contents.cc
index 510c611..9bdca3c 100644
--- a/chrome/browser/tab_contents.cc
+++ b/chrome/browser/tab_contents.cc
@@ -390,7 +390,7 @@ void TabContents::SetInitialFocus() {
void TabContents::AddInfoBar(InfoBarDelegate* delegate) {
// Look through the existing InfoBarDelegates we have for a match. If we've
// already got one that matches, then we don't add the new one.
- for (size_t i = 0; i < infobar_delegate_count(); ++i) {
+ for (int i = 0; i < infobar_delegate_count(); ++i) {
if (GetInfoBarDelegateAt(i)->EqualsDelegate(delegate))
return;
}
@@ -415,10 +415,10 @@ void TabContents::RemoveInfoBar(InfoBarDelegate* delegate) {
find(infobar_delegates_.begin(), infobar_delegates_.end(), delegate);
if (it != infobar_delegates_.end()) {
InfoBarDelegate* delegate = *it;
- infobar_delegates_.erase(it);
NotificationService::current()->Notify(NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED,
Source<TabContents>(this),
Details<InfoBarDelegate>(delegate));
+ infobar_delegates_.erase(it);
}
// Remove ourselves as an observer if we are tracking no more InfoBars.
@@ -590,11 +590,9 @@ void TabContents::ExpireInfoBars(
if (!details.is_user_initiated_main_frame_load())
return;
- for (size_t i = 0; i < infobar_delegate_count(); ++i) {
+ for (int i = infobar_delegate_count() - 1; i >= 0; --i) {
InfoBarDelegate* delegate = GetInfoBarDelegateAt(i);
- if (!TransitionIsReload(details.entry->transition_type()) &&
- delegate->ShouldCloseOnNavigate()) {
+ if (delegate->ShouldExpire(details))
RemoveInfoBar(delegate);
- }
}
}
diff --git a/chrome/browser/tab_contents.h b/chrome/browser/tab_contents.h
index 6893ee1..2f78a79 100644
--- a/chrome/browser/tab_contents.h
+++ b/chrome/browser/tab_contents.h
@@ -393,8 +393,8 @@ class TabContents : public PageNavigator,
void RemoveInfoBar(InfoBarDelegate* delegate);
// Enumeration and access functions.
- size_t infobar_delegate_count() const { return infobar_delegates_.size(); }
- InfoBarDelegate* GetInfoBarDelegateAt(size_t index) {
+ int infobar_delegate_count() const { return infobar_delegates_.size(); }
+ InfoBarDelegate* GetInfoBarDelegateAt(int index) {
return infobar_delegates_.at(index);
}
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index c3b5d07..91b148c 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -636,6 +636,7 @@ void BrowserView::TabDetachedAt(TabContents* contents, int index) {
// We need to reset the current tab contents to NULL before it gets
// freed. This is because the focus manager performs some operations
// on the selected TabContents when it is removed.
+ infobar_container_->ChangeTabContents(NULL);
contents_container_->SetTabContents(NULL);
}
}
diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc
index 2fe7a35..3a79464 100644
--- a/chrome/browser/views/infobars/infobar_container.cc
+++ b/chrome/browser/views/infobars/infobar_container.cc
@@ -19,6 +19,10 @@ InfoBarContainer::InfoBarContainer(BrowserView* browser_view)
}
InfoBarContainer::~InfoBarContainer() {
+ // We NULL this pointer before resetting the TabContents to prevent view
+ // hierarchy modifications from attempting to adjust the BrowserView, which is
+ // in the process of shutting down.
+ browser_view_ = NULL;
ChangeTabContents(NULL);
}
@@ -31,6 +35,9 @@ void InfoBarContainer::ChangeTabContents(TabContents* contents) {
this, NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED,
Source<TabContents>(tab_contents_));
}
+ // No need to delete the child views here, their removal from the view
+ // hierarchy does this automatically (see InfoBar::InfoBarRemoved).
+ RemoveAllChildViews(false);
tab_contents_ = contents;
if (tab_contents_) {
UpdateInfoBars();
@@ -44,7 +51,8 @@ void InfoBarContainer::ChangeTabContents(TabContents* contents) {
}
void InfoBarContainer::InfoBarAnimated(bool completed) {
- browser_view_->SelectedTabToolbarSizeChanged(!completed);
+ if (browser_view_)
+ browser_view_->SelectedTabToolbarSizeChanged(!completed);
}
void InfoBarContainer::RemoveDelegate(InfoBarDelegate* delegate) {
@@ -76,7 +84,7 @@ void InfoBarContainer::Layout() {
void InfoBarContainer::ViewHierarchyChanged(bool is_add,
views::View* parent,
views::View* child) {
- if (parent == this && child->GetParent() == this) {
+ if (parent == this && child->GetParent() == this && browser_view_) {
// An InfoBar child was added or removed. Tell the BrowserView it needs to
// re-layout since our preferred size will have changed.
browser_view_->SelectedTabToolbarSizeChanged(false);
@@ -100,10 +108,7 @@ void InfoBarContainer::Observe(NotificationType type,
// InfoBarContainer, private: --------------------------------------------------
void InfoBarContainer::UpdateInfoBars() {
- // Clear out all the old child views.
- RemoveAllChildViews(true);
-
- for (size_t i = 0; i < tab_contents_->infobar_delegate_count(); ++i) {
+ for (int i = 0; i < tab_contents_->infobar_delegate_count(); ++i) {
InfoBarDelegate* delegate = tab_contents_->GetInfoBarDelegateAt(i);
InfoBar* infobar = delegate->CreateInfoBar();
infobar->set_container(this);
@@ -120,7 +125,7 @@ void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate) {
}
void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate) {
- size_t index = 0;
+ int index = 0;
for (; index < tab_contents_->infobar_delegate_count(); ++index) {
if (tab_contents_->GetInfoBarDelegateAt(index) == delegate)
break;
diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc
index 5733d33..466a74f 100644
--- a/chrome/browser/views/infobars/infobars.cc
+++ b/chrome/browser/views/infobars/infobars.cc
@@ -11,8 +11,10 @@
#include "chrome/common/slide_animation.h"
#include "chrome/views/background.h"
#include "chrome/views/button.h"
+#include "chrome/views/external_focus_tracker.h"
#include "chrome/views/image_view.h"
#include "chrome/views/label.h"
+#include "chrome/views/widget.h"
#include "generated_resources.h"
@@ -66,7 +68,11 @@ class InfoBarBackground : public views::Background {
InfoBar::InfoBar(InfoBarDelegate* delegate)
: delegate_(delegate),
- close_button_(new views::Button) {
+ close_button_(new views::Button),
+ delete_factory_(this) {
+ // We delete ourselves when we're removed from the view hierarchy.
+ SetParentOwned(false);
+
set_background(new InfoBarBackground);
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
@@ -97,14 +103,19 @@ void InfoBar::Open() {
}
void InfoBar::AnimateClose() {
+ DestroyFocusTracker(true);
animation_->Hide();
}
void InfoBar::Close() {
GetParent()->RemoveChildView(this);
- if (delegate())
- delegate()->InfoBarClosed();
- delete this;
+ // Note that we only tell the delegate we're closed here, and not when we're
+ // simply destroyed (by virtue of a tab switch or being moved from window to
+ // window), since this action can cause the delegate to destroy itself.
+ if (delegate_) {
+ delegate_->InfoBarClosed();
+ delegate_ = NULL;
+ }
}
// InfoBar, views::View overrides: ---------------------------------------------
@@ -122,6 +133,17 @@ void InfoBar::Layout() {
}
+void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent,
+ views::View* child) {
+ if (child == this) {
+ if (is_add) {
+ InfoBarAdded();
+ } else {
+ InfoBarRemoved();
+ }
+ }
+}
+
// InfoBar, protected: ---------------------------------------------------------
int InfoBar::GetAvailableWidth() const {
@@ -138,14 +160,58 @@ void InfoBar::ButtonPressed(views::BaseButton* sender) {
// InfoBar, AnimationDelegate implementation: ----------------------------------
void InfoBar::AnimationProgressed(const Animation* animation) {
- container_->InfoBarAnimated(true);
+ if (container_)
+ container_->InfoBarAnimated(true);
}
void InfoBar::AnimationEnded(const Animation* animation) {
- container_->InfoBarAnimated(false);
+ if (container_) {
+ container_->InfoBarAnimated(false);
+
+ if (!animation_->IsShowing())
+ Close();
+ }
+}
+
+// InfoBar, private: -----------------------------------------------------------
+
+void InfoBar::InfoBarAdded() {
+ // The container_ pointer must be set before adding to the view hierarchy.
+ DCHECK(container_);
+ // When we're added to a view hierarchy within a widget, we create an
+ // external focus tracker to track what was focused in case we obtain
+ // focus so that we can restore focus when we're removed.
+ views::Widget* widget = GetWidget();
+ if (widget) {
+ focus_tracker_.reset(
+ new views::ExternalFocusTracker(this,
+ views::FocusManager::GetFocusManager(widget->GetHWND())));
+ }
+}
- if (!animation_->IsShowing())
- Close();
+void InfoBar::InfoBarRemoved() {
+ DestroyFocusTracker(false);
+ // NULL our container_ pointer so that if Animation::Stop results in
+ // AnimationEnded being called, we do not try and delete ourselves twice.
+ container_ = NULL;
+ animation_->Stop();
+ // Finally, clean ourselves up when we're removed from the view hierarchy
+ // since no-one refers to us now.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ delete_factory_.NewRunnableMethod(&InfoBar::DeleteSelf));
+}
+
+void InfoBar::DestroyFocusTracker(bool restore_focus) {
+ if (focus_tracker_.get()) {
+ if (restore_focus)
+ focus_tracker_->FocusLastFocusedExternalView();
+ focus_tracker_->SetFocusManager(NULL);
+ focus_tracker_.reset(NULL);
+ }
+}
+
+void InfoBar::DeleteSelf() {
+ delete this;
}
// AlertInfoBar, public: -------------------------------------------------------
@@ -199,6 +265,12 @@ ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate)
cancel_button_(NULL),
initialized_(false),
AlertInfoBar(delegate) {
+ ok_button_ = new views::NativeButton(
+ delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK));
+ ok_button_->SetListener(this);
+ cancel_button_ = new views::NativeButton(
+ delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL));
+ cancel_button_->SetListener(this);
}
ConfirmInfoBar::~ConfirmInfoBar() {
@@ -214,10 +286,16 @@ void ConfirmInfoBar::Layout() {
gfx::Size ok_ps = ok_button_->GetPreferredSize();
gfx::Size cancel_ps = cancel_button_->GetPreferredSize();
- if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK)
+ if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) {
ok_button_width = ok_ps.width();
- if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL)
- cancel_button_width = cancel_ps.width();
+ } else {
+ ok_button_->SetVisible(false);
+ }
+ if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
+ cancel_button_width = cancel_ps.width();
+ } else {
+ cancel_button_->SetVisible(false);
+ }
cancel_button_->SetBounds(available_width - cancel_button_width,
OffsetY(this, cancel_ps), cancel_ps.width(),
@@ -225,13 +303,13 @@ void ConfirmInfoBar::Layout() {
int spacing = cancel_button_width > 0 ? kButtonSpacing : 0;
ok_button_->SetBounds(cancel_button_->x() - spacing - ok_button_width,
OffsetY(this, ok_ps), ok_ps.width(), ok_ps.height());
-
AlertInfoBar::Layout();
}
void ConfirmInfoBar::ViewHierarchyChanged(bool is_add,
views::View* parent,
views::View* child) {
+ InfoBar::ViewHierarchyChanged(is_add, parent, child);
if (is_add && child == this && !initialized_) {
Init();
initialized_ = true;
@@ -243,8 +321,10 @@ void ConfirmInfoBar::ViewHierarchyChanged(bool is_add,
void ConfirmInfoBar::ButtonPressed(views::NativeButton* sender) {
if (sender == ok_button_) {
GetDelegate()->Accept();
+ AnimateClose();
} else if (sender == cancel_button_) {
GetDelegate()->Cancel();
+ AnimateClose();
} else {
NOTREACHED();
}
@@ -267,14 +347,7 @@ ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
}
void ConfirmInfoBar::Init() {
- ok_button_ = new views::NativeButton(
- GetDelegate()->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK));
- ok_button_->SetListener(this);
AddChildView(ok_button_);
-
- cancel_button_ = new views::NativeButton(
- GetDelegate()->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL));
- cancel_button_->SetListener(this);
AddChildView(cancel_button_);
}
diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h
index 1e02f96..f2ccc73 100644
--- a/chrome/browser/views/infobars/infobars.h
+++ b/chrome/browser/views/infobars/infobars.h
@@ -13,6 +13,7 @@ class InfoBarContainer;
class SlideAnimation;
namespace views {
class Button;
+class ExternalFocusTracker;
class ImageView;
class Label;
}
@@ -30,6 +31,8 @@ class InfoBar : public views::View,
InfoBarDelegate* delegate() const { return delegate_; }
+ // Set a link to the parent InfoBarContainer. This must be set before the
+ // InfoBar is added to the view hierarchy.
void set_container(InfoBarContainer* container) { container_ = container; }
// Starts animating the InfoBar open.
@@ -52,6 +55,11 @@ class InfoBar : public views::View,
virtual void Layout();
protected:
+ // Overridden from views::View:
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
+
// Returns the available width of the View for use by child view layout,
// excluding the close button.
virtual int GetAvailableWidth() const;
@@ -64,6 +72,20 @@ class InfoBar : public views::View,
virtual void AnimationProgressed(const Animation* animation);
virtual void AnimationEnded(const Animation* animation);
+ // Called when an InfoBar is added or removed from a view hierarchy to do
+ // setup and shutdown.
+ void InfoBarAdded();
+ void InfoBarRemoved();
+
+ // Destroys the external focus tracker, if present. If |restore_focus| is
+ // true, restores focus to the view tracked by the focus tracker before doing
+ // so.
+ void DestroyFocusTracker(bool restore_focus);
+
+ // Deletes this object (called after a return to the message loop to allow
+ // the stack in ViewHierarchyChanged to unwind).
+ void DeleteSelf();
+
// The InfoBar's container
InfoBarContainer* container_;
@@ -76,6 +98,13 @@ class InfoBar : public views::View,
// The animation that runs when the InfoBar is opened or closed.
scoped_ptr<SlideAnimation> animation_;
+ // Tracks and stores the last focused view which is not the InfoBar or any of
+ // its children. Used to restore focus once the InfoBar is closed.
+ scoped_ptr<views::ExternalFocusTracker> focus_tracker_;
+
+ // Used to delete this object after a return to the message loop.
+ ScopedRunnableMethodFactory<InfoBar> delete_factory_;
+
DISALLOW_COPY_AND_ASSIGN(InfoBar);
};
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index 60ba95b4..c3c0a9e 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -855,8 +855,6 @@ void WebContents::RequestMove(const gfx::Rect& new_bounds) {
}
void WebContents::DidStartLoading(RenderViewHost* rvh, int32 page_id) {
- if (plugin_installer_ != NULL)
- plugin_installer_->OnStartLoading();
SetIsLoading(true, NULL);
}
@@ -1339,12 +1337,13 @@ void WebContents::OnCrashedPlugin(const std::wstring& plugin_path) {
plugin_name = product_name;
}
AddInfoBar(new SimpleAlertInfoBarDelegate(
- l10n_util::GetStringF(IDS_PLUGIN_CRASHED_PROMPT, plugin_name), NULL));
+ this, l10n_util::GetStringF(IDS_PLUGIN_CRASHED_PROMPT, plugin_name),
+ NULL));
}
void WebContents::OnJSOutOfMemory() {
AddInfoBar(new SimpleAlertInfoBarDelegate(
- l10n_util::GetString(IDS_JS_OUT_OF_MEMORY_PROMPT), NULL));
+ this, l10n_util::GetString(IDS_JS_OUT_OF_MEMORY_PROMPT), NULL));
}
bool WebContents::CanBlur() const {
diff --git a/chrome/common/notification_types.h b/chrome/common/notification_types.h
index c748d36..d6ca458 100644
--- a/chrome/common/notification_types.h
+++ b/chrome/common/notification_types.h
@@ -200,18 +200,18 @@ enum NotificationType {
// No details are expected.
NOTIFY_WEB_CONTENTS_DISCONNECTED,
- // This message is sent when a new InfoBar is added to a TabContents. The
- // source is a Source<TabContents> with a pointer to the TabContents the
+ // This message is sent when a new InfoBar has been added to a TabContents.
+ // The source is a Source<TabContents> with a pointer to the TabContents the
// InfoBar was added to. The details is a Details<InfoBarDelegate> with a
// pointer to an object implementing the InfoBarDelegate interface for the
// InfoBar that was added.
NOTIFY_TAB_CONTENTS_INFOBAR_ADDED,
- // This message is sent when an InfoBar is removed from a TabContents. The
- // source is a Source<TabContents> with a pointer to the TabContents the
- // InfoBar was removed from. The details is a Details<InfoBarDelegate> with a
- // pointer to an object implementing the InfoBarDelegate interface for the
- // InfoBar that was removed.
+ // This message is sent when an InfoBar is about to be removed from a
+ // TabContents. The source is a Source<TabContents> with a pointer to the
+ // TabContents the InfoBar was removed from. The details is a
+ // Details<InfoBarDelegate> with a pointer to an object implementing the
+ // InfoBarDelegate interface for the InfoBar that was removed.
NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED,
// This is sent when an externally hosted tab is created. The details contain