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 |