Index: chrome/browser/ui/views/infobars/infobars.cc |
=================================================================== |
--- chrome/browser/ui/views/infobars/infobars.cc (revision 65711) |
+++ chrome/browser/ui/views/infobars/infobars.cc (working copy) |
@@ -143,11 +143,10 @@ |
void InfoBar::ViewHierarchyChanged(bool is_add, views::View* parent, |
views::View* child) { |
if (child == this) { |
- if (is_add) { |
+ if (is_add) |
InfoBarAdded(); |
- } else { |
+ else |
InfoBarRemoved(); |
- } |
} |
if (GetWidget() && GetWidget()->IsAccessibleWidget()) { |
@@ -188,9 +187,8 @@ |
// InfoBar, views::ButtonListener implementation: ------------------ |
void InfoBar::ButtonPressed(views::Button* sender, const views::Event& event) { |
- if (sender == close_button_) { |
- if (delegate_) |
- delegate_->InfoBarDismissed(); |
+ if ((sender == close_button_) && delegate_) { |
+ delegate_->InfoBarDismissed(); |
RemoveInfoBar(); |
} |
} |
@@ -216,7 +214,6 @@ |
void InfoBar::AnimationEnded(const Animation* animation) { |
if (container_) { |
container_->InfoBarAnimated(false); |
- |
if (!animation_->IsShowing()) |
Close(); |
} |
@@ -237,6 +234,7 @@ |
} |
void InfoBar::AnimateClose() { |
+ delegate_ = NULL; |
bool restore_focus = true; |
#if defined(OS_WIN) |
// Do not restore focus (and active state with it) on Windows if some other |
@@ -251,14 +249,8 @@ |
} |
void InfoBar::Close() { |
+ delegate_ = NULL; |
GetParent()->RemoveChildView(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; |
- } |
} |
void InfoBar::InfoBarAdded() { |
@@ -402,10 +394,9 @@ |
void LinkInfoBar::LinkActivated(views::Link* source, int event_flags) { |
DCHECK(source == link_); |
- if (GetDelegate()->LinkClicked( |
- event_utils::DispositionFromEventFlags(event_flags))) { |
+ if (delegate() && GetDelegate()->LinkClicked( |
+ event_utils::DispositionFromEventFlags(event_flags))) |
RemoveInfoBar(); |
- } |
} |
// LinkInfoBar, views::View overrides: ----------------------------------------- |
@@ -461,6 +452,7 @@ |
ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) |
: AlertInfoBar(delegate), |
+ cached_buttons_(delegate->GetButtons()), |
ok_button_(NULL), |
cancel_button_(NULL), |
link_(NULL), |
@@ -502,10 +494,9 @@ |
DCHECK(source == link_); |
DCHECK(link_->IsVisible()); |
DCHECK(!link_->GetText().empty()); |
- if (GetDelegate()->LinkClicked( |
- event_utils::DispositionFromEventFlags(event_flags))) { |
+ if (delegate() && GetDelegate()->LinkClicked( |
+ event_utils::DispositionFromEventFlags(event_flags))) |
RemoveInfoBar(); |
- } |
} |
// ConfirmInfoBar, views::View overrides: -------------------------------------- |
@@ -524,16 +515,18 @@ |
gfx::Size ok_ps = ok_button_->GetPreferredSize(); |
gfx::Size cancel_ps = cancel_button_->GetPreferredSize(); |
- if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_OK) { |
+ // Cache the button set so that once the delegate goes away we can still |
+ // Layout() (e.g. in the case of AnimateClose()). |
+ if (delegate()) |
+ cached_buttons_ = GetDelegate()->GetButtons(); |
+ if (cached_buttons_ & ConfirmInfoBarDelegate::BUTTON_OK) |
ok_button_width = ok_ps.width(); |
- } else { |
+ else |
ok_button_->SetVisible(false); |
- } |
- if (GetDelegate()->GetButtons() & ConfirmInfoBarDelegate::BUTTON_CANCEL) { |
+ if (cached_buttons_ & ConfirmInfoBarDelegate::BUTTON_CANCEL) |
cancel_button_width = cancel_ps.width(); |
- } else { |
+ else |
cancel_button_->SetVisible(false); |
- } |
cancel_button_->SetBounds(available_width - cancel_button_width, |
OffsetY(this, cancel_ps), cancel_ps.width(), |
@@ -565,9 +558,11 @@ |
// ConfirmInfoBar, views::ButtonListener implementation: --------------- |
-void ConfirmInfoBar::ButtonPressed( |
- views::Button* sender, const views::Event& event) { |
+void ConfirmInfoBar::ButtonPressed(views::Button* sender, |
+ const views::Event& event) { |
InfoBar::ButtonPressed(sender, event); |
+ if (!GetDelegate()) |
+ return; |
if (sender == ok_button_) { |
if (GetDelegate()->Accept()) |
RemoveInfoBar(); |