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/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_)
sky 2016/10/13 00:11:05 Please use a {} here
Avi (use Gerrit) 2016/10/13 15:00:50 Done.
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
532 return false; 529 return false;
533 } 530 }
534 531
535 WebContents* TabStripModel::GetOpenerOfWebContentsAt(int index) { 532 WebContents* TabStripModel::GetOpenerOfWebContentsAt(int index) {
536 DCHECK(ContainsIndex(index)); 533 DCHECK(ContainsIndex(index));
537 return contents_data_[index]->opener(); 534 return contents_data_[index]->opener();
538 } 535 }
539 536
540 void TabStripModel::SetOpenerOfWebContentsAt(int index, 537 void TabStripModel::SetOpenerOfWebContentsAt(int index,
541 WebContents* opener) { 538 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, 602 // In this specific case we also want to reset the group relationship,
606 // since it is now technically invalid. 603 // since it is now technically invalid.
607 ForgetGroup(contents); 604 ForgetGroup(contents);
608 } 605 }
609 } 606 }
610 } 607 }
611 608
612 void TabStripModel::ForgetAllOpeners() { 609 void TabStripModel::ForgetAllOpeners() {
613 // Forget all opener memories so we don't do anything weird with tab 610 // Forget all opener memories so we don't do anything weird with tab
614 // re-selection ordering. 611 // re-selection ordering.
615 for (WebContentsDataVector::const_iterator iter = contents_data_.begin(); 612 for (const auto& data : contents_data_)
616 iter != contents_data_.end(); ++iter) 613 data->set_opener(nullptr);
617 (*iter)->set_opener(NULL);
618 } 614 }
619 615
620 void TabStripModel::ForgetGroup(WebContents* contents) { 616 void TabStripModel::ForgetGroup(WebContents* contents) {
621 int index = GetIndexOfWebContents(contents); 617 int index = GetIndexOfWebContents(contents);
622 DCHECK(ContainsIndex(index)); 618 DCHECK(ContainsIndex(index));
623 contents_data_[index]->set_group(NULL); 619 contents_data_[index]->set_group(nullptr);
624 contents_data_[index]->set_opener(NULL); 620 contents_data_[index]->set_opener(nullptr);
625 } 621 }
626 622
627 bool TabStripModel::ShouldResetGroupOnSelect(WebContents* contents) const { 623 bool TabStripModel::ShouldResetGroupOnSelect(WebContents* contents) const {
628 int index = GetIndexOfWebContents(contents); 624 int index = GetIndexOfWebContents(contents);
629 DCHECK(ContainsIndex(index)); 625 DCHECK(ContainsIndex(index));
630 return contents_data_[index]->reset_group_on_select(); 626 return contents_data_[index]->reset_group_on_select();
631 } 627 }
632 628
633 void TabStripModel::SetTabBlocked(int index, bool blocked) { 629 void TabStripModel::SetTabBlocked(int index, bool blocked) {
634 DCHECK(ContainsIndex(index)); 630 DCHECK(ContainsIndex(index));
635 if (contents_data_[index]->blocked() == blocked) 631 if (contents_data_[index]->blocked() == blocked)
636 return; 632 return;
637 contents_data_[index]->set_blocked(blocked); 633 contents_data_[index]->set_blocked(blocked);
638 FOR_EACH_OBSERVER( 634 for (auto& observer : observers_)
639 TabStripModelObserver, observers_, 635 observer.TabBlockedStateChanged(contents_data_[index]->web_contents(),
640 TabBlockedStateChanged(contents_data_[index]->web_contents(), 636 index);
641 index));
642 } 637 }
643 638
644 void TabStripModel::SetTabPinned(int index, bool pinned) { 639 void TabStripModel::SetTabPinned(int index, bool pinned) {
645 DCHECK(ContainsIndex(index)); 640 DCHECK(ContainsIndex(index));
646 if (contents_data_[index]->pinned() == pinned) 641 if (contents_data_[index]->pinned() == pinned)
647 return; 642 return;
648 643
649 // The tab's position may have to change as the pinned tab state is changing. 644 // The tab's position may have to change as the pinned tab state is changing.
650 int non_pinned_tab_index = IndexOfFirstNonPinnedTab(); 645 int non_pinned_tab_index = IndexOfFirstNonPinnedTab();
651 contents_data_[index]->set_pinned(pinned); 646 contents_data_[index]->set_pinned(pinned);
652 if (pinned && index != non_pinned_tab_index) { 647 if (pinned && index != non_pinned_tab_index) {
653 MoveWebContentsAtImpl(index, non_pinned_tab_index, false); 648 MoveWebContentsAtImpl(index, non_pinned_tab_index, false);
654 index = non_pinned_tab_index; 649 index = non_pinned_tab_index;
655 } else if (!pinned && index + 1 != non_pinned_tab_index) { 650 } else if (!pinned && index + 1 != non_pinned_tab_index) {
656 MoveWebContentsAtImpl(index, non_pinned_tab_index - 1, false); 651 MoveWebContentsAtImpl(index, non_pinned_tab_index - 1, false);
657 index = non_pinned_tab_index - 1; 652 index = non_pinned_tab_index - 1;
658 } 653 }
659 654
660 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 655 for (auto& observer : observers_)
661 TabPinnedStateChanged( 656 observer.TabPinnedStateChanged(this, contents_data_[index]->web_contents(),
662 this, contents_data_[index]->web_contents(), index)); 657 index);
663 } 658 }
664 659
665 bool TabStripModel::IsTabPinned(int index) const { 660 bool TabStripModel::IsTabPinned(int index) const {
666 DCHECK(ContainsIndex(index)); 661 DCHECK(ContainsIndex(index));
667 return contents_data_[index]->pinned(); 662 return contents_data_[index]->pinned();
668 } 663 }
669 664
670 bool TabStripModel::IsTabBlocked(int index) const { 665 bool TabStripModel::IsTabBlocked(int index) const {
671 return contents_data_[index]->blocked(); 666 return contents_data_[index]->blocked();
672 } 667 }
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices, 1142 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices,
1148 uint32_t close_types) { 1143 uint32_t close_types) {
1149 if (indices.empty()) 1144 if (indices.empty())
1150 return true; 1145 return true;
1151 1146
1152 CloseTracker close_tracker(GetWebContentsFromIndices(indices)); 1147 CloseTracker close_tracker(GetWebContentsFromIndices(indices));
1153 1148
1154 base::WeakPtr<TabStripModel> ref(weak_factory_.GetWeakPtr()); 1149 base::WeakPtr<TabStripModel> ref(weak_factory_.GetWeakPtr());
1155 const bool closing_all = indices.size() == contents_data_.size(); 1150 const bool closing_all = indices.size() == contents_data_.size();
1156 if (closing_all) 1151 if (closing_all)
1157 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, WillCloseAllTabs()); 1152 for (auto& observer : observers_)
1153 observer.WillCloseAllTabs();
1158 1154
1159 // We only try the fast shutdown path if the whole browser process is *not* 1155 // 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 1156 // shutting down. Fast shutdown during browser termination is handled in
1161 // browser_shutdown::OnShutdownStarting. 1157 // browser_shutdown::OnShutdownStarting.
1162 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { 1158 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) {
1163 // Construct a map of processes to the number of associated tabs that are 1159 // Construct a map of processes to the number of associated tabs that are
1164 // closing. 1160 // closing.
1165 std::map<content::RenderProcessHost*, size_t> processes; 1161 std::map<content::RenderProcessHost*, size_t> processes;
1166 for (size_t i = 0; i < indices.size(); ++i) { 1162 for (size_t i = 0; i < indices.size(); ++i) {
1167 WebContents* closing_contents = GetWebContentsAtImpl(indices[i]); 1163 WebContents* closing_contents = GetWebContentsAtImpl(indices[i]);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 1199
1204 if (delegate_->RunUnloadListenerBeforeClosing(closing_contents)) { 1200 if (delegate_->RunUnloadListenerBeforeClosing(closing_contents)) {
1205 retval = false; 1201 retval = false;
1206 continue; 1202 continue;
1207 } 1203 }
1208 1204
1209 InternalCloseTab(closing_contents, index, 1205 InternalCloseTab(closing_contents, index,
1210 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0); 1206 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0);
1211 } 1207 }
1212 1208
1213 if (ref && closing_all && !retval) { 1209 if (ref && closing_all && !retval)
1214 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1210 for (auto& observer : observers_)
1215 CloseAllTabsCanceled()); 1211 observer.CloseAllTabsCanceled();
1216 }
1217 1212
1218 return retval; 1213 return retval;
1219 } 1214 }
1220 1215
1221 void TabStripModel::InternalCloseTab(WebContents* contents, 1216 void TabStripModel::InternalCloseTab(WebContents* contents,
1222 int index, 1217 int index,
1223 bool create_historical_tabs) { 1218 bool create_historical_tabs) {
1224 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1219 for (auto& observer : observers_)
1225 TabClosingAt(this, contents, index)); 1220 observer.TabClosingAt(this, contents, index);
1226 1221
1227 // Ask the delegate to save an entry for this tab in the historical tab 1222 // Ask the delegate to save an entry for this tab in the historical tab
1228 // database if applicable. 1223 // database if applicable.
1229 if (create_historical_tabs) 1224 if (create_historical_tabs)
1230 delegate_->CreateHistoricalTab(contents); 1225 delegate_->CreateHistoricalTab(contents);
1231 1226
1232 // Deleting the WebContents will call back to us via 1227 // Deleting the WebContents will call back to us via
1233 // WebContentsData::WebContentsDestroyed and detach it. 1228 // WebContentsData::WebContentsDestroyed and detach it.
1234 delete contents; 1229 delete contents;
1235 } 1230 }
1236 1231
1237 WebContents* TabStripModel::GetWebContentsAtImpl(int index) const { 1232 WebContents* TabStripModel::GetWebContentsAtImpl(int index) const {
1238 CHECK(ContainsIndex(index)) << 1233 CHECK(ContainsIndex(index)) <<
1239 "Failed to find: " << index << " in: " << count() << " entries."; 1234 "Failed to find: " << index << " in: " << count() << " entries.";
1240 return contents_data_[index]->web_contents(); 1235 return contents_data_[index]->web_contents();
1241 } 1236 }
1242 1237
1243 void TabStripModel::NotifyIfTabDeactivated(WebContents* contents) { 1238 void TabStripModel::NotifyIfTabDeactivated(WebContents* contents) {
1244 if (contents) { 1239 if (contents)
sky 2016/10/13 00:11:05 use {}
Avi (use Gerrit) 2016/10/13 15:00:50 Done.
1245 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1240 for (auto& observer : observers_)
1246 TabDeactivated(contents)); 1241 observer.TabDeactivated(contents);
1247 }
1248 } 1242 }
1249 1243
1250 void TabStripModel::NotifyIfActiveTabChanged(WebContents* old_contents, 1244 void TabStripModel::NotifyIfActiveTabChanged(WebContents* old_contents,
1251 NotifyTypes notify_types) { 1245 NotifyTypes notify_types) {
1252 WebContents* new_contents = GetWebContentsAtImpl(active_index()); 1246 WebContents* new_contents = GetWebContentsAtImpl(active_index());
1253 if (old_contents != new_contents) { 1247 if (old_contents != new_contents) {
1254 int reason = notify_types == NOTIFY_USER_GESTURE 1248 int reason = notify_types == NOTIFY_USER_GESTURE
1255 ? TabStripModelObserver::CHANGE_REASON_USER_GESTURE 1249 ? TabStripModelObserver::CHANGE_REASON_USER_GESTURE
1256 : TabStripModelObserver::CHANGE_REASON_NONE; 1250 : TabStripModelObserver::CHANGE_REASON_NONE;
1257 CHECK(!in_notify_); 1251 CHECK(!in_notify_);
1258 in_notify_ = true; 1252 in_notify_ = true;
1259 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1253 for (auto& observer : observers_)
1260 ActiveTabChanged(old_contents, 1254 observer.ActiveTabChanged(old_contents, new_contents, active_index(),
1261 new_contents, 1255 reason);
1262 active_index(),
1263 reason));
1264 in_notify_ = false; 1256 in_notify_ = false;
1265 } 1257 }
1266 } 1258 }
1267 1259
1268 void TabStripModel::NotifyIfActiveOrSelectionChanged( 1260 void TabStripModel::NotifyIfActiveOrSelectionChanged(
1269 WebContents* old_contents, 1261 WebContents* old_contents,
1270 NotifyTypes notify_types, 1262 NotifyTypes notify_types,
1271 const ui::ListSelectionModel& old_model) { 1263 const ui::ListSelectionModel& old_model) {
1272 NotifyIfActiveTabChanged(old_contents, notify_types); 1264 NotifyIfActiveTabChanged(old_contents, notify_types);
1273 1265
1274 if (!selection_model().Equals(old_model)) { 1266 if (!selection_model().Equals(old_model))
sky 2016/10/13 00:11:05 use {}
1275 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1267 for (auto& observer : observers_)
1276 TabSelectionChanged(this, old_model)); 1268 observer.TabSelectionChanged(this, old_model);
1277 }
1278 } 1269 }
1279 1270
1280 void TabStripModel::SetSelection( 1271 void TabStripModel::SetSelection(
1281 const ui::ListSelectionModel& new_model, 1272 const ui::ListSelectionModel& new_model,
1282 NotifyTypes notify_types) { 1273 NotifyTypes notify_types) {
1283 WebContents* old_contents = GetActiveWebContents(); 1274 WebContents* old_contents = GetActiveWebContents();
1284 ui::ListSelectionModel old_model; 1275 ui::ListSelectionModel old_model;
1285 old_model.Copy(selection_model_); 1276 old_model.Copy(selection_model_);
1286 if (new_model.active() != selection_model_.active()) 1277 if (new_model.active() != selection_model_.active())
1287 NotifyIfTabDeactivated(old_contents); 1278 NotifyIfTabDeactivated(old_contents);
(...skipping 11 matching lines...) Expand all
1299 int delta = next ? 1 : -1; 1290 int delta = next ? 1 : -1;
1300 index = (index + count() + delta) % count(); 1291 index = (index + count() + delta) % count();
1301 ActivateTabAt(index, true); 1292 ActivateTabAt(index, true);
1302 } 1293 }
1303 1294
1304 void TabStripModel::MoveWebContentsAtImpl(int index, 1295 void TabStripModel::MoveWebContentsAtImpl(int index,
1305 int to_position, 1296 int to_position,
1306 bool select_after_move) { 1297 bool select_after_move) {
1307 FixOpenersAndGroupsReferencing(index); 1298 FixOpenersAndGroupsReferencing(index);
1308 1299
1309 WebContentsData* moved_data = contents_data_[index]; 1300 std::unique_ptr<WebContentsData> moved_data =
1301 std::move(contents_data_[index]);
1302 WebContents* web_contents = moved_data->web_contents();
1310 contents_data_.erase(contents_data_.begin() + index); 1303 contents_data_.erase(contents_data_.begin() + index);
1311 contents_data_.insert(contents_data_.begin() + to_position, moved_data); 1304 contents_data_.insert(contents_data_.begin() + to_position,
1305 std::move(moved_data));
1312 1306
1313 selection_model_.Move(index, to_position); 1307 selection_model_.Move(index, to_position);
1314 if (!selection_model_.IsSelected(to_position) && select_after_move) { 1308 if (!selection_model_.IsSelected(to_position) && select_after_move) {
1315 // TODO(sky): why doesn't this code notify observers? 1309 // TODO(sky): why doesn't this code notify observers?
1316 selection_model_.SetSelectedIndex(to_position); 1310 selection_model_.SetSelectedIndex(to_position);
1317 } 1311 }
1318 1312
1319 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, 1313 for (auto& observer : observers_)
1320 TabMoved(moved_data->web_contents(), index, to_position)); 1314 observer.TabMoved(web_contents, index, to_position);
1321 } 1315 }
1322 1316
1323 void TabStripModel::MoveSelectedTabsToImpl(int index, 1317 void TabStripModel::MoveSelectedTabsToImpl(int index,
1324 size_t start, 1318 size_t start,
1325 size_t length) { 1319 size_t length) {
1326 DCHECK(start < selection_model_.selected_indices().size() && 1320 DCHECK(start < selection_model_.selected_indices().size() &&
1327 start + length <= selection_model_.selected_indices().size()); 1321 start + length <= selection_model_.selected_indices().size());
1328 size_t end = start + length; 1322 size_t end = start + length;
1329 int count_before_index = 0; 1323 int count_before_index = 0;
1330 for (size_t i = start; i < end && 1324 for (size_t i = start; i < end &&
(...skipping 19 matching lines...) Expand all
1350 if (selection_model_.selected_indices()[tab_index] != target_index) { 1344 if (selection_model_.selected_indices()[tab_index] != target_index) {
1351 MoveWebContentsAt(selection_model_.selected_indices()[tab_index], 1345 MoveWebContentsAt(selection_model_.selected_indices()[tab_index],
1352 target_index, false); 1346 target_index, false);
1353 } 1347 }
1354 tab_index++; 1348 tab_index++;
1355 target_index++; 1349 target_index++;
1356 } 1350 }
1357 } 1351 }
1358 1352
1359 // static 1353 // static
1360 bool TabStripModel::OpenerMatches(const WebContentsData* data, 1354 bool TabStripModel::OpenerMatches(const std::unique_ptr<WebContentsData>& data,
1361 const WebContents* opener, 1355 const WebContents* opener,
1362 bool use_group) { 1356 bool use_group) {
1363 return data->opener() == opener || (use_group && data->group() == opener); 1357 return data->opener() == opener || (use_group && data->group() == opener);
1364 } 1358 }
1365 1359
1366 void TabStripModel::FixOpenersAndGroupsReferencing(int index) { 1360 void TabStripModel::FixOpenersAndGroupsReferencing(int index) {
1367 WebContents* old_contents = GetWebContentsAtImpl(index); 1361 WebContents* old_contents = GetWebContentsAtImpl(index);
1368 for (WebContentsData* data : contents_data_) { 1362 for (auto& data : contents_data_) {
1369 if (data->group() == old_contents) 1363 if (data->group() == old_contents)
1370 data->set_group(contents_data_[index]->group()); 1364 data->set_group(contents_data_[index]->group());
1371 if (data->opener() == old_contents) 1365 if (data->opener() == old_contents)
1372 data->set_opener(contents_data_[index]->opener()); 1366 data->set_opener(contents_data_[index]->opener());
1373 } 1367 }
1374 } 1368 }
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