blob: f5f833b5c320c3346f4446b93b7acc1934a63d91 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/menu/action_factory.h"
#import "base/metrics/histogram_functions.h"
#import "base/metrics/user_metrics.h"
#import "ios/chrome/browser/shared/public/commands/application_commands.h"
#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/shared/ui/symbols/symbols.h"
#import "ios/chrome/browser/shared/ui/util/pasteboard_util.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ui/base/l10n/l10n_util_mac.h"
#import "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface ActionFactory ()
// Histogram to record executed actions.
@property(nonatomic, assign) const char* histogram;
@end
@implementation ActionFactory
- (instancetype)initWithScenario:(MenuScenarioHistogram)scenario {
if (self = [super init]) {
_histogram = GetActionsHistogramName(scenario);
}
return self;
}
- (UIAction*)actionWithTitle:(NSString*)title
image:(UIImage*)image
type:(MenuActionType)type
block:(ProceduralBlock)block {
// Capture only the histogram name's pointer to be copied by the block.
const char* histogram = self.histogram;
return [UIAction actionWithTitle:title
image:image
identifier:nil
handler:^(UIAction* action) {
base::UmaHistogramEnumeration(histogram, type);
if (block) {
block();
}
}];
}
- (UIAction*)actionToCopyURL:(const GURL)URL {
UIImage* image =
DefaultSymbolWithPointSize(kLinkActionSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_COPY_LINK_ACTION_TITLE)
image:image
type:MenuActionType::CopyURL
block:^{
StoreURLInPasteboard(URL);
}];
}
- (UIAction*)actionToShareWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kShareSymbol, kSymbolActionPointSize);
return
[self actionWithTitle:l10n_util::GetNSString(IDS_IOS_SHARE_BUTTON_LABEL)
image:image
type:MenuActionType::Share
block:block];
}
- (UIAction*)actionToPinTabWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kPinSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_PINTAB)
image:image
type:MenuActionType::PinTab
block:block];
}
- (UIAction*)actionToUnpinTabWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kPinSlashSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_UNPINTAB)
image:image
type:MenuActionType::UnpinTab
block:block];
}
- (UIAction*)actionToDeleteWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kDeleteActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(IDS_IOS_DELETE_ACTION_TITLE)
image:image
type:MenuActionType::Delete
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToOpenInNewTabWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kNewTabActionSymbol, kSymbolActionPointSize);
ProceduralBlock completionBlock =
[self recordMobileWebContextMenuOpenTabActionWithBlock:block];
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)
image:image
type:MenuActionType::OpenInNewTab
block:completionBlock];
}
- (UIAction*)actionToOpenAllTabsWithBlock:(ProceduralBlock)block {
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_OPEN_ALL_LINKS)
image:DefaultSymbolWithPointSize(
kPlusSymbol, kSymbolActionPointSize)
type:MenuActionType::OpenAllInNewTabs
block:block];
}
- (UIAction*)actionToRemoveWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kHideActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(IDS_IOS_REMOVE_ACTION_TITLE)
image:image
type:MenuActionType::Remove
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToEditWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kEditActionSymbol, kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(IDS_IOS_EDIT_ACTION_TITLE)
image:image
type:MenuActionType::Edit
block:block];
}
- (UIAction*)actionToHideWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kHideActionSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_RECENT_TABS_HIDE_MENU_OPTION)
image:image
type:MenuActionType::Hide
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToMoveFolderWithBlock:(ProceduralBlock)block {
// Use multi color to make sure the arrow is visible.
UIImage* image = MakeSymbolMulticolor(
CustomSymbolWithPointSize(kMoveFolderSymbol, kSymbolActionPointSize));
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_CONTEXT_MENU_MOVE)
image:image
type:MenuActionType::Move
block:block];
}
- (UIAction*)actionToMarkAsReadWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kMarkAsReadActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_READING_LIST_MARK_AS_READ_ACTION)
image:image
type:MenuActionType::Read
block:block];
}
- (UIAction*)actionToMarkAsUnreadWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kMarkAsUnreadActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_READING_LIST_MARK_AS_UNREAD_ACTION)
image:image
type:MenuActionType::Unread
block:block];
}
- (UIAction*)actionToOpenOfflineVersionInNewTabWithBlock:
(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kCheckmarkCircleSymbol,
kSymbolActionPointSize);
ProceduralBlock completionBlock =
[self recordMobileWebContextMenuOpenTabActionWithBlock:block];
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_READING_LIST_OPEN_OFFLINE_BUTTON)
image:image
type:MenuActionType::ViewOffline
block:completionBlock];
}
- (UIAction*)actionToAddToReadingListWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kReadLaterActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)
image:image
type:MenuActionType::AddToReadingList
block:block];
}
- (UIAction*)actionToBookmarkWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kAddBookmarkActionSymbol,
kSymbolActionPointSize);
return [self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS)
image:image
type:MenuActionType::AddToBookmarks
block:block];
}
- (UIAction*)actionToEditBookmarkWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kEditActionSymbol, kSymbolActionPointSize);
return [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_BOOKMARK_CONTEXT_MENU_EDIT)
image:image
type:MenuActionType::EditBookmark
block:block];
}
- (UIAction*)actionToCloseRegularTabWithBlock:(ProceduralBlock)block {
NSString* title = l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSETAB);
return [self actionToCloseTabWithTitle:title block:block];
}
- (UIAction*)actionToClosePinnedTabWithBlock:(ProceduralBlock)block {
NSString* title =
l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSEPINNEDTAB);
return [self actionToCloseTabWithTitle:title block:block];
}
- (UIAction*)actionSaveImageWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kSaveImageActionSymbol,
kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_SAVEIMAGE)
image:image
type:MenuActionType::SaveImage
block:block];
return action;
}
- (UIAction*)actionCopyImageWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kCopyActionSymbol, kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_COPYIMAGE)
image:image
type:MenuActionType::CopyImage
block:block];
return action;
}
- (UIAction*)actionSearchImageWithTitle:(NSString*)title
Block:(ProceduralBlock)block {
UIImage* image = CustomSymbolWithPointSize(kPhotoBadgeMagnifyingglassSymbol,
kSymbolActionPointSize);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::SearchImage
block:block];
return action;
}
- (UIAction*)actionToCloseAllTabsWithBlock:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kXMarkSymbol, kSymbolActionPointSize);
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_CLOSEALLTABS)
image:image
type:MenuActionType::CloseAllTabs
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
- (UIAction*)actionToSelectTabsWithBlock:(ProceduralBlock)block {
UIImage* image = DefaultSymbolWithPointSize(kCheckmarkCircleSymbol,
kSymbolActionPointSize);
UIAction* action = [self
actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_SELECTTABS)
image:image
type:MenuActionType::SelectTabs
block:block];
return action;
}
- (UIAction*)actionToSearchImageUsingLensWithBlock:(ProceduralBlock)block {
UIImage* image =
CustomSymbolWithPointSize(kCameraLensSymbol, kSymbolActionPointSize);
int actionTitleMessageId =
base::FeatureList::IsEnabled(kEnableLensContextMenuAltText)
? IDS_IOS_CONTEXT_MENU_SEARCHIMAGEWITHGOOGLE_ALT_TEXT
: IDS_IOS_CONTEXT_MENU_SEARCHIMAGEWITHGOOGLE;
UIAction* action =
[self actionWithTitle:l10n_util::GetNSString(actionTitleMessageId)
image:image
type:MenuActionType::SearchImageWithLens
block:block];
return action;
}
- (ProceduralBlock)recordMobileWebContextMenuOpenTabActionWithBlock:
(ProceduralBlock)block {
return ^{
base::RecordAction(base::UserMetricsAction("MobileWebContextMenuOpenTab"));
if (block) {
block();
}
};
}
#pragma mark - Private
// Creates a UIAction instance for closing a tab with a provided `title`.
- (UIAction*)actionToCloseTabWithTitle:(NSString*)title
block:(ProceduralBlock)block {
UIImage* image =
DefaultSymbolWithPointSize(kXMarkSymbol, kSymbolActionPointSize);
UIAction* action = [self actionWithTitle:title
image:image
type:MenuActionType::CloseTab
block:block];
action.attributes = UIMenuElementAttributesDestructive;
return action;
}
@end