Title: [292032] trunk
Revision
292032
Author
wenson_hs...@apple.com
Date
2022-03-29 08:48:33 -0700 (Tue, 29 Mar 2022)

Log Message

HTMLAttachmentElement.getAttachmentIdentifier() should propagate attachment data to the client
https://bugs.webkit.org/show_bug.cgi?id=238473
rdar://90938796

Reviewed by Devin Rousso.

Source/WebCore:

In the case where a WebKit client that has enabled the attachment element uses
`HTMLAttachmentElement.getAttachmentIdentifier` on an image element to create a new attachment-backed image, we
currently propagate an empty `_WKAttachment` to the UI delegate in the UI process, even in the case where the
image element has a visible image that has been loaded.

To support plain-text editing mode, Mail needs to be able to call `getAttachmentIdentifier` to create attachment
elements for images that already contain images with blob sources, but are inserted into the document via
_javascript_ (as opposed to native editing code).

To make this work, we plumb the image element itself through the `registerAttachmentIdentifier` method that
currently only takes a single attachment identifier, and use it to send the image data, image name, and MIME
type to the attachment client if the image has a loaded image; otherwise, we fall back to creating and surfacing
an empty _WKAttachment to the client.

Test: WKAttachmentTests.CreateAttachmentsFromExistingImage

* dom/Document.cpp:
(WebCore::Document::registerAttachmentIdentifier):
* dom/Document.h:
* editing/Editor.cpp:
(WebCore::Editor::registerAttachmentIdentifier):
* editing/Editor.h:
* html/HTMLAttachmentElement.cpp:
(WebCore::HTMLAttachmentElement::getAttachmentIdentifier):

Tools:

Add a new API test to exercise the fix.

* TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
(TestWebKitAPI::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (292031 => 292032)


--- trunk/Source/WebCore/ChangeLog	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Source/WebCore/ChangeLog	2022-03-29 15:48:33 UTC (rev 292032)
@@ -1,3 +1,36 @@
+2022-03-29  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        HTMLAttachmentElement.getAttachmentIdentifier() should propagate attachment data to the client
+        https://bugs.webkit.org/show_bug.cgi?id=238473
+        rdar://90938796
+
+        Reviewed by Devin Rousso.
+
+        In the case where a WebKit client that has enabled the attachment element uses
+        `HTMLAttachmentElement.getAttachmentIdentifier` on an image element to create a new attachment-backed image, we
+        currently propagate an empty `_WKAttachment` to the UI delegate in the UI process, even in the case where the
+        image element has a visible image that has been loaded.
+
+        To support plain-text editing mode, Mail needs to be able to call `getAttachmentIdentifier` to create attachment
+        elements for images that already contain images with blob sources, but are inserted into the document via
+        _javascript_ (as opposed to native editing code).
+
+        To make this work, we plumb the image element itself through the `registerAttachmentIdentifier` method that
+        currently only takes a single attachment identifier, and use it to send the image data, image name, and MIME
+        type to the attachment client if the image has a loaded image; otherwise, we fall back to creating and surfacing
+        an empty _WKAttachment to the client.
+
+        Test: WKAttachmentTests.CreateAttachmentsFromExistingImage
+
+        * dom/Document.cpp:
+        (WebCore::Document::registerAttachmentIdentifier):
+        * dom/Document.h:
+        * editing/Editor.cpp:
+        (WebCore::Editor::registerAttachmentIdentifier):
+        * editing/Editor.h:
+        * html/HTMLAttachmentElement.cpp:
+        (WebCore::HTMLAttachmentElement::getAttachmentIdentifier):
+
 2022-03-29  Tim Nguyen  <n...@apple.com>
 
         Use Canvas/CanvasText system colors for <dialog> default styling

Modified: trunk/Source/WebCore/dom/Document.cpp (292031 => 292032)


--- trunk/Source/WebCore/dom/Document.cpp	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Source/WebCore/dom/Document.cpp	2022-03-29 15:48:33 UTC (rev 292032)
@@ -8634,11 +8634,9 @@
 
 #if ENABLE(ATTACHMENT_ELEMENT)
 
-void Document::registerAttachmentIdentifier(const String& identifier)
+void Document::registerAttachmentIdentifier(const String& identifier, const HTMLImageElement& image)
 {
-    // FIXME: Can this null check for Frame be removed?
-    if (frame())
-        editor().registerAttachmentIdentifier(identifier);
+    editor().registerAttachmentIdentifier(identifier, image);
 }
 
 void Document::didInsertAttachmentElement(HTMLAttachmentElement& attachment)

Modified: trunk/Source/WebCore/dom/Document.h (292031 => 292032)


--- trunk/Source/WebCore/dom/Document.h	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Source/WebCore/dom/Document.h	2022-03-29 15:48:33 UTC (rev 292032)
@@ -1558,7 +1558,7 @@
     WhitespaceCache& whitespaceCache() { return m_whitespaceCache; }
 
 #if ENABLE(ATTACHMENT_ELEMENT)
-    void registerAttachmentIdentifier(const String&);
+    void registerAttachmentIdentifier(const String&, const HTMLImageElement&);
     void didInsertAttachmentElement(HTMLAttachmentElement&);
     void didRemoveAttachmentElement(HTMLAttachmentElement&);
     WEBCORE_EXPORT RefPtr<HTMLAttachmentElement> attachmentForIdentifier(const String&) const;

Modified: trunk/Source/WebCore/editing/Editor.cpp (292031 => 292032)


--- trunk/Source/WebCore/editing/Editor.cpp	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Source/WebCore/editing/Editor.cpp	2022-03-29 15:48:33 UTC (rev 292032)
@@ -91,6 +91,7 @@
 #include "RemoveFormatCommand.h"
 #include "RenderBlock.h"
 #include "RenderBlockFlow.h"
+#include "RenderImage.h"
 #include "RenderLayer.h"
 #include "RenderTextControl.h"
 #include "RenderedDocumentMarker.h"
@@ -4191,9 +4192,46 @@
         client->registerAttachments(WTFMove(data));
 }
 
-void Editor::registerAttachmentIdentifier(const String& identifier)
+void Editor::registerAttachmentIdentifier(const String& identifier, const HTMLImageElement& imageElement)
 {
-    if (auto* client = this->client())
+    auto* client = this->client();
+    if (!client)
+        return;
+
+    auto attachmentInfo = [&]() -> std::optional<std::tuple<String, String, Ref<FragmentedSharedBuffer>>> {
+        auto* renderer = dynamicDowncast<RenderImage>(imageElement.renderer());
+        if (!renderer)
+            return std::nullopt;
+
+        auto* cachedImage = renderer->cachedImage();
+        if (!cachedImage || cachedImage->errorOccurred())
+            return std::nullopt;
+
+        String contentType;
+        if (auto* image = cachedImage->image())
+            contentType = image->mimeType();
+
+        if (contentType.isEmpty())
+            return std::nullopt;
+
+        RefPtr imageData = cachedImage->resourceBuffer();
+        if (!imageData)
+            return std::nullopt;
+
+        String name = imageElement.alt();
+        if (name.isEmpty())
+            name = imageElement.document().completeURL(imageElement.imageSourceURL()).lastPathComponent().toString();
+
+        if (name.isEmpty())
+            return std::nullopt;
+
+        return { { WTFMove(contentType), WTFMove(name), imageData.releaseNonNull() } };
+    }();
+
+    if (attachmentInfo) {
+        auto& [contentType, preferredFileName, data] = *attachmentInfo;
+        client->registerAttachmentIdentifier(identifier, WTFMove(contentType), WTFMove(preferredFileName), WTFMove(data));
+    } else
         client->registerAttachmentIdentifier(identifier);
 }
 

Modified: trunk/Source/WebCore/editing/Editor.h (292031 => 292032)


--- trunk/Source/WebCore/editing/Editor.h	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Source/WebCore/editing/Editor.h	2022-03-29 15:48:33 UTC (rev 292032)
@@ -571,7 +571,7 @@
     void registerAttachmentIdentifier(const String&, const String& contentType, const String& preferredFileName, Ref<FragmentedSharedBuffer>&& fileData);
     void registerAttachments(Vector<SerializedAttachmentData>&&);
     void registerAttachmentIdentifier(const String&, const String& contentType, const String& filePath);
-    void registerAttachmentIdentifier(const String&);
+    void registerAttachmentIdentifier(const String&, const HTMLImageElement&);
     void cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier);
     void didInsertAttachmentElement(HTMLAttachmentElement&);
     void didRemoveAttachmentElement(HTMLAttachmentElement&);

Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.cpp (292031 => 292032)


--- trunk/Source/WebCore/html/HTMLAttachmentElement.cpp	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.cpp	2022-03-29 15:48:33 UTC (rev 292032)
@@ -82,7 +82,7 @@
     auto attachment = create(HTMLNames::attachmentTag, document);
     auto& identifier = attachment->ensureUniqueIdentifier();
 
-    document.registerAttachmentIdentifier(identifier);
+    document.registerAttachmentIdentifier(identifier, image);
     image.setAttachmentElement(WTFMove(attachment));
 
     return identifier;

Modified: trunk/Tools/ChangeLog (292031 => 292032)


--- trunk/Tools/ChangeLog	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Tools/ChangeLog	2022-03-29 15:48:33 UTC (rev 292032)
@@ -1,3 +1,16 @@
+2022-03-29  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        HTMLAttachmentElement.getAttachmentIdentifier() should propagate attachment data to the client
+        https://bugs.webkit.org/show_bug.cgi?id=238473
+        rdar://90938796
+
+        Reviewed by Devin Rousso.
+
+        Add a new API test to exercise the fix.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+        (TestWebKitAPI::TEST):
+
 2022-03-28  Lauro Moura  <lmo...@igalia.com>
 
         [AT-SPI] accessibility/native-text-control-attributed-string.html is failing

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm (292031 => 292032)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm	2022-03-29 14:31:04 UTC (rev 292031)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm	2022-03-29 15:48:33 UTC (rev 292032)
@@ -24,6 +24,7 @@
  */
 
 #import "config.h"
+#import "Test.h"
 
 #if PLATFORM(MAC) || PLATFORM(IOS)
 
@@ -1729,6 +1730,32 @@
     }
 }
 
+TEST(WKAttachmentTests, CreateAttachmentsFromExistingImage)
+{
+    auto webView = webViewForTestingAttachments();
+    NSString *asyncScript = @"return new Promise(resolve => {"
+        "const image = document.createElement('img');"
+        "image.addEventListener('load', () => resolve(HTMLAttachmentElement.getAttachmentIdentifier(image)), { once: true });"
+        "image.src = '';"
+        "document.body.appendChild(image);"
+        "})";
+
+    __block RetainPtr<NSString> attachmentIdentifier;
+    __block bool doneWithScript = false;
+    [webView callAsyncJavaScript:asyncScript arguments:nil inFrame:nil inContentWorld:WKContentWorld.pageWorld completionHandler:^(NSString *result, NSError *error) {
+        EXPECT_NULL(error);
+        attachmentIdentifier = result;
+        doneWithScript = true;
+    }];
+    Util::run(&doneWithScript);
+
+    EXPECT_NOT_NULL(attachmentIdentifier);
+    RetainPtr info = [[webView _attachmentForIdentifier:attachmentIdentifier.get()] info];
+    EXPECT_WK_STREQ("image/png", [info contentType]);
+    EXPECT_WK_STREQ("icon.png", [info name]);
+    EXPECT_TRUE([[info data] isEqualToData:testImageData()]);
+}
+
 #pragma mark - Platform-specific tests
 
 #if PLATFORM(MAC)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to