1 /* 2 * Copyright (C) 2006, 2007 Apple 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 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "WebContextMenuClient.h" 28 29 #include "UserGestureIndicator.h" 30 #include "WebElementPropertyBag.h" 31 #include "WebLocalizableStrings.h" 32 #include "WebView.h" 33 34 #include <WebCore/ContextMenu.h> 35 #include <WebCore/ContextMenuController.h> 36 #include <WebCore/Event.h> 37 #include <WebCore/Frame.h> 38 #include <WebCore/FrameLoader.h> 39 #include <WebCore/FrameLoadRequest.h> 40 #include <WebCore/Page.h> 41 #include <WebCore/ResourceRequest.h> 42 #include <WebCore/NotImplemented.h> 43 44 using namespace WebCore; 45 46 WebContextMenuClient::WebContextMenuClient(WebView* webView) 47 : m_webView(webView) 48 { 49 } 50 51 void WebContextMenuClient::contextMenuDestroyed() 52 { 53 delete this; 54 } 55 56 PassOwnPtr<ContextMenu> WebContextMenuClient::customizeMenu(PassOwnPtr<ContextMenu> popMenu) 57 { 58 OwnPtr<ContextMenu> menu = popMenu; 59 60 COMPtr<IWebUIDelegate> uiDelegate; 61 if (FAILED(m_webView->uiDelegate(&uiDelegate))) 62 return menu.release(); 63 64 ASSERT(uiDelegate); 65 66 HMENU nativeMenu = menu->nativeMenu(); 67 COMPtr<WebElementPropertyBag> propertyBag; 68 propertyBag.adoptRef(WebElementPropertyBag::createInstance(m_webView->page()->contextMenuController()->hitTestResult())); 69 // FIXME: We need to decide whether to do the default before calling this delegate method 70 if (FAILED(uiDelegate->contextMenuItemsForElement(m_webView, propertyBag.get(), (OLE_HANDLE)(ULONG64)nativeMenu, (OLE_HANDLE*)&nativeMenu))) { 71 ::DestroyMenu(nativeMenu); 72 return menu.release(); 73 } 74 75 OwnPtr<ContextMenu> customizedMenu = adoptPtr(new ContextMenu(nativeMenu)); 76 ::DestroyMenu(nativeMenu); 77 78 return customizedMenu.release(); 79 } 80 81 void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem* item, const ContextMenu* parentMenu) 82 { 83 ASSERT(item->type() == ActionType || item->type() == CheckableActionType); 84 85 COMPtr<IWebUIDelegate> uiDelegate; 86 if (FAILED(m_webView->uiDelegate(&uiDelegate))) 87 return; 88 89 ASSERT(uiDelegate); 90 91 COMPtr<WebElementPropertyBag> propertyBag; 92 propertyBag.adoptRef(WebElementPropertyBag::createInstance(m_webView->page()->contextMenuController()->hitTestResult())); 93 94 // This call would leak the MENUITEMINFO's subMenu if it had one, but on Windows, subMenus can't be selected, so there is 95 // no way we would get to this point. Also, it can't be a separator, because separators cannot be selected. 96 ASSERT(item->type() != SubmenuType); 97 ASSERT(item->type() != SeparatorType); 98 99 // ContextMenuItem::nativeMenuItem doesn't set the dwTypeData of the MENUITEMINFO, but no WebKit clients 100 // use the title in IWebUIDelegate::contextMenuItemSelected, so we don't need to populate it here. 101 MENUITEMINFO selectedItem = item->nativeMenuItem(); 102 103 uiDelegate->contextMenuItemSelected(m_webView, &selectedItem, propertyBag.get()); 104 } 105 106 void WebContextMenuClient::downloadURL(const KURL& url) 107 { 108 m_webView->downloadURL(url); 109 } 110 111 void WebContextMenuClient::searchWithGoogle(const Frame* frame) 112 { 113 String searchString = frame->editor()->selectedText(); 114 searchString.stripWhiteSpace(); 115 String encoded = encodeWithURLEscapeSequences(searchString); 116 encoded.replace("%20", "+"); 117 118 String url("http://www.google.com/search?q="); 119 url.append(encoded); 120 url.append("&ie=UTF-8&oe=UTF-8"); 121 122 if (Page* page = frame->page()) { 123 UserGestureIndicator indicator(DefinitelyProcessingUserGesture); 124 page->mainFrame()->loader()->urlSelected(KURL(ParsedURLString, url), String(), 0, false, false, SendReferrer); 125 } 126 } 127 128 void WebContextMenuClient::lookUpInDictionary(Frame*) 129 { 130 notImplemented(); 131 } 132 133 void WebContextMenuClient::speak(const String&) 134 { 135 notImplemented(); 136 } 137 138 void WebContextMenuClient::stopSpeaking() 139 { 140 notImplemented(); 141 } 142 143 bool WebContextMenuClient::isSpeaking() 144 { 145 notImplemented(); 146 return false; 147 } 148