summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-21 22:27:24 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-21 22:27:24 +0000
commit616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72 (patch)
tree04b8cd92d18cd6e1ff54e46c6c32b0d70391a831 /chrome
parentc7eeed7fa25e06ec3d0367a74d2b43671958c5d3 (diff)
downloadchromium_src-616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72.zip
chromium_src-616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72.tar.gz
chromium_src-616ed5a653d4bc13b4633d7c7b85d2f0c73bfd72.tar.bz2
Beginnings of a new InfoBar system.
This implements AlertInfoBar and InfoBarContainer. It also makes the crashed plugin/js oom infobars use this new system. Design Doc: http://dev.chromium.org/developers/design-documents/info-barshttp://crbug.com/4620 Review URL: http://codereview.chromium.org/11318 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5856 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/infobar_delegate.cc54
-rw-r--r--chrome/browser/infobar_delegate.h122
-rw-r--r--chrome/browser/tab_contents.cc77
-rw-r--r--chrome/browser/tab_contents.h32
-rw-r--r--chrome/browser/views/browser_views.vcproj16
-rw-r--r--chrome/browser/views/frame/browser_view.cc35
-rw-r--r--chrome/browser/views/frame/browser_view.h4
-rw-r--r--chrome/browser/views/infobars/infobar_container.cc131
-rw-r--r--chrome/browser/views/infobars/infobar_container.h73
-rw-r--r--chrome/browser/views/infobars/infobars.cc291
-rw-r--r--chrome/browser/views/infobars/infobars.h138
-rw-r--r--chrome/browser/web_contents.cc10
-rw-r--r--chrome/browser/web_contents.h1
-rw-r--r--chrome/common/notification_types.h22
15 files changed, 989 insertions, 25 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index f900e92..447618e 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -822,6 +822,14 @@
>
</File>
<File
+ RelativePath=".\infobar_delegate.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\infobar_delegate.h"
+ >
+ </File>
+ <File
RelativePath=".\ipc_status_view.cc"
>
</File>
diff --git a/chrome/browser/infobar_delegate.cc b/chrome/browser/infobar_delegate.cc
new file mode 100644
index 0000000..81965be
--- /dev/null
+++ b/chrome/browser/infobar_delegate.cc
@@ -0,0 +1,54 @@
+// 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/infobar_delegate.h"
+
+#include "base/logging.h"
+#include "chrome/common/l10n_util.h"
+
+#include "generated_resources.h"
+
+// AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------
+
+bool AlertInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
+ AlertInfoBarDelegate* alert_delegate = delegate->AsAlertInfoBarDelegate();
+ if (!alert_delegate)
+ return false;
+
+ return alert_delegate->GetMessageText() == GetMessageText();
+}
+
+// ConfirmInfoBarDelegate, public: ---------------------------------------------
+
+std::wstring ConfirmInfoBarDelegate::GetButtonLabel(
+ InfoBarButton button) const {
+ if (button == BUTTON_OK)
+ return l10n_util::GetString(IDS_OK);
+ if (button == BUTTON_CANCEL)
+ return l10n_util::GetString(IDS_CANCEL);
+ NOTREACHED();
+ return std::wstring();
+}
+
+// SimpleAlertInfoBarDelegate, public: -----------------------------------------
+
+SimpleAlertInfoBarDelegate::SimpleAlertInfoBarDelegate(
+ const std::wstring& message, SkBitmap* icon)
+ : message_(message),
+ icon_(icon) {
+}
+
+// SimpleAlertInfoBarDelegate, AlertInfoBarDelegate implementation: ------------
+
+std::wstring SimpleAlertInfoBarDelegate::GetMessageText() const {
+ return message_;
+}
+
+SkBitmap* SimpleAlertInfoBarDelegate::GetIcon() const {
+ return icon_;
+}
+
+void SimpleAlertInfoBarDelegate::InfoBarClosed() {
+ delete this;
+}
diff --git a/chrome/browser/infobar_delegate.h b/chrome/browser/infobar_delegate.h
new file mode 100644
index 0000000..57b0737
--- /dev/null
+++ b/chrome/browser/infobar_delegate.h
@@ -0,0 +1,122 @@
+// 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_INFOBAR_DELEGATE_H_
+#define CHROME_BROWSER_INFOBAR_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "skia/include/SkBitmap.h"
+
+class AlertInfoBarDelegate;
+class ConfirmInfoBarDelegate;
+class InfoBar;
+
+// An interface implemented by objects wishing to control an InfoBar.
+// Implementing this interface is not sufficient to use an InfoBar, since it
+// does not map to a specific InfoBar type. Instead, you must implement either
+// AlertInfoBarDelegate or ConfirmInfoBarDelegate, or override with your own
+// delegate for your own InfoBar variety.
+class InfoBarDelegate {
+ public:
+ // Returns true if the supplied |delegate| is equal to this one. Equality is
+ // left to the implementation to define. This function is called by the
+ // TabContents when determining whether or not a delegate should be added
+ // because a matching one already exists. If this function returns true, the
+ // TabContents will not add the new delegate because it considers one to
+ // already be present.
+ virtual bool EqualsDelegate(InfoBarDelegate* delegate) const {
+ return false;
+ }
+
+ // Returns true if the InfoBar should be closed automatically after the page
+ // is navigated.
+ virtual bool ShouldCloseOnNavigate() const { return true; }
+
+ // Called after the InfoBar is closed. The delegate is free to delete itself
+ // at this point.
+ virtual void InfoBarClosed() {}
+
+ // Called to create the InfoBar. Implementation of this method is
+ // platform-specific.
+ virtual InfoBar* CreateInfoBar() = 0;
+
+ // Returns a pointer to the ConfirmInfoBarDelegate interface, if implemented.
+ virtual AlertInfoBarDelegate* AsAlertInfoBarDelegate() {
+ return NULL;
+ }
+
+ // Returns a pointer to the ConfirmInfoBarDelegate interface, if implemented.
+ virtual ConfirmInfoBarDelegate* AsConfirmInfoBarDelegate() {
+ return NULL;
+ }
+};
+
+// An interface derived from InfoBarDelegate implemented by objects wishing to
+// control an AlertInfoBar.
+class AlertInfoBarDelegate : public InfoBarDelegate {
+ public:
+ // Returns the message string to be displayed for the InfoBar.
+ virtual std::wstring GetMessageText() const = 0;
+
+ // Return the icon to be shown for this InfoBar. If the returned bitmap is
+ // NULL, no icon is shown.
+ virtual SkBitmap* GetIcon() const { return NULL; }
+
+ // Overridden from InfoBarDelegate:
+ virtual bool EqualsDelegate(InfoBarDelegate* delegate) const;
+ virtual InfoBar* CreateInfoBar();
+ virtual AlertInfoBarDelegate* AsAlertInfoBarDelegate() { return this; }
+};
+
+// An interface derived from InfoBarDelegate implemented by objects wishing to
+// control a ConfirmInfoBar.
+class ConfirmInfoBarDelegate : public AlertInfoBarDelegate {
+ public:
+ enum InfoBarButton {
+ BUTTON_NONE = 0,
+ BUTTON_OK,
+ BUTTON_CANCEL
+ };
+
+ // Return the buttons to be shown for this InfoBar.
+ virtual int GetButtons() const {
+ return BUTTON_NONE;
+ }
+
+ // Return the label for the specified button. The default implementation
+ // returns "OK" for the OK button and "Cancel" for the Cancel button.
+ virtual std::wstring GetButtonLabel(InfoBarButton button) const;
+
+ // Called when the OK button is pressed.
+ virtual void Accept() {}
+
+ // Called when the Cancel button is pressed.
+ virtual void Cancel() {}
+
+ // Overridden from InfoBarDelegate:
+ virtual InfoBar* CreateInfoBar();
+ virtual ConfirmInfoBarDelegate* AsConfirmInfoBarDelegate() {
+ return this;
+ }
+};
+
+// Simple implementations for common use cases ---------------------------------
+
+class SimpleAlertInfoBarDelegate : public AlertInfoBarDelegate {
+ public:
+ SimpleAlertInfoBarDelegate(const std::wstring& message, SkBitmap* icon);
+
+ // Overridden from AlertInfoBarDelegate:
+ virtual std::wstring GetMessageText() const;
+ virtual SkBitmap* GetIcon() const;
+ virtual void InfoBarClosed();
+
+ private:
+ std::wstring message_;
+ SkBitmap* icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(SimpleAlertInfoBarDelegate);
+};
+
+#endif // #ifndef CHROME_BROWSER_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/tab_contents.cc b/chrome/browser/tab_contents.cc
index e5131dc..510c611 100644
--- a/chrome/browser/tab_contents.cc
+++ b/chrome/browser/tab_contents.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/cert_store.h"
#include "chrome/browser/navigation_entry.h"
+#include "chrome/browser/infobar_delegate.h"
#include "chrome/browser/views/download_shelf_view.h"
#include "chrome/browser/views/download_started_animation.h"
#include "chrome/browser/views/blocked_popup_container.h"
@@ -386,6 +387,48 @@ void TabContents::SetInitialFocus() {
::SetFocus(GetContainerHWND());
}
+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) {
+ if (GetInfoBarDelegateAt(i)->EqualsDelegate(delegate))
+ return;
+ }
+
+ infobar_delegates_.push_back(delegate);
+ NotificationService::current()->Notify(NOTIFY_TAB_CONTENTS_INFOBAR_ADDED,
+ Source<TabContents>(this),
+ Details<InfoBarDelegate>(delegate));
+
+ // Add ourselves as an observer for navigations the first time a delegate is
+ // added. We use this notification to expire InfoBars that need to expire on
+ // page transitions.
+ if (infobar_delegates_.size() == 1) {
+ NotificationService::current()->AddObserver(
+ this, NOTIFY_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(controller()));
+ }
+}
+
+void TabContents::RemoveInfoBar(InfoBarDelegate* delegate) {
+ std::vector<InfoBarDelegate*>::iterator it =
+ 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));
+ }
+
+ // Remove ourselves as an observer if we are tracking no more InfoBars.
+ if (infobar_delegates_.empty()) {
+ NotificationService::current()->RemoveObserver(
+ this, NOTIFY_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(controller()));
+ }
+}
+
void TabContents::SetDownloadShelfVisible(bool visible) {
if (shelf_visible_ != visible) {
if (visible) {
@@ -467,6 +510,17 @@ void TabContents::DidMoveOrResize(ConstrainedWindow* window) {
UpdateWindow(GetContainerHWND());
}
+void TabContents::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == NOTIFY_NAV_ENTRY_COMMITTED);
+ DCHECK(controller() == Source<NavigationController>(source).ptr());
+
+ NavigationController::LoadCommittedDetails& committed_details =
+ *(Details<NavigationController::LoadCommittedDetails>(details).ptr());
+ ExpireInfoBars(committed_details);
+}
+
// static
void TabContents::MigrateShelfView(TabContents* from, TabContents* to) {
bool was_shelf_visible = from->IsDownloadShelfVisible();
@@ -521,3 +575,26 @@ bool TabContents::ShowingBlockedPopupNotification() const {
return blocked_popups_ != NULL &&
blocked_popups_->GetTabContentsCount() != 0;
}
+
+namespace {
+bool TransitionIsReload(PageTransition::Type transition) {
+ return PageTransition::StripQualifier(transition) == PageTransition::RELOAD;
+}
+}
+
+void TabContents::ExpireInfoBars(
+ const NavigationController::LoadCommittedDetails& details) {
+ // Only hide InfoBars when the user has done something that makes the main
+ // frame load. We don't want various automatic or subframe navigations making
+ // it disappear.
+ if (!details.is_user_initiated_main_frame_load())
+ return;
+
+ for (size_t i = 0; i < infobar_delegate_count(); ++i) {
+ InfoBarDelegate* delegate = GetInfoBarDelegateAt(i);
+ if (!TransitionIsReload(details.entry->transition_type()) &&
+ delegate->ShouldCloseOnNavigate()) {
+ RemoveInfoBar(delegate);
+ }
+ }
+}
diff --git a/chrome/browser/tab_contents.h b/chrome/browser/tab_contents.h
index ebbc47b..6893ee1 100644
--- a/chrome/browser/tab_contents.h
+++ b/chrome/browser/tab_contents.h
@@ -10,6 +10,7 @@
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/constrained_window.h"
+#include "chrome/browser/infobar_delegate.h"
#include "chrome/browser/navigation_controller.h"
#include "chrome/browser/page_navigator.h"
#include "chrome/browser/tab_contents_type.h"
@@ -53,7 +54,8 @@ class WebContents;
// the NavigationController makes the active TabContents inactive, notifies the
// TabContentsDelegate that the TabContents is being replaced, and then
// activates the new TabContents.
-class TabContents : public PageNavigator {
+class TabContents : public PageNavigator,
+ public NotificationObserver {
public:
// Flags passed to the TabContentsDelegate.NavigationStateChanged to tell it
// what has changed. Combine them to update more than one thing.
@@ -382,6 +384,20 @@ class TabContents : public PageNavigator {
// the focus is passed to the RootView.
virtual views::RootView* GetContentsRootView() { return NULL; }
+ // Infobars ------------------------------------------------------------------
+
+ // Adds an InfoBar for the specified |delegate|.
+ void AddInfoBar(InfoBarDelegate* delegate);
+
+ // Removes the InfoBar for the specified |delegate|.
+ void RemoveInfoBar(InfoBarDelegate* delegate);
+
+ // Enumeration and access functions.
+ size_t infobar_delegate_count() const { return infobar_delegates_.size(); }
+ InfoBarDelegate* GetInfoBarDelegateAt(size_t index) {
+ return infobar_delegates_.at(index);
+ }
+
// Toolbars and such ---------------------------------------------------------
// Returns whether the bookmark bar should be visible.
@@ -417,6 +433,11 @@ class TabContents : public PageNavigator {
void DidMoveOrResize(ConstrainedWindow* window);
protected:
+ // NotificationObserver implementation:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
friend class NavigationController;
// Used to access the child_windows_ (ConstrainedWindowList) for testing
// automation purposes.
@@ -470,6 +491,12 @@ class TabContents : public PageNavigator {
bool ShowingBlockedPopupNotification() const;
private:
+ // Expires InfoBars that need to be expired, according to the state carried
+ // in |details|, in response to a new NavigationEntry being committed (the
+ // user navigated to another page).
+ void ExpireInfoBars(
+ const NavigationController::LoadCommittedDetails& details);
+
// Data ----------------------------------------------------------------------
TabContentsType type_;
@@ -512,6 +539,9 @@ class TabContents : public PageNavigator {
// repositioning, etc.
BlockedPopupContainer* blocked_popups_;
+ // Delegates for InfoBars associated with this TabContents.
+ std::vector<InfoBarDelegate*> infobar_delegates_;
+
DISALLOW_COPY_AND_ASSIGN(TabContents);
};
diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj
index 5a543cd..f7ca623 100644
--- a/chrome/browser/views/browser_views.vcproj
+++ b/chrome/browser/views/browser_views.vcproj
@@ -216,6 +216,22 @@
RelativePath=".\info_bar_view.h"
>
</File>
+ <File
+ RelativePath=".\infobars\infobar_container.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\infobars\infobar_container.h"
+ >
+ </File>
+ <File
+ RelativePath=".\infobars\infobars.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\infobars\infobars.h"
+ >
+ </File>
</Filter>
<Filter
Name="Options"
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 8dbeb98..c3b5d07 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -25,6 +25,7 @@
#include "chrome/browser/views/frame/browser_frame.h"
#include "chrome/browser/views/html_dialog_view.h"
#include "chrome/browser/views/importer_view.h"
+#include "chrome/browser/views/infobars/infobar_container.h"
#include "chrome/browser/views/keyword_editor_view.h"
#include "chrome/browser/views/password_manager_view.h"
#include "chrome/browser/views/status_bubble.h"
@@ -338,6 +339,9 @@ void BrowserView::Init() {
toolbar_->Init(browser_->profile());
toolbar_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TOOLBAR));
+ infobar_container_ = new InfoBarContainer(this);
+ AddChildView(infobar_container_);
+
contents_container_ = new TabContentsContainerView;
set_contents_view(contents_container_);
AddChildView(contents_container_);
@@ -645,7 +649,9 @@ void BrowserView::TabSelectedAt(TabContents* old_contents,
if (old_contents)
old_contents->StoreFocus();
- // Tell the frame what happened so that the TabContents gets resized, etc.
+ // Update various elements that are interested in knowing the current
+ // TabContents.
+ infobar_container_->ChangeTabContents(new_contents);
contents_container_->SetTabContents(new_contents);
// TODO(beng): This should be called automatically by SetTabContents, but I
// am striving for parity now rather than cleanliness. This is
@@ -1055,7 +1061,7 @@ int BrowserView::LayoutBookmarkAndInfoBars(int top) {
// the Bookmark bar isn't visible on all tabs, then we need to show the
// Info bar _above_ the Bookmark bar, since the Bookmark bar is styled to
// look like it's part of the New Tab Page...
- if (active_info_bar_ && active_bookmark_bar_ &&
+ if (active_bookmark_bar_ &&
bookmark_bar_view_->IsNewTabPage() &&
!bookmark_bar_view_->IsAlwaysShown()) {
top = LayoutInfoBar(top);
@@ -1078,13 +1084,21 @@ int BrowserView::LayoutBookmarkBar(int top) {
return top;
}
int BrowserView::LayoutInfoBar(int top) {
- if (SupportsWindowFeature(FEATURE_INFOBAR) && active_info_bar_) {
- gfx::Size ps = active_info_bar_->GetPreferredSize();
- active_info_bar_->SetBounds(0, top, width(), ps.height());
+ if (SupportsWindowFeature(FEATURE_INFOBAR)) {
+ // Layout the new infobar.
+ gfx::Size ps = infobar_container_->GetPreferredSize();
+ infobar_container_->SetBounds(0, top, width(), ps.height());
top += ps.height();
- if (SupportsWindowFeature(FEATURE_BOOKMARKBAR) && active_bookmark_bar_ &&
- !show_bookmark_bar_pref_.GetValue()) {
- top -= kSeparationLineHeight;
+
+ if (active_info_bar_) {
+ // Layout the old infobar.
+ ps = active_info_bar_->GetPreferredSize();
+ active_info_bar_->SetBounds(0, top, width(), ps.height());
+ top += ps.height();
+ if (SupportsWindowFeature(FEATURE_BOOKMARKBAR) && active_bookmark_bar_ &&
+ !show_bookmark_bar_pref_.GetValue()) {
+ top -= kSeparationLineHeight;
+ }
}
}
return top;
@@ -1131,7 +1145,10 @@ bool BrowserView::MaybeShowInfoBar(TabContents* contents) {
if (contents && contents->AsWebContents() &&
contents->AsWebContents()->view()->IsInfoBarVisible())
new_info_bar = contents->AsWebContents()->view()->GetInfoBarView();
- return UpdateChildViewAndLayout(new_info_bar, &active_info_bar_);
+ UpdateChildViewAndLayout(new_info_bar, &active_info_bar_);
+
+ // TODO(beng): remove this function once the InfoBar rejiggering is complete.
+ return true;
}
bool BrowserView::MaybeShowDownloadShelf(TabContents* contents) {
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index d777f5a..172a1db 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -22,6 +22,7 @@ class BookmarkBarView;
class Browser;
class BrowserToolbarView;
class EncodingMenuControllerDelegate;
+class InfoBarContainer;
class Menu;
class StatusBubble;
class TabContentsContainerView;
@@ -343,6 +344,9 @@ class BrowserView : public BrowserWindow,
// The Bookmark Bar View for this window. Lazily created.
scoped_ptr<BookmarkBarView> bookmark_bar_view_;
+ // The InfoBarContainer that contains InfoBars for the current tab.
+ InfoBarContainer* infobar_container_;
+
// The view that contains the selected TabContents.
TabContentsContainerView* contents_container_;
diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc
new file mode 100644
index 0000000..2fe7a35
--- /dev/null
+++ b/chrome/browser/views/infobars/infobar_container.cc
@@ -0,0 +1,131 @@
+// 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/views/infobars/infobar_container.h"
+
+#include "chrome/browser/infobar_delegate.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/views/infobars/infobars.h"
+#include "chrome/common/notification_types.h"
+
+// InfoBarContainer, public: ---------------------------------------------------
+
+InfoBarContainer::InfoBarContainer(BrowserView* browser_view)
+ : browser_view_(browser_view),
+ tab_contents_(NULL) {
+
+}
+
+InfoBarContainer::~InfoBarContainer() {
+ ChangeTabContents(NULL);
+}
+
+void InfoBarContainer::ChangeTabContents(TabContents* contents) {
+ if (tab_contents_) {
+ NotificationService::current()->RemoveObserver(
+ this, NOTIFY_TAB_CONTENTS_INFOBAR_ADDED,
+ Source<TabContents>(tab_contents_));
+ NotificationService::current()->RemoveObserver(
+ this, NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED,
+ Source<TabContents>(tab_contents_));
+ }
+ tab_contents_ = contents;
+ if (tab_contents_) {
+ UpdateInfoBars();
+ NotificationService::current()->AddObserver(
+ this, NOTIFY_TAB_CONTENTS_INFOBAR_ADDED,
+ Source<TabContents>(tab_contents_));
+ NotificationService::current()->AddObserver(
+ this, NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED,
+ Source<TabContents>(tab_contents_));
+ }
+}
+
+void InfoBarContainer::InfoBarAnimated(bool completed) {
+ browser_view_->SelectedTabToolbarSizeChanged(!completed);
+}
+
+void InfoBarContainer::RemoveDelegate(InfoBarDelegate* delegate) {
+ tab_contents_->RemoveInfoBar(delegate);
+}
+
+// InfoBarContainer, views::View overrides: ------------------------------------
+
+gfx::Size InfoBarContainer::GetPreferredSize() {
+ // We do not have a preferred width (we will expand to fit the available width
+ // of the BrowserView). Our preferred height is the sum of the preferred
+ // heights of the InfoBars contained within us.
+ int height = 0;
+ for (int i = 0; i < GetChildViewCount(); ++i)
+ height += GetChildViewAt(i)->GetPreferredSize().height();
+ return gfx::Size(0, height);
+}
+
+void InfoBarContainer::Layout() {
+ int top = 0;
+ for (int i = 0; i < GetChildViewCount(); ++i) {
+ views::View* child = GetChildViewAt(i);
+ gfx::Size ps = child->GetPreferredSize();
+ child->SetBounds(0, top, width(), ps.height());
+ top += ps.height();
+ }
+}
+
+void InfoBarContainer::ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child) {
+ if (parent == this && child->GetParent() == this) {
+ // 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);
+ }
+}
+
+// InfoBarContainer, NotificationObserver implementation: ----------------------
+
+void InfoBarContainer::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NOTIFY_TAB_CONTENTS_INFOBAR_ADDED) {
+ AddInfoBar(Details<InfoBarDelegate>(details).ptr());
+ } else if (type == NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED) {
+ RemoveInfoBar(Details<InfoBarDelegate>(details).ptr());
+ } else {
+ NOTREACHED();
+ }
+}
+
+// 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) {
+ InfoBarDelegate* delegate = tab_contents_->GetInfoBarDelegateAt(i);
+ InfoBar* infobar = delegate->CreateInfoBar();
+ infobar->set_container(this);
+ AddChildView(infobar);
+ infobar->Open();
+ }
+}
+
+void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate) {
+ InfoBar* infobar = delegate->CreateInfoBar();
+ infobar->set_container(this);
+ infobar->AnimateOpen();
+ AddChildView(infobar);
+}
+
+void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate) {
+ size_t index = 0;
+ for (; index < tab_contents_->infobar_delegate_count(); ++index) {
+ if (tab_contents_->GetInfoBarDelegateAt(index) == delegate)
+ break;
+ }
+
+ // The View will be removed once the Close animation completes.
+ static_cast<InfoBar*>(GetChildViewAt(index))->AnimateClose();
+}
diff --git a/chrome/browser/views/infobars/infobar_container.h b/chrome/browser/views/infobars/infobar_container.h
new file mode 100644
index 0000000..43c5280
--- /dev/null
+++ b/chrome/browser/views/infobars/infobar_container.h
@@ -0,0 +1,73 @@
+// 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_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_
+#define CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_
+
+#include "chrome/common/notification_service.h"
+#include "chrome/views/view.h"
+
+class BrowserView;
+class InfoBarDelegate;
+class TabContents;
+
+// A views::View subclass that contains a collection of InfoBars associated with
+// a TabContents.
+class InfoBarContainer : public views::View,
+ public NotificationObserver {
+ public:
+ explicit InfoBarContainer(BrowserView* browser_view);
+ virtual ~InfoBarContainer();
+
+ // Changes the TabContents for which this container is showing InfoBars. Can
+ // be NULL.
+ void ChangeTabContents(TabContents* contents);
+
+ // Called by child InfoBars as they animate. If |completed| is true, the
+ // animation has finished running.
+ void InfoBarAnimated(bool completed);
+
+ // Remove the specified InfoBarDelegate from the selected TabContents. This
+ // will notify us back and cause us to close the View. This is called from
+ // the InfoBar's close button handler.
+ void RemoveDelegate(InfoBarDelegate* delegate);
+
+ // Overridden from views::View:
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+ protected:
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
+
+ private:
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // Constructs the InfoBars needed to reflect the state of the current
+ // TabContents associated with this container. No animations are run during
+ // this process.
+ void UpdateInfoBars();
+
+ // Adds an InfoBar for the specified delegate, in response to a notification
+ // from the selected TabContents. The InfoBar's appearance will be animated.
+ void AddInfoBar(InfoBarDelegate* delegate);
+
+ // Removes an InfoBar for the specified delegate, in response to a
+ // notification from the selected TabContents. The InfoBar's disappearance
+ // will be animated.
+ void RemoveInfoBar(InfoBarDelegate* delegate);
+
+ // The BrowserView that hosts this InfoBarContainer.
+ BrowserView* browser_view_;
+
+ // The TabContents for which we are currently showing InfoBars.
+ TabContents* tab_contents_;
+
+ DISALLOW_COPY_AND_ASSIGN(InfoBarContainer);
+};
+
+#endif // #ifndef CHROME_BROWSER_VIEWS_INFOBARS_INFOBAR_CONTAINER_H_
diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc
new file mode 100644
index 0000000..5733d33
--- /dev/null
+++ b/chrome/browser/views/infobars/infobars.cc
@@ -0,0 +1,291 @@
+// 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/views/infobars/infobars.h"
+
+#include "chrome/app/theme/theme_resources.h"
+#include "chrome/browser/views/infobars/infobar_container.h"
+#include "chrome/common/l10n_util.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/common/slide_animation.h"
+#include "chrome/views/background.h"
+#include "chrome/views/button.h"
+#include "chrome/views/image_view.h"
+#include "chrome/views/label.h"
+
+#include "generated_resources.h"
+
+const double kInfoBarHeight = 37.0;
+
+static const int kVerticalPadding = 3;
+static const int kHorizontalPadding = 3;
+static const int kIconLabelSpacing = 5;
+static const int kButtonSpacing = 5;
+
+static const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183);
+static const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145);
+
+static const int kSeparatorLineHeight = 1;
+static const SkColor kSeparatorColor = SkColorSetRGB(165, 165, 165);
+
+namespace {
+int OffsetY(views::View* parent, const gfx::Size prefsize) {
+ return std::max((parent->height() - prefsize.height()) / 2, 0);
+}
+}
+
+// InfoBarBackground -----------------------------------------------------------
+
+class InfoBarBackground : public views::Background {
+ public:
+ InfoBarBackground() {
+ gradient_background_.reset(
+ views::Background::CreateVerticalGradientBackground(
+ kBackgroundColorTop, kBackgroundColorBottom));
+ }
+
+ // Overridden from views::View:
+ virtual void Paint(ChromeCanvas* canvas, views::View* view) const {
+ // First paint the gradient background.
+ gradient_background_->Paint(canvas, view);
+
+ // Now paint the separator line.
+ canvas->FillRectInt(kSeparatorColor, 0,
+ view->height() - kSeparatorLineHeight, view->width(),
+ kSeparatorLineHeight);
+ }
+
+ private:
+ scoped_ptr<views::Background> gradient_background_;
+
+ DISALLOW_COPY_AND_ASSIGN(InfoBarBackground);
+};
+
+// InfoBar, public: ------------------------------------------------------------
+
+InfoBar::InfoBar(InfoBarDelegate* delegate)
+ : delegate_(delegate),
+ close_button_(new views::Button) {
+ set_background(new InfoBarBackground);
+
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ close_button_->SetImage(views::Button::BS_NORMAL,
+ rb.GetBitmapNamed(IDR_CLOSE_BAR));
+ close_button_->SetImage(views::Button::BS_HOT,
+ rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
+ close_button_->SetImage(views::Button::BS_PUSHED,
+ rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
+ close_button_->SetListener(this, 0);
+ close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE));
+ AddChildView(close_button_);
+
+ animation_.reset(new SlideAnimation(this));
+ animation_->SetTweenType(SlideAnimation::NONE);
+}
+
+InfoBar::~InfoBar() {
+}
+
+void InfoBar::AnimateOpen() {
+ animation_->Show();
+}
+
+void InfoBar::Open() {
+ animation_->Reset(1.0);
+ animation_->Show();
+}
+
+void InfoBar::AnimateClose() {
+ animation_->Hide();
+}
+
+void InfoBar::Close() {
+ GetParent()->RemoveChildView(this);
+ if (delegate())
+ delegate()->InfoBarClosed();
+ delete this;
+}
+
+// InfoBar, views::View overrides: ---------------------------------------------
+
+gfx::Size InfoBar::GetPreferredSize() {
+ int height = static_cast<int>(kInfoBarHeight * animation_->GetCurrentValue());
+ return gfx::Size(0, height);
+}
+
+void InfoBar::Layout() {
+ gfx::Size button_ps = close_button_->GetPreferredSize();
+ close_button_->SetBounds(width() - kHorizontalPadding - button_ps.width(),
+ OffsetY(this, button_ps), button_ps.width(),
+ button_ps.height());
+
+}
+
+// InfoBar, protected: ---------------------------------------------------------
+
+int InfoBar::GetAvailableWidth() const {
+ return close_button_->x() - kIconLabelSpacing;
+}
+
+// InfoBar, views::BaseButton::ButtonListener implementation: ------------------
+
+void InfoBar::ButtonPressed(views::BaseButton* sender) {
+ if (sender == close_button_)
+ container_->RemoveDelegate(delegate());
+}
+
+// InfoBar, AnimationDelegate implementation: ----------------------------------
+
+void InfoBar::AnimationProgressed(const Animation* animation) {
+ container_->InfoBarAnimated(true);
+}
+
+void InfoBar::AnimationEnded(const Animation* animation) {
+ container_->InfoBarAnimated(false);
+
+ if (!animation_->IsShowing())
+ Close();
+}
+
+// AlertInfoBar, public: -------------------------------------------------------
+
+AlertInfoBar::AlertInfoBar(AlertInfoBarDelegate* delegate)
+ : InfoBar(delegate) {
+ label_ = new views::Label(
+ delegate->GetMessageText(),
+ ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont));
+ label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(label_);
+
+ icon_ = new views::ImageView;
+ if (delegate->GetIcon())
+ icon_->SetImage(delegate->GetIcon());
+ AddChildView(icon_);
+}
+
+AlertInfoBar::~AlertInfoBar() {
+
+}
+
+// AlertInfoBar, views::View overrides: ----------------------------------------
+
+void AlertInfoBar::Layout() {
+ // Layout the close button.
+ InfoBar::Layout();
+
+ // Layout the icon and text.
+ gfx::Size icon_ps = icon_->GetPreferredSize();
+ icon_->SetBounds(kHorizontalPadding, OffsetY(this, icon_ps), icon_ps.width(),
+ icon_ps.height());
+
+ gfx::Size text_ps = label_->GetPreferredSize();
+ int text_width =
+ GetAvailableWidth() - icon_->bounds().right() - kIconLabelSpacing;
+ label_->SetBounds(icon_->bounds().right() + kIconLabelSpacing,
+ OffsetY(this, text_ps), text_width, text_ps.height());
+}
+
+// AlertInfoBar, private: ------------------------------------------------------
+
+AlertInfoBarDelegate* AlertInfoBar::GetDelegate() {
+ return delegate()->AsAlertInfoBarDelegate();
+}
+
+// ConfirmInfoBar, public: -----------------------------------------------------
+
+ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate)
+ : ok_button_(NULL),
+ cancel_button_(NULL),
+ initialized_(false),
+ AlertInfoBar(delegate) {
+}
+
+ConfirmInfoBar::~ConfirmInfoBar() {
+}
+
+// ConfirmInfoBar, views::View overrides: --------------------------------------
+
+void ConfirmInfoBar::Layout() {
+ InfoBar::Layout();
+ int available_width = InfoBar::GetAvailableWidth();
+ int ok_button_width = 0;
+ int cancel_button_width = 0;
+ gfx::Size ok_ps = ok_button_->GetPreferredSize();
+ gfx::Size cancel_ps = cancel_button_->GetPreferredSize();
+
+ if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK)
+ ok_button_width = ok_ps.width();
+ if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL)
+ cancel_button_width = cancel_ps.width();
+
+ cancel_button_->SetBounds(available_width - cancel_button_width,
+ OffsetY(this, cancel_ps), cancel_ps.width(),
+ cancel_ps.height());
+ 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) {
+ if (is_add && child == this && !initialized_) {
+ Init();
+ initialized_ = true;
+ }
+}
+
+// ConfirmInfoBar, views::NativeButton::Listener implementation: ---------------
+
+void ConfirmInfoBar::ButtonPressed(views::NativeButton* sender) {
+ if (sender == ok_button_) {
+ GetDelegate()->Accept();
+ } else if (sender == cancel_button_) {
+ GetDelegate()->Cancel();
+ } else {
+ NOTREACHED();
+ }
+}
+
+// ConfirmInfoBar, InfoBar overrides: ------------------------------------------
+
+int ConfirmInfoBar::GetAvailableWidth() const {
+ if (ok_button_)
+ return ok_button_->x() - kButtonSpacing;
+ if (cancel_button_)
+ return cancel_button_->x() - kButtonSpacing;
+ return InfoBar::GetAvailableWidth();
+}
+
+// ConfirmInfoBar, private: ----------------------------------------------------
+
+ConfirmInfoBarDelegate* ConfirmInfoBar::GetDelegate() {
+ return delegate()->AsConfirmInfoBarDelegate();
+}
+
+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_);
+}
+
+// AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------
+
+InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
+ return new AlertInfoBar(this);
+}
+
+// ConfirmInfoBarDelegate, InfoBarDelegate overrides: --------------------------
+
+InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
+ return new ConfirmInfoBar(this);
+}
diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h
new file mode 100644
index 0000000..1e02f96
--- /dev/null
+++ b/chrome/browser/views/infobars/infobars.h
@@ -0,0 +1,138 @@
+// 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_VIEWS_INFOBARS_INFOBARS_H_
+#define CHROME_BROWSER_VIEWS_INFOBARS_INFOBARS_H_
+
+#include "chrome/browser/infobar_delegate.h"
+#include "chrome/views/base_button.h"
+#include "chrome/views/native_button.h"
+
+class InfoBarContainer;
+class SlideAnimation;
+namespace views {
+class Button;
+class ImageView;
+class Label;
+}
+
+// This file contains implementations for some general purpose InfoBars. See
+// chrome/browser/infobar_delegate.h for the delegate interface(s) that you must
+// implement to use these.
+
+class InfoBar : public views::View,
+ public views::BaseButton::ButtonListener,
+ public AnimationDelegate {
+ public:
+ explicit InfoBar(InfoBarDelegate* delegate);
+ virtual ~InfoBar();
+
+ InfoBarDelegate* delegate() const { return delegate_; }
+
+ void set_container(InfoBarContainer* container) { container_ = container; }
+
+ // Starts animating the InfoBar open.
+ void AnimateOpen();
+
+ // Opens the InfoBar immediately.
+ void Open();
+
+ // Starts animating the InfoBar closed. It will not be closed until the
+ // animation has completed, when |Close| will be called.
+ void AnimateClose();
+
+ // Closes the InfoBar immediately and removes it from its container. Notifies
+ // the delegate that it has closed. The InfoBar is deleted after this function
+ // is called.
+ void Close();
+
+ // Overridden from views::View:
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+
+ protected:
+ // Returns the available width of the View for use by child view layout,
+ // excluding the close button.
+ virtual int GetAvailableWidth() const;
+
+ private:
+ // Overridden from views::Button::ButtonListener:
+ virtual void ButtonPressed(views::BaseButton* sender);
+
+ // Overridden from AnimationDelegate:
+ virtual void AnimationProgressed(const Animation* animation);
+ virtual void AnimationEnded(const Animation* animation);
+
+ // The InfoBar's container
+ InfoBarContainer* container_;
+
+ // The InfoBar's delegate.
+ InfoBarDelegate* delegate_;
+
+ // The Close Button at the right edge of the InfoBar.
+ views::Button* close_button_;
+
+ // The animation that runs when the InfoBar is opened or closed.
+ scoped_ptr<SlideAnimation> animation_;
+
+ DISALLOW_COPY_AND_ASSIGN(InfoBar);
+};
+
+class AlertInfoBar : public InfoBar {
+ public:
+ explicit AlertInfoBar(AlertInfoBarDelegate* delegate);
+ virtual ~AlertInfoBar();
+
+ // Overridden from views::View:
+ virtual void Layout();
+
+ protected:
+ views::Label* label() const { return label_; }
+ views::ImageView* icon() const { return icon_; }
+
+ private:
+ AlertInfoBarDelegate* GetDelegate();
+
+ views::Label* label_;
+ views::ImageView* icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(AlertInfoBar);
+};
+
+class ConfirmInfoBar : public AlertInfoBar,
+ public views::NativeButton::Listener {
+ public:
+ explicit ConfirmInfoBar(ConfirmInfoBarDelegate* delegate);
+ virtual ~ConfirmInfoBar();
+
+ // Overridden from views::View:
+ virtual void Layout();
+
+ protected:
+ // Overridden from views::View:
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View* parent,
+ views::View* child);
+
+ // Overridden from views::NativeButton::Listener:
+ virtual void ButtonPressed(views::NativeButton* sender);
+
+ // Overridden from InfoBar:
+ virtual int GetAvailableWidth() const;
+
+ private:
+ void Init();
+
+ ConfirmInfoBarDelegate* GetDelegate();
+
+ views::NativeButton* ok_button_;
+ views::NativeButton* cancel_button_;
+
+ bool initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConfirmInfoBar);
+};
+
+
+#endif // #ifndef CHROME_BROWSER_VIEWS_INFOBARS_INFOBARS_H_
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index a8fe7db..60ba95b4 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -1338,13 +1338,13 @@ void WebContents::OnCrashedPlugin(const std::wstring& plugin_path) {
if (!product_name.empty())
plugin_name = product_name;
}
- view_->DisplayErrorInInfoBar(
- l10n_util::GetStringF(IDS_PLUGIN_CRASHED_PROMPT, plugin_name));
+ AddInfoBar(new SimpleAlertInfoBarDelegate(
+ l10n_util::GetStringF(IDS_PLUGIN_CRASHED_PROMPT, plugin_name), NULL));
}
void WebContents::OnJSOutOfMemory() {
- view_->DisplayErrorInInfoBar(
- l10n_util::GetString(IDS_JS_OUT_OF_MEMORY_PROMPT));
+ AddInfoBar(new SimpleAlertInfoBarDelegate(
+ l10n_util::GetString(IDS_JS_OUT_OF_MEMORY_PROMPT), NULL));
}
bool WebContents::CanBlur() const {
@@ -1477,7 +1477,7 @@ void WebContents::Observe(NotificationType type,
break;
}
default: {
- NOTREACHED();
+ TabContents::Observe(type, source, details);
break;
}
}
diff --git a/chrome/browser/web_contents.h b/chrome/browser/web_contents.h
index 71894de..75c5c689 100644
--- a/chrome/browser/web_contents.h
+++ b/chrome/browser/web_contents.h
@@ -30,7 +30,6 @@ class WebContents : public TabContents,
public RenderViewHostDelegate,
public RenderViewHostManager::Delegate,
public SelectFileDialog::Listener,
- public NotificationObserver,
public WebApp::Observer {
public:
// If instance is NULL, then creates a new process for this view. Otherwise
diff --git a/chrome/common/notification_types.h b/chrome/common/notification_types.h
index 53e0954..c748d36 100644
--- a/chrome/common/notification_types.h
+++ b/chrome/common/notification_types.h
@@ -200,15 +200,19 @@ enum NotificationType {
// No details are expected.
NOTIFY_WEB_CONTENTS_DISCONNECTED,
- // This message is sent when a new message is added to a WebContents. The
- // source is a Source<WebContents> with a pointer to the WebContents the
- // message was added to.
- NOTIFY_WEB_CONTENTS_MESSAGE_ADDED,
-
- // This message is sent when a message is removed from a WebContents. The
- // source is a Source<WebContents> with a pointer to the WebContents the
- // message was removed from.
- NOTIFY_WEB_CONTENTS_MESSAGE_REMOVED,
+ // 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
+ // 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.
+ NOTIFY_TAB_CONTENTS_INFOBAR_REMOVED,
// This is sent when an externally hosted tab is created. The details contain
// the ExternalTabContainer that contains the tab