Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(601)

Side by Side Diff: chrome/browser/infobars/infobar_tab_helper.cc

Issue 7810002: Move infobar handling to a tab helper. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/infobars/infobar_tab_helper.h"
6
7 #include "chrome/browser/tab_contents/infobar.h"
8 #include "chrome/browser/tab_contents/infobar_delegate.h"
9 #include "chrome/browser/tab_contents/insecure_content_infobar_delegate.h"
10 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
11 #include "chrome/common/chrome_notification_types.h"
12 #include "chrome/common/render_messages.h"
13 #include "content/common/notification_service.h"
14 #include "content/browser/tab_contents/tab_contents.h"
15
16 InfoBarTabHelper::InfoBarTabHelper(TabContentsWrapper* tab_contents)
17 : TabContentsObserver(tab_contents->tab_contents()),
18 infobars_enabled_(true),
19 tab_contents_wrapper_(tab_contents) {
20 DCHECK(tab_contents);
21 }
22
23 InfoBarTabHelper::~InfoBarTabHelper() {
24 // Destroy all remaining InfoBars. It's important to not animate here so that
25 // we guarantee that we'll delete all delegates before we do anything else.
26 //
27 // TODO(pkasting): If there is no InfoBarContainer, this leaks all the
28 // InfoBarDelegates. This will be fixed once we call CloseSoon() directly on
29 // Infobars.
30 RemoveAllInfoBars(false);
31 }
32
33 void InfoBarTabHelper::AddInfoBar(InfoBarDelegate* delegate) {
34 if (!infobars_enabled_) {
35 delegate->InfoBarClosed();
36 return;
37 }
38
39 for (size_t i = 0; i < infobars_.size(); ++i) {
40 if (GetInfoBarDelegateAt(i)->EqualsDelegate(delegate)) {
41 delegate->InfoBarClosed();
42 return;
43 }
44 }
45
46 infobars_.push_back(delegate);
47 NotificationService::current()->Notify(
48 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
49 Source<TabContentsWrapper>(tab_contents_wrapper_),
50 Details<InfoBarAddedDetails>(delegate));
51
52 // Add ourselves as an observer for navigations the first time a delegate is
53 // added. We use this notification to expire InfoBars that need to expire on
54 // page transitions.
55 if (infobars_.size() == 1) {
56 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
57 Source<NavigationController>(&tab_contents()->controller()));
58 }
59 }
60
61 void InfoBarTabHelper::RemoveInfoBar(InfoBarDelegate* delegate) {
62 RemoveInfoBarInternal(delegate, true);
63 }
64
65 void InfoBarTabHelper::ReplaceInfoBar(InfoBarDelegate* old_delegate,
66 InfoBarDelegate* new_delegate) {
67 if (!infobars_enabled_) {
68 AddInfoBar(new_delegate); // Deletes the delegate.
69 return;
70 }
71
72 size_t i;
73 for (i = 0; i < infobars_.size(); ++i) {
74 if (GetInfoBarDelegateAt(i) == old_delegate)
75 break;
76 }
77 DCHECK_LT(i, infobars_.size());
78
79 infobars_.insert(infobars_.begin() + i, new_delegate);
80
81 old_delegate->clear_owner();
82 InfoBarReplacedDetails replaced_details(old_delegate, new_delegate);
83 NotificationService::current()->Notify(
84 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REPLACED,
85 Source<TabContentsWrapper>(tab_contents_wrapper_),
86 Details<InfoBarReplacedDetails>(&replaced_details));
87
88 infobars_.erase(infobars_.begin() + i + 1);
89 }
90
91 InfoBarDelegate* InfoBarTabHelper::GetInfoBarDelegateAt(size_t index) {
92 return infobars_[index];
93 }
94
95 void InfoBarTabHelper::RemoveInfoBarInternal(InfoBarDelegate* delegate,
96 bool animate) {
97 if (!infobars_enabled_) {
98 DCHECK(infobars_.empty());
99 return;
100 }
101
102 size_t i;
103 for (i = 0; i < infobars_.size(); ++i) {
104 if (GetInfoBarDelegateAt(i) == delegate)
105 break;
106 }
107 DCHECK_LT(i, infobars_.size());
108 InfoBarDelegate* infobar = infobars_[i];
109
110 infobar->clear_owner();
111 InfoBarRemovedDetails removed_details(infobar, animate);
112 NotificationService::current()->Notify(
113 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
114 Source<TabContentsWrapper>(tab_contents_wrapper_),
115 Details<InfoBarRemovedDetails>(&removed_details));
116
117 infobars_.erase(infobars_.begin() + i);
118 // Remove ourselves as an observer if we are tracking no more InfoBars.
119 if (infobars_.empty()) {
120 registrar_.Remove(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
121 Source<NavigationController>(&tab_contents()->controller()));
122 }
123 }
124
125 void InfoBarTabHelper::RemoveAllInfoBars(bool animate) {
126 while (!infobars_.empty())
127 RemoveInfoBarInternal(GetInfoBarDelegateAt(infobar_count() - 1), animate);
128 }
129
130 void InfoBarTabHelper::OnDidBlockDisplayingInsecureContent() {
131 // At most one infobar and do not supersede the stronger running content bar.
132 for (size_t i = 0; i < infobars_.size(); ++i) {
133 if (GetInfoBarDelegateAt(i)->AsInsecureContentInfoBarDelegate())
134 return;
135 }
136 AddInfoBar(new InsecureContentInfoBarDelegate(tab_contents_wrapper_,
137 InsecureContentInfoBarDelegate::DISPLAY));
138 }
139
140 void InfoBarTabHelper::OnDidBlockRunningInsecureContent() {
141 // At most one infobar superseding any weaker displaying content bar.
142 for (size_t i = 0; i < infobars_.size(); ++i) {
143 InsecureContentInfoBarDelegate* delegate =
144 GetInfoBarDelegateAt(i)->AsInsecureContentInfoBarDelegate();
145 if (delegate) {
146 if (delegate->type() != InsecureContentInfoBarDelegate::RUN) {
147 ReplaceInfoBar(delegate, new InsecureContentInfoBarDelegate(
148 tab_contents_wrapper_,
149 InsecureContentInfoBarDelegate::RUN));
150 }
151 return;
152 }
153 }
154 AddInfoBar(new InsecureContentInfoBarDelegate(tab_contents_wrapper_,
155 InsecureContentInfoBarDelegate::RUN));
156 }
157
158 void InfoBarTabHelper::RenderViewGone() {
159 RemoveAllInfoBars(true);
160 }
161
162 bool InfoBarTabHelper::OnMessageReceived(const IPC::Message& message) {
163 bool handled = true;
164 IPC_BEGIN_MESSAGE_MAP(InfoBarTabHelper, message)
165 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockDisplayingInsecureContent,
166 OnDidBlockDisplayingInsecureContent)
167 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidBlockRunningInsecureContent,
168 OnDidBlockRunningInsecureContent)
169 IPC_MESSAGE_UNHANDLED(handled = false)
170 IPC_END_MESSAGE_MAP()
171 return handled;
172 }
173
174 void InfoBarTabHelper::Observe(int type,
175 const NotificationSource& source,
176 const NotificationDetails& details) {
177 switch (type) {
178 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
179 DCHECK(&tab_contents()->controller() ==
180 Source<NavigationController>(source).ptr());
181
182 content::LoadCommittedDetails& committed_details =
183 *(Details<content::LoadCommittedDetails>(details).ptr());
184
185 // NOTE: It is not safe to change the following code to count upwards or
186 // use iterators, as the RemoveInfoBar() call synchronously modifies our
187 // delegate list.
188 for (size_t i = infobars_.size(); i > 0; --i) {
189 InfoBarDelegate* delegate = GetInfoBarDelegateAt(i - 1);
190 if (delegate->ShouldExpire(committed_details))
191 RemoveInfoBar(delegate);
192 }
193
194 break;
195 }
196 default:
197 NOTREACHED();
198 }
199 }
OLDNEW
« no previous file with comments | « chrome/browser/infobars/infobar_tab_helper.h ('k') | chrome/browser/notifications/desktop_notification_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698