Title: [289882] trunk/Source
Revision
289882
Author
[email protected]
Date
2022-02-16 01:19:57 -0800 (Wed, 16 Feb 2022)

Log Message

[macOS] Add an "Markup Image" item to the sharing services picker context menu
https://bugs.webkit.org/show_bug.cgi?id=236628
rdar://86446810

Reviewed by Darin Adler.

Source/WebCore:

Add support for a new context menu item in the sharing services picker; see WebKit/ChangeLog for more details.

* dom/mac/ImageControlsMac.cpp:
(WebCore::ImageControlsMac::handleEvent):

Simplify this chrome client hook by passing along the entire HTMLImageElement, instead of the absolute bounds,
attachment element ID, and whether the image has contenteditable style as separate arguments. This makes it a
bit easier to compute and send the image MIME type and an ElementContext in WebKit2. See changes in WebPageMac
for more information.

* html/HTMLAttachmentElement.h: Export a method.
* page/ChromeClient.h:
(WebCore::ChromeClient::handleImageServiceClick):
* platform/LocalizedStrings.h:
* platform/cocoa/LocalizedStringsCocoa.mm:

Add a helper function for the "Markup Image" menu item's localized title.

(WebCore::contextMenuItemTitleMarkupImage):

Source/WebKit:

Add support for a new context menu item in the sharing services picker; to achieve this, we plumb along some
more information about the controlled image element for the services picker menu (i.e. MIME type and an element
context). In WebContextMenuProxyMac, we then append the "Markup Image" item if the system feature is enabled,
and use this information about the controlled image element to replace the image using image data returned from
VisionKit, transcoded to a format that matches that of the original source image. See below for more details.

* Shared/ContextMenuContextData.cpp:
(WebKit::ContextMenuContextData::ContextMenuContextData):
(WebKit::ContextMenuContextData::encode const):
(WebKit::ContextMenuContextData::decode):
* Shared/ContextMenuContextData.h:
(WebKit::ContextMenuContextData::controlledImageElementContext const):
(WebKit::ContextMenuContextData::controlledImageMIMEType const):

Add `m_controlledImageElementContext`, which can be used to identify the controlled image element, and
`m_controlledImageMIMEType`, the MIME type of the controlled image. See `applyMarkupToControlledImage` for more
information about usage.

* UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::replaceWithPasteboardData):

Add a helper method that's nearly identical to the extant `replaceSelectionWithPasteboardData` method, except
that it takes an ElementContext and applies the editing replacement to a selection containing the element
corresponding to the given context, rather than applying the edit command to the current selection.

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView updateImageAnalysisMarkupMenuItems:]):

Use the new WebCore localized string helper function.

* UIProcess/mac/WKSharingServicePickerDelegate.h:
* UIProcess/mac/WKSharingServicePickerDelegate.mm:
(-[WKSharingServicePickerDelegate markupImage]):

Handle the new context menu invocation.

* UIProcess/mac/WebContextMenuProxyMac.h:
* UIProcess/mac/WebContextMenuProxyMac.mm:
(WebKit::WebContextMenuProxyMac::setupServicesMenu):

If the controlled image is set and `isImageAnalysisMarkupSystemFeatureEnabled()` is true, append a new item to
the services menu to invoke "Markup Image"; when activated, this menu item invokes the
`-[WKSharingServicePickerDelegate markupImage]` method above, which in turn calls into
`applyMarkupToControlledImage` below.

(WebKit::WebContextMenuProxyMac::applyMarkupToControlledImage):

This method contains the main logic for coordinating "Markup Image" from the services menu on macOS. Using
information about the controlled image, this first creates a CGImageRef from the image bitmap, passes it to
VisionKit for analysis, and obtains a resulting CGImageRef; it then transcodes this resulting CGImageRef to
image data in a format that matches the MIME type of the source image, and replaces the controlled image using
this image data via the override pasteboard.

* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::handleImageServiceClick):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
(WebKit::WebPage::replaceWithPasteboardData):

Move the current selection to surround the element identified by the given ElementContext, and then call into
`replaceSelectionWithPasteboardData` to perform the replacement.

* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::handleImageServiceClick):

Additionally compute and send the controlled image MIME type and its element context.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (289881 => 289882)


--- trunk/Source/WebCore/ChangeLog	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebCore/ChangeLog	2022-02-16 09:19:57 UTC (rev 289882)
@@ -1,3 +1,31 @@
+2022-02-16  Wenson Hsieh  <[email protected]>
+
+        [macOS] Add an "Markup Image" item to the sharing services picker context menu
+        https://bugs.webkit.org/show_bug.cgi?id=236628
+        rdar://86446810
+
+        Reviewed by Darin Adler.
+
+        Add support for a new context menu item in the sharing services picker; see WebKit/ChangeLog for more details.
+
+        * dom/mac/ImageControlsMac.cpp:
+        (WebCore::ImageControlsMac::handleEvent):
+
+        Simplify this chrome client hook by passing along the entire HTMLImageElement, instead of the absolute bounds,
+        attachment element ID, and whether the image has contenteditable style as separate arguments. This makes it a
+        bit easier to compute and send the image MIME type and an ElementContext in WebKit2. See changes in WebPageMac
+        for more information.
+
+        * html/HTMLAttachmentElement.h: Export a method.
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::handleImageServiceClick):
+        * platform/LocalizedStrings.h:
+        * platform/cocoa/LocalizedStringsCocoa.mm:
+
+        Add a helper function for the "Markup Image" menu item's localized title.
+
+        (WebCore::contextMenuItemTitleMarkupImage):
+
 2022-02-15  Nikolaos Mouchtaris  <[email protected]>
 
         Implement parsing and animation support for offset shorthand

Modified: trunk/Source/WebCore/dom/mac/ImageControlsMac.cpp (289881 => 289882)


--- trunk/Source/WebCore/dom/mac/ImageControlsMac.cpp	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebCore/dom/mac/ImageControlsMac.cpp	2022-02-16 09:19:57 UTC (rev 289882)
@@ -138,16 +138,17 @@
     auto& node = downcast<Node>(*mouseEvent.target());
 
     if (ImageControlsMac::isImageControlsButtonElement(node)) {
-        auto shadowHost = node.shadowHost();
-        if (!is<HTMLImageElement>(*shadowHost))
+        RefPtr shadowHost = dynamicDowncast<HTMLImageElement>(node.shadowHost());
+        if (!shadowHost)
             return false;
-        if (auto* image = imageFromImageElementNode(*shadowHost)) {
-            HTMLImageElement& imageElement = downcast<HTMLImageElement>(*shadowHost);
-            auto attachmentID = HTMLAttachmentElement::getAttachmentIdentifier(imageElement);
-            page->chrome().client().handleImageServiceClick(roundedIntPoint(mouseEvent.absoluteLocation()), *image, imageElement.isContentEditable(), imageElement.renderBox()->absoluteContentQuad().enclosingBoundingBox(), attachmentID);
-            event.setDefaultHandled();
-            return true;
-        }
+
+        auto* image = imageFromImageElementNode(*shadowHost);
+        if (!image)
+            return false;
+
+        page->chrome().client().handleImageServiceClick(roundedIntPoint(mouseEvent.absoluteLocation()), *image, *shadowHost);
+        event.setDefaultHandled();
+        return true;
     }
     return false;
 }

Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.h (289881 => 289882)


--- trunk/Source/WebCore/html/HTMLAttachmentElement.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -42,7 +42,7 @@
     WTF_MAKE_ISO_ALLOCATED(HTMLAttachmentElement);
 public:
     static Ref<HTMLAttachmentElement> create(const QualifiedName&, Document&);
-    static const String& getAttachmentIdentifier(HTMLImageElement&);
+    WEBCORE_EXPORT static const String& getAttachmentIdentifier(HTMLImageElement&);
     static URL archiveResourceURL(const String&);
 
     WEBCORE_EXPORT URL blobURL() const;

Modified: trunk/Source/WebCore/page/ChromeClient.h (289881 => 289882)


--- trunk/Source/WebCore/page/ChromeClient.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebCore/page/ChromeClient.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -534,7 +534,7 @@
 #if ENABLE(SERVICE_CONTROLS)
     virtual void handleSelectionServiceClick(FrameSelection&, const Vector<String>&, const IntPoint&) { }
     virtual bool hasRelevantSelectionServices(bool /*isTextOnly*/) const { return false; }
-    virtual void handleImageServiceClick(const IntPoint&, Image&, bool /*isEditable*/, const IntRect&, const String& /*attachmentID*/) { }
+    virtual void handleImageServiceClick(const IntPoint&, Image&, HTMLImageElement&) { }
 #endif
 
     virtual bool shouldDispatchFakeMouseMoveEvents() const { return true; }

Modified: trunk/Source/WebCore/platform/LocalizedStrings.h (289881 => 289882)


--- trunk/Source/WebCore/platform/LocalizedStrings.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebCore/platform/LocalizedStrings.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -379,6 +379,7 @@
 
 #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
     WEBCORE_EXPORT String contextMenuItemTagCopyCroppedImage();
+    WEBCORE_EXPORT String contextMenuItemTitleMarkupImage();
 #endif
 
 #if HAVE(TRANSLATION_UI_SERVICES)

Modified: trunk/Source/WebCore/platform/cocoa/LocalizedStringsCocoa.mm (289881 => 289882)


--- trunk/Source/WebCore/platform/cocoa/LocalizedStringsCocoa.mm	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebCore/platform/cocoa/LocalizedStringsCocoa.mm	2022-02-16 09:19:57 UTC (rev 289882)
@@ -326,6 +326,11 @@
     return WEB_UI_STRING("Copy Cropped Image", "Title for Copy Cropped Image");
 }
 
-#endif
+String contextMenuItemTitleMarkupImage()
+{
+    return WEB_UI_STRING("Markup Image", "Image analysis markup menu item");
+}
 
+#endif // ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (289881 => 289882)


--- trunk/Source/WebKit/ChangeLog	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/ChangeLog	2022-02-16 09:19:57 UTC (rev 289882)
@@ -1,3 +1,81 @@
+2022-02-16  Wenson Hsieh  <[email protected]>
+
+        [macOS] Add an "Markup Image" item to the sharing services picker context menu
+        https://bugs.webkit.org/show_bug.cgi?id=236628
+        rdar://86446810
+
+        Reviewed by Darin Adler.
+
+        Add support for a new context menu item in the sharing services picker; to achieve this, we plumb along some
+        more information about the controlled image element for the services picker menu (i.e. MIME type and an element
+        context). In WebContextMenuProxyMac, we then append the "Markup Image" item if the system feature is enabled,
+        and use this information about the controlled image element to replace the image using image data returned from
+        VisionKit, transcoded to a format that matches that of the original source image. See below for more details.
+
+        * Shared/ContextMenuContextData.cpp:
+        (WebKit::ContextMenuContextData::ContextMenuContextData):
+        (WebKit::ContextMenuContextData::encode const):
+        (WebKit::ContextMenuContextData::decode):
+        * Shared/ContextMenuContextData.h:
+        (WebKit::ContextMenuContextData::controlledImageElementContext const):
+        (WebKit::ContextMenuContextData::controlledImageMIMEType const):
+
+        Add `m_controlledImageElementContext`, which can be used to identify the controlled image element, and
+        `m_controlledImageMIMEType`, the MIME type of the controlled image. See `applyMarkupToControlledImage` for more
+        information about usage.
+
+        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
+        (WebKit::WebPageProxy::replaceWithPasteboardData):
+
+        Add a helper method that's nearly identical to the extant `replaceSelectionWithPasteboardData` method, except
+        that it takes an ElementContext and applies the editing replacement to a selection containing the element
+        corresponding to the given context, rather than applying the edit command to the current selection.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView updateImageAnalysisMarkupMenuItems:]):
+
+        Use the new WebCore localized string helper function.
+
+        * UIProcess/mac/WKSharingServicePickerDelegate.h:
+        * UIProcess/mac/WKSharingServicePickerDelegate.mm:
+        (-[WKSharingServicePickerDelegate markupImage]):
+
+        Handle the new context menu invocation.
+
+        * UIProcess/mac/WebContextMenuProxyMac.h:
+        * UIProcess/mac/WebContextMenuProxyMac.mm:
+        (WebKit::WebContextMenuProxyMac::setupServicesMenu):
+
+        If the controlled image is set and `isImageAnalysisMarkupSystemFeatureEnabled()` is true, append a new item to
+        the services menu to invoke "Markup Image"; when activated, this menu item invokes the
+        `-[WKSharingServicePickerDelegate markupImage]` method above, which in turn calls into
+        `applyMarkupToControlledImage` below.
+
+        (WebKit::WebContextMenuProxyMac::applyMarkupToControlledImage):
+
+        This method contains the main logic for coordinating "Markup Image" from the services menu on macOS. Using
+        information about the controlled image, this first creates a CGImageRef from the image bitmap, passes it to
+        VisionKit for analysis, and obtains a resulting CGImageRef; it then transcodes this resulting CGImageRef to
+        image data in a format that matches the MIME type of the source image, and replaces the controlled image using
+        this image data via the override pasteboard.
+
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::handleImageServiceClick):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
+        (WebKit::WebPage::replaceWithPasteboardData):
+
+        Move the current selection to surround the element identified by the given ElementContext, and then call into
+        `replaceSelectionWithPasteboardData` to perform the replacement.
+
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/WebPageMac.mm:
+        (WebKit::WebPage::handleImageServiceClick):
+
+        Additionally compute and send the controlled image MIME type and its element context.
+
 2022-02-15  Sihui Liu  <[email protected]>
 
         Migrate IndexedDB and LocalStorage data to GeneralStorageDirectory

Modified: trunk/Source/WebKit/Shared/ContextMenuContextData.cpp (289881 => 289882)


--- trunk/Source/WebKit/Shared/ContextMenuContextData.cpp	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/Shared/ContextMenuContextData.cpp	2022-02-16 09:19:57 UTC (rev 289882)
@@ -67,12 +67,14 @@
 }
 
 #if ENABLE(SERVICE_CONTROLS)
-ContextMenuContextData::ContextMenuContextData(const WebCore::IntPoint& menuLocation, WebCore::Image& image, bool isEditable, const WebCore::IntRect& imageRect, const String& attachmentID)
+ContextMenuContextData::ContextMenuContextData(const WebCore::IntPoint& menuLocation, WebCore::Image& image, bool isEditable, const WebCore::IntRect& imageRect, const String& attachmentID, std::optional<ElementContext>&& elementContext, const String& sourceImageMIMEType)
     : m_type(Type::ServicesMenu)
     , m_menuLocation(menuLocation)
     , m_selectionIsEditable(isEditable)
     , m_controlledImageBounds(imageRect)
     , m_controlledImageAttachmentID(attachmentID)
+    , m_controlledImageElementContext(WTFMove(elementContext))
+    , m_controlledImageMIMEType(sourceImageMIMEType)
 {
     setImage(&image);
 }
@@ -106,6 +108,8 @@
     encoder << m_selectionIsEditable;
     encoder << m_controlledImageBounds;
     encoder << m_controlledImageAttachmentID;
+    encoder << m_controlledImageElementContext;
+    encoder << m_controlledImageMIMEType;
 #endif
 }
 
@@ -144,6 +148,10 @@
         return false;
     if (!decoder.decode(result.m_controlledImageAttachmentID))
         return false;
+    if (!decoder.decode(result.m_controlledImageElementContext))
+        return false;
+    if (!decoder.decode(result.m_controlledImageMIMEType))
+        return false;
 #endif
 
     return true;

Modified: trunk/Source/WebKit/Shared/ContextMenuContextData.h (289881 => 289882)


--- trunk/Source/WebKit/Shared/ContextMenuContextData.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/Shared/ContextMenuContextData.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -31,6 +31,7 @@
 #include "WebContextMenuItemData.h"
 #include "WebHitTestResultData.h"
 #include <WebCore/ContextMenuContext.h>
+#include <WebCore/ElementContext.h>
 #include <wtf/EnumTraits.h>
 
 namespace IPC {
@@ -64,7 +65,7 @@
     {
     }
     
-    ContextMenuContextData(const WebCore::IntPoint& menuLocation, WebCore::Image&, bool isEditable, const WebCore::IntRect& imageRect, const String& attachmentID);
+    ContextMenuContextData(const WebCore::IntPoint& menuLocation, WebCore::Image&, bool isEditable, const WebCore::IntRect& imageRect, const String& attachmentID, std::optional<WebCore::ElementContext>&&, const String& sourceImageMIMEType);
 
     ShareableBitmap* controlledImage() const { return m_controlledImage.get(); }
     const Vector<uint8_t>& controlledSelectionData() const { return m_controlledSelectionData; }
@@ -74,7 +75,9 @@
     bool controlledDataIsEditable() const;
     WebCore::IntRect controlledImageBounds() const { return m_controlledImageBounds; };
     String controlledImageAttachmentID() const { return m_controlledImageAttachmentID; };
-#endif
+    std::optional<WebCore::ElementContext> controlledImageElementContext() const { return m_controlledImageElementContext; }
+    String controlledImageMIMEType() const { return m_controlledImageMIMEType; }
+#endif // ENABLE(SERVICE_CONTROLS)
 
     void encode(IPC::Encoder&) const;
     static WARN_UNUSED_RETURN bool decode(IPC::Decoder&, ContextMenuContextData&);
@@ -97,6 +100,8 @@
     bool m_selectionIsEditable;
     WebCore::IntRect m_controlledImageBounds;
     String m_controlledImageAttachmentID;
+    std::optional<WebCore::ElementContext> m_controlledImageElementContext;
+    String m_controlledImageMIMEType;
 #endif
 };
 

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm (289881 => 289882)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm	2022-02-16 09:19:57 UTC (rev 289882)
@@ -868,6 +868,11 @@
     send(Messages::WebPage::ReplaceSelectionWithPasteboardData(types, data));
 }
 
+void WebPageProxy::replaceWithPasteboardData(const ElementContext& elementContext, const Vector<String>& types, const IPC::DataReference& data)
+{
+    send(Messages::WebPage::ReplaceWithPasteboardData(elementContext, types, data));
+}
+
 } // namespace WebKit
 
 #undef MESSAGE_CHECK_COMPLETION

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (289881 => 289882)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -1184,6 +1184,7 @@
     void registerWebProcessAccessibilityToken(const IPC::DataReference&);
     // Called by the UI process when it is ready to send its tokens to the web process.
     void registerUIProcessAccessibilityTokens(const IPC::DataReference& elemenToken, const IPC::DataReference& windowToken);
+    void replaceWithPasteboardData(const WebCore::ElementContext&, const Vector<String>& types, const IPC::DataReference&);
     void replaceSelectionWithPasteboardData(const Vector<String>& types, const IPC::DataReference&);
     bool readSelectionFromPasteboard(const String& pasteboardName);
     String stringSelectionForPasteboard();

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (289881 => 289882)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2022-02-16 09:19:57 UTC (rev 289882)
@@ -4667,7 +4667,7 @@
         if (currentItem)
             [updatedItems removeObject:currentItem];
     } else if (!currentItem)
-        [updatedItems addObject:adoptNS([[UIMenuItem alloc] initWithTitle:WEB_UI_STRING("Markup Image", "Image analysis markup menu item") action:@selector(performImageAnalysisMarkup:)]).get()];
+        [updatedItems addObject:adoptNS([[UIMenuItem alloc] initWithTitle:WebCore::contextMenuItemTitleMarkupImage() action:@selector(performImageAnalysisMarkup:)]).get()];
 }
 
 - (BOOL)canPerformImageAnalysisMarkup

Modified: trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.h (289881 => 289882)


--- trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -50,6 +50,7 @@
 - (void)setHandlesEditingReplacement:(BOOL)handlesEditingReplacement;
 - (void)setSourceFrame:(NSRect)sourceFrame;
 - (void)setAttachmentID:(String)attachmentID;
+- (void)markupImage;
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.mm (289881 => 289882)


--- trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.mm	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/UIProcess/mac/WKSharingServicePickerDelegate.mm	2022-02-16 09:19:57 UTC (rev 289882)
@@ -183,6 +183,11 @@
     return _menuProxy->window();
 }
 
+- (void)markupImage
+{
+    _menuProxy->applyMarkupToControlledImage();
+}
+
 @end
 
 #endif // ENABLE(SERVICE_CONTROLS)

Modified: trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h (289881 => 289882)


--- trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -53,6 +53,7 @@
 
 #if ENABLE(SERVICE_CONTROLS)
     void clearServicesMenu();
+    void applyMarkupToControlledImage();
 #endif
 
     NSWindow *window() const;

Modified: trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm (289881 => 289882)


--- trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm	2022-02-16 09:19:57 UTC (rev 289882)
@@ -30,10 +30,12 @@
 
 #import "APIAttachment.h"
 #import "APIContextMenuClient.h"
+#import "CocoaImage.h"
 #import "MenuUtilities.h"
 #import "PageClientImplMac.h"
 #import "ServicesController.h"
 #import "ShareableBitmap.h"
+#import "TextRecognitionUtilities.h"
 #import "WKMenuItemIdentifiersPrivate.h"
 #import "WKSharingServicePickerDelegate.h"
 #import "WebContextMenuItem.h"
@@ -49,6 +51,10 @@
 #import <wtf/BlockPtr.h>
 #import <wtf/RetainPtr.h>
 
+#if HAVE(UNIFORM_TYPE_IDENTIFIERS_FRAMEWORK)
+#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
+#endif
+
 @interface WKUserDataWrapper : NSObject {
     RefPtr<API::Object> _webUserData;
 }
@@ -256,6 +262,21 @@
 
     if (!hasControlledImage)
         [m_menu setShowsStateColumn:YES];
+#if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+    else if (isImageAnalysisMarkupSystemFeatureEnabled()) {
+        auto markupImageItem = adoptNS([[NSMenuItem alloc] initWithTitle:contextMenuItemTitleMarkupImage() action:@selector(markupImage) keyEquivalent:@""]);
+        [markupImageItem setImage:[NSImage imageWithSystemSymbolName:@"person.fill.viewfinder" accessibilityDescription:contextMenuItemTitleMarkupImage()]];
+        [markupImageItem setTarget:WKSharingServicePickerDelegate.sharedSharingServicePickerDelegate];
+        [markupImageItem setAction:@selector(markupImage)];
+        auto numberOfItems = [m_menu numberOfItems];
+        if (numberOfItems)
+            [markupImageItem setIndentationLevel:[m_menu itemAtIndex:numberOfItems - 1].indentationLevel];
+        if (numberOfItems >= 1)
+            [m_menu insertItem:markupImageItem.get() atIndex:numberOfItems - 1];
+        else
+            [m_menu addItem:markupImageItem.get()];
+    }
+#endif // ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
 
     // Explicitly add a menu item for each telephone number that is in the selection.
     Vector<RetainPtr<NSMenuItem>> telephoneNumberMenuItems;
@@ -301,6 +322,38 @@
     m_menu = nullptr;
 }
 
+void WebContextMenuProxyMac::applyMarkupToControlledImage()
+{
+#if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+    if (!page())
+        return;
+
+    auto elementContext = m_context.controlledImageElementContext();
+    if (!elementContext)
+        return;
+
+    auto* imageBitmap = m_context.controlledImage();
+    if (!imageBitmap)
+        return;
+
+    auto image = imageBitmap->makeCGImage();
+    if (!image)
+        return;
+
+    requestImageAnalysisMarkup(image.get(), [weakPage = WeakPtr { page() }, preferredMIMEType = m_context.controlledImageMIMEType(), elementContext = WTFMove(*elementContext)](CGImageRef result) {
+        RefPtr protectedPage = weakPage.get();
+        if (!protectedPage || !result)
+            return;
+
+        auto [data, type] = transcodeWithPreferredMIMEType(result, preferredMIMEType.createCFString().get(), (__bridge CFStringRef)UTTypeTIFF.identifier);
+        if (!data)
+            return;
+
+        protectedPage->replaceWithPasteboardData(elementContext, { String(type.get()) }, IPC::DataReference(static_cast<const uint8_t*>([data bytes]), [data length]));
+    });
+#endif // ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
+}
+
 static void getStandardShareMenuItem(NSArray *items, void (^completionHandler)(NSMenuItem *))
 {
 #if HAVE(NSSHARINGSERVICEPICKER_ASYNC_MENUS)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (289881 => 289882)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2022-02-16 09:19:57 UTC (rev 289882)
@@ -1346,9 +1346,9 @@
     return (isTextOnly && WebProcess::singleton().hasSelectionServices()) || WebProcess::singleton().hasRichContentServices();
 }
 
-void WebChromeClient::handleImageServiceClick(const IntPoint& point, Image& image, bool isEditable, const IntRect& imageRect, const String& attachmentID)
+void WebChromeClient::handleImageServiceClick(const IntPoint& point, Image& image, HTMLImageElement& element)
 {
-    m_page.handleImageServiceClick(point, image, isEditable, imageRect, attachmentID);
+    m_page.handleImageServiceClick(point, image, element);
 }
 
 #endif

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (289881 => 289882)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -381,7 +381,7 @@
 #if ENABLE(SERVICE_CONTROLS)
     void handleSelectionServiceClick(WebCore::FrameSelection&, const Vector<String>& telephoneNumbers, const WebCore::IntPoint&) final;
     bool hasRelevantSelectionServices(bool isTextOnly) const final;
-    void handleImageServiceClick(const WebCore::IntPoint&, WebCore::Image&, bool isEditable, const WebCore::IntRect&, const String& /*attachmentID*/) final;
+    void handleImageServiceClick(const WebCore::IntPoint&, WebCore::Image&, WebCore::HTMLImageElement&) final;
 #endif
 
     bool shouldDispatchFakeMouseMoveEvents() const final;

Modified: trunk/Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm (289881 => 289882)


--- trunk/Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm	2022-02-16 09:19:57 UTC (rev 289882)
@@ -457,6 +457,24 @@
     return string;
 }
 
+void WebPage::replaceWithPasteboardData(const ElementContext& elementContext, const Vector<String>& types, const IPC::DataReference& data)
+{
+    Ref frame = CheckedRef(m_page->focusController())->focusedOrMainFrame();
+    auto element = elementForContext(elementContext);
+    if (!element || !element->isContentEditable())
+        return;
+
+    if (frame->document() != &element->document())
+        return;
+
+    auto replacementRange = makeRangeSelectingNode(*element);
+    if (!replacementRange)
+        return;
+
+    frame->selection().setSelection(VisibleSelection { *replacementRange });
+    replaceSelectionWithPasteboardData(types, data);
+}
+
 void WebPage::replaceSelectionWithPasteboardData(const Vector<String>& types, const IPC::DataReference& data)
 {
     for (auto& type : types)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (289881 => 289882)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2022-02-16 09:19:57 UTC (rev 289882)
@@ -971,6 +971,7 @@
 #endif
 
 #if PLATFORM(COCOA)
+    void replaceWithPasteboardData(const WebCore::ElementContext&, const Vector<String>& types, const IPC::DataReference&);
     void replaceSelectionWithPasteboardData(const Vector<String>& types, const IPC::DataReference&);
 #endif
 
@@ -1210,7 +1211,7 @@
 #if ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)
     void handleTelephoneNumberClick(const String& number, const WebCore::IntPoint&, const WebCore::IntRect&);
     void handleSelectionServiceClick(WebCore::FrameSelection&, const Vector<String>& telephoneNumbers, const WebCore::IntPoint&);
-    void handleImageServiceClick(const WebCore::IntPoint&, WebCore::Image&, bool isEditable, const WebCore::IntRect&, const String& attachmentID);
+    void handleImageServiceClick(const WebCore::IntPoint&, WebCore::Image&, WebCore::HTMLImageElement&);
 #endif
 
     void didChangeScrollOffsetForFrame(WebCore::Frame*);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (289881 => 289882)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2022-02-16 09:19:57 UTC (rev 289882)
@@ -460,6 +460,7 @@
     GetStringSelectionForPasteboard() -> (String stringValue) Synchronous
     GetDataSelectionForPasteboard(String pasteboardType) -> (WebKit::SharedMemory::IPCHandle ipcHandle) Synchronous
     ReadSelectionFromPasteboard(String pasteboardName) -> (bool result) Synchronous
+    ReplaceWithPasteboardData(struct WebCore::ElementContext context, Vector<String> types, IPC::DataReference data)
     ReplaceSelectionWithPasteboardData(Vector<String> types, IPC::DataReference data)
 
     ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -> (bool result) Synchronous

Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm (289881 => 289882)


--- trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm	2022-02-16 09:17:09 UTC (rev 289881)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm	2022-02-16 09:19:57 UTC (rev 289882)
@@ -70,7 +70,9 @@
 #import <WebCore/FrameLoaderTypes.h>
 #import <WebCore/FrameView.h>
 #import <WebCore/GraphicsContext.h>
+#import <WebCore/HTMLAttachmentElement.h>
 #import <WebCore/HTMLConverter.h>
+#import <WebCore/HTMLImageElement.h>
 #import <WebCore/HTMLPlugInImageElement.h>
 #import <WebCore/HitTestResult.h>
 #import <WebCore/ImageOverlay.h>
@@ -759,9 +761,17 @@
     send(Messages::WebPageProxy::ShowContextMenu(ContextMenuContextData(point, selectionDataVector, phoneNumbers, selection.selection().isContentEditable()), UserData()));
 }
 
-void WebPage::handleImageServiceClick(const IntPoint& point, Image& image, bool isEditable, const IntRect& imageRect, const String& attachmentID)
+void WebPage::handleImageServiceClick(const IntPoint& point, Image& image, HTMLImageElement& element)
 {
-    send(Messages::WebPageProxy::ShowContextMenu(ContextMenuContextData(point, image, isEditable, imageRect, attachmentID), UserData()));
+    send(Messages::WebPageProxy::ShowContextMenu(ContextMenuContextData {
+        point,
+        image,
+        element.isContentEditable(),
+        element.renderBox()->absoluteContentQuad().enclosingBoundingBox(),
+        HTMLAttachmentElement::getAttachmentIdentifier(element),
+        contextForElement(element),
+        image.mimeType()
+    }, { }));
 }
 
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to