OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // ====== New Architecture ===== | 5 // ====== New Architecture ===== |
6 // = This code is only used in the new iOS Chrome architecture. = | 6 // = This code is only used in the new iOS Chrome architecture. = |
7 // ============================================================================ | 7 // ============================================================================ |
8 | 8 |
9 #import "base/logging.h" | 9 #import "base/logging.h" |
10 #import "ios/clean/chrome/browser/browser_coordinator+internal.h" | 10 #import "ios/clean/chrome/browser/browser_coordinator+internal.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 | 56 |
57 @implementation BrowserCoordinator (Internal) | 57 @implementation BrowserCoordinator (Internal) |
58 // Concrete implementations must implement a |viewController| property. | 58 // Concrete implementations must implement a |viewController| property. |
59 @dynamic viewController; | 59 @dynamic viewController; |
60 | 60 |
61 - (NSSet*)children { | 61 - (NSSet*)children { |
62 return [self.childCoordinators copy]; | 62 return [self.childCoordinators copy]; |
63 } | 63 } |
64 | 64 |
65 - (void)addChildCoordinator:(BrowserCoordinator*)coordinator { | 65 - (void)addChildCoordinator:(BrowserCoordinator*)coordinator { |
| 66 CHECK([self respondsToSelector:@selector(viewController)]) |
| 67 << "BrowserCoordinator implementations must provide a viewController " |
| 68 "property."; |
66 [self.childCoordinators addObject:coordinator]; | 69 [self.childCoordinators addObject:coordinator]; |
| 70 coordinator.parentCoordinator = self; |
67 coordinator.browserState = self.browserState; | 71 coordinator.browserState = self.browserState; |
68 coordinator.parentCoordinator = self; | |
69 coordinator.rootViewController = self.viewController; | 72 coordinator.rootViewController = self.viewController; |
70 } | 73 } |
71 | 74 |
72 - (BrowserCoordinator*)overlayCoordinator { | 75 - (BrowserCoordinator*)overlayCoordinator { |
73 if (self.overlaying) | 76 if (self.overlaying) |
74 return self; | 77 return self; |
75 for (BrowserCoordinator* child in self.children) { | 78 for (BrowserCoordinator* child in self.children) { |
76 BrowserCoordinator* overlay = child.overlayCoordinator; | 79 BrowserCoordinator* overlay = child.overlayCoordinator; |
77 if (overlay) | 80 if (overlay) |
78 return overlay; | 81 return overlay; |
79 } | 82 } |
80 return nil; | 83 return nil; |
81 } | 84 } |
82 | 85 |
83 - (void)addOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { | 86 - (void)addOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { |
84 // If this object has no children, then add |overlayCoordinator| as a child | 87 // If this object has no children, then add |overlayCoordinator| as a child |
85 // and mark it as such. | 88 // and mark it as such. |
86 if ([self canAddOverlayCoordinator:overlayCoordinator]) { | 89 if ([self canAddOverlayCoordinator:overlayCoordinator]) { |
87 [self addChildCoordinator:overlayCoordinator]; | 90 [self addChildCoordinator:overlayCoordinator]; |
88 overlayCoordinator.overlaying = YES; | 91 overlayCoordinator.overlaying = YES; |
89 } else if (self.childCoordinators.count == 1) { | 92 } else if (self.childCoordinators.count == 1) { |
90 [[self.childCoordinators anyObject] | 93 [[self.childCoordinators anyObject] |
91 addOverlayCoordinator:overlayCoordinator]; | 94 addOverlayCoordinator:overlayCoordinator]; |
92 } else { | 95 } else if (self.childCoordinators.count > 1) { |
93 CHECK(NO) << "Coordinators with multiple children must explicitly " | 96 CHECK(NO) << "Coordinators with multiple children must explicitly " |
94 << "handle -addOverlayCoordinator: or return NO to " | 97 << "handle -addOverlayCoordinator: or return NO to " |
95 << "-canAddOverlayCoordinator:"; | 98 << "-canAddOverlayCoordinator:"; |
96 } | 99 } |
| 100 // If control reaches here, the terminal child of the coordinator hierarchy |
| 101 // has returned NO to -canAddOverlayCoordinator, so no overlay can be added. |
| 102 // This is by default a silent no-op. |
97 } | 103 } |
98 | 104 |
99 - (void)removeOverlayCoordinator { | 105 - (void)removeOverlayCoordinator { |
100 BrowserCoordinator* overlay = self.overlayCoordinator; | 106 BrowserCoordinator* overlay = self.overlayCoordinator; |
101 [overlay.parentCoordinator removeChildCoordinator:overlay]; | 107 [overlay.parentCoordinator removeChildCoordinator:overlay]; |
| 108 overlay.overlaying = NO; |
102 } | 109 } |
103 | 110 |
104 - (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { | 111 - (BOOL)canAddOverlayCoordinator:(BrowserCoordinator*)overlayCoordinator { |
| 112 // By default, a hierarchy with an overlay can't add a new one. |
| 113 // By default, coordinators with parents can't be added as overlays. |
105 // By default, coordinators with no other children can add an overlay. | 114 // By default, coordinators with no other children can add an overlay. |
106 return self.childCoordinators.count == 0; | 115 return self.overlayCoordinator == nil && |
| 116 overlayCoordinator.parentCoordinator == nil && |
| 117 self.childCoordinators.count == 0; |
107 } | 118 } |
108 | 119 |
109 - (void)removeChildCoordinator:(BrowserCoordinator*)coordinator { | 120 - (void)removeChildCoordinator:(BrowserCoordinator*)coordinator { |
| 121 if (![self.childCoordinators containsObject:coordinator]) |
| 122 return; |
110 [self.childCoordinators removeObject:coordinator]; | 123 [self.childCoordinators removeObject:coordinator]; |
| 124 coordinator.parentCoordinator = nil; |
111 } | 125 } |
112 | 126 |
113 @end | 127 @end |
OLD | NEW |