a6dd828d76daeb124560fb1e8f603ecd65ca2e7d
[WebKit-https.git] / Source / WebKit / mac / DefaultDelegates / WebDefaultContextMenuDelegate.mm
1 /*
2  * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import "WebDefaultContextMenuDelegate.h"
30
31 #import "WebDOMOperations.h"
32 #import "WebDataSourcePrivate.h"
33 #import "WebDefaultUIDelegate.h"
34 #import "WebFrameInternal.h"
35 #import "WebFrameView.h"
36 #import "WebHTMLViewPrivate.h"
37 #import "WebLocalizableStringsInternal.h"
38 #import "WebNSPasteboardExtras.h"
39 #import "WebNSURLRequestExtras.h"
40 #import "WebPolicyDelegate.h"
41 #import "WebUIDelegate.h"
42 #import "WebUIDelegatePrivate.h"
43 #import "WebViewInternal.h"
44 #import <Foundation/NSURLConnection.h>
45 #import <Foundation/NSURLRequest.h>
46 #import <WebCore/Editor.h>
47 #import <WebCore/Frame.h>
48 #import <WebCore/FrameLoader.h>
49 #import <WebKit/DOM.h>
50 #import <WebKit/DOMPrivate.h>
51 #import <wtf/Assertions.h>
52
53 @implementation WebDefaultUIDelegate (WebContextMenu)
54
55 - (NSMenuItem *)menuItemWithTag:(int)tag target:(id)target representedObject:(id)representedObject
56 {
57     NSMenuItem *menuItem = [[[NSMenuItem alloc] init] autorelease];
58     [menuItem setTag:tag];
59     [menuItem setTarget:target]; // can be nil
60     [menuItem setRepresentedObject:representedObject];
61     
62     NSString *title = nil;
63     SEL action = NULL;
64     
65     switch(tag) {
66         case WebMenuItemTagCopy:
67             title = UI_STRING_INTERNAL("Copy", "Copy context menu item");
68             action = @selector(copy:);
69             break;
70         case WebMenuItemTagGoBack:
71             title = UI_STRING_INTERNAL("Back", "Back context menu item");
72             action = @selector(goBack:);
73             break;
74         case WebMenuItemTagGoForward:
75             title = UI_STRING_INTERNAL("Forward", "Forward context menu item");
76             action = @selector(goForward:);
77             break;
78         case WebMenuItemTagStop:
79             title = UI_STRING_INTERNAL("Stop", "Stop context menu item");
80             action = @selector(stopLoading:);
81             break;
82         case WebMenuItemTagReload:
83             title = UI_STRING_INTERNAL("Reload", "Reload context menu item");
84             action = @selector(reload:);
85             break;
86         case WebMenuItemTagSearchInSpotlight:
87             title = UI_STRING_INTERNAL("Search in Spotlight", "Search in Spotlight context menu item");
88             action = @selector(_searchWithSpotlightFromMenu:);
89             break;
90         case WebMenuItemTagSearchWeb:
91             title = UI_STRING_INTERNAL("Search in Google", "Search in Google context menu item");
92             action = @selector(_searchWithGoogleFromMenu:);
93             break;
94         case WebMenuItemTagLookUpInDictionary:
95             title = UI_STRING_INTERNAL("Look Up in Dictionary", "Look Up in Dictionary context menu item");
96             action = @selector(_lookUpInDictionaryFromMenu:);
97             break;
98         case WebMenuItemTagOpenFrameInNewWindow:
99             title = UI_STRING_INTERNAL("Open Frame in New Window", "Open Frame in New Window context menu item");
100             action = @selector(_openFrameInNewWindowFromMenu:);
101             break;
102         default:
103             ASSERT_NOT_REACHED();
104             return nil;
105     }
106
107     if (title)
108         [menuItem setTitle:title];
109
110     [menuItem setAction:action];
111     
112     return menuItem;
113 }
114
115 - (void)appendDefaultItems:(NSArray *)defaultItems toArray:(NSMutableArray *)menuItems
116 {
117     ASSERT_ARG(menuItems, menuItems != nil);
118     if ([defaultItems count] > 0) {
119         ASSERT(![[menuItems lastObject] isSeparatorItem]);
120         if (![[defaultItems objectAtIndex:0] isSeparatorItem]) {
121             [menuItems addObject:[NSMenuItem separatorItem]];
122             
123             NSEnumerator *e = [defaultItems objectEnumerator];
124             NSMenuItem *item;
125             while ((item = [e nextObject]) != nil) {
126                 [menuItems addObject:item];
127             }
128         }
129     }
130 }
131
132 #if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD)
133 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 1
134 #else
135 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 0
136 #endif
137
138 - (NSArray *)webView:(WebView *)wv contextMenuItemsForElement:(NSDictionary *)element  defaultMenuItems:(NSArray *)defaultMenuItems
139 {
140     // The defaultMenuItems here are ones supplied by the WebDocumentView protocol implementation. WebPDFView is
141     // one case that has non-nil default items here.
142     NSMutableArray *menuItems = [NSMutableArray array];
143
144     WebFrame *webFrame = [element objectForKey:WebElementFrameKey];
145     
146     if ([[element objectForKey:WebElementIsSelectedKey] boolValue]) {
147         // The Spotlight and Google items are implemented in WebView, and require that the
148         // current document view conforms to WebDocumentText
149         ASSERT([[[webFrame frameView] documentView] conformsToProtocol:@protocol(WebDocumentText)]);
150
151         // FIXME 4184640: The Look Up in Dictionary item is only implemented in WebHTMLView, and so is present but
152         // dimmed for other cases where WebElementIsSelectedKey is present. It would probably 
153         // be better not to include it in the menu if the documentView isn't a WebHTMLView, but that could break 
154         // existing clients that have code that relies on it being present (unlikely for clients outside of Apple, 
155         // but Safari has such code).
156
157 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
158         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagSearchInSpotlight target:nil representedObject:element]];
159 #else
160         NSMenuItem *lookupMenuItem = [self menuItemWithTag:WebMenuItemTagLookUpInDictionary target:nil representedObject:element];
161         NSString *selectedString = [(id <WebDocumentText>)[[webFrame frameView] documentView] selectedString];
162         [lookupMenuItem setTitle:[NSString stringWithFormat:UI_STRING_INTERNAL("Look Up “%@”", "Look Up context menu item with selected word"), selectedString]];
163         [menuItems addObject:lookupMenuItem];
164 #endif
165
166         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagSearchWeb target:nil representedObject:element]];
167
168 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
169         [menuItems addObject:[NSMenuItem separatorItem]];
170         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagLookUpInDictionary target:nil representedObject:element]];
171 #endif
172
173         [menuItems addObject:[NSMenuItem separatorItem]];
174         [menuItems addObject:[self menuItemWithTag:WebMenuItemTagCopy target:nil representedObject:element]];
175     } else {
176         WebView *wv = [webFrame webView];
177         if ([wv canGoBack]) {
178             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagGoBack target:wv representedObject:element]];
179         }
180         if ([wv canGoForward]) {
181             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagGoForward target:wv representedObject:element]];
182         }
183         if ([wv isLoading]) {
184             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagStop target:wv representedObject:element]];
185         } else {
186             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagReload target:wv representedObject:element]];
187         }
188
189         if (webFrame != [wv mainFrame]) {
190             [menuItems addObject:[self menuItemWithTag:WebMenuItemTagOpenFrameInNewWindow target:wv representedObject:element]];
191         }
192     }
193     
194     // Add the default items at the end, if any, after a separator
195     [self appendDefaultItems:defaultMenuItems toArray:menuItems];
196
197     return menuItems;
198 }
199
200 @end