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

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

Issue 2411113003: Remove stl_util's deletion functions from tab_strip_model, and do other modernization. (Closed)
Patch Set: {} Created 4 years, 2 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
« no previous file with comments | « chrome/browser/ui/tabs/tab_strip_model.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 11
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h"
13 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
14 #include "base/stl_util.h"
15 #include "chrome/app/chrome_command_ids.h" 15 #include "chrome/app/chrome_command_ids.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/tab_helper.h" 18 #include "chrome/browser/extensions/tab_helper.h"
19 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" 20 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
21 #include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h" 21 #include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" 22 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h"
24 #include "chrome/browser/ui/tabs/tab_utils.h" 24 #include "chrome/browser/ui/tabs/tab_utils.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 CloseTracker::~CloseTracker() { 102 CloseTracker::~CloseTracker() {
103 DCHECK(observers_.empty()); 103 DCHECK(observers_.empty());
104 } 104 }
105 105
106 bool CloseTracker::HasNext() const { 106 bool CloseTracker::HasNext() const {
107 return !observers_.empty(); 107 return !observers_.empty();
108 } 108 }
109 109
110 WebContents* CloseTracker::Next() { 110 WebContents* CloseTracker::Next() {
111 if (observers_.empty()) 111 if (observers_.empty())
112 return NULL; 112 return nullptr;
113 113
114 DeletionObserver* observer = observers_[0]; 114 DeletionObserver* observer = observers_[0];
115 WebContents* web_contents = observer->web_contents(); 115 WebContents* web_contents = observer->web_contents();
116 observers_.erase(observers_.begin()); 116 observers_.erase(observers_.begin());
117 delete observer; 117 delete observer;
118 return web_contents; 118 return web_contents;
119 } 119 }
120 120
121 void CloseTracker::OnWebContentsDestroyed(DeletionObserver* observer) { 121 void CloseTracker::OnWebContentsDestroyed(DeletionObserver* observer) {
122 Observers::iterator i = 122 Observers::iterator i =
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 bool blocked_; 203 bool blocked_;
204 204
205 DISALLOW_COPY_AND_ASSIGN(WebContentsData); 205 DISALLOW_COPY_AND_ASSIGN(WebContentsData);
206 }; 206 };
207 207
208 TabStripModel::WebContentsData::WebContentsData(TabStripModel* tab_strip_model, 208 TabStripModel::WebContentsData::WebContentsData(TabStripModel* tab_strip_model,
209 WebContents* contents) 209 WebContents* contents)
210 : content::WebContentsObserver(contents), 210 : content::WebContentsObserver(contents),
211 contents_(contents), 211 contents_(contents),
212 tab_strip_model_(tab_strip_model), 212 tab_strip_model_(tab_strip_model),
213 group_(NULL), 213 group_(nullptr),
214 opener_(NULL), 214 opener_(nullptr),
215 reset_group_on_select_(false), 215 reset_group_on_select_(false),
216 pinned_(false), 216 pinned_(false),
217 blocked_(false) {} 217 blocked_(false) {}
218 218
219 void TabStripModel::WebContentsData::SetWebContents(WebContents* contents) { 219 void TabStripModel::WebContentsData::SetWebContents(WebContents* contents) {
220 contents_ = contents; 220 contents_ = contents;
221 Observe(contents); 221 Observe(contents);
222 } 222 }
223 223
224 void TabStripModel::WebContentsData::WebContentsDestroyed() { 224 void TabStripModel::WebContentsData::WebContentsDestroyed() {
(...skipping 13 matching lines...) Expand all
238 : delegate_(delegate), 238 : delegate_(delegate),
239 profile_(profile), 239 profile_(profile),
240 closing_all_(false), 240 closing_all_(false),
241 in_notify_(false), 241 in_notify_(false),
242 weak_factory_(this) { 242 weak_factory_(this) {
243 DCHECK(delegate_); 243 DCHECK(delegate_);
244 order_controller_.reset(new TabStripModelOrderController(this)); 244 order_controller_.reset(new TabStripModelOrderController(this));
245 } 245 }
246 246
247 TabStripModel::~TabStripModel() { 247 TabStripModel::~TabStripModel() {
248 base::STLDeleteElements(&contents_data_); 248 contents_data_.clear();
249 order_controller_.reset(); 249 order_controller_.reset();
250 } 250 }
251 251
252 void TabStripModel::AddObserver(TabStripModelObserver* observer) { 252 void TabStripModel::AddObserver(TabStripModelObserver* observer) {
253 observers_.AddObserver(observer); 253 observers_.AddObserver(observer);
254 } 254 }
255 255
256 void TabStripModel::RemoveObserver(TabStripModelObserver* observer) { 256 void TabStripModel::RemoveObserver(TabStripModelObserver* observer) {
257 observers_.RemoveObserver(observer); 257 observers_.RemoveObserver(observer);
258 } 258 }
(...skipping 21 matching lines...) Expand all
280 // In tab dragging situations, if the last tab in the window was detached 280 // In tab dragging situations, if the last tab in the window was detached
281 // then the user aborted the drag, we will have the |closing_all_| member 281 // then the user aborted the drag, we will have the |closing_all_| member
282 // set (see DetachWebContentsAt) which will mess with our mojo here. We need 282 // set (see DetachWebContentsAt) which will mess with our mojo here. We need
283 // to clear this bit. 283 // to clear this bit.
284 closing_all_ = false; 284 closing_all_ = false;
285 285
286 // Have to get the active contents before we monkey with the contents 286 // Have to get the active contents before we monkey with the contents
287 // otherwise we run into problems when we try to change the active contents 287 // otherwise we run into problems when we try to change the active contents
288 // since the old contents and the new contents will be the same... 288 // since the old contents and the new contents will be the same...
289 WebContents* active_contents = GetActiveWebContents(); 289 WebContents* active_contents = GetActiveWebContents();
290 WebContentsData* data = new WebContentsData(this, contents); 290 std::unique_ptr<WebContentsData> data =
291 base::MakeUnique<WebContentsData>(this, contents);
291 data->set_pinned(pin); 292 data->set_pinned(pin);
292 if ((add_types & ADD_INHERIT_GROUP) && active_contents) { 293 if ((add_types & ADD_INHERIT_GROUP) && active_contents) {
293 if (active) { 294 if (active) {
294 // Forget any existing relationships, we don't want to make things too 295 // Forget any existing relationships, we don't want to make things too
295 // confusing by having multiple groups active at the same time. 296 // confusing by having multiple groups active at the same time.
296 ForgetAllOpeners(); 297 ForgetAllOpeners();
297 } 298 }
298 // Anything opened by a link we deem to have an opener. 299 // Anything opened by a link we deem to have an opener.
299 data->set_group(active_contents); 300 data->set_group(active_contents);
300 data->set_opener(active_contents); 301 data->set_opener(active_contents);
301 } else if ((add_types & ADD_INHERIT_OPENER) && active_contents) { 302 } else if ((add_types & ADD_INHERIT_OPENER) && active_contents) {
302 if (active) { 303 if (active) {
303 // Forget any existing relationships, we don't want to make things too 304 // Forget any existing relationships, we don't want to make things too
304 // confusing by having multiple groups active at the same time. 305 // confusing by having multiple groups active at the same time.
305 ForgetAllOpeners(); 306 ForgetAllOpeners();
306 } 307 }
307 data->set_opener(active_contents); 308 data->set_opener(active_contents);
308 } 309 }
309 310
310 // TODO(gbillock): Ask the modal dialog manager whether the WebContents should 311 // TODO(gbillock): Ask the modal dialog manager whether the WebContents should
311 // be blocked, or just let the modal dialog manager make the blocking call 312 // be blocked, or just let the modal dialog manager make the blocking call
312 // directly and not use this at all. 313 // directly and not use this at all.
313 const web_modal::WebContentsModalDialogManager* manager = 314 const web_modal::WebContentsModalDialogManager* manager =
314 web_modal::WebContentsModalDialogManager::FromWebContents(contents); 315 web_modal::WebContentsModalDialogManager::FromWebContents(contents);
315 if (manager) 316 if (manager)
316 data->set_blocked(manager->IsDialogActive()); 317 data->set_blocked(manager->IsDialogActive());
317 318
318 contents_data_.insert(contents_data_.begin() + index, data); 319 contents_data_.insert(contents_data_.begin() + index, std::move(data));
319 320
320 selection_model_.IncrementFrom(index); 321 selection_model_.IncrementFrom(index);
321 322
322 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 323 for (auto& observer : observers_)
323 TabInsertedAt(this, contents, index, active)); 324 observer.TabInsertedAt(this, contents, index, active);
325
324 if (active) { 326 if (active) {
325 ui::ListSelectionModel new_model; 327 ui::ListSelectionModel new_model;
326 new_model.Copy(selection_model_); 328 new_model.Copy(selection_model_);
327 new_model.SetSelectedIndex(index); 329 new_model.SetSelectedIndex(index);
328 SetSelection(new_model, NOTIFY_DEFAULT); 330 SetSelection(new_model, NOTIFY_DEFAULT);
329 } 331 }
330 } 332 }
331 333
332 WebContents* TabStripModel::ReplaceWebContentsAt(int index, 334 WebContents* TabStripModel::ReplaceWebContentsAt(int index,
333 WebContents* new_contents) { 335 WebContents* new_contents) {
334 delegate_->WillAddWebContents(new_contents); 336 delegate_->WillAddWebContents(new_contents);
335 337
336 DCHECK(ContainsIndex(index)); 338 DCHECK(ContainsIndex(index));
337 WebContents* old_contents = GetWebContentsAtImpl(index); 339 WebContents* old_contents = GetWebContentsAtImpl(index);
338 340
339 FixOpenersAndGroupsReferencing(index); 341 FixOpenersAndGroupsReferencing(index);
340 342
341 contents_data_[index]->SetWebContents(new_contents); 343 contents_data_[index]->SetWebContents(new_contents);
342 344
343 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 345 for (auto& observer : observers_)
344 TabReplacedAt(this, old_contents, new_contents, index)); 346 observer.TabReplacedAt(this, old_contents, new_contents, index);
345 347
346 // When the active WebContents is replaced send out a selection notification 348 // When the active WebContents is replaced send out a selection notification
347 // too. We do this as nearly all observers need to treat a replacement of the 349 // too. We do this as nearly all observers need to treat a replacement of the
348 // selected contents as the selection changing. 350 // selected contents as the selection changing.
349 if (active_index() == index) { 351 if (active_index() == index) {
350 FOR_EACH_OBSERVER( 352 for (auto& observer : observers_)
351 TabStripModelObserver, 353 observer.ActiveTabChanged(old_contents, new_contents, active_index(),
352 observers_, 354 TabStripModelObserver::CHANGE_REASON_REPLACED);
353 ActiveTabChanged(old_contents,
354 new_contents,
355 active_index(),
356 TabStripModelObserver::CHANGE_REASON_REPLACED));
357 } 355 }
358 return old_contents; 356 return old_contents;
359 } 357 }
360 358
361 WebContents* TabStripModel::DetachWebContentsAt(int index) { 359 WebContents* TabStripModel::DetachWebContentsAt(int index) {
362 CHECK(!in_notify_); 360 CHECK(!in_notify_);
363 if (contents_data_.empty()) 361 if (contents_data_.empty())
364 return NULL; 362 return nullptr;
365 DCHECK(ContainsIndex(index)); 363 DCHECK(ContainsIndex(index));
366 364
367 FixOpenersAndGroupsReferencing(index); 365 FixOpenersAndGroupsReferencing(index);
368 366
369 WebContents* removed_contents = GetWebContentsAtImpl(index); 367 WebContents* removed_contents = GetWebContentsAtImpl(index);
370 bool was_selected = IsTabSelected(index); 368 bool was_selected = IsTabSelected(index);
371 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index); 369 int next_selected_index = order_controller_->DetermineNewSelectedIndex(index);
372 delete contents_data_[index];
373 contents_data_.erase(contents_data_.begin() + index); 370 contents_data_.erase(contents_data_.begin() + index);
374 if (empty()) 371 if (empty())
375 closing_all_ = true; 372 closing_all_ = true;
376 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 373 for (auto& observer : observers_)
377 TabDetachedAt(removed_contents, index)); 374 observer.TabDetachedAt(removed_contents, index);
378 if (empty()) { 375 if (empty()) {
379 selection_model_.Clear(); 376 selection_model_.Clear();
380 // TabDetachedAt() might unregister observers, so send |TabStripEmpty()| in 377 // TabDetachedAt() might unregister observers, so send |TabStripEmpty()| in
381 // a second pass. 378 // a second pass.
382 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, TabStripEmpty()); 379 for (auto& observer : observers_)
380 observer.TabStripEmpty();
383 } else { 381 } else {
384 int old_active = active_index(); 382 int old_active = active_index();
385 selection_model_.DecrementFrom(index); 383 selection_model_.DecrementFrom(index);
386 ui::ListSelectionModel old_model; 384 ui::ListSelectionModel old_model;
387 old_model.Copy(selection_model_); 385 old_model.Copy(selection_model_);
388 if (index == old_active) { 386 if (index == old_active) {
389 NotifyIfTabDeactivated(removed_contents); 387 NotifyIfTabDeactivated(removed_contents);
390 if (!selection_model_.empty()) { 388 if (!selection_model_.empty()) {
391 // The active tab was removed, but there is still something selected. 389 // The active tab was removed, but there is still something selected.
392 // Move the active and anchor to the first selected index. 390 // Move the active and anchor to the first selected index.
393 selection_model_.set_active(selection_model_.selected_indices()[0]); 391 selection_model_.set_active(selection_model_.selected_indices()[0]);
394 selection_model_.set_anchor(selection_model_.active()); 392 selection_model_.set_anchor(selection_model_.active());
395 } else { 393 } else {
396 // The active tab was removed and nothing is selected. Reset the 394 // The active tab was removed and nothing is selected. Reset the
397 // selection and send out notification. 395 // selection and send out notification.
398 selection_model_.SetSelectedIndex(next_selected_index); 396 selection_model_.SetSelectedIndex(next_selected_index);
399 } 397 }
400 NotifyIfActiveTabChanged(removed_contents, NOTIFY_DEFAULT); 398 NotifyIfActiveTabChanged(removed_contents, NOTIFY_DEFAULT);
401 } 399 }
402 400
403 // Sending notification in case the detached tab was selected. Using 401 // Sending notification in case the detached tab was selected. Using
404 // NotifyIfActiveOrSelectionChanged() here would not guarantee that a 402 // NotifyIfActiveOrSelectionChanged() here would not guarantee that a
405 // notification is sent even though the tab selection has changed because 403 // notification is sent even though the tab selection has changed because
406 // |old_model| is stored after calling DecrementFrom(). 404 // |old_model| is stored after calling DecrementFrom().
407 if (was_selected) { 405 if (was_selected) {
408 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 406 for (auto& observer : observers_)
409 TabSelectionChanged(this, old_model)); 407 observer.TabSelectionChanged(this, old_model);
410 } 408 }
411 } 409 }
412 return removed_contents; 410 return removed_contents;
413 } 411 }
414 412
415 void TabStripModel::ActivateTabAt(int index, bool user_gesture) { 413 void TabStripModel::ActivateTabAt(int index, bool user_gesture) {
416 DCHECK(ContainsIndex(index)); 414 DCHECK(ContainsIndex(index));
417 ui::ListSelectionModel new_model; 415 ui::ListSelectionModel new_model;
418 new_model.Copy(selection_model_); 416 new_model.Copy(selection_model_);
419 new_model.SetSelectedIndex(index); 417 new_model.SetSelectedIndex(index);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 selected_count - selected_pinned_count); 477 selected_count - selected_pinned_count);
480 } 478 }
481 479
482 WebContents* TabStripModel::GetActiveWebContents() const { 480 WebContents* TabStripModel::GetActiveWebContents() const {
483 return GetWebContentsAt(active_index()); 481 return GetWebContentsAt(active_index());
484 } 482 }
485 483
486 WebContents* TabStripModel::GetWebContentsAt(int index) const { 484 WebContents* TabStripModel::GetWebContentsAt(int index) const {
487 if (ContainsIndex(index)) 485 if (ContainsIndex(index))
488 return GetWebContentsAtImpl(index); 486 return GetWebContentsAtImpl(index);
489 return NULL; 487 return nullptr;
490 } 488 }
491 489
492 int TabStripModel::GetIndexOfWebContents(const WebContents* contents) const { 490 int TabStripModel::GetIndexOfWebContents(const WebContents* contents) const {
493 for (size_t i = 0; i < contents_data_.size(); ++i) { 491 for (size_t i = 0; i < contents_data_.size(); ++i) {
494 if (contents_data_[i]->web_contents() == contents) 492 if (contents_data_[i]->web_contents() == contents)
495 return i; 493 return i;
496 } 494 }
497 return kNoTab; 495 return kNoTab;
498 } 496 }
499 497
500 void TabStripModel::UpdateWebContentsStateAt(int index, 498 void TabStripModel::UpdateWebContentsStateAt(int index,
501 TabStripModelObserver::TabChangeType change_type) { 499 TabStripModelObserver::TabChangeType change_type) {
502 DCHECK(ContainsIndex(index)); 500 DCHECK(ContainsIndex(index));
503 501
504 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 502 for (auto& observer : observers_)
505 TabChangedAt(GetWebContentsAtImpl(index), index, change_type)); 503 observer.TabChangedAt(GetWebContentsAtImpl(index), index, change_type);
506 } 504 }
507 505
508 void TabStripModel::CloseAllTabs() { 506 void TabStripModel::CloseAllTabs() {
509 // Set state so that observers can adjust their behavior to suit this 507 // Set state so that observers can adjust their behavior to suit this
510 // specific condition when CloseWebContentsAt causes a flurry of 508 // specific condition when CloseWebContentsAt causes a flurry of
511 // Close/Detach/Select notifications to be sent. 509 // Close/Detach/Select notifications to be sent.
512 closing_all_ = true; 510 closing_all_ = true;
513 std::vector<int> closing_tabs; 511 std::vector<int> closing_tabs;
514 for (int i = count() - 1; i >= 0; --i) 512 for (int i = count() - 1; i >= 0; --i)
515 closing_tabs.push_back(i); 513 closing_tabs.push_back(i);
516 InternalCloseTabs(closing_tabs, CLOSE_CREATE_HISTORICAL_TAB); 514 InternalCloseTabs(closing_tabs, CLOSE_CREATE_HISTORICAL_TAB);
517 } 515 }
518 516
519 bool TabStripModel::CloseWebContentsAt(int index, uint32_t close_types) { 517 bool TabStripModel::CloseWebContentsAt(int index, uint32_t close_types) {
520 DCHECK(ContainsIndex(index)); 518 DCHECK(ContainsIndex(index));
521 std::vector<int> closing_tabs; 519 std::vector<int> closing_tabs;
522 closing_tabs.push_back(index); 520 closing_tabs.push_back(index);
523 return InternalCloseTabs(closing_tabs, close_types); 521 return InternalCloseTabs(closing_tabs, close_types);
524 } 522 }
525 523
526 bool TabStripModel::TabsAreLoading() const { 524 bool TabStripModel::TabsAreLoading() const {
527 for (WebContentsDataVector::const_iterator iter = contents_data_.begin(); 525 for (const auto& data : contents_data_) {
528 iter != contents_data_.end(); ++iter) { 526 if (data->web_contents()->IsLoading())
529 if ((*iter)->web_contents()->IsLoading())
530 return true; 527 return true;
531 } 528 }
529
532 return false; 530 return false;
533 } 531 }
534 532
535 WebContents* TabStripModel::GetOpenerOfWebContentsAt(int index) { 533 WebContents* TabStripModel::GetOpenerOfWebContentsAt(int index) {
536 DCHECK(ContainsIndex(index)); 534 DCHECK(ContainsIndex(index));
537 return contents_data_[index]->opener(); 535 return contents_data_[index]->opener();
538 } 536 }
539 537
540 void TabStripModel::SetOpenerOfWebContentsAt(int index, 538 void TabStripModel::SetOpenerOfWebContentsAt(int index,
541 WebContents* opener) { 539 WebContents* opener) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // In this specific case we also want to reset the group relationship, 603 // In this specific case we also want to reset the group relationship,
606 // since it is now technically invalid. 604 // since it is now technically invalid.
607 ForgetGroup(contents); 605 ForgetGroup(contents);
608 } 606 }
609 } 607 }
610 } 608 }
611 609
612 void TabStripModel::ForgetAllOpeners() { 610 void TabStripModel::ForgetAllOpeners() {
613 // Forget all opener memories so we don't do anything weird with tab 611 // Forget all opener memories so we don't do anything weird with tab
614 // re-selection ordering. 612 // re-selection ordering.
615 for (WebContentsDataVector::const_iterator iter = contents_data_.begin(); 613 for (const auto& data : contents_data_)
616 iter != contents_data_.end(); ++iter) 614 data->set_opener(nullptr);
617 (*iter)->set_opener(NULL);
618 } 615 }
619 616
620 void TabStripModel::ForgetGroup(WebContents* contents) { 617 void TabStripModel::ForgetGroup(WebContents* contents) {
621 int index = GetIndexOfWebContents(contents); 618 int index = GetIndexOfWebContents(contents);
622 DCHECK(ContainsIndex(index)); 619 DCHECK(ContainsIndex(index));
623 contents_data_[index]->set_group(NULL); 620 contents_data_[index]->set_group(nullptr);
624 contents_data_[index]->set_opener(NULL); 621 contents_data_[index]->set_opener(nullptr);
625 } 622 }
626 623
627 bool TabStripModel::ShouldResetGroupOnSelect(WebContents* contents) const { 624 bool TabStripModel::ShouldResetGroupOnSelect(WebContents* contents) const {
628 int index = GetIndexOfWebContents(contents); 625 int index = GetIndexOfWebContents(contents);
629 DCHECK(ContainsIndex(index)); 626 DCHECK(ContainsIndex(index));
630 return contents_data_[index]->reset_group_on_select(); 627 return contents_data_[index]->reset_group_on_select();
631 } 628 }
632 629
633 void TabStripModel::SetTabBlocked(int index, bool blocked) { 630 void TabStripModel::SetTabBlocked(int index, bool blocked) {
634 DCHECK(ContainsIndex(index)); 631 DCHECK(ContainsIndex(index));
635 if (contents_data_[index]->blocked() == blocked) 632 if (contents_data_[index]->blocked() == blocked)
636 return; 633 return;
637 contents_data_[index]->set_blocked(blocked); 634 contents_data_[index]->set_blocked(blocked);
638 FOR_EACH_OBSERVER( 635 for (auto& observer : observers_)
639 TabStripModelObserver, observers_, 636 observer.TabBlockedStateChanged(contents_data_[index]->web_contents(),
640 TabBlockedStateChanged(contents_data_[index]->web_contents(), 637 index);
641 index));
642 } 638 }
643 639
644 void TabStripModel::SetTabPinned(int index, bool pinned) { 640 void TabStripModel::SetTabPinned(int index, bool pinned) {
645 DCHECK(ContainsIndex(index)); 641 DCHECK(ContainsIndex(index));
646 if (contents_data_[index]->pinned() == pinned) 642 if (contents_data_[index]->pinned() == pinned)
647 return; 643 return;
648 644
649 // The tab's position may have to change as the pinned tab state is changing. 645 // The tab's position may have to change as the pinned tab state is changing.
650 int non_pinned_tab_index = IndexOfFirstNonPinnedTab(); 646 int non_pinned_tab_index = IndexOfFirstNonPinnedTab();
651 contents_data_[index]->set_pinned(pinned); 647 contents_data_[index]->set_pinned(pinned);
652 if (pinned && index != non_pinned_tab_index) { 648 if (pinned && index != non_pinned_tab_index) {
653 MoveWebContentsAtImpl(index, non_pinned_tab_index, false); 649 MoveWebContentsAtImpl(index, non_pinned_tab_index, false);
654 index = non_pinned_tab_index; 650 index = non_pinned_tab_index;
655 } else if (!pinned && index + 1 != non_pinned_tab_index) { 651 } else if (!pinned && index + 1 != non_pinned_tab_index) {
656 MoveWebContentsAtImpl(index, non_pinned_tab_index - 1, false); 652 MoveWebContentsAtImpl(index, non_pinned_tab_index - 1, false);
657 index = non_pinned_tab_index - 1; 653 index = non_pinned_tab_index - 1;
658 } 654 }
659 655
660 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 656 for (auto& observer : observers_)
661 TabPinnedStateChanged( 657 observer.TabPinnedStateChanged(this, contents_data_[index]->web_contents(),
662 this, contents_data_[index]->web_contents(), index)); 658 index);
663 } 659 }
664 660
665 bool TabStripModel::IsTabPinned(int index) const { 661 bool TabStripModel::IsTabPinned(int index) const {
666 DCHECK(ContainsIndex(index)); 662 DCHECK(ContainsIndex(index));
667 return contents_data_[index]->pinned(); 663 return contents_data_[index]->pinned();
668 } 664 }
669 665
670 bool TabStripModel::IsTabBlocked(int index) const { 666 bool TabStripModel::IsTabBlocked(int index) const {
671 return contents_data_[index]->blocked(); 667 return contents_data_[index]->blocked();
672 } 668 }
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices, 1143 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices,
1148 uint32_t close_types) { 1144 uint32_t close_types) {
1149 if (indices.empty()) 1145 if (indices.empty())
1150 return true; 1146 return true;
1151 1147
1152 CloseTracker close_tracker(GetWebContentsFromIndices(indices)); 1148 CloseTracker close_tracker(GetWebContentsFromIndices(indices));
1153 1149
1154 base::WeakPtr<TabStripModel> ref(weak_factory_.GetWeakPtr()); 1150 base::WeakPtr<TabStripModel> ref(weak_factory_.GetWeakPtr());
1155 const bool closing_all = indices.size() == contents_data_.size(); 1151 const bool closing_all = indices.size() == contents_data_.size();
1156 if (closing_all) 1152 if (closing_all)
1157 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, WillCloseAllTabs()); 1153 for (auto& observer : observers_)
1154 observer.WillCloseAllTabs();
1158 1155
1159 // We only try the fast shutdown path if the whole browser process is *not* 1156 // We only try the fast shutdown path if the whole browser process is *not*
1160 // shutting down. Fast shutdown during browser termination is handled in 1157 // shutting down. Fast shutdown during browser termination is handled in
1161 // browser_shutdown::OnShutdownStarting. 1158 // browser_shutdown::OnShutdownStarting.
1162 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { 1159 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) {
1163 // Construct a map of processes to the number of associated tabs that are 1160 // Construct a map of processes to the number of associated tabs that are
1164 // closing. 1161 // closing.
1165 std::map<content::RenderProcessHost*, size_t> processes; 1162 std::map<content::RenderProcessHost*, size_t> processes;
1166 for (size_t i = 0; i < indices.size(); ++i) { 1163 for (size_t i = 0; i < indices.size(); ++i) {
1167 WebContents* closing_contents = GetWebContentsAtImpl(indices[i]); 1164 WebContents* closing_contents = GetWebContentsAtImpl(indices[i]);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 1200
1204 if (delegate_->RunUnloadListenerBeforeClosing(closing_contents)) { 1201 if (delegate_->RunUnloadListenerBeforeClosing(closing_contents)) {
1205 retval = false; 1202 retval = false;
1206 continue; 1203 continue;
1207 } 1204 }
1208 1205
1209 InternalCloseTab(closing_contents, index, 1206 InternalCloseTab(closing_contents, index,
1210 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0); 1207 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0);
1211 } 1208 }
1212 1209
1213 if (ref && closing_all && !retval) { 1210 if (ref && closing_all && !retval)
1214 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1211 for (auto& observer : observers_)
1215 CloseAllTabsCanceled()); 1212 observer.CloseAllTabsCanceled();
1216 }
1217 1213
1218 return retval; 1214 return retval;
1219 } 1215 }
1220 1216
1221 void TabStripModel::InternalCloseTab(WebContents* contents, 1217 void TabStripModel::InternalCloseTab(WebContents* contents,
1222 int index, 1218 int index,
1223 bool create_historical_tabs) { 1219 bool create_historical_tabs) {
1224 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1220 for (auto& observer : observers_)
1225 TabClosingAt(this, contents, index)); 1221 observer.TabClosingAt(this, contents, index);
1226 1222
1227 // Ask the delegate to save an entry for this tab in the historical tab 1223 // Ask the delegate to save an entry for this tab in the historical tab
1228 // database if applicable. 1224 // database if applicable.
1229 if (create_historical_tabs) 1225 if (create_historical_tabs)
1230 delegate_->CreateHistoricalTab(contents); 1226 delegate_->CreateHistoricalTab(contents);
1231 1227
1232 // Deleting the WebContents will call back to us via 1228 // Deleting the WebContents will call back to us via
1233 // WebContentsData::WebContentsDestroyed and detach it. 1229 // WebContentsData::WebContentsDestroyed and detach it.
1234 delete contents; 1230 delete contents;
1235 } 1231 }
1236 1232
1237 WebContents* TabStripModel::GetWebContentsAtImpl(int index) const { 1233 WebContents* TabStripModel::GetWebContentsAtImpl(int index) const {
1238 CHECK(ContainsIndex(index)) << 1234 CHECK(ContainsIndex(index)) <<
1239 "Failed to find: " << index << " in: " << count() << " entries."; 1235 "Failed to find: " << index << " in: " << count() << " entries.";
1240 return contents_data_[index]->web_contents(); 1236 return contents_data_[index]->web_contents();
1241 } 1237 }
1242 1238
1243 void TabStripModel::NotifyIfTabDeactivated(WebContents* contents) { 1239 void TabStripModel::NotifyIfTabDeactivated(WebContents* contents) {
1244 if (contents) { 1240 if (contents) {
1245 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1241 for (auto& observer : observers_)
1246 TabDeactivated(contents)); 1242 observer.TabDeactivated(contents);
1247 } 1243 }
1248 } 1244 }
1249 1245
1250 void TabStripModel::NotifyIfActiveTabChanged(WebContents* old_contents, 1246 void TabStripModel::NotifyIfActiveTabChanged(WebContents* old_contents,
1251 NotifyTypes notify_types) { 1247 NotifyTypes notify_types) {
1252 WebContents* new_contents = GetWebContentsAtImpl(active_index()); 1248 WebContents* new_contents = GetWebContentsAtImpl(active_index());
1253 if (old_contents != new_contents) { 1249 if (old_contents != new_contents) {
1254 int reason = notify_types == NOTIFY_USER_GESTURE 1250 int reason = notify_types == NOTIFY_USER_GESTURE
1255 ? TabStripModelObserver::CHANGE_REASON_USER_GESTURE 1251 ? TabStripModelObserver::CHANGE_REASON_USER_GESTURE
1256 : TabStripModelObserver::CHANGE_REASON_NONE; 1252 : TabStripModelObserver::CHANGE_REASON_NONE;
1257 CHECK(!in_notify_); 1253 CHECK(!in_notify_);
1258 in_notify_ = true; 1254 in_notify_ = true;
1259 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1255 for (auto& observer : observers_)
1260 ActiveTabChanged(old_contents, 1256 observer.ActiveTabChanged(old_contents, new_contents, active_index(),
1261 new_contents, 1257 reason);
1262 active_index(),
1263 reason));
1264 in_notify_ = false; 1258 in_notify_ = false;
1265 } 1259 }
1266 } 1260 }
1267 1261
1268 void TabStripModel::NotifyIfActiveOrSelectionChanged( 1262 void TabStripModel::NotifyIfActiveOrSelectionChanged(
1269 WebContents* old_contents, 1263 WebContents* old_contents,
1270 NotifyTypes notify_types, 1264 NotifyTypes notify_types,
1271 const ui::ListSelectionModel& old_model) { 1265 const ui::ListSelectionModel& old_model) {
1272 NotifyIfActiveTabChanged(old_contents, notify_types); 1266 NotifyIfActiveTabChanged(old_contents, notify_types);
1273 1267
1274 if (!selection_model().Equals(old_model)) { 1268 if (!selection_model().Equals(old_model)) {
1275 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1269 for (auto& observer : observers_)
1276 TabSelectionChanged(this, old_model)); 1270 observer.TabSelectionChanged(this, old_model);
1277 } 1271 }
1278 } 1272 }
1279 1273
1280 void TabStripModel::SetSelection( 1274 void TabStripModel::SetSelection(
1281 const ui::ListSelectionModel& new_model, 1275 const ui::ListSelectionModel& new_model,
1282 NotifyTypes notify_types) { 1276 NotifyTypes notify_types) {
1283 WebContents* old_contents = GetActiveWebContents(); 1277 WebContents* old_contents = GetActiveWebContents();
1284 ui::ListSelectionModel old_model; 1278 ui::ListSelectionModel old_model;
1285 old_model.Copy(selection_model_); 1279 old_model.Copy(selection_model_);
1286 if (new_model.active() != selection_model_.active()) 1280 if (new_model.active() != selection_model_.active())
(...skipping 12 matching lines...) Expand all
1299 int delta = next ? 1 : -1; 1293 int delta = next ? 1 : -1;
1300 index = (index + count() + delta) % count(); 1294 index = (index + count() + delta) % count();
1301 ActivateTabAt(index, true); 1295 ActivateTabAt(index, true);
1302 } 1296 }
1303 1297
1304 void TabStripModel::MoveWebContentsAtImpl(int index, 1298 void TabStripModel::MoveWebContentsAtImpl(int index,
1305 int to_position, 1299 int to_position,
1306 bool select_after_move) { 1300 bool select_after_move) {
1307 FixOpenersAndGroupsReferencing(index); 1301 FixOpenersAndGroupsReferencing(index);
1308 1302
1309 WebContentsData* moved_data = contents_data_[index]; 1303 std::unique_ptr<WebContentsData> moved_data =
1304 std::move(contents_data_[index]);
1305 WebContents* web_contents = moved_data->web_contents();
1310 contents_data_.erase(contents_data_.begin() + index); 1306 contents_data_.erase(contents_data_.begin() + index);
1311 contents_data_.insert(contents_data_.begin() + to_position, moved_data); 1307 contents_data_.insert(contents_data_.begin() + to_position,
1308 std::move(moved_data));
1312 1309
1313 selection_model_.Move(index, to_position); 1310 selection_model_.Move(index, to_position);
1314 if (!selection_model_.IsSelected(to_position) && select_after_move) { 1311 if (!selection_model_.IsSelected(to_position) && select_after_move) {
1315 // TODO(sky): why doesn't this code notify observers? 1312 // TODO(sky): why doesn't this code notify observers?
1316 selection_model_.SetSelectedIndex(to_position); 1313 selection_model_.SetSelectedIndex(to_position);
1317 } 1314 }
1318 1315
1319 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1316 for (auto& observer : observers_)
1320 TabMoved(moved_data->web_contents(), index, to_position)); 1317 observer.TabMoved(web_contents, index, to_position);
1321 } 1318 }
1322 1319
1323 void TabStripModel::MoveSelectedTabsToImpl(int index, 1320 void TabStripModel::MoveSelectedTabsToImpl(int index,
1324 size_t start, 1321 size_t start,
1325 size_t length) { 1322 size_t length) {
1326 DCHECK(start < selection_model_.selected_indices().size() && 1323 DCHECK(start < selection_model_.selected_indices().size() &&
1327 start + length <= selection_model_.selected_indices().size()); 1324 start + length <= selection_model_.selected_indices().size());
1328 size_t end = start + length; 1325 size_t end = start + length;
1329 int count_before_index = 0; 1326 int count_before_index = 0;
1330 for (size_t i = start; i < end && 1327 for (size_t i = start; i < end &&
(...skipping 19 matching lines...) Expand all
1350 if (selection_model_.selected_indices()[tab_index] != target_index) { 1347 if (selection_model_.selected_indices()[tab_index] != target_index) {
1351 MoveWebContentsAt(selection_model_.selected_indices()[tab_index], 1348 MoveWebContentsAt(selection_model_.selected_indices()[tab_index],
1352 target_index, false); 1349 target_index, false);
1353 } 1350 }
1354 tab_index++; 1351 tab_index++;
1355 target_index++; 1352 target_index++;
1356 } 1353 }
1357 } 1354 }
1358 1355
1359 // static 1356 // static
1360 bool TabStripModel::OpenerMatches(const WebContentsData* data, 1357 bool TabStripModel::OpenerMatches(const std::unique_ptr<WebContentsData>& data,
1361 const WebContents* opener, 1358 const WebContents* opener,
1362 bool use_group) { 1359 bool use_group) {
1363 return data->opener() == opener || (use_group && data->group() == opener); 1360 return data->opener() == opener || (use_group && data->group() == opener);
1364 } 1361 }
1365 1362
1366 void TabStripModel::FixOpenersAndGroupsReferencing(int index) { 1363 void TabStripModel::FixOpenersAndGroupsReferencing(int index) {
1367 WebContents* old_contents = GetWebContentsAtImpl(index); 1364 WebContents* old_contents = GetWebContentsAtImpl(index);
1368 for (WebContentsData* data : contents_data_) { 1365 for (auto& data : contents_data_) {
1369 if (data->group() == old_contents) 1366 if (data->group() == old_contents)
1370 data->set_group(contents_data_[index]->group()); 1367 data->set_group(contents_data_[index]->group());
1371 if (data->opener() == old_contents) 1368 if (data->opener() == old_contents)
1372 data->set_opener(contents_data_[index]->opener()); 1369 data->set_opener(contents_data_[index]->opener());
1373 } 1370 }
1374 } 1371 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/tabs/tab_strip_model.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698