Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.h" | 5 #import "ios/clean/chrome/browser/ui/context_menu/context_menu_mediator.h" |
| 6 | 6 |
| 7 #include <objc/runtime.h> | |
| 8 | |
| 9 #import "ios/clean/chrome/browser/ui/commands/context_menu_commands.h" | |
| 7 #import "ios/clean/chrome/browser/ui/context_menu/context_menu_consumer.h" | 10 #import "ios/clean/chrome/browser/ui/context_menu/context_menu_consumer.h" |
| 11 #import "ios/web/public/url_scheme_util.h" | |
| 8 #import "ios/web/public/web_state/context_menu_params.h" | 12 #import "ios/web/public/web_state/context_menu_params.h" |
| 9 | 13 |
| 10 #if !defined(__has_feature) || !__has_feature(objc_arc) | 14 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 11 #error "This file requires ARC support." | 15 #error "This file requires ARC support." |
| 12 #endif | 16 #endif |
| 13 | 17 |
| 14 @interface ContextMenuMediator () | 18 @interface ContextMenuMediator () { |
| 15 @property(nonatomic, weak) id<ContextMenuConsumer> consumer; | 19 // Backing object for |params|. |
| 20 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
| |
| 21 } | |
| 22 | |
| 23 // The consumer for context menu functionality mediated by this class. | |
| 24 @property(nonatomic, readonly, weak) id<ContextMenuConsumer> consumer; | |
| 25 // The ContextMenuParams passed on initialization. | |
| 26 @property(nonatomic, readonly) web::ContextMenuParams& params; | |
| 27 // Whether this context menu is for an Incognito browser. | |
| 28 @property(nonatomic, readonly, getter=isIncognito) BOOL incognito; | |
| 29 | |
| 30 // Updates |consumer| using the data from |params|. | |
| 31 - (void)updateConsumer; | |
| 32 | |
| 33 // Creates an NSInvocation from one of the ContextMenuCommands navigaiton | |
| 34 // selectors, using |URL| as the input parameter. | |
| 35 - (NSInvocation*)newContextMenuCommandWithSelector:(SEL)selector URL:(GURL&)URL; | |
| 36 | |
| 37 // ContextMenuItem factory methods. Each method corresponds to a command in | |
| 38 // ContextMenuCommands. The methods will return a ContextMenuItem if its | |
| 39 // corresponding command is appropriate for |params|, or nil otherwise. | |
| 40 - (ContextMenuItem*)newOpenJavaScriptItem; | |
| 41 - (ContextMenuItem*)newOpenInNewTabItem; | |
| 42 - (ContextMenuItem*)newOpenInNewIncognitoTabItem; | |
| 43 - (ContextMenuItem*)newCopyURLItem; | |
| 44 - (ContextMenuItem*)newSaveImageItem; | |
| 45 - (ContextMenuItem*)newOpenImageItem; | |
| 46 - (ContextMenuItem*)newOpenImageInNewTabItem; | |
| 47 | |
| 16 @end | 48 @end |
| 17 | 49 |
| 18 @implementation ContextMenuMediator | 50 @implementation ContextMenuMediator |
| 19 @synthesize consumer = _consumer; | 51 @synthesize consumer = _consumer; |
| 52 @synthesize incognito = _incognito; | |
| 20 | 53 |
| 21 - (instancetype)initWithConsumer:(id<ContextMenuConsumer>)consumer { | 54 - (instancetype)initWithConsumer:(id<ContextMenuConsumer>)consumer |
| 55 contextMenuParams:(const web::ContextMenuParams&)params | |
| 56 isIncognito:(BOOL)isIncognito { | |
| 22 if ((self = [super init])) { | 57 if ((self = [super init])) { |
| 23 _consumer = consumer; | 58 _consumer = consumer; |
| 59 _params = params; | |
| 60 _incognito = isIncognito; | |
| 24 [self updateConsumer]; | 61 [self updateConsumer]; |
| 25 } | 62 } |
| 26 return self; | 63 return self; |
| 27 } | 64 } |
| 28 | 65 |
| 29 // Update the consumer. | 66 #pragma mark - Accessors |
| 67 | |
| 68 - (web::ContextMenuParams&)params { | |
| 69 return _params; | |
| 70 } | |
| 71 | |
| 72 #pragma mark - | |
| 73 | |
| 30 - (void)updateConsumer { | 74 - (void)updateConsumer { |
| 31 // PLACEHOLDER. Fake title. | 75 // Use the menu title provided by |params|. |
| 32 [self.consumer setContextMenuTitle:@"http://some/link.html"]; | 76 [self.consumer setContextMenuTitle:self.params.menu_title]; |
| 77 | |
| 78 // Create context menu items. | |
| 33 NSMutableArray<ContextMenuItem*>* items = | 79 NSMutableArray<ContextMenuItem*>* items = |
| 34 [[NSMutableArray<ContextMenuItem*> alloc] init]; | 80 [[NSMutableArray<ContextMenuItem*> alloc] init]; |
| 35 | 81 ContextMenuItem* item = nil; |
| 36 // PLACEHOLDER. Two non-functional items. | 82 if ((item = [self newOpenJavaScriptItem])) |
| 37 [items | 83 [items addObject:item]; |
| 38 addObject:[ContextMenuItem itemWithTitle:@"Open in New Tab" command:nil]]; | 84 if ((item = [self newOpenInNewTabItem])) |
| 39 [items | 85 [items addObject:item]; |
| 40 addObject:[ContextMenuItem itemWithTitle:@"Copy Link URL" command:nil]]; | 86 if ((item = [self newOpenInNewIncognitoTabItem])) |
| 87 [items addObject:item]; | |
| 88 if ((item = [self newCopyURLItem])) | |
| 89 [items addObject:item]; | |
| 90 if ((item = [self newSaveImageItem])) | |
| 91 [items addObject:item]; | |
| 92 if ((item = [self newOpenImageItem])) | |
| 93 [items addObject:item]; | |
| 94 if ((item = [self newOpenImageInNewTabItem])) | |
| 95 [items addObject:item]; | |
| 41 [self.consumer setContextMenuItems:[items copy]]; | 96 [self.consumer setContextMenuItems:[items copy]]; |
| 42 } | 97 } |
| 43 | 98 |
| 99 - (NSInvocation*)newContextMenuCommandWithSelector:(SEL)selector | |
| 100 URL:(GURL&)URL { | |
| 101 struct objc_method_description methodDescription = | |
| 102 protocol_getMethodDescription(@protocol(ContextMenuCommands), selector, | |
| 103 YES /* isRequiredMethod */, | |
| 104 YES /* isInstanceMethod */); | |
| 105 NSMethodSignature* signature = | |
| 106 [NSMethodSignature signatureWithObjCTypes:methodDescription.types]; | |
| 107 NSInvocation* command = | |
| 108 [NSInvocation invocationWithMethodSignature:signature]; | |
| 109 command.selector = selector; | |
| 110 // NSInvocation's |-setArgument:atIndex:| does not work properly for copying | |
| 111 // 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
| |
| 112 GURL* URLPtr = &URL; | |
| 113 [command setArgument:&URLPtr atIndex:2]; | |
| 114 return command; | |
| 115 } | |
| 116 | |
| 117 - (ContextMenuItem*)newOpenJavaScriptItem { | |
| 118 GURL& URL = self.params.link_url; | |
| 119 if (!URL.is_valid() || !URL.SchemeIs(url::kJavaScriptScheme)) | |
| 120 return nil; | |
| 121 NSString* title = @"Open JavaScript"; | |
| 122 NSInvocation* command = | |
| 123 [self newContextMenuCommandWithSelector:@selector(openJavaScriptURL:) | |
| 124 URL:URL]; | |
| 125 return [ContextMenuItem itemWithTitle:title command:command]; | |
| 126 } | |
| 127 | |
| 128 - (ContextMenuItem*)newOpenInNewTabItem { | |
| 129 GURL& URL = self.params.link_url; | |
| 130 if (!URL.is_valid() || !web::UrlHasWebScheme(URL)) | |
| 131 return nil; | |
| 132 NSString* title = @"Open In New Tab"; | |
| 133 NSInvocation* command = | |
| 134 [self newContextMenuCommandWithSelector:@selector(openURLInNewTab:) | |
| 135 URL:URL]; | |
| 136 return [ContextMenuItem itemWithTitle:title command:command]; | |
| 137 } | |
| 138 | |
| 139 - (ContextMenuItem*)newOpenInNewIncognitoTabItem { | |
| 140 GURL& URL = self.params.link_url; | |
| 141 if (!URL.is_valid() || !web::UrlHasWebScheme(URL) || self.incognito) | |
| 142 return nil; | |
| 143 NSString* title = @"Open In New Incognito Tab"; | |
| 144 NSInvocation* command = [self | |
| 145 newContextMenuCommandWithSelector:@selector(openURLInNewIncognitoTab:) | |
| 146 URL:URL]; | |
| 147 return [ContextMenuItem itemWithTitle:title command:command]; | |
| 148 } | |
| 149 | |
| 150 - (ContextMenuItem*)newCopyURLItem { | |
| 151 GURL& URL = self.params.link_url; | |
| 152 if (!URL.is_valid() || !web::UrlHasWebScheme(URL)) | |
| 153 return nil; | |
| 154 NSString* title = @"Copy Link"; | |
| 155 NSInvocation* command = | |
| 156 [self newContextMenuCommandWithSelector:@selector(copyURL:) URL:URL]; | |
| 157 return [ContextMenuItem itemWithTitle:title command:command]; | |
| 158 } | |
| 159 | |
| 160 - (ContextMenuItem*)newSaveImageItem { | |
| 161 GURL& imageURL = self.params.src_url; | |
| 162 if (!imageURL.is_valid()) | |
| 163 return nil; | |
| 164 NSString* title = @"Save Image"; | |
| 165 NSInvocation* command = | |
| 166 [self newContextMenuCommandWithSelector:@selector(saveImageAtURL:) | |
| 167 URL:imageURL]; | |
| 168 return [ContextMenuItem itemWithTitle:title command:command]; | |
| 169 } | |
| 170 | |
| 171 - (ContextMenuItem*)newOpenImageItem { | |
| 172 GURL& imageURL = self.params.src_url; | |
| 173 if (!imageURL.is_valid()) | |
| 174 return nil; | |
| 175 NSString* title = @"Open Image"; | |
| 176 NSInvocation* command = | |
| 177 [self newContextMenuCommandWithSelector:@selector(openImageAtURL:) | |
| 178 URL:imageURL]; | |
| 179 return [ContextMenuItem itemWithTitle:title command:command]; | |
| 180 } | |
| 181 | |
| 182 - (ContextMenuItem*)newOpenImageInNewTabItem { | |
| 183 GURL& imageURL = self.params.src_url; | |
| 184 if (!imageURL.is_valid()) | |
| 185 return nil; | |
| 186 NSString* title = @"Open Image In New Tab"; | |
| 187 NSInvocation* command = | |
| 188 [self newContextMenuCommandWithSelector:@selector(openImageAtURLInNewTab:) | |
| 189 URL:imageURL]; | |
| 190 return [ContextMenuItem itemWithTitle:title command:command]; | |
| 191 } | |
| 192 | |
| 44 @end | 193 @end |
| OLD | NEW |