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

Side by Side Diff: chrome/browser/sidebar/sidebar_manager.cc

Issue 9006027: Rip Out the Sidebar API (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years 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/sidebar/sidebar_manager.h"
6
7 #include <vector>
8
9 #include "base/command_line.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/extensions/extension_sidebar_api.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sidebar/sidebar_container.h"
14 #include "chrome/common/chrome_notification_types.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "content/browser/tab_contents/tab_contents.h"
17 #include "content/public/browser/notification_service.h"
18 #include "googleurl/src/gurl.h"
19
20 struct SidebarManager::SidebarStateForTab {
21 // Sidebars linked to this tab.
22 ContentIdToSidebarHostMap content_id_to_sidebar_host;
23 // Content id of the currently active (expanded and visible) sidebar.
24 std::string active_content_id;
25 };
26
27 // static
28 SidebarManager* SidebarManager::GetInstance() {
29 return g_browser_process->sidebar_manager();
30 }
31
32 // static
33 bool SidebarManager::IsSidebarAllowed() {
34 return CommandLine::ForCurrentProcess()->HasSwitch(
35 switches::kEnableExperimentalExtensionApis);
36 }
37
38 SidebarManager::SidebarManager() {
39 }
40
41 SidebarContainer* SidebarManager::GetActiveSidebarContainerFor(
42 TabContents* tab) {
43 TabToSidebarHostMap::iterator it = tab_to_sidebar_host_.find(tab);
44 if (it == tab_to_sidebar_host_.end())
45 return NULL;
46 if (it->second.active_content_id.empty())
47 return NULL;
48 ContentIdToSidebarHostMap::iterator host_it =
49 it->second.content_id_to_sidebar_host.find(it->second.active_content_id);
50 DCHECK(host_it != it->second.content_id_to_sidebar_host.end());
51 return host_it->second;
52 }
53
54 SidebarContainer* SidebarManager::GetSidebarContainerFor(
55 TabContents* tab, const std::string& content_id) {
56 DCHECK(!content_id.empty());
57 TabToSidebarHostMap::iterator it = tab_to_sidebar_host_.find(tab);
58 if (it == tab_to_sidebar_host_.end())
59 return NULL;
60 ContentIdToSidebarHostMap::iterator host_it =
61 it->second.content_id_to_sidebar_host.find(content_id);
62 if (host_it == it->second.content_id_to_sidebar_host.end())
63 return NULL;
64 return host_it->second;
65 }
66
67 TabContents* SidebarManager::GetSidebarTabContents(
68 TabContents* tab, const std::string& content_id) {
69 DCHECK(!content_id.empty());
70 SidebarContainer* sidebar_host = GetSidebarContainerFor(tab, content_id);
71 if (!sidebar_host)
72 return NULL;
73 return sidebar_host->sidebar_contents();
74 }
75
76 void SidebarManager::NotifyStateChanges(
77 TabContents* was_active_sidebar_contents,
78 TabContents* active_sidebar_contents) {
79 if (was_active_sidebar_contents == active_sidebar_contents)
80 return;
81
82 SidebarContainer* was_active_host =
83 was_active_sidebar_contents == NULL ? NULL :
84 FindSidebarContainerFor(was_active_sidebar_contents);
85 SidebarContainer* active_host =
86 active_sidebar_contents == NULL ? NULL :
87 FindSidebarContainerFor(active_sidebar_contents);
88
89 if (was_active_host != NULL) {
90 Profile* profile = Profile::FromBrowserContext(
91 was_active_sidebar_contents->browser_context());
92 ExtensionSidebarEventRouter::OnStateChanged(
93 profile,
94 was_active_host->tab_contents(),
95 was_active_host->content_id(),
96 extension_sidebar_constants::kShownState);
97 }
98
99 if (active_host != NULL) {
100 Profile* profile = Profile::FromBrowserContext(
101 active_sidebar_contents->browser_context());
102 ExtensionSidebarEventRouter::OnStateChanged(
103 profile,
104 active_host->tab_contents(),
105 active_host->content_id(),
106 extension_sidebar_constants::kActiveState);
107 }
108 }
109
110 void SidebarManager::ShowSidebar(TabContents* tab,
111 const std::string& content_id) {
112 DCHECK(!content_id.empty());
113 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
114 if (!host) {
115 host = new SidebarContainer(tab, content_id, this);
116 RegisterSidebarContainerFor(tab, host);
117 // It might trigger UpdateSidebar notification, so load them after
118 // the registration.
119 host->LoadDefaults();
120 }
121
122 host->Show();
123
124 Profile* profile = Profile::FromBrowserContext(tab->browser_context());
125 ExtensionSidebarEventRouter::OnStateChanged(
126 profile, tab, content_id,
127 extension_sidebar_constants::kShownState);
128 }
129
130 void SidebarManager::ExpandSidebar(TabContents* tab,
131 const std::string& content_id) {
132 DCHECK(!content_id.empty());
133 TabToSidebarHostMap::iterator it = tab_to_sidebar_host_.find(tab);
134 if (it == tab_to_sidebar_host_.end())
135 return;
136 // If it's already active, bail out.
137 if (it->second.active_content_id == content_id)
138 return;
139
140 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
141 DCHECK(host);
142 if (!host)
143 return;
144 it->second.active_content_id = content_id;
145
146 host->Expand();
147 }
148
149 void SidebarManager::CollapseSidebar(TabContents* tab,
150 const std::string& content_id) {
151 DCHECK(!content_id.empty());
152 TabToSidebarHostMap::iterator it = tab_to_sidebar_host_.find(tab);
153 if (it == tab_to_sidebar_host_.end())
154 return;
155 // If it's not the one active now, bail out.
156 if (it->second.active_content_id != content_id)
157 return;
158
159 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
160 DCHECK(host);
161 if (!host)
162 return;
163 it->second.active_content_id.clear();
164
165 host->Collapse();
166 }
167
168 void SidebarManager::HideSidebar(TabContents* tab,
169 const std::string& content_id) {
170 DCHECK(!content_id.empty());
171 TabToSidebarHostMap::iterator it = tab_to_sidebar_host_.find(tab);
172 if (it == tab_to_sidebar_host_.end())
173 return;
174 if (it->second.active_content_id == content_id)
175 it->second.active_content_id.clear();
176
177 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
178 DCHECK(host);
179
180 UnregisterSidebarContainerFor(tab, content_id);
181
182 Profile* profile = Profile::FromBrowserContext(tab->browser_context());
183 ExtensionSidebarEventRouter::OnStateChanged(
184 profile, tab, content_id,
185 extension_sidebar_constants::kHiddenState);
186 }
187
188 void SidebarManager::NavigateSidebar(TabContents* tab,
189 const std::string& content_id,
190 const GURL& url) {
191 DCHECK(!content_id.empty());
192 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
193 if (!host)
194 return;
195
196 host->Navigate(url);
197 }
198
199 void SidebarManager::SetSidebarBadgeText(
200 TabContents* tab, const std::string& content_id,
201 const string16& badge_text) {
202 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
203 if (!host)
204 return;
205 host->SetBadgeText(badge_text);
206 }
207
208 void SidebarManager::SetSidebarIcon(
209 TabContents* tab, const std::string& content_id,
210 const SkBitmap& bitmap) {
211 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
212 if (!host)
213 return;
214 host->SetIcon(bitmap);
215 }
216
217 void SidebarManager::SetSidebarTitle(
218 TabContents* tab, const std::string& content_id,
219 const string16& title) {
220 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
221 if (!host)
222 return;
223 host->SetTitle(title);
224 }
225
226 SidebarManager::~SidebarManager() {
227 DCHECK(tab_to_sidebar_host_.empty());
228 DCHECK(sidebar_host_to_tab_.empty());
229 }
230
231 void SidebarManager::Observe(int type,
232 const content::NotificationSource& source,
233 const content::NotificationDetails& details) {
234 if (type == content::NOTIFICATION_TAB_CONTENTS_DESTROYED) {
235 HideAllSidebars(content::Source<TabContents>(source).ptr());
236 } else {
237 NOTREACHED() << "Got a notification we didn't register for!";
238 }
239 }
240
241 void SidebarManager::UpdateSidebar(SidebarContainer* host) {
242 content::NotificationService::current()->Notify(
243 chrome::NOTIFICATION_SIDEBAR_CHANGED,
244 content::Source<SidebarManager>(this),
245 content::Details<SidebarContainer>(host));
246 }
247
248 void SidebarManager::HideAllSidebars(TabContents* tab) {
249 TabToSidebarHostMap::iterator tab_it = tab_to_sidebar_host_.find(tab);
250 if (tab_it == tab_to_sidebar_host_.end())
251 return;
252 const ContentIdToSidebarHostMap& hosts =
253 tab_it->second.content_id_to_sidebar_host;
254
255 std::vector<std::string> content_ids;
256 for (ContentIdToSidebarHostMap::const_iterator it = hosts.begin();
257 it != hosts.end(); ++it) {
258 content_ids.push_back(it->first);
259 }
260
261 for (std::vector<std::string>::iterator it = content_ids.begin();
262 it != content_ids.end(); ++it) {
263 HideSidebar(tab, *it);
264 }
265 }
266
267 SidebarContainer* SidebarManager::FindSidebarContainerFor(
268 TabContents* sidebar_contents) {
269 for (SidebarHostToTabMap::iterator it = sidebar_host_to_tab_.begin();
270 it != sidebar_host_to_tab_.end();
271 ++it) {
272 if (sidebar_contents == it->first->sidebar_contents())
273 return it->first;
274 }
275 return NULL;
276 }
277
278 void SidebarManager::RegisterSidebarContainerFor(
279 TabContents* tab, SidebarContainer* sidebar_host) {
280 DCHECK(!GetSidebarContainerFor(tab, sidebar_host->content_id()));
281
282 // If it's a first sidebar for this tab, register destroy notification.
283 if (tab_to_sidebar_host_.find(tab) == tab_to_sidebar_host_.end()) {
284 registrar_.Add(this,
285 content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
286 content::Source<TabContents>(tab));
287 }
288
289 BindSidebarHost(tab, sidebar_host);
290 }
291
292 void SidebarManager::UnregisterSidebarContainerFor(
293 TabContents* tab, const std::string& content_id) {
294 SidebarContainer* host = GetSidebarContainerFor(tab, content_id);
295 DCHECK(host);
296 if (!host)
297 return;
298
299 UnbindSidebarHost(tab, host);
300
301 // If there's no more sidebars linked to this tab, unsubscribe.
302 if (tab_to_sidebar_host_.find(tab) == tab_to_sidebar_host_.end()) {
303 registrar_.Remove(this,
304 content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
305 content::Source<TabContents>(tab));
306 }
307
308 // Issue tab closing event post unbound.
309 host->SidebarClosing();
310 // Destroy sidebar container.
311 delete host;
312 }
313
314 void SidebarManager::BindSidebarHost(TabContents* tab,
315 SidebarContainer* sidebar_host) {
316 const std::string& content_id = sidebar_host->content_id();
317
318 DCHECK(GetSidebarContainerFor(tab, content_id) == NULL);
319 DCHECK(sidebar_host_to_tab_.find(sidebar_host) ==
320 sidebar_host_to_tab_.end());
321
322 tab_to_sidebar_host_[tab].content_id_to_sidebar_host[content_id] =
323 sidebar_host;
324 sidebar_host_to_tab_[sidebar_host] = tab;
325 }
326
327 void SidebarManager::UnbindSidebarHost(TabContents* tab,
328 SidebarContainer* sidebar_host) {
329 const std::string& content_id = sidebar_host->content_id();
330
331 DCHECK(GetSidebarContainerFor(tab, content_id) == sidebar_host);
332 DCHECK(sidebar_host_to_tab_.find(sidebar_host)->second == tab);
333 DCHECK(tab_to_sidebar_host_[tab].active_content_id != content_id);
334
335 tab_to_sidebar_host_[tab].content_id_to_sidebar_host.erase(content_id);
336 if (tab_to_sidebar_host_[tab].content_id_to_sidebar_host.empty())
337 tab_to_sidebar_host_.erase(tab);
338 sidebar_host_to_tab_.erase(sidebar_host);
339 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698