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

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

Issue 2828743002: LabelObserver is no longer retained by the label (Closed)
Patch Set: Address comments 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"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 // If there are tap buttons, but they are not subviews of |_label|'s superview 126 // 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 127 // (if _label's superview has changed since the buttons were created), then
128 // the tap buttons are migrated into the new superview. 128 // the tap buttons are migrated into the new superview.
129 - (void)updateTapButtons; 129 - (void)updateTapButtons;
130 130
131 @end 131 @end
132 132
133 @implementation LabelLinkController { 133 @implementation LabelLinkController {
134 // Ivars immutable for the lifetime of the object. 134 // Ivars immutable for the lifetime of the object.
135 base::mac::ScopedBlock<ProceduralBlockWithURL> _action; 135 base::mac::ScopedBlock<ProceduralBlockWithURL> _action;
136 base::WeakNSObject<UILabel> _label; // weak 136 base::scoped_nsobject<UILabel> _label;
137 base::scoped_nsobject<UITapGestureRecognizer> _linkTapRecognizer; 137 base::scoped_nsobject<UITapGestureRecognizer> _linkTapRecognizer;
138 138
139 // Ivas backing properties. 139 // Ivas backing properties.
140 base::scoped_nsobject<UIColor> _linkColor; 140 base::scoped_nsobject<UIColor> _linkColor;
141 base::scoped_nsobject<UIFont> _linkFont; 141 base::scoped_nsobject<UIFont> _linkFont;
142 142
143 // Ivars that reset when label text changes. 143 // Ivars that reset when label text changes.
144 base::scoped_nsobject<NSMutableDictionary> _layoutsForURLs; 144 base::scoped_nsobject<NSMutableDictionary> _layoutsForURLs;
145 base::scoped_nsobject<NSAttributedString> _originalLabelText; 145 base::scoped_nsobject<NSAttributedString> _originalLabelText;
146 CGRect _lastLabelFrame; 146 CGRect _lastLabelFrame;
147 147
148 // Ivars that reset when text or bounds change. 148 // Ivars that reset when text or bounds change.
149 base::scoped_nsprotocol<id<TextRegionMapper>> _textMapper; 149 base::scoped_nsprotocol<id<TextRegionMapper>> _textMapper;
150 150
151 // Internal tracking. 151 // Internal tracking.
152 BOOL _justUpdatedStyles; 152 BOOL _justUpdatedStyles;
153 base::scoped_nsobject<NSMutableArray> _linkButtons; 153 base::scoped_nsobject<NSMutableArray> _linkButtons;
154 base::scoped_nsobject<LabelObserver> _labelObserver;
154 } 155 }
155 156
156 @synthesize showTapAreas = _showTapAreas; 157 @synthesize showTapAreas = _showTapAreas;
157 @synthesize textMapperClass = _textMapperClass; 158 @synthesize textMapperClass = _textMapperClass;
158 @synthesize linkUnderlineStyle = _linkUnderlineStyle; 159 @synthesize linkUnderlineStyle = _linkUnderlineStyle;
159 160
160 - (instancetype)initWithLabel:(UILabel*)label 161 - (instancetype)initWithLabel:(UILabel*)label
161 action:(ProceduralBlockWithURL)action { 162 action:(ProceduralBlockWithURL)action {
162 if ((self = [super init])) { 163 if ((self = [super init])) {
163 DCHECK(label); 164 DCHECK(label);
164 _label.reset(label); 165 _label.reset([label retain]);
165 _action.reset(action, base::scoped_policy::RETAIN); 166 _action.reset(action, base::scoped_policy::RETAIN);
166 _linkUnderlineStyle = NSUnderlineStyleNone; 167 _linkUnderlineStyle = NSUnderlineStyleNone;
167 [self reset]; 168 [self reset];
168 169
170 _labelObserver.reset([[LabelObserver observerForLabel:_label] retain]);
171 [_labelObserver startObserving];
169 [self addLabelObserverActions]; 172 [self addLabelObserverActions];
170 173
171 self.textMapperClass = [CoreTextRegionMapper class]; 174 self.textMapperClass = [CoreTextRegionMapper class];
172 _linkButtons.reset([[NSMutableArray alloc] init]); 175 _linkButtons.reset([[NSMutableArray alloc] init]);
173 } 176 }
174 return self; 177 return self;
175 } 178 }
176 179
177 - (NSAttributedString*)originalLabelText { 180 - (NSAttributedString*)originalLabelText {
178 return _originalLabelText.get(); 181 return _originalLabelText.get();
179 } 182 }
180 183
181 - (NSArray*)linkButtons { 184 - (NSArray*)linkButtons {
182 return _linkButtons.get(); 185 return _linkButtons.get();
183 } 186 }
184 187
185 - (void)addLabelObserverActions { 188 - (void)addLabelObserverActions {
186 LabelObserver* observer = [LabelObserver observerForLabel:_label];
187 base::WeakNSObject<LabelLinkController> weakSelf(self); 189 base::WeakNSObject<LabelLinkController> weakSelf(self);
188 [observer addStyleChangedAction:^(UILabel* label) { 190 [_labelObserver addStyleChangedAction:^(UILabel* label) {
189 // One of the style properties has been changed, which will silently 191 // One of the style properties has been changed, which will silently
190 // update the label's attributedText. 192 // update the label's attributedText.
191 if (!weakSelf) 193 if (!weakSelf)
192 return; 194 return;
193 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]); 195 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]);
194 [strongSelf labelStyleInvalidated]; 196 [strongSelf labelStyleInvalidated];
195 }]; 197 }];
196 [observer addTextChangedAction:^(UILabel* label) { 198 [_labelObserver addTextChangedAction:^(UILabel* label) {
197 if (!weakSelf) 199 if (!weakSelf)
198 return; 200 return;
199 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]); 201 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]);
200 NSString* originalText = [[strongSelf originalLabelText] string]; 202 NSString* originalText = [[strongSelf originalLabelText] string];
201 if ([label.text isEqualToString:originalText]) { 203 if ([label.text isEqualToString:originalText]) {
202 // The actual text of the label didn't change, so this was a change to 204 // The actual text of the label didn't change, so this was a change to
203 // the string attributes only. 205 // the string attributes only.
204 [strongSelf labelStyleInvalidated]; 206 [strongSelf labelStyleInvalidated];
205 } else { 207 } else {
206 // The label text has changed, so start everything from scratch. 208 // The label text has changed, so start everything from scratch.
207 [strongSelf reset]; 209 [strongSelf reset];
208 } 210 }
209 }]; 211 }];
210 [observer addLayoutChangedAction:^(UILabel* label) { 212 [_labelObserver addLayoutChangedAction:^(UILabel* label) {
211 if (!weakSelf) 213 if (!weakSelf)
212 return; 214 return;
213 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]); 215 base::scoped_nsobject<LabelLinkController> strongSelf([weakSelf retain]);
214 [strongSelf labelLayoutInvalidated]; 216 [strongSelf labelLayoutInvalidated];
215 NSArray* linkButtons = [strongSelf linkButtons]; 217 NSArray* linkButtons = [strongSelf linkButtons];
216 // If this layout change corresponds to |label|'s moving to a new superview, 218 // If this layout change corresponds to |label|'s moving to a new superview,
217 // update the tap buttons so that they are inserted above |label| in the new 219 // update the tap buttons so that they are inserted above |label| in the new
218 // hierarchy. 220 // hierarchy.
219 if (linkButtons.count && label.superview != [linkButtons[0] superview]) 221 if (linkButtons.count && label.superview != [linkButtons[0] superview])
220 [strongSelf updateTapButtons]; 222 [strongSelf updateTapButtons];
221 }]; 223 }];
222 } 224 }
223 225
224 - (void)dealloc { 226 - (void)dealloc {
225 [self clearTapButtons]; 227 [self clearTapButtons];
228 [_labelObserver stopObserving];
226 [super dealloc]; 229 [super dealloc];
227 } 230 }
228 231
229 - (void)addLinkWithRange:(NSRange)range url:(GURL)url { 232 - (void)addLinkWithRange:(NSRange)range url:(GURL)url {
230 DCHECK(url.is_valid()); 233 DCHECK(url.is_valid());
231 if (!_layoutsForURLs) 234 if (!_layoutsForURLs)
232 _layoutsForURLs.reset([[NSMutableDictionary alloc] init]); 235 _layoutsForURLs.reset([[NSMutableDictionary alloc] init]);
233 NSURL* key = net::NSURLWithGURL(url); 236 NSURL* key = net::NSURLWithGURL(url);
234 base::scoped_nsobject<LinkLayout> layout( 237 base::scoped_nsobject<LinkLayout> layout(
235 [[LinkLayout alloc] initWithRange:range]); 238 [[LinkLayout alloc] initWithRange:range]);
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 if (CGRectContainsPoint(frame, point)) { 445 if (CGRectContainsPoint(frame, point)) {
443 _action.get()(net::GURLWithNSURL(key)); 446 _action.get()(net::GURLWithNSURL(key));
444 *stop = YES; 447 *stop = YES;
445 break; 448 break;
446 } 449 }
447 } 450 }
448 }]; 451 }];
449 } 452 }
450 453
451 @end 454 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/util/label_link_controller.h ('k') | ios/chrome/browser/ui/util/label_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698