Commit bf8e840d authored by Rohit Rao's avatar Rohit Rao Committed by Commit Bot

[ios] Introduces BookmarkHomeSharedState.

An upcoming refactoring will move methods out of BookmarkTableView and into
BookmarkHomeViewController or BookmarkHomeMediator. To ease this transition, we
introduce a data structure that holds various ivars that used to be in
BookmarkTableView.

BUG=839427,840381

Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: Iaeb854e3a5cc243e90dd6b5a6e15e70f679728f6
Reviewed-on: https://chromium-review.googlesource.com/1047365
Commit-Queue: Rohit Rao <rohitrao@chromium.org>
Reviewed-by: default avatarSergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556471}
parent 9628f381
...@@ -17,6 +17,8 @@ source_set("bookmarks") { ...@@ -17,6 +17,8 @@ source_set("bookmarks") {
"bookmark_folder_table_view_cell.mm", "bookmark_folder_table_view_cell.mm",
"bookmark_folder_view_controller.h", "bookmark_folder_view_controller.h",
"bookmark_folder_view_controller.mm", "bookmark_folder_view_controller.mm",
"bookmark_home_shared_state.h",
"bookmark_home_shared_state.mm",
"bookmark_home_view_controller.h", "bookmark_home_view_controller.h",
"bookmark_home_view_controller.mm", "bookmark_home_view_controller.mm",
"bookmark_home_waiting_view.h", "bookmark_home_waiting_view.h",
...@@ -102,6 +104,7 @@ source_set("bookmarks") { ...@@ -102,6 +104,7 @@ source_set("bookmarks") {
"//ios/chrome/browser/ui/icons", "//ios/chrome/browser/ui/icons",
"//ios/chrome/browser/ui/image_util", "//ios/chrome/browser/ui/image_util",
"//ios/chrome/browser/ui/keyboard", "//ios/chrome/browser/ui/keyboard",
"//ios/chrome/browser/ui/list_model",
"//ios/chrome/browser/ui/main:feature_flags", "//ios/chrome/browser/ui/main:feature_flags",
"//ios/chrome/browser/ui/material_components", "//ios/chrome/browser/ui/material_components",
"//ios/chrome/browser/ui/ntp", "//ios/chrome/browser/ui/ntp",
......
// Copyright 2018 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 IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_HOME_SHARED_STATE_H_
#define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_HOME_SHARED_STATE_H_
#import <UIKit/UIKit.h>
#import <set>
#import "ios/chrome/browser/ui/list_model/list_model.h"
@class BookmarkHomeSharedState;
@class BookmarkTableCell;
@class MDCFlexibleHeaderView;
@class TableViewModel;
namespace bookmarks {
class BookmarkModel;
class BookmarkNode;
}
typedef NS_ENUM(NSInteger, BookmarkHomeSectionIdentifier) {
BookmarkHomeSectionIdentifierPromo = kSectionIdentifierEnumZero,
BookmarkHomeSectionIdentifierBookmarks,
};
typedef NS_ENUM(NSInteger, BookmarkHomeItemType) {
BookmarkHomeItemTypePromo = kItemTypeEnumZero,
BookmarkHomeItemTypeBookmark,
};
@protocol BookmarkHomeSharedStateObserver
// Called when the set of edit nodes is cleared.
- (void)sharedStateDidClearEditNodes:(BookmarkHomeSharedState*)sharedState;
@end
// BookmarkHomeSharedState is a data structure that contains a number of fields
// that were previously ivars of BookmarkTableView. They are moved to a separate
// data structure in order to ease moving code between files.
@interface BookmarkHomeSharedState : NSObject
// Models.
// The model backing the table view.
@property(nonatomic, readonly, strong) TableViewModel* tableViewModel;
// The model holding bookmark data.
@property(nonatomic, readonly, assign) bookmarks::BookmarkModel* bookmarkModel;
// Views.
// The UITableView to show bookmarks.
@property(nonatomic, strong) UITableView* tableView;
// Header view to display the shadow below the app bar. It must be tracking the
// |tableView|.
@property(nonatomic, weak) MDCFlexibleHeaderView* headerView;
// State variables.
// The BookmarkNode that is currently being displayed by the table view. May be
// nil.
@property(nonatomic, assign)
const bookmarks::BookmarkNode* tableViewDisplayedRootNode;
// If the table view is in edit mode.
@property(nonatomic, assign) BOOL currentlyInEditMode;
// The set of nodes currently being edited.
@property(nonatomic, readonly, assign)
std::set<const bookmarks::BookmarkNode*>& editNodes;
// If a new folder is being added currently.
@property(nonatomic, assign) BOOL addingNewFolder;
// The cell for the newly created folder while its name is being edited. Set
// to nil once the editing completes. Corresponds to |editingFolderNode|.
@property(nonatomic, weak) BookmarkTableCell* editingFolderCell;
// The newly created folder node its name is being edited.
@property(nonatomic, assign) const bookmarks::BookmarkNode* editingFolderNode;
// Counts the number of favicon download requests from Google server in the
// lifespan of this tableView.
@property(nonatomic, assign) NSUInteger faviconDownloadCount;
// True if the promo is visible.
@property(nonatomic, assign) BOOL promoVisible;
// This object can have at most one observer.
@property(nonatomic, weak) id<BookmarkHomeSharedStateObserver> observer;
// Constants
// Minimal acceptable favicon size, in points.
+ (CGFloat)minFaviconSizePt;
// Desired favicon size, in points.
+ (CGFloat)desiredFaviconSizePt;
// Cell height, in points.
+ (CGFloat)cellHeightPt;
// Minimium spacing between keyboard and the titleText when creating new folder,
// in points.
+ (CGFloat)keyboardSpacingPt;
// Max number of favicon download requests in the lifespan of this tableView.
+ (NSUInteger)maxDownloadFaviconCount;
- (instancetype)initWithBookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
displayedRootNode:
(const bookmarks::BookmarkNode*)displayedRootNode
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@end
#endif // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_HOME_SHARED_STATE_H_
// Copyright 2018 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/ui/bookmarks/bookmark_home_shared_state.h"
#include "base/logging.h"
#import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_cell.h"
#import "ios/chrome/browser/ui/table_view/table_view_model.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Minimal acceptable favicon size, in points.
const CGFloat kMinFaviconSizePt = 16.0;
// Desired favicon size, in points.
const CGFloat kDesiredFaviconSizePt = 32.0;
// Cell height, in points.
const CGFloat kCellHeightPt = 56.0;
// Minimium spacing between keyboard and the titleText when creating new folder,
// in points.
const CGFloat kKeyboardSpacingPt = 16.0;
// Max number of favicon download requests in the lifespan of this tableView.
const NSUInteger kMaxDownloadFaviconCount = 50;
} // namespace
@implementation BookmarkHomeSharedState {
std::set<const bookmarks::BookmarkNode*> _editNodes;
}
@synthesize addingNewFolder = _addingNewFolder;
@synthesize bookmarkModel = _bookmarkModel;
@synthesize currentlyInEditMode = _currentlyInEditMode;
@synthesize editingFolderCell = _editingFolderCell;
@synthesize editingFolderNode = _editingFolderNode;
@synthesize faviconDownloadCount = _faviconDownloadCount;
@synthesize headerView = _headerView;
@synthesize observer = _observer;
@synthesize promoVisible = _promoVisible;
@synthesize tableView = _tableView;
@synthesize tableViewDisplayedRootNode = _tableViewDisplayedRootNode;
@synthesize tableViewModel = _tableViewModel;
- (instancetype)initWithBookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
displayedRootNode:
(const bookmarks::BookmarkNode*)displayedRootNode {
if ((self = [super init])) {
_tableViewModel = [[TableViewModel alloc] init];
_bookmarkModel = bookmarkModel;
_tableViewDisplayedRootNode = displayedRootNode;
}
return self;
}
- (void)setCurrentlyInEditMode:(BOOL)currentlyInEditMode {
DCHECK(self.tableView);
// If not in editing mode but the tableView's editing is ON, it means the
// table is waiting for a swipe-to-delete confirmation. In this case, we need
// to close the confirmation by setting tableView.editing to NO.
if (!_currentlyInEditMode && self.tableView.editing) {
self.tableView.editing = NO;
}
[self.editingFolderCell stopEdit];
_currentlyInEditMode = currentlyInEditMode;
_editNodes.clear();
[self.observer sharedStateDidClearEditNodes:self];
[self.tableView setEditing:currentlyInEditMode animated:YES];
}
- (std::set<const bookmarks::BookmarkNode*>&)editNodes {
return _editNodes;
}
+ (CGFloat)minFaviconSizePt {
return kMinFaviconSizePt;
}
+ (CGFloat)desiredFaviconSizePt {
return kDesiredFaviconSizePt;
}
+ (CGFloat)cellHeightPt {
return kCellHeightPt;
}
+ (CGFloat)keyboardSpacingPt {
return kKeyboardSpacingPt;
}
+ (NSUInteger)maxDownloadFaviconCount {
return kMaxDownloadFaviconCount;
}
@end
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_home_shared_state.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h"
#include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_navigation_controller.h"
...@@ -72,6 +73,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -72,6 +73,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
BookmarkEditViewControllerDelegate, BookmarkEditViewControllerDelegate,
BookmarkFolderEditorViewControllerDelegate, BookmarkFolderEditorViewControllerDelegate,
BookmarkFolderViewControllerDelegate, BookmarkFolderViewControllerDelegate,
BookmarkHomeSharedStateObserver,
BookmarkModelBridgeObserver, BookmarkModelBridgeObserver,
BookmarkPromoControllerDelegate, BookmarkPromoControllerDelegate,
BookmarkTableViewDelegate, BookmarkTableViewDelegate,
...@@ -87,6 +89,10 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -87,6 +89,10 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
BOOL _addedConstraints; BOOL _addedConstraints;
} }
// Shared state between BookmarkHome classes. Used as a temporary refactoring
// aid.
@property(nonatomic, strong) BookmarkHomeSharedState* sharedState;
// The bookmark model used. // The bookmark model used.
@property(nonatomic, assign) bookmarks::BookmarkModel* bookmarks; @property(nonatomic, assign) bookmarks::BookmarkModel* bookmarks;
...@@ -153,6 +159,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -153,6 +159,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
@synthesize dispatcher = _dispatcher; @synthesize dispatcher = _dispatcher;
@synthesize cachedContentPosition = _cachedContentPosition; @synthesize cachedContentPosition = _cachedContentPosition;
@synthesize isReconstructingFromCache = _isReconstructingFromCache; @synthesize isReconstructingFromCache = _isReconstructingFromCache;
@synthesize sharedState = _sharedState;
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
...@@ -243,13 +250,18 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -243,13 +250,18 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
#pragma mark - Protected #pragma mark - Protected
- (void)loadBookmarkViews { - (void)loadBookmarkViews {
DCHECK(_rootNode);
self.sharedState =
[[BookmarkHomeSharedState alloc] initWithBookmarkModel:_bookmarks
displayedRootNode:_rootNode];
self.sharedState.observer = self;
self.automaticallyAdjustsScrollViewInsets = NO; self.automaticallyAdjustsScrollViewInsets = NO;
self.bookmarksTableView = [[BookmarkTableView alloc] self.bookmarksTableView =
initWithBrowserState:self.browserState [[BookmarkTableView alloc] initWithSharedState:self.sharedState
browserState:self.browserState
delegate:self delegate:self
rootNode:_rootNode frame:self.view.bounds];
frame:self.view.bounds
presenter:self /* id<SigninPresenter> */];
[self.bookmarksTableView [self.bookmarksTableView
setAutoresizingMask:UIViewAutoresizingFlexibleWidth | setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight]; UIViewAutoresizingFlexibleHeight];
...@@ -413,7 +425,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -413,7 +425,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
selectedEditNodes: selectedEditNodes:
(const std::set<const bookmarks::BookmarkNode*>&)nodes { (const std::set<const bookmarks::BookmarkNode*>&)nodes {
// Early return if bookmarks table is not in edit mode. // Early return if bookmarks table is not in edit mode.
if (!self.bookmarksTableView.editing) { if (!self.sharedState.currentlyInEditMode) {
return; return;
} }
...@@ -716,15 +728,15 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -716,15 +728,15 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
// Set up navigation bar for the new UI. // Set up navigation bar for the new UI.
- (void)setupNavigationBar { - (void)setupNavigationBar {
DCHECK(self.sharedState.tableView);
self.navigationController.navigationBarHidden = YES; self.navigationController.navigationBarHidden = YES;
self.appBar = [[MDCAppBar alloc] init]; self.appBar = [[MDCAppBar alloc] init];
[self addChildViewController:self.appBar.headerViewController]; [self addChildViewController:self.appBar.headerViewController];
ConfigureAppBarWithCardStyle(self.appBar); ConfigureAppBarWithCardStyle(self.appBar);
// Set the header view's tracking scroll view. // Set the header view's tracking scroll view.
self.appBar.headerViewController.headerView.trackingScrollView = self.appBar.headerViewController.headerView.trackingScrollView =
self.bookmarksTableView.tableView; self.sharedState.tableView;
self.bookmarksTableView.headerView = self.sharedState.headerView = self.appBar.headerViewController.headerView;
self.appBar.headerViewController.headerView;
[self.appBar addSubviewsToParent]; [self.appBar addSubviewsToParent];
// Prevent the touch events on appBar from being forwarded to the tableView. // Prevent the touch events on appBar from being forwarded to the tableView.
...@@ -840,7 +852,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -840,7 +852,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
// Sets the editing mode for tableView, update context bar state accordingly. // Sets the editing mode for tableView, update context bar state accordingly.
- (void)setTableViewEditing:(BOOL)editing { - (void)setTableViewEditing:(BOOL)editing {
[self.bookmarksTableView setEditing:editing]; self.sharedState.currentlyInEditMode = editing;
[self setContextBarState:editing ? BookmarksContextBarBeginSelection [self setContextBarState:editing ? BookmarksContextBarBeginSelection
: BookmarksContextBarDefault]; : BookmarksContextBarDefault];
} }
...@@ -854,7 +866,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -854,7 +866,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
return; return;
} }
const std::set<const bookmarks::BookmarkNode*> nodes = const std::set<const bookmarks::BookmarkNode*> nodes =
[self.bookmarksTableView editNodes]; self.sharedState.editNodes;
switch (self.contextBarState) { switch (self.contextBarState) {
case BookmarksContextBarDefault: case BookmarksContextBarDefault:
// New Folder clicked. // New Folder clicked.
...@@ -886,7 +898,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -886,7 +898,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
return; return;
} }
const std::set<const bookmarks::BookmarkNode*> nodes = const std::set<const bookmarks::BookmarkNode*> nodes =
[self.bookmarksTableView editNodes]; self.sharedState.editNodes;
// Center button is shown and is clickable only when at least // Center button is shown and is clickable only when at least
// one node is selected. // one node is selected.
DCHECK(nodes.size() > 0); DCHECK(nodes.size() > 0);
...@@ -941,7 +953,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -941,7 +953,7 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
return; return;
} }
// Toggle edit mode. // Toggle edit mode.
[self setTableViewEditing:!self.bookmarksTableView.editing]; [self setTableViewEditing:!self.sharedState.currentlyInEditMode];
} }
#pragma mark - ContextBarStates #pragma mark - ContextBarStates
...@@ -1202,4 +1214,11 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) { ...@@ -1202,4 +1214,11 @@ std::vector<GURL> GetUrlsToOpen(const std::vector<const BookmarkNode*>& nodes) {
[self.dispatcher showSignin:command baseViewController:self]; [self.dispatcher showSignin:command baseViewController:self];
} }
#pragma mark - BookmarkHomeSharedStateObserver
- (void)sharedStateDidClearEditNodes:(BookmarkHomeSharedState*)sharedState {
[self bookmarkTableView:self.bookmarksTableView
selectedEditNodes:sharedState.editNodes];
}
@end @end
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include <set> #include <set>
@class BookmarkHomeSharedState;
@class BookmarkTableView;
class GURL; class GURL;
@protocol SigninPresenter; @protocol SigninPresenter;
@class SigninPromoViewConfigurator; @class SigninPromoViewConfigurator;
...@@ -21,9 +23,6 @@ namespace ios { ...@@ -21,9 +23,6 @@ namespace ios {
class ChromeBrowserState; class ChromeBrowserState;
} }
@class BookmarkTableView;
@class MDCFlexibleHeaderView;
// Delegate to handle actions on the table. // Delegate to handle actions on the table.
@protocol BookmarkTableViewDelegate<NSObject> @protocol BookmarkTableViewDelegate<NSObject>
...@@ -70,24 +69,15 @@ class ChromeBrowserState; ...@@ -70,24 +69,15 @@ class ChromeBrowserState;
@end @end
@interface BookmarkTableView : UIView @interface BookmarkTableView : UIView
// If the table is in edit mode.
@property(nonatomic, assign) BOOL editing;
// The UITableView to show bookmarks.
@property(nonatomic, strong, readonly) UITableView* tableView;
// Header view to display the shadow below the app bar. It must be tracking the
// |tableView|.
@property(nonatomic, weak) MDCFlexibleHeaderView* headerView;
// Shows all sub-folders and sub-urls of a folder node (that is set as the root // Shows all sub-folders and sub-urls of a folder node (that is set as the root
// node) in a UITableView. Note: This class intentionally does not try to // node) in a UITableView. Note: This class intentionally does not try to
// maintain state through a folder transition. A new instance of this class is // maintain state through a folder transition. A new instance of this class is
// pushed on the navigation stack for a different root node. // pushed on the navigation stack for a different root node.
- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState - (instancetype)initWithSharedState:(BookmarkHomeSharedState*)sharedState
browserState:(ios::ChromeBrowserState*)browserState
delegate:(id<BookmarkTableViewDelegate>)delegate delegate:(id<BookmarkTableViewDelegate>)delegate
rootNode:(const bookmarks::BookmarkNode*)rootNode frame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
frame:(CGRect)frame
presenter:(id<SigninPresenter>)presenter
NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
- (instancetype)initWithFrame:(CGRect)frame - (instancetype)initWithFrame:(CGRect)frame
...@@ -108,9 +98,6 @@ class ChromeBrowserState; ...@@ -108,9 +98,6 @@ class ChromeBrowserState;
// Called when adding a new folder // Called when adding a new folder
- (void)addNewFolder; - (void)addNewFolder;
// Returns the currently selected edit nodes.
- (const std::set<const bookmarks::BookmarkNode*>&)editNodes;
// Returns a vector of edit nodes. // Returns a vector of edit nodes.
- (std::vector<const bookmarks::BookmarkNode*>)getEditNodesInVector; - (std::vector<const bookmarks::BookmarkNode*>)getEditNodesInVector;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#import "ios/chrome/browser/ui/authentication/signin_promo_view_consumer.h" #import "ios/chrome/browser/ui/authentication/signin_promo_view_consumer.h"
#import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h"
#include "ios/chrome/browser/ui/bookmarks/bookmark_empty_background.h" #include "ios/chrome/browser/ui/bookmarks/bookmark_empty_background.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_home_shared_state.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_home_waiting_view.h"
#include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h" #include "ios/chrome/browser/ui/bookmarks/bookmark_model_bridge_observer.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
...@@ -40,21 +41,6 @@ ...@@ -40,21 +41,6 @@
#endif #endif
namespace { namespace {
// Minimal acceptable favicon size, in points.
const CGFloat kMinFaviconSizePt = 16.0;
// Desired favicon size, in points.
const CGFloat kDesiredFaviconSizePt = 32.0;
// Cell height, in points.
const CGFloat kCellHeightPt = 56.0;
// Minimium spacing between keyboard and the titleText when creating new folder,
// in points.
const CGFloat kKeyboardSpacing = 16.0;
// Max number of favicon download requests in the lifespan of this tableView.
const NSUInteger kMaxDownloadFaviconCount = 50;
// NetworkTrafficAnnotationTag for fetching favicon from a Google server. // NetworkTrafficAnnotationTag for fetching favicon from a Google server.
const net::NetworkTrafficAnnotationTag kTrafficAnnotation = const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
...@@ -77,16 +63,6 @@ const net::NetworkTrafficAnnotationTag kTrafficAnnotation = ...@@ -77,16 +63,6 @@ const net::NetworkTrafficAnnotationTag kTrafficAnnotation =
} }
)"); )");
typedef NS_ENUM(NSInteger, SectionIdentifier) {
SectionIdentifierPromo = kSectionIdentifierEnumZero,
SectionIdentifierBookmarks,
};
typedef NS_ENUM(NSInteger, ItemType) {
ItemTypePromo = kItemTypeEnumZero,
ItemTypeBookmark,
};
} // namespace } // namespace
using bookmarks::BookmarkNode; using bookmarks::BookmarkNode;
...@@ -168,12 +144,6 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -168,12 +144,6 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
UIGestureRecognizerDelegate, UIGestureRecognizerDelegate,
UITableViewDataSource, UITableViewDataSource,
UITableViewDelegate> { UITableViewDelegate> {
// The current root node of this table view.
const BookmarkNode* _currentRootNode;
// The newly created folder node its name is being edited.
const BookmarkNode* _editingFolderNode;
// Bridge to register for bookmark changes. // Bridge to register for bookmark changes.
std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge; std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge;
...@@ -187,18 +157,10 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -187,18 +157,10 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
std::map<IntegerPair, base::CancelableTaskTracker::TaskId> _faviconLoadTasks; std::map<IntegerPair, base::CancelableTaskTracker::TaskId> _faviconLoadTasks;
// Task tracker used for async favicon loads. // Task tracker used for async favicon loads.
base::CancelableTaskTracker _faviconTaskTracker; base::CancelableTaskTracker _faviconTaskTracker;
// True if the promo is visible.
BOOL _promoVisible;
// Set of nodes being editing currently.
std::set<const bookmarks::BookmarkNode*> _editNodes;
} }
// The model backing the table view. // State used by this table view.
@property(nonatomic, strong) TableViewModel* tableViewModel; @property(nonatomic, strong) BookmarkHomeSharedState* sharedState;
// The model holding bookmark data.
@property(nonatomic, assign) bookmarks::BookmarkModel* bookmarkModel;
// The browser state. // The browser state.
@property(nonatomic, assign) ios::ChromeBrowserState* browserState; @property(nonatomic, assign) ios::ChromeBrowserState* browserState;
// The delegate for actions on the table. // The delegate for actions on the table.
...@@ -209,94 +171,71 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -209,94 +171,71 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// The loading spinner background which appears when syncing. // The loading spinner background which appears when syncing.
@property(nonatomic, strong) BookmarkHomeWaitingView* spinnerView; @property(nonatomic, strong) BookmarkHomeWaitingView* spinnerView;
// Presenter for showing signin UI.
@property(nonatomic, readonly, weak) id<SigninPresenter> presenter;
// If a new folder is being added currently.
@property(nonatomic, assign) BOOL addingNewFolder;
// The cell for the newly created folder while its name is being edited. Set
// to nil once the editing completes. Corresponds to |_editingFolderNode|.
@property(nonatomic, weak) BookmarkTableCell* editingFolderCell;
// Counts the number of favicon download requests from Google server in the
// lifespan of this tableView.
@property(nonatomic, assign) NSUInteger faviconDownloadCount;
@end @end
@implementation BookmarkTableView @implementation BookmarkTableView
@synthesize tableView = _tableView;
@synthesize tableViewModel = _tableViewModel;
@synthesize headerView = _headerView;
@synthesize bookmarkModel = _bookmarkModel;
@synthesize browserState = _browserState; @synthesize browserState = _browserState;
@synthesize delegate = _delegate; @synthesize delegate = _delegate;
@synthesize emptyTableBackgroundView = _emptyTableBackgroundView; @synthesize emptyTableBackgroundView = _emptyTableBackgroundView;
@synthesize spinnerView = _spinnerView; @synthesize spinnerView = _spinnerView;
@synthesize editing = _editing; @synthesize sharedState = _sharedState;
@synthesize presenter = _presenter;
@synthesize addingNewFolder = _addingNewFolder;
@synthesize editingFolderCell = _editingFolderCell;
@synthesize faviconDownloadCount = _faviconDownloadCount;
- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState - (instancetype)initWithSharedState:(BookmarkHomeSharedState*)sharedState
browserState:(ios::ChromeBrowserState*)browserState
delegate:(id<BookmarkTableViewDelegate>)delegate delegate:(id<BookmarkTableViewDelegate>)delegate
rootNode:(const BookmarkNode*)rootNode frame:(CGRect)frame {
frame:(CGRect)frame
presenter:(id<SigninPresenter>)presenter {
self = [super initWithFrame:frame]; self = [super initWithFrame:frame];
if (self) { if (self) {
DCHECK(rootNode); DCHECK(sharedState.tableViewDisplayedRootNode);
_sharedState = sharedState;
_browserState = browserState; _browserState = browserState;
_delegate = delegate; _delegate = delegate;
_currentRootNode = rootNode;
_presenter = presenter;
// Set up connection to the BookmarkModel. // Temporary calls to ensure that we're initializing to the right values.
_bookmarkModel = DCHECK_EQ(self.sharedState.bookmarkModel,
ios::BookmarkModelFactory::GetForBrowserState(browserState); ios::BookmarkModelFactory::GetForBrowserState(browserState));
// Set up observers. // Set up observers.
_modelBridge = _modelBridge = std::make_unique<bookmarks::BookmarkModelBridge>(
std::make_unique<bookmarks::BookmarkModelBridge>(self, _bookmarkModel); self, self.sharedState.bookmarkModel);
_syncedSessionsObserver = _syncedSessionsObserver =
std::make_unique<synced_sessions::SyncedSessionsObserverBridge>( std::make_unique<synced_sessions::SyncedSessionsObserverBridge>(
self, _browserState); self, _browserState);
// Create and populate the model. // Populate the model.
_tableViewModel = [[TableViewModel alloc] init];
[self computeBookmarkTableViewData]; [self computeBookmarkTableViewData];
// Set promo state before the tableview is created. // Set promo state before the tableview is created.
[self promoStateChangedAnimated:NO]; [self promoStateChangedAnimated:NO];
// Create and setup tableview. // Create and setup tableview.
_tableView = self.sharedState.tableView =
[[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain]; [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain];
self.tableView.accessibilityIdentifier = @"bookmarksTableView"; self.sharedState.tableView.accessibilityIdentifier = @"bookmarksTableView";
self.tableView.dataSource = self; self.sharedState.tableView.dataSource = self;
self.tableView.delegate = self; self.sharedState.tableView.delegate = self;
if (@available(iOS 11.0, *)) { if (@available(iOS 11.0, *)) {
self.tableView.contentInsetAdjustmentBehavior = self.sharedState.tableView.contentInsetAdjustmentBehavior =
UIScrollViewContentInsetAdjustmentNever; UIScrollViewContentInsetAdjustmentNever;
} }
self.tableView.estimatedRowHeight = kCellHeightPt; self.sharedState.tableView.estimatedRowHeight =
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; [BookmarkHomeSharedState cellHeightPt];
self.sharedState.tableView.separatorStyle =
UITableViewCellSeparatorStyleNone;
// Remove extra rows. // Remove extra rows.
self.tableView.autoresizingMask = self.sharedState.tableView.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.tableView.allowsMultipleSelectionDuringEditing = YES; self.sharedState.tableView.allowsMultipleSelectionDuringEditing = YES;
UILongPressGestureRecognizer* longPressRecognizer = UILongPressGestureRecognizer* longPressRecognizer =
[[UILongPressGestureRecognizer alloc] [[UILongPressGestureRecognizer alloc]
initWithTarget:self initWithTarget:self
action:@selector(handleLongPress:)]; action:@selector(handleLongPress:)];
longPressRecognizer.numberOfTouchesRequired = 1; longPressRecognizer.numberOfTouchesRequired = 1;
longPressRecognizer.delegate = self; longPressRecognizer.delegate = self;
[self.tableView addGestureRecognizer:longPressRecognizer]; [self.sharedState.tableView addGestureRecognizer:longPressRecognizer];
[self addSubview:self.tableView]; [self addSubview:self.sharedState.tableView];
[self bringSubviewToFront:self.tableView]; [self bringSubviewToFront:self.sharedState.tableView];
[self registerForKeyboardNotifications]; [self registerForKeyboardNotifications];
[self showEmptyOrLoadingSpinnerBackgroundIfNeeded]; [self showEmptyOrLoadingSpinnerBackgroundIfNeeded];
...@@ -306,8 +245,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -306,8 +245,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)dealloc { - (void)dealloc {
[self removeKeyboardObservers]; [self removeKeyboardObservers];
_tableView.dataSource = nil; _sharedState.tableView.dataSource = nil;
_tableView.delegate = nil; _sharedState.tableView.delegate = nil;
_faviconTaskTracker.TryCancelAll(); _faviconTaskTracker.TryCancelAll();
} }
...@@ -317,25 +256,28 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -317,25 +256,28 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// We show promo cell only on the root view, that is when showing // We show promo cell only on the root view, that is when showing
// the permanent nodes. // the permanent nodes.
BOOL promoVisible = BOOL promoVisible =
((_currentRootNode == self.bookmarkModel->root_node()) && ((self.sharedState.tableViewDisplayedRootNode ==
self.sharedState.bookmarkModel->root_node()) &&
[self.delegate bookmarkTableViewShouldShowPromoCell:self]); [self.delegate bookmarkTableViewShouldShowPromoCell:self]);
if (promoVisible == _promoVisible) { if (promoVisible == self.sharedState.promoVisible) {
return; return;
} }
_promoVisible = promoVisible; self.sharedState.promoVisible = promoVisible;
SigninPromoViewMediator* mediator = self.delegate.signinPromoViewMediator; SigninPromoViewMediator* mediator = self.delegate.signinPromoViewMediator;
if (_promoVisible) { if (self.sharedState.promoVisible) {
DCHECK(![self.tableViewModel DCHECK(![self.sharedState.tableViewModel
hasSectionForSectionIdentifier:SectionIdentifierPromo]); hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]);
[self.tableViewModel insertSectionWithIdentifier:SectionIdentifierPromo [self.sharedState.tableViewModel
insertSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo
atIndex:0]; atIndex:0];
BookmarkPromoItem* item = BookmarkPromoItem* item =
[[BookmarkPromoItem alloc] initWithType:ItemTypePromo]; [[BookmarkPromoItem alloc] initWithType:BookmarkHomeItemTypePromo];
item.mediatorProvider = self.delegate; item.mediatorProvider = self.delegate;
[self.tableViewModel addItem:item [self.sharedState.tableViewModel
toSectionWithIdentifier:SectionIdentifierPromo]; addItem:item
toSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo];
[mediator signinPromoViewVisible]; [mediator signinPromoViewVisible];
} else { } else {
if (![mediator isInvalidClosedOrNeverVisible]) { if (![mediator isInvalidClosedOrNeverVisible]) {
...@@ -344,27 +286,28 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -344,27 +286,28 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
[mediator signinPromoViewHidden]; [mediator signinPromoViewHidden];
} }
DCHECK([self.tableViewModel DCHECK([self.sharedState.tableViewModel
hasSectionForSectionIdentifier:SectionIdentifierPromo]); hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]);
[self.tableViewModel removeSectionWithIdentifier:SectionIdentifierPromo]; [self.sharedState.tableViewModel
removeSectionWithIdentifier:BookmarkHomeSectionIdentifierPromo];
} }
[self.tableView reloadData]; [self.sharedState.tableView reloadData];
} }
- (void)configureSigninPromoWithConfigurator: - (void)configureSigninPromoWithConfigurator:
(SigninPromoViewConfigurator*)configurator (SigninPromoViewConfigurator*)configurator
identityChanged:(BOOL)identityChanged { identityChanged:(BOOL)identityChanged {
if (![self.tableViewModel if (![self.sharedState.tableViewModel
hasSectionForSectionIdentifier:SectionIdentifierPromo]) { hasSectionForSectionIdentifier:BookmarkHomeSectionIdentifierPromo]) {
return; return;
} }
NSIndexPath* indexPath = NSIndexPath* indexPath = [self.sharedState.tableViewModel
[self.tableViewModel indexPathForItemType:ItemTypePromo indexPathForItemType:BookmarkHomeItemTypePromo
sectionIdentifier:SectionIdentifierPromo]; sectionIdentifier:BookmarkHomeSectionIdentifierPromo];
BookmarkTableSigninPromoCell* signinPromoCell = BookmarkTableSigninPromoCell* signinPromoCell =
base::mac::ObjCCast<BookmarkTableSigninPromoCell>( base::mac::ObjCCast<BookmarkTableSigninPromoCell>(
[self.tableView cellForRowAtIndexPath:indexPath]); [self.sharedState.tableView cellForRowAtIndexPath:indexPath]);
if (!signinPromoCell) { if (!signinPromoCell) {
return; return;
} }
...@@ -374,68 +317,59 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -374,68 +317,59 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
if (identityChanged) { if (identityChanged) {
// The section should be reload to update the cell height. // The section should be reload to update the cell height.
NSIndexSet* indexSet = [NSIndexSet indexSetWithIndex:indexPath.section]; NSIndexSet* indexSet = [NSIndexSet indexSetWithIndex:indexPath.section];
[self.tableView reloadSections:indexSet [self.sharedState.tableView reloadSections:indexSet
withRowAnimation:UITableViewRowAnimationNone]; withRowAnimation:UITableViewRowAnimationNone];
} }
} }
- (void)addNewFolder { - (void)addNewFolder {
[self.editingFolderCell stopEdit]; [self.sharedState.editingFolderCell stopEdit];
if (!_currentRootNode) { if (!self.sharedState.tableViewDisplayedRootNode) {
return; return;
} }
self.addingNewFolder = YES; self.sharedState.addingNewFolder = YES;
base::string16 folderTitle = base::SysNSStringToUTF16( base::string16 folderTitle = base::SysNSStringToUTF16(
l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_GROUP_DEFAULT_NAME)); l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_GROUP_DEFAULT_NAME));
_editingFolderNode = self.bookmarkModel->AddFolder( self.sharedState.editingFolderNode =
_currentRootNode, _currentRootNode->child_count(), folderTitle); self.sharedState.bookmarkModel->AddFolder(
self.sharedState.tableViewDisplayedRootNode,
BookmarkNodeItem* nodeItem = self.sharedState.tableViewDisplayedRootNode->child_count(),
[[BookmarkNodeItem alloc] initWithType:ItemTypeBookmark folderTitle);
bookmarkNode:_editingFolderNode];
[self.tableViewModel addItem:nodeItem BookmarkNodeItem* nodeItem = [[BookmarkNodeItem alloc]
toSectionWithIdentifier:SectionIdentifierBookmarks]; initWithType:BookmarkHomeItemTypeBookmark
bookmarkNode:self.sharedState.editingFolderNode];
[self.sharedState.tableViewModel
addItem:nodeItem
toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
// Insert the new folder cell at the end of the table. // Insert the new folder cell at the end of the table.
NSIndexPath* newRowIndexPath = NSIndexPath* newRowIndexPath =
[self.tableViewModel indexPathForItem:nodeItem]; [self.sharedState.tableViewModel indexPathForItem:nodeItem];
NSMutableArray* newRowIndexPaths = NSMutableArray* newRowIndexPaths =
[[NSMutableArray alloc] initWithObjects:newRowIndexPath, nil]; [[NSMutableArray alloc] initWithObjects:newRowIndexPath, nil];
[self.tableView beginUpdates]; [self.sharedState.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:newRowIndexPaths [self.sharedState.tableView
insertRowsAtIndexPaths:newRowIndexPaths
withRowAnimation:UITableViewRowAnimationNone]; withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; [self.sharedState.tableView endUpdates];
// Scroll to the end of the table // Scroll to the end of the table
[self.tableView scrollToRowAtIndexPath:newRowIndexPath [self.sharedState.tableView
scrollToRowAtIndexPath:newRowIndexPath
atScrollPosition:UITableViewScrollPositionBottom atScrollPosition:UITableViewScrollPositionBottom
animated:YES]; animated:YES];
} }
- (void)setEditing:(BOOL)editing {
// If not in editing mode but the tableView's editing is ON, it means the
// table is waiting for a swipe-to-delete confirmation. In this case, we need
// to close the confirmation by setting tableView.editing to NO.
if (!_editing && self.tableView.editing) {
self.tableView.editing = NO;
}
[self.editingFolderCell stopEdit];
_editing = editing;
[self resetEditNodes];
[self.tableView setEditing:editing animated:YES];
}
- (const std::set<const bookmarks::BookmarkNode*>&)editNodes {
return _editNodes;
}
- (std::vector<const bookmarks::BookmarkNode*>)getEditNodesInVector { - (std::vector<const bookmarks::BookmarkNode*>)getEditNodesInVector {
// Create a vector of edit nodes in the same order as the nodes in folder. // Create a vector of edit nodes in the same order as the nodes in folder.
std::vector<const bookmarks::BookmarkNode*> nodes; std::vector<const bookmarks::BookmarkNode*> nodes;
int childCount = _currentRootNode->child_count(); int childCount = self.sharedState.tableViewDisplayedRootNode->child_count();
for (int i = 0; i < childCount; ++i) { for (int i = 0; i < childCount; ++i) {
const BookmarkNode* node = _currentRootNode->GetChild(i); const BookmarkNode* node =
if (_editNodes.find(node) != _editNodes.end()) { self.sharedState.tableViewDisplayedRootNode->GetChild(i);
if (self.sharedState.editNodes.find(node) !=
self.sharedState.editNodes.end()) {
nodes.push_back(node); nodes.push_back(node);
} }
} }
...@@ -443,31 +377,37 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -443,31 +377,37 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
} }
- (BOOL)hasBookmarksOrFolders { - (BOOL)hasBookmarksOrFolders {
return _currentRootNode && !_currentRootNode->empty(); return self.sharedState.tableViewDisplayedRootNode &&
!self.sharedState.tableViewDisplayedRootNode->empty();
} }
- (BOOL)allowsNewFolder { - (BOOL)allowsNewFolder {
// When the current root node has been removed remotely (becomes NULL), // When the current root node has been removed remotely (becomes NULL),
// creating new folder is forbidden. // creating new folder is forbidden.
return _currentRootNode != NULL; return self.sharedState.tableViewDisplayedRootNode != NULL;
} }
- (CGFloat)contentPosition { - (CGFloat)contentPosition {
if (_currentRootNode == self.bookmarkModel->root_node()) { if (self.sharedState.tableViewDisplayedRootNode ==
self.sharedState.bookmarkModel->root_node()) {
return 0; return 0;
} }
// Divided the scroll position by cell height so that it will stay correct in // Divided the scroll position by cell height so that it will stay correct in
// case the cell height is changed in future. // case the cell height is changed in future.
return self.tableView.contentOffset.y / kCellHeightPt; return self.sharedState.tableView.contentOffset.y /
[BookmarkHomeSharedState cellHeightPt];
} }
- (void)setContentPosition:(CGFloat)position { - (void)setContentPosition:(CGFloat)position {
// The scroll position was divided by the cell height when stored. // The scroll position was divided by the cell height when stored.
[self.tableView setContentOffset:CGPointMake(0, position * kCellHeightPt)]; [self.sharedState.tableView
setContentOffset:CGPointMake(
0,
position * [BookmarkHomeSharedState cellHeightPt])];
} }
- (void)navigateAway { - (void)navigateAway {
[self.editingFolderCell stopEdit]; [self.sharedState.editingFolderCell stopEdit];
} }
#pragma mark - UIView #pragma mark - UIView
...@@ -475,41 +415,42 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -475,41 +415,42 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection]; [super traitCollectionDidChange:previousTraitCollection];
// Stop edit of current bookmark folder name, if any. // Stop edit of current bookmark folder name, if any.
[self.editingFolderCell stopEdit]; [self.sharedState.editingFolderCell stopEdit];
} }
#pragma mark - UITableViewDataSource #pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
return [self.tableViewModel numberOfSections]; return [self.sharedState.tableViewModel numberOfSections];
} }
- (NSInteger)tableView:(UITableView*)tableView - (NSInteger)tableView:(UITableView*)tableView
numberOfRowsInSection:(NSInteger)section { numberOfRowsInSection:(NSInteger)section {
return [self.tableViewModel numberOfItemsInSection:section]; return [self.sharedState.tableViewModel numberOfItemsInSection:section];
} }
- (UITableViewCell*)tableView:(UITableView*)tableView - (UITableViewCell*)tableView:(UITableView*)tableView
cellForRowAtIndexPath:(NSIndexPath*)indexPath { cellForRowAtIndexPath:(NSIndexPath*)indexPath {
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; TableViewItem* item =
[self.sharedState.tableViewModel itemAtIndexPath:indexPath];
Class cellClass = [item cellClass]; Class cellClass = [item cellClass];
NSString* reuseIdentifier = NSStringFromClass(cellClass); NSString* reuseIdentifier = NSStringFromClass(cellClass);
[self.tableView registerClass:cellClass [self.sharedState.tableView registerClass:cellClass
forCellReuseIdentifier:reuseIdentifier]; forCellReuseIdentifier:reuseIdentifier];
UITableViewCell* cell = UITableViewCell* cell = [self.sharedState.tableView
[self.tableView dequeueReusableCellWithIdentifier:reuseIdentifier dequeueReusableCellWithIdentifier:reuseIdentifier
forIndexPath:indexPath]; forIndexPath:indexPath];
[item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]]; [item configureCell:cell withStyler:[[ChromeTableViewStyler alloc] init]];
if (item.type == ItemTypeBookmark) { if (item.type == BookmarkHomeItemTypeBookmark) {
BookmarkNodeItem* nodeItem = BookmarkNodeItem* nodeItem =
base::mac::ObjCCastStrict<BookmarkNodeItem>(item); base::mac::ObjCCastStrict<BookmarkNodeItem>(item);
BookmarkTableCell* tableCell = BookmarkTableCell* tableCell =
base::mac::ObjCCastStrict<BookmarkTableCell>(cell); base::mac::ObjCCastStrict<BookmarkTableCell>(cell);
if (nodeItem.bookmarkNode == _editingFolderNode) { if (nodeItem.bookmarkNode == self.sharedState.editingFolderNode) {
// Delay starting edit, so that the cell is fully created. // Delay starting edit, so that the cell is fully created.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
self.editingFolderCell = tableCell; self.sharedState.editingFolderCell = tableCell;
[tableCell startEdit]; [tableCell startEdit];
tableCell.textDelegate = self; tableCell.textDelegate = self;
}); });
...@@ -527,8 +468,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -527,8 +468,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (BOOL)tableView:(UITableView*)tableView - (BOOL)tableView:(UITableView*)tableView
canEditRowAtIndexPath:(NSIndexPath*)indexPath { canEditRowAtIndexPath:(NSIndexPath*)indexPath {
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; TableViewItem* item =
if (item.type != ItemTypeBookmark) { [self.sharedState.tableViewModel itemAtIndexPath:indexPath];
if (item.type != BookmarkHomeItemTypeBookmark) {
// Can only edit bookmarks. // Can only edit bookmarks.
return NO; return NO;
} }
...@@ -544,8 +486,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -544,8 +486,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)tableView:(UITableView*)tableView - (void)tableView:(UITableView*)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath*)indexPath { forRowAtIndexPath:(NSIndexPath*)indexPath {
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; TableViewItem* item =
if (item.type != ItemTypeBookmark) { [self.sharedState.tableViewModel itemAtIndexPath:indexPath];
if (item.type != BookmarkHomeItemTypeBookmark) {
// Can only commit edits for bookmarks. // Can only commit edits for bookmarks.
return; return;
} }
...@@ -562,8 +505,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -562,8 +505,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (BOOL)tableView:(UITableView*)tableView - (BOOL)tableView:(UITableView*)tableView
canMoveRowAtIndexPath:(NSIndexPath*)indexPath { canMoveRowAtIndexPath:(NSIndexPath*)indexPath {
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; TableViewItem* item =
if (item.type != ItemTypeBookmark) { [self.sharedState.tableViewModel itemAtIndexPath:indexPath];
if (item.type != BookmarkHomeItemTypeBookmark) {
// Can only move bookmarks. // Can only move bookmarks.
return NO; return NO;
} }
...@@ -596,10 +540,10 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -596,10 +540,10 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (CGFloat)tableView:(UITableView*)tableView - (CGFloat)tableView:(UITableView*)tableView
heightForRowAtIndexPath:(NSIndexPath*)indexPath { heightForRowAtIndexPath:(NSIndexPath*)indexPath {
NSInteger sectionIdentifier = NSInteger sectionIdentifier = [self.sharedState.tableViewModel
[self.tableViewModel sectionIdentifierForSection:indexPath.section]; sectionIdentifierForSection:indexPath.section];
if (sectionIdentifier == SectionIdentifierBookmarks) { if (sectionIdentifier == BookmarkHomeSectionIdentifierBookmarks) {
return kCellHeightPt; return [BookmarkHomeSharedState cellHeightPt];
} }
return UITableViewAutomaticDimension; return UITableViewAutomaticDimension;
} }
...@@ -608,18 +552,19 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -608,18 +552,19 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)tableView:(UITableView*)tableView - (void)tableView:(UITableView*)tableView
didSelectRowAtIndexPath:(NSIndexPath*)indexPath { didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
NSInteger sectionIdentifier = NSInteger sectionIdentifier = [self.sharedState.tableViewModel
[self.tableViewModel sectionIdentifierForSection:indexPath.section]; sectionIdentifierForSection:indexPath.section];
if (sectionIdentifier == SectionIdentifierBookmarks) { if (sectionIdentifier == BookmarkHomeSectionIdentifierBookmarks) {
const BookmarkNode* node = [self nodeAtIndexPath:indexPath]; const BookmarkNode* node = [self nodeAtIndexPath:indexPath];
DCHECK(node); DCHECK(node);
// If table is in edit mode, record all the nodes added to edit set. // If table is in edit mode, record all the nodes added to edit set.
if (self.editing) { if (self.sharedState.currentlyInEditMode) {
_editNodes.insert(node); self.sharedState.editNodes.insert(node);
[self.delegate bookmarkTableView:self selectedEditNodes:_editNodes]; [self.delegate bookmarkTableView:self
selectedEditNodes:self.sharedState.editNodes];
return; return;
} }
[self.editingFolderCell stopEdit]; [self.sharedState.editingFolderCell stopEdit];
if (node->is_folder()) { if (node->is_folder()) {
[self.delegate bookmarkTableView:self selectedFolderForNavigation:node]; [self.delegate bookmarkTableView:self selectedFolderForNavigation:node];
} else { } else {
...@@ -634,13 +579,15 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -634,13 +579,15 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)tableView:(UITableView*)tableView - (void)tableView:(UITableView*)tableView
didDeselectRowAtIndexPath:(NSIndexPath*)indexPath { didDeselectRowAtIndexPath:(NSIndexPath*)indexPath {
NSInteger sectionIdentifier = NSInteger sectionIdentifier = [self.sharedState.tableViewModel
[self.tableViewModel sectionIdentifierForSection:indexPath.section]; sectionIdentifierForSection:indexPath.section];
if (sectionIdentifier == SectionIdentifierBookmarks && self.editing) { if (sectionIdentifier == BookmarkHomeSectionIdentifierBookmarks &&
self.sharedState.currentlyInEditMode) {
const BookmarkNode* node = [self nodeAtIndexPath:indexPath]; const BookmarkNode* node = [self nodeAtIndexPath:indexPath];
DCHECK(node); DCHECK(node);
_editNodes.erase(node); self.sharedState.editNodes.erase(node);
[self.delegate bookmarkTableView:self selectedEditNodes:_editNodes]; [self.delegate bookmarkTableView:self
selectedEditNodes:self.sharedState.editNodes];
} }
} }
...@@ -656,7 +603,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -656,7 +603,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// The node has changed, but not its children. // The node has changed, but not its children.
- (void)bookmarkNodeChanged:(const BookmarkNode*)bookmarkNode { - (void)bookmarkNodeChanged:(const BookmarkNode*)bookmarkNode {
// The root folder changed. Do nothing. // The root folder changed. Do nothing.
if (bookmarkNode == _currentRootNode) { if (bookmarkNode == self.sharedState.tableViewDisplayedRootNode) {
return; return;
} }
...@@ -671,7 +618,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -671,7 +618,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// The current root folder's children changed. Reload everything. // The current root folder's children changed. Reload everything.
// (When adding new folder, table is already been updated. So no need to // (When adding new folder, table is already been updated. So no need to
// reload here.) // reload here.)
if (bookmarkNode == _currentRootNode && !self.addingNewFolder) { if (bookmarkNode == self.sharedState.tableViewDisplayedRootNode &&
!self.sharedState.addingNewFolder) {
[self refreshContents]; [self refreshContents];
return; return;
} }
...@@ -681,7 +629,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -681,7 +629,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)bookmarkNode:(const BookmarkNode*)bookmarkNode - (void)bookmarkNode:(const BookmarkNode*)bookmarkNode
movedFromParent:(const BookmarkNode*)oldParent movedFromParent:(const BookmarkNode*)oldParent
toParent:(const BookmarkNode*)newParent { toParent:(const BookmarkNode*)newParent {
if (oldParent == _currentRootNode || newParent == _currentRootNode) { if (oldParent == self.sharedState.tableViewDisplayedRootNode ||
newParent == self.sharedState.tableViewDisplayedRootNode) {
// A folder was added or removed from the current root folder. // A folder was added or removed from the current root folder.
[self refreshContents]; [self refreshContents];
} }
...@@ -690,8 +639,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -690,8 +639,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// |node| was deleted from |folder|. // |node| was deleted from |folder|.
- (void)bookmarkNodeDeleted:(const BookmarkNode*)node - (void)bookmarkNodeDeleted:(const BookmarkNode*)node
fromFolder:(const BookmarkNode*)folder { fromFolder:(const BookmarkNode*)folder {
if (_currentRootNode == node) { if (self.sharedState.tableViewDisplayedRootNode == node) {
_currentRootNode = NULL; self.sharedState.tableViewDisplayedRootNode = NULL;
[self refreshContents]; [self refreshContents];
} }
} }
...@@ -713,8 +662,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -713,8 +662,9 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
} }
// Check that this cell is visible. // Check that this cell is visible.
NSIndexPath* indexPath = [self.tableViewModel indexPathForItem:nodeItem]; NSIndexPath* indexPath =
NSArray* visiblePaths = [self.tableView indexPathsForVisibleRows]; [self.sharedState.tableViewModel indexPathForItem:nodeItem];
NSArray* visiblePaths = [self.sharedState.tableView indexPathsForVisibleRows];
if (![visiblePaths containsObject:indexPath]) { if (![visiblePaths containsObject:indexPath]) {
return; return;
} }
...@@ -728,7 +678,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -728,7 +678,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
shouldReceiveTouch:(UITouch*)touch { shouldReceiveTouch:(UITouch*)touch {
// Ignore long press in edit mode. // Ignore long press in edit mode.
if (self.editing) { if (self.sharedState.currentlyInEditMode) {
return NO; return NO;
} }
return YES; return YES;
...@@ -737,15 +687,17 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -737,15 +687,17 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
#pragma mark - Private #pragma mark - Private
- (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer { - (void)handleLongPress:(UILongPressGestureRecognizer*)gestureRecognizer {
if (self.editing || if (self.sharedState.currentlyInEditMode ||
gestureRecognizer.state != UIGestureRecognizerStateBegan) { gestureRecognizer.state != UIGestureRecognizerStateBegan) {
return; return;
} }
CGPoint touchPoint = [gestureRecognizer locationInView:self.tableView]; CGPoint touchPoint =
NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:touchPoint]; [gestureRecognizer locationInView:self.sharedState.tableView];
if (indexPath == nil || NSIndexPath* indexPath =
[self.tableViewModel sectionIdentifierForSection:indexPath.section] != [self.sharedState.tableView indexPathForRowAtPoint:touchPoint];
SectionIdentifierBookmarks) { if (indexPath == nil || [self.sharedState.tableViewModel
sectionIdentifierForSection:indexPath.section] !=
BookmarkHomeSectionIdentifierBookmarks) {
return; return;
} }
...@@ -759,14 +711,6 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -759,14 +711,6 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
[self.delegate bookmarkTableView:self showContextMenuForNode:node]; [self.delegate bookmarkTableView:self showContextMenuForNode:node];
} }
- (void)resetEditNodes {
_editNodes.clear();
if (self.editing) {
// Also update viewcontroler that the edit nodes changed, if in edit mode.
[self.delegate bookmarkTableView:self selectedEditNodes:_editNodes];
}
}
// Row selection of the tableView will be cleared after reloadData. This // Row selection of the tableView will be cleared after reloadData. This
// function is used to restore the row selection. It also updates editNodes in // function is used to restore the row selection. It also updates editNodes in
// case some selected nodes are removed. // case some selected nodes are removed.
...@@ -776,31 +720,35 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -776,31 +720,35 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// Add selected nodes to editNodes only if they are not removed (still exist // Add selected nodes to editNodes only if they are not removed (still exist
// in the table). // in the table).
NSArray<TableViewItem*>* items = [self.tableViewModel NSArray<TableViewItem*>* items = [self.sharedState.tableViewModel
itemsInSectionWithIdentifier:SectionIdentifierBookmarks]; itemsInSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
for (TableViewItem* item in items) { for (TableViewItem* item in items) {
BookmarkNodeItem* nodeItem = BookmarkNodeItem* nodeItem =
base::mac::ObjCCastStrict<BookmarkNodeItem>(item); base::mac::ObjCCastStrict<BookmarkNodeItem>(item);
const BookmarkNode* node = nodeItem.bookmarkNode; const BookmarkNode* node = nodeItem.bookmarkNode;
if (_editNodes.find(node) != _editNodes.end()) { if (self.sharedState.editNodes.find(node) !=
self.sharedState.editNodes.end()) {
newEditNodes.insert(node); newEditNodes.insert(node);
// Reselect the row of this node. // Reselect the row of this node.
NSIndexPath* itemPath = [self.tableViewModel indexPathForItem:nodeItem]; NSIndexPath* itemPath =
[self.tableView selectRowAtIndexPath:itemPath [self.sharedState.tableViewModel indexPathForItem:nodeItem];
[self.sharedState.tableView
selectRowAtIndexPath:itemPath
animated:NO animated:NO
scrollPosition:UITableViewScrollPositionNone]; scrollPosition:UITableViewScrollPositionNone];
} }
} }
// if editNodes is changed, update it and tell BookmarkTableViewDelegate. // if editNodes is changed, update it and tell BookmarkTableViewDelegate.
if (_editNodes.size() != newEditNodes.size()) { if (self.sharedState.editNodes.size() != newEditNodes.size()) {
_editNodes = newEditNodes; self.sharedState.editNodes = newEditNodes;
[self.delegate bookmarkTableView:self selectedEditNodes:_editNodes]; [self.delegate bookmarkTableView:self
selectedEditNodes:self.sharedState.editNodes];
} }
} }
- (BOOL)shouldShowPromoCell { - (BOOL)shouldShowPromoCell {
return _promoVisible; return self.sharedState.promoVisible;
} }
- (void)refreshContents { - (void)refreshContents {
...@@ -808,18 +756,20 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -808,18 +756,20 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
[self showEmptyOrLoadingSpinnerBackgroundIfNeeded]; [self showEmptyOrLoadingSpinnerBackgroundIfNeeded];
[self cancelAllFaviconLoads]; [self cancelAllFaviconLoads];
[self.delegate bookmarkTableViewRefreshContextBar:self]; [self.delegate bookmarkTableViewRefreshContextBar:self];
[self.editingFolderCell stopEdit]; [self.sharedState.editingFolderCell stopEdit];
[self.tableView reloadData]; [self.sharedState.tableView reloadData];
if (self.editing && !_editNodes.empty()) { if (self.sharedState.currentlyInEditMode &&
!self.sharedState.editNodes.empty()) {
[self restoreRowSelection]; [self restoreRowSelection];
} }
} }
// Returns the bookmark node associated with |indexPath|. // Returns the bookmark node associated with |indexPath|.
- (const BookmarkNode*)nodeAtIndexPath:(NSIndexPath*)indexPath { - (const BookmarkNode*)nodeAtIndexPath:(NSIndexPath*)indexPath {
TableViewItem* item = [self.tableViewModel itemAtIndexPath:indexPath]; TableViewItem* item =
[self.sharedState.tableViewModel itemAtIndexPath:indexPath];
if (item.type == ItemTypeBookmark) { if (item.type == BookmarkHomeItemTypeBookmark) {
BookmarkNodeItem* nodeItem = BookmarkNodeItem* nodeItem =
base::mac::ObjCCastStrict<BookmarkNodeItem>(item); base::mac::ObjCCastStrict<BookmarkNodeItem>(item);
return nodeItem.bookmarkNode; return nodeItem.bookmarkNode;
...@@ -832,18 +782,22 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -832,18 +782,22 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// Computes the bookmarks table view based on the current root node. // Computes the bookmarks table view based on the current root node.
- (void)computeBookmarkTableViewData { - (void)computeBookmarkTableViewData {
// Regenerate the list of all bookmarks. // Regenerate the list of all bookmarks.
if ([self.tableViewModel if ([self.sharedState.tableViewModel
hasSectionForSectionIdentifier:SectionIdentifierBookmarks]) { hasSectionForSectionIdentifier:
[self.tableViewModel BookmarkHomeSectionIdentifierBookmarks]) {
removeSectionWithIdentifier:SectionIdentifierBookmarks]; [self.sharedState.tableViewModel
removeSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
} }
[self.tableViewModel addSectionWithIdentifier:SectionIdentifierBookmarks]; [self.sharedState.tableViewModel
addSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
if (!self.bookmarkModel->loaded() || !_currentRootNode) { if (!self.sharedState.bookmarkModel->loaded() ||
!self.sharedState.tableViewDisplayedRootNode) {
return; return;
} }
if (_currentRootNode == self.bookmarkModel->root_node()) { if (self.sharedState.tableViewDisplayedRootNode ==
self.sharedState.bookmarkModel->root_node()) {
[self generateTableViewDataForRootNode]; [self generateTableViewDataForRootNode];
return; return;
} }
...@@ -852,18 +806,20 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -852,18 +806,20 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// Generate the table view data when the current root node is a child node. // Generate the table view data when the current root node is a child node.
- (void)generateTableViewData { - (void)generateTableViewData {
if (!_currentRootNode) { if (!self.sharedState.tableViewDisplayedRootNode) {
return; return;
} }
// Add all bookmarks and folders of the current root node to the table. // Add all bookmarks and folders of the current root node to the table.
int childCount = _currentRootNode->child_count(); int childCount = self.sharedState.tableViewDisplayedRootNode->child_count();
for (int i = 0; i < childCount; ++i) { for (int i = 0; i < childCount; ++i) {
const BookmarkNode* node = _currentRootNode->GetChild(i); const BookmarkNode* node =
self.sharedState.tableViewDisplayedRootNode->GetChild(i);
BookmarkNodeItem* nodeItem = BookmarkNodeItem* nodeItem =
[[BookmarkNodeItem alloc] initWithType:ItemTypeBookmark [[BookmarkNodeItem alloc] initWithType:BookmarkHomeItemTypeBookmark
bookmarkNode:node]; bookmarkNode:node];
[self.tableViewModel addItem:nodeItem [self.sharedState.tableViewModel
toSectionWithIdentifier:SectionIdentifierBookmarks]; addItem:nodeItem
toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
} }
} }
...@@ -871,38 +827,45 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -871,38 +827,45 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// root. // root.
- (void)generateTableViewDataForRootNode { - (void)generateTableViewDataForRootNode {
// Add "Mobile Bookmarks" to the table. // Add "Mobile Bookmarks" to the table.
const BookmarkNode* mobileNode = self.bookmarkModel->mobile_node(); const BookmarkNode* mobileNode =
self.sharedState.bookmarkModel->mobile_node();
BookmarkNodeItem* mobileItem = BookmarkNodeItem* mobileItem =
[[BookmarkNodeItem alloc] initWithType:ItemTypeBookmark [[BookmarkNodeItem alloc] initWithType:BookmarkHomeItemTypeBookmark
bookmarkNode:mobileNode]; bookmarkNode:mobileNode];
[self.tableViewModel addItem:mobileItem [self.sharedState.tableViewModel
toSectionWithIdentifier:SectionIdentifierBookmarks]; addItem:mobileItem
toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
// Add "Bookmarks Bar" and "Other Bookmarks" only when they are not empty. // Add "Bookmarks Bar" and "Other Bookmarks" only when they are not empty.
const BookmarkNode* bookmarkBar = self.bookmarkModel->bookmark_bar_node(); const BookmarkNode* bookmarkBar =
self.sharedState.bookmarkModel->bookmark_bar_node();
if (!bookmarkBar->empty()) { if (!bookmarkBar->empty()) {
BookmarkNodeItem* barItem = BookmarkNodeItem* barItem =
[[BookmarkNodeItem alloc] initWithType:ItemTypeBookmark [[BookmarkNodeItem alloc] initWithType:BookmarkHomeItemTypeBookmark
bookmarkNode:bookmarkBar]; bookmarkNode:bookmarkBar];
[self.tableViewModel addItem:barItem [self.sharedState.tableViewModel
toSectionWithIdentifier:SectionIdentifierBookmarks]; addItem:barItem
toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
} }
const BookmarkNode* otherBookmarks = self.bookmarkModel->other_node(); const BookmarkNode* otherBookmarks =
self.sharedState.bookmarkModel->other_node();
if (!otherBookmarks->empty()) { if (!otherBookmarks->empty()) {
BookmarkNodeItem* otherItem = BookmarkNodeItem* otherItem =
[[BookmarkNodeItem alloc] initWithType:ItemTypeBookmark [[BookmarkNodeItem alloc] initWithType:BookmarkHomeItemTypeBookmark
bookmarkNode:otherBookmarks]; bookmarkNode:otherBookmarks];
[self.tableViewModel addItem:otherItem [self.sharedState.tableViewModel
toSectionWithIdentifier:SectionIdentifierBookmarks]; addItem:otherItem
toSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
} }
} }
// If the current root node is the outermost root, check if we need to show the // If the current root node is the outermost root, check if we need to show the
// spinner backgound. Otherwise, check if we need to show the empty background. // spinner backgound. Otherwise, check if we need to show the empty background.
- (void)showEmptyOrLoadingSpinnerBackgroundIfNeeded { - (void)showEmptyOrLoadingSpinnerBackgroundIfNeeded {
if (_currentRootNode == self.bookmarkModel->root_node()) { if (self.sharedState.tableViewDisplayedRootNode ==
if (self.bookmarkModel->HasNoUserCreatedBookmarksOrFolders() && self.sharedState.bookmarkModel->root_node()) {
if (self.sharedState.bookmarkModel->HasNoUserCreatedBookmarksOrFolders() &&
_syncedSessionsObserver->IsSyncing()) { _syncedSessionsObserver->IsSyncing()) {
[self showLoadingSpinnerBackground]; [self showLoadingSpinnerBackground];
} else { } else {
...@@ -915,19 +878,19 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -915,19 +878,19 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
[self showEmptyBackground]; [self showEmptyBackground];
} else { } else {
// Hides the empty bookmarks background if it is showing. // Hides the empty bookmarks background if it is showing.
self.tableView.backgroundView = nil; self.sharedState.tableView.backgroundView = nil;
} }
} }
// Shows loading spinner background view. // Shows loading spinner background view.
- (void)showLoadingSpinnerBackground { - (void)showLoadingSpinnerBackground {
if (!self.spinnerView) { if (!self.spinnerView) {
self.spinnerView = self.spinnerView = [[BookmarkHomeWaitingView alloc]
[[BookmarkHomeWaitingView alloc] initWithFrame:self.tableView.bounds initWithFrame:self.sharedState.tableView.bounds
backgroundColor:[UIColor clearColor]]; backgroundColor:[UIColor clearColor]];
[self.spinnerView startWaiting]; [self.spinnerView startWaiting];
} }
self.tableView.backgroundView = self.spinnerView; self.sharedState.tableView.backgroundView = self.spinnerView;
} }
// Hide the loading spinner if it is showing. // Hide the loading spinner if it is showing.
...@@ -939,7 +902,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -939,7 +902,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
self.spinnerView.alpha = 0.0; self.spinnerView.alpha = 0.0;
} }
completion:^(BOOL finished) { completion:^(BOOL finished) {
self.tableView.backgroundView = nil; self.sharedState.tableView.backgroundView = nil;
self.spinnerView = nil; self.spinnerView = nil;
}]; }];
}]; }];
...@@ -950,22 +913,22 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -950,22 +913,22 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)showEmptyBackground { - (void)showEmptyBackground {
if (!self.emptyTableBackgroundView) { if (!self.emptyTableBackgroundView) {
// Set up the background view shown when the table is empty. // Set up the background view shown when the table is empty.
self.emptyTableBackgroundView = self.emptyTableBackgroundView = [[BookmarkEmptyBackground alloc]
[[BookmarkEmptyBackground alloc] initWithFrame:self.tableView.bounds]; initWithFrame:self.sharedState.tableView.bounds];
self.emptyTableBackgroundView.autoresizingMask = self.emptyTableBackgroundView.autoresizingMask =
UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.emptyTableBackgroundView.text = self.emptyTableBackgroundView.text =
l10n_util::GetNSString(IDS_IOS_BOOKMARK_NO_BOOKMARKS_LABEL); l10n_util::GetNSString(IDS_IOS_BOOKMARK_NO_BOOKMARKS_LABEL);
self.emptyTableBackgroundView.frame = self.tableView.bounds; self.emptyTableBackgroundView.frame = self.sharedState.tableView.bounds;
} }
self.tableView.backgroundView = self.emptyTableBackgroundView; self.sharedState.tableView.backgroundView = self.emptyTableBackgroundView;
} }
- (BookmarkNodeItem*)itemForNode:(const bookmarks::BookmarkNode*)bookmarkNode { - (BookmarkNodeItem*)itemForNode:(const bookmarks::BookmarkNode*)bookmarkNode {
NSArray<TableViewItem*>* items = [self.tableViewModel NSArray<TableViewItem*>* items = [self.sharedState.tableViewModel
itemsInSectionWithIdentifier:SectionIdentifierBookmarks]; itemsInSectionWithIdentifier:BookmarkHomeSectionIdentifierBookmarks];
for (TableViewItem* item in items) { for (TableViewItem* item in items) {
if (item.type == ItemTypeBookmark) { if (item.type == BookmarkHomeItemTypeBookmark) {
BookmarkNodeItem* nodeItem = BookmarkNodeItem* nodeItem =
base::mac::ObjCCastStrict<BookmarkNodeItem>(item); base::mac::ObjCCastStrict<BookmarkNodeItem>(item);
if (nodeItem.bookmarkNode == bookmarkNode) { if (nodeItem.bookmarkNode == bookmarkNode) {
...@@ -981,7 +944,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -981,7 +944,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
backgroundColor:(UIColor*)backgroundColor backgroundColor:(UIColor*)backgroundColor
textColor:(UIColor*)textColor textColor:(UIColor*)textColor
fallbackText:(NSString*)fallbackText { fallbackText:(NSString*)fallbackText {
BookmarkTableCell* cell = [self.tableView cellForRowAtIndexPath:indexPath]; BookmarkTableCell* cell =
[self.sharedState.tableView cellForRowAtIndexPath:indexPath];
if (!cell) { if (!cell) {
return; return;
} }
...@@ -1050,8 +1014,10 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -1050,8 +1014,10 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
} }
CGFloat scale = [UIScreen mainScreen].scale; CGFloat scale = [UIScreen mainScreen].scale;
CGFloat desiredFaviconSizeInPixel = scale * kDesiredFaviconSizePt; CGFloat desiredFaviconSizeInPixel =
CGFloat minFaviconSizeInPixel = scale * kMinFaviconSizePt; scale * [BookmarkHomeSharedState desiredFaviconSizePt];
CGFloat minFaviconSizeInPixel =
scale * [BookmarkHomeSharedState minFaviconSizePt];
// Start loading a favicon. // Start loading a favicon.
__weak BookmarkTableView* weakSelf = self; __weak BookmarkTableView* weakSelf = self;
...@@ -1068,7 +1034,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -1068,7 +1034,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
// cache is allowed, fetch icon from server here when cached icon is smaller // cache is allowed, fetch icon from server here when cached icon is smaller
// than the desired size. // than the desired size.
if (!result.bitmap.is_valid() && continueToGoogleServer && if (!result.bitmap.is_valid() && continueToGoogleServer &&
strongSelf.faviconDownloadCount < kMaxDownloadFaviconCount) { strongSelf.sharedState.faviconDownloadCount <
[BookmarkHomeSharedState maxDownloadFaviconCount]) {
void (^faviconLoadedFromServerBlock)( void (^faviconLoadedFromServerBlock)(
favicon_base::GoogleFaviconServerRequestStatus status) = favicon_base::GoogleFaviconServerRequestStatus status) =
^(const favicon_base::GoogleFaviconServerRequestStatus status) { ^(const favicon_base::GoogleFaviconServerRequestStatus status) {
...@@ -1088,7 +1055,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -1088,7 +1055,7 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
} }
}; // faviconLoadedFromServerBlock }; // faviconLoadedFromServerBlock
strongSelf.faviconDownloadCount++; strongSelf.sharedState.faviconDownloadCount++;
IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState) IOSChromeLargeIconServiceFactory::GetForBrowserState(self.browserState)
->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache( ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
node->url(), minFaviconSizeInPixel, desiredFaviconSizeInPixel, node->url(), minFaviconSizeInPixel, desiredFaviconSizeInPixel,
...@@ -1149,18 +1116,20 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -1149,18 +1116,20 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
NSDictionary* info = [aNotification userInfo]; NSDictionary* info = [aNotification userInfo];
CGFloat keyboardTop = CGFloat keyboardTop =
[[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y; [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].origin.y;
CGFloat tableBottom = CGFloat tableBottom = CGRectGetMaxY(
CGRectGetMaxY([self convertRect:self.tableView.frame toView:nil]); [self convertRect:self.sharedState.tableView.frame toView:nil]);
CGFloat shiftY = tableBottom - keyboardTop + kKeyboardSpacing; CGFloat shiftY =
tableBottom - keyboardTop + [BookmarkHomeSharedState keyboardSpacingPt];
if (shiftY >= 0) { if (shiftY >= 0) {
UIEdgeInsets previousContentInsets = self.tableView.contentInset; UIEdgeInsets previousContentInsets =
self.sharedState.tableView.contentInset;
// Shift the content inset to prevent the editing content from being hidden // Shift the content inset to prevent the editing content from being hidden
// by the keyboard. // by the keyboard.
UIEdgeInsets contentInsets = UIEdgeInsets contentInsets =
UIEdgeInsetsMake(previousContentInsets.top, 0.0, shiftY, 0.0); UIEdgeInsetsMake(previousContentInsets.top, 0.0, shiftY, 0.0);
self.tableView.contentInset = contentInsets; self.sharedState.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets; self.sharedState.tableView.scrollIndicatorInsets = contentInsets;
} }
} }
...@@ -1169,12 +1138,12 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -1169,12 +1138,12 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
if (![self.delegate isAtTopOfNavigation:self]) { if (![self.delegate isAtTopOfNavigation:self]) {
return; return;
} }
UIEdgeInsets previousContentInsets = self.tableView.contentInset; UIEdgeInsets previousContentInsets = self.sharedState.tableView.contentInset;
// Restore the content inset now that the keyboard has been hidden. // Restore the content inset now that the keyboard has been hidden.
UIEdgeInsets contentInsets = UIEdgeInsets contentInsets =
UIEdgeInsetsMake(previousContentInsets.top, 0, 0, 0); UIEdgeInsetsMake(previousContentInsets.top, 0, 0, 0);
self.tableView.contentInset = contentInsets; self.sharedState.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets; self.sharedState.tableView.scrollIndicatorInsets = contentInsets;
} }
#pragma mark - SyncedSessionsObserver #pragma mark - SyncedSessionsObserver
...@@ -1186,7 +1155,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -1186,7 +1155,8 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
- (void)onSyncStateChanged { - (void)onSyncStateChanged {
// Permanent nodes ("Bookmarks Bar", "Other Bookmarks") at the root node might // Permanent nodes ("Bookmarks Bar", "Other Bookmarks") at the root node might
// be added after syncing. So we need to refresh here. // be added after syncing. So we need to refresh here.
if (_currentRootNode == self.bookmarkModel->root_node()) { if (self.sharedState.tableViewDisplayedRootNode ==
self.sharedState.bookmarkModel->root_node()) {
[self refreshContents]; [self refreshContents];
return; return;
} }
...@@ -1196,43 +1166,44 @@ using IntegerPair = std::pair<NSInteger, NSInteger>; ...@@ -1196,43 +1166,44 @@ using IntegerPair = std::pair<NSInteger, NSInteger>;
#pragma mark - BookmarkTableCellTextFieldDelegate #pragma mark - BookmarkTableCellTextFieldDelegate
- (void)textDidChangeTo:(NSString*)newName { - (void)textDidChangeTo:(NSString*)newName {
DCHECK(_editingFolderNode); DCHECK(self.sharedState.editingFolderNode);
self.addingNewFolder = NO; self.sharedState.addingNewFolder = NO;
if (newName.length > 0) { if (newName.length > 0) {
self.bookmarkModel->SetTitle(_editingFolderNode, self.sharedState.bookmarkModel->SetTitle(self.sharedState.editingFolderNode,
base::SysNSStringToUTF16(newName)); base::SysNSStringToUTF16(newName));
} }
_editingFolderNode = NULL; self.sharedState.editingFolderNode = NULL;
self.editingFolderCell = nil; self.sharedState.editingFolderCell = nil;
[self refreshContents]; [self refreshContents];
} }
#pragma mark UIScrollViewDelegate #pragma mark UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView*)scrollView { - (void)scrollViewDidScroll:(UIScrollView*)scrollView {
if (scrollView == self.headerView.trackingScrollView) { if (scrollView == self.sharedState.headerView.trackingScrollView) {
[self.headerView trackingScrollViewDidScroll]; [self.sharedState.headerView trackingScrollViewDidScroll];
} }
} }
- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView { - (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView {
if (scrollView == self.headerView.trackingScrollView) { if (scrollView == self.sharedState.headerView.trackingScrollView) {
[self.headerView trackingScrollViewDidEndDecelerating]; [self.sharedState.headerView trackingScrollViewDidEndDecelerating];
} }
} }
- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView - (void)scrollViewDidEndDragging:(UIScrollView*)scrollView
willDecelerate:(BOOL)decelerate { willDecelerate:(BOOL)decelerate {
if (scrollView == self.headerView.trackingScrollView) { if (scrollView == self.sharedState.headerView.trackingScrollView) {
[self.headerView trackingScrollViewDidEndDraggingWillDecelerate:decelerate]; [self.sharedState.headerView
trackingScrollViewDidEndDraggingWillDecelerate:decelerate];
} }
} }
- (void)scrollViewWillEndDragging:(UIScrollView*)scrollView - (void)scrollViewWillEndDragging:(UIScrollView*)scrollView
withVelocity:(CGPoint)velocity withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint*)targetContentOffset { targetContentOffset:(inout CGPoint*)targetContentOffset {
if (scrollView == self.headerView.trackingScrollView) { if (scrollView == self.sharedState.headerView.trackingScrollView) {
[self.headerView [self.sharedState.headerView
trackingScrollViewWillEndDraggingWithVelocity:velocity trackingScrollViewWillEndDraggingWithVelocity:velocity
targetContentOffset:targetContentOffset]; targetContentOffset:targetContentOffset];
} }
......
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