Fix Bug 14324: Cannot remove/customize the "Inspect Element" contextual menu item
authoraroben <aroben@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jul 2007 21:17:25 +0000 (21:17 +0000)
committeraroben <aroben@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jul 2007 21:17:25 +0000 (21:17 +0000)
WebCore:

        Fix Bug 14324: Cannot remove/customize the "Inspect Element" contextual menu item
        http://bugs.webkit.org/show_bug.cgi?id=14324

        Reviewed by Tim.

        No regression test possible.

        * page/ContextMenuController.cpp:
        (WebCore::ContextMenuController::handleContextMenuEvent): Add the
        Inspect Element item to the menu before passing it to the
        ContextMenuClient so that the UI delegate has a chance to
        modify/remove the item.

WebKit:

        Fix Bug 14324: Cannot remove/customize the "Inspect Element" contextual menu item
        http://bugs.webkit.org/show_bug.cgi?id=14324

        Only clients linking against new versions of WebKit will see the item.
        I've maintained our behavior for old clients of not including the
        Inspect Element item in the menu items passed to the UI delegate.

        Reviewed by Tim.

        * Misc/WebKitVersionChecks.h: Added a new constant.
        * WebCoreSupport/WebContextMenuClient.mm:
        (isPreInspectElementTagClient): Added.
        (fixMenusToSendToOldClients): Return an array of items that should be
        appended to the menu received from the delegate.
        (fixMenusReceivedFromOldClients): Append the saved items to the array.
        (WebContextMenuClient::getCustomMenuFromDefaultItems): Retain/release
        the saved items.

WebKit/win:

        Fix Bug 14324: Cannot remove/customize the "Inspect Element" contextual menu item
        http://bugs.webkit.org/show_bug.cgi?id=14324

        If we detect that we're running against the Safari 3 Beta, we add back
        the Inspect Element menu item after passing it off to the delegate
        because Safari's UI delegate will remove it.

        Reviewed by Tim.

        * WebContextMenuClient.cpp:
        (isPreInspectElementTagSafari): Added.
        (fixMenuReceivedFromOldSafari): Added.
        (WebContextMenuClient::getCustomMenuFromDefaultItems): Call
        fixMenuReceivedFromOldSafari before returning the new menu.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@24381 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/page/ContextMenuController.cpp
WebKit/ChangeLog
WebKit/Misc/WebKitVersionChecks.h
WebKit/WebCoreSupport/WebContextMenuClient.mm
WebKit/win/ChangeLog
WebKit/win/WebContextMenuClient.cpp

index acf865c8f115a2be702156b315d860594fa66be2..a67f955f55a92b0076070bbb82236b481a06c60f 100644 (file)
@@ -1,3 +1,18 @@
+2007-07-17  Adam Roben  <aroben@apple.com>
+
+        Fix Bug 14324: Cannot remove/customize the "Inspect Element" contextual menu item
+        http://bugs.webkit.org/show_bug.cgi?id=14324
+
+        Reviewed by Tim.
+
+        No regression test possible.
+
+        * page/ContextMenuController.cpp:
+        (WebCore::ContextMenuController::handleContextMenuEvent): Add the
+        Inspect Element item to the menu before passing it to the
+        ContextMenuClient so that the UI delegate has a chance to
+        modify/remove the item.
+
 2007-07-17  Adam Roben  <aroben@apple.com>
 
         Remove ContextMenuClient::shouldIncludeInspectElementItem
index 49ea31e3d4d4862d0a98a6d9b5c6e4fa6e7a895c..15fa7fa31c0662e43aa3e85adf7bb8084f5d2b0b 100644 (file)
@@ -95,11 +95,12 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
 
     m_contextMenu.set(new ContextMenu(result));
     m_contextMenu->populate();
+    if (m_page->settings()->developerExtrasEnabled())
+        m_contextMenu->addInspectElementItem();
+
     PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
     m_contextMenu->setPlatformDescription(customMenu);
 
-    if (m_page->settings()->developerExtrasEnabled())
-        m_contextMenu->addInspectElementItem();
     event->setDefaultHandled();
 }
 
index 23d93a79d3ac87bdb0b96a6efcf7a4c003e2ca7e..5bb43dbf033023b0b13563f6176b9c8a15e1f6bd 100644 (file)
@@ -1,3 +1,23 @@
+2007-07-17  Adam Roben  <aroben@apple.com>
+
+        Fix Bug 14324: Cannot remove/customize the "Inspect Element" contextual menu item
+        http://bugs.webkit.org/show_bug.cgi?id=14324
+
+        Only clients linking against new versions of WebKit will see the item.
+        I've maintained our behavior for old clients of not including the
+        Inspect Element item in the menu items passed to the UI delegate.
+
+        Reviewed by Tim.
+
+        * Misc/WebKitVersionChecks.h: Added a new constant.
+        * WebCoreSupport/WebContextMenuClient.mm:
+        (isPreInspectElementTagClient): Added.
+        (fixMenusToSendToOldClients): Return an array of items that should be
+        appended to the menu received from the delegate.
+        (fixMenusReceivedFromOldClients): Append the saved items to the array.
+        (WebContextMenuClient::getCustomMenuFromDefaultItems): Retain/release
+        the saved items.
+
 2007-07-17  Adam Roben  <aroben@apple.com>
 
         Remove WebContextMenuClient::shouldIncludeInspectElementItem
index afead94a844718559e5c2343137bdba7a26bd203..7d7428d719627eed4679c889af453ffa2c9c2987 100644 (file)
@@ -38,6 +38,7 @@
 #define WEBKIT_FIRST_VERSION_WITHOUT_VITALSOURCE_QUIRK 0x020A0000 // 522.0.0
 #define WEBKIT_FIRST_VERSION_WITH_MAIN_THREAD_EXCEPTIONS 0x020A0000 // 522.0.0
 #define WEBKIT_FIRST_VERSION_WITHOUT_ADOBE_INSTALLER_QUIRK 0x020A0000 // 522.0.0
+#define WEBKIT_FIRST_VERSION_WITH_INSPECT_ELEMENT_MENU_TAG 0x020A0C00 // 522.12.0
 
 #ifdef __cplusplus
 extern "C" {
index 2b629eb8653473733008929b4bee6ab27d36a306..d12a6626f7220496f96fa34a7c9a1d7eacb67f5f 100644 (file)
@@ -71,14 +71,37 @@ static BOOL isPreVersion3Client(void)
     return preVersion3Client;
 }
 
-static void fixMenusToSendToOldClients(NSMutableArray *defaultMenuItems)
+static BOOL isPreInspectElementTagClient(void)
 {
+    static BOOL preInspectElementTagClient = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_INSPECT_ELEMENT_MENU_TAG);
+    return preInspectElementTagClient;
+}
+
+static NSMutableArray *fixMenusToSendToOldClients(NSMutableArray *defaultMenuItems)
+{
+    NSMutableArray *savedItems = nil;
+
+    unsigned defaultItemsCount = [defaultMenuItems count];
+
+    if (isPreInspectElementTagClient()) {
+        NSMenuItem *secondToLastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 2];
+        NSMenuItem *lastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 1];
+
+        if ([secondToLastItem isSeparatorItem] && [lastItem tag] == WebMenuItemTagInspectElement) {
+            savedItems = [NSMutableArray arrayWithCapacity:2];
+            [savedItems addObject:secondToLastItem];
+            [savedItems addObject:lastItem];
+
+            [defaultMenuItems removeObject:secondToLastItem];
+            [defaultMenuItems removeObject:lastItem];
+        }
+    }
+
     BOOL preVersion3Client = isPreVersion3Client();
     if (!preVersion3Client)
-        return;
+        return savedItems;
         
     BOOL isMail = isAppleMail();
-    unsigned defaultItemsCount = [defaultMenuItems count];
     for (unsigned i = 0; i < defaultItemsCount; ++i) {
         NSMenuItem *item = [defaultMenuItems objectAtIndex:i];
         int tag = [item tag];
@@ -123,10 +146,15 @@ static void fixMenusToSendToOldClients(NSMutableArray *defaultMenuItems)
         if (oldStyleTag != tag)
             [item setTag:oldStyleTag];
     }
+
+    return savedItems;
 }
 
-static void fixMenusReceivedFromOldClients(NSMutableArray *newMenuItems)
+static void fixMenusReceivedFromOldClients(NSMutableArray *newMenuItems, NSMutableArray *savedItems)
 {   
+    if (savedItems)
+        [newMenuItems addObjectsFromArray:savedItems];
+
     BOOL preVersion3Client = isPreVersion3Client();
     if (!preVersion3Client)
         return;
@@ -240,9 +268,10 @@ NSMutableArray* WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu*
     for (unsigned i = 0; i < defaultItemsCount; ++i)
         [[defaultMenuItems objectAtIndex:i] setRepresentedObject:element];
             
-    fixMenusToSendToOldClients(defaultMenuItems);
+    NSMutableArray *savedItems = [fixMenusToSendToOldClients(defaultMenuItems) retain];
     NSMutableArray *newMenuItems = [[[delegate webView:m_webView contextMenuItemsForElement:element defaultMenuItems:defaultMenuItems] mutableCopy] autorelease];
-    fixMenusReceivedFromOldClients(newMenuItems);
+    fixMenusReceivedFromOldClients(newMenuItems, savedItems);
+    [savedItems release];
     return newMenuItems;
 }
 
index 36cba942fae28d5652a51f1c772691f5da51b29a..6c4ea44e5296353592d099fcf8d4ef1b83c68ea8 100644 (file)
@@ -1,3 +1,20 @@
+2007-07-17  Adam Roben  <aroben@apple.com>
+
+        Fix Bug 14324: Cannot remove/customize the "Inspect Element" contextual menu item
+        http://bugs.webkit.org/show_bug.cgi?id=14324
+
+        If we detect that we're running against the Safari 3 Beta, we add back
+        the Inspect Element menu item after passing it off to the delegate
+        because Safari's UI delegate will remove it.
+
+        Reviewed by Tim.
+
+        * WebContextMenuClient.cpp:
+        (isPreInspectElementTagSafari): Added.
+        (fixMenuReceivedFromOldSafari): Added.
+        (WebContextMenuClient::getCustomMenuFromDefaultItems): Call
+        fixMenuReceivedFromOldSafari before returning the new menu.
+
 2007-07-17  Adam Roben  <aroben@apple.com>
 
         Remove WebContextMenuClient::shouldIncludeInspectElementItem
index bf8e5af01e98dbe863c4b55ab7b9ecfa3fe93d5c..d91d2ff2ceb3ec734ade1f610c286c386fd07a80 100644 (file)
@@ -54,6 +54,49 @@ void WebContextMenuClient::contextMenuDestroyed()
     delete this;
 }
 
+static bool isPreInspectElementTagSafari(IWebUIDelegate* uiDelegate)
+{
+    if (!uiDelegate)
+        return false;
+
+    // We assume anyone who implements IWebUIDelegate2 also knows about the Inspect Element item.
+    COMPtr<IWebUIDelegate2> uiDelegate2;
+    if (SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegate2, (void**)&uiDelegate2)))
+        return false;
+
+    TCHAR modulePath[MAX_PATH];
+    DWORD length = ::GetModuleFileName(0, modulePath, _countof(modulePath));
+    if (!length)
+        return false;
+
+    return String(modulePath, length).endsWith("Safari.exe", false);
+}
+
+static HMENU fixMenuReceivedFromOldSafari(IWebUIDelegate* uiDelegate, ContextMenu* originalMenu, HMENU menuFromClient)
+{
+    ASSERT_ARG(menu, menu);
+    if (!isPreInspectElementTagSafari(uiDelegate))
+        return menuFromClient;
+
+    int count = ::GetMenuItemCount(originalMenu->platformDescription());
+    if (count < 1)
+        return menuFromClient;
+
+    if (::GetMenuItemID(originalMenu->platformDescription(), count - 1) != WebMenuItemTagInspectElement)
+        return menuFromClient;
+
+    count = ::GetMenuItemCount(menuFromClient);
+    if (count < 1)
+        return menuFromClient;
+
+    if (::GetMenuItemID(menuFromClient, count - 1) == WebMenuItemTagInspectElement)
+        return menuFromClient;
+
+    originalMenu->setPlatformDescription(menuFromClient);
+    originalMenu->addInspectElementItem();
+    return originalMenu->platformDescription();
+}
+
 HMENU WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu)
 {
     COMPtr<IWebUIDelegate> uiDelegate;
@@ -68,8 +111,7 @@ HMENU WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu)
     // FIXME: We need to decide whether to do the default before calling this delegate method
     if (FAILED(uiDelegate->contextMenuItemsForElement(m_webView, propertyBag.get(), (OLE_HANDLE)(ULONG64)menu->platformDescription(), (OLE_HANDLE*)&newMenu)))
         return menu->platformDescription();
-
-    return newMenu;
+    return fixMenuReceivedFromOldSafari(uiDelegate.get(), menu, newMenu);
 }
 
 void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem* item, const ContextMenu* parentMenu)