| Index: ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
|
| diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..da55fb7293bae425573755d151ef387d1cc364f5
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/bookmarks/bookmark_folder_view_controller.mm
|
| @@ -0,0 +1,555 @@
|
| +// Copyright 2014 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_folder_view_controller.h"
|
| +
|
| +#include <memory>
|
| +#include <vector>
|
| +
|
| +#import "base/ios/weak_nsobject.h"
|
| +#include "base/logging.h"
|
| +#include "base/mac/objc_property_releaser.h"
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#include "components/bookmarks/browser/bookmark_model.h"
|
| +#import "ios/chrome/browser/ui/bookmarks/bookmark_folder_editor_view_controller.h"
|
| +#import "ios/chrome/browser/ui/bookmarks/bookmark_folder_table_view_cell.h"
|
| +#import "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_utils_ios.h"
|
| +#import "ios/chrome/browser/ui/icons/chrome_icon.h"
|
| +#import "ios/chrome/browser/ui/material_components/utils.h"
|
| +#include "ios/chrome/grit/ios_strings.h"
|
| +#import "ios/third_party/material_components_ios/src/components/AppBar/src/MaterialAppBar.h"
|
| +#include "ui/base/l10n/l10n_util_mac.h"
|
| +
|
| +using bookmarks::BookmarkNode;
|
| +
|
| +namespace {
|
| +
|
| +// The height of every folder cell.
|
| +const CGFloat kFolderCellHeight = 48.0;
|
| +
|
| +// Height of section headers/footers.
|
| +const CGFloat kSectionHeaderHeight = 8.0;
|
| +const CGFloat kSectionFooterHeight = 8.0;
|
| +
|
| +// Enum for the available sections.
|
| +// First section displays a cell to create a new folder.
|
| +// The second section displays as many folders as are available.
|
| +typedef enum {
|
| + BookmarkFolderSectionDefault = 0,
|
| + BookmarkFolderSectionFolders,
|
| +} BookmarkFolderSection;
|
| +const NSInteger BookmarkFolderSectionCount = 2;
|
| +
|
| +} // namespace
|
| +
|
| +@interface BookmarkFolderViewController ()<
|
| + BookmarkFolderEditorViewControllerDelegate,
|
| + BookmarkModelBridgeObserver,
|
| + UITableViewDataSource,
|
| + UITableViewDelegate> {
|
| + std::set<const BookmarkNode*> _editedNodes;
|
| + std::vector<const BookmarkNode*> _folders;
|
| + std::unique_ptr<bookmarks::BookmarkModelBridge> _modelBridge;
|
| + base::scoped_nsobject<MDCAppBar> _appBar;
|
| + base::mac::ObjCPropertyReleaser
|
| + _propertyReleaser_BookmarkFolderViewController;
|
| +}
|
| +
|
| +// Should the controller setup Cancel and Done buttons instead of a back button.
|
| +@property(nonatomic, assign) BOOL allowsCancel;
|
| +
|
| +// Should the controller setup a new-folder button.
|
| +@property(nonatomic, assign) BOOL allowsNewFolders;
|
| +
|
| +// Reference to the main bookmark model.
|
| +@property(nonatomic, assign) bookmarks::BookmarkModel* bookmarkModel;
|
| +
|
| +// The currently selected folder.
|
| +@property(nonatomic, readonly) const BookmarkNode* selectedFolder;
|
| +
|
| +// The view controller to present when creating a new folder.
|
| +@property(nonatomic, retain)
|
| + BookmarkFolderEditorViewController* folderAddController;
|
| +
|
| +// A linear list of folders.
|
| +@property(nonatomic, assign, readonly)
|
| + const std::vector<const BookmarkNode*>& folders;
|
| +
|
| +// The table view that displays the options and folders.
|
| +@property(nonatomic, retain) UITableView* tableView;
|
| +
|
| +// Returns the cell for the default section and the given |row|.
|
| +- (BookmarkFolderTableViewCell*)defaultSectionCellForRow:(NSInteger)row;
|
| +
|
| +// Returns a folder cell for the folder at |row| in |self.folders|.
|
| +- (BookmarkFolderTableViewCell*)folderSectionCellForRow:(NSInteger)row;
|
| +
|
| +// Reloads the folder list.
|
| +- (void)reloadFolders;
|
| +
|
| +// Pushes on the navigation controller a view controller to create a new folder.
|
| +- (void)pushFolderAddViewController;
|
| +
|
| +// Called when the user taps on a folder row. The cell is checked, the UI is
|
| +// locked so that the user can't interact with it, then the delegate is
|
| +// notified. Usual implementations of this delegate callback are to pop or
|
| +// dismiss this controller on selection. The delay is here to let the user get a
|
| +// visual feedback of the selection before this view disappears.
|
| +- (void)delayedNotifyDelegateOfSelection;
|
| +
|
| +@end
|
| +
|
| +@implementation BookmarkFolderViewController
|
| +
|
| +@synthesize allowsCancel = _allowsCancel;
|
| +@synthesize allowsNewFolders = _allowsNewFolders;
|
| +@synthesize bookmarkModel = _bookmarkModel;
|
| +@synthesize editedNodes = _editedNodes;
|
| +@synthesize folderAddController = _folderAddController;
|
| +@synthesize delegate = _delegate;
|
| +@synthesize folders = _folders;
|
| +@synthesize tableView = _tableView;
|
| +@synthesize selectedFolder = _selectedFolder;
|
| +
|
| +- (instancetype)initWithBookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
|
| + allowsNewFolders:(BOOL)allowsNewFolders
|
| + editedNodes:
|
| + (const std::set<const BookmarkNode*>&)nodes
|
| + allowsCancel:(BOOL)allowsCancel
|
| + selectedFolder:(const BookmarkNode*)selectedFolder {
|
| + DCHECK(bookmarkModel);
|
| + DCHECK(bookmarkModel->loaded());
|
| + DCHECK(selectedFolder == NULL || selectedFolder->is_folder());
|
| + self = [super initWithNibName:nil bundle:nil];
|
| + if (self) {
|
| + _propertyReleaser_BookmarkFolderViewController.Init(
|
| + self, [BookmarkFolderViewController class]);
|
| + _allowsCancel = allowsCancel;
|
| + _allowsNewFolders = allowsNewFolders;
|
| + _bookmarkModel = bookmarkModel;
|
| + _editedNodes = nodes;
|
| + _selectedFolder = selectedFolder;
|
| +
|
| + // Set up the bookmark model oberver.
|
| + _modelBridge.reset(
|
| + new bookmarks::BookmarkModelBridge(self, _bookmarkModel));
|
| +
|
| + _appBar.reset([[MDCAppBar alloc] init]);
|
| + [self addChildViewController:[_appBar headerViewController]];
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (void)changeSelectedFolder:(const BookmarkNode*)selectedFolder {
|
| + DCHECK(selectedFolder);
|
| + DCHECK(selectedFolder->is_folder());
|
| + _selectedFolder = selectedFolder;
|
| + [self.tableView reloadData];
|
| +}
|
| +
|
| +- (void)dealloc {
|
| + _tableView.dataSource = nil;
|
| + _tableView.delegate = nil;
|
| + _folderAddController.delegate = nil;
|
| + [super dealloc];
|
| +}
|
| +
|
| +- (UIStatusBarStyle)preferredStatusBarStyle {
|
| + return UIStatusBarStyleDefault;
|
| +}
|
| +
|
| +#pragma mark - View lifecycle
|
| +
|
| +- (void)viewDidLoad {
|
| + [super viewDidLoad];
|
| + if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
|
| + [self setEdgesForExtendedLayout:UIRectEdgeNone];
|
| + }
|
| + self.view.backgroundColor = [UIColor whiteColor];
|
| + self.view.accessibilityIdentifier = @"Folder Picker";
|
| +
|
| + self.title = l10n_util::GetNSString(IDS_IOS_BOOKMARK_CHOOSE_GROUP_BUTTON);
|
| +
|
| + base::scoped_nsobject<UIBarButtonItem> doneItem([[UIBarButtonItem alloc]
|
| + initWithTitle:l10n_util::GetNSString(
|
| + IDS_IOS_BOOKMARK_EDIT_MODE_EXIT_MOBILE)
|
| + style:UIBarButtonItemStylePlain
|
| + target:self
|
| + action:@selector(done:)]);
|
| + doneItem.get().accessibilityIdentifier = @"Done";
|
| + self.navigationItem.rightBarButtonItem = doneItem;
|
| +
|
| + if (self.allowsCancel) {
|
| + UIBarButtonItem* cancelItem =
|
| + [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon closeIcon]
|
| + target:self
|
| + action:@selector(cancel:)];
|
| + cancelItem.accessibilityLabel =
|
| + l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_CANCEL_BUTTON_LABEL);
|
| + cancelItem.accessibilityIdentifier = @"Cancel";
|
| + self.navigationItem.leftBarButtonItem = cancelItem;
|
| + } else {
|
| + UIBarButtonItem* backItem =
|
| + [ChromeIcon templateBarButtonItemWithImage:[ChromeIcon backIcon]
|
| + target:self
|
| + action:@selector(back:)];
|
| + backItem.accessibilityLabel =
|
| + l10n_util::GetNSString(IDS_IOS_BOOKMARK_NEW_BACK_LABEL);
|
| + backItem.accessibilityIdentifier = @"Back";
|
| + self.navigationItem.leftBarButtonItem = backItem;
|
| + }
|
| +
|
| + // The table view.
|
| + base::scoped_nsobject<UITableView> tableView([[UITableView alloc]
|
| + initWithFrame:self.view.bounds
|
| + style:UITableViewStylePlain]);
|
| + tableView.get().dataSource = self;
|
| + tableView.get().delegate = self;
|
| + tableView.get().autoresizingMask =
|
| + UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
| + tableView.get().separatorStyle = UITableViewCellSeparatorStyleNone;
|
| + [self.view addSubview:tableView];
|
| + [self.view sendSubviewToBack:tableView];
|
| + self.tableView = tableView;
|
| +
|
| + // Add the app bar to the view hierarchy. This must be done last, so that the
|
| + // app bar's views are the frontmost.
|
| + ConfigureAppBarWithCardStyle(_appBar);
|
| + [_appBar headerViewController].headerView.trackingScrollView = self.tableView;
|
| + [_appBar addSubviewsToParent];
|
| +}
|
| +
|
| +- (void)viewWillAppear:(BOOL)animated {
|
| + [super viewWillAppear:animated];
|
| + [self reloadFolders];
|
| +}
|
| +
|
| +- (UIViewController*)childViewControllerForStatusBarHidden {
|
| + return [_appBar headerViewController];
|
| +}
|
| +
|
| +- (UIViewController*)childViewControllerForStatusBarStyle {
|
| + return [_appBar headerViewController];
|
| +}
|
| +
|
| +#pragma mark - Accessibility
|
| +
|
| +- (BOOL)accessibilityPerformEscape {
|
| + [self.delegate folderPickerDidCancel:self];
|
| + return YES;
|
| +}
|
| +
|
| +#pragma mark - UIScrollViewDelegate
|
| +
|
| +- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
|
| + MDCFlexibleHeaderView* headerView = [_appBar headerViewController].headerView;
|
| + if (scrollView == headerView.trackingScrollView) {
|
| + [headerView trackingScrollViewDidScroll];
|
| + }
|
| +}
|
| +
|
| +- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView {
|
| + MDCFlexibleHeaderView* headerView = [_appBar headerViewController].headerView;
|
| + if (scrollView == headerView.trackingScrollView) {
|
| + [headerView trackingScrollViewDidEndDecelerating];
|
| + }
|
| +}
|
| +
|
| +- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView
|
| + willDecelerate:(BOOL)decelerate {
|
| + MDCFlexibleHeaderView* headerView = [_appBar headerViewController].headerView;
|
| + if (scrollView == headerView.trackingScrollView) {
|
| + [headerView trackingScrollViewDidEndDraggingWillDecelerate:decelerate];
|
| + }
|
| +}
|
| +
|
| +- (void)scrollViewWillEndDragging:(UIScrollView*)scrollView
|
| + withVelocity:(CGPoint)velocity
|
| + targetContentOffset:(inout CGPoint*)targetContentOffset {
|
| + MDCFlexibleHeaderView* headerView = [_appBar headerViewController].headerView;
|
| + if (scrollView == headerView.trackingScrollView) {
|
| + [headerView
|
| + trackingScrollViewWillEndDraggingWithVelocity:velocity
|
| + targetContentOffset:targetContentOffset];
|
| + }
|
| +}
|
| +
|
| +#pragma mark - UITableViewDataSource
|
| +
|
| +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
|
| + return BookmarkFolderSectionCount;
|
| +}
|
| +
|
| +- (NSInteger)tableView:(UITableView*)tableView
|
| + numberOfRowsInSection:(NSInteger)section {
|
| + switch (static_cast<BookmarkFolderSection>(section)) {
|
| + case BookmarkFolderSectionDefault:
|
| + return [self shouldShowDefaultSection] ? 1 : 0;
|
| +
|
| + case BookmarkFolderSectionFolders:
|
| + return self.folders.size();
|
| + }
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +- (UITableViewCell*)tableView:(UITableView*)tableView
|
| + cellForRowAtIndexPath:(NSIndexPath*)indexPath {
|
| + BookmarkFolderTableViewCell* cell = nil;
|
| + switch (static_cast<BookmarkFolderSection>(indexPath.section)) {
|
| + case BookmarkFolderSectionDefault:
|
| + cell = [self defaultSectionCellForRow:indexPath.row];
|
| + break;
|
| +
|
| + case BookmarkFolderSectionFolders:
|
| + cell = [self folderSectionCellForRow:indexPath.row];
|
| + break;
|
| + }
|
| + return cell;
|
| +}
|
| +
|
| +#pragma mark - UITableViewDelegate
|
| +
|
| +- (CGFloat)tableView:(UITableView*)tableView
|
| + heightForRowAtIndexPath:(NSIndexPath*)indexPath {
|
| + return kFolderCellHeight;
|
| +}
|
| +
|
| +- (CGFloat)tableView:(UITableView*)tableView
|
| + heightForHeaderInSection:(NSInteger)section {
|
| + switch (static_cast<BookmarkFolderSection>(section)) {
|
| + case BookmarkFolderSectionDefault:
|
| + return [self shouldShowDefaultSection] ? kSectionHeaderHeight : 0;
|
| +
|
| + case BookmarkFolderSectionFolders:
|
| + return kSectionHeaderHeight;
|
| + }
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +- (UIView*)tableView:(UITableView*)tableView
|
| + viewForHeaderInSection:(NSInteger)section {
|
| + CGRect headerViewFrame =
|
| + CGRectMake(0, 0, CGRectGetWidth(tableView.frame),
|
| + [self tableView:tableView heightForHeaderInSection:section]);
|
| + UIView* headerView =
|
| + [[[UIView alloc] initWithFrame:headerViewFrame] autorelease];
|
| + if (section == BookmarkFolderSectionFolders &&
|
| + [self shouldShowDefaultSection]) {
|
| + CGRect separatorFrame =
|
| + CGRectMake(0, 0, CGRectGetWidth(headerView.bounds),
|
| + 1.0 / [[UIScreen mainScreen] scale]); // 1-pixel divider.
|
| + base::scoped_nsobject<UIView> separator(
|
| + [[UIView alloc] initWithFrame:separatorFrame]);
|
| + separator.get().autoresizingMask = UIViewAutoresizingFlexibleBottomMargin |
|
| + UIViewAutoresizingFlexibleWidth;
|
| + separator.get().backgroundColor = bookmark_utils_ios::separatorColor();
|
| + [headerView addSubview:separator];
|
| + }
|
| + return headerView;
|
| +}
|
| +
|
| +- (CGFloat)tableView:(UITableView*)tableView
|
| + heightForFooterInSection:(NSInteger)section {
|
| + switch (static_cast<BookmarkFolderSection>(section)) {
|
| + case BookmarkFolderSectionDefault:
|
| + return [self shouldShowDefaultSection] ? kSectionFooterHeight : 0;
|
| +
|
| + case BookmarkFolderSectionFolders:
|
| + return kSectionFooterHeight;
|
| + }
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +- (UIView*)tableView:(UITableView*)tableView
|
| + viewForFooterInSection:(NSInteger)section {
|
| + return [[[UIView alloc] init] autorelease];
|
| +}
|
| +
|
| +- (void)tableView:(UITableView*)tableView
|
| + didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
|
| + [tableView deselectRowAtIndexPath:indexPath animated:YES];
|
| + switch (static_cast<BookmarkFolderSection>(indexPath.section)) {
|
| + case BookmarkFolderSectionDefault:
|
| + [self pushFolderAddViewController];
|
| + break;
|
| +
|
| + case BookmarkFolderSectionFolders: {
|
| + const BookmarkNode* folder = self.folders[indexPath.row];
|
| + [self changeSelectedFolder:folder];
|
| + [self delayedNotifyDelegateOfSelection];
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +#pragma mark - BookmarkFolderEditorViewControllerDelegate
|
| +
|
| +- (void)bookmarkFolderEditor:(BookmarkFolderEditorViewController*)folderEditor
|
| + didFinishEditingFolder:(const BookmarkNode*)folder {
|
| + DCHECK(folder);
|
| + [self reloadFolders];
|
| + [self changeSelectedFolder:folder];
|
| + [self delayedNotifyDelegateOfSelection];
|
| +}
|
| +
|
| +- (void)bookmarkFolderEditorDidDeleteEditedFolder:
|
| + (BookmarkFolderEditorViewController*)folderEditor {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +- (void)bookmarkFolderEditorDidCancel:
|
| + (BookmarkFolderEditorViewController*)folderEditor {
|
| + [self.navigationController popViewControllerAnimated:YES];
|
| + self.folderAddController.delegate = nil;
|
| + self.folderAddController = nil;
|
| +}
|
| +
|
| +#pragma mark - BookmarkModelBridgeObserver
|
| +
|
| +- (void)bookmarkModelLoaded {
|
| + // The bookmark model is assumed to be loaded when this controller is created.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +- (void)bookmarkNodeChanged:(const BookmarkNode*)bookmarkNode {
|
| + if (!bookmarkNode->is_folder())
|
| + return;
|
| + [self reloadFolders];
|
| +}
|
| +
|
| +- (void)bookmarkNodeChildrenChanged:(const BookmarkNode*)bookmarkNode {
|
| + [self reloadFolders];
|
| +}
|
| +
|
| +- (void)bookmarkNode:(const BookmarkNode*)bookmarkNode
|
| + movedFromParent:(const BookmarkNode*)oldParent
|
| + toParent:(const BookmarkNode*)newParent {
|
| + if (bookmarkNode->is_folder()) {
|
| + [self reloadFolders];
|
| + }
|
| +}
|
| +
|
| +- (void)bookmarkNodeDeleted:(const BookmarkNode*)bookmarkNode
|
| + fromFolder:(const BookmarkNode*)folder {
|
| + if (!bookmarkNode->is_folder())
|
| + return;
|
| +
|
| + if (bookmarkNode == self.selectedFolder) {
|
| + // The selected folder has been deleted. Fallback on the Mobile Bookmarks
|
| + // node.
|
| + [self changeSelectedFolder:self.bookmarkModel->mobile_node()];
|
| + }
|
| + [self reloadFolders];
|
| +}
|
| +
|
| +- (void)bookmarkModelRemovedAllNodes {
|
| + // The selected folder is no longer valid. Fallback on the Mobile Bookmarks
|
| + // node.
|
| + [self changeSelectedFolder:self.bookmarkModel->mobile_node()];
|
| + [self reloadFolders];
|
| +}
|
| +
|
| +#pragma mark - Actions
|
| +
|
| +- (void)done:(id)sender {
|
| + [self.delegate folderPicker:self didFinishWithFolder:self.selectedFolder];
|
| +}
|
| +
|
| +- (void)cancel:(id)sender {
|
| + [self.delegate folderPickerDidCancel:self];
|
| +}
|
| +
|
| +- (void)back:(id)sender {
|
| + [self.delegate folderPickerDidCancel:self];
|
| +}
|
| +
|
| +#pragma mark - Private
|
| +
|
| +- (BOOL)shouldShowDefaultSection {
|
| + return self.allowsNewFolders;
|
| +}
|
| +
|
| +- (BookmarkFolderTableViewCell*)defaultSectionCellForRow:(NSInteger)row {
|
| + DCHECK([self shouldShowDefaultSection]);
|
| + DCHECK_EQ(0, row);
|
| + BookmarkFolderTableViewCell* cell = [self.tableView
|
| + dequeueReusableCellWithIdentifier:[BookmarkFolderTableViewCell
|
| + folderCreationCellReuseIdentifier]];
|
| + if (!cell) {
|
| + cell = [BookmarkFolderTableViewCell folderCreationCell];
|
| + }
|
| + return cell;
|
| +}
|
| +
|
| +- (BookmarkFolderTableViewCell*)folderSectionCellForRow:(NSInteger)row {
|
| + DCHECK(row <
|
| + [self.tableView numberOfRowsInSection:BookmarkFolderSectionFolders]);
|
| + BookmarkFolderTableViewCell* cell = [self.tableView
|
| + dequeueReusableCellWithIdentifier:[BookmarkFolderTableViewCell
|
| + folderCellReuseIdentifier]];
|
| + if (!cell) {
|
| + cell = [BookmarkFolderTableViewCell folderCell];
|
| + }
|
| + const BookmarkNode* folder = self.folders[row];
|
| + NSString* title = bookmark_utils_ios::TitleForBookmarkNode(folder);
|
| + cell.textLabel.text = title;
|
| + cell.accessibilityIdentifier = title;
|
| + cell.accessibilityLabel = title;
|
| + cell.checked = (self.selectedFolder == folder);
|
| +
|
| + // Indentation level.
|
| + NSInteger level = 0;
|
| + const BookmarkNode* node = folder;
|
| + while (node && !(self.bookmarkModel->is_root_node(node))) {
|
| + ++level;
|
| + node = node->parent();
|
| + }
|
| + // The root node is not shown as a folder, so top level folders have a
|
| + // level strictly positive.
|
| + DCHECK(level > 0);
|
| + cell.indentationLevel = level - 1;
|
| +
|
| + return cell;
|
| +}
|
| +
|
| +- (void)reloadFolders {
|
| + _folders = bookmark_utils_ios::VisibleNonDescendantNodes(self.editedNodes,
|
| + self.bookmarkModel);
|
| + [self.tableView reloadData];
|
| +}
|
| +
|
| +- (void)pushFolderAddViewController {
|
| + DCHECK(self.allowsNewFolders);
|
| + BookmarkFolderEditorViewController* folderCreator =
|
| + [BookmarkFolderEditorViewController
|
| + folderCreatorWithBookmarkModel:self.bookmarkModel
|
| + parentFolder:self.selectedFolder];
|
| + folderCreator.delegate = self;
|
| + [self.navigationController pushViewController:folderCreator animated:YES];
|
| + self.folderAddController = folderCreator;
|
| +}
|
| +
|
| +- (void)delayedNotifyDelegateOfSelection {
|
| + self.view.userInteractionEnabled = NO;
|
| + base::WeakNSObject<BookmarkFolderViewController> weakSelf(self);
|
| + dispatch_after(
|
| + dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)),
|
| + dispatch_get_main_queue(), ^{
|
| + base::scoped_nsobject<BookmarkFolderViewController> strongSelf(
|
| + [weakSelf retain]);
|
| + // Early return if the controller has been deallocated.
|
| + if (!strongSelf)
|
| + return;
|
| + strongSelf.get().view.userInteractionEnabled = YES;
|
| + [strongSelf done:nil];
|
| + });
|
| +}
|
| +
|
| +@end
|
|
|