Commit 4d4b9424 authored by edchin's avatar edchin Committed by Commit Bot

[ios] Enable recently closed in tab grid

This CL enables the user to:
1) See recently closed tabs in the tab grid.
2) Tap and open recently close tabs.

This CL adds a method to UrlLoader protocol that restores a tab to
the WebStateList based on SessionID.

In BVC, the restored tab replaces the current WebState.
In tab grid, the restored tab is added to the end of the WebStateList.

Bug: 851219
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I6dc6c22f43d746a9dc73d15b65d6fd5193899a25
Reviewed-on: https://chromium-review.googlesource.com/1094324
Commit-Queue: edchin <edchin@chromium.org>
Reviewed-by: default avatarRohit Rao <rohitrao@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Reviewed-by: default avataredchin <edchin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567175}
parent 85dbb93c
......@@ -33,6 +33,7 @@ source_set("ui") {
deps = [
"//base",
"//base:i18n",
"//components/sessions",
"//ios/chrome/browser",
"//ios/chrome/browser/store_kit",
"//ios/chrome/browser/ui/commands",
......
......@@ -4149,11 +4149,7 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
return;
[self.dispatcher openNewTab:[OpenNewTabCommand command]];
TabRestoreServiceDelegateImplIOS* const delegate =
TabRestoreServiceDelegateImplIOSFactory::GetForBrowserState(
_browserState);
tabRestoreService->RestoreEntryById(delegate, entry->id,
WindowOpenDisposition::CURRENT_TAB);
[self restoreTabWithSessionID:entry->id];
}
#pragma mark - MainContentUI
......@@ -4353,6 +4349,16 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
sessionTab->navigations));
}
- (void)restoreTabWithSessionID:(const SessionID)sessionID {
TabRestoreServiceDelegateImplIOS* delegate =
TabRestoreServiceDelegateImplIOSFactory::GetForBrowserState(
self.browserState);
sessions::TabRestoreService* restoreService =
IOSChromeTabRestoreServiceFactory::GetForBrowserState(self.browserState);
restoreService->RestoreEntryById(delegate, sessionID,
WindowOpenDisposition::CURRENT_TAB);
}
#pragma mark - UrlLoader helpers
// Induce an intentional crash in the browser process.
......
......@@ -11,14 +11,13 @@
#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
@protocol ApplicationCommands;
@protocol BrowserCommands;
@protocol UrlLoader;
@protocol HistoryPresentationDelegate;
// Coordinator that presents History.
@interface HistoryCoordinator : ChromeCoordinator
// The dispatcher for this Coordinator.
@property(nonatomic, weak) id<ApplicationCommands, BrowserCommands> dispatcher;
@property(nonatomic, weak) id<ApplicationCommands> dispatcher;
// URL loader being managed by this Coordinator.
@property(nonatomic, weak) id<UrlLoader> loader;
// Delegate used to make the Tab UI visible.
......
......@@ -4,8 +4,6 @@
#include "ios/chrome/browser/ui/history/history_coordinator.h"
#include <memory>
#include "components/browser_sync/profile_sync_service.h"
#include "components/history/core/browser/browsing_history_service.h"
#include "components/keyed_service/core/service_access_type.h"
......
......@@ -96,6 +96,8 @@ const int kRelativeTimeMaxHours = 4;
const CGFloat kSingleLineSectionHeaderHeight = 44;
// Height for double line headers.
const CGFloat kDoubleLineSectionHeaderHeight = 56;
// Section index for recently closed tabs.
const int kRecentlyClosedTabsSectionIndex = 0;
} // namespace
......@@ -194,7 +196,8 @@ const CGFloat kDoubleLineSectionHeaderHeight = 56;
TableViewModel* model = self.tableViewModel;
// Recently Closed Section.
[model addSectionWithIdentifier:SectionIdentifierRecentlyClosedTabs];
[model insertSectionWithIdentifier:SectionIdentifierRecentlyClosedTabs
atIndex:kRecentlyClosedTabsSectionIndex];
[model setSectionIdentifier:SectionIdentifierRecentlyClosedTabs
collapsedKey:kRecentlyClosedCollapsedKey];
TableViewDisclosureHeaderFooterItem* header =
......@@ -218,6 +221,8 @@ const CGFloat kDoubleLineSectionHeaderHeight = 56;
toSectionWithIdentifier:SectionIdentifierRecentlyClosedTabs];
}
// Iterates through all the TabRestoreService entries and adds items to the
// recently closed tabs section. This method performs no UITableView operations.
- (void)addRecentlyClosedTabItems {
if (!self.tabRestoreService)
return;
......@@ -241,6 +246,19 @@ const CGFloat kDoubleLineSectionHeaderHeight = 56;
}
}
// Updates the recently closed tabs section by clobbering and reinserting
// section. Needs to be called inside a [UITableView beginUpdates] block on
// iOS10, or performBatchUpdates on iOS11+.
- (void)updateRecentlyClosedSection {
[self.tableViewModel
removeSectionWithIdentifier:SectionIdentifierRecentlyClosedTabs];
[self addRecentlyClosedSection];
NSUInteger index = [self.tableViewModel
sectionForSectionIdentifier:SectionIdentifierRecentlyClosedTabs];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index]
withRowAnimation:UITableViewRowAnimationNone];
}
#pragma mark Sessions Section
// Cleans up the model in order to update the Session sections. Needs to be
......@@ -560,7 +578,16 @@ const CGFloat kDoubleLineSectionHeaderHeight = 56;
}
- (void)refreshRecentlyClosedTabs {
[self.tableView reloadData];
if (@available(iOS 11, *)) {
[self.tableView performBatchUpdates:^{
[self updateRecentlyClosedSection];
}
completion:nil];
} else {
[self.tableView beginUpdates];
[self updateRecentlyClosedSection];
[self.tableView endUpdates];
}
}
- (void)setTabRestoreService:(sessions::TabRestoreService*)tabRestoreService {
......@@ -807,21 +834,13 @@ const CGFloat kDoubleLineSectionHeaderHeight = 56;
- (void)openTabWithTabRestoreEntry:
(const sessions::TabRestoreService::Entry*)entry {
DCHECK(entry);
if (!entry)
return;
// Only TAB type is handled.
if (entry->type != sessions::TabRestoreService::TAB)
return;
TabRestoreServiceDelegateImplIOS* delegate =
TabRestoreServiceDelegateImplIOSFactory::GetForBrowserState(
self.browserState);
DCHECK_EQ(entry->type, sessions::TabRestoreService::TAB);
base::RecordAction(
base::UserMetricsAction("MobileRecentTabManagerRecentTabOpened"));
new_tab_page_uma::RecordAction(
self.browserState, new_tab_page_uma::ACTION_OPENED_RECENTLY_CLOSED_ENTRY);
self.tabRestoreService->RestoreEntryById(delegate, entry->id,
WindowOpenDisposition::CURRENT_TAB);
[self.loader restoreTabWithSessionID:entry->id];
[self.presentationDelegate showActiveRegularTabFromRecentTabs];
}
......
......@@ -25,6 +25,7 @@ source_set("tab_grid") {
"//components/favicon/ios",
"//ios/chrome/browser",
"//ios/chrome/browser/browser_state",
"//ios/chrome/browser/sessions",
"//ios/chrome/browser/sessions:serialisation",
"//ios/chrome/browser/snapshots",
"//ios/chrome/browser/tabs",
......
......@@ -356,6 +356,8 @@
browserState:self.regularTabModel.browserState];
self.historyCoordinator.loader = self.URLLoader;
self.historyCoordinator.presentationDelegate = self;
self.historyCoordinator.dispatcher =
static_cast<id<ApplicationCommands>>(self.dispatcher);
[self.historyCoordinator start];
}
......
......@@ -15,7 +15,11 @@ class ChromeBrowserState;
class WebStateList;
// Specialized URLLoader for the tab grid, which behaves differently than BVC.
// Specialized URLLoader for the tab grid.
// Loading a URL or sessionTab normally navigates the currently visible tab
// view, which meaning replacing the active WebState. When there is no currently
// visible tab view, loading a URL means adding a new WebState to the
// WebStateList.
@interface TabGridURLLoader : NSObject<UrlLoader>
- (instancetype)
initWithRegularWebStateList:(WebStateList*)regularWebStateList
......
......@@ -5,8 +5,12 @@
#import "ios/chrome/browser/ui/tab_grid/tab_grid_url_loader.h"
#include "components/sessions/core/session_types.h"
#include "components/sessions/core/tab_restore_service.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
#include "ios/chrome/browser/sessions/session_util.h"
#include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios.h"
#include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios_factory.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h"
#include "ios/chrome/browser/web_state_list/web_state_opener.h"
#include "ios/web/public/web_state/web_state.h"
......@@ -108,7 +112,8 @@ initWithRegularWebStateList:(WebStateList*)regularWebStateList
AppendAndActivateWebState(webStateList, std::move(webState));
}
// Opens |loadParams| in a new regular tab.
// Opens |loadParams| in a new regular tab, rather than replacing the active
// tab.
- (void)loadURLWithParams:
(const web::NavigationManager::WebLoadParams&)loadParams {
DCHECK(self.regularBrowserState);
......@@ -118,8 +123,21 @@ initWithRegularWebStateList:(WebStateList*)regularWebStateList
AppendAndActivateWebState(self.regularWebStateList, std::move(webState));
}
// Restores |sessionID| in a new foreground tab, instead of replacing the active
// tab.
- (void)restoreTabWithSessionID:(const SessionID)sessionID {
TabRestoreServiceDelegateImplIOS* delegate =
TabRestoreServiceDelegateImplIOSFactory::GetForBrowserState(
self.regularBrowserState);
sessions::TabRestoreService* restoreService =
IOSChromeTabRestoreServiceFactory::GetForBrowserState(
self.regularBrowserState);
restoreService->RestoreEntryById(delegate, sessionID,
WindowOpenDisposition::NEW_FOREGROUND_TAB);
}
- (void)loadJavaScriptFromLocationBar:(NSString*)script {
NOTREACHED() << "This is intentionally NO-OP in TabGridMediator.";
NOTREACHED() << "This is intentionally NO-OP in TabGridURLLoader.";
}
@end
......@@ -48,6 +48,8 @@ const float kImageWidth = 28.0f;
cell.imageView.backgroundColor = styler.tableViewBackgroundColor;
cell.titleLabel.backgroundColor = styler.tableViewBackgroundColor;
if (styler.cellTitleColor)
cell.titleLabel.textColor = styler.cellTitleColor;
}
@end
......
......@@ -8,6 +8,7 @@
#import <UIKit/UIKit.h>
#include "base/strings/string16.h"
#include "components/sessions/core/session_id.h"
#import "ios/web/public/navigation_manager.h"
class GURL;
......@@ -49,6 +50,9 @@ enum OpenPosition {
// Load a tab with the given session.
- (void)loadSessionTab:(const sessions::SessionTab*)sessionTab;
// Restores a closed tab with |sessionID|.
- (void)restoreTabWithSessionID:(const SessionID)sessionID;
// Loads the text entered in the location bar as javascript.
- (void)loadJavaScriptFromLocationBar:(NSString*)script;
......
......@@ -53,6 +53,9 @@
- (void)loadSessionTab:(const sessions::SessionTab*)sessionTab {
}
- (void)restoreTabWithSessionID:(const SessionID)sessionID {
}
- (void)loadJavaScriptFromLocationBar:(NSString*)script {
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment