[iOS] Create BookmarkEditCoordinator

This new Coordinator will enable an edit-only scenario, requiring only
a minimal set of dependencies. Without this new Coordinator, the "Edit
Bookmark" flow ended up being dependent on the SharingCoordinator (via
the BookmarkHomeViewController). Since bookmarks can be edited via the
sharing activities ("Edit Bookmark"), we ended up with a cyclic
dependency. The creation of this new Coordinator enables such flow.

e.g. Open a page -> Add it to Reading List -> Add it to Bookmarks ->
Open Reading List -> Long-press on the entry -> Select Share -> Select
"Edit Bookmark".

(cherry picked from commit b9fb744f121ed3f076d25ffb491fbda05679c122)

Bug: 1133294
Change-Id: Ib646a7e79e6c46b5cd4b373417caa447a4365ba1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2441956
Commit-Queue: Sebastien Lalancette <[email protected]>
Reviewed-by: Gauthier Ambard <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#813750}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2458626
Reviewed-by: Sebastien Lalancette <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#98}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index 7982a25..eae33d4 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -90,6 +90,23 @@
   frameworks = [ "UIKit.framework" ]
 }
 
+source_set("edit") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "bookmark_edit_coordinator.h",
+    "bookmark_edit_coordinator.mm",
+  ]
+  deps = [
+    ":bookmarks_ui",
+    ":core",
+    "//components/bookmarks/browser",
+    "//ios/chrome/browser/ui/coordinators:chrome_coordinators",
+    "//ios/chrome/browser/ui/table_view",
+    "//url",
+  ]
+  frameworks = [ "UIKit.framework" ]
+}
+
 source_set("core") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.h b/ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.h
new file mode 100644
index 0000000..569723c
--- /dev/null
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.h
@@ -0,0 +1,46 @@
+// Copyright 2020 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_EDIT_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_EDIT_COORDINATOR_H_
+
+#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
+#include "url/gurl.h"
+
+@class BookmarkEditCoordinator;
+
+namespace bookmarks {
+class BookmarkNode;
+}
+
+// Delegate protocol for getting updates from the coordinator.
+@protocol BookmarkEditCoordinatorDelegate
+
+// Called when the bookmark edit view has been dismissed. The |coordinator|
+// passes itself as parameter.
+- (void)bookmarkEditDismissed:(BookmarkEditCoordinator*)coordinator;
+
+@end
+
+// BookmarkEditCoordinator presents the public interface for a slimmed-down
+// bookmark edit functionality.
+@interface BookmarkEditCoordinator : ChromeCoordinator
+
+// Initializes an instance with a base |viewController|, the current |browser|,
+// and the |bookmark| to edit.
+- (instancetype)initWithBaseViewController:(UIViewController*)viewController
+                                   browser:(Browser*)browser
+                                  bookmark:
+                                      (const bookmarks::BookmarkNode*)bookmark
+    NS_DESIGNATED_INITIALIZER;
+
+// Unavailable, use -initWithBaseViewController:browser:title:URL:.
+- (instancetype)initWithBaseViewController:(UIViewController*)viewController
+                                   browser:(Browser*)browser NS_UNAVAILABLE;
+
+@property(nonatomic, weak) id<BookmarkEditCoordinatorDelegate> delegate;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_EDIT_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.mm
new file mode 100644
index 0000000..2ee9037
--- /dev/null
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_coordinator.mm
@@ -0,0 +1,81 @@
+// Copyright 2020 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_edit_coordinator.h"
+
+#import "components/bookmarks/browser/bookmark_node.h"
+#import "ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.h"
+#import "ios/chrome/browser/ui/table_view/table_view_navigation_controller.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+using bookmarks::BookmarkNode;
+
+@interface BookmarkEditCoordinator () <BookmarkEditViewControllerDelegate>
+
+@property(nonatomic, assign) const BookmarkNode* bookmark;
+
+@property(nonatomic, strong) BookmarkEditViewController* editViewController;
+
+@property(nonatomic, strong) TableViewNavigationController* navController;
+
+@end
+
+@implementation BookmarkEditCoordinator
+
+- (instancetype)initWithBaseViewController:(UIViewController*)viewController
+                                   browser:(Browser*)browser
+                                  bookmark:(const BookmarkNode*)bookmark {
+  if (self = [super initWithBaseViewController:viewController
+                                       browser:browser]) {
+    // This Coordinator only supports URL bookmarks for now.
+    DCHECK(bookmark);
+    DCHECK(bookmark->type() == BookmarkNode::URL);
+    _bookmark = bookmark;
+  }
+  return self;
+}
+
+#pragma mark - ChromeCoordinator
+
+- (void)start {
+  self.editViewController =
+      [[BookmarkEditViewController alloc] initWithBookmark:self.bookmark
+                                                   browser:self.browser];
+  self.editViewController.delegate = self;
+
+  self.navController = [[TableViewNavigationController alloc]
+      initWithTable:self.editViewController];
+  self.navController.modalPresentationStyle = UIModalPresentationFormSheet;
+
+  [self.baseViewController presentViewController:self.navController
+                                        animated:YES
+                                      completion:nil];
+}
+
+- (void)stop {
+  [self.baseViewController dismissViewControllerAnimated:YES completion:nil];
+  self.editViewController = nil;
+  self.navController = nil;
+}
+
+#pragma mark - BookmarkEditViewControllerDelegate
+
+- (BOOL)bookmarkEditor:(BookmarkEditViewController*)controller
+    shoudDeleteAllOccurencesOfBookmark:(const BookmarkNode*)bookmark {
+  return YES;
+}
+
+- (void)bookmarkEditorWantsDismissal:(BookmarkEditViewController*)controller {
+  [self.delegate bookmarkEditDismissed:self];
+}
+
+- (void)bookmarkEditorWillCommitTitleOrUrlChange:
+    (BookmarkEditViewController*)controller {
+  // No-op.
+}
+
+@end