[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:38:52 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 42bd97cb9ba6c2d0f83686f0008a468878918b09
Author: beidson at apple.com <beidson at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Nov 9 22:56:14 2010 +0000

    WebCore: <rdar://problem/8613727> and https://bugs.webkit.org/show_bug.cgi?id=48720
    Customizable context menu support in WebKit2.
    
    Reviewed by Darin Adler.
    
    Various WebCore support to allow WebKit2 to create new ContextMenuItems with
    the information it has.
    
    * WebCore.exp.in:
    
    * platform/ContextMenu.h:
    * platform/ContextMenuItem.h:
    
    * platform/mac/ContextMenuItemMac.mm:
    (WebCore::ContextMenuItem::ContextMenuItem):
    (WebCore::ContextMenuItem::setSubMenu):
    * platform/mac/ContextMenuMac.mm:
    (WebCore::platformMenuDescription):
    
    * platform/qt/ContextMenuItemQt.cpp:
    (WebCore::ContextMenuItem::ContextMenuItem):
    (WebCore::ContextMenuItem::setSubMenu):
    * platform/qt/ContextMenuQt.cpp:
    (WebCore::platformMenuDescription):
    
    * platform/win/ContextMenuItemWin.cpp:
    (WebCore::ContextMenuItem::ContextMenuItem):
    (WebCore::ContextMenuItem::setSubMenu):
    * platform/win/ContextMenuWin.cpp:
    (WebCore::platformMenuDescription):
    
    WebKit2: Part of <rdar://problem/8613727> and https://bugs.webkit.org/show_bug.cgi?id=48720
    Customizable context menu support in WebKit2.
    
    Reviewed by Darin Adler.
    
    This adds a BundlePageContextMenu client and lets WebKit2 consult it with the proposed
    list of WebContextMenuItems.
    There is no realistic API for the embedding app to actually inspect or create new
    WebContextMenuItems (will be "WKContextMenuItem") and that ability will come later.
    
    * WebKit2.pro:
    * WebKit2.xcodeproj/project.pbxproj:
    * win/WebKit2.vcproj:
    
    * Platform/Logging.cpp:
    (initializeLogChannelsIfNecessary):
    * Platform/Logging.h:
    
    * Shared/APIObject.h:
    
    * Shared/MutableArray.cpp:
    (WebKit::MutableArray::reserveCapacity):
    * Shared/MutableArray.h:
    
    * Shared/WebContextMenuItem.cpp: Added.
    (WebKit::WebContextMenuItem::WebContextMenuItem):
    (WebKit::WebContextMenuItem::data):
    * Shared/WebContextMenuItem.h: Added.
    (WebKit::WebContextMenuItem::create):
    (WebKit::WebContextMenuItem::type):
    
    * Shared/WebContextMenuItemData.cpp:
    (WebKit::WebContextMenuItemData::core):
    (WebKit::kitItems):
    (WebKit::coreItems):
    * Shared/WebContextMenuItemData.h:
    
    * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
    (WKBundlePageSetContextMenuClient):
    * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
    
    * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp: Added.
    (WebKit::InjectedBundlePageContextMenuClient::InjectedBundlePageContextMenuClient):
    (WebKit::InjectedBundlePageContextMenuClient::initialize):
    (WebKit::InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems):
    * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h: Added.
    
    * WebProcess/WebCoreSupport/WebContextMenuClient.cpp:
    (WebKit::WebContextMenuClient::getCustomMenuFromDefaultItems): Call through to the injected bundle client
      with the default items and convert the returned items back for WebCore to use.
    
    * WebProcess/WebPage/WebPage.cpp:
    (WebKit::WebPage::initializeInjectedBundleContextMenuClient):
    * WebProcess/WebPage/WebPage.h:
    (WebKit::WebPage::injectedBundleContextMenuClient):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71682 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e0a979e..4a140c8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,36 @@
+2010-11-09  Brady Eidson  <beidson at apple.com>
+
+        Reviewed by Darin Adler.
+
+        <rdar://problem/8613727> and https://bugs.webkit.org/show_bug.cgi?id=48720
+        Customizable context menu support in WebKit2.
+
+        Various WebCore support to allow WebKit2 to create new ContextMenuItems with
+        the information it has.
+
+        * WebCore.exp.in:
+
+        * platform/ContextMenu.h:
+        * platform/ContextMenuItem.h:
+
+        * platform/mac/ContextMenuItemMac.mm:
+        (WebCore::ContextMenuItem::ContextMenuItem):
+        (WebCore::ContextMenuItem::setSubMenu):
+        * platform/mac/ContextMenuMac.mm:
+        (WebCore::platformMenuDescription):
+
+        * platform/qt/ContextMenuItemQt.cpp:
+        (WebCore::ContextMenuItem::ContextMenuItem):
+        (WebCore::ContextMenuItem::setSubMenu):
+        * platform/qt/ContextMenuQt.cpp:
+        (WebCore::platformMenuDescription):
+
+        * platform/win/ContextMenuItemWin.cpp:
+        (WebCore::ContextMenuItem::ContextMenuItem):
+        (WebCore::ContextMenuItem::setSubMenu):
+        * platform/win/ContextMenuWin.cpp:
+        (WebCore::platformMenuDescription):
+
 2010-11-09  Sam Weinig  <sam at webkit.org>
 
         Reviewed by Anders Carlsson.
diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in
index 18cc68b..10494e2 100644
--- a/WebCore/WebCore.exp.in
+++ b/WebCore/WebCore.exp.in
@@ -1235,11 +1235,14 @@ __ZN7WebCore11ContextMenu22setPlatformDescriptionEP14NSMutableArray
 __ZN7WebCore12EventHandler20sendContextMenuEventEP7NSEvent
 __ZN7WebCore12EventHandler20sendContextMenuEventERKNS_18PlatformMouseEventE
 __ZN7WebCore15ContextMenuItem26releasePlatformDescriptionEv
+__ZN7WebCore15ContextMenuItemC1ENS_17ContextMenuActionERKN3WTF6StringEbbRNS2_6VectorIS0_Lm0EEE
 __ZN7WebCore15ContextMenuItemC1ENS_19ContextMenuItemTypeENS_17ContextMenuActionERKN3WTF6StringEPNS_11ContextMenuE
+__ZN7WebCore15ContextMenuItemC1ENS_19ContextMenuItemTypeENS_17ContextMenuActionERKN3WTF6StringEbb
 __ZN7WebCore15ContextMenuItemD1Ev
 __ZN7WebCore21ContextMenuController16clearContextMenuEv
 __ZN7WebCore21ContextMenuController23contextMenuItemSelectedEPNS_15ContextMenuItemE
 __ZN7WebCore21contextMenuItemVectorEP14NSMutableArray
+__ZN7WebCore23platformMenuDescriptionERN3WTF6VectorINS_15ContextMenuItemELm0EEE
 __ZN7WebCore6Chrome15showContextMenuEv
 __ZNK7WebCore11ContextMenu19platformDescriptionEv
 __ZNK7WebCore11ContextMenu21checkOrEnableIfNeededERNS_15ContextMenuItemE
diff --git a/WebCore/platform/ContextMenu.h b/WebCore/platform/ContextMenu.h
index 2a2a017..a162fe4 100644
--- a/WebCore/platform/ContextMenu.h
+++ b/WebCore/platform/ContextMenu.h
@@ -92,6 +92,7 @@ namespace WebCore {
     };
 
 Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription);
+PlatformMenuDescription platformMenuDescription(Vector<ContextMenuItem>&);
 
 }
 
diff --git a/WebCore/platform/ContextMenuItem.h b/WebCore/platform/ContextMenuItem.h
index f7fa5e6..e702921 100644
--- a/WebCore/platform/ContextMenuItem.h
+++ b/WebCore/platform/ContextMenuItem.h
@@ -257,6 +257,9 @@ namespace WebCore {
         ContextMenuItem(PlatformMenuItemDescription);
         ContextMenuItem(ContextMenu* subMenu = 0);
         ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu = 0);
+
+        ContextMenuItem(ContextMenuItemType, ContextMenuAction, const String&, bool enabled, bool checked);
+        ContextMenuItem(ContextMenuAction, const String&, bool enabled, bool checked, Vector<ContextMenuItem>& submenuItems);
 #if PLATFORM(GTK)
         ContextMenuItem(GtkMenuItem*);
 #endif
@@ -275,6 +278,7 @@ namespace WebCore {
 
         PlatformMenuDescription platformSubMenu() const;
         void setSubMenu(ContextMenu*);
+        void setSubMenu(Vector<ContextMenuItem>&);
 
         void setChecked(bool = true);
         bool checked() const;
diff --git a/WebCore/platform/mac/ContextMenuItemMac.mm b/WebCore/platform/mac/ContextMenuItemMac.mm
index ce779ec..2d72ba9 100644
--- a/WebCore/platform/mac/ContextMenuItemMac.mm
+++ b/WebCore/platform/mac/ContextMenuItemMac.mm
@@ -58,22 +58,39 @@ ContextMenuItem::ContextMenuItem(ContextMenu* subMenu)
         setSubMenu(subMenu);
 }
 
-ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu)
+static PlatformMenuItemDescription createPlatformMenuItemDescription(ContextMenuItemType type, ContextMenuAction action, const String& title, bool enabled, bool checked)
 {
-    if (type == SeparatorType) {
-        m_platformDescription = [NSMenuItem separatorItem];
-        return;
-    }
+    if (type == SeparatorType)
+        return [[NSMenuItem separatorItem] retain];
 
     NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""];
-    m_platformDescription = item;
-    [item release];
+    [item setEnabled:enabled];
+    [item setState:checked ? NSOnState : NSOffState];
+    [item setTag:action];
+
+    return item;
+}
+
+ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu)
+{
+    m_platformDescription.adoptNS(createPlatformMenuItemDescription(type, action, title, true, false));
 
-    [m_platformDescription.get() setTag:action];
     if (subMenu)
         setSubMenu(subMenu);
 }
 
+ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, bool enabled, bool checked)
+{
+    m_platformDescription.adoptNS(createPlatformMenuItemDescription(type, action, title, enabled, checked));
+}
+
+ContextMenuItem::ContextMenuItem(ContextMenuAction action, const String& title, bool enabled, bool checked, Vector<ContextMenuItem>& subMenuItems)
+{
+    m_platformDescription.adoptNS(createPlatformMenuItemDescription(SubmenuType, action, title, enabled, checked));
+    
+    setSubMenu(subMenuItems);
+}
+
 ContextMenuItem::~ContextMenuItem()
 {
 }
@@ -136,6 +153,17 @@ void ContextMenuItem::setSubMenu(ContextMenu* menu)
     [subMenu release];
 }
 
+void ContextMenuItem::setSubMenu(Vector<ContextMenuItem>& subMenuItems)
+{
+    NSMenu* subMenu = [[NSMenu alloc] init];
+    [subMenu setAutoenablesItems:NO];
+    for (unsigned i = 0; i < subMenuItems.size(); ++i)
+        [subMenu addItem:subMenuItems[i].releasePlatformDescription()];
+        
+    [m_platformDescription.get() setSubmenu:subMenu];
+    [subMenu release];
+}
+
 void ContextMenuItem::setChecked(bool checked)
 {
     if (checked)
diff --git a/WebCore/platform/mac/ContextMenuMac.mm b/WebCore/platform/mac/ContextMenuMac.mm
index c427e3c..7c91028 100644
--- a/WebCore/platform/mac/ContextMenuMac.mm
+++ b/WebCore/platform/mac/ContextMenuMac.mm
@@ -166,6 +166,18 @@ Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription menu)
     return items;
 }
 
+PlatformMenuDescription platformMenuDescription(Vector<ContextMenuItem>& menuItemVector)
+{
+    PlatformMenuDescription platformMenu = [[NSMutableArray alloc] initWithCapacity:menuItemVector.size()];
+    for (unsigned i = 0; i < menuItemVector.size(); ++i) {
+        PlatformMenuItemDescription platformItem = menuItemVector[i].releasePlatformDescription();
+        [platformMenu addObject:platformItem];
+        [platformItem release];
+    }
+    
+    return [platformMenu autorelease];
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/platform/qt/ContextMenuItemQt.cpp b/WebCore/platform/qt/ContextMenuItemQt.cpp
index a65e50c..2a36b87 100644
--- a/WebCore/platform/qt/ContextMenuItemQt.cpp
+++ b/WebCore/platform/qt/ContextMenuItemQt.cpp
@@ -49,6 +49,16 @@ ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction act
         setSubMenu(subMenu);
 }
 
+ContextMenuItem::ContextMenuItem(ContextMenuItemType, ContextMenuAction, const String&, bool, bool)
+{
+    // FIXME: Implement
+}
+
+ContextMenuItem::ContextMenuItem(ContextMenuAction, const String&, bool, bool, Vector<ContextMenuItem>&)
+{
+    // FIXME: Implement
+}
+
 ContextMenuItem::~ContextMenuItem()
 {
 }
@@ -99,6 +109,11 @@ void ContextMenuItem::setSubMenu(ContextMenu* menu)
     m_platformDescription.subMenuItems = *menu->platformDescription();
 }
 
+void ContextMenuItem::setSubMenu(Vector<ContextMenuItem>&)
+{
+    // FIXME: Implement
+}
+
 void ContextMenuItem::setChecked(bool on)
 {
     m_platformDescription.checked = on;
diff --git a/WebCore/platform/qt/ContextMenuQt.cpp b/WebCore/platform/qt/ContextMenuQt.cpp
index 2c1a6cb..e3715c9 100644
--- a/WebCore/platform/qt/ContextMenuQt.cpp
+++ b/WebCore/platform/qt/ContextMenuQt.cpp
@@ -80,5 +80,11 @@ Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription)
     return Vector<ContextMenuItem>();
 }
 
+PlatformMenuDescription platformMenuDescription(Vector<ContextMenuItem>& menuItemVector)
+{
+    // FIXME - Implement    
+    return 0;
+}
+
 }
 // vim: ts=4 sw=4 et
diff --git a/WebCore/platform/win/ContextMenuItemWin.cpp b/WebCore/platform/win/ContextMenuItemWin.cpp
index d2ce76d..8d1c175 100644
--- a/WebCore/platform/win/ContextMenuItemWin.cpp
+++ b/WebCore/platform/win/ContextMenuItemWin.cpp
@@ -95,6 +95,16 @@ ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction act
     m_platformDescription->dwTypeData = wcsdup(t.charactersWithNullTermination());
 }
 
+ContextMenuItem::ContextMenuItem(ContextMenuItemType, ContextMenuAction, const String&, bool, bool)
+{
+    // FIXME: Implement
+}
+
+ContextMenuItem::ContextMenuItem(ContextMenuAction, const String&, bool, bool, Vector<ContextMenuItem>&)
+{
+    // FIXME: Implement
+}
+
 ContextMenuItem::~ContextMenuItem()
 {
     if (m_platformDescription) {
@@ -172,6 +182,11 @@ void ContextMenuItem::setSubMenu(ContextMenu* subMenu)
     m_platformDescription->hSubMenu = subMenu->releasePlatformDescription();
 }
 
+void ContextMenuItem::setSubMenu(Vector<ContextMenuItem>&)
+{
+    // FIXME: Implement
+}
+
 void ContextMenuItem::setChecked(bool checked)
 {
     m_platformDescription->fMask |= MIIM_STATE;
diff --git a/WebCore/platform/win/ContextMenuWin.cpp b/WebCore/platform/win/ContextMenuWin.cpp
index 82511e4..ad53f7e 100644
--- a/WebCore/platform/win/ContextMenuWin.cpp
+++ b/WebCore/platform/win/ContextMenuWin.cpp
@@ -161,4 +161,10 @@ Vector<ContextMenuItem> contextMenuItemVector(PlatformMenuDescription)
     return Vector<ContextMenuItem>();
 }
 
+PlatformMenuDescription platformMenuDescription(Vector<ContextMenuItem>& menuItemVector)
+{
+    // FIXME - Implement    
+    return 0;
+}
+
 }
diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index 058002f..8394436 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -1,3 +1,61 @@
+2010-11-09  Brady Eidson  <beidson at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Part of <rdar://problem/8613727> and https://bugs.webkit.org/show_bug.cgi?id=48720
+        Customizable context menu support in WebKit2.
+
+        This adds a BundlePageContextMenu client and lets WebKit2 consult it with the proposed
+        list of WebContextMenuItems.
+        There is no realistic API for the embedding app to actually inspect or create new
+        WebContextMenuItems (will be "WKContextMenuItem") and that ability will come later.
+
+        * WebKit2.pro:
+        * WebKit2.xcodeproj/project.pbxproj:
+        * win/WebKit2.vcproj:
+
+        * Platform/Logging.cpp:
+        (initializeLogChannelsIfNecessary):
+        * Platform/Logging.h:
+
+        * Shared/APIObject.h:
+
+        * Shared/MutableArray.cpp:
+        (WebKit::MutableArray::reserveCapacity):
+        * Shared/MutableArray.h:
+
+        * Shared/WebContextMenuItem.cpp: Added.
+        (WebKit::WebContextMenuItem::WebContextMenuItem):
+        (WebKit::WebContextMenuItem::data):
+        * Shared/WebContextMenuItem.h: Added.
+        (WebKit::WebContextMenuItem::create):
+        (WebKit::WebContextMenuItem::type):
+
+        * Shared/WebContextMenuItemData.cpp:
+        (WebKit::WebContextMenuItemData::core):
+        (WebKit::kitItems):
+        (WebKit::coreItems):
+        * Shared/WebContextMenuItemData.h:
+
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+        (WKBundlePageSetContextMenuClient):
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.h:
+
+        * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp: Added.
+        (WebKit::InjectedBundlePageContextMenuClient::InjectedBundlePageContextMenuClient):
+        (WebKit::InjectedBundlePageContextMenuClient::initialize):
+        (WebKit::InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems):
+        * WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h: Added.
+
+        * WebProcess/WebCoreSupport/WebContextMenuClient.cpp:
+        (WebKit::WebContextMenuClient::getCustomMenuFromDefaultItems): Call through to the injected bundle client
+          with the default items and convert the returned items back for WebCore to use.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::initializeInjectedBundleContextMenuClient):
+        * WebProcess/WebPage/WebPage.h:
+        (WebKit::WebPage::injectedBundleContextMenuClient):
+
 2010-11-09  Sam Weinig  <sam at webkit.org>
 
         Add some stylistic flourish to the last patch as suggested by Lord Darin Adler.
diff --git a/WebKit2/Platform/Logging.cpp b/WebKit2/Platform/Logging.cpp
index 3afcfb8..381a41d 100644
--- a/WebKit2/Platform/Logging.cpp
+++ b/WebKit2/Platform/Logging.cpp
@@ -28,6 +28,7 @@
 #if !LOG_DISABLED
 
 WTFLogChannel LogSessionState = { 0x00000001, "WebKit2LogLevel", WTFLogChannelOn };
+WTFLogChannel LogContextMenu  = { 0x00000002, "WebKit2LogLevel", WTFLogChannelOn };
 
 static inline void initializeLogChannel(WTFLogChannel* channel)
 {
@@ -41,6 +42,7 @@ void initializeLogChannelsIfNecessary()
         return;
     haveInitializedLogChannels = true;
 
+    initializeLogChannel(&LogContextMenu);
     initializeLogChannel(&LogSessionState);
 }
 
diff --git a/WebKit2/Platform/Logging.h b/WebKit2/Platform/Logging.h
index f655552..59dad73 100644
--- a/WebKit2/Platform/Logging.h
+++ b/WebKit2/Platform/Logging.h
@@ -36,6 +36,7 @@
 
 EXTERN_C_BEGIN
 
+extern WTFLogChannel LogContextMenu;
 extern WTFLogChannel LogSessionState;
 
 void initializeLogChannelsIfNecessary(void);
diff --git a/WebKit2/Shared/APIObject.h b/WebKit2/Shared/APIObject.h
index d793cae..dd626a5 100644
--- a/WebKit2/Shared/APIObject.h
+++ b/WebKit2/Shared/APIObject.h
@@ -37,6 +37,7 @@ public:
         TypeNull = 0,
         TypeArray,
         TypeCertificateInfo,
+        TypeContextMenuItem,
         TypeData,
         TypeDictionary,
         TypeError,
diff --git a/WebKit2/Shared/MutableArray.cpp b/WebKit2/Shared/MutableArray.cpp
index f76c70a..79245f3 100644
--- a/WebKit2/Shared/MutableArray.cpp
+++ b/WebKit2/Shared/MutableArray.cpp
@@ -40,4 +40,9 @@ void MutableArray::append(APIObject* item)
     m_entries.append(item);
 }
 
+void MutableArray::reserveCapacity(unsigned capacity)
+{
+    m_entries.reserveCapacity(capacity);
+}
+
 } // namespace WebKit
diff --git a/WebKit2/Shared/MutableArray.h b/WebKit2/Shared/MutableArray.h
index 59b7b2d..9cf369b 100644
--- a/WebKit2/Shared/MutableArray.h
+++ b/WebKit2/Shared/MutableArray.h
@@ -42,6 +42,7 @@ public:
     ~MutableArray();
 
     void append(APIObject*);
+    void reserveCapacity(unsigned);
 
     virtual bool isMutable() { return true; }
 
diff --git a/WebKit2/Shared/WebContextMenuItem.cpp b/WebKit2/Shared/WebContextMenuItem.cpp
new file mode 100644
index 0000000..3765b43
--- /dev/null
+++ b/WebKit2/Shared/WebContextMenuItem.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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 "WebContextMenuItem.h"
+
+namespace WebKit {
+
+WebContextMenuItem::WebContextMenuItem(const WebContextMenuItemData& data)
+    : m_webContextMenuItemData(data)
+{
+}
+
+} // namespace WebKit
+
diff --git a/WebKit2/Shared/WebContextMenuItem.h b/WebKit2/Shared/WebContextMenuItem.h
new file mode 100644
index 0000000..5bfca4e
--- /dev/null
+++ b/WebKit2/Shared/WebContextMenuItem.h
@@ -0,0 +1,55 @@
+/*
+ * 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 WebContextMenuItem_h
+#define WebContextMenuItem_h
+
+#include "APIObject.h"
+#include "WebContextMenuItemData.h"
+
+namespace WebKit {
+
+class WebContextMenuItem : public APIObject {
+public:
+    static const Type APIType = TypeContextMenuItem;
+
+    static PassRefPtr<WebContextMenuItem> create(const WebContextMenuItemData& data)
+    {
+        return adoptRef(new WebContextMenuItem(data));
+    }
+    
+    WebContextMenuItemData* data() { return &m_webContextMenuItemData; }
+
+private:
+    WebContextMenuItem(const WebContextMenuItemData&);
+    
+    virtual Type type() const { return APIType; }
+    
+    WebContextMenuItemData m_webContextMenuItemData;
+};
+
+} // namespace WebKit
+
+#endif // WebContextMenuItem_h
diff --git a/WebKit2/Shared/WebContextMenuItemData.cpp b/WebKit2/Shared/WebContextMenuItemData.cpp
index 22319f1..a2d43c5 100644
--- a/WebKit2/Shared/WebContextMenuItemData.cpp
+++ b/WebKit2/Shared/WebContextMenuItemData.cpp
@@ -30,6 +30,8 @@
 #include <wtf/text/CString.h>
 #include <WebCore/ContextMenu.h>
 
+using namespace WebCore;
+
 namespace WebKit {
 
 WebContextMenuItemData::WebContextMenuItemData()
@@ -76,6 +78,17 @@ WebContextMenuItemData::WebContextMenuItemData(WebCore::ContextMenuItem& item, W
     m_checked = item.checked();
 }
 
+ContextMenuItem WebContextMenuItemData::core() const
+{
+    if (m_type != SubmenuType) {
+        ContextMenuItem result(m_type, m_action, m_title, m_enabled, m_checked);
+        return result;
+    }
+    
+    Vector<ContextMenuItem> subMenuItems = coreItems(m_submenu);
+    return ContextMenuItem(m_action, m_title, m_enabled, m_checked, subMenuItems);
+}
+
 void WebContextMenuItemData::encode(CoreIPC::ArgumentEncoder* encoder) const
 {
     encoder->encode(CoreIPC::In(static_cast<uint32_t>(m_type), static_cast<uint32_t>(m_action), m_title, m_checked, m_enabled, m_submenu));
@@ -110,12 +123,22 @@ bool WebContextMenuItemData::decode(CoreIPC::ArgumentDecoder* decoder, WebContex
     return true;
 }
 
-Vector<WebContextMenuItemData> kitItems(Vector<WebCore::ContextMenuItem>& coreItems, WebCore::ContextMenu* menu)
+Vector<WebContextMenuItemData> kitItems(Vector<WebCore::ContextMenuItem>& coreItemVector, WebCore::ContextMenu* menu)
 {
     Vector<WebContextMenuItemData> result;
-    result.reserveCapacity(coreItems.size());
-    for (unsigned i = 0; i < coreItems.size(); ++i)
-        result.append(WebContextMenuItemData(coreItems[i], menu));
+    result.reserveCapacity(coreItemVector.size());
+    for (unsigned i = 0; i < coreItemVector.size(); ++i)
+        result.append(WebContextMenuItemData(coreItemVector[i], menu));
+    
+    return result;
+}
+
+Vector<ContextMenuItem> coreItems(const Vector<WebContextMenuItemData>& kitItemVector)
+{
+    Vector<ContextMenuItem> result;
+    result.reserveCapacity(kitItemVector.size());
+    for (unsigned i = 0; i < kitItemVector.size(); ++i)
+        result.append(kitItemVector[i].core());
     
     return result;
 }
diff --git a/WebKit2/Shared/WebContextMenuItemData.h b/WebKit2/Shared/WebContextMenuItemData.h
index 06685c2..a10c70c 100644
--- a/WebKit2/Shared/WebContextMenuItemData.h
+++ b/WebKit2/Shared/WebContextMenuItemData.h
@@ -54,6 +54,8 @@ public:
     bool checked() const { return m_checked; }
     const Vector<WebContextMenuItemData>& submenu() const { return m_submenu; }
     
+    WebCore::ContextMenuItem core() const;
+    
     void encode(CoreIPC::ArgumentEncoder*) const;
     static bool decode(CoreIPC::ArgumentDecoder*, WebContextMenuItemData&);
 
@@ -67,6 +69,7 @@ private:
 };
 
 Vector<WebContextMenuItemData> kitItems(Vector<WebCore::ContextMenuItem>&, WebCore::ContextMenu*);
+Vector<WebCore::ContextMenuItem> coreItems(const Vector<WebContextMenuItemData>&);
 
 } // namespace WebKit
 
diff --git a/WebKit2/WebKit2.pro b/WebKit2/WebKit2.pro
index e35dfd1..ee66c42 100644
--- a/WebKit2/WebKit2.pro
+++ b/WebKit2/WebKit2.pro
@@ -230,6 +230,7 @@ HEADERS += \
     Shared/UserMessageCoders.h \
     Shared/VisitedLinkTable.h \
     Shared/WebCertificateInfo.h \
+    Shared/WebContextMenuItem.h \
     Shared/WebContextMenuItemData.h \
     Shared/WebEvent.h \
     Shared/WebError.h \
@@ -319,6 +320,7 @@ HEADERS += \
     WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h \
     WebProcess/InjectedBundle/InjectedBundle.h \
     WebProcess/InjectedBundle/InjectedBundleHitTestResult.h \
+    WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h \
     WebProcess/InjectedBundle/InjectedBundlePageFormClient.h \
     WebProcess/InjectedBundle/InjectedBundlePageUIClient.h \
     WebProcess/InjectedBundle/InjectedBundleScriptWorld.h \
@@ -402,6 +404,7 @@ SOURCES += \
     Shared/qt/WebURLResponseQt.cpp \
     Shared/PlatformPopupMenuData.cpp \
     Shared/VisitedLinkTable.cpp \
+    Shared/WebContextMenuItem.cpp \
     Shared/WebContextMenuItemData.cpp \
     Shared/WebError.cpp \
     Shared/WebEvent.cpp \
@@ -488,7 +491,8 @@ SOURCES += \
     WebProcess/InjectedBundle/InjectedBundle.cpp \
     WebProcess/InjectedBundle/InjectedBundleBackForwardList.cpp \
     WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.cpp \
-    WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp \
+    WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp \    
+    WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp \
     WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp \
     WebProcess/InjectedBundle/InjectedBundlePageFormClient.cpp \
     WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp \
diff --git a/WebKit2/WebKit2.xcodeproj/project.pbxproj b/WebKit2/WebKit2.xcodeproj/project.pbxproj
index afb2539..fcfeb12 100644
--- a/WebKit2/WebKit2.xcodeproj/project.pbxproj
+++ b/WebKit2/WebKit2.xcodeproj/project.pbxproj
@@ -190,6 +190,10 @@
 		1C8E2A361277852400BC7BD0 /* WebInspectorMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C8E2A321277852400BC7BD0 /* WebInspectorMessages.h */; };
 		510FBB9A1288C95E00AFFDF4 /* WebContextMenuItemData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 510FBB981288C95E00AFFDF4 /* WebContextMenuItemData.cpp */; };
 		510FBB9B1288C95E00AFFDF4 /* WebContextMenuItemData.h in Headers */ = {isa = PBXBuildFile; fileRef = 510FBB991288C95E00AFFDF4 /* WebContextMenuItemData.h */; };
+		512935D71288D19400A4B695 /* WebContextMenuItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 512935D51288D19400A4B695 /* WebContextMenuItem.cpp */; };
+		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 */; };
 		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 */; };
@@ -735,6 +739,10 @@
 		32DBCF5E0370ADEE00C91783 /* WebKit2Prefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKit2Prefix.h; sourceTree = "<group>"; };
 		510FBB981288C95E00AFFDF4 /* WebContextMenuItemData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebContextMenuItemData.cpp; sourceTree = "<group>"; };
 		510FBB991288C95E00AFFDF4 /* WebContextMenuItemData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebContextMenuItemData.h; sourceTree = "<group>"; };
+		512935D51288D19400A4B695 /* WebContextMenuItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebContextMenuItem.cpp; sourceTree = "<group>"; };
+		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>"; };
 		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>"; };
@@ -1368,6 +1376,8 @@
 				1A0F29CA120B37160053D1B9 /* VisitedLinkTable.h */,
 				BC1DD7B1114DC396005ADAF3 /* WebCoreArgumentCoders.h */,
 				BCF50726124329AA005955AE /* WebCertificateInfo.h */,
+				512935D51288D19400A4B695 /* WebContextMenuItem.cpp */,
+				512935D61288D19400A4B695 /* WebContextMenuItem.h */,
 				510FBB981288C95E00AFFDF4 /* WebContextMenuItemData.cpp */,
 				510FBB991288C95E00AFFDF4 /* WebContextMenuItemData.h */,
 				51578B821209ECEF00A37C4A /* WebData.h */,
@@ -1812,6 +1822,8 @@
 				935EEB921277615D003322B8 /* InjectedBundleBackForwardListItem.h */,
 				BC498617124D10E200D834E1 /* InjectedBundleHitTestResult.cpp */,
 				BC498616124D10E200D834E1 /* InjectedBundleHitTestResult.h */,
+				512935E11288D97800A4B695 /* InjectedBundlePageContextMenuClient.cpp */,
+				512935E21288D97800A4B695 /* InjectedBundlePageContextMenuClient.h */,
 				E1EE53E611F8CFFB00CCBEE4 /* InjectedBundlePageEditorClient.cpp */,
 				E1EE53DC11F8CF9F00CCBEE4 /* InjectedBundlePageEditorClient.h */,
 				BC14E107120B905E00826C0C /* InjectedBundlePageFormClient.cpp */,
@@ -2360,6 +2372,8 @@
 				510FBB9B1288C95E00AFFDF4 /* WebContextMenuItemData.h in Headers */,
 				1AB7D4CA1288AAA700CFD08C /* DownloadProxy.h in Headers */,
 				1AB7D61A1288B9D900CFD08C /* DownloadProxyMessages.h in Headers */,
+				512935D81288D19400A4B695 /* WebContextMenuItem.h in Headers */,
+				512935E41288D97800A4B695 /* InjectedBundlePageContextMenuClient.h in Headers */,
 				1AB7D72C1288CAAD00CFD08C /* WebDownloadClient.h in Headers */,
 				1AB7D78D1288CD9A00CFD08C /* WKDownload.h in Headers */,
 			);
@@ -2710,6 +2724,8 @@
 				510FBB9A1288C95E00AFFDF4 /* WebContextMenuItemData.cpp in Sources */,
 				1AB7D4CB1288AAA700CFD08C /* DownloadProxy.cpp in Sources */,
 				1AB7D6191288B9D900CFD08C /* DownloadProxyMessageReceiver.cpp in Sources */,
+				512935D71288D19400A4B695 /* WebContextMenuItem.cpp in Sources */,
+				512935E31288D97800A4B695 /* InjectedBundlePageContextMenuClient.cpp in Sources */,
 				1AB7D72D1288CAAD00CFD08C /* WebDownloadClient.cpp in Sources */,
 				1AB7D78E1288CD9A00CFD08C /* WKDownload.cpp in Sources */,
 			);
diff --git a/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp b/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
index 089fceb..474ebf7 100644
--- a/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
+++ b/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
@@ -38,6 +38,13 @@ WKTypeID WKBundlePageGetTypeID()
     return toAPI(WebPage::APIType);
 }
 
+void WKBundlePageSetContextMenuClient(WKBundlePageRef pageRef, WKBundlePageContextMenuClient* wkClient)
+{
+    if (wkClient && wkClient->version)
+        return;
+    toImpl(pageRef)->initializeInjectedBundleContextMenuClient(wkClient);
+}
+
 void WKBundlePageSetEditorClient(WKBundlePageRef pageRef, WKBundlePageEditorClient* wkClient)
 {
     if (wkClient && wkClient->version)
diff --git a/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h b/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
index 53061de..6ca58a7 100644
--- a/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
+++ b/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h
@@ -181,8 +181,19 @@ struct WKBundlePageFormClient {
 };
 typedef struct WKBundlePageFormClient WKBundlePageFormClient;
 
-WK_EXPORT WKTypeID WKBundlePageGetTypeID();
+// ContextMenu client
+typedef void (*WKBundlePageGetContextMenuFromDefaultContextMenuCallback)(WKBundlePageRef page, WKBundleHitTestResultRef hitTestResult, WKArrayRef defaultMenu, WKArrayRef* newMenu, const void* clientInfo);
+
+struct WKBundlePageContextMenuClient {
+    int                                                                 version;
+    const void *                                                        clientInfo;
+    WKBundlePageGetContextMenuFromDefaultContextMenuCallback            getContextMenuFromDefaultMenu;
+};
+typedef struct WKBundlePageContextMenuClient WKBundlePageContextMenuClient;
 
+WK_EXPORT WKTypeID WKBundlePageGetTypeID();
+ 
+WK_EXPORT void WKBundlePageSetContextMenuClient(WKBundlePageRef page, WKBundlePageContextMenuClient* client);
 WK_EXPORT void WKBundlePageSetEditorClient(WKBundlePageRef page, WKBundlePageEditorClient* client);
 WK_EXPORT void WKBundlePageSetFormClient(WKBundlePageRef page, WKBundlePageFormClient* client);
 WK_EXPORT void WKBundlePageSetLoaderClient(WKBundlePageRef page, WKBundlePageLoaderClient* client);
diff --git a/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp
new file mode 100644
index 0000000..498ac09
--- /dev/null
+++ b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp
@@ -0,0 +1,92 @@
+/*
+ * 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 "InjectedBundlePageContextMenuClient.h"
+
+#include "ImmutableArray.h"
+#include "InjectedBundleHitTestResult.h"
+#include "Logging.h"
+#include "MutableArray.h"
+#include "WebContextMenuItem.h"
+#include "WKAPICast.h"
+#include "WKBundleAPICast.h"
+#include <WebCore/ContextMenu.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+InjectedBundlePageContextMenuClient::InjectedBundlePageContextMenuClient()
+{
+    initialize(0);
+}
+
+void InjectedBundlePageContextMenuClient::initialize(WKBundlePageContextMenuClient* client)
+{
+    if (client && !client->version)
+        m_client = *client;
+    else 
+        memset(&m_client, 0, sizeof(m_client));
+}
+
+bool InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems(WebPage* page, WebCore::ContextMenu* defaultMenu, Vector<WebContextMenuItemData>& newMenu)
+{
+    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());
+
+    WKArrayRef newMenuWK = 0;
+    m_client.getContextMenuFromDefaultMenu(toAPI(page), toAPI(hitTestResult.get()), toAPI(defaultMenuArray.get()), &newMenuWK, m_client.clientInfo);
+    RefPtr<ImmutableArray> array = adoptRef(toImpl(newMenuWK));
+    
+    newMenu.clear();
+    
+    if (!array || !array->size())
+        return true;
+    
+    size_t size = array->size();
+    for (size_t i = 0; i < size; ++i) {
+        WebContextMenuItem* item = array->at<WebContextMenuItem>(i);
+        if (!item) {
+            LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i);
+            continue;
+        }
+        
+        newMenu.append(*item->data());
+    }
+    
+    return true;
+}
+
+} // namespace WebKit
diff --git a/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h
new file mode 100644
index 0000000..122eb35
--- /dev/null
+++ b/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.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 InjectedBundlePageContextMenuClient_h
+#define InjectedBundlePageContextMenuClient_h
+
+#include "WKBundlePage.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+    class ContextMenu;
+}
+
+namespace WebKit {
+
+class WebContextMenuItemData;
+class WebPage;
+
+class InjectedBundlePageContextMenuClient {
+public:
+    InjectedBundlePageContextMenuClient();
+    void initialize(WKBundlePageContextMenuClient*);
+
+    bool getCustomMenuFromDefaultItems(WebPage*, WebCore::ContextMenu* defaultMenu, Vector<WebContextMenuItemData>& newMenu);
+
+private:
+    WKBundlePageContextMenuClient m_client;
+};
+
+} // namespace WebKit
+
+#endif // InjectedBundlePageEditorClient_h
diff --git a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
index 4e9f430..4a541c7 100644
--- a/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
+++ b/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
@@ -25,6 +25,8 @@
 
 #include "WebContextMenuClient.h"
 
+#include "WebContextMenuItemData.h"
+#include "WebPage.h"
 #include <WebCore/ContextMenu.h>
 
 #define DISABLE_NOT_IMPLEMENTED_WARNINGS 1
@@ -41,11 +43,12 @@ void WebContextMenuClient::contextMenuDestroyed()
 
 PlatformMenuDescription WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu)
 {
-    // FIXME:  The embedded app needs a chance to customize the context menu, and that will probably happen
-    // via an injected bundle. <rdar://problem/8613727> and https://bugs.webkit.org/show_bug.cgi?id=48720 cover this task.
-
-    ASSERT(menu);
-    return menu->platformDescription();
+    Vector<WebContextMenuItemData> newMenu;
+    if (!m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, menu, newMenu))
+        return menu->platformDescription();
+    
+    Vector<ContextMenuItem> coreItemVector = coreItems(newMenu);
+    return platformMenuDescription(coreItemVector);
 }
 
 void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem*, const ContextMenu*)
diff --git a/WebKit2/WebProcess/WebPage/WebPage.cpp b/WebKit2/WebProcess/WebPage/WebPage.cpp
index 241145e..2ce51c8 100644
--- a/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -162,6 +162,11 @@ CoreIPC::Connection* WebPage::connection() const
     return WebProcess::shared().connection();
 }
 
+void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client)
+{
+    m_contextMenuClient.initialize(client);
+}
+
 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client)
 {
     m_editorClient.initialize(client);
diff --git a/WebKit2/WebProcess/WebPage/WebPage.h b/WebKit2/WebProcess/WebPage/WebPage.h
index bc0640e..daab869 100644
--- a/WebKit2/WebProcess/WebPage/WebPage.h
+++ b/WebKit2/WebProcess/WebPage/WebPage.h
@@ -29,6 +29,7 @@
 #include "APIObject.h"
 #include "DrawingArea.h"
 #include "FindController.h"
+#include "InjectedBundlePageContextMenuClient.h"
 #include "InjectedBundlePageEditorClient.h"
 #include "InjectedBundlePageFormClient.h"
 #include "InjectedBundlePageLoaderClient.h"
@@ -132,11 +133,13 @@ public:
     void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
 
     // -- InjectedBundle methods
+    void initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient*);
     void initializeInjectedBundleEditorClient(WKBundlePageEditorClient*);
     void initializeInjectedBundleFormClient(WKBundlePageFormClient*);
     void initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient*);
     void initializeInjectedBundleUIClient(WKBundlePageUIClient*);
 
+    InjectedBundlePageContextMenuClient& injectedBundleContextMenuClient() { return m_contextMenuClient; }
     InjectedBundlePageEditorClient& injectedBundleEditorClient() { return m_editorClient; }
     InjectedBundlePageFormClient& injectedBundleFormClient() { return m_formClient; }
     InjectedBundlePageLoaderClient& injectedBundleLoaderClient() { return m_loaderClient; }
@@ -295,6 +298,7 @@ private:
 
     WebCore::IntSize m_windowResizerSize;
 
+    InjectedBundlePageContextMenuClient m_contextMenuClient;
     InjectedBundlePageEditorClient m_editorClient;
     InjectedBundlePageFormClient m_formClient;
     InjectedBundlePageLoaderClient m_loaderClient;
diff --git a/WebKit2/win/WebKit2.vcproj b/WebKit2/win/WebKit2.vcproj
index 5e3ff55..fa71ea7 100755
--- a/WebKit2/win/WebKit2.vcproj
+++ b/WebKit2/win/WebKit2.vcproj
@@ -505,6 +505,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\Shared\WebContextMenuItem.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\Shared\WebContextMenuItem.h"
+				>
+			</File>
+			<File
 				RelativePath="..\Shared\WebContextMenuItemData.cpp"
 				>
 			</File>
@@ -1344,6 +1352,14 @@
 					>
 				</File>
 				<File
+					RelativePath="..\WebProcess\InjectedBundle\InjectedBundlePageContextMenuClient.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\WebProcess\InjectedBundle\InjectedBundlePageContextMenuClient.h"
+					>
+				</File>
+				<File
 					RelativePath="..\WebProcess\InjectedBundle\InjectedBundlePageEditorClient.cpp"
 					>
 				</File>

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list