- 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)