Chromium Code Reviews| Index: ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.mm |
| diff --git a/ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.mm b/ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.mm |
| index 4178094ccbf8eccadbcfa3b405c446ce6e7a5c3b..d1d120a79866e35e1cdf9bcc43c2e2170db9c7f7 100644 |
| --- a/ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.mm |
| +++ b/ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.mm |
| @@ -4,6 +4,9 @@ |
| #import "ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.h" |
| +#include "base/logging.h" |
| +#import "ios/clean/chrome/browser/ui/context_menu/context_menu_context.h" |
| + |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| @@ -11,22 +14,44 @@ |
| namespace { |
| // Typedef the block parameter for UIAlertAction for readability. |
| typedef void (^AlertActionHandler)(UIAlertAction*); |
| +// Sends |commands| to |dispatcher| using |context| as the menu context. |
| +void DispatchContextMenuCommands(const std::vector<SEL>& commands, |
| + id dispatcher, |
| + ContextMenuContext* context) { |
| + DCHECK(dispatcher); |
| + DCHECK(context); |
| + for (SEL command : commands) { |
| + IMP command_imp = [dispatcher methodForSelector:command]; |
| + DCHECK(command_imp); |
| + command_imp(dispatcher, command, context); |
|
marq (ping after 24h)
2017/05/31 12:26:09
Why not -performSelector:withObject: ?
(my concer
kkhorimoto
2017/05/31 18:00:20
|-performSelector:withObject| doesn't compile unde
|
| + } |
| +} |
| } |
| @interface ContextMenuViewController () |
| -// Object to which command messages will be sent. |
| -@property(nonatomic, weak) id dispatcher; |
| +// The dispatcher passed on initialization. |
| +@property(nonatomic, readonly, weak) id<ContextMenuCommands> dispatcher; |
| +// The context passed on initialization. |
| +@property(nonatomic, strong) ContextMenuContext* context; |
| + |
| +// Creates an UIAlertAction for |item| using |style| to manage the action's |
| +// appearance. |
| +- (UIAlertAction*)alertActionForItem:(ContextMenuItem*)item |
| + style:(UIAlertActionStyle)style; |
| + |
| @end |
| @implementation ContextMenuViewController |
| @synthesize dispatcher = _dispatcher; |
| +@synthesize context = _context; |
| -- (instancetype)initWithDispatcher:(id)dispatcher { |
| +- (instancetype)initWithDispatcher:(id<ContextMenuCommands>)dispatcher { |
| self = |
| [[self class] alertControllerWithTitle:nil |
| message:nil |
| preferredStyle:UIAlertControllerStyleActionSheet]; |
| if (self) { |
| + DCHECK(dispatcher); |
| _dispatcher = dispatcher; |
| } |
| return self; |
| @@ -34,26 +59,36 @@ - (instancetype)initWithDispatcher:(id)dispatcher { |
| #pragma mark - ContextMenuConsumer |
| +- (void)setContextMenuContext:(ContextMenuContext*)context { |
| + DCHECK(context); |
| + self.context = context; |
| +} |
| + |
| - (void)setContextMenuTitle:(NSString*)title { |
| self.title = title; |
| } |
| -- (void)setContextMenuItems:(NSArray<ContextMenuItem*>*)items { |
| +- (void)setContextMenuItems:(NSArray<ContextMenuItem*>*)items |
| + cancelItem:(ContextMenuItem*)cancelItem { |
| + // Add an alert action for each item in |items|, then add |cancelItem|. |
| for (ContextMenuItem* item in items) { |
| - // Create a block that sends the invocation passed in with the item's |
| - // configuration to the dispatcher. |
| - AlertActionHandler handler = ^(UIAlertAction* action) { |
| - [item.command invokeWithTarget:self.dispatcher]; |
| - }; |
| - [self addAction:[UIAlertAction actionWithTitle:item.title |
| - style:UIAlertActionStyleDefault |
| - handler:handler]]; |
| + [self addAction:[self alertActionForItem:item |
| + style:UIAlertActionStyleDefault]]; |
| } |
| + [self addAction:[self alertActionForItem:cancelItem |
| + style:UIAlertActionStyleCancel]]; |
| +} |
| + |
| +#pragma mark - |
| - // Always add a cancel action. |
| - [self addAction:[UIAlertAction actionWithTitle:@"Cancel" |
| - style:UIAlertActionStyleCancel |
| - handler:nil]]; |
| +- (UIAlertAction*)alertActionForItem:(ContextMenuItem*)item |
| + style:(UIAlertActionStyle)style { |
| + DCHECK(item); |
| + // Create a block that dispatches |item|'s ContextMenuCommands. |
| + AlertActionHandler handler = ^(UIAlertAction* action) { |
| + DispatchContextMenuCommands(item.commands, self.dispatcher, self.context); |
| + }; |
| + return [UIAlertAction actionWithTitle:item.title style:style handler:handler]; |
| } |
| @end |