[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

beidson at apple.com beidson at apple.com
Wed Dec 22 15:52:12 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 0cc69dcd9634a90fa196025f5b71542aa079c99d
Author: beidson at apple.com <beidson at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Nov 15 20:47:15 2010 +0000

    Finish off <rdar://problem/8613727> and https://bugs.webkit.org/show_bug.cgi?id=48720
    Customizable context menu support in WebKit2.
    
    Reviewed by Sam Weinig.
    
    - Adds an API-level WKContextMenuItem.
    - Round trips through both the InjectedBundle client and the new PageContextMenuClient before
      actually displaying the menu.
    
    * WebKit2.pro:
    * WebKit2.xcodeproj/project.pbxproj:
    * win/WebKit2.vcproj:
    
    * Shared/API/c/WKBase.h:
    * Shared/API/c/WKContextMenuItem.cpp: Added.
    (WKContextMenuItemGetTypeID):
    (WKContextMenuItemCreateAsAction):
    (WKContextMenuItemCreateAsCheckableAction):
    (WKContextMenuItemCreateAsSubmenu):
    (WKContextMenuItemSeparatorItem):
    (WKContextMenuItemGetTag):
    (WKContextMenuItemGetType):
    (WKContextMenuItemCopyTitle):
    (WKContextMenuItemGetEnabled):
    (WKContextMenuItemGetChecked):
    (WKContextMenuCopySubmenuItems):
    * Shared/API/c/WKContextMenuItem.h: Added.
    * Shared/API/c/WKContextMenuItemTypes.h: Added.
    
    * Shared/API/c/WKSharedAPICast.h:
    (WebKit::toAPI):
    (WebKit::toImpl):
    
    * Shared/WebContextMenuItem.cpp:
    (WebKit::WebContextMenuItem::create):
    (WebKit::WebContextMenuItem::separatorItem):
    (WebKit::WebContextMenuItem::submenuItemsAsImmutableArray):
    * Shared/WebContextMenuItem.h:
    
    * UIProcess/API/C/WKPage.cpp:
    (WKPageSetPageContextMenuClient):
    (WKPageSetPageFindClient):
    (WKPageSetPageLoaderClient):
    (WKPageSetPagePolicyClient):
    (WKPageSetPageUIClient):
    * UIProcess/API/C/WKPage.h:
    
    * UIProcess/WebPageContextMenuClient.cpp: Added.
    (WebKit::WebPageContextMenuClient::getContextMenuFromProposedMenu):
    * UIProcess/WebPageContextMenuClient.h: Added.
    
    * UIProcess/WebPageProxy.cpp:
    (WebKit::WebPageProxy::initializeContextMenuClient):
    (WebKit::WebPageProxy::showContextMenu):
    * UIProcess/WebPageProxy.h:
    * UIProcess/WebPageProxy.messages.in:
    
    * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
    * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp:
    (WebKit::InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems):
    * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h:
    
    * WebProcess/WebCoreSupport/WebContextMenuClient.cpp:
    (WebKit::WebContextMenuClient::getCustomMenuFromDefaultItems):
    * WebProcess/WebPage/WebContextMenu.cpp:
    (WebKit::WebContextMenu::show):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72024 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index 37c2052..7db37f2 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -1,3 +1,72 @@
+2010-11-15  Brady Eidson  <beidson at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Finish off <rdar://problem/8613727> and https://bugs.webkit.org/show_bug.cgi?id=48720
+        Customizable context menu support in WebKit2.
+
+        - Adds an API-level WKContextMenuItem.
+        - Round trips through both the InjectedBundle client and the new PageContextMenuClient before
+          actually displaying the menu.
+
+        * WebKit2.pro:
+        * WebKit2.xcodeproj/project.pbxproj:
+        * win/WebKit2.vcproj:
+
+        * Shared/API/c/WKBase.h:
+        * Shared/API/c/WKContextMenuItem.cpp: Added.
+        (WKContextMenuItemGetTypeID):
+        (WKContextMenuItemCreateAsAction):
+        (WKContextMenuItemCreateAsCheckableAction):
+        (WKContextMenuItemCreateAsSubmenu):
+        (WKContextMenuItemSeparatorItem):
+        (WKContextMenuItemGetTag):
+        (WKContextMenuItemGetType):
+        (WKContextMenuItemCopyTitle):
+        (WKContextMenuItemGetEnabled):
+        (WKContextMenuItemGetChecked):
+        (WKContextMenuCopySubmenuItems):
+        * Shared/API/c/WKContextMenuItem.h: Added.
+        * Shared/API/c/WKContextMenuItemTypes.h: Added.
+
+        * Shared/API/c/WKSharedAPICast.h:
+        (WebKit::toAPI):
+        (WebKit::toImpl):
+
+        * Shared/WebContextMenuItem.cpp:
+        (WebKit::WebContextMenuItem::create):
+        (WebKit::WebContextMenuItem::separatorItem):
+        (WebKit::WebContextMenuItem::submenuItemsAsImmutableArray):
+        * Shared/WebContextMenuItem.h:
+
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageContextMenuClient):
+        (WKPageSetPageFindClient):
+        (WKPageSetPageLoaderClient):
+        (WKPageSetPagePolicyClient):
+        (WKPageSetPageUIClient):
+        * UIProcess/API/C/WKPage.h:
+
+        * UIProcess/WebPageContextMenuClient.cpp: Added.
+        (WebKit::WebPageContextMenuClient::getContextMenuFromProposedMenu):
+        * UIProcess/WebPageContextMenuClient.h: Added.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::initializeContextMenuClient):
+        (WebKit::WebPageProxy::showContextMenu):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
+        * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp:
+        (WebKit::InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems):
+        * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h:
+
+        * WebProcess/WebCoreSupport/WebContextMenuClient.cpp:
+        (WebKit::WebContextMenuClient::getCustomMenuFromDefaultItems):
+        * WebProcess/WebPage/WebContextMenu.cpp:
+        (WebKit::WebContextMenu::show):
+
 2010-11-15  Anders Carlsson  <andersca at apple.com>
 
         Reviewed by Sam Weinig.
diff --git a/WebKit2/Shared/API/c/WKBase.h b/WebKit2/Shared/API/c/WKBase.h
index c220eac..a9b8093 100644
--- a/WebKit2/Shared/API/c/WKBase.h
+++ b/WebKit2/Shared/API/c/WKBase.h
@@ -44,6 +44,7 @@ typedef const struct OpaqueWKDictionary* WKDictionaryRef;
 typedef struct OpaqueWKDictionary* WKMutableDictionaryRef;
 
 typedef const struct OpaqueWKBoolean* WKBooleanRef;
+typedef const struct OpaqueWKContextMenuItem* WKContextMenuItemRef;
 typedef const struct OpaqueWKData* WKDataRef;
 typedef const struct OpaqueWKDouble* WKDoubleRef;
 typedef const struct OpaqueWKError* WKErrorRef;
diff --git a/WebKit2/Shared/API/c/WKContextMenuItem.cpp b/WebKit2/Shared/API/c/WKContextMenuItem.cpp
new file mode 100644
index 0000000..5dfa9f4
--- /dev/null
+++ b/WebKit2/Shared/API/c/WKContextMenuItem.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WKContextMenuItem.h"
+
+#include "MutableArray.h"
+#include "WebContextMenuItem.h"
+#include "WebContextMenuItemData.h"
+#include "WKAPICast.h"
+#include "WKContextMenuItemTypes.h"
+
+using namespace WebCore;
+using namespace WebKit;
+
+WKTypeID WKContextMenuItemGetTypeID()
+{
+    return toAPI(WebContextMenuItem::APIType);
+}
+
+WKContextMenuItemRef WKContextMenuItemCreateAsAction(WKContextMenuItemTag tag, WKStringRef title, bool enabled)
+{
+    return toAPI(WebContextMenuItem::create(WebContextMenuItemData(ActionType, toImpl(tag), toImpl(title)->string(), enabled, false)).leakRef());
+}
+
+WKContextMenuItemRef WKContextMenuItemCreateAsCheckableAction(WKContextMenuItemTag tag, WKStringRef title, bool enabled, bool checked)
+{
+    return toAPI(WebContextMenuItem::create(WebContextMenuItemData(CheckableActionType, toImpl(tag), toImpl(title)->string(), enabled, checked)).leakRef());
+}
+
+WKContextMenuItemRef WKContextMenuItemCreateAsSubmenu(WKStringRef title, bool enabled, WKArrayRef submenuItems)
+{
+    return toAPI(WebContextMenuItem::create(toImpl(title)->string(), enabled, toImpl(submenuItems)).leakRef());
+}
+
+WKContextMenuItemRef WKContextMenuItemSeparatorItem()
+{
+    return toAPI(WebContextMenuItem::separatorItem());
+}
+
+WKContextMenuItemTag WKContextMenuItemGetTag(WKContextMenuItemRef itemRef)
+{
+    return toAPI(toImpl(itemRef)->data()->action());
+}
+
+WKContextMenuItemType WKContextMenuItemGetType(WKContextMenuItemRef itemRef)
+{
+    return toAPI(toImpl(itemRef)->data()->type());
+}
+
+WKStringRef WKContextMenuItemCopyTitle(WKContextMenuItemRef itemRef)
+{
+    return toCopiedAPI(toImpl(itemRef)->data()->title().impl());
+}
+
+bool WKContextMenuItemGetEnabled(WKContextMenuItemRef itemRef)
+{
+    return toImpl(itemRef)->data()->enabled();
+}
+
+bool WKContextMenuItemGetChecked(WKContextMenuItemRef itemRef)
+{
+    return toImpl(itemRef)->data()->checked();
+}
+
+WKArrayRef WKContextMenuCopySubmenuItems(WKContextMenuItemRef itemRef)
+{
+    return toAPI(toImpl(itemRef)->submenuItemsAsImmutableArray().leakRef());
+}
diff --git a/WebKit2/Shared/API/c/WKContextMenuItem.h b/WebKit2/Shared/API/c/WKContextMenuItem.h
new file mode 100644
index 0000000..c6a21eb
--- /dev/null
+++ b/WebKit2/Shared/API/c/WKContextMenuItem.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKContextMenuItem_h
+#define WKContextMenuItem_h
+
+#include <WebKit2/WKBase.h>
+#include <WebKit2/WKContextMenuItemTypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+WK_EXPORT WKTypeID WKContextMenuItemGetTypeID();
+
+WK_EXPORT WKContextMenuItemRef WKContextMenuItemCreateAsAction(WKContextMenuItemTag, WKStringRef title, bool enabled);
+WK_EXPORT WKContextMenuItemRef WKContextMenuItemCreateAsCheckableAction(WKContextMenuItemTag, WKStringRef title, bool enabled, bool checked);
+WK_EXPORT WKContextMenuItemRef WKContextMenuItemCreateAsSubmenu(WKStringRef title, bool enabled, WKArrayRef submenuItems);
+WK_EXPORT WKContextMenuItemRef WKContextMenuItemSeparatorItem();
+
+WK_EXPORT WKContextMenuItemTag WKContextMenuItemGetTag(WKContextMenuItemRef);
+WK_EXPORT WKContextMenuItemType WKContextMenuItemGetType(WKContextMenuItemRef);
+WK_EXPORT WKStringRef WKContextMenuItemCopyTitle(WKContextMenuItemRef);
+WK_EXPORT bool WKContextMenuItemGetEnabled(WKContextMenuItemRef);
+WK_EXPORT bool WKContextMenuItemGetChecked(WKContextMenuItemRef);
+WK_EXPORT WKArrayRef WKContextMenuCopySubmenuItems(WKContextMenuItemRef);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WKContextMenuItem_h */
diff --git a/WebKit2/Shared/API/c/WKContextMenuItemTypes.h b/WebKit2/Shared/API/c/WKContextMenuItemTypes.h
new file mode 100644
index 0000000..a3536d9
--- /dev/null
+++ b/WebKit2/Shared/API/c/WKContextMenuItemTypes.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WKContextMenuItemTypes_h
+#define WKContextMenuItemTypes_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+    kWKContextMenuItemTagNoAction = 0,
+    kWKContextMenuItemTagOpenLinkInNewWindow,
+    kWKContextMenuItemTagDownloadLinkToDisk,
+    kWKContextMenuItemTagCopyLinkToClipboard,
+    kWKContextMenuItemTagOpenImageInNewWindow,
+    kWKContextMenuItemTagDownloadImageToDisk,
+    kWKContextMenuItemTagCopyImageToClipboard,
+    kWKContextMenuItemTagOpenFrameInNewWindow,
+    kWKContextMenuItemTagCopy,
+    kWKContextMenuItemTagGoBack,
+    kWKContextMenuItemTagGoForward,
+    kWKContextMenuItemTagStop,
+    kWKContextMenuItemTagReload,
+    kWKContextMenuItemTagCut,
+    kWKContextMenuItemTagPaste,
+    kWKContextMenuItemTagSpellingGuess,
+    kWKContextMenuItemTagNoGuessesFound,
+    kWKContextMenuItemTagIgnoreSpelling,
+    kWKContextMenuItemTagLearnSpelling,
+    kWKContextMenuItemTagOther,
+    kWKContextMenuItemTagSearchInSpotlight,
+    kWKContextMenuItemTagSearchWeb,
+    kWKContextMenuItemTagLookUpInDictionary,
+    kWKContextMenuItemTagOpenWithDefaultApplication,
+    kWKContextMenuItemTagPDFActualSize,
+    kWKContextMenuItemTagPDFZoomIn,
+    kWKContextMenuItemTagPDFZoomOut,
+    kWKContextMenuItemTagPDFAutoSize,
+    kWKContextMenuItemTagPDFSinglePage,
+    kWKContextMenuItemTagPDFFacingPages,
+    kWKContextMenuItemTagPDFContinuous,
+    kWKContextMenuItemTagPDFNextPage,
+    kWKContextMenuItemTagPDFPreviousPage,
+    kWKContextMenuItemTagOpenLink,
+    kWKContextMenuItemTagIgnoreGrammar,
+    kWKContextMenuItemTagSpellingMenu, 
+    kWKContextMenuItemTagShowSpellingPanel,
+    kWKContextMenuItemTagCheckSpelling,
+    kWKContextMenuItemTagCheckSpellingWhileTyping,
+    kWKContextMenuItemTagCheckGrammarWithSpelling,
+    kWKContextMenuItemTagFontMenu, 
+    kWKContextMenuItemTagShowFonts,
+    kWKContextMenuItemTagBold,
+    kWKContextMenuItemTagItalic,
+    kWKContextMenuItemTagUnderline,
+    kWKContextMenuItemTagOutline,
+    kWKContextMenuItemTagStyles,
+    kWKContextMenuItemTagShowColors,
+    kWKContextMenuItemTagSpeechMenu, 
+    kWKContextMenuItemTagStartSpeaking,
+    kWKContextMenuItemTagStopSpeaking,
+    kWKContextMenuItemTagWritingDirectionMenu, 
+    kWKContextMenuItemTagDefaultDirection,
+    kWKContextMenuItemTagLeftToRight,
+    kWKContextMenuItemTagRightToLeft,
+    kWKContextMenuItemTagPDFSinglePageScrolling,
+    kWKContextMenuItemTagPDFFacingPagesScrolling,
+    kWKContextMenuItemTagInspectElement,
+    kWKContextMenuItemTagTextDirectionMenu,
+    kWKContextMenuItemTagTextDirectionDefault,
+    kWKContextMenuItemTagTextDirectionLeftToRight,
+    kWKContextMenuItemTagTextDirectionRightToLeft,
+    kWKContextMenuItemTagCorrectSpellingAutomatically,
+    kWKContextMenuItemTagSubstitutionsMenu,
+    kWKContextMenuItemTagShowSubstitutions,
+    kWKContextMenuItemTagSmartCopyPaste,
+    kWKContextMenuItemTagSmartQuotes,
+    kWKContextMenuItemTagSmartDashes,
+    kWKContextMenuItemTagSmartLinks,
+    kWKContextMenuItemTagTextReplacement,
+    kWKContextMenuItemTagTransformationsMenu,
+    kWKContextMenuItemTagMakeUpperCase,
+    kWKContextMenuItemTagMakeLowerCase,
+    kWKContextMenuItemTagCapitalize,
+    kWKContextMenuItemTagChangeBack,
+    kWKContextMenuItemTagOpenMediaInNewWindow,
+    kWKContextMenuItemTagCopyMediaLinkToClipboard,
+    kWKContextMenuItemTagToggleMediaControls,
+    kWKContextMenuItemTagToggleMediaLoop,
+    kWKContextMenuItemTagEnterVideoFullscreen,
+    kWKContextMenuItemTagMediaPlayPause,
+    kWKContextMenuItemTagMediaMute,
+    kWKContextMenuItemBaseApplicationTag = 10000
+};
+typedef uint32_t WKContextMenuItemTag;
+
+enum {
+    kWKContextMenuItemTypeAction,
+    kWKContextMenuItemTypeCheckableAction,
+    kWKContextMenuItemTypeSeparator,
+    kWKContextMenuItemTypeSubmenu
+};
+typedef uint32_t WKContextMenuItemType;
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WKContextMenuItemTypes_h */
diff --git a/WebKit2/Shared/API/c/WKSharedAPICast.h b/WebKit2/Shared/API/c/WKSharedAPICast.h
index 773376c..e95fb8b 100644
--- a/WebKit2/Shared/API/c/WKSharedAPICast.h
+++ b/WebKit2/Shared/API/c/WKSharedAPICast.h
@@ -27,6 +27,7 @@
 #define WKSharedAPICast_h
 
 #include "WKBase.h"
+#include "WKContextMenuItemTypes.h"
 #include "WKEvent.h"
 #include "WKGeometry.h"
 #include "WebError.h"
@@ -34,6 +35,7 @@
 #include "WebNumber.h"
 #include "WebString.h"
 #include "WebURL.h"
+#include <WebCore/ContextMenuItem.h>
 #include <WebCore/IntRect.h>
 #include <WebCore/FloatRect.h>
 #include <WebCore/IntPoint.h>
@@ -46,6 +48,7 @@ class ImmutableDictionary;
 class MutableArray;
 class MutableDictionary;
 class WebCertificateInfo;
+class WebContextMenuItem;
 class WebData;
 class WebSerializedScriptValue;
 class WebURLRequest;
@@ -62,6 +65,7 @@ template<typename ImplType> struct ImplTypeInfo { };
 WK_ADD_API_MAPPING(WKArrayRef, ImmutableArray)
 WK_ADD_API_MAPPING(WKBooleanRef, WebBoolean)
 WK_ADD_API_MAPPING(WKCertificateInfoRef, WebCertificateInfo)
+WK_ADD_API_MAPPING(WKContextMenuItemRef, WebContextMenuItem)
 WK_ADD_API_MAPPING(WKDataRef, WebData)
 WK_ADD_API_MAPPING(WKDictionaryRef, ImmutableDictionary)
 WK_ADD_API_MAPPING(WKDoubleRef, WebDouble)
@@ -234,6 +238,375 @@ inline WKEventMouseButton toAPI(WebMouseEvent::Button mouseButton)
     return wkMouseButton;
 }
 
+inline WKContextMenuItemTag toAPI(WebCore::ContextMenuAction action)
+{
+    switch (action) {
+    case WebCore::ContextMenuItemTagNoAction:
+        return kWKContextMenuItemTagNoAction;
+    case WebCore::ContextMenuItemTagOpenLinkInNewWindow:
+        return kWKContextMenuItemTagOpenLinkInNewWindow;
+    case WebCore::ContextMenuItemTagDownloadLinkToDisk:
+        return kWKContextMenuItemTagDownloadLinkToDisk;
+    case WebCore::ContextMenuItemTagCopyLinkToClipboard:
+        return kWKContextMenuItemTagCopyLinkToClipboard;
+    case WebCore::ContextMenuItemTagOpenImageInNewWindow:
+        return kWKContextMenuItemTagOpenImageInNewWindow;
+    case WebCore::ContextMenuItemTagDownloadImageToDisk:
+        return kWKContextMenuItemTagDownloadImageToDisk;
+    case WebCore::ContextMenuItemTagCopyImageToClipboard:
+        return kWKContextMenuItemTagCopyImageToClipboard;
+    case WebCore::ContextMenuItemTagOpenFrameInNewWindow:
+        return kWKContextMenuItemTagOpenFrameInNewWindow;
+    case WebCore::ContextMenuItemTagCopy:
+        return kWKContextMenuItemTagCopy;
+    case WebCore::ContextMenuItemTagGoBack:
+        return kWKContextMenuItemTagGoBack;
+    case WebCore::ContextMenuItemTagGoForward:
+        return kWKContextMenuItemTagGoForward;
+    case WebCore::ContextMenuItemTagStop:
+        return kWKContextMenuItemTagStop;
+    case WebCore::ContextMenuItemTagReload:
+        return kWKContextMenuItemTagReload;
+    case WebCore::ContextMenuItemTagCut:
+        return kWKContextMenuItemTagCut;
+    case WebCore::ContextMenuItemTagPaste:
+        return kWKContextMenuItemTagPaste;
+    case WebCore::ContextMenuItemTagSpellingGuess:
+        return kWKContextMenuItemTagSpellingGuess;
+    case WebCore::ContextMenuItemTagNoGuessesFound:
+        return kWKContextMenuItemTagNoGuessesFound;
+    case WebCore::ContextMenuItemTagIgnoreSpelling:
+        return kWKContextMenuItemTagIgnoreSpelling;
+    case WebCore::ContextMenuItemTagLearnSpelling:
+        return kWKContextMenuItemTagLearnSpelling;
+    case WebCore::ContextMenuItemTagOther:
+        return kWKContextMenuItemTagOther;
+    case WebCore::ContextMenuItemTagSearchInSpotlight:
+        return kWKContextMenuItemTagSearchInSpotlight;
+    case WebCore::ContextMenuItemTagSearchWeb:
+        return kWKContextMenuItemTagSearchWeb;
+    case WebCore::ContextMenuItemTagLookUpInDictionary:
+        return kWKContextMenuItemTagLookUpInDictionary;
+    case WebCore::ContextMenuItemTagOpenWithDefaultApplication:
+        return kWKContextMenuItemTagOpenWithDefaultApplication;
+    case WebCore::ContextMenuItemPDFActualSize:
+        return kWKContextMenuItemTagPDFActualSize;
+    case WebCore::ContextMenuItemPDFZoomIn:
+        return kWKContextMenuItemTagPDFZoomIn;
+    case WebCore::ContextMenuItemPDFZoomOut:
+        return kWKContextMenuItemTagPDFZoomOut;
+    case WebCore::ContextMenuItemPDFAutoSize:
+        return kWKContextMenuItemTagPDFAutoSize;
+    case WebCore::ContextMenuItemPDFSinglePage:
+        return kWKContextMenuItemTagPDFSinglePage;
+    case WebCore::ContextMenuItemPDFFacingPages:
+        return kWKContextMenuItemTagPDFFacingPages;
+    case WebCore::ContextMenuItemPDFContinuous:
+        return kWKContextMenuItemTagPDFContinuous;
+    case WebCore::ContextMenuItemPDFNextPage:
+        return kWKContextMenuItemTagPDFNextPage;
+    case WebCore::ContextMenuItemPDFPreviousPage:
+        return kWKContextMenuItemTagPDFPreviousPage;
+    case WebCore::ContextMenuItemTagOpenLink:
+        return kWKContextMenuItemTagOpenLink;
+    case WebCore::ContextMenuItemTagIgnoreGrammar:
+        return kWKContextMenuItemTagIgnoreGrammar;
+    case WebCore::ContextMenuItemTagSpellingMenu:
+        return kWKContextMenuItemTagSpellingMenu;
+    case WebCore::ContextMenuItemTagShowSpellingPanel:
+        return kWKContextMenuItemTagShowSpellingPanel;
+    case WebCore::ContextMenuItemTagCheckSpelling:
+        return kWKContextMenuItemTagCheckSpelling;
+    case WebCore::ContextMenuItemTagCheckSpellingWhileTyping:
+        return kWKContextMenuItemTagCheckSpellingWhileTyping;
+    case WebCore::ContextMenuItemTagCheckGrammarWithSpelling:
+        return kWKContextMenuItemTagCheckGrammarWithSpelling;
+    case WebCore::ContextMenuItemTagFontMenu:
+        return kWKContextMenuItemTagFontMenu;
+    case WebCore::ContextMenuItemTagShowFonts:
+        return kWKContextMenuItemTagShowFonts;
+    case WebCore::ContextMenuItemTagBold:
+        return kWKContextMenuItemTagBold;
+    case WebCore::ContextMenuItemTagItalic:
+        return kWKContextMenuItemTagItalic;
+    case WebCore::ContextMenuItemTagUnderline:
+        return kWKContextMenuItemTagUnderline;
+    case WebCore::ContextMenuItemTagOutline:
+        return kWKContextMenuItemTagOutline;
+    case WebCore::ContextMenuItemTagStyles:
+        return kWKContextMenuItemTagStyles;
+    case WebCore::ContextMenuItemTagShowColors:
+        return kWKContextMenuItemTagShowColors;
+    case WebCore::ContextMenuItemTagSpeechMenu:
+        return kWKContextMenuItemTagSpeechMenu;
+    case WebCore::ContextMenuItemTagStartSpeaking:
+        return kWKContextMenuItemTagStartSpeaking;
+    case WebCore::ContextMenuItemTagStopSpeaking:
+        return kWKContextMenuItemTagStopSpeaking;
+    case WebCore::ContextMenuItemTagWritingDirectionMenu:
+        return kWKContextMenuItemTagWritingDirectionMenu;
+    case WebCore::ContextMenuItemTagDefaultDirection:
+        return kWKContextMenuItemTagDefaultDirection;
+    case WebCore::ContextMenuItemTagLeftToRight:
+        return kWKContextMenuItemTagLeftToRight;
+    case WebCore::ContextMenuItemTagRightToLeft:
+        return kWKContextMenuItemTagRightToLeft;
+    case WebCore::ContextMenuItemTagPDFSinglePageScrolling:
+        return kWKContextMenuItemTagPDFSinglePageScrolling;
+    case WebCore::ContextMenuItemTagPDFFacingPagesScrolling:
+        return kWKContextMenuItemTagPDFFacingPagesScrolling;
+    case WebCore::ContextMenuItemTagInspectElement:
+        return kWKContextMenuItemTagInspectElement;
+    case WebCore::ContextMenuItemTagTextDirectionMenu:
+        return kWKContextMenuItemTagTextDirectionMenu;
+    case WebCore::ContextMenuItemTagTextDirectionDefault:
+        return kWKContextMenuItemTagTextDirectionDefault;
+    case WebCore::ContextMenuItemTagTextDirectionLeftToRight:
+        return kWKContextMenuItemTagTextDirectionLeftToRight;
+    case WebCore::ContextMenuItemTagTextDirectionRightToLeft:
+        return kWKContextMenuItemTagTextDirectionRightToLeft;
+    case WebCore::ContextMenuItemTagOpenMediaInNewWindow:
+        return kWKContextMenuItemTagOpenMediaInNewWindow;
+    case WebCore::ContextMenuItemTagCopyMediaLinkToClipboard:
+        return kWKContextMenuItemTagCopyMediaLinkToClipboard;
+    case WebCore::ContextMenuItemTagToggleMediaControls:
+        return kWKContextMenuItemTagToggleMediaControls;
+    case WebCore::ContextMenuItemTagToggleMediaLoop:
+        return kWKContextMenuItemTagToggleMediaLoop;
+    case WebCore::ContextMenuItemTagEnterVideoFullscreen:
+        return kWKContextMenuItemTagEnterVideoFullscreen;
+    case WebCore::ContextMenuItemTagMediaPlayPause:
+        return kWKContextMenuItemTagMediaPlayPause;
+    case WebCore::ContextMenuItemTagMediaMute:
+        return kWKContextMenuItemTagMediaMute;
+#if PLATFORM(MAC)
+    case WebCore::ContextMenuItemTagCorrectSpellingAutomatically:
+        return kWKContextMenuItemTagCorrectSpellingAutomatically;
+    case WebCore::ContextMenuItemTagSubstitutionsMenu:
+        return kWKContextMenuItemTagSubstitutionsMenu;
+    case WebCore::ContextMenuItemTagShowSubstitutions:
+        return kWKContextMenuItemTagShowSubstitutions;
+    case WebCore::ContextMenuItemTagSmartCopyPaste:
+        return kWKContextMenuItemTagSmartCopyPaste;
+    case WebCore::ContextMenuItemTagSmartQuotes:
+        return kWKContextMenuItemTagSmartQuotes;
+    case WebCore::ContextMenuItemTagSmartDashes:
+        return kWKContextMenuItemTagSmartDashes;
+    case WebCore::ContextMenuItemTagSmartLinks:
+        return kWKContextMenuItemTagSmartLinks;
+    case WebCore::ContextMenuItemTagTextReplacement:
+        return kWKContextMenuItemTagTextReplacement;
+    case WebCore::ContextMenuItemTagTransformationsMenu:
+        return kWKContextMenuItemTagTransformationsMenu;
+    case WebCore::ContextMenuItemTagMakeUpperCase:
+        return kWKContextMenuItemTagMakeUpperCase;
+    case WebCore::ContextMenuItemTagMakeLowerCase:
+        return kWKContextMenuItemTagMakeLowerCase;
+    case WebCore::ContextMenuItemTagCapitalize:
+        return kWKContextMenuItemTagCapitalize;
+    case WebCore::ContextMenuItemTagChangeBack:
+        return kWKContextMenuItemTagChangeBack;
+#endif
+    default:
+        if (action < WebCore::ContextMenuItemBaseApplicationTag)
+            LOG_ERROR("ContextMenuAction %i is an unknown tag but is below the allowable custom tag value of %i", action, WebCore::  ContextMenuItemBaseApplicationTag);
+        return static_cast<WKContextMenuItemTag>(action);
+    }
+}
+
+inline WebCore::ContextMenuAction toImpl(WKContextMenuItemTag tag)
+{
+    switch (tag) {
+    case kWKContextMenuItemTagNoAction:
+        return WebCore::ContextMenuItemTagNoAction;
+    case kWKContextMenuItemTagOpenLinkInNewWindow:
+        return WebCore::ContextMenuItemTagOpenLinkInNewWindow;
+    case kWKContextMenuItemTagDownloadLinkToDisk:
+        return WebCore::ContextMenuItemTagDownloadLinkToDisk;
+    case kWKContextMenuItemTagCopyLinkToClipboard:
+        return WebCore::ContextMenuItemTagCopyLinkToClipboard;
+    case kWKContextMenuItemTagOpenImageInNewWindow:
+        return WebCore::ContextMenuItemTagOpenImageInNewWindow;
+    case kWKContextMenuItemTagDownloadImageToDisk:
+        return WebCore::ContextMenuItemTagDownloadImageToDisk;
+    case kWKContextMenuItemTagCopyImageToClipboard:
+        return WebCore::ContextMenuItemTagCopyImageToClipboard;
+    case kWKContextMenuItemTagOpenFrameInNewWindow:
+        return WebCore::ContextMenuItemTagOpenFrameInNewWindow;
+    case kWKContextMenuItemTagCopy:
+        return WebCore::ContextMenuItemTagCopy;
+    case kWKContextMenuItemTagGoBack:
+        return WebCore::ContextMenuItemTagGoBack;
+    case kWKContextMenuItemTagGoForward:
+        return WebCore::ContextMenuItemTagGoForward;
+    case kWKContextMenuItemTagStop:
+        return WebCore::ContextMenuItemTagStop;
+    case kWKContextMenuItemTagReload:
+        return WebCore::ContextMenuItemTagReload;
+    case kWKContextMenuItemTagCut:
+        return WebCore::ContextMenuItemTagCut;
+    case kWKContextMenuItemTagPaste:
+        return WebCore::ContextMenuItemTagPaste;
+    case kWKContextMenuItemTagSpellingGuess:
+        return WebCore::ContextMenuItemTagSpellingGuess;
+    case kWKContextMenuItemTagNoGuessesFound:
+        return WebCore::ContextMenuItemTagNoGuessesFound;
+    case kWKContextMenuItemTagIgnoreSpelling:
+        return WebCore::ContextMenuItemTagIgnoreSpelling;
+    case kWKContextMenuItemTagLearnSpelling:
+        return WebCore::ContextMenuItemTagLearnSpelling;
+    case kWKContextMenuItemTagOther:
+        return WebCore::ContextMenuItemTagOther;
+    case kWKContextMenuItemTagSearchInSpotlight:
+        return WebCore::ContextMenuItemTagSearchInSpotlight;
+    case kWKContextMenuItemTagSearchWeb:
+        return WebCore::ContextMenuItemTagSearchWeb;
+    case kWKContextMenuItemTagLookUpInDictionary:
+        return WebCore::ContextMenuItemTagLookUpInDictionary;
+    case kWKContextMenuItemTagOpenWithDefaultApplication:
+        return WebCore::ContextMenuItemTagOpenWithDefaultApplication;
+    case kWKContextMenuItemTagPDFActualSize:
+        return WebCore::ContextMenuItemPDFActualSize;
+    case kWKContextMenuItemTagPDFZoomIn:
+        return WebCore::ContextMenuItemPDFZoomIn;
+    case kWKContextMenuItemTagPDFZoomOut:
+        return WebCore::ContextMenuItemPDFZoomOut;
+    case kWKContextMenuItemTagPDFAutoSize:
+        return WebCore::ContextMenuItemPDFAutoSize;
+    case kWKContextMenuItemTagPDFSinglePage:
+        return WebCore::ContextMenuItemPDFSinglePage;
+    case kWKContextMenuItemTagPDFFacingPages:
+        return WebCore::ContextMenuItemPDFFacingPages;
+    case kWKContextMenuItemTagPDFContinuous:
+        return WebCore::ContextMenuItemPDFContinuous;
+    case kWKContextMenuItemTagPDFNextPage:
+        return WebCore::ContextMenuItemPDFNextPage;
+    case kWKContextMenuItemTagPDFPreviousPage:
+        return WebCore::ContextMenuItemPDFPreviousPage;
+    case kWKContextMenuItemTagOpenLink:
+        return WebCore::ContextMenuItemTagOpenLink;
+    case kWKContextMenuItemTagIgnoreGrammar:
+        return WebCore::ContextMenuItemTagIgnoreGrammar;
+    case kWKContextMenuItemTagSpellingMenu:
+        return WebCore::ContextMenuItemTagSpellingMenu;
+    case kWKContextMenuItemTagShowSpellingPanel:
+        return WebCore::ContextMenuItemTagShowSpellingPanel;
+    case kWKContextMenuItemTagCheckSpelling:
+        return WebCore::ContextMenuItemTagCheckSpelling;
+    case kWKContextMenuItemTagCheckSpellingWhileTyping:
+        return WebCore::ContextMenuItemTagCheckSpellingWhileTyping;
+    case kWKContextMenuItemTagCheckGrammarWithSpelling:
+        return WebCore::ContextMenuItemTagCheckGrammarWithSpelling;
+    case kWKContextMenuItemTagFontMenu:
+        return WebCore::ContextMenuItemTagFontMenu;
+    case kWKContextMenuItemTagShowFonts:
+        return WebCore::ContextMenuItemTagShowFonts;
+    case kWKContextMenuItemTagBold:
+        return WebCore::ContextMenuItemTagBold;
+    case kWKContextMenuItemTagItalic:
+        return WebCore::ContextMenuItemTagItalic;
+    case kWKContextMenuItemTagUnderline:
+        return WebCore::ContextMenuItemTagUnderline;
+    case kWKContextMenuItemTagOutline:
+        return WebCore::ContextMenuItemTagOutline;
+    case kWKContextMenuItemTagStyles:
+        return WebCore::ContextMenuItemTagStyles;
+    case kWKContextMenuItemTagShowColors:
+        return WebCore::ContextMenuItemTagShowColors;
+    case kWKContextMenuItemTagSpeechMenu:
+        return WebCore::ContextMenuItemTagSpeechMenu;
+    case kWKContextMenuItemTagStartSpeaking:
+        return WebCore::ContextMenuItemTagStartSpeaking;
+    case kWKContextMenuItemTagStopSpeaking:
+        return WebCore::ContextMenuItemTagStopSpeaking;
+    case kWKContextMenuItemTagWritingDirectionMenu:
+        return WebCore::ContextMenuItemTagWritingDirectionMenu;
+    case kWKContextMenuItemTagDefaultDirection:
+        return WebCore::ContextMenuItemTagDefaultDirection;
+    case kWKContextMenuItemTagLeftToRight:
+        return WebCore::ContextMenuItemTagLeftToRight;
+    case kWKContextMenuItemTagRightToLeft:
+        return WebCore::ContextMenuItemTagRightToLeft;
+    case kWKContextMenuItemTagPDFSinglePageScrolling:
+        return WebCore::ContextMenuItemTagPDFSinglePageScrolling;
+    case kWKContextMenuItemTagPDFFacingPagesScrolling:
+        return WebCore::ContextMenuItemTagPDFFacingPagesScrolling;
+    case kWKContextMenuItemTagInspectElement:
+        return WebCore::ContextMenuItemTagInspectElement;
+    case kWKContextMenuItemTagTextDirectionMenu:
+        return WebCore::ContextMenuItemTagTextDirectionMenu;
+    case kWKContextMenuItemTagTextDirectionDefault:
+        return WebCore::ContextMenuItemTagTextDirectionDefault;
+    case kWKContextMenuItemTagTextDirectionLeftToRight:
+        return WebCore::ContextMenuItemTagTextDirectionLeftToRight;
+    case kWKContextMenuItemTagTextDirectionRightToLeft:
+        return WebCore::ContextMenuItemTagTextDirectionRightToLeft;
+    case kWKContextMenuItemTagOpenMediaInNewWindow:
+        return WebCore::ContextMenuItemTagOpenMediaInNewWindow;
+    case kWKContextMenuItemTagCopyMediaLinkToClipboard:
+        return WebCore::ContextMenuItemTagCopyMediaLinkToClipboard;
+    case kWKContextMenuItemTagToggleMediaControls:
+        return WebCore::ContextMenuItemTagToggleMediaControls;
+    case kWKContextMenuItemTagToggleMediaLoop:
+        return WebCore::ContextMenuItemTagToggleMediaLoop;
+    case kWKContextMenuItemTagEnterVideoFullscreen:
+        return WebCore::ContextMenuItemTagEnterVideoFullscreen;
+    case kWKContextMenuItemTagMediaPlayPause:
+        return WebCore::ContextMenuItemTagMediaPlayPause;
+    case kWKContextMenuItemTagMediaMute:
+        return WebCore::ContextMenuItemTagMediaMute;
+#if PLATFORM(MAC)
+    case kWKContextMenuItemTagCorrectSpellingAutomatically:
+        return WebCore::ContextMenuItemTagCorrectSpellingAutomatically;
+    case kWKContextMenuItemTagSubstitutionsMenu:
+        return WebCore::ContextMenuItemTagSubstitutionsMenu;
+    case kWKContextMenuItemTagShowSubstitutions:
+        return WebCore::ContextMenuItemTagShowSubstitutions;
+    case kWKContextMenuItemTagSmartCopyPaste:
+        return WebCore::ContextMenuItemTagSmartCopyPaste;
+    case kWKContextMenuItemTagSmartQuotes:
+        return WebCore::ContextMenuItemTagSmartQuotes;
+    case kWKContextMenuItemTagSmartDashes:
+        return WebCore::ContextMenuItemTagSmartDashes;
+    case kWKContextMenuItemTagSmartLinks:
+        return WebCore::ContextMenuItemTagSmartLinks;
+    case kWKContextMenuItemTagTextReplacement:
+        return WebCore::ContextMenuItemTagTextReplacement;
+    case kWKContextMenuItemTagTransformationsMenu:
+        return WebCore::ContextMenuItemTagTransformationsMenu;
+    case kWKContextMenuItemTagMakeUpperCase:
+        return WebCore::ContextMenuItemTagMakeUpperCase;
+    case kWKContextMenuItemTagMakeLowerCase:
+        return WebCore::ContextMenuItemTagMakeLowerCase;
+    case kWKContextMenuItemTagCapitalize:
+        return WebCore::ContextMenuItemTagCapitalize;
+    case kWKContextMenuItemTagChangeBack:
+        return WebCore::ContextMenuItemTagChangeBack;
+#endif
+    default:
+        if (tag < kWKContextMenuItemBaseApplicationTag)
+            LOG_ERROR("WKContextMenuItemTag %i is an unknown tag but is below the allowable custom tag value of %i", tag, kWKContextMenuItemBaseApplicationTag);
+        return static_cast<WebCore::ContextMenuAction>(tag);
+    }
+}
+
+inline WKContextMenuItemType toAPI(WebCore::ContextMenuItemType type)
+{
+    switch(type) {
+    case WebCore::ActionType:
+        return kWKContextMenuItemTypeAction;
+    case WebCore::CheckableActionType:
+        return kWKContextMenuItemTypeCheckableAction;
+    case WebCore::SeparatorType:
+        return kWKContextMenuItemTypeSeparator;
+    case WebCore::SubmenuType:
+        return kWKContextMenuItemTypeSubmenu;
+    default:
+        ASSERT_NOT_REACHED();
+        return kWKContextMenuItemTypeAction;
+    }
+}
+
 } // namespace WebKit
 
 #endif // WKSharedAPICast_h
diff --git a/WebKit2/Shared/WebContextMenuItem.cpp b/WebKit2/Shared/WebContextMenuItem.cpp
index 3765b43..bca6c8f 100644
--- a/WebKit2/Shared/WebContextMenuItem.cpp
+++ b/WebKit2/Shared/WebContextMenuItem.cpp
@@ -25,6 +25,9 @@
  
 #include "WebContextMenuItem.h"
 
+#include "ImmutableArray.h"
+#include <WebCore/ContextMenuItem.h>
+
 namespace WebKit {
 
 WebContextMenuItem::WebContextMenuItem(const WebContextMenuItemData& data)
@@ -32,5 +35,44 @@ WebContextMenuItem::WebContextMenuItem(const WebContextMenuItemData& data)
 {
 }
 
+PassRefPtr<WebContextMenuItem> WebContextMenuItem::create(const String& title, bool enabled, ImmutableArray* submenuItems)
+{
+    size_t size = submenuItems->size();
+    
+    Vector<WebContextMenuItemData> submenu;
+    submenu.reserveCapacity(size);
+    
+    for (size_t i = 0; i < size; ++i) {
+        WebContextMenuItem* item = submenuItems->at<WebContextMenuItem>(i);
+        if (item)
+            submenu.append(*item->data());
+    }
+    
+    return adoptRef(new WebContextMenuItem(WebContextMenuItemData(WebCore::ContextMenuItemTagNoAction, title, enabled, submenu))).leakRef();
+}
+
+WebContextMenuItem* WebContextMenuItem::separatorItem()
+{
+    static RefPtr<WebContextMenuItem> separatorItem = adoptRef(new WebContextMenuItem(WebContextMenuItemData(WebCore::SeparatorType, WebCore::ContextMenuItemTagNoAction, String(), true, false)));
+    return separatorItem.get();
+}
+
+PassRefPtr<ImmutableArray> WebContextMenuItem::submenuItemsAsImmutableArray() const
+{    
+    if (m_webContextMenuItemData.type() != WebCore::SubmenuType)
+        return ImmutableArray::create();
+
+    const Vector<WebContextMenuItemData>& submenuVector(m_webContextMenuItemData.submenu());
+    unsigned size = submenuVector.size();
+    
+    Vector<RefPtr<APIObject> > result;
+    result.reserveCapacity(size);
+    
+    for (unsigned i = 0; i < size; ++i)
+        result.append(WebContextMenuItem::create(submenuVector[i]));
+    
+    return ImmutableArray::adopt(result);
+}
+
 } // namespace WebKit
 
diff --git a/WebKit2/Shared/WebContextMenuItem.h b/WebKit2/Shared/WebContextMenuItem.h
index 5bfca4e..b2e6115 100644
--- a/WebKit2/Shared/WebContextMenuItem.h
+++ b/WebKit2/Shared/WebContextMenuItem.h
@@ -31,6 +31,8 @@
 
 namespace WebKit {
 
+class ImmutableArray;
+
 class WebContextMenuItem : public APIObject {
 public:
     static const Type APIType = TypeContextMenuItem;
@@ -39,6 +41,10 @@ public:
     {
         return adoptRef(new WebContextMenuItem(data));
     }
+    static PassRefPtr<WebContextMenuItem> create(const String& title, bool enabled, ImmutableArray* submenuItems);
+    static WebContextMenuItem* separatorItem();
+    
+    PassRefPtr<ImmutableArray> submenuItemsAsImmutableArray() const;
     
     WebContextMenuItemData* data() { return &m_webContextMenuItemData; }
 
diff --git a/WebKit2/UIProcess/API/C/WKPage.cpp b/WebKit2/UIProcess/API/C/WKPage.cpp
index c661e5c..b516efe 100644
--- a/WebKit2/UIProcess/API/C/WKPage.cpp
+++ b/WebKit2/UIProcess/API/C/WKPage.cpp
@@ -238,18 +238,18 @@ void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, bool caseIn
     toImpl(pageRef)->countStringMatches(toImpl(string)->string(), caseInsensitive, maxMatchCount);
 }
 
-void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClient* wkClient)
+void WKPageSetPageContextMenuClient(WKPageRef pageRef, const WKPageContextMenuClient* wkClient)
 {
     if (wkClient && wkClient->version)
         return;
-    toImpl(pageRef)->initializeLoaderClient(wkClient);
+    toImpl(pageRef)->initializeContextMenuClient(wkClient);
 }
 
-void WKPageSetPagePolicyClient(WKPageRef pageRef, const WKPagePolicyClient* wkClient)
+void WKPageSetPageFindClient(WKPageRef pageRef, const WKPageFindClient* wkClient)
 {
     if (wkClient && wkClient->version)
         return;
-    toImpl(pageRef)->initializePolicyClient(wkClient);
+    toImpl(pageRef)->initializeFindClient(wkClient);
 }
 
 void WKPageSetPageFormClient(WKPageRef pageRef, const WKPageFormClient* wkClient)
@@ -259,18 +259,25 @@ void WKPageSetPageFormClient(WKPageRef pageRef, const WKPageFormClient* wkClient
     toImpl(pageRef)->initializeFormClient(wkClient);
 }
 
-void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClient* wkClient)
+void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClient* wkClient)
 {
     if (wkClient && wkClient->version)
         return;
-    toImpl(pageRef)->initializeUIClient(wkClient);
+    toImpl(pageRef)->initializeLoaderClient(wkClient);
 }
 
-void WKPageSetPageFindClient(WKPageRef pageRef, const WKPageFindClient* wkClient)
+void WKPageSetPagePolicyClient(WKPageRef pageRef, const WKPagePolicyClient* wkClient)
 {
     if (wkClient && wkClient->version)
         return;
-    toImpl(pageRef)->initializeFindClient(wkClient);
+    toImpl(pageRef)->initializePolicyClient(wkClient);
+}
+
+void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClient* wkClient)
+{
+    if (wkClient && wkClient->version)
+        return;
+    toImpl(pageRef)->initializeUIClient(wkClient);
 }
 
 void WKPageRunJavaScriptInMainFrame(WKPageRef pageRef, WKStringRef scriptRef, void* context, WKPageRunJavaScriptFunction callback)
diff --git a/WebKit2/UIProcess/API/C/WKPage.h b/WebKit2/UIProcess/API/C/WKPage.h
index 8c618c3..2706618 100644
--- a/WebKit2/UIProcess/API/C/WKPage.h
+++ b/WebKit2/UIProcess/API/C/WKPage.h
@@ -203,6 +203,16 @@ enum {
     kWKMoreThanMaximumMatchCount = -1
 };
 
+// ContextMenu client
+typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKTypeRef userData, const void* clientInfo);
+
+struct WKPageContextMenuClient {
+    int                                                                 version;
+    const void *                                                        clientInfo;
+    WKPageGetContextMenuFromProposedContextMenuCallback                 getContextMenuFromProposedMenu;
+};
+typedef struct WKPageContextMenuClient WKPageContextMenuClient;
+
 WK_EXPORT WKTypeID WKPageGetTypeID();
 
 WK_EXPORT WKPageNamespaceRef WKPageGetPageNamespace(WKPageRef page);
@@ -275,11 +285,12 @@ WK_EXPORT void WKPageFindString(WKPageRef page, WKStringRef string, WKFindDirect
 WK_EXPORT void WKPageHideFindUI(WKPageRef page);
 WK_EXPORT void WKPageCountStringMatches(WKPageRef page, WKStringRef string, bool caseInsensitive, unsigned maxMatchCount);
 
+WK_EXPORT void WKPageSetPageContextMenuClient(WKPageRef page, const WKPageContextMenuClient* client);
+WK_EXPORT void WKPageSetPageFindClient(WKPageRef page, const WKPageFindClient* client);
+WK_EXPORT void WKPageSetPageFormClient(WKPageRef page, const WKPageFormClient* client);
 WK_EXPORT void WKPageSetPageLoaderClient(WKPageRef page, const WKPageLoaderClient* client);
 WK_EXPORT void WKPageSetPagePolicyClient(WKPageRef page, const WKPagePolicyClient* client);
-WK_EXPORT void WKPageSetPageFormClient(WKPageRef page, const WKPageFormClient* client);
 WK_EXPORT void WKPageSetPageUIClient(WKPageRef page, const WKPageUIClient* client);
-WK_EXPORT void WKPageSetPageFindClient(WKPageRef page, const WKPageFindClient* client);
 
 typedef void (*WKPageRunJavaScriptFunction)(WKStringRef, WKErrorRef, void*);
 WK_EXPORT void WKPageRunJavaScriptInMainFrame(WKPageRef page, WKStringRef script, void* context, WKPageRunJavaScriptFunction function);
diff --git a/WebKit2/UIProcess/WebPageContextMenuClient.cpp b/WebKit2/UIProcess/WebPageContextMenuClient.cpp
new file mode 100644
index 0000000..08bbd28
--- /dev/null
+++ b/WebKit2/UIProcess/WebPageContextMenuClient.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WebPageContextMenuClient.h"
+
+#include "Logging.h"
+#include "MutableArray.h"
+#include "WebContextMenuItem.h"
+#include "WKAPICast.h"
+#include "WKSharedAPICast.h"
+
+namespace WebKit {
+
+bool WebPageContextMenuClient::getContextMenuFromProposedMenu(WebPageProxy* page, const Vector<WebContextMenuItemData>& proposedMenuVector, Vector<WebContextMenuItemData>& customMenu, APIObject* userData)
+{
+    if (!m_client.getContextMenuFromProposedMenu)
+        return false;
+        
+    unsigned size = proposedMenuVector.size();
+    RefPtr<MutableArray> proposedMenu = MutableArray::create();
+    proposedMenu->reserveCapacity(size);
+    for (unsigned i = 0; i < size; ++i)
+        proposedMenu->append(WebContextMenuItem::create(proposedMenuVector[i]).get());
+        
+    WKArrayRef newMenu = 0;
+    m_client.getContextMenuFromProposedMenu(toAPI(page), toAPI(proposedMenu.get()), &newMenu, toAPI(userData), m_client.clientInfo);
+    RefPtr<ImmutableArray> array = adoptRef(toImpl(newMenu));
+    
+    customMenu.clear();
+    
+    size_t newSize = array ? array->size() : 0;
+    for (size_t i = 0; i < newSize; ++i) {
+        WebContextMenuItem* item = array->at<WebContextMenuItem>(i);
+        if (!item) {
+            LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i);
+            continue;
+        }
+        
+        customMenu.append(*item->data());
+    }
+    
+    return true;
+}
+
+} // namespace WebKit
diff --git a/WebKit2/UIProcess/WebPageContextMenuClient.h b/WebKit2/UIProcess/WebPageContextMenuClient.h
new file mode 100644
index 0000000..33019bd
--- /dev/null
+++ b/WebKit2/UIProcess/WebPageContextMenuClient.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebPageContextMenuClient_h
+#define WebPageContextMenuClient_h
+
+#include "APIClient.h"
+#include "WKPage.h"
+#include <wtf/Vector.h>
+
+namespace WebKit {
+
+class APIObject;
+class WebContextMenuItemData;
+class WebPageProxy;
+
+class WebPageContextMenuClient : public APIClient<WKPageContextMenuClient> {
+public:
+    bool getContextMenuFromProposedMenu(WebPageProxy*, const Vector<WebContextMenuItemData>& proposedMenu, Vector<WebContextMenuItemData>& customMenu, APIObject* userData);
+};
+
+} // namespace WebKit
+
+#endif // WebPageContextMenuClient_h
diff --git a/WebKit2/UIProcess/WebPageProxy.cpp b/WebKit2/UIProcess/WebPageProxy.cpp
index c5509d3..59fb431 100644
--- a/WebKit2/UIProcess/WebPageProxy.cpp
+++ b/WebKit2/UIProcess/WebPageProxy.cpp
@@ -163,6 +163,11 @@ void WebPageProxy::initializeFindClient(const WKPageFindClient* client)
     m_findClient.initialize(client);
 }
 
+void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClient* client)
+{
+    m_contextMenuClient.initialize(client);
+}
+
 void WebPageProxy::relaunch()
 {
     m_isValid = true;
@@ -1171,14 +1176,28 @@ void WebPageProxy::hidePopupMenu()
     m_activePopupMenu = 0;
 }
 
-void WebPageProxy::showContextMenu(const WebCore::IntPoint& menuLocation, const Vector<WebContextMenuItemData>& items)
+void WebPageProxy::showContextMenu(const WebCore::IntPoint& menuLocation, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments)
 {
+    RefPtr<APIObject> userData;
+    WebContextUserMessageDecoder messageDecoder(userData, pageNamespace()->context());
+    if (!arguments->decode(messageDecoder))
+        return;
+
     if (m_activeContextMenu)
         m_activeContextMenu->hideContextMenu();
     else
         m_activeContextMenu = m_pageClient->createContextMenuProxy(this);
-      
-    m_activeContextMenu->showContextMenu(menuLocation, items);
+
+    // Give the PageContextMenuClient one last swipe at changing the menu.
+    Vector<WebContextMenuItemData> items;
+        
+    if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, userData.get())) {
+        m_activeContextMenu->showContextMenu(menuLocation, proposedItems);
+        return;
+    }
+    
+    if (items.size())
+        m_activeContextMenu->showContextMenu(menuLocation, items);
 }
 
 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
diff --git a/WebKit2/UIProcess/WebPageProxy.h b/WebKit2/UIProcess/WebPageProxy.h
index b47ec19..adea894 100644
--- a/WebKit2/UIProcess/WebPageProxy.h
+++ b/WebKit2/UIProcess/WebPageProxy.h
@@ -32,6 +32,7 @@
 #include "GenericCallback.h"
 #include "SharedMemory.h"
 #include "WKBase.h"
+#include "WebPageContextMenuClient.h"
 #include "WebContextMenuItemData.h"
 #include "WebEvent.h"
 #include "WebFindClient.h"
@@ -119,11 +120,12 @@ public:
     WebInspectorProxy* inspector();
 
     void setPageClient(PageClient*);
+    void initializeContextMenuClient(const WKPageContextMenuClient*);
+    void initializeFindClient(const WKPageFindClient*);
+    void initializeFormClient(const WKPageFormClient*);
     void initializeLoaderClient(const WKPageLoaderClient*);
     void initializePolicyClient(const WKPagePolicyClient*);
-    void initializeFormClient(const WKPageFormClient*);
     void initializeUIClient(const WKPageUIClient*);
-    void initializeFindClient(const WKPageFindClient*);
     void relaunch();
 
     void initializeWebPage(const WebCore::IntSize&);
@@ -340,7 +342,7 @@ private:
     void hidePopupMenu();
 
     // Context Menu.
-    void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>& items);
+    void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>&, CoreIPC::ArgumentDecoder*);
 
     void takeFocus(bool direction);
     void setToolTip(const String&);
@@ -366,6 +368,7 @@ private:
     WebFormClient m_formClient;
     WebUIClient m_uiClient;
     WebFindClient m_findClient;
+    WebPageContextMenuClient m_contextMenuClient;
 
     OwnPtr<DrawingAreaProxy> m_drawingArea;
     RefPtr<WebPageNamespace> m_pageNamespace;
diff --git a/WebKit2/UIProcess/WebPageProxy.messages.in b/WebKit2/UIProcess/WebPageProxy.messages.in
index d116d6c..fd7d6a8 100644
--- a/WebKit2/UIProcess/WebPageProxy.messages.in
+++ b/WebKit2/UIProcess/WebPageProxy.messages.in
@@ -128,7 +128,7 @@ messages -> WebPageProxy {
     HidePopupMenu()
     
     # ContextMenu
-    ShowContextMenu(WebCore::IntPoint point, Vector<WebKit::WebContextMenuItemData> items)
+    ShowContextMenu(WebCore::IntPoint point, Vector<WebKit::WebContextMenuItemData> items, WebKit::InjectedBundleUserMessageEncoder userData)
 
 #if USE(ACCELERATED_COMPOSITING)
     # Accelerated compsiting messages.
diff --git a/WebKit2/WebKit2.pro b/WebKit2/WebKit2.pro
index fca8f06..560de5e 100644
--- a/WebKit2/WebKit2.pro
+++ b/WebKit2/WebKit2.pro
@@ -200,6 +200,8 @@ HEADERS += \
     Platform/qt/MappedMemoryPool.h \
     Shared/API/c/WKBase.h \
     Shared/API/c/WKCertificateInfo.h \
+    Shared/API/c/WKContextMenuItem.h \
+    Shared/API/c/WKContextMenuItemTypes.h \
     Shared/API/c/WKGeometry.h \
     Shared/API/c/WKNumber.h \
     Shared/API/c/WKSerializedScriptValue.h \
@@ -302,6 +304,7 @@ HEADERS += \
     UIProcess/WebInspectorProxy.h \
     UIProcess/WebLoaderClient.h \
     UIProcess/WebNavigationData.h \
+    UIProcess/WebPageContextMenuClient.h \
     UIProcess/WebPageNamespace.h \
     UIProcess/WebPageProxy.h \
     UIProcess/WebPolicyClient.h \
@@ -385,6 +388,7 @@ SOURCES += \
     Platform/qt/WorkQueueQt.cpp \
     Shared/API/c/WKArray.cpp \
     Shared/API/c/WKCertificateInfo.cpp \
+    Shared/API/c/WKContextMenuItem.cpp \
     Shared/API/c/WKNumber.cpp \
     Shared/API/c/WKSerializedScriptValue.cpp \
     Shared/API/c/WKString.cpp \
@@ -474,6 +478,7 @@ SOURCES += \
     UIProcess/WebInspectorProxy.cpp \
     UIProcess/WebLoaderClient.cpp \
     UIProcess/WebNavigationData.cpp \
+    UIProcess/WebPageContextMenuClient.cpp \
     UIProcess/WebPageNamespace.cpp \
     UIProcess/WebPageProxy.cpp \
     UIProcess/WebPolicyClient.cpp \
diff --git a/WebKit2/WebKit2.xcodeproj/project.pbxproj b/WebKit2/WebKit2.xcodeproj/project.pbxproj
index de0964d..b796c46 100644
--- a/WebKit2/WebKit2.xcodeproj/project.pbxproj
+++ b/WebKit2/WebKit2.xcodeproj/project.pbxproj
@@ -198,10 +198,15 @@
 		512935D81288D19400A4B695 /* WebContextMenuItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 512935D61288D19400A4B695 /* WebContextMenuItem.h */; };
 		512935E31288D97800A4B695 /* InjectedBundlePageContextMenuClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 512935E11288D97800A4B695 /* InjectedBundlePageContextMenuClient.cpp */; };
 		512935E41288D97800A4B695 /* InjectedBundlePageContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 512935E21288D97800A4B695 /* InjectedBundlePageContextMenuClient.h */; };
+		5153569C1291B1D2000749DC /* WebPageContextMenuClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5153569A1291B1D2000749DC /* WebPageContextMenuClient.cpp */; };
+		5153569D1291B1D2000749DC /* WebPageContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 5153569B1291B1D2000749DC /* WebPageContextMenuClient.h */; };
 		51578B831209ECEF00A37C4A /* WebData.h in Headers */ = {isa = PBXBuildFile; fileRef = 51578B821209ECEF00A37C4A /* WebData.h */; };
 		516A4A5D120A2CCD00C05B7F /* WebError.h in Headers */ = {isa = PBXBuildFile; fileRef = 516A4A5B120A2CCD00C05B7F /* WebError.h */; };
 		51871B5B127CB89D00F76232 /* WebContextMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51871B59127CB89D00F76232 /* WebContextMenu.cpp */; };
 		51871B5C127CB89D00F76232 /* WebContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 51871B5A127CB89D00F76232 /* WebContextMenu.h */; };
+		51A555F5128C6C47009ABCEC /* WKContextMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A555F3128C6C47009ABCEC /* WKContextMenuItem.cpp */; };
+		51A555F6128C6C47009ABCEC /* WKContextMenuItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A555F4128C6C47009ABCEC /* WKContextMenuItem.h */; };
+		51A55601128C6D92009ABCEC /* WKContextMenuItemTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A55600128C6D92009ABCEC /* WKContextMenuItemTypes.h */; };
 		51A7F2F3125BF820008AEB1D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A7F2F2125BF820008AEB1D /* Logging.h */; };
 		51A7F2F5125BF8D4008AEB1D /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A7F2F4125BF8D4008AEB1D /* Logging.cpp */; };
 		51A84CE3127F386B00CA6EA4 /* WebContextMenuProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A84CE2127F386B00CA6EA4 /* WebContextMenuProxy.cpp */; };
@@ -758,10 +763,15 @@
 		512935D61288D19400A4B695 /* WebContextMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebContextMenuItem.h; sourceTree = "<group>"; };
 		512935E11288D97800A4B695 /* InjectedBundlePageContextMenuClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageContextMenuClient.cpp; sourceTree = "<group>"; };
 		512935E21288D97800A4B695 /* InjectedBundlePageContextMenuClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundlePageContextMenuClient.h; sourceTree = "<group>"; };
+		5153569A1291B1D2000749DC /* WebPageContextMenuClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPageContextMenuClient.cpp; sourceTree = "<group>"; };
+		5153569B1291B1D2000749DC /* WebPageContextMenuClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageContextMenuClient.h; sourceTree = "<group>"; };
 		51578B821209ECEF00A37C4A /* WebData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebData.h; sourceTree = "<group>"; };
 		516A4A5B120A2CCD00C05B7F /* WebError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebError.h; sourceTree = "<group>"; };
 		51871B59127CB89D00F76232 /* WebContextMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebContextMenu.cpp; sourceTree = "<group>"; };
 		51871B5A127CB89D00F76232 /* WebContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebContextMenu.h; sourceTree = "<group>"; };
+		51A555F3128C6C47009ABCEC /* WKContextMenuItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKContextMenuItem.cpp; sourceTree = "<group>"; };
+		51A555F4128C6C47009ABCEC /* WKContextMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContextMenuItem.h; sourceTree = "<group>"; };
+		51A55600128C6D92009ABCEC /* WKContextMenuItemTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContextMenuItemTypes.h; sourceTree = "<group>"; };
 		51A7F2F2125BF820008AEB1D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
 		51A7F2F4125BF8D4008AEB1D /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logging.cpp; sourceTree = "<group>"; };
 		51A84CE2127F386B00CA6EA4 /* WebContextMenuProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebContextMenuProxy.cpp; sourceTree = "<group>"; };
@@ -1676,6 +1686,8 @@
 				BC59534010FC04520098F82D /* WebLoaderClient.h */,
 				BCF69FA11176D01400471A52 /* WebNavigationData.cpp */,
 				BCF69FA01176D01400471A52 /* WebNavigationData.h */,
+				5153569A1291B1D2000749DC /* WebPageContextMenuClient.cpp */,
+				5153569B1291B1D2000749DC /* WebPageContextMenuClient.h */,
 				BCEE98C4113314D7006BCC24 /* WebPageNamespace.cpp */,
 				BCEE98C5113314D7006BCC24 /* WebPageNamespace.h */,
 				BC111B0B112F5E4F00337BAB /* WebPageProxy.cpp */,
@@ -2042,6 +2054,9 @@
 				BCDDB316124EBD130048D13C /* WKBase.h */,
 				BC4075D9124FF0270068F20A /* WKCertificateInfo.cpp */,
 				BC4075DA124FF0270068F20A /* WKCertificateInfo.h */,
+				51A555F3128C6C47009ABCEC /* WKContextMenuItem.cpp */,
+				51A555F4128C6C47009ABCEC /* WKContextMenuItem.h */,
+				51A55600128C6D92009ABCEC /* WKContextMenuItemTypes.h */,
 				BC4075DB124FF0270068F20A /* WKData.cpp */,
 				BC4075DC124FF0270068F20A /* WKData.h */,
 				BC4075DD124FF0270068F20A /* WKDictionary.cpp */,
@@ -2402,9 +2417,12 @@
 				512935E41288D97800A4B695 /* InjectedBundlePageContextMenuClient.h in Headers */,
 				1AB7D72C1288CAAD00CFD08C /* WebDownloadClient.h in Headers */,
 				1AB7D78D1288CD9A00CFD08C /* WKDownload.h in Headers */,
+				51A555F6128C6C47009ABCEC /* WKContextMenuItem.h in Headers */,
+				51A55601128C6D92009ABCEC /* WKContextMenuItemTypes.h in Headers */,
 				BCEE7DC5128B645D009827DA /* InjectedBundleClient.h in Headers */,
 				ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */,
 				1CA8B946127C882A00576C2B /* WebInspectorProxyMessages.h in Headers */,
+				5153569D1291B1D2000749DC /* WebPageContextMenuClient.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2757,11 +2775,13 @@
 				512935E31288D97800A4B695 /* InjectedBundlePageContextMenuClient.cpp in Sources */,
 				1AB7D72D1288CAAD00CFD08C /* WebDownloadClient.cpp in Sources */,
 				1AB7D78E1288CD9A00CFD08C /* WKDownload.cpp in Sources */,
+				51A555F5128C6C47009ABCEC /* WKContextMenuItem.cpp in Sources */,
 				BCEE7DC6128B645D009827DA /* InjectedBundleClient.cpp in Sources */,
 				1CA8B936127C774E00576C2B /* WebInspectorProxyMac.mm in Sources */,
 				1CA8B945127C882A00576C2B /* WebInspectorProxyMessageReceiver.cpp in Sources */,
 				1CA8B954127C891500576C2B /* WebInspectorMac.mm in Sources */,
 				EDCA71B7128DDA8C00201B26 /* WKBundlePageOverlay.cpp in Sources */,
+				5153569C1291B1D2000749DC /* WebPageContextMenuClient.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h b/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
index fd1bcb5..aa58930 100644
--- a/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
+++ b/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
@@ -182,7 +182,7 @@ struct WKBundlePageFormClient {
 typedef struct WKBundlePageFormClient WKBundlePageFormClient;
 
 // ContextMenu client
-typedef void (*WKBundlePageGetContextMenuFromDefaultContextMenuCallback)(WKBundlePageRef page, WKBundleHitTestResultRef hitTestResult, WKArrayRef defaultMenu, WKArrayRef* newMenu, const void* clientInfo);
+typedef void (*WKBundlePageGetContextMenuFromDefaultContextMenuCallback)(WKBundlePageRef page, WKBundleHitTestResultRef hitTestResult, WKArrayRef defaultMenu, WKArrayRef* newMenu, WKTypeRef* userData, const void* clientInfo);
 
 struct WKBundlePageContextMenuClient {
     int                                                                 version;
diff --git a/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp
index c80c0be..a2d16cb 100644
--- a/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp
+++ b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp
@@ -38,24 +38,21 @@ using namespace WebCore;
 
 namespace WebKit {
 
-bool InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems(WebPage* page, WebCore::ContextMenu* defaultMenu, Vector<WebContextMenuItemData>& newMenu)
+bool InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems(WebPage* page, InjectedBundleHitTestResult* hitTestResult, const Vector<WebContextMenuItemData>& defaultMenu, Vector<WebContextMenuItemData>& newMenu, RefPtr<APIObject>& userData)
 {
     if (!m_client.getContextMenuFromDefaultMenu)
         return false;
 
-    RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(defaultMenu->hitTestResult());
-    
-    Vector<WebCore::ContextMenuItem> coreItems = WebCore::contextMenuItemVector(defaultMenu->platformDescription());
-    Vector<WebContextMenuItemData> webItems = kitItems(coreItems, defaultMenu);
-
     RefPtr<MutableArray> defaultMenuArray = MutableArray::create();
-    defaultMenuArray->reserveCapacity(webItems.size());
-    for (unsigned i = 0; i < webItems.size(); ++i)
-        defaultMenuArray->append(WebContextMenuItem::create(webItems[i]).get());
+    defaultMenuArray->reserveCapacity(defaultMenu.size());
+    for (unsigned i = 0; i < defaultMenu.size(); ++i)
+        defaultMenuArray->append(WebContextMenuItem::create(defaultMenu[i]).get());
 
     WKArrayRef newMenuWK = 0;
-    m_client.getContextMenuFromDefaultMenu(toAPI(page), toAPI(hitTestResult.get()), toAPI(defaultMenuArray.get()), &newMenuWK, m_client.clientInfo);
+    WKTypeRef userDataToPass = 0;
+    m_client.getContextMenuFromDefaultMenu(toAPI(page), toAPI(hitTestResult), toAPI(defaultMenuArray.get()), &newMenuWK, &userDataToPass, m_client.clientInfo);
     RefPtr<ImmutableArray> array = adoptRef(toImpl(newMenuWK));
+    userData = adoptRef(toImpl(userDataToPass));
     
     newMenu.clear();
     
diff --git a/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h
index 9a25e28..1d17a8a 100644
--- a/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h
+++ b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h
@@ -36,12 +36,14 @@ namespace WebCore {
 
 namespace WebKit {
 
+class APIObject;
+class InjectedBundleHitTestResult;
 class WebContextMenuItemData;
 class WebPage;
 
 class InjectedBundlePageContextMenuClient : public APIClient<WKBundlePageContextMenuClient> {
 public:
-    bool getCustomMenuFromDefaultItems(WebPage*, WebCore::ContextMenu* defaultMenu, Vector<WebContextMenuItemData>& newMenu);
+    bool getCustomMenuFromDefaultItems(WebPage*, InjectedBundleHitTestResult*, const Vector<WebContextMenuItemData>& defaultMenu, Vector<WebContextMenuItemData>& newMenu, RefPtr<APIObject>& userData);
 };
 
 } // namespace WebKit
diff --git a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
index 4a541c7..2fad128 100644
--- a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
+++ b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
@@ -43,12 +43,8 @@ void WebContextMenuClient::contextMenuDestroyed()
 
 PlatformMenuDescription WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu)
 {
-    Vector<WebContextMenuItemData> newMenu;
-    if (!m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, menu, newMenu))
-        return menu->platformDescription();
-    
-    Vector<ContextMenuItem> coreItemVector = coreItems(newMenu);
-    return platformMenuDescription(coreItemVector);
+    // WebKit2 ignores this client callback and does context menu customization when it is told to show the menu.
+    return menu->platformDescription();
 }
 
 void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem*, const ContextMenu*)
diff --git a/WebKit2/WebProcess/WebPage/WebContextMenu.cpp b/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
index 29ff339..6ce928e 100644
--- a/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
+++ b/WebKit2/WebProcess/WebPage/WebContextMenu.cpp
@@ -21,6 +21,7 @@
 
 #include "WebContextMenu.h"
 
+#include "InjectedBundleUserMessageCoders.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
@@ -58,10 +59,16 @@ void WebContextMenu::show()
     if (!view)
         return;
 
-    IntPoint point = view->contentsToWindow(menu->hitTestResult().point());
-    Vector<ContextMenuItem> items = contextMenuItemVector(menu->platformDescription());
+    // Give the bundle client a chance to process the menu.
+    Vector<ContextMenuItem> coreItems = contextMenuItemVector(menu->platformDescription());
+    Vector<WebContextMenuItemData> proposedMenu = kitItems(coreItems, menu);
+    Vector<WebContextMenuItemData> newMenu;
+    RefPtr<APIObject> userData;
+    if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, 0, proposedMenu, newMenu, userData))
+        proposedMenu = newMenu;
 
-    m_page->send(Messages::WebPageProxy::ShowContextMenu(point, kitItems(items, menu)));
+    // Notify the UIProcess.
+    m_page->send(Messages::WebPageProxy::ShowContextMenu(view->contentsToWindow(menu->hitTestResult().point()), proposedMenu, InjectedBundleUserMessageEncoder(userData.get())));
 }
 
 void WebContextMenu::itemSelected(const WebContextMenuItemData& item)
diff --git a/WebKit2/win/WebKit2.vcproj b/WebKit2/win/WebKit2.vcproj
index baba0b6..f80b7a7 100755
--- a/WebKit2/win/WebKit2.vcproj
+++ b/WebKit2/win/WebKit2.vcproj
@@ -668,6 +668,18 @@
 					>
 				</File>
 				<File
+					RelativePath="..\Shared\API\c\WKContextMenuItem.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\Shared\API\c\WKContextMenuItem.h"
+					>
+				</File>
+				<File
+					RelativePath="..\Shared\API\c\WKContextMenuItemTypes.h"
+					>
+				</File>
+				<File
 					RelativePath="..\Shared\API\c\win\WKCertificateInfoWin.cpp"
 					>
 				</File>
@@ -1865,6 +1877,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\UIProcess\WebPageContextMenuClient.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\UIProcess\WebPageContextMenuClient.h"
+				>
+			</File>
+			<File
 				RelativePath="..\UIProcess\WebPageNamespace.cpp"
 				>
 			</File>

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list