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

Side by Side Diff: ios/chrome/browser/ui/history/history_entry_item.mm

Issue 2590473002: Upstream Chrome on iOS source code [5/11]. (Closed)
Patch Set: Created 4 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/ui/history/history_entry_item.h"
6
7 #include "base/i18n/time_formatting.h"
8 #include "base/ios/weak_nsobject.h"
9 #import "base/mac/foundation_util.h"
10 #import "base/mac/objc_property_releaser.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "components/history/core/browser/url_row.h"
14 #include "components/strings/grit/components_strings.h"
15 #include "components/url_formatter/url_formatter.h"
16 #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
17 #import "ios/chrome/browser/ui/history/favicon_view.h"
18 #import "ios/chrome/browser/ui/history/favicon_view_provider.h"
19 #import "ios/chrome/browser/ui/history/history_entry.h"
20 #include "ios/chrome/browser/ui/rtl_geometry.h"
21 #import "ios/chrome/browser/ui/uikit_ui_util.h"
22 #include "ios/chrome/grit/ios_strings.h"
23 #import "ios/third_party/material_components_ios/src/components/Palettes/src/Mat erialPalettes.h"
24 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoF ontLoader.h"
25 #include "ui/base/l10n/l10n_util.h"
26
27 namespace {
28 // Size at which the favicon will be displayed.
29 const CGFloat kFaviconSize = 24.0;
30 // Minimum size at which to fetch favicons.
31 const CGFloat kMinFaviconSize = 16.0;
32 // Horizontal spacing between edge of the cell and the cell content.
33 const CGFloat kMargin = 16.0;
34 // Horizontal spacing between the leading edge of the cell and the text.
35 const CGFloat kHeaderMargin = 56.0;
36
37 NSString* FormattedTitle(const base::string16& title, const GURL& url) {
38 // Use url as title if no title.
39 bool using_url_as_the_title = false;
40 base::string16 formatted_title(title);
41 if (title.empty()) {
42 using_url_as_the_title = true;
43 formatted_title = url_formatter::FormatUrl(url);
44 }
45 // Since the title can contain BiDi text, mark the text as either RTL or LTR,
46 // depending on the characters in the string. If the URL is used as the title,
47 // mark the title as LTR since URLs are always treated as left to right
48 // strings.
49 if (base::i18n::IsRTL()) {
50 if (using_url_as_the_title)
51 base::i18n::WrapStringWithLTRFormatting(&formatted_title);
52 else
53 base::i18n::AdjustStringForLocaleDirection(&formatted_title);
54 }
55 return base::SysUTF16ToNSString(formatted_title);
56 }
57 } // namespace
58
59 #pragma mark - HistoryEntryItem
60
61 @interface HistoryEntryItem ()<FaviconViewProviderDelegate> {
62 // Property releaser for HistoryEntryItem.
63 base::mac::ObjCPropertyReleaser _propertyReleaser_HistoryEntryItem;
64 // Delegate for HistoryEntryItem.
65 base::WeakNSProtocol<id<HistoryEntryItemDelegate>> _delegate;
66 }
67
68 // FaviconViewProvider to fetch the favicon and format the favicon view.
69 @property(nonatomic, retain) FaviconViewProvider* faviconViewProvider;
70
71 // Custom accessibility actions for the history entry view.
72 - (NSArray*)accessibilityActions;
73 // Custom accessibility action to delete the history entry.
74 - (BOOL)deleteHistoryEntry;
75 // Custom accessibility action to open the history entry's URL in a new tab.
76 - (BOOL)openInNewTab;
77 // Custom accessibility action to open the history entry's URL in a new
78 // incognito tab.
79 - (BOOL)openInNewIncognitoTab;
80 // Custom accessibility action to copy the history entry's URL to the clipboard.
81 - (BOOL)copyURL;
82 @end
83
84 @implementation HistoryEntryItem
85
86 @synthesize faviconViewProvider = _faviconViewProvider;
87 @synthesize text = _text;
88 @synthesize detailText = _detailText;
89 @synthesize timeText = _timeText;
90 @synthesize URL = _URL;
91 @synthesize timestamp = _timestamp;
92
93 - (instancetype)initWithType:(NSInteger)type
94 historyEntry:(const history::HistoryEntry&)entry
95 browserState:(ios::ChromeBrowserState*)browserState
96 delegate:(id<HistoryEntryItemDelegate>)delegate {
97 self = [super initWithType:type];
98 if (self) {
99 _propertyReleaser_HistoryEntryItem.Init(self, [HistoryEntryItem class]);
100 self.cellClass = [HistoryEntryCell class];
101 favicon::LargeIconService* largeIconService =
102 IOSChromeLargeIconServiceFactory::GetForBrowserState(browserState);
103 _faviconViewProvider =
104 [[FaviconViewProvider alloc] initWithURL:entry.url
105 faviconSize:kFaviconSize
106 minFaviconSize:kMinFaviconSize
107 largeIconService:largeIconService
108 delegate:self];
109 _text = [FormattedTitle(entry.title, entry.url) copy];
110 _detailText = [base::SysUTF8ToNSString(entry.url.spec()) copy];
111 _timeText =
112 [base::SysUTF16ToNSString(base::TimeFormatTimeOfDay(entry.time)) copy];
113 _URL = GURL(entry.url);
114 _timestamp = entry.time;
115 _delegate.reset(delegate);
116 }
117 return self;
118 }
119
120 - (instancetype)initWithType:(NSInteger)type {
121 NOTREACHED();
122 return nil;
123 }
124
125 - (BOOL)isEqualToHistoryEntryItem:(HistoryEntryItem*)item {
126 return item && item.URL == _URL && item.timestamp == _timestamp;
127 }
128
129 - (BOOL)isEqual:(id)object {
130 if (self == object)
131 return YES;
132
133 if (![object isMemberOfClass:[HistoryEntryItem class]])
134 return NO;
135
136 return [self isEqualToHistoryEntryItem:object];
137 }
138
139 - (NSUInteger)hash {
140 return [base::SysUTF8ToNSString(self.URL.spec()) hash] ^
141 self.timestamp.ToInternalValue();
142 }
143
144 - (NSArray*)accessibilityActions {
145 UIAccessibilityCustomAction* deleteAction =
146 [[[UIAccessibilityCustomAction alloc]
147 initWithName:l10n_util::GetNSString(
148 IDS_HISTORY_ENTRY_ACCESSIBILITY_DELETE)
149 target:self
150 selector:@selector(deleteHistoryEntry)] autorelease];
151 UIAccessibilityCustomAction* openInNewTabAction =
152 [[[UIAccessibilityCustomAction alloc]
153 initWithName:l10n_util::GetNSString(
154 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)
155 target:self
156 selector:@selector(openInNewTab)] autorelease];
157 UIAccessibilityCustomAction* openInNewIncognitoTabAction =
158 [[[UIAccessibilityCustomAction alloc]
159 initWithName:l10n_util::GetNSString(
160 IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB)
161 target:self
162 selector:@selector(openInNewIncognitoTab)] autorelease];
163 UIAccessibilityCustomAction* copyURLAction =
164 [[[UIAccessibilityCustomAction alloc]
165 initWithName:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_COPY)
166 target:self
167 selector:@selector(copyURL)] autorelease];
168 return @[
169 deleteAction, openInNewTabAction, openInNewIncognitoTabAction, copyURLAction
170 ];
171 }
172
173 - (BOOL)deleteHistoryEntry {
174 [_delegate historyEntryItemDidRequestDelete:self];
175 return YES;
176 }
177
178 - (BOOL)openInNewTab {
179 [_delegate historyEntryItemDidRequestOpenInNewTab:self];
180 return YES;
181 }
182
183 - (BOOL)openInNewIncognitoTab {
184 [_delegate historyEntryItemDidRequestOpenInNewIncognitoTab:self];
185 return YES;
186 }
187
188 - (BOOL)copyURL {
189 [_delegate historyEntryItemDidRequestCopy:self];
190 return YES;
191 }
192
193 - (void)configureCell:(HistoryEntryCell*)cell {
194 [super configureCell:cell];
195
196 // Set favicon view and constraints.
197 FaviconView* faviconView = self.faviconViewProvider.faviconView;
198 [cell.faviconViewContainer addSubview:faviconView];
199 [faviconView setTranslatesAutoresizingMaskIntoConstraints:NO];
200 AddSameSizeConstraint(faviconView, cell.faviconViewContainer);
201 AddSameCenterConstraints(faviconView, cell.faviconViewContainer);
202
203 cell.textLabel.text = self.text;
204 cell.detailTextLabel.text = self.detailText;
205 cell.timeLabel.text = self.timeText;
206 cell.isAccessibilityElement = YES;
207 cell.accessibilityCustomActions = self.accessibilityActions;
208 cell.accessibilityLabel =
209 l10n_util::GetNSStringF(IDS_HISTORY_ENTRY_ACCESSIBILITY_LABEL,
210 base::SysNSStringToUTF16(self.text),
211 base::SysNSStringToUTF16(self.detailText),
212 base::SysNSStringToUTF16(self.timeText));
213 }
214
215 - (void)faviconViewProviderFaviconDidLoad:(FaviconViewProvider*)provider {
216 [_delegate historyEntryItemShouldUpdateView:self];
217 }
218
219 @end
220
221 #pragma mark - HistoryEntryCell
222
223 @interface HistoryEntryCell () {
224 // Property releaser for HistoryEntryCell.
225 base::mac::ObjCPropertyReleaser _propertyReleaser_HistoryEntryCell;
226 }
227
228 // Redeclare as readwrite to allow property releaser to handle these properties.
229 @property(nonatomic, readwrite, retain) UILabel* textLabel;
230 @property(nonatomic, readwrite, retain) UILabel* detailTextLabel;
231 @property(nonatomic, readwrite, retain) UILabel* timeLabel;
232 @end
233
234 @implementation HistoryEntryCell
235
236 @synthesize faviconViewContainer = _faviconViewContainer;
237 @synthesize textLabel = _textLabel;
238 @synthesize detailTextLabel = _detailTextLabel;
239 @synthesize timeLabel = _timeLabel;
240
241 - (id)initWithFrame:(CGRect)frame {
242 self = [super initWithFrame:frame];
243 if (self) {
244 _propertyReleaser_HistoryEntryCell.Init(self, [HistoryEntryCell class]);
245
246 _faviconViewContainer = [[UIView alloc] initWithFrame:CGRectZero];
247
248 _textLabel = [[UILabel alloc] initWithFrame:CGRectZero];
249 [_textLabel
250 setFont:[[MDFRobotoFontLoader sharedInstance] mediumFontOfSize:16]];
251 [_textLabel setTextColor:[[MDCPalette greyPalette] tint900]];
252
253 _detailTextLabel = [[UILabel alloc] initWithFrame:CGRectZero];
254 [_detailTextLabel
255 setFont:[[MDFRobotoFontLoader sharedInstance] regularFontOfSize:14]];
256 [_detailTextLabel setTextColor:[[MDCPalette greyPalette] tint600]];
257
258 _timeLabel = [[UILabel alloc] initWithFrame:CGRectZero];
259 [_timeLabel
260 setFont:[[MDFRobotoFontLoader sharedInstance] mediumFontOfSize:14]];
261 [_timeLabel setTextColor:[[MDCPalette greyPalette] tint600]];
262 _timeLabel.textAlignment =
263 UseRTLLayout() ? NSTextAlignmentLeft : NSTextAlignmentRight;
264
265 UIView* contentView = self.contentView;
266 [contentView addSubview:_faviconViewContainer];
267 [contentView addSubview:_textLabel];
268 [contentView addSubview:_detailTextLabel];
269 [contentView addSubview:_timeLabel];
270
271 [_faviconViewContainer setTranslatesAutoresizingMaskIntoConstraints:NO];
272 [_textLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
273 [_detailTextLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
274 [_timeLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
275
276 [_faviconViewContainer.widthAnchor constraintEqualToConstant:kFaviconSize];
277
278 NSDictionary* views = @{
279 @"title" : _textLabel,
280 @"URL" : _detailTextLabel,
281 @"time" : _timeLabel,
282 @"favicon" : _faviconViewContainer,
283 };
284 NSDictionary* metrics = @{
285 @"margin" : @(kMargin),
286 @"spacing" : @(kHeaderMargin - (kMargin + kFaviconSize)),
287 };
288 NSArray* constraints = @[
289 @"H:|-margin-[favicon]-spacing-[title]-[time]-margin-|",
290 @"H:|-margin-[favicon]-spacing-[URL]-margin-|",
291 @"V:|-margin-[title][URL]-margin-|",
292 ];
293 ApplyVisualConstraintsWithMetrics(constraints, views, metrics);
294 AddSameCenterYConstraint(_textLabel, _timeLabel);
295 AddSameCenterYConstraint(_faviconViewContainer, _textLabel);
296
297 [_timeLabel
298 setContentCompressionResistancePriority:UILayoutPriorityRequired
299 forAxis:
300 UILayoutConstraintAxisHorizontal];
301 }
302 return self;
303 }
304
305 - (void)prepareForReuse {
306 [super prepareForReuse];
307 _textLabel.text = nil;
308 _detailTextLabel.text = nil;
309 _timeLabel.text = nil;
310 for (UIView* subview in _faviconViewContainer.subviews) {
311 [subview removeFromSuperview];
312 }
313 }
314
315 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/history/history_entry_item.h ('k') | ios/chrome/browser/ui/history/history_entry_item_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698