13cc2abd926996f6747eeef298cd039175cf54af
[WebKit-https.git] / WebKit / WebView.subproj / WebDefaultContextMenuDelegate.m
1 /*
2       WebDefaultContextMenuDelegate.m
3       Copyright 2002, Apple, Inc. All rights reserved.
4 */
5
6 #import <WebKit/WebDefaultContextMenuDelegate.h>
7
8 #import <WebKit/WebAssertions.h>
9 #import <WebKit/DOM.h>
10 #import <WebKit/WebBridge.h>
11 #import <WebKit/WebDataSourcePrivate.h>
12 #import <WebKit/WebDefaultUIDelegate.h>
13 #import <WebKit/WebDOMOperations.h>
14 #import <WebKit/WebFramePrivate.h>
15 #import <WebKit/WebHTMLViewPrivate.h>
16 #import <WebKit/WebLocalizableStrings.h>
17 #import <WebKit/WebNSPasteboardExtras.h>
18 #import <WebKit/WebFrameView.h>
19 #import <WebKit/WebPolicyDelegate.h>
20 #import <WebKit/WebViewPrivate.h>
21 #import <WebKit/WebUIDelegate.h>
22
23 #import <WebCore/WebCoreBridge.h>
24
25 #import <Foundation/NSURLConnection.h>
26 #import <Foundation/NSURLRequest.h>
27 #import <Foundation/NSURLRequestPrivate.h>
28
29 @implementation WebDefaultUIDelegate (WebContextMenu)
30
31 - (NSMenuItem *)menuItemWithTag:(int)tag
32 {
33     NSMenuItem *menuItem = [[[NSMenuItem alloc] init] autorelease];
34     [menuItem setTag:tag];
35     
36     NSString *title = nil;
37     SEL action = NULL;
38     
39     switch(tag) {
40         case WebMenuItemTagOpenLinkInNewWindow:
41             title = UI_STRING("Open Link in New Window", "Open in New Window context menu item");
42             action = @selector(openLinkInNewWindow:);
43             [menuItem setTarget:self];
44             break;
45         case WebMenuItemTagDownloadLinkToDisk:
46             title = UI_STRING("Download Linked File", "Download Linked File context menu item");
47             action = @selector(downloadLinkToDisk:);
48             [menuItem setTarget:self];
49             break;
50         case WebMenuItemTagCopyLinkToClipboard:
51             title = UI_STRING("Copy Link", "Copy Link context menu item");
52             action = @selector(copyLinkToClipboard:);
53             [menuItem setTarget:self];
54             break;
55         case WebMenuItemTagOpenImageInNewWindow:
56             title = UI_STRING("Open Image in New Window", "Open Image in New Window context menu item");
57             action = @selector(openImageInNewWindow:);
58             [menuItem setTarget:self];
59             break;
60         case WebMenuItemTagDownloadImageToDisk:
61             title = UI_STRING("Download Image", "Download Image context menu item");
62             action = @selector(downloadImageToDisk:);
63             [menuItem setTarget:self];
64             break;
65         case WebMenuItemTagCopyImageToClipboard:
66             title = UI_STRING("Copy Image", "Copy Image context menu item");
67             action = @selector(copyImageToClipboard:);
68             [menuItem setTarget:self];
69             break;
70         case WebMenuItemTagOpenFrameInNewWindow:
71             title = UI_STRING("Open Frame in New Window", "Open Frame in New Window context menu item");
72             action = @selector(openFrameInNewWindow:);
73             [menuItem setTarget:self];
74             break;
75         case WebMenuItemTagCopy:
76             title = UI_STRING("Copy", "Copy context menu item");
77             action = @selector(copy:);
78             break;
79         case WebMenuItemTagGoBack:
80             title = UI_STRING("Back", "Back context menu item");
81             action = @selector(goBack:);
82             break;
83         case WebMenuItemTagGoForward:
84             title = UI_STRING("Forward", "Forward context menu item");
85             action = @selector(goForward:);
86             break;
87         case WebMenuItemTagStop:
88             title = UI_STRING("Stop", "Stop context menu item");
89             action = @selector(stopLoading:);
90             break;
91         case WebMenuItemTagReload:
92             title = UI_STRING("Reload", "Reload context menu item");
93             action = @selector(reload:);
94             break;
95         case WebMenuItemTagCut:
96             title = UI_STRING("Cut", "Cut context menu item");
97             action = @selector(cut:);
98             break;
99         case WebMenuItemTagPaste:
100             title = UI_STRING("Paste", "Paste context menu item");
101             action = @selector(paste:);
102             break;
103         case WebMenuItemTagSpellingGuess:
104             action = @selector(_changeSpellingFromMenu:);
105             break;
106         case WebMenuItemTagNoGuessesFound:
107             title = UI_STRING("No Guesses Found", "No Guesses Found context menu item");
108             break;
109         case WebMenuItemTagIgnoreSpelling:
110             title = UI_STRING("Ignore Spelling", "Ignore Spelling context menu item");
111             action = @selector(_ignoreSpellingFromMenu:);
112             break;
113         case WebMenuItemTagLearnSpelling:
114             title = UI_STRING("Learn Spelling", "Learn Spelling context menu item");
115             action = @selector(_learnSpellingFromMenu:);
116             break;
117         default:
118             return nil;
119     }
120
121     if (title != nil) {
122         [menuItem setTitle:title];
123     }
124     [menuItem setAction:action];
125     
126     return menuItem;
127 }
128
129 - (NSArray *)contextMenuItemsForElement:(NSDictionary *)element
130 {
131     NSMutableArray *menuItems = [NSMutableArray array];
132     
133     NSURL *linkURL = [element objectForKey:WebElementLinkURLKey];
134     
135     if (linkURL) {
136         if([WebView _canHandleRequest:[NSURLRequest requestWithURL:linkURL]]) {
137             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagOpenLinkInNewWindow]];
138             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagDownloadLinkToDisk]];
139         }
140         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagCopyLinkToClipboard]];
141     }
142     
143     NSURL *imageURL = [element objectForKey:WebElementImageURLKey];
144     if (imageURL) {
145         if (linkURL) {
146             [menuItems addObject:[NSMenuItem separatorItem]];
147         }
148         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagOpenImageInNewWindow]];
149         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagDownloadImageToDisk]];
150         if ([element objectForKey:WebElementImageURLKey] != nil) {
151             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagCopyImageToClipboard]];
152         }
153     }
154     
155     if (!imageURL && !linkURL) {
156         if ([[element objectForKey:WebElementIsSelectedKey] boolValue]) {
157             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagCopy]];
158         } else {
159             WebFrame *webFrame = [element objectForKey:WebElementFrameKey];
160             WebView *wv = [webFrame webView];
161             if ([wv canGoBack]) {
162                 [menuItems addObject:[self menuItemWithTag:WebMenuItemTagGoBack]];
163             }
164             if ([wv canGoForward]) {
165                 [menuItems addObject:[self menuItemWithTag:WebMenuItemTagGoForward]];
166             }
167             if ([wv isLoading]) {
168                 [menuItems addObject:[self menuItemWithTag:WebMenuItemTagStop]];
169             } else {
170                 [menuItems addObject:[self menuItemWithTag:WebMenuItemTagReload]];
171             }
172             
173             if (webFrame != [wv mainFrame]) {
174                 [menuItems addObject:[self menuItemWithTag:WebMenuItemTagOpenFrameInNewWindow]];
175             }
176         }
177     }
178     
179     // Attach element as the represented object to each item.
180     [menuItems makeObjectsPerformSelector:@selector(setRepresentedObject:) withObject:element];
181     
182     return menuItems;
183 }
184
185 - (NSArray *)editingContextMenuItemsForElement:(NSDictionary *)element
186 {
187     NSMenuItem *item;
188     NSMutableArray *menuItems = [NSMutableArray array];
189     WebHTMLView *HTMLView = (WebHTMLView *)[[[element objectForKey:WebElementFrameKey] frameView] documentView];
190     ASSERT([HTMLView isKindOfClass:[WebHTMLView class]]);
191     
192     // Add spelling related context menu items.
193     if ([HTMLView _isSelectionMisspelled]) {
194         NSArray *guesses = [HTMLView _guessesForMisspelledSelection];
195         unsigned count = [guesses count];
196         if (count > 0) {
197             NSEnumerator *enumerator = [guesses objectEnumerator];
198             NSString *guess;
199             while ((guess = [enumerator nextObject]) != nil) {
200                 item = [self menuItemWithTag:WebMenuItemTagSpellingGuess];
201                 [item setTitle:guess];
202                 [menuItems addObject:item];
203             }
204         } else {
205             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagNoGuessesFound]];
206         }
207         [menuItems addObject:[NSMenuItem separatorItem]];
208         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagIgnoreSpelling]];
209         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagLearnSpelling]];
210         [menuItems addObject:[NSMenuItem separatorItem]];
211     }
212     
213     // Load the standard NSTextView context menu nib.
214     if (defaultMenu == nil) {
215         static NSNib *textViewMenuNib = nil;
216         if (textViewMenuNib == nil) {
217             textViewMenuNib = [[NSNib alloc] initWithNibNamed:@"NSTextViewContextMenu" bundle:[NSBundle bundleForClass:[NSTextView class]]];
218         }
219         [textViewMenuNib instantiateNibWithOwner:self topLevelObjects:nil];
220     }
221     
222     // Add tags to the menu items because this is what the WebUIDelegate expects.
223     NSEnumerator *enumerator = [[defaultMenu itemArray] objectEnumerator];
224     while ((item = [enumerator nextObject]) != nil) {
225         item = [item copy];
226         SEL action = [item action];
227         int tag;
228         if (action == @selector(cut:)) {
229             tag = WebMenuItemTagCut;
230         } else if (action == @selector(copy:)) {
231             tag = WebMenuItemTagCopy;
232         } else if (action == @selector(paste:)) {
233             tag = WebMenuItemTagPaste;
234         } else {
235             tag = WebMenuItemTagOther;
236         }
237         [item setTag:tag];
238         [menuItems addObject:item];
239         [item release];
240     }
241     
242     return menuItems;
243 }
244
245 - (NSArray *)webView:(WebView *)wv contextMenuItemsForElement:(NSDictionary *)element  defaultMenuItems:(NSArray *)defaultMenuItems
246 {
247     WebHTMLView *HTMLView = (WebHTMLView *)[[[element objectForKey:WebElementFrameKey] frameView] documentView];
248     if ([HTMLView isKindOfClass:[WebHTMLView class]] && [HTMLView _isEditable]) {
249         return [self editingContextMenuItemsForElement:element];
250     } else {
251         return [self contextMenuItemsForElement:element];
252     }
253 }
254
255 - (void)openNewWindowWithURL:(NSURL *)URL element:(NSDictionary *)element
256 {
257     WebFrame *webFrame = [element objectForKey:WebElementFrameKey];
258     WebView *webView = [webFrame webView];
259     
260     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
261     NSString *referrer = [[webFrame _bridge] referrer];
262     if (referrer) {
263         [request setHTTPReferrer:referrer];
264     }
265     
266     [webView _openNewWindowWithRequest:request];
267 }
268
269 - (void)downloadURL:(NSURL *)URL element:(NSDictionary *)element
270 {
271     WebFrame *webFrame = [element objectForKey:WebElementFrameKey];
272     WebView *webView = [webFrame webView];
273     [webView _downloadURL:URL];
274 }
275
276 - (void)openLinkInNewWindow:(id)sender
277 {
278     NSDictionary *element = [sender representedObject];
279     [self openNewWindowWithURL:[element objectForKey:WebElementLinkURLKey] element:element];
280 }
281
282 - (void)downloadLinkToDisk:(id)sender
283 {
284     NSDictionary *element = [sender representedObject];
285     [self downloadURL:[element objectForKey:WebElementLinkURLKey] element:element];
286 }
287
288 - (void)copyLinkToClipboard:(id)sender
289 {
290     NSDictionary *element = [sender representedObject];
291     NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
292     NSArray *types = [NSPasteboard _web_writableTypesForURL];
293     [pasteboard declareTypes:types owner:self];    
294     [[[element objectForKey:WebElementFrameKey] webView] _writeLinkElement:element 
295                                                        withPasteboardTypes:types
296                                                               toPasteboard:pasteboard];
297 }
298
299 - (void)openImageInNewWindow:(id)sender
300 {
301     NSDictionary *element = [sender representedObject];
302     [self openNewWindowWithURL:[element objectForKey:WebElementImageURLKey] element:element];
303 }
304
305 - (void)downloadImageToDisk:(id)sender
306 {
307     NSDictionary *element = [sender representedObject];
308     [self downloadURL:[element objectForKey:WebElementImageURLKey] element:element];
309 }
310
311 - (void)copyImageToClipboard:(id)sender
312 {
313     NSDictionary *element = [sender representedObject];
314     NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
315     NSArray *types = [NSPasteboard _web_writableTypesForImage];
316     [pasteboard declareTypes:types owner:self];
317     [[[element objectForKey:WebElementFrameKey] webView] _writeImageElement:element 
318                                                         withPasteboardTypes:types 
319                                                                toPasteboard:pasteboard];
320 }
321
322 - (void)openFrameInNewWindow:(id)sender
323 {
324     NSDictionary *element = [sender representedObject];
325     WebFrame *webFrame = [element objectForKey:WebElementFrameKey];
326     [self openNewWindowWithURL:[[webFrame dataSource] _URL] element:element];
327 }
328
329 @end