OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #import "ios/web/web_state/ui/crw_web_controller_container_view.h" | 5 #import "ios/web/web_state/ui/crw_web_controller_container_view.h" |
6 | 6 |
| 7 #import "base/ios/weak_nsobject.h" |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #import "base/mac/scoped_nsobject.h" |
8 #import "ios/web/public/web_state/ui/crw_content_view.h" | 10 #import "ios/web/public/web_state/ui/crw_content_view.h" |
9 #import "ios/web/public/web_state/ui/crw_native_content.h" | 11 #import "ios/web/public/web_state/ui/crw_native_content.h" |
10 #import "ios/web/public/web_state/ui/crw_web_view_content_view.h" | 12 #import "ios/web/public/web_state/ui/crw_web_view_content_view.h" |
11 #import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" | 13 #import "ios/web/web_state/ui/crw_web_view_proxy_impl.h" |
12 | 14 |
13 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
14 #error "This file requires ARC support." | |
15 #endif | |
16 | |
17 #pragma mark - CRWToolbarContainerView | 15 #pragma mark - CRWToolbarContainerView |
18 | 16 |
19 // Class that manages the display of toolbars. | 17 // Class that manages the display of toolbars. |
20 @interface CRWToolbarContainerView : UIView { | 18 @interface CRWToolbarContainerView : UIView { |
21 // Backing object for |self.toolbars|. | 19 // Backing object for |self.toolbars|. |
22 NSMutableArray* _toolbars; | 20 base::scoped_nsobject<NSMutableArray> _toolbars; |
23 } | 21 } |
24 | 22 |
25 // The toolbars currently managed by this view. | 23 // The toolbars currently managed by this view. |
26 @property(nonatomic, strong, readonly) NSMutableArray* toolbars; | 24 @property(nonatomic, retain, readonly) NSMutableArray* toolbars; |
27 | 25 |
28 // Adds |toolbar| as a subview and bottom aligns to any previously added | 26 // Adds |toolbar| as a subview and bottom aligns to any previously added |
29 // toolbars. | 27 // toolbars. |
30 - (void)addToolbar:(UIView*)toolbar; | 28 - (void)addToolbar:(UIView*)toolbar; |
31 | 29 |
32 // Removes |toolbar| from the container view. | 30 // Removes |toolbar| from the container view. |
33 - (void)removeToolbar:(UIView*)toolbar; | 31 - (void)removeToolbar:(UIView*)toolbar; |
34 | 32 |
35 @end | 33 @end |
36 | 34 |
37 @implementation CRWToolbarContainerView | 35 @implementation CRWToolbarContainerView |
38 | 36 |
39 #pragma mark Accessors | 37 #pragma mark Accessors |
40 | 38 |
41 - (NSMutableArray*)toolbars { | 39 - (NSMutableArray*)toolbars { |
42 if (!_toolbars) | 40 if (!_toolbars) |
43 _toolbars = [[NSMutableArray alloc] init]; | 41 _toolbars.reset([[NSMutableArray alloc] init]); |
44 return _toolbars; | 42 return _toolbars.get(); |
45 } | 43 } |
46 | 44 |
47 #pragma mark Layout | 45 #pragma mark Layout |
48 | 46 |
49 - (void)layoutSubviews { | 47 - (void)layoutSubviews { |
50 [super layoutSubviews]; | 48 [super layoutSubviews]; |
51 | 49 |
52 // Bottom-align the toolbars. | 50 // Bottom-align the toolbars. |
53 CGPoint toolbarOrigin = | 51 CGPoint toolbarOrigin = |
54 CGPointMake(self.bounds.origin.x, CGRectGetMaxY(self.bounds)); | 52 CGPointMake(self.bounds.origin.x, CGRectGetMaxY(self.bounds)); |
(...skipping 29 matching lines...) Expand all Loading... |
84 DCHECK([self.toolbars containsObject:toolbar]); | 82 DCHECK([self.toolbars containsObject:toolbar]); |
85 [self.toolbars removeObject:toolbar]; | 83 [self.toolbars removeObject:toolbar]; |
86 [toolbar removeFromSuperview]; | 84 [toolbar removeFromSuperview]; |
87 } | 85 } |
88 | 86 |
89 @end | 87 @end |
90 | 88 |
91 #pragma mark - CRWWebControllerContainerView | 89 #pragma mark - CRWWebControllerContainerView |
92 | 90 |
93 @interface CRWWebControllerContainerView () { | 91 @interface CRWWebControllerContainerView () { |
| 92 // The delegate passed on initialization. |
| 93 base::WeakNSProtocol<id<CRWWebControllerContainerViewDelegate>> _delegate; |
| 94 // Backing objects for corresponding properties. |
| 95 base::scoped_nsobject<CRWWebViewContentView> _webViewContentView; |
| 96 base::scoped_nsprotocol<id<CRWNativeContent>> _nativeController; |
| 97 base::scoped_nsobject<CRWContentView> _transientContentView; |
| 98 base::scoped_nsobject<CRWToolbarContainerView> _toolbarContainerView; |
94 } | 99 } |
95 | 100 |
96 // Redefine properties as readwrite. | 101 // Redefine properties as readwrite. |
97 @property(nonatomic, strong, readwrite) | 102 @property(nonatomic, retain, readwrite) |
98 CRWWebViewContentView* webViewContentView; | 103 CRWWebViewContentView* webViewContentView; |
99 @property(nonatomic, strong, readwrite) id<CRWNativeContent> nativeController; | 104 @property(nonatomic, retain, readwrite) id<CRWNativeContent> nativeController; |
100 @property(nonatomic, strong, readwrite) CRWContentView* transientContentView; | 105 @property(nonatomic, retain, readwrite) CRWContentView* transientContentView; |
101 | 106 |
102 // Container view that displays any added toolbars. It is always the top-most | 107 // Container view that displays any added toolbars. It is always the top-most |
103 // subview, and is bottom aligned with the CRWWebControllerContainerView. | 108 // subview, and is bottom aligned with the CRWWebControllerContainerView. |
104 @property(nonatomic, strong, readonly) | 109 @property(nonatomic, retain, readonly) |
105 CRWToolbarContainerView* toolbarContainerView; | 110 CRWToolbarContainerView* toolbarContainerView; |
106 | 111 |
107 // Convenience getter for the proxy object. | 112 // Convenience getter for the proxy object. |
108 @property(nonatomic, weak, readonly) CRWWebViewProxyImpl* contentViewProxy; | 113 @property(nonatomic, readonly) CRWWebViewProxyImpl* contentViewProxy; |
109 | 114 |
110 // Returns |self.bounds| after being inset at the top by the header height | 115 // Returns |self.bounds| after being inset at the top by the header height |
111 // returned by the delegate. This is only used to lay out native controllers, | 116 // returned by the delegate. This is only used to lay out native controllers, |
112 // as the header height is already accounted for in the scroll view content | 117 // as the header height is already accounted for in the scroll view content |
113 // insets for other CRWContentViews. | 118 // insets for other CRWContentViews. |
114 @property(nonatomic, readonly) CGRect visibleFrame; | 119 @property(nonatomic, readonly) CGRect visibleFrame; |
115 | 120 |
116 @end | 121 @end |
117 | 122 |
118 @implementation CRWWebControllerContainerView | 123 @implementation CRWWebControllerContainerView |
119 | 124 |
120 @synthesize webViewContentView = _webViewContentView; | |
121 @synthesize nativeController = _nativeController; | |
122 @synthesize transientContentView = _transientContentView; | |
123 @synthesize toolbarContainerView = _toolbarContainerView; | |
124 @synthesize delegate = _delegate; | |
125 | |
126 - (instancetype)initWithDelegate: | 125 - (instancetype)initWithDelegate: |
127 (id<CRWWebControllerContainerViewDelegate>)delegate { | 126 (id<CRWWebControllerContainerViewDelegate>)delegate { |
128 self = [super initWithFrame:CGRectZero]; | 127 self = [super initWithFrame:CGRectZero]; |
129 if (self) { | 128 if (self) { |
130 DCHECK(delegate); | 129 DCHECK(delegate); |
131 _delegate = delegate; | 130 _delegate.reset(delegate); |
132 self.backgroundColor = [UIColor whiteColor]; | 131 self.backgroundColor = [UIColor whiteColor]; |
133 self.autoresizingMask = | 132 self.autoresizingMask = |
134 UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; | 133 UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; |
135 } | 134 } |
136 return self; | 135 return self; |
137 } | 136 } |
138 | 137 |
139 - (instancetype)initWithCoder:(NSCoder*)decoder { | 138 - (instancetype)initWithCoder:(NSCoder*)decoder { |
140 NOTREACHED(); | 139 NOTREACHED(); |
141 return nil; | 140 return nil; |
142 } | 141 } |
143 | 142 |
144 - (instancetype)initWithFrame:(CGRect)frame { | 143 - (instancetype)initWithFrame:(CGRect)frame { |
145 NOTREACHED(); | 144 NOTREACHED(); |
146 return nil; | 145 return nil; |
147 } | 146 } |
148 | 147 |
149 - (void)dealloc { | 148 - (void)dealloc { |
150 self.contentViewProxy.contentView = nil; | 149 self.contentViewProxy.contentView = nil; |
| 150 [super dealloc]; |
151 } | 151 } |
152 | 152 |
153 #pragma mark Accessors | 153 #pragma mark Accessors |
154 | 154 |
| 155 - (CRWWebViewContentView*)webViewContentView { |
| 156 return _webViewContentView.get(); |
| 157 } |
| 158 |
155 - (void)setWebViewContentView:(CRWWebViewContentView*)webViewContentView { | 159 - (void)setWebViewContentView:(CRWWebViewContentView*)webViewContentView { |
156 if (![_webViewContentView isEqual:webViewContentView]) { | 160 if (![_webViewContentView isEqual:webViewContentView]) { |
157 [_webViewContentView removeFromSuperview]; | 161 [_webViewContentView removeFromSuperview]; |
158 _webViewContentView = webViewContentView; | 162 _webViewContentView.reset([webViewContentView retain]); |
159 [_webViewContentView setFrame:self.bounds]; | 163 [_webViewContentView setFrame:self.bounds]; |
160 [self addSubview:_webViewContentView]; | 164 [self addSubview:_webViewContentView]; |
161 } | 165 } |
162 } | 166 } |
163 | 167 |
| 168 - (id<CRWNativeContent>)nativeController { |
| 169 return _nativeController.get(); |
| 170 } |
| 171 |
164 - (void)setNativeController:(id<CRWNativeContent>)nativeController { | 172 - (void)setNativeController:(id<CRWNativeContent>)nativeController { |
165 if (![_nativeController isEqual:nativeController]) { | 173 if (![_nativeController isEqual:nativeController]) { |
166 __weak id oldController = _nativeController; | 174 base::WeakNSProtocol<id> oldController(_nativeController); |
167 if ([oldController respondsToSelector:@selector(willBeDismissed)]) { | 175 if ([oldController respondsToSelector:@selector(willBeDismissed)]) { |
168 [oldController willBeDismissed]; | 176 [oldController willBeDismissed]; |
169 } | 177 } |
170 [[oldController view] removeFromSuperview]; | 178 [[oldController view] removeFromSuperview]; |
171 _nativeController = nativeController; | 179 _nativeController.reset([nativeController retain]); |
172 // TODO(crbug.com/503297): Re-enable this DCHECK once native controller | 180 // TODO(crbug.com/503297): Re-enable this DCHECK once native controller |
173 // leaks are fixed. | 181 // leaks are fixed. |
174 // DCHECK(!oldController); | 182 // DCHECK(!oldController); |
175 } | 183 } |
176 } | 184 } |
177 | 185 |
| 186 - (CRWContentView*)transientContentView { |
| 187 return _transientContentView.get(); |
| 188 } |
| 189 |
178 - (void)setTransientContentView:(CRWContentView*)transientContentView { | 190 - (void)setTransientContentView:(CRWContentView*)transientContentView { |
179 if (![_transientContentView isEqual:transientContentView]) { | 191 if (![_transientContentView isEqual:transientContentView]) { |
180 [_transientContentView removeFromSuperview]; | 192 [_transientContentView removeFromSuperview]; |
181 _transientContentView = transientContentView; | 193 _transientContentView.reset([transientContentView retain]); |
182 } | 194 } |
183 } | 195 } |
184 | 196 |
185 - (void)setToolbarContainerView:(CRWToolbarContainerView*)toolbarContainerView { | 197 - (void)setToolbarContainerView:(CRWToolbarContainerView*)toolbarContainerView { |
186 if (![_toolbarContainerView isEqual:toolbarContainerView]) { | 198 if (![_toolbarContainerView isEqual:toolbarContainerView]) { |
187 [_toolbarContainerView removeFromSuperview]; | 199 [_toolbarContainerView removeFromSuperview]; |
188 _toolbarContainerView = toolbarContainerView; | 200 _toolbarContainerView.reset([toolbarContainerView retain]); |
189 } | 201 } |
190 } | 202 } |
191 | 203 |
| 204 - (UIView*)toolbarContainerView { |
| 205 return _toolbarContainerView.get(); |
| 206 } |
| 207 |
192 - (CRWWebViewProxyImpl*)contentViewProxy { | 208 - (CRWWebViewProxyImpl*)contentViewProxy { |
193 return [_delegate contentViewProxyForContainerView:self]; | 209 return [_delegate contentViewProxyForContainerView:self]; |
194 } | 210 } |
195 | 211 |
196 - (CGRect)visibleFrame { | 212 - (CGRect)visibleFrame { |
197 CGFloat headerHeight = [_delegate headerHeightForContainerView:self]; | 213 CGFloat headerHeight = [_delegate headerHeightForContainerView:self]; |
198 return UIEdgeInsetsInsetRect(self.bounds, | 214 return UIEdgeInsetsInsetRect(self.bounds, |
199 UIEdgeInsetsMake(headerHeight, 0, 0, 0)); | 215 UIEdgeInsetsMake(headerHeight, 0, 0, 0)); |
200 } | 216 } |
201 | 217 |
| 218 - (id<CRWWebControllerContainerViewDelegate>)delegate { |
| 219 return _delegate.get(); |
| 220 } |
| 221 |
| 222 - (void)setDelegate:(id<CRWWebControllerContainerViewDelegate>)delegate { |
| 223 _delegate.reset(delegate); |
| 224 } |
| 225 |
202 #pragma mark Layout | 226 #pragma mark Layout |
203 | 227 |
204 - (void)layoutSubviews { | 228 - (void)layoutSubviews { |
205 [super layoutSubviews]; | 229 [super layoutSubviews]; |
206 | 230 |
207 self.webViewContentView.frame = self.bounds; | 231 self.webViewContentView.frame = self.bounds; |
208 | 232 |
209 // TODO(crbug.com/570114): Move adding of the following subviews to another | 233 // TODO(crbug.com/570114): Move adding of the following subviews to another |
210 // place. | 234 // place. |
211 | 235 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 - (void)clearTransientContentView { | 308 - (void)clearTransientContentView { |
285 self.transientContentView = nil; | 309 self.transientContentView = nil; |
286 self.contentViewProxy.contentView = self.webViewContentView; | 310 self.contentViewProxy.contentView = self.webViewContentView; |
287 } | 311 } |
288 | 312 |
289 #pragma mark Toolbars | 313 #pragma mark Toolbars |
290 | 314 |
291 - (void)addToolbar:(UIView*)toolbar { | 315 - (void)addToolbar:(UIView*)toolbar { |
292 // Create toolbar container if necessary. | 316 // Create toolbar container if necessary. |
293 if (!self.toolbarContainerView) { | 317 if (!self.toolbarContainerView) { |
294 self.toolbarContainerView = | 318 self.toolbarContainerView = [ |
295 [[CRWToolbarContainerView alloc] initWithFrame:CGRectZero]; | 319 [[CRWToolbarContainerView alloc] initWithFrame:CGRectZero] autorelease]; |
296 } | 320 } |
297 // Add the toolbar to the container. | 321 // Add the toolbar to the container. |
298 [self.toolbarContainerView addToolbar:toolbar]; | 322 [self.toolbarContainerView addToolbar:toolbar]; |
299 [self setNeedsLayout]; | 323 [self setNeedsLayout]; |
300 } | 324 } |
301 | 325 |
302 - (void)addToolbars:(NSArray*)toolbars { | 326 - (void)addToolbars:(NSArray*)toolbars { |
303 DCHECK(toolbars); | 327 DCHECK(toolbars); |
304 for (UIView* toolbar in toolbars) | 328 for (UIView* toolbar in toolbars) |
305 [self addToolbar:toolbar]; | 329 [self addToolbar:toolbar]; |
306 } | 330 } |
307 | 331 |
308 - (void)removeToolbar:(UIView*)toolbar { | 332 - (void)removeToolbar:(UIView*)toolbar { |
309 // Remove the toolbar from the container view. | 333 // Remove the toolbar from the container view. |
310 [self.toolbarContainerView removeToolbar:toolbar]; | 334 [self.toolbarContainerView removeToolbar:toolbar]; |
311 // Reset the container if there are no more toolbars. | 335 // Reset the container if there are no more toolbars. |
312 if ([self.toolbarContainerView.toolbars count]) | 336 if ([self.toolbarContainerView.toolbars count]) |
313 [self setNeedsLayout]; | 337 [self setNeedsLayout]; |
314 else | 338 else |
315 self.toolbarContainerView = nil; | 339 self.toolbarContainerView = nil; |
316 } | 340 } |
317 | 341 |
318 - (void)removeAllToolbars { | 342 - (void)removeAllToolbars { |
319 // Resetting the property will remove the toolbars from the hierarchy. | 343 // Resetting the property will remove the toolbars from the hierarchy. |
320 self.toolbarContainerView = nil; | 344 self.toolbarContainerView = nil; |
321 } | 345 } |
322 | 346 |
323 @end | 347 @end |
OLD | NEW |