forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
infobar_manager.cc
127 lines (101 loc) · 4.07 KB
/
infobar_manager.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2014 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/infobars/infobar_manager.h"
#include "base/command_line.h"
#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_delegate.h"
#include "chrome/common/chrome_switches.h"
InfoBar* InfoBarManager::AddInfoBar(scoped_ptr<InfoBar> infobar) {
DCHECK(infobar);
if (!infobars_enabled_)
return NULL;
for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end();
++i) {
if ((*i)->delegate()->EqualsDelegate(infobar->delegate())) {
DCHECK_NE((*i)->delegate(), infobar->delegate());
return NULL;
}
}
InfoBar* infobar_ptr = infobar.release();
infobars_.push_back(infobar_ptr);
infobar_ptr->SetOwner(this);
FOR_EACH_OBSERVER(Observer, observer_list_, OnInfoBarAdded(infobar_ptr));
return infobar_ptr;
}
void InfoBarManager::RemoveInfoBar(InfoBar* infobar) {
RemoveInfoBarInternal(infobar, true);
}
void InfoBarManager::RemoveAllInfoBars(bool animate) {
while (!infobars_.empty())
RemoveInfoBarInternal(infobars_.back(), animate);
}
InfoBar* InfoBarManager::ReplaceInfoBar(InfoBar* old_infobar,
scoped_ptr<InfoBar> new_infobar) {
DCHECK(old_infobar);
if (!infobars_enabled_)
return AddInfoBar(new_infobar.Pass()); // Deletes the infobar.
DCHECK(new_infobar);
InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
old_infobar));
DCHECK(i != infobars_.end());
InfoBar* new_infobar_ptr = new_infobar.release();
i = infobars_.insert(i, new_infobar_ptr);
new_infobar_ptr->SetOwner(this);
// Remove the old infobar before notifying, so that if any observers call back
// to AddInfoBar() or similar, we don't dupe-check against this infobar.
infobars_.erase(++i);
FOR_EACH_OBSERVER(Observer,
observer_list_,
OnInfoBarReplaced(old_infobar, new_infobar_ptr));
old_infobar->CloseSoon();
return new_infobar_ptr;
}
void InfoBarManager::AddObserver(Observer* obs) {
observer_list_.AddObserver(obs);
}
void InfoBarManager::RemoveObserver(Observer* obs) {
observer_list_.RemoveObserver(obs);
}
InfoBarManager::InfoBarManager(content::WebContents* web_contents)
: infobars_enabled_(true),
web_contents_(web_contents) {
DCHECK(web_contents);
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableInfoBars))
infobars_enabled_ = false;
}
InfoBarManager::~InfoBarManager() {
// Destroy all remaining InfoBars. It's important to not animate here so that
// we guarantee that we'll delete all delegates before we do anything else.
RemoveAllInfoBars(false);
FOR_EACH_OBSERVER(Observer, observer_list_, OnManagerShuttingDown(this));
}
void InfoBarManager::OnNavigation(
const content::LoadCommittedDetails& load_details) {
// NOTE: It is not safe to change the following code to count upwards or
// use iterators, as the RemoveInfoBar() call synchronously modifies our
// delegate list.
for (size_t i = infobars_.size(); i > 0; --i) {
InfoBar* infobar = infobars_[i - 1];
if (infobar->delegate()->ShouldExpire(load_details))
RemoveInfoBar(infobar);
}
}
void InfoBarManager::OnWebContentsDestroyed() { web_contents_ = NULL; }
void InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) {
DCHECK(infobar);
if (!infobars_enabled_) {
DCHECK(infobars_.empty());
return;
}
InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
DCHECK(i != infobars_.end());
// Remove the infobar before notifying, so that if any observers call back to
// AddInfoBar() or similar, we don't dupe-check against this infobar.
infobars_.erase(i);
// This notification must happen before the call to CloseSoon() below, since
// observers may want to access |infobar| and that call can delete it.
FOR_EACH_OBSERVER(Observer, observer_list_,
OnInfoBarRemoved(infobar, animate));
infobar->CloseSoon();
}