Home | History | Annotate | Download | only in WebCoreSupport
      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 "WebElementPropertyBag.h"
     30 #include "WebLocalizableStrings.h"
     31 #include "WebView.h"
     32 
     33 #include <WebCore/ContextMenu.h>
     34 #include <WebCore/Event.h>
     35 #include <WebCore/Frame.h>
     36 #include <WebCore/FrameLoader.h>
     37 #include <WebCore/FrameLoadRequest.h>
     38 #include <WebCore/Page.h>
     39 #include <WebCore/ResourceRequest.h>
     40 #include <WebCore/NotImplemented.h>
     41 
     42 #include <tchar.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 static bool isPreInspectElementTagSafari(IWebUIDelegate* uiDelegate)
     57 {
     58     if (!uiDelegate)
     59         return false;
     60 
     61     TCHAR modulePath[MAX_PATH];
     62     DWORD length = ::GetModuleFileName(0, modulePath, _countof(modulePath));
     63     if (!length)
     64         return false;
     65 
     66     return String(modulePath, length).endsWith("Safari.exe", false);
     67 }
     68 
     69 static HMENU fixMenuReceivedFromOldSafari(IWebUIDelegate* uiDelegate, ContextMenu* originalMenu, HMENU menuFromClient)
     70 {
     71     ASSERT_ARG(originalMenu, originalMenu);
     72     if (!isPreInspectElementTagSafari(uiDelegate))
     73         return menuFromClient;
     74 
     75     int count = ::GetMenuItemCount(originalMenu->platformDescription());
     76     if (count < 1)
     77         return menuFromClient;
     78 
     79     if (::GetMenuItemID(originalMenu->platformDescription(), count - 1) != WebMenuItemTagInspectElement)
     80         return menuFromClient;
     81 
     82     count = ::GetMenuItemCount(menuFromClient);
     83     if (count < 1)
     84         return menuFromClient;
     85 
     86     if (::GetMenuItemID(menuFromClient, count - 1) == WebMenuItemTagInspectElement)
     87         return menuFromClient;
     88 
     89     originalMenu->setPlatformDescription(menuFromClient);
     90     originalMenu->addInspectElementItem();
     91     return originalMenu->platformDescription();
     92 }
     93 
     94 HMENU WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu)
     95 {
     96     COMPtr<IWebUIDelegate> uiDelegate;
     97     if (FAILED(m_webView->uiDelegate(&uiDelegate)))
     98         return menu->platformDescription();
     99 
    100     ASSERT(uiDelegate);
    101 
    102     HMENU newMenu = 0;
    103     COMPtr<WebElementPropertyBag> propertyBag;
    104     propertyBag.adoptRef(WebElementPropertyBag::createInstance(menu->hitTestResult()));
    105     // FIXME: We need to decide whether to do the default before calling this delegate method
    106     if (FAILED(uiDelegate->contextMenuItemsForElement(m_webView, propertyBag.get(), (OLE_HANDLE)(ULONG64)menu->platformDescription(), (OLE_HANDLE*)&newMenu)))
    107         return menu->platformDescription();
    108     return fixMenuReceivedFromOldSafari(uiDelegate.get(), menu, newMenu);
    109 }
    110 
    111 void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem* item, const ContextMenu* parentMenu)
    112 {
    113     ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
    114 
    115     COMPtr<IWebUIDelegate> uiDelegate;
    116     if (FAILED(m_webView->uiDelegate(&uiDelegate)))
    117         return;
    118 
    119     ASSERT(uiDelegate);
    120 
    121     COMPtr<WebElementPropertyBag> propertyBag;
    122     propertyBag.adoptRef(WebElementPropertyBag::createInstance(parentMenu->hitTestResult()));
    123 
    124     uiDelegate->contextMenuItemSelected(m_webView, item->releasePlatformDescription(), propertyBag.get());
    125 }
    126 
    127 void WebContextMenuClient::downloadURL(const KURL& url)
    128 {
    129     m_webView->downloadURL(url);
    130 }
    131 
    132 void WebContextMenuClient::searchWithGoogle(const Frame* frame)
    133 {
    134     String searchString = frame->selectedText();
    135     searchString.stripWhiteSpace();
    136     String encoded = encodeWithURLEscapeSequences(searchString);
    137     encoded.replace("%20", "+");
    138 
    139     String url("http://www.google.com/search?q=");
    140     url.append(encoded);
    141     url.append("&ie=UTF-8&oe=UTF-8");
    142 
    143     ResourceRequest request = ResourceRequest(url);
    144     if (Page* page = frame->page())
    145         page->mainFrame()->loader()->urlSelected(request, String(), 0, false, false, true, SendReferrer);
    146 }
    147 
    148 void WebContextMenuClient::lookUpInDictionary(Frame*)
    149 {
    150     notImplemented();
    151 }
    152 
    153 void WebContextMenuClient::speak(const String&)
    154 {
    155     notImplemented();
    156 }
    157 
    158 void WebContextMenuClient::stopSpeaking()
    159 {
    160     notImplemented();
    161 }
    162 
    163 bool WebContextMenuClient::isSpeaking()
    164 {
    165     notImplemented();
    166     return false;
    167 }
    168