Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: ios/chrome/browser/ui/util/label_link_controller.mm

Issue 2819283004: [ObjC ARC] Converts ios/chrome/browser/ui/util:util to ARC. (Closed)
Patch Set: Fix copy for block Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/chrome/browser/ui/util/label_link_controller.h" 5 #import "ios/chrome/browser/ui/util/label_link_controller.h"
6 6
7 #include <map> 7 #include <map>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/ios/ios_util.h" 10 #include "base/ios/ios_util.h"
11 #include "base/ios/weak_nsobject.h"
12 #include "base/logging.h" 11 #include "base/logging.h"
13 #include "base/mac/foundation_util.h" 12 #include "base/mac/foundation_util.h"
14 #include "base/mac/scoped_block.h"
15 #import "base/mac/scoped_nsobject.h"
16 #import "base/strings/sys_string_conversions.h" 13 #import "base/strings/sys_string_conversions.h"
17 #include "ios/chrome/browser/ui/ui_util.h" 14 #include "ios/chrome/browser/ui/ui_util.h"
18 #import "ios/chrome/browser/ui/util/label_observer.h" 15 #import "ios/chrome/browser/ui/util/label_observer.h"
19 #import "ios/chrome/browser/ui/util/text_region_mapper.h" 16 #import "ios/chrome/browser/ui/util/text_region_mapper.h"
20 #import "ios/chrome/browser/ui/util/transparent_link_button.h" 17 #import "ios/chrome/browser/ui/util/transparent_link_button.h"
21 #import "net/base/mac/url_conversions.h" 18 #import "net/base/mac/url_conversions.h"
22 #include "url/gurl.h" 19 #include "url/gurl.h"
23 20
21 #if !defined(__has_feature) || !__has_feature(objc_arc)
22 #error "This file requires ARC support."
23 #endif
24
24 #pragma mark - LinkLayout 25 #pragma mark - LinkLayout
25 26
26 // Object encapsulating the range of a link and the frames corresponding with 27 // Object encapsulating the range of a link and the frames corresponding with
27 // that range. 28 // that range.
28 @interface LinkLayout : NSObject { 29 @interface LinkLayout : NSObject
29 // Backing objects for properties of same name.
30 base::scoped_nsobject<NSArray> _frames;
31 }
32 30
33 // Designated initializer. 31 // Designated initializer.
34 - (instancetype)initWithRange:(NSRange)range NS_DESIGNATED_INITIALIZER; 32 - (instancetype)initWithRange:(NSRange)range NS_DESIGNATED_INITIALIZER;
35 - (instancetype)init NS_UNAVAILABLE; 33 - (instancetype)init NS_UNAVAILABLE;
36 34
37 // The range passed on initialization. 35 // The range passed on initialization.
38 @property(nonatomic, readonly) NSRange range; 36 @property(nonatomic, readonly) NSRange range;
39 37
40 // The frames calculated for |_range|. 38 // The frames calculated for |_range|.
41 @property(nonatomic, retain) NSArray* frames; 39 @property(nonatomic, strong) NSArray* frames;
42 40
43 @end 41 @end
44 42
45 @implementation LinkLayout 43 @implementation LinkLayout
46 44
47 @synthesize range = _range; 45 @synthesize range = _range;
46 @synthesize frames = _frames;
48 47
49 - (instancetype)initWithRange:(NSRange)range { 48 - (instancetype)initWithRange:(NSRange)range {
50 if ((self = [super init])) { 49 if ((self = [super init])) {
51 DCHECK_NE(range.location, static_cast<NSUInteger>(NSNotFound)); 50 DCHECK_NE(range.location, static_cast<NSUInteger>(NSNotFound));
52 DCHECK_NE(range.length, 0U); 51 DCHECK_NE(range.length, 0U);
53 _range = range; 52 _range = range;
54 } 53 }
55 return self; 54 return self;
56 } 55 }
57 56
58 #pragma mark - Accessors
59
60 - (void)setFrames:(NSArray*)frames {
61 _frames.reset([frames retain]);
62 }
63
64 - (NSArray*)frames {
65 return _frames.get();
66 }
67
68 @end 57 @end
69 58
70 #pragma mark - LabelLinkController 59 #pragma mark - LabelLinkController
71 60
72 @interface LabelLinkController () 61 @interface LabelLinkController ()
73 // Private property exposed publically in testing interface. 62 // Private property exposed publically in testing interface.
74 @property(nonatomic, assign) Class textMapperClass; 63 @property(nonatomic, unsafe_unretained) Class textMapperClass;
75 64
76 // The original attributed text set on the label. This may be different from 65 // The original attributed text set on the label. This may be different from
77 // the label's |attributedText| property, as additional style attributes may be 66 // the label's |attributedText| property, as additional style attributes may be
78 // introduced for links. 67 // introduced for links.
79 @property(nonatomic, readonly) NSAttributedString* originalLabelText; 68 @property(nonatomic, strong, readonly) NSAttributedString* originalLabelText;
80 69
81 // The array of TransparentLinkButtons inserted above the label. 70 // The array of TransparentLinkButtons inserted above the label.
82 @property(nonatomic, readonly) NSArray* linkButtons; 71 @property(nonatomic, strong, readonly) NSMutableArray* linkButtons;
83 72
84 // Adds LabelObserverActions to the LabelObserver corresponding to |_label|. 73 // Adds LabelObserverActions to the LabelObserver corresponding to |_label|.
85 - (void)addLabelObserverActions; 74 - (void)addLabelObserverActions;
86 75
87 // Clears all defined links and any data associated with them. Update the 76 // Clears all defined links and any data associated with them. Update the
88 // original attributed text from the controlled label. 77 // original attributed text from the controlled label.
89 - (void)reset; 78 - (void)reset;
90 79
91 // Handle a change to the label that changes the positioning of glyphs but not 80 // Handle a change to the label that changes the positioning of glyphs but not
92 // any styling of those glyphs. Forces a recomputation of the tap regions, and 81 // any styling of those glyphs. Forces a recomputation of the tap regions, and
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 // are cleared. 114 // are cleared.
126 // If there are tap buttons, but they are not subviews of |_label|'s superview 115 // If there are tap buttons, but they are not subviews of |_label|'s superview
127 // (if _label's superview has changed since the buttons were created), then 116 // (if _label's superview has changed since the buttons were created), then
128 // the tap buttons are migrated into the new superview. 117 // the tap buttons are migrated into the new superview.
129 - (void)updateTapButtons; 118 - (void)updateTapButtons;
130 119
131 @end 120 @end
132 121
133 @implementation LabelLinkController { 122 @implementation LabelLinkController {
134 // Ivars immutable for the lifetime of the object. 123 // Ivars immutable for the lifetime of the object.
135 base::mac::ScopedBlock<ProceduralBlockWithURL> _action; 124 ProceduralBlockWithURL _action;
136 base::scoped_nsobject<UILabel> _label; 125 UILabel* _label;
137 base::scoped_nsobject<UITapGestureRecognizer> _linkTapRecognizer; 126 UITapGestureRecognizer* _linkTapRecognizer;
138
139 // Ivas backing properties.
140 base::scoped_nsobject<UIColor> _linkColor;
141 base::scoped_nsobject<UIFont> _linkFont;
142 127
143 // Ivars that reset when label text changes. 128 // Ivars that reset when label text changes.
144 base::scoped_nsobject<NSMutableDictionary> _layoutsForURLs; 129 NSMutableDictionary* _layoutsForURLs;
145 base::scoped_nsobject<NSAttributedString> _originalLabelText;
146 CGRect _lastLabelFrame; 130 CGRect _lastLabelFrame;
147 131
148 // Ivars that reset when text or bounds change. 132 // Ivars that reset when text or bounds change.
149 base::scoped_nsprotocol<id<TextRegionMapper>> _textMapper; 133 id<TextRegionMapper> _textMapper;
150 134
151 // Internal tracking. 135 // Internal tracking.
152 BOOL _justUpdatedStyles; 136 BOOL _justUpdatedStyles;
153 base::scoped_nsobject<NSMutableArray> _linkButtons; 137 LabelObserver* _labelObserver;
154 base::scoped_nsobject<LabelObserver> _labelObserver;
155 } 138 }
156 139
157 @synthesize showTapAreas = _showTapAreas; 140 @synthesize showTapAreas = _showTapAreas;
158 @synthesize textMapperClass = _textMapperClass; 141 @synthesize textMapperClass = _textMapperClass;
159 @synthesize linkUnderlineStyle = _linkUnderlineStyle; 142 @synthesize linkUnderlineStyle = _linkUnderlineStyle;
143 @synthesize linkButtons = _linkButtons;
144 @synthesize originalLabelText = _originalLabelText;
145 @synthesize linkFont = _linkFont;
146 @synthesize linkColor = _linkColor;
160 147
161 - (instancetype)initWithLabel:(UILabel*)label 148 - (instancetype)initWithLabel:(UILabel*)label
162 action:(ProceduralBlockWithURL)action { 149 action:(ProceduralBlockWithURL)action {
163 if ((self = [super init])) { 150 if ((self = [super init])) {
164 DCHECK(label); 151 DCHECK(label);
165 _label.reset([label retain]); 152 _label = label;
166 _action.reset(action, base::scoped_policy::RETAIN); 153 _action = [action copy];
167 _linkUnderlineStyle = NSUnderlineStyleNone; 154 _linkUnderlineStyle = NSUnderlineStyleNone;
168 [self reset]; 155 [self reset];
169 156
170 _labelObserver.reset([[LabelObserver observerForLabel:_label] retain]); 157 _labelObserver = [LabelObserver observerForLabel:_label];
171 [_labelObserver startObserving]; 158 [_labelObserver startObserving];
172 [self addLabelObserverActions]; 159 [self addLabelObserverActions];
173 160
174 self.textMapperClass = [CoreTextRegionMapper class]; 161 self.textMapperClass = [CoreTextRegionMapper class];
175 _linkButtons.reset([[NSMutableArray alloc] init]); 162 _linkButtons = [[NSMutableArray alloc] init];
176 } 163 }
177 return self; 164 return self;
178 } 165 }
179 166
180 - (NSAttributedString*)originalLabelText {
181 return _originalLabelText.get();
182 }
183
184 - (NSArray*)linkButtons {
185 return _linkButtons.get();
186 }
187
188 - (void)addLabelObserverActions { 167 - (void)addLabelObserverActions {
189 base::WeakNSObject<LabelLinkController> weakSelf(self); 168 __weak LabelLinkController* weakSelf = self;
190 [_labelObserver addStyleChangedAction:^(UILabel* label) { 169 [_labelObserver addStyleChangedAction:^(UILabel* label) {
191 // One of the style properties has been changed, which will silently 170 // One of the style properties has been changed, which will silently
192 // update the label's attributedText. 171 // update the label's attributedText.
193 if (!weakSelf) 172 if (!weakSelf)
194 return; 173 return;
195 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]); 174 LabelLinkController* strongSelf = weakSelf;
196 [strongSelf labelStyleInvalidated]; 175 [strongSelf labelStyleInvalidated];
197 }]; 176 }];
198 [_labelObserver addTextChangedAction:^(UILabel* label) { 177 [_labelObserver addTextChangedAction:^(UILabel* label) {
199 if (!weakSelf) 178 if (!weakSelf)
200 return; 179 return;
201 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]); 180 LabelLinkController* strongSelf = weakSelf;
202 NSString* originalText = [[strongSelf originalLabelText] string]; 181 NSString* originalText = [[strongSelf originalLabelText] string];
203 if ([label.text isEqualToString:originalText]) { 182 if ([label.text isEqualToString:originalText]) {
204 // The actual text of the label didn't change, so this was a change to 183 // The actual text of the label didn't change, so this was a change to
205 // the string attributes only. 184 // the string attributes only.
206 [strongSelf labelStyleInvalidated]; 185 [strongSelf labelStyleInvalidated];
207 } else { 186 } else {
208 // The label text has changed, so start everything from scratch. 187 // The label text has changed, so start everything from scratch.
209 [strongSelf reset]; 188 [strongSelf reset];
210 } 189 }
211 }]; 190 }];
212 [_labelObserver addLayoutChangedAction:^(UILabel* label) { 191 [_labelObserver addLayoutChangedAction:^(UILabel* label) {
213 if (!weakSelf) 192 if (!weakSelf)
214 return; 193 return;
215 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]); 194 LabelLinkController* strongSelf = weakSelf;
216 [strongSelf labelLayoutInvalidated]; 195 [strongSelf labelLayoutInvalidated];
217 NSArray* linkButtons = [strongSelf linkButtons]; 196 NSArray* linkButtons = [strongSelf linkButtons];
218 // If this layout change corresponds to |label|'s moving to a new superview, 197 // If this layout change corresponds to |label|'s moving to a new superview,
219 // update the tap buttons so that they are inserted above |label| in the new 198 // update the tap buttons so that they are inserted above |label| in the new
220 // hierarchy. 199 // hierarchy.
221 if (linkButtons.count && label.superview != [linkButtons[0] superview]) 200 if (linkButtons.count && label.superview != [linkButtons[0] superview])
222 [strongSelf updateTapButtons]; 201 [strongSelf updateTapButtons];
223 }]; 202 }];
224 } 203 }
225 204
226 - (void)dealloc { 205 - (void)dealloc {
227 [self clearTapButtons]; 206 [self clearTapButtons];
228 [_labelObserver stopObserving]; 207 [_labelObserver stopObserving];
229 [super dealloc];
230 } 208 }
231 209
232 - (void)addLinkWithRange:(NSRange)range url:(GURL)url { 210 - (void)addLinkWithRange:(NSRange)range url:(GURL)url {
233 DCHECK(url.is_valid()); 211 DCHECK(url.is_valid());
234 if (!_layoutsForURLs) 212 if (!_layoutsForURLs)
235 _layoutsForURLs.reset([[NSMutableDictionary alloc] init]); 213 _layoutsForURLs = [[NSMutableDictionary alloc] init];
236 NSURL* key = net::NSURLWithGURL(url); 214 NSURL* key = net::NSURLWithGURL(url);
237 base::scoped_nsobject<LinkLayout> layout( 215 LinkLayout* layout = [[LinkLayout alloc] initWithRange:range];
238 [[LinkLayout alloc] initWithRange:range]);
239 [_layoutsForURLs setObject:layout forKey:key]; 216 [_layoutsForURLs setObject:layout forKey:key];
240 [self updateStyles]; 217 [self updateStyles];
241 } 218 }
242 219
243 - (UIColor*)linkColor {
244 return _linkColor.get();
245 }
246
247 - (void)setLinkColor:(UIColor*)linkColor { 220 - (void)setLinkColor:(UIColor*)linkColor {
248 _linkColor.reset([linkColor copy]); 221 _linkColor = [linkColor copy];
249 [self updateStyles]; 222 [self updateStyles];
250 } 223 }
251 224
252 - (void)setLinkUnderlineStyle:(NSUnderlineStyle)underlineStyle { 225 - (void)setLinkUnderlineStyle:(NSUnderlineStyle)underlineStyle {
253 _linkUnderlineStyle = underlineStyle; 226 _linkUnderlineStyle = underlineStyle;
254 [self updateStyles]; 227 [self updateStyles];
255 } 228 }
256 229
257 - (UIFont*)linkFont {
258 return _linkFont.get();
259 }
260
261 - (void)setLinkFont:(UIFont*)linkFont { 230 - (void)setLinkFont:(UIFont*)linkFont {
262 _linkFont.reset([linkFont retain]); 231 _linkFont = linkFont;
263 [self updateStyles]; 232 [self updateStyles];
264 } 233 }
265 234
266 - (void)setShowTapAreas:(BOOL)showTapAreas { 235 - (void)setShowTapAreas:(BOOL)showTapAreas {
267 #ifndef NDEBUG 236 #ifndef NDEBUG
268 for (TransparentLinkButton* button in _linkButtons.get()) { 237 for (TransparentLinkButton* button in _linkButtons) {
269 button.debug = showTapAreas; 238 button.debug = showTapAreas;
270 } 239 }
271 #endif // NDEBUG 240 #endif // NDEBUG
272 _showTapAreas = showTapAreas; 241 _showTapAreas = showTapAreas;
273 } 242 }
274 243
275 #pragma mark - internal methods 244 #pragma mark - internal methods
276 245
277 - (void)reset { 246 - (void)reset {
278 _originalLabelText.reset([[_label attributedText] copy]); 247 _originalLabelText = [[_label attributedText] copy];
279 _textMapper.reset(); 248 _textMapper = nil;
280 _lastLabelFrame = CGRectZero; 249 _lastLabelFrame = CGRectZero;
281 _layoutsForURLs.reset(); 250 _layoutsForURLs = nil;
282 } 251 }
283 252
284 - (void)labelLayoutInvalidated { 253 - (void)labelLayoutInvalidated {
285 _textMapper.reset(); 254 _textMapper = nil;
286 [self updateTapRects]; 255 [self updateTapRects];
287 } 256 }
288 257
289 - (void)labelStyleInvalidated { 258 - (void)labelStyleInvalidated {
290 // If the style invalidation was triggered by this class updating link styles, 259 // If the style invalidation was triggered by this class updating link styles,
291 // then the original label text is still correct, but the tap rects still need 260 // then the original label text is still correct, but the tap rects still need
292 // to be updated. Otherwise, update the original label text, and then update 261 // to be updated. Otherwise, update the original label text, and then update
293 // styles. This will set |_justUpdatedStyles| and trigger another call to 262 // styles. This will set |_justUpdatedStyles| and trigger another call to
294 // this method via KVO. 263 // this method via KVO.
295 if (_justUpdatedStyles) { 264 if (_justUpdatedStyles) {
296 // TODO(crbug.com/664648): Remove _justUpdatedStyles due to bug that 265 // TODO(crbug.com/664648): Remove _justUpdatedStyles due to bug that
297 // prevents proper style updates after successive label format changes. 266 // prevents proper style updates after successive label format changes.
298 _justUpdatedStyles = NO; 267 _justUpdatedStyles = NO;
299 } else if (![_originalLabelText isEqual:[_label attributedText]]) { 268 } else if (![_originalLabelText isEqual:[_label attributedText]]) {
300 _originalLabelText.reset([[_label attributedText] copy]); 269 _originalLabelText = [[_label attributedText] copy];
301 [self updateStyles]; 270 [self updateStyles];
302 } 271 }
303 _lastLabelFrame = CGRectZero; 272 _lastLabelFrame = CGRectZero;
304 [self labelLayoutInvalidated]; 273 [self labelLayoutInvalidated];
305 } 274 }
306 275
307 - (void)updateStyles { 276 - (void)updateStyles {
308 if (![_layoutsForURLs count]) 277 if (![_layoutsForURLs count])
309 return; 278 return;
310 279
311 __block base::scoped_nsobject<NSMutableAttributedString> labelText( 280 __block NSMutableAttributedString* labelText =
312 [_originalLabelText mutableCopy]); 281 [_originalLabelText mutableCopy];
313 [_layoutsForURLs enumerateKeysAndObjectsUsingBlock:^( 282 [_layoutsForURLs enumerateKeysAndObjectsUsingBlock:^(
314 NSURL* key, LinkLayout* layout, BOOL* stop) { 283 NSURL* key, LinkLayout* layout, BOOL* stop) {
315 if (_linkColor) { 284 if (_linkColor) {
316 [labelText addAttribute:NSForegroundColorAttributeName 285 [labelText addAttribute:NSForegroundColorAttributeName
317 value:_linkColor 286 value:_linkColor
318 range:layout.range]; 287 range:layout.range];
319 } 288 }
320 if (_linkUnderlineStyle != NSUnderlineStyleNone) { 289 if (_linkUnderlineStyle != NSUnderlineStyleNone) {
321 [labelText addAttribute:NSUnderlineStyleAttributeName 290 [labelText addAttribute:NSUnderlineStyleAttributeName
322 value:@(_linkUnderlineStyle) 291 value:@(_linkUnderlineStyle)
323 range:layout.range]; 292 range:layout.range];
324 } 293 }
325 if (_linkFont) { 294 if (_linkFont) {
326 [labelText addAttribute:NSFontAttributeName 295 [labelText addAttribute:NSFontAttributeName
327 value:_linkFont 296 value:_linkFont
328 range:layout.range]; 297 range:layout.range];
329 } 298 }
330 }]; 299 }];
331 _justUpdatedStyles = YES; 300 _justUpdatedStyles = YES;
332 [_label setAttributedText:labelText]; 301 [_label setAttributedText:labelText];
333 _textMapper.reset(); 302 _textMapper = nil;
334 } 303 }
335 304
336 - (void)updateTapRects { 305 - (void)updateTapRects {
337 // Don't update if the label hasn't changed size or position. 306 // Don't update if the label hasn't changed size or position.
338 if (CGRectEqualToRect([_label frame], _lastLabelFrame)) 307 if (CGRectEqualToRect([_label frame], _lastLabelFrame))
339 return; 308 return;
340 // Don't update if there are no links. 309 // Don't update if there are no links.
341 if (![_layoutsForURLs count]) 310 if (![_layoutsForURLs count])
342 return; 311 return;
343 312
344 _lastLabelFrame = [_label frame]; 313 _lastLabelFrame = [_label frame];
345 [self clearTapButtons]; 314 [self clearTapButtons];
346 315
347 // If the label bounds are zero in either dimension, no rects are possible. 316 // If the label bounds are zero in either dimension, no rects are possible.
348 if (0.0 == _lastLabelFrame.size.width || 0.0 == _lastLabelFrame.size.height) 317 if (0.0 == _lastLabelFrame.size.width || 0.0 == _lastLabelFrame.size.height)
349 return; 318 return;
350 319
351 if (!_textMapper) 320 if (!_textMapper)
352 [self resetTextMapper]; 321 [self resetTextMapper];
353 322
354 for (LinkLayout* layout in [_layoutsForURLs allValues]) { 323 for (LinkLayout* layout in [_layoutsForURLs allValues]) {
355 base::scoped_nsobject<NSMutableArray> frames([[NSMutableArray alloc] init]); 324 NSMutableArray* frames = [[NSMutableArray alloc] init];
356 NSArray* rects = [_textMapper rectsForRange:layout.range]; 325 NSArray* rects = [_textMapper rectsForRange:layout.range];
357 for (NSUInteger rectIdx = 0; rectIdx < [rects count]; ++rectIdx) { 326 for (NSUInteger rectIdx = 0; rectIdx < [rects count]; ++rectIdx) {
358 CGRect frame = [rects[rectIdx] CGRectValue]; 327 CGRect frame = [rects[rectIdx] CGRectValue];
359 frame = [[_label superview] convertRect:frame fromView:_label]; 328 frame = [[_label superview] convertRect:frame fromView:_label];
360 [frames addObject:[NSValue valueWithCGRect:frame]]; 329 [frames addObject:[NSValue valueWithCGRect:frame]];
361 } 330 }
362 layout.frames = frames; 331 layout.frames = frames;
363 } 332 }
364 [self updateTapButtons]; 333 [self updateTapButtons];
365 } 334 }
366 335
367 - (void)resetTextMapper { 336 - (void)resetTextMapper {
368 DCHECK([self.textMapperClass conformsToProtocol:@protocol(TextRegionMapper)]); 337 DCHECK([self.textMapperClass conformsToProtocol:@protocol(TextRegionMapper)]);
369 _textMapper.reset([[self.textMapperClass alloc] 338 _textMapper = [[self.textMapperClass alloc]
370 initWithAttributedString:[_label attributedText] 339 initWithAttributedString:[_label attributedText]
371 bounds:[_label bounds]]); 340 bounds:[_label bounds]];
372 } 341 }
373 342
374 - (void)clearTapButtons { 343 - (void)clearTapButtons {
375 for (TransparentLinkButton* button in _linkButtons.get()) { 344 for (TransparentLinkButton* button in _linkButtons) {
376 [button removeFromSuperview]; 345 [button removeFromSuperview];
377 } 346 }
378 [_linkButtons removeAllObjects]; 347 [_linkButtons removeAllObjects];
379 } 348 }
380 349
381 - (void)updateTapButtons { 350 - (void)updateTapButtons {
382 // If the label has no superview, clear any existing buttons. 351 // If the label has no superview, clear any existing buttons.
383 if (![_label superview]) { 352 if (![_label superview]) {
384 [self clearTapButtons]; 353 [self clearTapButtons];
385 return; 354 return;
386 } else if ([_linkButtons count]) { 355 } else if ([_linkButtons count]) {
387 // If the buttons are currently in some view other than the label's 356 // If the buttons are currently in some view other than the label's
388 // superview, repatriate them. 357 // superview, repatriate them.
389 if (base::mac::ObjCCast<TransparentLinkButton>(_linkButtons[0]).superview != 358 if (base::mac::ObjCCast<TransparentLinkButton>(_linkButtons[0]).superview !=
390 [_label superview]) { 359 [_label superview]) {
391 for (TransparentLinkButton* button in _linkButtons.get()) { 360 for (TransparentLinkButton* button in _linkButtons) {
392 CGRect newFrame = 361 CGRect newFrame =
393 [[_label superview] convertRect:button.frame fromView:button]; 362 [[_label superview] convertRect:button.frame fromView:button];
394 [[_label superview] insertSubview:button aboveSubview:_label]; 363 [[_label superview] insertSubview:button aboveSubview:_label];
395 button.frame = newFrame; 364 button.frame = newFrame;
396 } 365 }
397 } 366 }
398 } 367 }
399 // If there are no buttons, make some and put them in the label's superview. 368 // If there are no buttons, make some and put them in the label's superview.
400 if (![_linkButtons count] && _layoutsForURLs) { 369 if (![_linkButtons count] && _layoutsForURLs) {
401 [_layoutsForURLs enumerateKeysAndObjectsUsingBlock:^( 370 [_layoutsForURLs enumerateKeysAndObjectsUsingBlock:^(
(...skipping 17 matching lines...) Expand all
419 } 388 }
420 }]; 389 }];
421 } 390 }
422 } 391 }
423 392
424 #pragma mark - Tap Handlers 393 #pragma mark - Tap Handlers
425 394
426 - (void)linkButtonTapped:(id)sender { 395 - (void)linkButtonTapped:(id)sender {
427 TransparentLinkButton* button = 396 TransparentLinkButton* button =
428 base::mac::ObjCCast<TransparentLinkButton>(sender); 397 base::mac::ObjCCast<TransparentLinkButton>(sender);
429 _action.get()(button.URL); 398 _action(button.URL);
430 } 399 }
431 400
432 #pragma mark - Test facilitators 401 #pragma mark - Test facilitators
433 402
434 - (NSArray*)tapRectsForURL:(GURL)url { 403 - (NSArray*)tapRectsForURL:(GURL)url {
435 NSURL* key = net::NSURLWithGURL(url); 404 NSURL* key = net::NSURLWithGURL(url);
436 LinkLayout* layout = [_layoutsForURLs objectForKey:key]; 405 LinkLayout* layout = [_layoutsForURLs objectForKey:key];
437 return layout.frames; 406 return layout.frames;
438 } 407 }
439 408
440 - (void)tapLabelAtPoint:(CGPoint)point { 409 - (void)tapLabelAtPoint:(CGPoint)point {
441 [_layoutsForURLs enumerateKeysAndObjectsUsingBlock:^( 410 [_layoutsForURLs enumerateKeysAndObjectsUsingBlock:^(
442 NSURL* key, LinkLayout* layout, BOOL* stop) { 411 NSURL* key, LinkLayout* layout, BOOL* stop) {
443 for (NSValue* frameValue in layout.frames) { 412 for (NSValue* frameValue in layout.frames) {
444 CGRect frame = [frameValue CGRectValue]; 413 CGRect frame = [frameValue CGRectValue];
445 if (CGRectContainsPoint(frame, point)) { 414 if (CGRectContainsPoint(frame, point)) {
446 _action.get()(net::GURLWithNSURL(key)); 415 _action(net::GURLWithNSURL(key));
447 *stop = YES; 416 *stop = YES;
448 break; 417 break;
449 } 418 }
450 } 419 }
451 }]; 420 }];
452 } 421 }
453 422
454 @end 423 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698