| Index: ios/chrome/browser/tabs/tab_model_order_controller.mm
|
| diff --git a/ios/chrome/browser/tabs/tab_model_order_controller.mm b/ios/chrome/browser/tabs/tab_model_order_controller.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..215540b6c9312f9f7e333c033207985d7e76b909
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/tabs/tab_model_order_controller.mm
|
| @@ -0,0 +1,104 @@
|
| +// Copyright 2012 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.
|
| +
|
| +#import "ios/chrome/browser/tabs/tab_model_order_controller.h"
|
| +
|
| +#include "base/logging.h"
|
| +
|
| +@implementation TabModelOrderController
|
| +
|
| +@synthesize insertionPolicy = insertionPolicy_;
|
| +
|
| +- (id)initWithTabModel:(TabModel*)model {
|
| + DCHECK(model);
|
| + self = [super init];
|
| + if (self) {
|
| + model_ = model;
|
| + insertionPolicy_ = TabModelOrderConstants::kInsertAfter;
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (NSUInteger)insertionIndexForTab:(Tab*)newTab
|
| + transition:(ui::PageTransition)transition
|
| + opener:(Tab*)parentTab
|
| + adjacency:(TabModelOrderConstants::InsertionAdjacency)
|
| + adjacency {
|
| + if (model_.isEmpty)
|
| + return 0;
|
| +
|
| + if (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK) &&
|
| + parentTab) {
|
| + NSUInteger referenceIndex = [model_ indexOfTab:parentTab];
|
| + Tab* openLocation = nil;
|
| + if (insertionPolicy_ == TabModelOrderConstants::kInsertAfter) {
|
| + openLocation = [model_ lastTabWithOpener:parentTab];
|
| + } else {
|
| + openLocation = [model_ firstTabWithOpener:parentTab];
|
| + }
|
| + if (openLocation)
|
| + referenceIndex = [model_ indexOfTab:openLocation];
|
| +
|
| + // If the reference tab is no longer in the model (e.g., it was closed
|
| + // before the open request was handled), fall through to default behavior.
|
| + if (referenceIndex != NSNotFound) {
|
| + BOOL insertAfter =
|
| + insertionPolicy_ == TabModelOrderConstants::kInsertAfter ||
|
| + adjacency == TabModelOrderConstants::kAdjacentAfter;
|
| + NSUInteger delta = insertAfter ? 1 : 0;
|
| + return referenceIndex + delta;
|
| + }
|
| + }
|
| + // In other cases, such as a normal new tab, open at the end.
|
| + return [self insertionIndexForAppending];
|
| +}
|
| +
|
| +- (NSUInteger)insertionIndexForAppending {
|
| + return insertionPolicy_ == TabModelOrderConstants::kInsertAfter ? model_.count
|
| + : 0;
|
| +}
|
| +
|
| +- (Tab*)determineNewSelectedTabFromRemovedTab:(Tab*)removedTab {
|
| + // While the desktop version of this code deals in indices, this deals in
|
| + // actual tabs. As a result, the tab only needs to change iff the selection
|
| + // is the tab that's removed.
|
| + if (removedTab != model_.currentTab)
|
| + return model_.currentTab;
|
| +
|
| + const NSUInteger numberOfTabs = model_.count;
|
| + if (numberOfTabs < 2)
|
| + return nil;
|
| + DCHECK(numberOfTabs >= 2);
|
| + DCHECK(removedTab == model_.currentTab);
|
| +
|
| + // First see if the tab being removed has any "child" tabs. If it does, we
|
| + // want to select the first in that child group, not the next tab in the same
|
| + // group of the removed tab.
|
| + Tab* firstChild = [model_ nextTabWithOpener:removedTab afterTab:nil];
|
| + if (firstChild)
|
| + return firstChild;
|
| + Tab* parentTab = [model_ openerOfTab:removedTab];
|
| + if (parentTab) {
|
| + // If the tab was in a group, shift selection to the next tab in the group.
|
| + Tab* nextTab = [model_ nextTabWithOpener:parentTab afterTab:removedTab];
|
| + if (nextTab)
|
| + return nextTab;
|
| +
|
| + // If we can't find a subsequent group member, just fall back to the
|
| + // parentTab itself. Note that we use "group" here since opener is
|
| + // reset by select operations.
|
| + return parentTab;
|
| + }
|
| +
|
| + // No opener set, fall through to the default handler...
|
| + NSUInteger selectedIndex = [model_ indexOfTab:removedTab];
|
| + DCHECK(selectedIndex <= numberOfTabs - 1);
|
| + // Is the closing tab the last one? If so, return the penultimate tab.
|
| + if (selectedIndex == numberOfTabs - 1)
|
| + return [model_ tabAtIndex:selectedIndex - 1];
|
| + // Otherwise return the next tab after the current tab.
|
| + return [model_ tabAtIndex:selectedIndex + 1];
|
| +}
|
| +
|
| +@end
|
|
|