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

Side by Side Diff: chrome/browser/ui/tabs/tab_strip_model.cc

Issue 10537062: TabContentsWrapper -> TabContents, part 13. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fiz Created 8 years, 6 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/tabs/tab_strip_model.h" 5 #include "chrome/browser/ui/tabs/tab_strip_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "chrome/app/chrome_command_ids.h" 14 #include "chrome/app/chrome_command_ids.h"
15 #include "chrome/browser/bookmarks/bookmark_model.h" 15 #include "chrome/browser/bookmarks/bookmark_model.h"
16 #include "chrome/browser/browser_shutdown.h" 16 #include "chrome/browser/browser_shutdown.h"
17 #include "chrome/browser/defaults.h" 17 #include "chrome/browser/defaults.h"
18 #include "chrome/browser/extensions/extension_service.h" 18 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/extensions/extension_tab_helper.h" 19 #include "chrome/browser/extensions/extension_tab_helper.h"
20 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/sessions/tab_restore_service.h" 21 #include "chrome/browser/sessions/tab_restore_service.h"
22 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 22 #include "chrome/browser/ui/tab_contents/tab_contents.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h" 24 #include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h"
25 #include "chrome/common/chrome_notification_types.h" 25 #include "chrome/common/chrome_notification_types.h"
26 #include "chrome/common/extensions/extension.h" 26 #include "chrome/common/extensions/extension.h"
27 #include "chrome/common/url_constants.h" 27 #include "chrome/common/url_constants.h"
28 #include "content/public/browser/navigation_controller.h" 28 #include "content/public/browser/navigation_controller.h"
29 #include "content/public/browser/navigation_entry.h" 29 #include "content/public/browser/navigation_entry.h"
30 #include "content/public/browser/notification_service.h" 30 #include "content/public/browser/notification_service.h"
31 #include "content/public/browser/render_process_host.h" 31 #include "content/public/browser/render_process_host.h"
32 #include "content/public/browser/user_metrics.h" 32 #include "content/public/browser/user_metrics.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 105 }
106 106
107 bool TabStripModel::HasObserver(TabStripModelObserver* observer) { 107 bool TabStripModel::HasObserver(TabStripModelObserver* observer) {
108 return observers_.HasObserver(observer); 108 return observers_.HasObserver(observer);
109 } 109 }
110 110
111 bool TabStripModel::ContainsIndex(int index) const { 111 bool TabStripModel::ContainsIndex(int index) const {
112 return index >= 0 && index < count(); 112 return index >= 0 && index < count();
113 } 113 }
114 114
115 void TabStripModel::AppendTabContents(TabContentsWrapper* contents, 115 void TabStripModel::AppendTabContents(TabContents* contents,
116 bool foreground) { 116 bool foreground) {
117 int index = order_controller_->DetermineInsertionIndexForAppending(); 117 int index = order_controller_->DetermineInsertionIndexForAppending();
118 InsertTabContentsAt(index, contents, 118 InsertTabContentsAt(index, contents,
119 foreground ? (ADD_INHERIT_GROUP | ADD_ACTIVE) : 119 foreground ? (ADD_INHERIT_GROUP | ADD_ACTIVE) :
120 ADD_NONE); 120 ADD_NONE);
121 } 121 }
122 122
123 void TabStripModel::InsertTabContentsAt(int index, 123 void TabStripModel::InsertTabContentsAt(int index,
124 TabContentsWrapper* contents, 124 TabContents* contents,
125 int add_types) { 125 int add_types) {
126 bool active = add_types & ADD_ACTIVE; 126 bool active = add_types & ADD_ACTIVE;
127 // Force app tabs to be pinned. 127 // Force app tabs to be pinned.
128 bool pin = 128 bool pin =
129 contents->extension_tab_helper()->is_app() || add_types & ADD_PINNED; 129 contents->extension_tab_helper()->is_app() || add_types & ADD_PINNED;
130 index = ConstrainInsertionIndex(index, pin); 130 index = ConstrainInsertionIndex(index, pin);
131 131
132 // In tab dragging situations, if the last tab in the window was detached 132 // In tab dragging situations, if the last tab in the window was detached
133 // then the user aborted the drag, we will have the |closing_all_| member 133 // then the user aborted the drag, we will have the |closing_all_| member
134 // set (see DetachTabContentsAt) which will mess with our mojo here. We need 134 // set (see DetachTabContentsAt) which will mess with our mojo here. We need
135 // to clear this bit. 135 // to clear this bit.
136 closing_all_ = false; 136 closing_all_ = false;
137 137
138 // Have to get the active contents before we monkey with |contents_| 138 // Have to get the active contents before we monkey with |contents_|
139 // otherwise we run into problems when we try to change the active contents 139 // otherwise we run into problems when we try to change the active contents
140 // since the old contents and the new contents will be the same... 140 // since the old contents and the new contents will be the same...
141 TabContentsWrapper* selected_contents = GetActiveTabContents(); 141 TabContents* selected_contents = GetActiveTabContents();
142 TabContentsData* data = new TabContentsData(contents); 142 TabContentsData* data = new TabContentsData(contents);
143 data->pinned = pin; 143 data->pinned = pin;
144 if ((add_types & ADD_INHERIT_GROUP) && selected_contents) { 144 if ((add_types & ADD_INHERIT_GROUP) && selected_contents) {
145 if (active) { 145 if (active) {
146 // Forget any existing relationships, we don't want to make things too 146 // Forget any existing relationships, we don't want to make things too
147 // confusing by having multiple groups active at the same time. 147 // confusing by having multiple groups active at the same time.
148 ForgetAllOpeners(); 148 ForgetAllOpeners();
149 } 149 }
150 // Anything opened by a link we deem to have an opener. 150 // Anything opened by a link we deem to have an opener.
151 data->SetGroup(&selected_contents->web_contents()->GetController()); 151 data->SetGroup(&selected_contents->web_contents()->GetController());
(...skipping 13 matching lines...) Expand all
165 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 165 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
166 TabInsertedAt(contents, index, active)); 166 TabInsertedAt(contents, index, active));
167 if (active) { 167 if (active) {
168 TabStripSelectionModel new_model; 168 TabStripSelectionModel new_model;
169 new_model.Copy(selection_model_); 169 new_model.Copy(selection_model_);
170 new_model.SetSelectedIndex(index); 170 new_model.SetSelectedIndex(index);
171 SetSelection(new_model, NOTIFY_DEFAULT); 171 SetSelection(new_model, NOTIFY_DEFAULT);
172 } 172 }
173 } 173 }
174 174
175 TabContentsWrapper* TabStripModel::ReplaceTabContentsAt( 175 TabContents* TabStripModel::ReplaceTabContentsAt(int index,
176 int index, 176 TabContents* new_contents) {
177 TabContentsWrapper* new_contents) {
178 DCHECK(ContainsIndex(index)); 177 DCHECK(ContainsIndex(index));
179 TabContentsWrapper* old_contents = GetContentsAt(index); 178 TabContents* old_contents = GetContentsAt(index);
180 179
181 ForgetOpenersAndGroupsReferencing( 180 ForgetOpenersAndGroupsReferencing(
182 &(old_contents->web_contents()->GetController())); 181 &(old_contents->web_contents()->GetController()));
183 182
184 contents_data_[index]->contents = new_contents; 183 contents_data_[index]->contents = new_contents;
185 184
186 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 185 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
187 TabReplacedAt(this, old_contents, new_contents, index)); 186 TabReplacedAt(this, old_contents, new_contents, index));
188 187
189 // When the active tab contents is replaced send out selected notification 188 // When the active tab contents is replaced send out selected notification
190 // too. We do this as nearly all observers need to treat a replace of the 189 // too. We do this as nearly all observers need to treat a replace of the
191 // selected contents as selection changing. 190 // selected contents as selection changing.
192 if (active_index() == index) { 191 if (active_index() == index) {
193 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 192 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
194 ActiveTabChanged(old_contents, new_contents, 193 ActiveTabChanged(old_contents, new_contents,
195 active_index(), false)); 194 active_index(), false));
196 } 195 }
197 return old_contents; 196 return old_contents;
198 } 197 }
199 198
200 void TabStripModel::ReplaceNavigationControllerAt( 199 void TabStripModel::ReplaceNavigationControllerAt(
201 int index, TabContentsWrapper* contents) { 200 int index, TabContents* contents) {
202 // This appears to be OK with no flicker since no redraw event 201 // This appears to be OK with no flicker since no redraw event
203 // occurs between the call to add an additional tab and one to close 202 // occurs between the call to add an additional tab and one to close
204 // the previous tab. 203 // the previous tab.
205 InsertTabContentsAt(index + 1, contents, ADD_ACTIVE | ADD_INHERIT_GROUP); 204 InsertTabContentsAt(index + 1, contents, ADD_ACTIVE | ADD_INHERIT_GROUP);
206 std::vector<int> closing_tabs; 205 std::vector<int> closing_tabs;
207 closing_tabs.push_back(index); 206 closing_tabs.push_back(index);
208 InternalCloseTabs(closing_tabs, CLOSE_NONE); 207 InternalCloseTabs(closing_tabs, CLOSE_NONE);
209 } 208 }
210 209
211 TabContentsWrapper* TabStripModel::DiscardTabContentsAt(int index) { 210 TabContents* TabStripModel::DiscardTabContentsAt(int index) {
212 DCHECK(ContainsIndex(index)); 211 DCHECK(ContainsIndex(index));
213 TabContentsWrapper* null_contents = 212 TabContents* null_contents = new TabContents(
214 new TabContentsWrapper( 213 WebContents::Create(profile(),
215 WebContents::Create(profile(), 214 NULL /* site_instance */,
216 NULL /* site_instance */, 215 MSG_ROUTING_NONE,
217 MSG_ROUTING_NONE, 216 NULL /* base_tab_contents */,
218 NULL /* base_tab_contents */, 217 NULL /* session_storage_namespace */));
219 NULL /* session_storage_namespace */)); 218 TabContents* old_contents = GetContentsAt(index);
220 TabContentsWrapper* old_contents = GetContentsAt(index);
221 // Copy over the state from the navigation controller so we preserve the 219 // Copy over the state from the navigation controller so we preserve the
222 // back/forward history and continue to display the correct title/favicon. 220 // back/forward history and continue to display the correct title/favicon.
223 null_contents->web_contents()->GetController().CopyStateFrom( 221 null_contents->web_contents()->GetController().CopyStateFrom(
224 old_contents->web_contents()->GetController()); 222 old_contents->web_contents()->GetController());
225 // Replace the tab we're discarding with the null version. 223 // Replace the tab we're discarding with the null version.
226 ReplaceTabContentsAt(index, null_contents); 224 ReplaceTabContentsAt(index, null_contents);
227 // Mark the tab so it will reload when we click. 225 // Mark the tab so it will reload when we click.
228 contents_data_[index]->discarded = true; 226 contents_data_[index]->discarded = true;
229 // Discard the old tab's renderer. 227 // Discard the old tab's renderer.
230 // TODO(jamescook): This breaks script connections with other tabs. 228 // TODO(jamescook): This breaks script connections with other tabs.
231 // We need to find a different approach that doesn't do that, perhaps based 229 // We need to find a different approach that doesn't do that, perhaps based
232 // on navigation to swappedout://. 230 // on navigation to swappedout://.
233 delete old_contents; 231 delete old_contents;
234 return null_contents; 232 return null_contents;
235 } 233 }
236 234
237 TabContentsWrapper* TabStripModel::DetachTabContentsAt(int index) { 235 TabContents* TabStripModel::DetachTabContentsAt(int index) {
238 if (contents_data_.empty()) 236 if (contents_data_.empty())
239 return NULL; 237 return NULL;
240 238
241 DCHECK(ContainsIndex(index)); 239 DCHECK(ContainsIndex(index));
242 240
243 TabContentsWrapper* removed_contents = GetContentsAt(index); 241 TabContents* removed_contents = GetContentsAt(index);
244 bool was_selected = IsTabSelected(index); 242 bool was_selected = IsTabSelected(index);
245 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index); 243 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index);
246 delete contents_data_[index]; 244 delete contents_data_[index];
247 contents_data_.erase(contents_data_.begin() + index); 245 contents_data_.erase(contents_data_.begin() + index);
248 ForgetOpenersAndGroupsReferencing( 246 ForgetOpenersAndGroupsReferencing(
249 &(removed_contents->web_contents()->GetController())); 247 &(removed_contents->web_contents()->GetController()));
250 if (empty()) 248 if (empty())
251 closing_all_ = true; 249 closing_all_ = true;
252 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 250 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
253 TabDetachedAt(removed_contents, index)); 251 TabDetachedAt(removed_contents, index));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 346 }
349 if (selected_mini_count == selected_count) 347 if (selected_mini_count == selected_count)
350 return; 348 return;
351 349
352 // Then move the non-pinned tabs. 350 // Then move the non-pinned tabs.
353 MoveSelectedTabsToImpl(std::max(index, total_mini_count), 351 MoveSelectedTabsToImpl(std::max(index, total_mini_count),
354 selected_mini_count, 352 selected_mini_count,
355 selected_count - selected_mini_count); 353 selected_count - selected_mini_count);
356 } 354 }
357 355
358 TabContentsWrapper* TabStripModel::GetActiveTabContents() const { 356 TabContents* TabStripModel::GetActiveTabContents() const {
359 return GetTabContentsAt(active_index()); 357 return GetTabContentsAt(active_index());
360 } 358 }
361 359
362 TabContentsWrapper* TabStripModel::GetTabContentsAt(int index) const { 360 TabContents* TabStripModel::GetTabContentsAt(int index) const {
363 if (ContainsIndex(index)) 361 if (ContainsIndex(index))
364 return GetContentsAt(index); 362 return GetContentsAt(index);
365 return NULL; 363 return NULL;
366 } 364 }
367 365
368 int TabStripModel::GetIndexOfTabContents( 366 int TabStripModel::GetIndexOfTabContents(const TabContents* contents) const {
369 const TabContentsWrapper* contents) const {
370 int index = 0; 367 int index = 0;
371 TabContentsDataVector::const_iterator iter = contents_data_.begin(); 368 TabContentsDataVector::const_iterator iter = contents_data_.begin();
372 for (; iter != contents_data_.end(); ++iter, ++index) { 369 for (; iter != contents_data_.end(); ++iter, ++index) {
373 if ((*iter)->contents == contents) 370 if ((*iter)->contents == contents)
374 return index; 371 return index;
375 } 372 }
376 return kNoTab; 373 return kNoTab;
377 } 374 }
378 375
379 int TabStripModel::GetWrapperIndex(const WebContents* contents) const { 376 int TabStripModel::GetIndexOfWebContents(const WebContents* contents) const {
380 int index = 0; 377 int index = 0;
381 TabContentsDataVector::const_iterator iter = contents_data_.begin(); 378 TabContentsDataVector::const_iterator iter = contents_data_.begin();
382 for (; iter != contents_data_.end(); ++iter, ++index) { 379 for (; iter != contents_data_.end(); ++iter, ++index) {
383 if ((*iter)->contents->web_contents() == contents) 380 if ((*iter)->contents->web_contents() == contents)
384 return index; 381 return index;
385 } 382 }
386 return kNoTab; 383 return kNoTab;
387 } 384 }
388 385
389 int TabStripModel::GetIndexOfController( 386 int TabStripModel::GetIndexOfController(
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 for (; iter != end; --iter) { 485 for (; iter != end; --iter) {
489 next = iter - 1; 486 next = iter - 1;
490 if (next == end) 487 if (next == end)
491 break; 488 break;
492 if ((*next)->opener == opener) 489 if ((*next)->opener == opener)
493 return static_cast<int>(next - contents_data_.begin()); 490 return static_cast<int>(next - contents_data_.begin());
494 } 491 }
495 return kNoTab; 492 return kNoTab;
496 } 493 }
497 494
498 void TabStripModel::TabNavigating(TabContentsWrapper* contents, 495 void TabStripModel::TabNavigating(TabContents* contents,
499 content::PageTransition transition) { 496 content::PageTransition transition) {
500 if (ShouldForgetOpenersForTransition(transition)) { 497 if (ShouldForgetOpenersForTransition(transition)) {
501 // Don't forget the openers if this tab is a New Tab page opened at the 498 // Don't forget the openers if this tab is a New Tab page opened at the
502 // end of the TabStrip (e.g. by pressing Ctrl+T). Give the user one 499 // end of the TabStrip (e.g. by pressing Ctrl+T). Give the user one
503 // navigation of one of these transition types before resetting the 500 // navigation of one of these transition types before resetting the
504 // opener relationships (this allows for the use case of opening a new 501 // opener relationships (this allows for the use case of opening a new
505 // tab to do a quick look-up of something while viewing a tab earlier in 502 // tab to do a quick look-up of something while viewing a tab earlier in
506 // the strip). We can make this heuristic more permissive if need be. 503 // the strip). We can make this heuristic more permissive if need be.
507 if (!IsNewTabAtEndOfTabStrip(contents)) { 504 if (!IsNewTabAtEndOfTabStrip(contents)) {
508 // If the user navigates the current tab to another page in any way 505 // If the user navigates the current tab to another page in any way
509 // other than by clicking a link, we want to pro-actively forget all 506 // other than by clicking a link, we want to pro-actively forget all
510 // TabStrip opener relationships since we assume they're beginning a 507 // TabStrip opener relationships since we assume they're beginning a
511 // different task by reusing the current tab. 508 // different task by reusing the current tab.
512 ForgetAllOpeners(); 509 ForgetAllOpeners();
513 // In this specific case we also want to reset the group relationship, 510 // In this specific case we also want to reset the group relationship,
514 // since it is now technically invalid. 511 // since it is now technically invalid.
515 ForgetGroup(contents); 512 ForgetGroup(contents);
516 } 513 }
517 } 514 }
518 } 515 }
519 516
520 void TabStripModel::ForgetAllOpeners() { 517 void TabStripModel::ForgetAllOpeners() {
521 // Forget all opener memories so we don't do anything weird with tab 518 // Forget all opener memories so we don't do anything weird with tab
522 // re-selection ordering. 519 // re-selection ordering.
523 TabContentsDataVector::const_iterator iter = contents_data_.begin(); 520 TabContentsDataVector::const_iterator iter = contents_data_.begin();
524 for (; iter != contents_data_.end(); ++iter) 521 for (; iter != contents_data_.end(); ++iter)
525 (*iter)->ForgetOpener(); 522 (*iter)->ForgetOpener();
526 } 523 }
527 524
528 void TabStripModel::ForgetGroup(TabContentsWrapper* contents) { 525 void TabStripModel::ForgetGroup(TabContents* contents) {
529 int index = GetIndexOfTabContents(contents); 526 int index = GetIndexOfTabContents(contents);
530 DCHECK(ContainsIndex(index)); 527 DCHECK(ContainsIndex(index));
531 contents_data_[index]->SetGroup(NULL); 528 contents_data_[index]->SetGroup(NULL);
532 contents_data_[index]->ForgetOpener(); 529 contents_data_[index]->ForgetOpener();
533 } 530 }
534 531
535 bool TabStripModel::ShouldResetGroupOnSelect( 532 bool TabStripModel::ShouldResetGroupOnSelect(TabContents* contents) const {
536 TabContentsWrapper* contents) const {
537 int index = GetIndexOfTabContents(contents); 533 int index = GetIndexOfTabContents(contents);
538 DCHECK(ContainsIndex(index)); 534 DCHECK(ContainsIndex(index));
539 return contents_data_[index]->reset_group_on_select; 535 return contents_data_[index]->reset_group_on_select;
540 } 536 }
541 537
542 void TabStripModel::SetTabBlocked(int index, bool blocked) { 538 void TabStripModel::SetTabBlocked(int index, bool blocked) {
543 DCHECK(ContainsIndex(index)); 539 DCHECK(ContainsIndex(index));
544 if (contents_data_[index]->blocked == blocked) 540 if (contents_data_[index]->blocked == blocked)
545 return; 541 return;
546 contents_data_[index]->blocked = blocked; 542 contents_data_[index]->blocked = blocked;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 bool TabStripModel::IsTabPinned(int index) const { 587 bool TabStripModel::IsTabPinned(int index) const {
592 DCHECK(ContainsIndex(index)); 588 DCHECK(ContainsIndex(index));
593 return contents_data_[index]->pinned; 589 return contents_data_[index]->pinned;
594 } 590 }
595 591
596 bool TabStripModel::IsMiniTab(int index) const { 592 bool TabStripModel::IsMiniTab(int index) const {
597 return IsTabPinned(index) || IsAppTab(index); 593 return IsTabPinned(index) || IsAppTab(index);
598 } 594 }
599 595
600 bool TabStripModel::IsAppTab(int index) const { 596 bool TabStripModel::IsAppTab(int index) const {
601 TabContentsWrapper* contents = GetTabContentsAt(index); 597 TabContents* contents = GetTabContentsAt(index);
602 return contents && contents->extension_tab_helper()->is_app(); 598 return contents && contents->extension_tab_helper()->is_app();
603 } 599 }
604 600
605 bool TabStripModel::IsTabBlocked(int index) const { 601 bool TabStripModel::IsTabBlocked(int index) const {
606 return contents_data_[index]->blocked; 602 return contents_data_[index]->blocked;
607 } 603 }
608 604
609 bool TabStripModel::IsTabDiscarded(int index) const { 605 bool TabStripModel::IsTabDiscarded(int index) const {
610 return contents_data_[index]->discarded; 606 return contents_data_[index]->discarded;
611 } 607 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 DCHECK(ContainsIndex(index)); 662 DCHECK(ContainsIndex(index));
667 return selection_model_.IsSelected(index); 663 return selection_model_.IsSelected(index);
668 } 664 }
669 665
670 void TabStripModel::SetSelectionFromModel( 666 void TabStripModel::SetSelectionFromModel(
671 const TabStripSelectionModel& source) { 667 const TabStripSelectionModel& source) {
672 DCHECK_NE(TabStripSelectionModel::kUnselectedIndex, source.active()); 668 DCHECK_NE(TabStripSelectionModel::kUnselectedIndex, source.active());
673 SetSelection(source, NOTIFY_DEFAULT); 669 SetSelection(source, NOTIFY_DEFAULT);
674 } 670 }
675 671
676 void TabStripModel::AddTabContents(TabContentsWrapper* contents, 672 void TabStripModel::AddTabContents(TabContents* contents,
677 int index, 673 int index,
678 content::PageTransition transition, 674 content::PageTransition transition,
679 int add_types) { 675 int add_types) {
680 // If the newly-opened tab is part of the same task as the parent tab, we want 676 // If the newly-opened tab is part of the same task as the parent tab, we want
681 // to inherit the parent's "group" attribute, so that if this tab is then 677 // to inherit the parent's "group" attribute, so that if this tab is then
682 // closed we'll jump back to the parent tab. 678 // closed we'll jump back to the parent tab.
683 bool inherit_group = (add_types & ADD_INHERIT_GROUP) == ADD_INHERIT_GROUP; 679 bool inherit_group = (add_types & ADD_INHERIT_GROUP) == ADD_INHERIT_GROUP;
684 680
685 if (transition == content::PAGE_TRANSITION_LINK && 681 if (transition == content::PAGE_TRANSITION_LINK &&
686 (add_types & ADD_FORCE_INDEX) == 0) { 682 (add_types & ADD_FORCE_INDEX) == 0) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 // TODO(sky): figure out why this is here and not in InsertTabContentsAt. When 716 // TODO(sky): figure out why this is here and not in InsertTabContentsAt. When
721 // here we seem to get failures in startup perf tests. 717 // here we seem to get failures in startup perf tests.
722 // Ensure that the new WebContentsView begins at the same size as the 718 // Ensure that the new WebContentsView begins at the same size as the
723 // previous WebContentsView if it existed. Otherwise, the initial WebKit 719 // previous WebContentsView if it existed. Otherwise, the initial WebKit
724 // layout will be performed based on a width of 0 pixels, causing a 720 // layout will be performed based on a width of 0 pixels, causing a
725 // very long, narrow, inaccurate layout. Because some scripts on pages (as 721 // very long, narrow, inaccurate layout. Because some scripts on pages (as
726 // well as WebKit's anchor link location calculation) are run on the 722 // well as WebKit's anchor link location calculation) are run on the
727 // initial layout and not recalculated later, we need to ensure the first 723 // initial layout and not recalculated later, we need to ensure the first
728 // layout is performed with sane view dimensions even when we're opening a 724 // layout is performed with sane view dimensions even when we're opening a
729 // new background tab. 725 // new background tab.
730 if (TabContentsWrapper* old_contents = GetActiveTabContents()) { 726 if (TabContents* old_contents = GetActiveTabContents()) {
731 if ((add_types & ADD_ACTIVE) == 0) { 727 if ((add_types & ADD_ACTIVE) == 0) {
732 contents->web_contents()->GetView()-> 728 contents->web_contents()->GetView()->
733 SizeContents(old_contents->web_contents()-> 729 SizeContents(old_contents->web_contents()->
734 GetView()->GetContainerSize()); 730 GetView()->GetContainerSize());
735 // We need to hide the contents or else we get and execute paints for 731 // We need to hide the contents or else we get and execute paints for
736 // background tabs. With enough background tabs they will steal the 732 // background tabs. With enough background tabs they will steal the
737 // backing store of the visible tab causing flashing. See bug 20831. 733 // backing store of the visible tab causing flashing. See bug 20831.
738 contents->web_contents()->HideContents(); 734 contents->web_contents()->HideContents();
739 } 735 }
740 } 736 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 switch (command_id) { 776 switch (command_id) {
781 case CommandNewTab: 777 case CommandNewTab:
782 return true; 778 return true;
783 779
784 case CommandCloseTab: 780 case CommandCloseTab:
785 return delegate_->CanCloseTab(); 781 return delegate_->CanCloseTab();
786 782
787 case CommandReload: { 783 case CommandReload: {
788 std::vector<int> indices = GetIndicesForCommand(context_index); 784 std::vector<int> indices = GetIndicesForCommand(context_index);
789 for (size_t i = 0; i < indices.size(); ++i) { 785 for (size_t i = 0; i < indices.size(); ++i) {
790 TabContentsWrapper* tab = GetTabContentsAt(indices[i]); 786 TabContents* tab = GetTabContentsAt(indices[i]);
791 if (tab && tab->web_contents()->GetDelegate()->CanReloadContents( 787 if (tab && tab->web_contents()->GetDelegate()->CanReloadContents(
792 tab->web_contents())) { 788 tab->web_contents())) {
793 return true; 789 return true;
794 } 790 }
795 } 791 }
796 return false; 792 return false;
797 } 793 }
798 794
799 case CommandCloseOtherTabs: 795 case CommandCloseOtherTabs:
800 case CommandCloseTabsToRight: 796 case CommandCloseTabsToRight:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 switch (command_id) { 837 switch (command_id) {
842 case CommandNewTab: 838 case CommandNewTab:
843 content::RecordAction(UserMetricsAction("TabContextMenu_NewTab")); 839 content::RecordAction(UserMetricsAction("TabContextMenu_NewTab"));
844 delegate()->AddBlankTabAt(context_index + 1, true); 840 delegate()->AddBlankTabAt(context_index + 1, true);
845 break; 841 break;
846 842
847 case CommandReload: { 843 case CommandReload: {
848 content::RecordAction(UserMetricsAction("TabContextMenu_Reload")); 844 content::RecordAction(UserMetricsAction("TabContextMenu_Reload"));
849 std::vector<int> indices = GetIndicesForCommand(context_index); 845 std::vector<int> indices = GetIndicesForCommand(context_index);
850 for (size_t i = 0; i < indices.size(); ++i) { 846 for (size_t i = 0; i < indices.size(); ++i) {
851 TabContentsWrapper* tab = GetTabContentsAt(indices[i]); 847 TabContents* tab = GetTabContentsAt(indices[i]);
852 if (tab && tab->web_contents()->GetDelegate()->CanReloadContents( 848 if (tab && tab->web_contents()->GetDelegate()->CanReloadContents(
853 tab->web_contents())) { 849 tab->web_contents())) {
854 tab->web_contents()->GetController().Reload(true); 850 tab->web_contents()->GetController().Reload(true);
855 } 851 }
856 } 852 }
857 break; 853 break;
858 } 854 }
859 855
860 case CommandDuplicate: { 856 case CommandDuplicate: {
861 content::RecordAction(UserMetricsAction("TabContextMenu_Duplicate")); 857 content::RecordAction(UserMetricsAction("TabContextMenu_Duplicate"));
862 std::vector<int> indices = GetIndicesForCommand(context_index); 858 std::vector<int> indices = GetIndicesForCommand(context_index);
863 // Copy the TabContentsWrapper off as the indices will change as tabs are 859 // Copy the TabContents off as the indices will change as tabs are
864 // duplicated. 860 // duplicated.
865 std::vector<TabContentsWrapper*> tabs; 861 std::vector<TabContents*> tabs;
866 for (size_t i = 0; i < indices.size(); ++i) 862 for (size_t i = 0; i < indices.size(); ++i)
867 tabs.push_back(GetTabContentsAt(indices[i])); 863 tabs.push_back(GetTabContentsAt(indices[i]));
868 for (size_t i = 0; i < tabs.size(); ++i) { 864 for (size_t i = 0; i < tabs.size(); ++i) {
869 int index = GetIndexOfTabContents(tabs[i]); 865 int index = GetIndexOfTabContents(tabs[i]);
870 if (index != -1 && delegate_->CanDuplicateContentsAt(index)) 866 if (index != -1 && delegate_->CanDuplicateContentsAt(index))
871 delegate_->DuplicateContentsAt(index); 867 delegate_->DuplicateContentsAt(index);
872 } 868 }
873 break; 869 break;
874 } 870 }
875 871
876 case CommandCloseTab: { 872 case CommandCloseTab: {
877 content::RecordAction(UserMetricsAction("TabContextMenu_CloseTab")); 873 content::RecordAction(UserMetricsAction("TabContextMenu_CloseTab"));
878 std::vector<int> indices = GetIndicesForCommand(context_index); 874 std::vector<int> indices = GetIndicesForCommand(context_index);
879 // Copy the TabContentsWrapper off as the indices will change as we remove 875 // Copy the TabContents off as the indices will change as we remove
880 // things. 876 // things.
881 std::vector<TabContentsWrapper*> tabs; 877 std::vector<TabContents*> tabs;
882 for (size_t i = 0; i < indices.size(); ++i) 878 for (size_t i = 0; i < indices.size(); ++i)
883 tabs.push_back(GetTabContentsAt(indices[i])); 879 tabs.push_back(GetTabContentsAt(indices[i]));
884 for (size_t i = 0; i < tabs.size() && delegate_->CanCloseTab(); ++i) { 880 for (size_t i = 0; i < tabs.size() && delegate_->CanCloseTab(); ++i) {
885 int index = GetIndexOfTabContents(tabs[i]); 881 int index = GetIndexOfTabContents(tabs[i]);
886 if (index != -1) { 882 if (index != -1) {
887 CloseTabContentsAt(index, 883 CloseTabContentsAt(index,
888 CLOSE_CREATE_HISTORICAL_TAB | CLOSE_USER_GESTURE); 884 CLOSE_CREATE_HISTORICAL_TAB | CLOSE_USER_GESTURE);
889 } 885 }
890 } 886 }
891 break; 887 break;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 1000
1005 void TabStripModel::Observe(int type, 1001 void TabStripModel::Observe(int type,
1006 const content::NotificationSource& source, 1002 const content::NotificationSource& source,
1007 const content::NotificationDetails& details) { 1003 const content::NotificationDetails& details) {
1008 switch (type) { 1004 switch (type) {
1009 case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: { 1005 case chrome::NOTIFICATION_TAB_CONTENTS_DESTROYED: {
1010 // Sometimes, on qemu, it seems like a WebContents object can be destroyed 1006 // Sometimes, on qemu, it seems like a WebContents object can be destroyed
1011 // while we still have a reference to it. We need to break this reference 1007 // while we still have a reference to it. We need to break this reference
1012 // here so we don't crash later. 1008 // here so we don't crash later.
1013 int index = GetIndexOfTabContents( 1009 int index = GetIndexOfTabContents(
1014 content::Source<TabContentsWrapper>(source).ptr()); 1010 content::Source<TabContents>(source).ptr());
1015 if (index != TabStripModel::kNoTab) { 1011 if (index != TabStripModel::kNoTab) {
1016 // Note that we only detach the contents here, not close it - it's 1012 // Note that we only detach the contents here, not close it - it's
1017 // already been closed. We just want to undo our bookkeeping. 1013 // already been closed. We just want to undo our bookkeeping.
1018 DetachTabContentsAt(index); 1014 DetachTabContentsAt(index);
1019 } 1015 }
1020 break; 1016 break;
1021 } 1017 }
1022 1018
1023 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { 1019 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
1024 const extensions::Extension* extension = 1020 const extensions::Extension* extension =
1025 content::Details<extensions::UnloadedExtensionInfo>( 1021 content::Details<extensions::UnloadedExtensionInfo>(
1026 details)->extension; 1022 details)->extension;
1027 // Iterate backwards as we may remove items while iterating. 1023 // Iterate backwards as we may remove items while iterating.
1028 for (int i = count() - 1; i >= 0; i--) { 1024 for (int i = count() - 1; i >= 0; i--) {
1029 TabContentsWrapper* contents = GetTabContentsAt(i); 1025 TabContents* contents = GetTabContentsAt(i);
1030 if (contents->extension_tab_helper()->extension_app() == extension) { 1026 if (contents->extension_tab_helper()->extension_app() == extension) {
1031 // The extension an app tab was created from has been nuked. Delete 1027 // The extension an app tab was created from has been nuked. Delete
1032 // the WebContents. Deleting a WebContents results in a notification 1028 // the WebContents. Deleting a WebContents results in a notification
1033 // of type NOTIFICATION_WEB_CONTENTS_DESTROYED; we do the necessary 1029 // of type NOTIFICATION_WEB_CONTENTS_DESTROYED; we do the necessary
1034 // cleanup in handling that notification. 1030 // cleanup in handling that notification.
1035 1031
1036 InternalCloseTab(contents, i, false); 1032 InternalCloseTab(contents, i, false);
1037 } 1033 }
1038 } 1034 }
1039 break; 1035 break;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 } 1068 }
1073 1069
1074 return true; 1070 return true;
1075 } 1071 }
1076 1072
1077 /////////////////////////////////////////////////////////////////////////////// 1073 ///////////////////////////////////////////////////////////////////////////////
1078 // TabStripModel, private: 1074 // TabStripModel, private:
1079 1075
1080 void TabStripModel::GetIndicesWithSameDomain(int index, 1076 void TabStripModel::GetIndicesWithSameDomain(int index,
1081 std::vector<int>* indices) { 1077 std::vector<int>* indices) {
1082 TabContentsWrapper* tab = GetTabContentsAt(index); 1078 TabContents* tab = GetTabContentsAt(index);
1083 std::string domain = tab->web_contents()->GetURL().host(); 1079 std::string domain = tab->web_contents()->GetURL().host();
1084 if (domain.empty()) 1080 if (domain.empty())
1085 return; 1081 return;
1086 for (int i = 0; i < count(); ++i) { 1082 for (int i = 0; i < count(); ++i) {
1087 if (i == index) 1083 if (i == index)
1088 continue; 1084 continue;
1089 if (GetTabContentsAt(i)->web_contents()->GetURL().host() == domain) 1085 if (GetTabContentsAt(i)->web_contents()->GetURL().host() == domain)
1090 indices->push_back(i); 1086 indices->push_back(i);
1091 } 1087 }
1092 } 1088 }
(...skipping 19 matching lines...) Expand all
1112 1108
1113 std::vector<int> TabStripModel::GetIndicesForCommand(int index) const { 1109 std::vector<int> TabStripModel::GetIndicesForCommand(int index) const {
1114 if (!IsTabSelected(index)) { 1110 if (!IsTabSelected(index)) {
1115 std::vector<int> indices; 1111 std::vector<int> indices;
1116 indices.push_back(index); 1112 indices.push_back(index);
1117 return indices; 1113 return indices;
1118 } 1114 }
1119 return selection_model_.selected_indices(); 1115 return selection_model_.selected_indices();
1120 } 1116 }
1121 1117
1122 bool TabStripModel::IsNewTabAtEndOfTabStrip( 1118 bool TabStripModel::IsNewTabAtEndOfTabStrip(TabContents* contents) const {
1123 TabContentsWrapper* contents) const {
1124 const GURL& url = contents->web_contents()->GetURL(); 1119 const GURL& url = contents->web_contents()->GetURL();
1125 return url.SchemeIs(chrome::kChromeUIScheme) && 1120 return url.SchemeIs(chrome::kChromeUIScheme) &&
1126 url.host() == chrome::kChromeUINewTabHost && 1121 url.host() == chrome::kChromeUINewTabHost &&
1127 contents == GetContentsAt(count() - 1) && 1122 contents == GetContentsAt(count() - 1) &&
1128 contents->web_contents()->GetController().GetEntryCount() == 1; 1123 contents->web_contents()->GetController().GetEntryCount() == 1;
1129 } 1124 }
1130 1125
1131 bool TabStripModel::InternalCloseTabs(const std::vector<int>& in_indices, 1126 bool TabStripModel::InternalCloseTabs(const std::vector<int>& in_indices,
1132 uint32 close_types) { 1127 uint32 close_types) {
1133 if (in_indices.empty()) 1128 if (in_indices.empty())
1134 return true; 1129 return true;
1135 1130
1136 std::vector<int> indices(in_indices); 1131 std::vector<int> indices(in_indices);
1137 bool retval = delegate_->CanCloseContents(&indices); 1132 bool retval = delegate_->CanCloseContents(&indices);
1138 if (indices.empty()) 1133 if (indices.empty())
1139 return retval; 1134 return retval;
1140 1135
1141 // Map the indices to TabContentsWrapper, that way if deleting a tab deletes 1136 // Map the indices to TabContents, that way if deleting a tab deletes
1142 // other tabs we're ok. Crashes seem to indicate during tab deletion other 1137 // other tabs we're ok. Crashes seem to indicate during tab deletion other
1143 // tabs are getting removed. 1138 // tabs are getting removed.
1144 std::vector<TabContentsWrapper*> tabs; 1139 std::vector<TabContents*> tabs;
1145 for (size_t i = 0; i < indices.size(); ++i) 1140 for (size_t i = 0; i < indices.size(); ++i)
1146 tabs.push_back(GetContentsAt(indices[i])); 1141 tabs.push_back(GetContentsAt(indices[i]));
1147 1142
1148 // We only try the fast shutdown path if the whole browser process is *not* 1143 // We only try the fast shutdown path if the whole browser process is *not*
1149 // shutting down. Fast shutdown during browser termination is handled in 1144 // shutting down. Fast shutdown during browser termination is handled in
1150 // BrowserShutdown. 1145 // BrowserShutdown.
1151 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { 1146 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) {
1152 // Construct a map of processes to the number of associated tabs that are 1147 // Construct a map of processes to the number of associated tabs that are
1153 // closing. 1148 // closing.
1154 std::map<content::RenderProcessHost*, size_t> processes; 1149 std::map<content::RenderProcessHost*, size_t> processes;
1155 for (size_t i = 0; i < indices.size(); ++i) { 1150 for (size_t i = 0; i < indices.size(); ++i) {
1156 TabContentsWrapper* detached_contents = GetContentsAt(indices[i]); 1151 TabContents* detached_contents = GetContentsAt(indices[i]);
1157 content::RenderProcessHost* process = 1152 content::RenderProcessHost* process =
1158 detached_contents->web_contents()->GetRenderProcessHost(); 1153 detached_contents->web_contents()->GetRenderProcessHost();
1159 std::map<content::RenderProcessHost*, size_t>::iterator iter = 1154 std::map<content::RenderProcessHost*, size_t>::iterator iter =
1160 processes.find(process); 1155 processes.find(process);
1161 if (iter == processes.end()) { 1156 if (iter == processes.end()) {
1162 processes[process] = 1; 1157 processes[process] = 1;
1163 } else { 1158 } else {
1164 iter->second++; 1159 iter->second++;
1165 } 1160 }
1166 } 1161 }
1167 1162
1168 // Try to fast shutdown the tabs that can close. 1163 // Try to fast shutdown the tabs that can close.
1169 for (std::map<content::RenderProcessHost*, size_t>::iterator iter = 1164 for (std::map<content::RenderProcessHost*, size_t>::iterator iter =
1170 processes.begin(); 1165 processes.begin();
1171 iter != processes.end(); ++iter) { 1166 iter != processes.end(); ++iter) {
1172 iter->first->FastShutdownForPageCount(iter->second); 1167 iter->first->FastShutdownForPageCount(iter->second);
1173 } 1168 }
1174 } 1169 }
1175 1170
1176 // We now return to our regularly scheduled shutdown procedure. 1171 // We now return to our regularly scheduled shutdown procedure.
1177 for (size_t i = 0; i < tabs.size(); ++i) { 1172 for (size_t i = 0; i < tabs.size(); ++i) {
1178 TabContentsWrapper* detached_contents = tabs[i]; 1173 TabContents* detached_contents = tabs[i];
1179 int index = GetIndexOfTabContents(detached_contents); 1174 int index = GetIndexOfTabContents(detached_contents);
1180 // Make sure we still contain the tab. 1175 // Make sure we still contain the tab.
1181 if (index == kNoTab) 1176 if (index == kNoTab)
1182 continue; 1177 continue;
1183 1178
1184 detached_contents->web_contents()->OnCloseStarted(); 1179 detached_contents->web_contents()->OnCloseStarted();
1185 1180
1186 // Update the explicitly closed state. If the unload handlers cancel the 1181 // Update the explicitly closed state. If the unload handlers cancel the
1187 // close the state is reset in Browser. We don't update the explicitly 1182 // close the state is reset in Browser. We don't update the explicitly
1188 // closed state if already marked as explicitly closed as unload handlers 1183 // closed state if already marked as explicitly closed as unload handlers
1189 // call back to this if the close is allowed. 1184 // call back to this if the close is allowed.
1190 if (!detached_contents->web_contents()->GetClosedByUserGesture()) { 1185 if (!detached_contents->web_contents()->GetClosedByUserGesture()) {
1191 detached_contents->web_contents()->SetClosedByUserGesture( 1186 detached_contents->web_contents()->SetClosedByUserGesture(
1192 close_types & CLOSE_USER_GESTURE); 1187 close_types & CLOSE_USER_GESTURE);
1193 } 1188 }
1194 1189
1195 if (delegate_->RunUnloadListenerBeforeClosing(detached_contents)) { 1190 if (delegate_->RunUnloadListenerBeforeClosing(detached_contents)) {
1196 retval = false; 1191 retval = false;
1197 continue; 1192 continue;
1198 } 1193 }
1199 1194
1200 InternalCloseTab(detached_contents, index, 1195 InternalCloseTab(detached_contents, index,
1201 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0); 1196 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0);
1202 } 1197 }
1203 1198
1204 return retval; 1199 return retval;
1205 } 1200 }
1206 1201
1207 void TabStripModel::InternalCloseTab(TabContentsWrapper* contents, 1202 void TabStripModel::InternalCloseTab(TabContents* contents,
1208 int index, 1203 int index,
1209 bool create_historical_tabs) { 1204 bool create_historical_tabs) {
1210 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1205 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
1211 TabClosingAt(this, contents, index)); 1206 TabClosingAt(this, contents, index));
1212 1207
1213 // Ask the delegate to save an entry for this tab in the historical tab 1208 // Ask the delegate to save an entry for this tab in the historical tab
1214 // database if applicable. 1209 // database if applicable.
1215 if (create_historical_tabs) 1210 if (create_historical_tabs)
1216 delegate_->CreateHistoricalTab(contents); 1211 delegate_->CreateHistoricalTab(contents);
1217 1212
1218 // Deleting the TabContentsWrapper will call back to us via 1213 // Deleting the TabContents will call back to us via
1219 // NotificationObserver and detach it. 1214 // NotificationObserver and detach it.
1220 delete contents; 1215 delete contents;
1221 } 1216 }
1222 1217
1223 TabContentsWrapper* TabStripModel::GetContentsAt(int index) const { 1218 TabContents* TabStripModel::GetContentsAt(int index) const {
1224 CHECK(ContainsIndex(index)) << 1219 CHECK(ContainsIndex(index)) <<
1225 "Failed to find: " << index << " in: " << count() << " entries."; 1220 "Failed to find: " << index << " in: " << count() << " entries.";
1226 return contents_data_[index]->contents; 1221 return contents_data_[index]->contents;
1227 } 1222 }
1228 1223
1229 void TabStripModel::NotifyIfTabDeactivated(TabContentsWrapper* contents) { 1224 void TabStripModel::NotifyIfTabDeactivated(TabContents* contents) {
1230 if (contents) { 1225 if (contents) {
1231 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1226 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
1232 TabDeactivated(contents)); 1227 TabDeactivated(contents));
1233 } 1228 }
1234 } 1229 }
1235 1230
1236 void TabStripModel::NotifyIfActiveTabChanged( 1231 void TabStripModel::NotifyIfActiveTabChanged(TabContents* old_contents,
1237 TabContentsWrapper* old_contents, 1232 NotifyTypes notify_types) {
1238 NotifyTypes notify_types) { 1233 TabContents* new_contents = GetContentsAt(active_index());
1239 TabContentsWrapper* new_contents = GetContentsAt(active_index());
1240 if (old_contents != new_contents) { 1234 if (old_contents != new_contents) {
1241 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1235 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
1242 ActiveTabChanged(old_contents, new_contents, 1236 ActiveTabChanged(old_contents, new_contents,
1243 active_index(), 1237 active_index(),
1244 notify_types == NOTIFY_USER_GESTURE)); 1238 notify_types == NOTIFY_USER_GESTURE));
1245 // Activating a discarded tab reloads it, so it is no longer discarded. 1239 // Activating a discarded tab reloads it, so it is no longer discarded.
1246 contents_data_[active_index()]->discarded = false; 1240 contents_data_[active_index()]->discarded = false;
1247 } 1241 }
1248 } 1242 }
1249 1243
1250 void TabStripModel::NotifyIfActiveOrSelectionChanged( 1244 void TabStripModel::NotifyIfActiveOrSelectionChanged(
1251 TabContentsWrapper* old_contents, 1245 TabContents* old_contents,
1252 NotifyTypes notify_types, 1246 NotifyTypes notify_types,
1253 const TabStripSelectionModel& old_model) { 1247 const TabStripSelectionModel& old_model) {
1254 NotifyIfActiveTabChanged(old_contents, notify_types); 1248 NotifyIfActiveTabChanged(old_contents, notify_types);
1255 1249
1256 if (!selection_model().Equals(old_model)) { 1250 if (!selection_model().Equals(old_model)) {
1257 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1251 FOR_EACH_OBSERVER(TabStripModelObserver, observers_,
1258 TabSelectionChanged(this, old_model)); 1252 TabSelectionChanged(this, old_model));
1259 } 1253 }
1260 } 1254 }
1261 1255
1262 void TabStripModel::SetSelection( 1256 void TabStripModel::SetSelection(
1263 const TabStripSelectionModel& new_model, 1257 const TabStripSelectionModel& new_model,
1264 NotifyTypes notify_types) { 1258 NotifyTypes notify_types) {
1265 TabContentsWrapper* old_contents = GetActiveTabContents(); 1259 TabContents* old_contents = GetActiveTabContents();
1266 TabStripSelectionModel old_model; 1260 TabStripSelectionModel old_model;
1267 old_model.Copy(selection_model_); 1261 old_model.Copy(selection_model_);
1268 if (new_model.active() != selection_model_.active()) 1262 if (new_model.active() != selection_model_.active())
1269 NotifyIfTabDeactivated(old_contents); 1263 NotifyIfTabDeactivated(old_contents);
1270 selection_model_.Copy(new_model); 1264 selection_model_.Copy(new_model);
1271 NotifyIfActiveOrSelectionChanged(old_contents, notify_types, old_model); 1265 NotifyIfActiveOrSelectionChanged(old_contents, notify_types, old_model);
1272 } 1266 }
1273 1267
1274 void TabStripModel::SelectRelativeTab(bool next) { 1268 void TabStripModel::SelectRelativeTab(bool next) {
1275 // This may happen during automated testing or if a user somehow buffers 1269 // This may happen during automated testing or if a user somehow buffers
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 void TabStripModel::ForgetOpenersAndGroupsReferencing( 1340 void TabStripModel::ForgetOpenersAndGroupsReferencing(
1347 const NavigationController* tab) { 1341 const NavigationController* tab) {
1348 for (TabContentsDataVector::const_iterator i = contents_data_.begin(); 1342 for (TabContentsDataVector::const_iterator i = contents_data_.begin();
1349 i != contents_data_.end(); ++i) { 1343 i != contents_data_.end(); ++i) {
1350 if ((*i)->group == tab) 1344 if ((*i)->group == tab)
1351 (*i)->group = NULL; 1345 (*i)->group = NULL;
1352 if ((*i)->opener == tab) 1346 if ((*i)->opener == tab)
1353 (*i)->opener = NULL; 1347 (*i)->opener = NULL;
1354 } 1348 }
1355 } 1349 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/tabs/tab_strip_model.h ('k') | chrome/browser/ui/tabs/tab_strip_model_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698