diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 22:45:40 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 22:45:40 +0000 |
commit | ecc523f661dd66ab6dafa276971c84f491f2521e (patch) | |
tree | bf6bbe6619420fb19210ed99f31ac385614137b9 | |
parent | 19e300520d7474d430e2bb904a564253fe66a547 (diff) | |
download | chromium_src-ecc523f661dd66ab6dafa276971c84f491f2521e.zip chromium_src-ecc523f661dd66ab6dafa276971c84f491f2521e.tar.gz chromium_src-ecc523f661dd66ab6dafa276971c84f491f2521e.tar.bz2 |
Create a TabHandler object to decouple Browser from TabStripModel API.
Currently it's just a pass-through so everything still works while I begin to move stuff out of Browser down into it.
BUG=none
TEST=existing unittests.
Review URL: http://codereview.chromium.org/3412041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60860 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser.cc | 235 | ||||
-rw-r--r-- | chrome/browser/browser.h | 59 | ||||
-rw-r--r-- | chrome/browser/tabs/default_tab_handler.cc | 198 | ||||
-rw-r--r-- | chrome/browser/tabs/default_tab_handler.h | 88 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_handler.h | 36 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 3 |
6 files changed, 488 insertions, 131 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 783ff7e..1d2c82f 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -182,7 +182,8 @@ Browser::Browser(Type type, Profile* profile) : type_(type), profile_(profile), window_(NULL), - tabstrip_model_(new TabStripModel(this, profile)), + ALLOW_THIS_IN_INITIALIZER_LIST( + tab_handler_(TabHandler::CreateTabHandler(this))), command_updater_(this), toolbar_model_(this), chrome_updater_factory_(this), @@ -195,8 +196,6 @@ Browser::Browser(Type type, Profile* profile) last_blocked_command_disposition_(CURRENT_TAB), pending_web_app_action_(NONE), extension_app_(NULL) { - tabstrip_model_->AddObserver(this); - registrar_.Add(this, NotificationType::SSL_VISIBLE_STATE_CHANGED, NotificationService::AllSources()); registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED, @@ -247,10 +246,6 @@ Browser::Browser(Type type, Profile* profile) } Browser::~Browser() { - // The tab strip should not have any significant tabs at this point. - DCHECK(!tabstrip_model_->HasNonPhantomTabs()); - tabstrip_model_->RemoveObserver(this); - if (profile_->GetProfileSyncService()) profile_->GetProfileSyncService()->RemoveObserver(this); @@ -693,7 +688,8 @@ SkBitmap Browser::GetCurrentPageIcon() const { } string16 Browser::GetWindowTitleForCurrentTab() const { - TabContents* contents = tabstrip_model_->GetSelectedTabContents(); + TabContents* contents = + tab_handler_->GetTabStripModel()->GetSelectedTabContents(); string16 title; // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the @@ -816,40 +812,40 @@ void Browser::InProgressDownloadResponse(bool cancel_downloads) { // Browser, TabStripModel pass-thrus: int Browser::tab_count() const { - return tabstrip_model_->count(); + return tab_handler_->GetTabStripModel()->count(); } int Browser::selected_index() const { - return tabstrip_model_->selected_index(); + return tab_handler_->GetTabStripModel()->selected_index(); } int Browser::GetIndexOfController( const NavigationController* controller) const { - return tabstrip_model_->GetIndexOfController(controller); + return tab_handler_->GetTabStripModel()->GetIndexOfController(controller); } TabContents* Browser::GetTabContentsAt(int index) const { - return tabstrip_model_->GetTabContentsAt(index); + return tab_handler_->GetTabStripModel()->GetTabContentsAt(index); } TabContents* Browser::GetSelectedTabContents() const { - return tabstrip_model_->GetSelectedTabContents(); + return tab_handler_->GetTabStripModel()->GetSelectedTabContents(); } void Browser::SelectTabContentsAt(int index, bool user_gesture) { - tabstrip_model_->SelectTabContentsAt(index, user_gesture); + tab_handler_->GetTabStripModel()->SelectTabContentsAt(index, user_gesture); } void Browser::CloseAllTabs() { - tabstrip_model_->CloseAllTabs(); + tab_handler_->GetTabStripModel()->CloseAllTabs(); } //////////////////////////////////////////////////////////////////////////////// // Browser, Tab adding/showing functions: int Browser::GetIndexForInsertionDuringRestore(int relative_index) { - return (tabstrip_model_->insertion_policy() == TabStripModel::INSERT_AFTER) ? - tab_count() : relative_index; + return (tab_handler_->GetTabStripModel()->insertion_policy() == + TabStripModel::INSERT_AFTER) ? tab_count() : relative_index; } TabContents* Browser::AddTabWithURL(const GURL& url, @@ -868,7 +864,8 @@ TabContents* Browser::AddTabWithURL(const GURL& url, contents = CreateTabContentsForURL(url_to_load, referrer, profile_, transition, false, instance); contents->SetExtensionAppById(extension_app_id); - tabstrip_model_->AddTabContents(contents, index, transition, add_types); + tab_handler_->GetTabStripModel()->AddTabContents(contents, index, + transition, add_types); // TODO(sky): figure out why this is needed. Without it we seem to get // failures in startup tests. // By default, content believes it is not hidden. When adding contents @@ -899,7 +896,7 @@ TabContents* Browser::AddTabWithURL(const GURL& url, TabContents* Browser::AddTab(TabContents* tab_contents, PageTransition::Type type) { - tabstrip_model_->AddTabContents( + tab_handler_->GetTabStripModel()->AddTabContents( tab_contents, -1, type, TabStripModel::ADD_SELECTED); return tab_contents; } @@ -939,18 +936,19 @@ TabContents* Browser::AddRestoredTab( SessionStorageNamespace* session_storage_namespace) { TabContents* new_tab = new TabContents( profile(), NULL, MSG_ROUTING_NONE, - tabstrip_model_->GetSelectedTabContents(), session_storage_namespace); + tab_handler_->GetTabStripModel()->GetSelectedTabContents(), + session_storage_namespace); new_tab->SetExtensionAppById(extension_app_id); new_tab->controller().RestoreFromState(navigations, selected_navigation, from_last_session); bool really_pin = (pin && tab_index == tabstrip_model()->IndexOfFirstNonMiniTab()); - tabstrip_model_->InsertTabContentsAt( + tab_handler_->GetTabStripModel()->InsertTabContentsAt( tab_index, new_tab, select ? TabStripModel::ADD_SELECTED : TabStripModel::ADD_NONE); if (really_pin) - tabstrip_model_->SetTabPinned(tab_index, true); + tab_handler_->GetTabStripModel()->SetTabPinned(tab_index, true); if (select) { window_->Activate(); } else { @@ -978,14 +976,15 @@ void Browser::ReplaceRestoredTab( const std::string& extension_app_id, SessionStorageNamespace* session_storage_namespace) { TabContents* replacement = new TabContents(profile(), NULL, - MSG_ROUTING_NONE, tabstrip_model_->GetSelectedTabContents(), + MSG_ROUTING_NONE, + tab_handler_->GetTabStripModel()->GetSelectedTabContents(), session_storage_namespace); replacement->SetExtensionAppById(extension_app_id); replacement->controller().RestoreFromState(navigations, selected_navigation, from_last_session); - tabstrip_model_->ReplaceNavigationControllerAt( - tabstrip_model_->selected_index(), + tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt( + tab_handler_->GetTabStripModel()->selected_index(), &replacement->controller()); } @@ -1013,11 +1012,12 @@ void Browser::ShowSingletonTab(const GURL& url) { &reverse_on_redirect); // See if we already have a tab with the given URL and select it if so. - for (int i = 0; i < tabstrip_model_->count(); i++) { - TabContents* tc = tabstrip_model_->GetTabContentsAt(i); + TabStripModel* model = tab_handler_->GetTabStripModel(); + for (int i = 0; i < model->count(); i++) { + TabContents* tc = model->GetTabContentsAt(i); if (CompareURLsIgnoreRef(tc->GetURL(), url) || CompareURLsIgnoreRef(tc->GetURL(), rewritten_url)) { - tabstrip_model_->SelectTabContentsAt(i, false); + model->SelectTabContentsAt(i, false); return; } } @@ -1107,7 +1107,7 @@ TabContents* Browser::GetOrCloneTabForDisposition( TabContents* current_tab = GetSelectedTabContents(); if (ShouldOpenNewTabForWindowDisposition(disposition)) { current_tab = current_tab->Clone(); - tabstrip_model_->AddTabContents( + tab_handler_->GetTabStripModel()->AddTabContents( current_tab, -1, PageTransition::LINK, disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_SELECTED : TabStripModel::ADD_NONE); @@ -1116,7 +1116,7 @@ TabContents* Browser::GetOrCloneTabForDisposition( } void Browser::UpdateTabStripModelInsertionPolicy() { - tabstrip_model_->SetInsertionPolicy(UseVerticalTabs() ? + tab_handler_->GetTabStripModel()->SetInsertionPolicy(UseVerticalTabs() ? TabStripModel::INSERT_BEFORE : TabStripModel::INSERT_AFTER); } @@ -1301,8 +1301,8 @@ void Browser::CloseTab() { UserMetrics::RecordAction(UserMetricsAction("CloseTab_Accelerator"), profile_); if (CanCloseTab()) { - tabstrip_model_->CloseTabContentsAt( - tabstrip_model_->selected_index(), + tab_handler_->GetTabStripModel()->CloseTabContentsAt( + tab_handler_->GetTabStripModel()->selected_index(), TabStripModel::CLOSE_USER_GESTURE | TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); } @@ -1310,12 +1310,12 @@ void Browser::CloseTab() { void Browser::SelectNextTab() { UserMetrics::RecordAction(UserMetricsAction("SelectNextTab"), profile_); - tabstrip_model_->SelectNextTab(); + tab_handler_->GetTabStripModel()->SelectNextTab(); } void Browser::SelectPreviousTab() { UserMetrics::RecordAction(UserMetricsAction("SelectPrevTab"), profile_); - tabstrip_model_->SelectPreviousTab(); + tab_handler_->GetTabStripModel()->SelectPreviousTab(); } void Browser::OpenTabpose() { @@ -1334,25 +1334,25 @@ void Browser::OpenTabpose() { void Browser::MoveTabNext() { UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"), profile_); - tabstrip_model_->MoveTabNext(); + tab_handler_->GetTabStripModel()->MoveTabNext(); } void Browser::MoveTabPrevious() { UserMetrics::RecordAction(UserMetricsAction("MoveTabPrevious"), profile_); - tabstrip_model_->MoveTabPrevious(); + tab_handler_->GetTabStripModel()->MoveTabPrevious(); } void Browser::SelectNumberedTab(int index) { if (index < tab_count()) { UserMetrics::RecordAction(UserMetricsAction("SelectNumberedTab"), profile_); - tabstrip_model_->SelectTabContentsAt(index, true); + tab_handler_->GetTabStripModel()->SelectTabContentsAt(index, true); } } void Browser::SelectLastTab() { UserMetrics::RecordAction(UserMetricsAction("SelectLastTab"), profile_); - tabstrip_model_->SelectLastTab(); + tab_handler_->GetTabStripModel()->SelectLastTab(); } void Browser::DuplicateTab() { @@ -1386,8 +1386,9 @@ void Browser::WriteCurrentURLToClipboard() { void Browser::ConvertPopupToTabbedBrowser() { UserMetrics::RecordAction(UserMetricsAction("ShowAsTab"), profile_); - int tab_strip_index = tabstrip_model_->selected_index(); - TabContents* contents = tabstrip_model_->DetachTabContentsAt(tab_strip_index); + int tab_strip_index = tab_handler_->GetTabStripModel()->selected_index(); + TabContents* contents = + tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index); Browser* browser = Browser::Create(profile_); browser->tabstrip_model()->AppendTabContents(contents, true); browser->window()->Show(); @@ -1760,8 +1761,9 @@ void Browser::ShowOptionsTab(const std::string& sub_page) { GURL url(chrome::kChromeUISettingsURL + sub_page); // See if there is already an options tab open that we can use. - for (int i = 0; i < tabstrip_model_->count(); i++) { - TabContents* tc = tabstrip_model_->GetTabContentsAt(i); + TabStripModel* model = tab_handler_->GetTabStripModel(); + for (int i = 0; i < model->count(); i++) { + TabContents* tc = model->GetTabContentsAt(i); const GURL& tab_url = tc->GetURL(); if (tab_url.scheme() == url.scheme() && tab_url.host() == url.host()) { @@ -1771,7 +1773,7 @@ void Browser::ShowOptionsTab(const std::string& sub_page) { // URL in the address bar, but security policy doesn't allow that. OpenURLAtIndex(tc, url, GURL(), CURRENT_TAB, PageTransition::GENERATED, -1, -1); - tabstrip_model_->SelectTabContentsAt(i, false); + model->SelectTabContentsAt(i, false); return; } } @@ -1996,11 +1998,29 @@ void Browser::RegisterUserPrefs(PrefService* prefs) { } // static +bool Browser::RunUnloadEventsHelper(TabContents* contents) { + // If the TabContents is not connected yet, then there's no unload + // handler we can fire even if the TabContents has an unload listener. + // One case where we hit this is in a tab that has an infinite loop + // before load. + if (TabHasUnloadListener(contents)) { + // If the page has unload listeners, then we tell the renderer to fire + // them. Once they have fired, we'll get a message back saying whether + // to proceed closing the page or not, which sends us back to this method + // with the HasUnloadListener bit cleared. + contents->render_view_host()->FirePageBeforeUnload(false); + return true; + } + return false; +} + +// static Browser* Browser::GetBrowserForController( const NavigationController* controller, int* index_result) { BrowserList::const_iterator it; for (it = BrowserList::begin(); it != BrowserList::end(); ++it) { - int index = (*it)->tabstrip_model_->GetIndexOfController(controller); + int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController( + controller); if (index != TabStripModel::kNoTab) { if (index_result) *index_result = index; @@ -2225,6 +2245,14 @@ int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) { } /////////////////////////////////////////////////////////////////////////////// +// Browser, PageNavigator implementation: +void Browser::OpenURL(const GURL& url, const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + OpenURLFromTab(NULL, url, referrer, disposition, transition); +} + +/////////////////////////////////////////////////////////////////////////////// // Browser, CommandUpdater::CommandUpdaterDelegate implementation: void Browser::ExecuteCommand(int id) { @@ -2232,6 +2260,17 @@ void Browser::ExecuteCommand(int id) { } /////////////////////////////////////////////////////////////////////////////// +// Browser, TabHandlerDelegate implementation: + +Profile* Browser::GetProfile() const { + return profile(); +} + +Browser* Browser::AsBrowser() { + return this; +} + +/////////////////////////////////////////////////////////////////////////////// // Browser, TabStripModelDelegate implementation: TabContents* Browser::AddBlankTab(bool foreground) { @@ -2287,7 +2326,8 @@ void Browser::ContinueDraggingDetachedTab(TabContents* contents, } int Browser::GetDragActions() const { - return TAB_TEAROFF_ACTION | (tab_count() > 1 ? TAB_MOVE_ACTION : 0); + return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ? + TabStripModelDelegate::TAB_MOVE_ACTION : 0); } TabContents* Browser::CreateTabContentsForURL( @@ -2295,7 +2335,8 @@ TabContents* Browser::CreateTabContentsForURL( PageTransition::Type transition, bool defer_load, SiteInstance* instance) const { TabContents* contents = new TabContents(profile, instance, - MSG_ROUTING_NONE, tabstrip_model_->GetSelectedTabContents(), NULL); + MSG_ROUTING_NONE, + tab_handler_->GetTabStripModel()->GetSelectedTabContents(), NULL); if (!defer_load) { // Load the initial URL before adding the new tab contents to the tab strip @@ -2321,11 +2362,13 @@ void Browser::DuplicateContentsAt(int index) { // If this is a tabbed browser, just create a duplicate tab inside the same // window next to the tab being duplicated. new_contents = contents->Clone(); - pinned = tabstrip_model_->IsTabPinned(index); + pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index); int add_types = TabStripModel::ADD_SELECTED | TabStripModel::ADD_INHERIT_GROUP | (pinned ? TabStripModel::ADD_PINNED : 0); - tabstrip_model_->InsertTabContentsAt(index + 1, new_contents, add_types); + tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1, + new_contents, + add_types); } else { Browser* browser = NULL; if (type_ & TYPE_APP) { @@ -2397,7 +2440,7 @@ bool Browser::CanReloadContents(TabContents* source) const { bool Browser::CanCloseContentsAt(int index) { if (!CanCloseTab()) return false; - if (tabstrip_model_->count() > 1) + if (tab_handler_->GetTabStripModel()->count() > 1) return true; // We are closing the last tab for this browser. Make sure to check for // in-progress downloads. @@ -2525,9 +2568,9 @@ void Browser::TabSelectedAt(TabContents* old_contents, // exist, the change will be picked up by sessions when created. if (profile_->HasSessionService()) { SessionService* session_service = profile_->GetSessionService(); - if (session_service && !tabstrip_model_->closing_all()) { + if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) { session_service->SetSelectedTabInWindow( - session_id(), tabstrip_model_->selected_index()); + session_id(), tab_handler_->GetTabStripModel()->selected_index()); } } } @@ -2544,7 +2587,7 @@ void Browser::TabReplacedAt(TabContents* old_contents, TabContents* new_contents, int index) { TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE); TabInsertedAt(new_contents, index, - (index == tabstrip_model_->selected_index())); + (index == tab_handler_->GetTabStripModel()->selected_index())); int entry_count = new_contents->controller().entry_count(); if (entry_count > 0) { @@ -2563,7 +2606,7 @@ void Browser::TabPinnedStateChanged(TabContents* contents, int index) { session_service->SetPinnedState( session_id(), GetTabContentsAt(index)->controller().session_id(), - tabstrip_model_->IsTabPinned(index)); + tab_handler_->GetTabStripModel()->IsTabPinned(index)); } } @@ -2581,14 +2624,6 @@ void Browser::TabStripEmpty() { } /////////////////////////////////////////////////////////////////////////////// -// Browser, PageNavigator implementation: -void Browser::OpenURL(const GURL& url, const GURL& referrer, - WindowOpenDisposition disposition, - PageTransition::Type transition) { - OpenURLFromTab(NULL, url, referrer, disposition, transition); -} - -/////////////////////////////////////////////////////////////////////////////// // Browser, TabContentsDelegate implementation: void Browser::OpenURLFromTab(TabContents* source, @@ -2624,7 +2659,8 @@ void Browser::AddNewContents(TabContents* source, // If this is a window with no tabstrip, we can only have one tab so we need // to process this in tabbed browser window. if (!CanSupportWindowFeature(FEATURE_TABSTRIP) && - tabstrip_model_->count() > 0 && disposition != NEW_WINDOW && + tab_handler_->GetTabStripModel()->count() > 0 && + disposition != NEW_WINDOW && disposition != NEW_POPUP) { Browser* b = GetOrCreateTabbedBrowser(profile_); DCHECK(b); @@ -2650,7 +2686,7 @@ void Browser::AddNewContents(TabContents* source, initial_pos, user_gesture); browser->window()->Show(); } else if (disposition != SUPPRESS_OPEN) { - tabstrip_model_->AddTabContents( + tab_handler_->GetTabStripModel()->AddTabContents( new_contents, -1, PageTransition::LINK, disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_SELECTED : TabStripModel::ADD_NONE); @@ -2658,8 +2694,8 @@ void Browser::AddNewContents(TabContents* source, } void Browser::ActivateContents(TabContents* contents) { - tabstrip_model_->SelectTabContentsAt( - tabstrip_model_->GetIndexOfTabContents(contents), false); + tab_handler_->GetTabStripModel()->SelectTabContentsAt( + tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents), false); window_->Activate(); } @@ -2668,7 +2704,8 @@ void Browser::DeactivateContents(TabContents* contents) { } void Browser::LoadingStateChanged(TabContents* source) { - window_->UpdateLoadingAnimations(tabstrip_model_->TabsAreLoading()); + window_->UpdateLoadingAnimations( + tab_handler_->GetTabStripModel()->TabsAreLoading()); window_->UpdateTitleBar(); if (source == GetSelectedTabContents()) { @@ -2707,12 +2744,12 @@ void Browser::CloseContents(TabContents* source) { return; } - int index = tabstrip_model_->GetIndexOfTabContents(source); + int index = tab_handler_->GetTabStripModel()->GetIndexOfTabContents(source); if (index == TabStripModel::kNoTab) { NOTREACHED() << "CloseContents called for tab not in our strip"; return; } - tabstrip_model_->CloseTabContentsAt( + tab_handler_->GetTabStripModel()->CloseTabContentsAt( index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); } @@ -2726,9 +2763,9 @@ void Browser::MoveContents(TabContents* source, const gfx::Rect& pos) { } void Browser::DetachContents(TabContents* source) { - int index = tabstrip_model_->GetIndexOfTabContents(source); + int index = tab_handler_->GetTabStripModel()->GetIndexOfTabContents(source); if (index >= 0) - tabstrip_model_->DetachTabContentsAt(index); + tab_handler_->GetTabStripModel()->DetachTabContentsAt(index); } bool Browser::IsPopup(const TabContents* source) const { @@ -3082,8 +3119,9 @@ void Browser::Observe(NotificationType type, // Close any tabs from the unloaded extension. Extension* extension = Details<Extension>(details).ptr(); - for (int i = tabstrip_model_->count() - 1; i >= 0; --i) { - TabContents* tc = tabstrip_model_->GetTabContentsAt(i); + TabStripModel* model = tab_handler_->GetTabStripModel(); + for (int i = model->count() - 1; i >= 0; --i) { + TabContents* tc = model->GetTabContentsAt(i); if (tc->GetURL().SchemeIs(chrome::kExtensionScheme) && tc->GetURL().host() == extension->id()) { CloseTabContents(tc); @@ -3203,12 +3241,13 @@ void Browser::HideMatchPreview() { void Browser::CommitMatchPreview(TabContents* preview_contents) { TabContents* tab_contents = match_preview_->tab_contents(); - int index = tabstrip_model_->GetIndexOfTabContents(tab_contents); + int index = tab_handler_->GetTabStripModel()->GetIndexOfTabContents( + tab_contents); DCHECK_NE(-1, index); preview_contents->controller().CopyStateFromAndPrune( tab_contents->controller()); // TabStripModel takes ownership of preview_contents. - tabstrip_model_->ReplaceTabContentsAt( + tab_handler_->GetTabStripModel()->ReplaceTabContentsAt( index, preview_contents, TabStripModelObserver::REPLACE_MATCH_PREVIEW); @@ -3474,8 +3513,9 @@ void Browser::ScheduleUIUpdate(const TabContents* source, // Update the loading state synchronously. This is so the throbber will // immediately start/stop, which gives a more snappy feel. We want to do // this for any tab so they start & stop quickly. - tabstrip_model_->UpdateTabContentsStateAt( - tabstrip_model_->GetIndexOfController(&source->controller()), + tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt( + tab_handler_->GetTabStripModel()->GetIndexOfController( + &source->controller()), TabStripModelObserver::LOADING_ONLY); // The status bubble needs to be updated during INVALIDATE_LOAD too, but // we do that asynchronously by not stripping INVALIDATE_LOAD from @@ -3487,8 +3527,9 @@ void Browser::ScheduleUIUpdate(const TabContents* source, // we need to process the update synchronously. This state only matters for // the TabStripModel, so we notify the TabStripModel now and notify others // asynchronously. - tabstrip_model_->UpdateTabContentsStateAt( - tabstrip_model_->GetIndexOfController(&source->controller()), + tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt( + tab_handler_->GetTabStripModel()->GetIndexOfController( + &source->controller()), TabStripModelObserver::TITLE_NOT_LOADING); } @@ -3564,8 +3605,8 @@ void Browser::ProcessPendingUIUpdates() { // Updates that don't depend upon the selected state go here. if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) { - tabstrip_model_->UpdateTabContentsStateAt( - tabstrip_model_->GetIndexOfTabContents(contents), + tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt( + tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents), TabStripModelObserver::ALL); } @@ -3610,9 +3651,10 @@ void Browser::SyncHistoryWithTabs(int index) { if (contents) { session_service->SetTabIndexInWindow( session_id(), contents->controller().session_id(), i); - session_service->SetPinnedState(session_id(), - contents->controller().session_id(), - tabstrip_model_->IsTabPinned(i)); + session_service->SetPinnedState( + session_id(), + contents->controller().session_id(), + tab_handler_->GetTabStripModel()->IsTabPinned(i)); } } } @@ -3897,7 +3939,7 @@ void Browser::OpenURLAtIndex(TabContents* source, &browser); browser->window()->Show(); } else if ((disposition == CURRENT_TAB) && current_tab) { - tabstrip_model_->TabNavigating(current_tab, transition); + tab_handler_->GetTabStripModel()->TabNavigating(current_tab, transition); bool user_initiated = (PageTransition::StripQualifier(transition) == PageTransition::AUTO_BOOKMARK); @@ -4017,15 +4059,17 @@ void Browser::TabDetachedAtImpl(TabContents* contents, int index, // Save what the user's currently typed. window_->GetLocationBar()->SaveStateToContents(contents); - if (!tabstrip_model_->closing_all()) + if (!tab_handler_->GetTabStripModel()->closing_all()) SyncHistoryWithTabs(0); } contents->set_delegate(NULL); RemoveScheduledUpdatesFor(contents); - if (find_bar_controller_.get() && index == tabstrip_model_->selected_index()) + if (find_bar_controller_.get() && + index == tab_handler_->GetTabStripModel()->selected_index()) { find_bar_controller_->ChangeTabContents(NULL); + } registrar_.Remove(this, NotificationType::TAB_CONTENTS_DISCONNECTED, Source<TabContents>(contents)); @@ -4054,23 +4098,6 @@ void Browser::RegisterAppPrefs(const std::string& app_name) { prefs->RegisterDictionaryPref(window_pref.c_str()); } -// static -bool Browser::RunUnloadEventsHelper(TabContents* contents) { - // If the TabContents is not connected yet, then there's no unload - // handler we can fire even if the TabContents has an unload listener. - // One case where we hit this is in a tab that has an infinite loop - // before load. - if (TabHasUnloadListener(contents)) { - // If the page has unload listeners, then we tell the renderer to fire - // them. Once they have fired, we'll get a message back saying whether - // to proceed closing the page or not, which sends us back to this method - // with the HasUnloadListener bit cleared. - contents->render_view_host()->FirePageBeforeUnload(false); - return true; - } - return false; -} - void Browser::TabRestoreServiceChanged(TabRestoreService* service) { command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, !service->entries().empty()); @@ -4098,7 +4125,7 @@ bool Browser::OpenMatchPreview(WindowOpenDisposition disposition) { TabContents* preview_contents = match_preview()->ReleasePreviewContents( MatchPreview::COMMIT_PRESSED_ENTER); preview_contents->controller().PruneAllButActive(); - tabstrip_model_->AddTabContents( + tab_handler_->GetTabStripModel()->AddTabContents( preview_contents, -1, match_preview()->last_transition_type(), diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 27e8db0..695d353 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -23,8 +23,9 @@ #include "chrome/browser/sessions/tab_restore_service_observer.h" #include "chrome/browser/shell_dialogs.h" #include "chrome/browser/sync/profile_sync_service_observer.h" -#include "chrome/browser/tabs/tab_strip_model_delegate.h" -#include "chrome/browser/tabs/tab_strip_model_observer.h" +#include "chrome/browser/tabs/tab_handler.h" +#include "chrome/browser/tabs/tab_strip_model_delegate.h" // TODO(beng): remove +#include "chrome/browser/tabs/tab_strip_model_observer.h" // TODO(beng): remove #include "chrome/browser/tab_contents/match_preview_delegate.h" #include "chrome/browser/tab_contents/page_navigator.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" @@ -50,8 +51,7 @@ namespace gfx { class Point; } -class Browser : public TabStripModelDelegate, - public TabStripModelObserver, +class Browser : public TabHandlerDelegate, public TabContentsDelegate, public PageNavigator, public CommandUpdater::CommandUpdaterDelegate, @@ -316,7 +316,8 @@ class Browser : public TabStripModelDelegate, // TabStripModel pass-thrus ///////////////////////////////////////////////// TabStripModel* tabstrip_model() const { - return const_cast<TabStripModel*>(tabstrip_model_.get()); + // TODO(beng): remove this accessor. It violates google style. + return tab_handler_->GetTabStripModel(); } int tab_count() const; @@ -566,6 +567,9 @@ class Browser : public TabStripModelDelegate, static void RegisterPrefs(PrefService* prefs); static void RegisterUserPrefs(PrefService* prefs); + // Helper function to run unload listeners on a TabContents. + static bool RunUnloadEventsHelper(TabContents* contents); + // Returns the Browser which contains the tab with the given // NavigationController, also filling in |index| (if valid) with the tab's // index in the tab strip. @@ -610,7 +614,7 @@ class Browser : public TabStripModelDelegate, // Interface implementations //////////////////////////////////////////////// - // Overridden from PageNavigator + // Overridden from PageNavigator: virtual void OpenURL(const GURL& url, const GURL& referrer, WindowOpenDisposition disposition, PageTransition::Type transition); @@ -618,28 +622,13 @@ class Browser : public TabStripModelDelegate, // Overridden from CommandUpdater::CommandUpdaterDelegate: virtual void ExecuteCommand(int id); - // Helper function to run unload listeners on a TabContents. - static bool RunUnloadEventsHelper(TabContents* contents); - - // TabRestoreServiceObserver ///////////////////////////////////////////////// + // Overridden from TabRestoreServiceObserver: virtual void TabRestoreServiceChanged(TabRestoreService* service); virtual void TabRestoreServiceDestroyed(TabRestoreService* service); - private: - FRIEND_TEST_ALL_PREFIXES(BrowserTest, NoTabsInPopups); - - // Used to describe why a tab is being detached. This is used by - // TabDetachedAtImpl. - enum DetachType { - // Result of TabDetachedAt. - DETACH_TYPE_DETACH, - - // Result of TabReplacedAt. - DETACH_TYPE_REPLACE, - - // Result of the tab strip not having any significant tabs. - DETACH_TYPE_EMPTY - }; + // Overridden from TabHandlerDelegate: + virtual Profile* GetProfile() const; + virtual Browser* AsBrowser(); // Overridden from TabStripModelDelegate: virtual TabContents* AddBlankTab(bool foreground); @@ -694,6 +683,22 @@ class Browser : public TabStripModelDelegate, virtual void TabPinnedStateChanged(TabContents* contents, int index); virtual void TabStripEmpty(); + private: + FRIEND_TEST_ALL_PREFIXES(BrowserTest, NoTabsInPopups); + + // Used to describe why a tab is being detached. This is used by + // TabDetachedAtImpl. + enum DetachType { + // Result of TabDetachedAt. + DETACH_TYPE_DETACH, + + // Result of TabReplacedAt. + DETACH_TYPE_REPLACE, + + // Result of the tab strip not having any significant tabs. + DETACH_TYPE_EMPTY + }; + // Overridden from TabContentsDelegate: virtual void OpenURLFromTab(TabContents* source, const GURL& url, @@ -977,8 +982,8 @@ class Browser : public TabStripModelDelegate, // This Browser's window. BrowserWindow* window_; - // This Browser's TabStripModel. - scoped_ptr<TabStripModel> tabstrip_model_; + // This Browser's current TabHandler. + scoped_ptr<TabHandler> tab_handler_; // The CommandUpdater that manages the browser window commands. CommandUpdater command_updater_; diff --git a/chrome/browser/tabs/default_tab_handler.cc b/chrome/browser/tabs/default_tab_handler.cc new file mode 100644 index 0000000..5149173 --- /dev/null +++ b/chrome/browser/tabs/default_tab_handler.cc @@ -0,0 +1,198 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/tabs/default_tab_handler.h" + +#include "chrome/browser/browser.h" +#include "chrome/browser/tabs/tab_strip_model.h" + +//////////////////////////////////////////////////////////////////////////////// +// DefaultTabHandler, public: + +DefaultTabHandler::DefaultTabHandler(TabHandlerDelegate* delegate) + : delegate_(delegate), + ALLOW_THIS_IN_INITIALIZER_LIST( + model_(new TabStripModel(this, delegate->GetProfile()))) { + model_->AddObserver(this); +} + +DefaultTabHandler::~DefaultTabHandler() { + // The tab strip should not have any significant tabs at this point. + DCHECK(!model_->HasNonPhantomTabs()); + model_->RemoveObserver(this); +} + +//////////////////////////////////////////////////////////////////////////////// +// DefaultTabHandler, TabHandler implementation: + +TabStripModel* DefaultTabHandler::GetTabStripModel() const { + return model_.get(); +} + +//////////////////////////////////////////////////////////////////////////////// +// DefaultTabHandler, TabStripModelDelegate implementation: + +TabContents* DefaultTabHandler::AddBlankTab(bool foreground) { + return delegate_->AsBrowser()->AddBlankTab(foreground); +} + +TabContents* DefaultTabHandler::AddBlankTabAt(int index, bool foreground) { + return delegate_->AsBrowser()->AddBlankTabAt(index, foreground); +} + +Browser* DefaultTabHandler::CreateNewStripWithContents( + TabContents* detached_contents, + const gfx::Rect& window_bounds, + const DockInfo& dock_info, + bool maximize) { + return delegate_->AsBrowser()->CreateNewStripWithContents(detached_contents, + window_bounds, + dock_info, + maximize); +} + +void DefaultTabHandler::ContinueDraggingDetachedTab( + TabContents* contents, + const gfx::Rect& window_bounds, + const gfx::Rect& tab_bounds) { + delegate_->AsBrowser()->ContinueDraggingDetachedTab(contents, + window_bounds, + tab_bounds); +} + +int DefaultTabHandler::GetDragActions() const { + return delegate_->AsBrowser()->GetDragActions(); +} + +TabContents* DefaultTabHandler::CreateTabContentsForURL( + const GURL& url, + const GURL& referrer, + Profile* profile, + PageTransition::Type transition, + bool defer_load, + SiteInstance* instance) const { + return delegate_->AsBrowser()->CreateTabContentsForURL(url, + referrer, + profile, + transition, + defer_load, + instance); +} + +bool DefaultTabHandler::CanDuplicateContentsAt(int index) { + return delegate_->AsBrowser()->CanDuplicateContentsAt(index); +} + +void DefaultTabHandler::DuplicateContentsAt(int index) { + delegate_->AsBrowser()->DuplicateContentsAt(index); +} + +void DefaultTabHandler::CloseFrameAfterDragSession() { + delegate_->AsBrowser()->CloseFrameAfterDragSession(); +} + +void DefaultTabHandler::CreateHistoricalTab(TabContents* contents) { + delegate_->AsBrowser()->CreateHistoricalTab(contents); +} + +bool DefaultTabHandler::RunUnloadListenerBeforeClosing(TabContents* contents) { + return delegate_->AsBrowser()->RunUnloadListenerBeforeClosing(contents); +} + +bool DefaultTabHandler::CanCloseContentsAt(int index) { + return delegate_->AsBrowser()->CanCloseContentsAt(index); +} + +bool DefaultTabHandler::CanBookmarkAllTabs() const { + return delegate_->AsBrowser()->CanBookmarkAllTabs(); +} + +void DefaultTabHandler::BookmarkAllTabs() { + delegate_->AsBrowser()->BookmarkAllTabs(); +} + +bool DefaultTabHandler::CanCloseTab() const { + return delegate_->AsBrowser()->CanCloseTab(); +} + +void DefaultTabHandler::ToggleUseVerticalTabs() { + delegate_->AsBrowser()->ToggleUseVerticalTabs(); +} + +bool DefaultTabHandler::CanRestoreTab() { + return delegate_->AsBrowser()->CanRestoreTab(); +} + +void DefaultTabHandler::RestoreTab() { + delegate_->AsBrowser()->RestoreTab(); +} + +bool DefaultTabHandler::LargeIconsPermitted() const { + return delegate_->AsBrowser()->LargeIconsPermitted(); +} + +bool DefaultTabHandler::UseVerticalTabs() const { + return delegate_->AsBrowser()->UseVerticalTabs(); +} + +//////////////////////////////////////////////////////////////////////////////// +// DefaultTabHandler, TabStripModelObserver implementation: + +void DefaultTabHandler::TabInsertedAt(TabContents* contents, + int index, + bool foreground) { + delegate_->AsBrowser()->TabInsertedAt(contents, index, foreground); +} + +void DefaultTabHandler::TabClosingAt(TabContents* contents, int index) { + delegate_->AsBrowser()->TabClosingAt(contents, index); +} + +void DefaultTabHandler::TabDetachedAt(TabContents* contents, int index) { + delegate_->AsBrowser()->TabDetachedAt(contents, index); +} + +void DefaultTabHandler::TabDeselectedAt(TabContents* contents, int index) { + delegate_->AsBrowser()->TabDeselectedAt(contents, index); +} + +void DefaultTabHandler::TabSelectedAt(TabContents* old_contents, + TabContents* new_contents, + int index, + bool user_gesture) { + delegate_->AsBrowser()->TabSelectedAt(old_contents, + new_contents, + index, + user_gesture); +} + +void DefaultTabHandler::TabMoved(TabContents* contents, + int from_index, + int to_index) { + delegate_->AsBrowser()->TabMoved(contents, from_index, to_index); +} + +void DefaultTabHandler::TabReplacedAt(TabContents* old_contents, + TabContents* new_contents, + int index) { + delegate_->AsBrowser()->TabReplacedAt(old_contents, new_contents, index); +} + +void DefaultTabHandler::TabPinnedStateChanged(TabContents* contents, + int index) { + delegate_->AsBrowser()->TabPinnedStateChanged(contents, index); +} + +void DefaultTabHandler::TabStripEmpty() { + delegate_->AsBrowser()->TabStripEmpty(); +} + +//////////////////////////////////////////////////////////////////////////////// +// TabHandler, public: + +// static +TabHandler* TabHandler::CreateTabHandler(TabHandlerDelegate* delegate) { + return new DefaultTabHandler(delegate); +} + diff --git a/chrome/browser/tabs/default_tab_handler.h b/chrome/browser/tabs/default_tab_handler.h new file mode 100644 index 0000000..8a2af16 --- /dev/null +++ b/chrome/browser/tabs/default_tab_handler.h @@ -0,0 +1,88 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_TABS_DEFAULT_TAB_HANDLER_H_ +#define CHROME_BROWSER_TABS_DEFAULT_TAB_HANDLER_H_ +#pragma once + +#include "base/scoped_ptr.h" +#include "chrome/browser/tabs/tab_handler.h" +#include "chrome/browser/tabs/tab_strip_model_delegate.h" +#include "chrome/browser/tabs/tab_strip_model_observer.h" + +// A TabHandler implementation that interacts with the default TabStripModel. +// The intent is that the TabStripModel API is contained at this level, and +// never propagates beyond to the Browser. +class DefaultTabHandler : public TabHandler, + public TabStripModelDelegate, + public TabStripModelObserver { + public: + explicit DefaultTabHandler(TabHandlerDelegate* delegate); + virtual ~DefaultTabHandler(); + + // Overridden from TabHandler: + virtual TabStripModel* GetTabStripModel() const; + + // Overridden from TabStripModelDelegate: + virtual TabContents* AddBlankTab(bool foreground); + virtual TabContents* AddBlankTabAt(int index, bool foreground); + virtual Browser* CreateNewStripWithContents(TabContents* detached_contents, + const gfx::Rect& window_bounds, + const DockInfo& dock_info, + bool maximize); + virtual void ContinueDraggingDetachedTab(TabContents* contents, + const gfx::Rect& window_bounds, + const gfx::Rect& tab_bounds); + virtual int GetDragActions() const; + virtual TabContents* CreateTabContentsForURL(const GURL& url, + const GURL& referrer, + Profile* profile, + PageTransition::Type transition, + bool defer_load, + SiteInstance* instance) const; + virtual bool CanDuplicateContentsAt(int index); + virtual void DuplicateContentsAt(int index); + virtual void CloseFrameAfterDragSession(); + virtual void CreateHistoricalTab(TabContents* contents); + virtual bool RunUnloadListenerBeforeClosing(TabContents* contents); + virtual bool CanCloseContentsAt(int index); + virtual bool CanBookmarkAllTabs() const; + virtual void BookmarkAllTabs(); + virtual bool CanCloseTab() const; + virtual void ToggleUseVerticalTabs(); + virtual bool CanRestoreTab(); + virtual void RestoreTab(); + virtual bool LargeIconsPermitted() const; + virtual bool UseVerticalTabs() const; + + // Overridden from TabStripModelObserver: + virtual void TabInsertedAt(TabContents* contents, + int index, + bool foreground); + virtual void TabClosingAt(TabContents* contents, int index); + virtual void TabDetachedAt(TabContents* contents, int index); + virtual void TabDeselectedAt(TabContents* contents, int index); + virtual void TabSelectedAt(TabContents* old_contents, + TabContents* new_contents, + int index, + bool user_gesture); + virtual void TabMoved(TabContents* contents, + int from_index, + int to_index); + virtual void TabReplacedAt(TabContents* old_contents, + TabContents* new_contents, + int index); + virtual void TabPinnedStateChanged(TabContents* contents, int index); + virtual void TabStripEmpty(); + + private: + TabHandlerDelegate* delegate_; + + scoped_ptr<TabStripModel> model_; + + DISALLOW_COPY_AND_ASSIGN(DefaultTabHandler); +}; + +#endif // CHROME_BROWSER_TABS_DEFAULT_TAB_HANDLER_H_ + diff --git a/chrome/browser/tabs/tab_handler.h b/chrome/browser/tabs/tab_handler.h new file mode 100644 index 0000000..e67aece --- /dev/null +++ b/chrome/browser/tabs/tab_handler.h @@ -0,0 +1,36 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_TABS_TAB_HANDLER_H_ +#define CHROME_BROWSER_TABS_TAB_HANDLER_H_ +#pragma once + +class Browser; +class Profile; +class TabStripModel; + +class TabHandlerDelegate { + public: + virtual Profile* GetProfile() const = 0; + + // TODO(beng): remove once decoupling with Browser is complete. + virtual Browser* AsBrowser() = 0; +}; + +// An interface implemented by an object that can perform tab related +// functionality for a Browser. This functionality includes mapping individual +// TabContentses into indices for an index-based tab organization scheme for +// example. +class TabHandler { + public: + // Creates a TabHandler implementation and returns it, transferring ownership + // to the caller. + static TabHandler* CreateTabHandler(TabHandlerDelegate* delegate); + + // TODO(beng): remove once decoupling with Browser is complete. + virtual TabStripModel* GetTabStripModel() const = 0; +}; + +#endif // CHROME_BROWSER_TABS_TAB_HANDLER_H_ + diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7575488..6bbe52d 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2755,10 +2755,13 @@ 'browser/tab_contents/web_drop_target_win.h', 'browser/tab_menu_model.cc', 'browser/tab_menu_model.h', + 'browser/tabs/default_tab_handler.cc', + 'browser/tabs/default_tab_handler.h', 'browser/tabs/pinned_tab_codec.cc', 'browser/tabs/pinned_tab_codec.h', 'browser/tabs/pinned_tab_service.cc', 'browser/tabs/pinned_tab_service.h', + 'browser/tabs/tab_handler.h', 'browser/tabs/tab_strip_model.cc', 'browser/tabs/tab_strip_model.h', 'browser/tabs/tab_strip_model_delegate.h', |