Title: [275749] trunk/Source
Revision
275749
Author
[email protected]
Date
2021-04-08 21:25:33 -0700 (Thu, 08 Apr 2021)

Log Message

Add a completion handler argument to `ChromeClient::requestImageExtraction`
https://bugs.webkit.org/show_bug.cgi?id=224348

Reviewed by Tim Horton.

Source/WebCore:

See WebKit/ChangeLog for more details. No change in behavior.

* html/HTMLElement.h:

Export an existing helper method.

* page/ChromeClient.h:
(WebCore::ChromeClient::requestImageExtraction):

Add a (null-by-default) `CompletionHandler` argument to this client method, for future use by accessibility.

Source/WebKit:

Add an optional completion handler argument to `ChromeClient::requestImageExtraction`. If specified, this
completion handler will be invoked with the image overlay host element (if present), once image extraction
finishes, or if the element is not suitable for image extraction.

* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::requestImageExtraction):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::didCommitLoad):
(WebKit::WebPage::requestImageExtraction):

Refactor this code, such that the data structure that (weakly) holds elements pending image extraction is
distinct from the set of elements that have completed image extraction. This allows us to queue completion
handlers to each element with a pending image extraction request, and invoke them once image extraction is
finished.

The existing weak set, `m_elementsWithExtractedImages`, is now repurposed to keep track of only elements that
have finished image extraction (and may or may not contain an image overlay). The new member variable,
`m_elementsPendingImageExtraction`, maintains pairs of weak elements and completion handlers; upon finishing
image extraction, each completion handler corresponding to the element (if it still exists) will be invoked.
Since the element is weakly held, in the case where the element is destroyed before image extraction finishes,
we will clean up the (now-null) entries in `m_elementsPendingImageExtraction` when the image extraction request
is finished.

* WebProcess/WebPage/WebPage.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (275748 => 275749)


--- trunk/Source/WebCore/ChangeLog	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebCore/ChangeLog	2021-04-09 04:25:33 UTC (rev 275749)
@@ -1,3 +1,21 @@
+2021-04-08  Wenson Hsieh  <[email protected]>
+
+        Add a completion handler argument to `ChromeClient::requestImageExtraction`
+        https://bugs.webkit.org/show_bug.cgi?id=224348
+
+        Reviewed by Tim Horton.
+
+        See WebKit/ChangeLog for more details. No change in behavior.
+
+        * html/HTMLElement.h:
+
+        Export an existing helper method.
+
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::requestImageExtraction):
+
+        Add a (null-by-default) `CompletionHandler` argument to this client method, for future use by accessibility.
+
 2021-04-08  Tim Horton  <[email protected]>
 
         Safari unit tests sometimes fail an ASSERTion in IOSurface.mm's optionsFor32BitSurface()

Modified: trunk/Source/WebCore/html/HTMLElement.h (275748 => 275749)


--- trunk/Source/WebCore/html/HTMLElement.h	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebCore/html/HTMLElement.h	2021-04-09 04:25:33 UTC (rev 275749)
@@ -130,7 +130,7 @@
     void setEnterKeyHint(const String& value);
 
     WEBCORE_EXPORT static bool shouldExtendSelectionToTargetNode(const Node& targetNode, const VisibleSelection& selectionBeforeUpdate);
-    bool hasImageOverlay() const;
+    WEBCORE_EXPORT bool hasImageOverlay() const;
     static bool isInsideImageOverlay(const SimpleRange&);
     static bool isInsideImageOverlay(const Node&);
     WEBCORE_EXPORT static bool isImageOverlayText(const Node&);

Modified: trunk/Source/WebCore/page/ChromeClient.h (275748 => 275749)


--- trunk/Source/WebCore/page/ChromeClient.h	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebCore/page/ChromeClient.h	2021-04-09 04:25:33 UTC (rev 275749)
@@ -560,7 +560,11 @@
 #endif
 
 #if ENABLE(IMAGE_EXTRACTION)
-    virtual void requestImageExtraction(Element&) { }
+    virtual void requestImageExtraction(Element&, CompletionHandler<void(RefPtr<Element>&&)>&& completion = { })
+    {
+        if (completion)
+            completion({ });
+    }
 #endif
     virtual bool needsImageOverlayControllerForSelectionPainting() const { return false; }
 

Modified: trunk/Source/WebKit/ChangeLog (275748 => 275749)


--- trunk/Source/WebKit/ChangeLog	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebKit/ChangeLog	2021-04-09 04:25:33 UTC (rev 275749)
@@ -1,3 +1,36 @@
+2021-04-08  Wenson Hsieh  <[email protected]>
+
+        Add a completion handler argument to `ChromeClient::requestImageExtraction`
+        https://bugs.webkit.org/show_bug.cgi?id=224348
+
+        Reviewed by Tim Horton.
+
+        Add an optional completion handler argument to `ChromeClient::requestImageExtraction`. If specified, this
+        completion handler will be invoked with the image overlay host element (if present), once image extraction
+        finishes, or if the element is not suitable for image extraction.
+
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::requestImageExtraction):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::didCommitLoad):
+        (WebKit::WebPage::requestImageExtraction):
+
+        Refactor this code, such that the data structure that (weakly) holds elements pending image extraction is
+        distinct from the set of elements that have completed image extraction. This allows us to queue completion
+        handlers to each element with a pending image extraction request, and invoke them once image extraction is
+        finished.
+
+        The existing weak set, `m_elementsWithExtractedImages`, is now repurposed to keep track of only elements that
+        have finished image extraction (and may or may not contain an image overlay). The new member variable,
+        `m_elementsPendingImageExtraction`, maintains pairs of weak elements and completion handlers; upon finishing
+        image extraction, each completion handler corresponding to the element (if it still exists) will be invoked.
+        Since the element is weakly held, in the case where the element is destroyed before image extraction finishes,
+        we will clean up the (now-null) entries in `m_elementsPendingImageExtraction` when the image extraction request
+        is finished.
+
+        * WebProcess/WebPage/WebPage.h:
+
 2021-04-08  Jiewen Tan  <[email protected]>
 
         PCM: Write more blinded secret tests

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (275748 => 275749)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-04-09 04:25:33 UTC (rev 275749)
@@ -1448,9 +1448,9 @@
 
 #if ENABLE(IMAGE_EXTRACTION)
 
-void WebChromeClient::requestImageExtraction(Element& element)
+void WebChromeClient::requestImageExtraction(Element& element, CompletionHandler<void(RefPtr<Element>&&)>&& completion)
 {
-    m_page.requestImageExtraction(element);
+    m_page.requestImageExtraction(element, WTFMove(completion));
 }
 
 #endif

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (275748 => 275749)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-04-09 04:25:33 UTC (rev 275749)
@@ -415,7 +415,7 @@
 #endif
 
 #if ENABLE(IMAGE_EXTRACTION)
-    void requestImageExtraction(WebCore::Element&) final;
+    void requestImageExtraction(WebCore::Element&, CompletionHandler<void(RefPtr<WebCore::Element>&&)>&& = { }) final;
 #endif
 
     bool needsImageOverlayControllerForSelectionPainting() const final

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (275748 => 275749)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-04-09 04:25:33 UTC (rev 275749)
@@ -6183,6 +6183,11 @@
     unfreezeLayerTree(LayerTreeFreezeReason::ProcessSwap);
 
 #if ENABLE(IMAGE_EXTRACTION)
+    for (auto& [element, completionHandlers] : m_elementsPendingImageExtraction) {
+        for (auto& completionHandler : completionHandlers)
+            completionHandler({ });
+    }
+    m_elementsPendingImageExtraction.clear();
     m_elementsWithExtractedImages.clear();
 #endif
 
@@ -7262,36 +7267,98 @@
 
 #if ENABLE(IMAGE_EXTRACTION)
 
-void WebPage::requestImageExtraction(WebCore::Element& element)
+void WebPage::requestImageExtraction(WebCore::Element& element, CompletionHandler<void(RefPtr<WebCore::Element>&&)>&& completion)
 {
-    if (!is<HTMLElement>(element))
+    if (!is<HTMLElement>(element)) {
+        if (completion)
+            completion({ });
         return;
+    }
 
-    if (m_elementsWithExtractedImages.contains(element))
+    if (m_elementsWithExtractedImages.contains(element)) {
+        if (completion) {
+            ASSERT(is<HTMLElement>(element));
+            RefPtr<Element> imageOverlayHost;
+            if (is<HTMLElement>(element) && downcast<HTMLElement>(element).hasImageOverlay())
+                imageOverlayHost = makeRefPtr(element);
+            completion(WTFMove(imageOverlayHost));
+        }
         return;
+    }
 
+    auto matchIndex = m_elementsPendingImageExtraction.findMatching([&] (auto& elementAndCompletionHandlers) {
+        return elementAndCompletionHandlers.first == &element;
+    });
+
+    if (matchIndex != notFound) {
+        m_elementsPendingImageExtraction[matchIndex].second.append(WTFMove(completion));
+        return;
+    }
+
     auto* renderer = element.renderer();
-    if (!is<RenderImage>(renderer))
+    if (!is<RenderImage>(renderer)) {
+        if (completion)
+            completion({ });
         return;
+    }
 
     auto& renderImage = downcast<RenderImage>(*renderer);
-
-    m_elementsWithExtractedImages.add(element);
-
     auto bitmap = createShareableBitmap(renderImage);
-    if (!bitmap)
+    if (!bitmap) {
+        if (completion)
+            completion({ });
         return;
+    }
 
     ShareableBitmap::Handle bitmapHandle;
     bitmap->createHandle(bitmapHandle);
-    if (bitmapHandle.isNull())
+    if (bitmapHandle.isNull()) {
+        if (completion)
+            completion({ });
         return;
+    }
 
+    Vector<CompletionHandler<void(RefPtr<Element>&&)>> completionHandlers;
+    if (completion)
+        completionHandlers.append(WTFMove(completion));
+    m_elementsPendingImageExtraction.append({ makeWeakPtr(element), WTFMove(completionHandlers) });
+
     auto imageURL = element.document().completeURL(renderImage.cachedImage()->url().string());
+    sendWithAsyncReply(Messages::WebPageProxy::RequestImageExtraction(WTFMove(imageURL), WTFMove(bitmapHandle)), [webPage = makeWeakPtr(*this), weakElement = makeWeakPtr(element)] (auto&& result) {
+        auto protectedPage = makeRefPtr(webPage.get());
+        if (!protectedPage)
+            return;
 
-    sendWithAsyncReply(Messages::WebPageProxy::RequestImageExtraction(WTFMove(imageURL), WTFMove(bitmapHandle)), [weakElement = makeWeakPtr(element)] (ImageExtractionResult&& result) {
-        if (auto element = weakElement.get(); is<HTMLElement>(element))
-            downcast<HTMLElement>(*element).updateWithImageExtractionResult(WTFMove(result));
+        protectedPage->m_elementsPendingImageExtraction.removeAllMatching([&] (auto& elementAndCompletionHandlers) {
+            auto& [element, completionHandlers] = elementAndCompletionHandlers;
+            if (element)
+                return false;
+
+            for (auto& completionHandler : completionHandlers)
+                completionHandler({ });
+            return true;
+        });
+
+        auto protectedElement = makeRefPtr(weakElement.get());
+        if (!protectedElement)
+            return;
+
+        auto& htmlElement = downcast<HTMLElement>(*protectedElement);
+        htmlElement.updateWithImageExtractionResult(WTFMove(result));
+        protectedPage->m_elementsWithExtractedImages.add(htmlElement);
+
+        auto matchIndex = protectedPage->m_elementsPendingImageExtraction.findMatching([&] (auto& elementAndCompletionHandlers) {
+            return elementAndCompletionHandlers.first == &htmlElement;
+        });
+
+        if (matchIndex == notFound)
+            return;
+
+        auto imageOverlayHost = htmlElement.hasImageOverlay() ? makeRefPtr(htmlElement) : nullptr;
+        for (auto& completionHandler : protectedPage->m_elementsPendingImageExtraction[matchIndex].second)
+            completionHandler(imageOverlayHost.copyRef());
+
+        protectedPage->m_elementsPendingImageExtraction.remove(matchIndex);
     });
 }
 

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (275748 => 275749)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-04-09 04:06:39 UTC (rev 275748)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-04-09 04:25:33 UTC (rev 275749)
@@ -182,6 +182,7 @@
 class FrameSelection;
 class FrameView;
 class GraphicsContext;
+class HTMLElement;
 class HTMLImageElement;
 class HTMLMenuElement;
 class HTMLMenuItemElement;
@@ -1381,7 +1382,7 @@
 #endif
 
 #if ENABLE(IMAGE_EXTRACTION)
-    void requestImageExtraction(WebCore::Element&);
+    void requestImageExtraction(WebCore::Element&, CompletionHandler<void(RefPtr<WebCore::Element>&&)>&&);
     void updateWithImageExtractionResult(WebCore::ImageExtractionResult&&, const WebCore::ElementContext&, const WebCore::FloatPoint& location, CompletionHandler<void(bool)>&&);
 #endif
 
@@ -2306,7 +2307,8 @@
 #endif
 
 #if ENABLE(IMAGE_EXTRACTION)
-    WeakHashSet<WebCore::Element> m_elementsWithExtractedImages;
+    Vector<std::pair<WeakPtr<WebCore::HTMLElement>, Vector<CompletionHandler<void(RefPtr<WebCore::Element>&&)>>>> m_elementsPendingImageExtraction;
+    WeakHashSet<WebCore::HTMLElement> m_elementsWithExtractedImages;
 #endif
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to