summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tabs/tab_strip_model.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/tabs/tab_strip_model.cc')
-rw-r--r--chrome/browser/tabs/tab_strip_model.cc53
1 files changed, 45 insertions, 8 deletions
diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc
index 327047e..46d56fb 100644
--- a/chrome/browser/tabs/tab_strip_model.cc
+++ b/chrome/browser/tabs/tab_strip_model.cc
@@ -20,6 +20,22 @@
#include "chrome/common/notification_service.h"
#include "chrome/common/stl_util-inl.h"
+namespace {
+
+// Returns true if the specified transition is one of the types that cause the
+// opener relationships for the tab in which the transition occured to be
+// forgotten. This is generally any navigation that isn't a link click (i.e.
+// any navigation that can be considered to be the start of a new task distinct
+// from what had previously occurred in that tab).
+bool ShouldForgetOpenersForTransition(PageTransition::Type transition) {
+ return transition == PageTransition::TYPED ||
+ transition == PageTransition::AUTO_BOOKMARK ||
+ transition == PageTransition::GENERATED ||
+ transition == PageTransition::START_PAGE;
+}
+
+} // namespace
+
///////////////////////////////////////////////////////////////////////////////
// TabStripModel, public:
@@ -33,7 +49,7 @@ TabStripModel::TabStripModel(TabStripModelDelegate* delegate, Profile* profile)
NotificationService::current()->AddObserver(this,
NotificationType::TAB_CONTENTS_DESTROYED,
NotificationService::AllSources());
- SetOrderController(new TabStripModelOrderController(this));
+ order_controller_ = new TabStripModelOrderController(this);
}
TabStripModel::~TabStripModel() {
@@ -52,13 +68,6 @@ void TabStripModel::RemoveObserver(TabStripModelObserver* observer) {
observers_.RemoveObserver(observer);
}
-void TabStripModel::SetOrderController(
- TabStripModelOrderController* order_controller) {
- if (order_controller_)
- delete order_controller_;
- order_controller_ = order_controller;
-}
-
bool TabStripModel::ContainsIndex(int index) const {
return index >= 0 && index < count();
}
@@ -287,6 +296,28 @@ int TabStripModel::GetIndexOfLastTabContentsOpenedBy(
return kNoTab;
}
+void TabStripModel::TabNavigating(TabContents* contents,
+ PageTransition::Type transition) {
+ if (ShouldForgetOpenersForTransition(transition)) {
+ // Don't forget the openers if this tab is a New Tab page opened at the
+ // end of the TabStrip (e.g. by pressing Ctrl+T). Give the user one
+ // navigation of one of these transition types before resetting the
+ // opener relationships (this allows for the use case of opening a new
+ // tab to do a quick look-up of something while viewing a tab earlier in
+ // the strip). We can make this heuristic more permissive if need be.
+ if (!IsNewTabAtEndOfTabStrip(contents)) {
+ // If the user navigates the current tab to another page in any way
+ // other than by clicking a link, we want to pro-actively forget all
+ // TabStrip opener relationships since we assume they're beginning a
+ // different task by reusing the current tab.
+ ForgetAllOpeners();
+ // In this specific case we also want to reset the group relationship,
+ // since it is now technically invalid.
+ ForgetGroup(contents);
+ }
+ }
+}
+
void TabStripModel::ForgetAllOpeners() {
// Forget all opener memories so we don't do anything weird with tab
// re-selection ordering.
@@ -500,6 +531,12 @@ void TabStripModel::Observe(NotificationType type,
///////////////////////////////////////////////////////////////////////////////
// TabStripModel, private:
+bool TabStripModel::IsNewTabAtEndOfTabStrip(TabContents* contents) const {
+ return contents->type() == TAB_CONTENTS_NEW_TAB_UI &&
+ contents == GetContentsAt(count() - 1) &&
+ contents->controller()->GetEntryCount() == 1;
+}
+
bool TabStripModel::InternalCloseTabContentsAt(int index,
bool create_historical_tab) {
TabContents* detached_contents = GetContentsAt(index);