Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/tabs/tab_strip_model.h" | 5 #include "chrome/browser/tabs/tab_strip_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/stl_util-inl.h" | 10 #include "base/stl_util-inl.h" |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 | 782 |
| 783 bool TabStripModel::IsNewTabAtEndOfTabStrip(TabContents* contents) const { | 783 bool TabStripModel::IsNewTabAtEndOfTabStrip(TabContents* contents) const { |
| 784 return LowerCaseEqualsASCII(contents->GetURL().spec(), | 784 return LowerCaseEqualsASCII(contents->GetURL().spec(), |
| 785 chrome::kChromeUINewTabURL) && | 785 chrome::kChromeUINewTabURL) && |
| 786 contents == GetContentsAt(count() - 1) && | 786 contents == GetContentsAt(count() - 1) && |
| 787 contents->controller().entry_count() == 1; | 787 contents->controller().entry_count() == 1; |
| 788 } | 788 } |
| 789 | 789 |
| 790 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices, | 790 bool TabStripModel::InternalCloseTabs(const std::vector<int>& indices, |
| 791 uint32 close_types) { | 791 uint32 close_types) { |
| 792 if (indices.empty()) | |
| 793 return true; | |
| 794 | |
| 792 bool retval = true; | 795 bool retval = true; |
| 793 | 796 |
| 797 // Map the indices to TabContents, that way if deleting a tab deletes other | |
| 798 // tabs we're ok. | |
|
Ben Goodger (Google)
2010/11/11 22:20:28
Can you mention what situations would cause one ta
| |
| 799 std::vector<TabContents*> tabs; | |
| 800 for (size_t i = 0; i < indices.size(); ++i) | |
| 801 tabs.push_back(GetContentsAt(indices[i])); | |
| 802 | |
| 794 // We only try the fast shutdown path if the whole browser process is *not* | 803 // We only try the fast shutdown path if the whole browser process is *not* |
| 795 // shutting down. Fast shutdown during browser termination is handled in | 804 // shutting down. Fast shutdown during browser termination is handled in |
| 796 // BrowserShutdown. | 805 // BrowserShutdown. |
| 797 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { | 806 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID) { |
| 798 // Construct a map of processes to the number of associated tabs that are | 807 // Construct a map of processes to the number of associated tabs that are |
| 799 // closing. | 808 // closing. |
| 800 std::map<RenderProcessHost*, size_t> processes; | 809 std::map<RenderProcessHost*, size_t> processes; |
| 801 for (size_t i = 0; i < indices.size(); ++i) { | 810 for (size_t i = 0; i < indices.size(); ++i) { |
| 802 if (!delegate_->CanCloseContentsAt(indices[i])) { | 811 if (!delegate_->CanCloseContentsAt(indices[i])) { |
| 803 retval = false; | 812 retval = false; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 817 | 826 |
| 818 // Try to fast shutdown the tabs that can close. | 827 // Try to fast shutdown the tabs that can close. |
| 819 for (std::map<RenderProcessHost*, size_t>::iterator iter = | 828 for (std::map<RenderProcessHost*, size_t>::iterator iter = |
| 820 processes.begin(); | 829 processes.begin(); |
| 821 iter != processes.end(); ++iter) { | 830 iter != processes.end(); ++iter) { |
| 822 iter->first->FastShutdownForPageCount(iter->second); | 831 iter->first->FastShutdownForPageCount(iter->second); |
| 823 } | 832 } |
| 824 } | 833 } |
| 825 | 834 |
| 826 // We now return to our regularly scheduled shutdown procedure. | 835 // We now return to our regularly scheduled shutdown procedure. |
| 827 for (size_t i = 0; i < indices.size(); ++i) { | 836 for (size_t i = 0; i < tabs.size(); ++i) { |
| 828 TabContents* detached_contents = GetContentsAt(indices[i]); | 837 TabContents* detached_contents = tabs[i]; |
| 838 int index = GetIndexOfTabContents(detached_contents); | |
| 839 // Make sure we still contain the tab. | |
| 840 if (index == kNoTab) | |
| 841 continue; | |
| 842 | |
| 829 detached_contents->OnCloseStarted(); | 843 detached_contents->OnCloseStarted(); |
| 830 | 844 |
| 831 if (!delegate_->CanCloseContentsAt(indices[i])) { | 845 if (!delegate_->CanCloseContentsAt(index)) { |
| 832 retval = false; | 846 retval = false; |
| 833 continue; | 847 continue; |
| 834 } | 848 } |
| 835 | 849 |
| 836 // Update the explicitly closed state. If the unload handlers cancel the | 850 // Update the explicitly closed state. If the unload handlers cancel the |
| 837 // close the state is reset in Browser. We don't update the explicitly | 851 // close the state is reset in Browser. We don't update the explicitly |
| 838 // closed state if already marked as explicitly closed as unload handlers | 852 // closed state if already marked as explicitly closed as unload handlers |
| 839 // call back to this if the close is allowed. | 853 // call back to this if the close is allowed. |
| 840 if (!detached_contents->closed_by_user_gesture()) { | 854 if (!detached_contents->closed_by_user_gesture()) { |
| 841 detached_contents->set_closed_by_user_gesture( | 855 detached_contents->set_closed_by_user_gesture( |
| 842 close_types & CLOSE_USER_GESTURE); | 856 close_types & CLOSE_USER_GESTURE); |
| 843 } | 857 } |
| 844 | 858 |
| 845 if (delegate_->RunUnloadListenerBeforeClosing(detached_contents)) { | 859 if (delegate_->RunUnloadListenerBeforeClosing(detached_contents)) { |
| 846 retval = false; | 860 retval = false; |
| 847 continue; | 861 continue; |
| 848 } | 862 } |
| 849 | 863 |
| 850 InternalCloseTab(detached_contents, indices[i], | 864 InternalCloseTab(detached_contents, index, |
| 851 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0); | 865 (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0); |
| 852 } | 866 } |
| 853 | 867 |
| 854 return retval; | 868 return retval; |
| 855 } | 869 } |
| 856 | 870 |
| 857 void TabStripModel::InternalCloseTab(TabContents* contents, | 871 void TabStripModel::InternalCloseTab(TabContents* contents, |
| 858 int index, | 872 int index, |
| 859 bool create_historical_tabs) { | 873 bool create_historical_tabs) { |
| 860 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, | 874 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 924 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, | 938 FOR_EACH_OBSERVER(TabStripModelObserver, observers_, |
| 925 TabMoved(moved_data->contents, index, to_position)); | 939 TabMoved(moved_data->contents, index, to_position)); |
| 926 } | 940 } |
| 927 | 941 |
| 928 // static | 942 // static |
| 929 bool TabStripModel::OpenerMatches(const TabContentsData* data, | 943 bool TabStripModel::OpenerMatches(const TabContentsData* data, |
| 930 const NavigationController* opener, | 944 const NavigationController* opener, |
| 931 bool use_group) { | 945 bool use_group) { |
| 932 return data->opener == opener || (use_group && data->group == opener); | 946 return data->opener == opener || (use_group && data->group == opener); |
| 933 } | 947 } |
| OLD | NEW |