[ios] Adds custom accessibility actions to HistoryEntryItem
- Migrates the code from LegacyHistoryCollectionVC and LegacyHistoryEntryItem into
HistoryTableVC and HistoryEntryItem to add support for custom accessibility actions.
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I73d9a35a31822e98fb09d5828f7eee37211d06d5
Reviewed-on: https://chromium-review.googlesource.com/1125328
Reviewed-by: edchin <edchin@chromium.org>
Commit-Queue: Sergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576174}
diff --git a/ios/chrome/browser/ui/history/history_entry_item.h b/ios/chrome/browser/ui/history/history_entry_item.h
index 3cef1f0f..131b021 100644
--- a/ios/chrome/browser/ui/history/history_entry_item.h
+++ b/ios/chrome/browser/ui/history/history_entry_item.h
@@ -8,10 +8,19 @@
#import "ios/chrome/browser/ui/history/history_entry_item_interface.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
+@protocol HistoryEntryItemDelegate;
+
// Item that display a History entry. A history entry contains the title of the
// website, the URL and a timestamp of a previously visited website.
@interface HistoryEntryItem : TableViewItem<HistoryEntryItemInterface>
+// The |delegate| is used to perform accessibility actions, it might be nil and
+// it will not be retained.
+- (instancetype)initWithType:(NSInteger)type
+ accessibilityDelegate:(id<HistoryEntryItemDelegate>)delegate
+ NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithType:(NSInteger)type NS_UNAVAILABLE;
+
// Identifier to match a URLItem with its URLCell. Uses URL.host() as "unique"
// identifier. Ensures that cell still is displaying item's contents before
// setting favicon in async callback. Even if there is a case of cells with the
diff --git a/ios/chrome/browser/ui/history/history_entry_item.mm b/ios/chrome/browser/ui/history/history_entry_item.mm
index 4357bf5a..866d847 100644
--- a/ios/chrome/browser/ui/history/history_entry_item.mm
+++ b/ios/chrome/browser/ui/history/history_entry_item.mm
@@ -7,8 +7,12 @@
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "components/history/core/browser/browsing_history_service.h"
+#include "components/strings/grit/components_strings.h"
+#import "ios/chrome/browser/ui/history/history_entry_item_delegate.h"
#import "ios/chrome/browser/ui/table_view/cells/table_view_url_item.h"
#import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
+#include "ios/chrome/grit/ios_strings.h"
+#include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
@@ -16,17 +20,28 @@
#pragma mark - HistoryEntryItem
+@interface HistoryEntryItem ()
+// Delegate to perform custom accessibility actions.
+@property(nonatomic, weak) id<HistoryEntryItemDelegate> accessibilityDelegate;
+
+// Custom accessibility actions for the history entry cell.
+- (NSArray*)accessibilityActions;
+@end
+
@implementation HistoryEntryItem
+@synthesize accessibilityDelegate = _accessibilityDelegate;
@synthesize text = _text;
@synthesize detailText = _detailText;
@synthesize timeText = _timeText;
@synthesize URL = _URL;
@synthesize timestamp = _timestamp;
-- (instancetype)initWithType:(NSInteger)type {
+- (instancetype)initWithType:(NSInteger)type
+ accessibilityDelegate:(id<HistoryEntryItemDelegate>)delegate {
self = [super initWithType:type];
if (self) {
self.cellClass = [TableViewURLCell class];
+ _accessibilityDelegate = delegate;
}
return self;
}
@@ -46,13 +61,63 @@
cell.titleLabel.backgroundColor = styler.tableViewBackgroundColor;
cell.URLLabel.backgroundColor = styler.tableViewBackgroundColor;
cell.metadataLabel.backgroundColor = styler.tableViewBackgroundColor;
+ cell.isAccessibilityElement = YES;
+ cell.accessibilityCustomActions = self.accessibilityActions;
}
- (NSString*)uniqueIdentifier {
return base::SysUTF8ToNSString(self.URL.host());
}
-#pragma mark NSObject
+#pragma mark - Accessibility
+
+- (NSArray*)accessibilityActions {
+ UIAccessibilityCustomAction* deleteAction =
+ [[UIAccessibilityCustomAction alloc]
+ initWithName:l10n_util::GetNSString(
+ IDS_HISTORY_ENTRY_ACCESSIBILITY_DELETE)
+ target:self
+ selector:@selector(deleteHistoryEntry)];
+ UIAccessibilityCustomAction* openInNewTabAction =
+ [[UIAccessibilityCustomAction alloc]
+ initWithName:l10n_util::GetNSString(
+ IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)
+ target:self
+ selector:@selector(openInNewTab)];
+ UIAccessibilityCustomAction* openInNewIncognitoTabAction =
+ [[UIAccessibilityCustomAction alloc]
+ initWithName:l10n_util::GetNSString(
+ IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB)
+ target:self
+ selector:@selector(openInNewIncognitoTab)];
+ UIAccessibilityCustomAction* copyURLAction =
+ [[UIAccessibilityCustomAction alloc]
+ initWithName:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_COPY)
+ target:self
+ selector:@selector(copyURL)];
+ return @[
+ deleteAction, openInNewTabAction, openInNewIncognitoTabAction, copyURLAction
+ ];
+}
+
+- (void)deleteHistoryEntry {
+ [self.accessibilityDelegate historyEntryItemDidRequestDelete:self];
+}
+
+- (void)openInNewTab {
+ [self.accessibilityDelegate historyEntryItemDidRequestOpenInNewTab:self];
+}
+
+- (void)openInNewIncognitoTab {
+ [self.accessibilityDelegate
+ historyEntryItemDidRequestOpenInNewIncognitoTab:self];
+}
+
+- (void)copyURL {
+ [self.accessibilityDelegate historyEntryItemDidRequestCopy:self];
+}
+
+#pragma mark - NSObject
- (BOOL)isEqualToHistoryEntryItem:(HistoryEntryItem*)item {
return item && item.URL == _URL && item.timestamp == _timestamp;
diff --git a/ios/chrome/browser/ui/history/history_entry_item_delegate.h b/ios/chrome/browser/ui/history/history_entry_item_delegate.h
index 31774bd..38f274a 100644
--- a/ios/chrome/browser/ui/history/history_entry_item_delegate.h
+++ b/ios/chrome/browser/ui/history/history_entry_item_delegate.h
@@ -5,24 +5,29 @@
#ifndef IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_ITEM_DELEGATE_H_
#define IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_ITEM_DELEGATE_H_
-@class LegacyHistoryEntryItem;
+@class ListItem;
+@protocol HistoryEntryItemInterface;
// Delegate for HistoryEntryItem. Handles actions invoked as custom
// accessibility actions.
@protocol HistoryEntryItemDelegate
// Called when custom accessibility action to delete the entry is invoked.
-- (void)historyEntryItemDidRequestDelete:(LegacyHistoryEntryItem*)item;
+- (void)historyEntryItemDidRequestDelete:
+ (ListItem<HistoryEntryItemInterface>*)item;
// Called when custom accessibility action to open the entry in a new tab is
// invoked.
-- (void)historyEntryItemDidRequestOpenInNewTab:(LegacyHistoryEntryItem*)item;
+- (void)historyEntryItemDidRequestOpenInNewTab:
+ (ListItem<HistoryEntryItemInterface>*)item;
// Called when custom accessibility action to open the entry in a new incognito
// tab is invoked.
- (void)historyEntryItemDidRequestOpenInNewIncognitoTab:
- (LegacyHistoryEntryItem*)item;
+ (ListItem<HistoryEntryItemInterface>*)item;
// Called when custom accessibility action to copy the entry's URL is invoked.
-- (void)historyEntryItemDidRequestCopy:(LegacyHistoryEntryItem*)item;
+- (void)historyEntryItemDidRequestCopy:
+ (ListItem<HistoryEntryItemInterface>*)item;
// Called when the view associated with the HistoryEntryItem should be updated.
-- (void)historyEntryItemShouldUpdateView:(LegacyHistoryEntryItem*)item;
+- (void)historyEntryItemShouldUpdateView:
+ (ListItem<HistoryEntryItemInterface>*)item;
@end
#endif // IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_ITEM_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/history/history_table_view_controller.mm b/ios/chrome/browser/ui/history/history_table_view_controller.mm
index 54a0cb3..e7f0f78 100644
--- a/ios/chrome/browser/ui/history/history_table_view_controller.mm
+++ b/ios/chrome/browser/ui/history/history_table_view_controller.mm
@@ -21,6 +21,7 @@
#import "ios/chrome/browser/ui/history/history_entries_status_item_delegate.h"
#include "ios/chrome/browser/ui/history/history_entry_inserter.h"
#import "ios/chrome/browser/ui/history/history_entry_item.h"
+#import "ios/chrome/browser/ui/history/history_entry_item_delegate.h"
#import "ios/chrome/browser/ui/history/history_image_data_source.h"
#include "ios/chrome/browser/ui/history/history_local_commands.h"
#import "ios/chrome/browser/ui/history/history_ui_constants.h"
@@ -65,6 +66,7 @@
@interface HistoryTableViewController ()<HistoryEntriesStatusItemDelegate,
HistoryEntryInserterDelegate,
+ HistoryEntryItemDelegate,
TableViewTextLinkCellDelegate,
UISearchResultsUpdating,
UISearchBarDelegate> {
@@ -272,7 +274,8 @@
DCHECK([[self tableViewModel] numberOfSections]);
for (const BrowsingHistoryService::HistoryEntry& entry : results) {
HistoryEntryItem* item =
- [[HistoryEntryItem alloc] initWithType:ItemTypeHistoryEntry];
+ [[HistoryEntryItem alloc] initWithType:ItemTypeHistoryEntry
+ accessibilityDelegate:self];
item.text = [history::FormattedTitle(entry.title, entry.url) copy];
item.detailText =
[base::SysUTF8ToNSString(entry.url.GetOrigin().spec()) copy];
@@ -364,8 +367,48 @@
}
#pragma mark HistoryEntryItemDelegate
-// TODO(crbug.com/805190): Migrate once we decide how to handle favicons and the
-// a11y callback on HistoryEntryItem.
+
+- (void)historyEntryItemDidRequestOpen:(HistoryEntryItem*)item {
+ [self openURL:item.URL];
+}
+
+- (void)historyEntryItemDidRequestDelete:(HistoryEntryItem*)item {
+ NSInteger sectionIdentifier =
+ [self.entryInserter sectionIdentifierForTimestamp:item.timestamp];
+ if ([self.tableViewModel hasSectionForSectionIdentifier:sectionIdentifier] &&
+ [self.tableViewModel hasItem:item
+ inSectionWithIdentifier:sectionIdentifier]) {
+ NSIndexPath* indexPath = [self.tableViewModel indexPathForItem:item];
+ [self.tableView selectRowAtIndexPath:indexPath
+ animated:NO
+ scrollPosition:UITableViewScrollPositionNone];
+ [self deleteSelectedItemsFromHistory];
+ }
+}
+
+- (void)historyEntryItemDidRequestCopy:(HistoryEntryItem*)item {
+ StoreURLInPasteboard(item.URL);
+}
+
+- (void)historyEntryItemDidRequestOpenInNewTab:(HistoryEntryItem*)item {
+ [self openURLInNewTab:item.URL];
+}
+
+- (void)historyEntryItemDidRequestOpenInNewIncognitoTab:
+ (HistoryEntryItem*)item {
+ [self openURLInNewIncognitoTab:item.URL];
+}
+
+- (void)historyEntryItemShouldUpdateView:(HistoryEntryItem*)item {
+ NSInteger sectionIdentifier =
+ [self.entryInserter sectionIdentifierForTimestamp:item.timestamp];
+ // If the item is still in the model, reconfigure it.
+ if ([self.tableViewModel hasSectionForSectionIdentifier:sectionIdentifier] &&
+ [self.tableViewModel hasItem:item
+ inSectionWithIdentifier:sectionIdentifier]) {
+ [self reconfigureCellsForItems:@[ item ]];
+ }
+}
#pragma mark TableViewTextLinkCellDelegate