Index: chrome/browser/tab_contents.cc |
=================================================================== |
--- chrome/browser/tab_contents.cc (revision 5722) |
+++ chrome/browser/tab_contents.cc (working copy) |
@@ -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 @@ |
::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 @@ |
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 @@ |
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); |
+ } |
+ } |
+} |