Chromium Code Reviews| Index: ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.mm |
| diff --git a/ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.mm b/ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.mm |
| index fade9f30af58ed9a648d0c6941780f080649daef..a9e3bc71a7d5bcbafc817f84bd7dab1046806448 100644 |
| --- a/ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.mm |
| +++ b/ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.mm |
| @@ -4,41 +4,190 @@ |
| #import "ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.h" |
| +#include <objc/runtime.h> |
| + |
| +#import "ios/clean/chrome/browser/ui/commands/context_menu_commands.h" |
| #import "ios/clean/chrome/browser/ui/context_menu/context_menu_consumer.h" |
| +#import "ios/web/public/url_scheme_util.h" |
| #import "ios/web/public/web_state/context_menu_params.h" |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| -@interface ContextMenuMediator () |
| -@property(nonatomic, weak) id<ContextMenuConsumer> consumer; |
| +@interface ContextMenuMediator () { |
| + // Backing object for |params|. |
| + web::ContextMenuParams _params; |
|
marq (ping after 24h)
2017/05/04 09:41:28
Why doesn't property autosynthesis take care of th
kkhorimoto
2017/05/05 05:17:54
I'm doing something similar for the new ContextMen
|
| +} |
| + |
| +// The consumer for context menu functionality mediated by this class. |
| +@property(nonatomic, readonly, weak) id<ContextMenuConsumer> consumer; |
| +// The ContextMenuParams passed on initialization. |
| +@property(nonatomic, readonly) web::ContextMenuParams& params; |
| +// Whether this context menu is for an Incognito browser. |
| +@property(nonatomic, readonly, getter=isIncognito) BOOL incognito; |
| + |
| +// Updates |consumer| using the data from |params|. |
| +- (void)updateConsumer; |
| + |
| +// Creates an NSInvocation from one of the ContextMenuCommands navigaiton |
| +// selectors, using |URL| as the input parameter. |
| +- (NSInvocation*)newContextMenuCommandWithSelector:(SEL)selector URL:(GURL&)URL; |
| + |
| +// ContextMenuItem factory methods. Each method corresponds to a command in |
| +// ContextMenuCommands. The methods will return a ContextMenuItem if its |
| +// corresponding command is appropriate for |params|, or nil otherwise. |
| +- (ContextMenuItem*)newOpenJavaScriptItem; |
| +- (ContextMenuItem*)newOpenInNewTabItem; |
| +- (ContextMenuItem*)newOpenInNewIncognitoTabItem; |
| +- (ContextMenuItem*)newCopyURLItem; |
| +- (ContextMenuItem*)newSaveImageItem; |
| +- (ContextMenuItem*)newOpenImageItem; |
| +- (ContextMenuItem*)newOpenImageInNewTabItem; |
| + |
| @end |
| @implementation ContextMenuMediator |
| @synthesize consumer = _consumer; |
| +@synthesize incognito = _incognito; |
| -- (instancetype)initWithConsumer:(id<ContextMenuConsumer>)consumer { |
| +- (instancetype)initWithConsumer:(id<ContextMenuConsumer>)consumer |
| + contextMenuParams:(const web::ContextMenuParams&)params |
| + isIncognito:(BOOL)isIncognito { |
| if ((self = [super init])) { |
| _consumer = consumer; |
| + _params = params; |
| + _incognito = isIncognito; |
| [self updateConsumer]; |
| } |
| return self; |
| } |
| -// Update the consumer. |
| +#pragma mark - Accessors |
| + |
| +- (web::ContextMenuParams&)params { |
| + return _params; |
| +} |
| + |
| +#pragma mark - |
| + |
| - (void)updateConsumer { |
| - // PLACEHOLDER. Fake title. |
| - [self.consumer setContextMenuTitle:@"http://some/link.html"]; |
| + // Use the menu title provided by |params|. |
| + [self.consumer setContextMenuTitle:self.params.menu_title]; |
| + |
| + // Create context menu items. |
| NSMutableArray<ContextMenuItem*>* items = |
| [[NSMutableArray<ContextMenuItem*> alloc] init]; |
| - |
| - // PLACEHOLDER. Two non-functional items. |
| - [items |
| - addObject:[ContextMenuItem itemWithTitle:@"Open in New Tab" command:nil]]; |
| - [items |
| - addObject:[ContextMenuItem itemWithTitle:@"Copy Link URL" command:nil]]; |
| + ContextMenuItem* item = nil; |
| + if ((item = [self newOpenJavaScriptItem])) |
| + [items addObject:item]; |
| + if ((item = [self newOpenInNewTabItem])) |
| + [items addObject:item]; |
| + if ((item = [self newOpenInNewIncognitoTabItem])) |
| + [items addObject:item]; |
| + if ((item = [self newCopyURLItem])) |
| + [items addObject:item]; |
| + if ((item = [self newSaveImageItem])) |
| + [items addObject:item]; |
| + if ((item = [self newOpenImageItem])) |
| + [items addObject:item]; |
| + if ((item = [self newOpenImageInNewTabItem])) |
| + [items addObject:item]; |
| [self.consumer setContextMenuItems:[items copy]]; |
| } |
| +- (NSInvocation*)newContextMenuCommandWithSelector:(SEL)selector |
| + URL:(GURL&)URL { |
| + struct objc_method_description methodDescription = |
| + protocol_getMethodDescription(@protocol(ContextMenuCommands), selector, |
| + YES /* isRequiredMethod */, |
| + YES /* isInstanceMethod */); |
| + NSMethodSignature* signature = |
| + [NSMethodSignature signatureWithObjCTypes:methodDescription.types]; |
| + NSInvocation* command = |
| + [NSInvocation invocationWithMethodSignature:signature]; |
| + command.selector = selector; |
| + // NSInvocation's |-setArgument:atIndex:| does not work properly for copying |
| + // C++ objects or C++ object references, so the URL is passed by pointer. |
|
kkhorimoto
2017/05/04 05:38:01
I know that you want to use NSInvocations here to
marq (ping after 24h)
2017/05/04 09:41:28
There are a couple of alternatives.
(1) Don't use
kkhorimoto
2017/05/05 05:17:54
I went with approach (1). Instead of NSInvocation
|
| + GURL* URLPtr = &URL; |
| + [command setArgument:&URLPtr atIndex:2]; |
| + return command; |
| +} |
| + |
| +- (ContextMenuItem*)newOpenJavaScriptItem { |
| + GURL& URL = self.params.link_url; |
| + if (!URL.is_valid() || !URL.SchemeIs(url::kJavaScriptScheme)) |
| + return nil; |
| + NSString* title = @"Open JavaScript"; |
| + NSInvocation* command = |
| + [self newContextMenuCommandWithSelector:@selector(openJavaScriptURL:) |
| + URL:URL]; |
| + return [ContextMenuItem itemWithTitle:title command:command]; |
| +} |
| + |
| +- (ContextMenuItem*)newOpenInNewTabItem { |
| + GURL& URL = self.params.link_url; |
| + if (!URL.is_valid() || !web::UrlHasWebScheme(URL)) |
| + return nil; |
| + NSString* title = @"Open In New Tab"; |
| + NSInvocation* command = |
| + [self newContextMenuCommandWithSelector:@selector(openURLInNewTab:) |
| + URL:URL]; |
| + return [ContextMenuItem itemWithTitle:title command:command]; |
| +} |
| + |
| +- (ContextMenuItem*)newOpenInNewIncognitoTabItem { |
| + GURL& URL = self.params.link_url; |
| + if (!URL.is_valid() || !web::UrlHasWebScheme(URL) || self.incognito) |
| + return nil; |
| + NSString* title = @"Open In New Incognito Tab"; |
| + NSInvocation* command = [self |
| + newContextMenuCommandWithSelector:@selector(openURLInNewIncognitoTab:) |
| + URL:URL]; |
| + return [ContextMenuItem itemWithTitle:title command:command]; |
| +} |
| + |
| +- (ContextMenuItem*)newCopyURLItem { |
| + GURL& URL = self.params.link_url; |
| + if (!URL.is_valid() || !web::UrlHasWebScheme(URL)) |
| + return nil; |
| + NSString* title = @"Copy Link"; |
| + NSInvocation* command = |
| + [self newContextMenuCommandWithSelector:@selector(copyURL:) URL:URL]; |
| + return [ContextMenuItem itemWithTitle:title command:command]; |
| +} |
| + |
| +- (ContextMenuItem*)newSaveImageItem { |
| + GURL& imageURL = self.params.src_url; |
| + if (!imageURL.is_valid()) |
| + return nil; |
| + NSString* title = @"Save Image"; |
| + NSInvocation* command = |
| + [self newContextMenuCommandWithSelector:@selector(saveImageAtURL:) |
| + URL:imageURL]; |
| + return [ContextMenuItem itemWithTitle:title command:command]; |
| +} |
| + |
| +- (ContextMenuItem*)newOpenImageItem { |
| + GURL& imageURL = self.params.src_url; |
| + if (!imageURL.is_valid()) |
| + return nil; |
| + NSString* title = @"Open Image"; |
| + NSInvocation* command = |
| + [self newContextMenuCommandWithSelector:@selector(openImageAtURL:) |
| + URL:imageURL]; |
| + return [ContextMenuItem itemWithTitle:title command:command]; |
| +} |
| + |
| +- (ContextMenuItem*)newOpenImageInNewTabItem { |
| + GURL& imageURL = self.params.src_url; |
| + if (!imageURL.is_valid()) |
| + return nil; |
| + NSString* title = @"Open Image In New Tab"; |
| + NSInvocation* command = |
| + [self newContextMenuCommandWithSelector:@selector(openImageAtURLInNewTab:) |
| + URL:imageURL]; |
| + return [ContextMenuItem itemWithTitle:title command:command]; |
| +} |
| + |
| @end |