Title: [236634] trunk
Revision
236634
Author
wenson_hs...@apple.com
Date
2018-09-28 19:12:57 -0700 (Fri, 28 Sep 2018)

Log Message

No DOM API to instantiate an attachment for an img element
https://bugs.webkit.org/show_bug.cgi?id=189934
<rdar://problem/44743222>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Adds support for HTMLAttachmentElement.getAttachmentIdentifier, a function that internal WebKit clients can use
to ensure that an image element is backed by a unique _WKAttachment. See below for more details.

Tests:  WKAttachmentTests.AddAttachmentToConnectedImageElement
        WKAttachmentTests.ChangeFileWrapperForPastedImage
        WKAttachmentTests.ConnectImageWithAttachmentToDocument

* dom/Document.cpp:
(WebCore::Document::registerAttachmentIdentifier):

Add a new hook to register an empty _WKAttachment in the UI process with a given identifier. Used when creating
a new empty attachment to back an image element.

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

Creates an attachment element to back the image element, if an attachment does not already exist, and returns
the unique identifier. This also causes an empty corresponding _WKAttachment to be created in the client, whose
file wrapper determines the contents of the image.

(WebCore::HTMLAttachmentElement::ensureUniqueIdentifier):
(WebCore::HTMLAttachmentElement::hasEnclosingImage const):
(WebCore::HTMLAttachmentElement::updateEnclosingImageWithData):

Add a helper that updates the source of the enclosing image element given a content type and image data, by
creating a new blob and blob URL.

* html/HTMLAttachmentElement.h:
* html/HTMLAttachmentElement.idl:
* html/HTMLImageElement.idl:

Rename webkitAttachmentIdentifier to just attachmentIdentifier.

* page/EditorClient.h:
(WebCore::EditorClient::registerAttachmentIdentifier):
(WebCore::EditorClient::didInsertAttachmentWithIdentifier):

Source/WebKit:

Makes some adjustments to support using _WKAttachment's file wrapper to change the contents of any image element
hosting the attachment in its shadow root. To do this, we add some plumbing to allow the UI process to update an
attachment element's enclosing image with data from its file wrapper.

* UIProcess/API/APIAttachment.cpp:
(API::Attachment::isEmpty const):
(API::Attachment::enclosingImageData const):

Helper method that creates a SharedBuffer representing image data for the attachment. Only returns a non-null
value for attachment elements that are enclosed within an image.

* UIProcess/API/APIAttachment.h:
* UIProcess/API/Cocoa/APIAttachmentCocoa.mm:
(API::Attachment::enclosingImageData const):
(API::Attachment::isEmpty const):
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _attachmentForIdentifier:]):

Add new SPI to request a _WKAttachment for a given unique identifier. Currently, this is only used for testing.

* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::platformRegisterAttachment):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::updateAttachmentAttributes):
(WebKit::WebPageProxy::registerAttachmentIdentifier):
(WebKit::WebPageProxy::didInsertAttachmentWithIdentifier):

Plumb whether or not the attachment is enclosed by an image from the web process to the UI process.

(WebKit::WebPageProxy::didRemoveAttachmentWithIdentifier):
(WebKit::WebPageProxy::didInsertAttachment): Deleted.
(WebKit::WebPageProxy::didRemoveAttachment):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::registerAttachmentIdentifier):
(WebKit::WebEditorClient::didInsertAttachmentWithIdentifier):

Update attachment attributes after inserting an attachment. This ensures that an attachment that was created and
later inserted via script into the document will be synced with state in the UI process, if the client has
changed the contents of the attachment.

* WebProcess/WebCoreSupport/WebEditorClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updateAttachmentAttributes):

Plumb attachment data from the UI process to the web process.

* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

Adds 3 new API tests in WKAttachmentTests:

`AddAttachmentToConnectedImageElement` verifies that an image element that's already in the document can gain an
attachment element via `HTMLAttachmentElement.getAttachmentIdentifier`.

`ChangeFileWrapperForPastedImage` verifies that an image that has been pasted produces a _WKAttachment in the UI
process, and changing the file wrapper of that _WKAttachment changes the pasted image.

`ConnectImageWithAttachmentToDocument` verifies that script can create an image element, ensure that it has an
attachment, and set a file wrapper for the generated _WKAttachment. Connecting the image to the document should
then result in an image element with the contents of the _WKAttachment's file wrapper.

* TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
(-[TestWKWebView imageElementSize]):
(-[TestWKWebView waitForImageElementSizeToBecome:]):
(TestWebKitAPI::TEST):
(-[TestWKWebView waitForAttachmentElementSizeToBecome:]): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (236633 => 236634)


--- trunk/Source/WebCore/ChangeLog	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/ChangeLog	2018-09-29 02:12:57 UTC (rev 236634)
@@ -1,3 +1,53 @@
+2018-09-28  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        No DOM API to instantiate an attachment for an img element
+        https://bugs.webkit.org/show_bug.cgi?id=189934
+        <rdar://problem/44743222>
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds support for HTMLAttachmentElement.getAttachmentIdentifier, a function that internal WebKit clients can use
+        to ensure that an image element is backed by a unique _WKAttachment. See below for more details.
+
+        Tests:  WKAttachmentTests.AddAttachmentToConnectedImageElement
+                WKAttachmentTests.ChangeFileWrapperForPastedImage
+                WKAttachmentTests.ConnectImageWithAttachmentToDocument
+
+        * dom/Document.cpp:
+        (WebCore::Document::registerAttachmentIdentifier):
+
+        Add a new hook to register an empty _WKAttachment in the UI process with a given identifier. Used when creating
+        a new empty attachment to back an image element.
+
+        * dom/Document.h:
+        * editing/Editor.cpp:
+        (WebCore::Editor::registerAttachmentIdentifier):
+        (WebCore::Editor::notifyClientOfAttachmentUpdates):
+        * editing/Editor.h:
+        * html/HTMLAttachmentElement.cpp:
+        (WebCore::HTMLAttachmentElement::getAttachmentIdentifier):
+
+        Creates an attachment element to back the image element, if an attachment does not already exist, and returns
+        the unique identifier. This also causes an empty corresponding _WKAttachment to be created in the client, whose
+        file wrapper determines the contents of the image.
+
+        (WebCore::HTMLAttachmentElement::ensureUniqueIdentifier):
+        (WebCore::HTMLAttachmentElement::hasEnclosingImage const):
+        (WebCore::HTMLAttachmentElement::updateEnclosingImageWithData):
+
+        Add a helper that updates the source of the enclosing image element given a content type and image data, by
+        creating a new blob and blob URL.
+
+        * html/HTMLAttachmentElement.h:
+        * html/HTMLAttachmentElement.idl:
+        * html/HTMLImageElement.idl:
+
+        Rename webkitAttachmentIdentifier to just attachmentIdentifier.
+
+        * page/EditorClient.h:
+        (WebCore::EditorClient::registerAttachmentIdentifier):
+        (WebCore::EditorClient::didInsertAttachmentWithIdentifier):
+
 2018-09-28  Chris Dumez  <cdu...@apple.com>
 
         The return value of an OnBeforeUnloadEventHandler should always be coerced into a DOMString

Modified: trunk/Source/WebCore/dom/Document.cpp (236633 => 236634)


--- trunk/Source/WebCore/dom/Document.cpp	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/dom/Document.cpp	2018-09-29 02:12:57 UTC (rev 236634)
@@ -8109,6 +8109,12 @@
 
 #if ENABLE(ATTACHMENT_ELEMENT)
 
+void Document::registerAttachmentIdentifier(const String& identifier)
+{
+    if (auto* frame = this->frame())
+        frame->editor().registerAttachmentIdentifier(identifier);
+}
+
 void Document::didInsertAttachmentElement(HTMLAttachmentElement& attachment)
 {
     auto identifier = attachment.uniqueIdentifier();

Modified: trunk/Source/WebCore/dom/Document.h (236633 => 236634)


--- trunk/Source/WebCore/dom/Document.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/dom/Document.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -1462,9 +1462,10 @@
     Vector<RefPtr<WebAnimation>> getAnimations();
         
 #if ENABLE(ATTACHMENT_ELEMENT)
+    void registerAttachmentIdentifier(const String&);
     void didInsertAttachmentElement(HTMLAttachmentElement&);
     void didRemoveAttachmentElement(HTMLAttachmentElement&);
-    WEBCORE_EXPORT RefPtr<HTMLAttachmentElement> attachmentForIdentifier(const String& identifier) const;
+    WEBCORE_EXPORT RefPtr<HTMLAttachmentElement> attachmentForIdentifier(const String&) const;
     const HashMap<String, Ref<HTMLAttachmentElement>>& attachmentElementsByIdentifier() const { return m_attachmentIdentifierToElementMap; }
 #endif
 

Modified: trunk/Source/WebCore/editing/Editor.cpp (236633 => 236634)


--- trunk/Source/WebCore/editing/Editor.cpp	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/editing/Editor.cpp	2018-09-29 02:12:57 UTC (rev 236634)
@@ -3943,6 +3943,12 @@
         client->registerAttachmentIdentifier(identifier, contentType, filePath);
 }
 
+void Editor::registerAttachmentIdentifier(const String& identifier)
+{
+    if (auto* client = this->client())
+        client->registerAttachmentIdentifier(identifier);
+}
+
 void Editor::cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier)
 {
     if (auto* client = this->client())
@@ -3987,7 +3993,7 @@
 
     for (auto& identifier : insertedAttachmentIdentifiers) {
         if (auto attachment = document->attachmentForIdentifier(identifier))
-            client()->didInsertAttachmentWithIdentifier(identifier, attachment->attributeWithoutSynchronization(HTMLNames::srcAttr));
+            client()->didInsertAttachmentWithIdentifier(identifier, attachment->attributeWithoutSynchronization(HTMLNames::srcAttr), attachment->hasEnclosingImage());
         else
             ASSERT_NOT_REACHED();
     }

Modified: trunk/Source/WebCore/editing/Editor.h (236633 => 236634)


--- trunk/Source/WebCore/editing/Editor.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/editing/Editor.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -511,6 +511,7 @@
     WEBCORE_EXPORT void insertAttachment(const String& identifier, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType);
     void registerAttachmentIdentifier(const String&, const String& /* contentType */, const String& /* preferredFileName */, Ref<SharedBuffer>&&);
     void registerAttachmentIdentifier(const String&, const String& /* contentType */, const String& /* filePath */);
+    void registerAttachmentIdentifier(const String&);
     void cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier);
     void didInsertAttachmentElement(HTMLAttachmentElement&);
     void didRemoveAttachmentElement(HTMLAttachmentElement&);

Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.cpp (236633 => 236634)


--- trunk/Source/WebCore/html/HTMLAttachmentElement.cpp	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.cpp	2018-09-29 02:12:57 UTC (rev 236634)
@@ -33,7 +33,9 @@
 #include "Editor.h"
 #include "File.h"
 #include "Frame.h"
+#include "HTMLImageElement.h"
 #include "HTMLNames.h"
+#include "MIMETypeRegistry.h"
 #include "RenderAttachment.h"
 #include "SharedBuffer.h"
 #include <pal/FileSizeFormatter.h>
@@ -40,6 +42,10 @@
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/UUID.h>
 
+#if PLATFORM(COCOA)
+#include "UTIUtilities.h"
+#endif
+
 namespace WebCore {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLAttachmentElement);
@@ -64,6 +70,21 @@
     return createRenderer<RenderAttachment>(*this, WTFMove(style));
 }
 
+const String& HTMLAttachmentElement::getAttachmentIdentifier(HTMLImageElement& image)
+{
+    if (auto attachment = image.attachmentElement())
+        return attachment->uniqueIdentifier();
+
+    auto& document = image.document();
+    auto attachment = create(HTMLNames::attachmentTag, document);
+    auto& identifier = attachment->ensureUniqueIdentifier();
+
+    document.registerAttachmentIdentifier(identifier);
+    image.setAttachmentElement(WTFMove(attachment));
+
+    return identifier;
+}
+
 File* HTMLAttachmentElement::file() const
 {
     return m_file.get();
@@ -109,7 +130,7 @@
         document().didRemoveAttachmentElement(*this);
 }
 
-String HTMLAttachmentElement::ensureUniqueIdentifier()
+const String& HTMLAttachmentElement::ensureUniqueIdentifier()
 {
     if (m_uniqueIdentifier.isEmpty())
         m_uniqueIdentifier = createCanonicalUUIDString();
@@ -116,6 +137,11 @@
     return m_uniqueIdentifier;
 }
 
+bool HTMLAttachmentElement::hasEnclosingImage() const
+{
+    return is<HTMLImageElement>(shadowHost());
+}
+
 void HTMLAttachmentElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     if (name == progressAttr || name == subtitleAttr || name == titleAttr || name == typeAttr) {
@@ -165,6 +191,24 @@
         renderer->invalidate();
 }
 
+void HTMLAttachmentElement::updateEnclosingImageWithData(const String& contentType, Ref<SharedBuffer>&& data)
+{
+    auto* hostElement = shadowHost();
+    if (!is<HTMLImageElement>(hostElement) || !data->size())
+        return;
+
+    String mimeType = contentType;
+#if PLATFORM(COCOA)
+    if (isDeclaredUTI(contentType))
+        mimeType = MIMETypeFromUTI(contentType);
+#endif
+
+    if (!MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
+        return;
+
+    hostElement->setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(document(), Blob::create(WTFMove(data), mimeType)));
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ATTACHMENT_ELEMENT)

Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.h (236633 => 236634)


--- trunk/Source/WebCore/html/HTMLAttachmentElement.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -32,12 +32,15 @@
 namespace WebCore {
 
 class File;
+class HTMLImageElement;
 class RenderAttachment;
+class SharedBuffer;
 
 class HTMLAttachmentElement final : public HTMLElement {
     WTF_MAKE_ISO_ALLOCATED(HTMLAttachmentElement);
 public:
     static Ref<HTMLAttachmentElement> create(const QualifiedName&, Document&);
+    static const String& getAttachmentIdentifier(HTMLImageElement&);
 
     WEBCORE_EXPORT URL blobURL() const;
     WEBCORE_EXPORT File* file() const;
@@ -49,11 +52,13 @@
     void setUniqueIdentifier(const String& uniqueIdentifier) { m_uniqueIdentifier = uniqueIdentifier; }
 
     WEBCORE_EXPORT void updateAttributes(std::optional<uint64_t>&& newFileSize, const String& newContentType, const String& newFilename);
+    WEBCORE_EXPORT void updateEnclosingImageWithData(const String& contentType, Ref<SharedBuffer>&& data);
 
     InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) final;
     void removedFromAncestor(RemovalType, ContainerNode&) final;
 
-    String ensureUniqueIdentifier();
+    const String& ensureUniqueIdentifier();
+    bool hasEnclosingImage() const;
 
     WEBCORE_EXPORT String attachmentTitle() const;
     String attachmentType() const;

Modified: trunk/Source/WebCore/html/HTMLAttachmentElement.idl (236633 => 236634)


--- trunk/Source/WebCore/html/HTMLAttachmentElement.idl	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/html/HTMLAttachmentElement.idl	2018-09-29 02:12:57 UTC (rev 236634)
@@ -29,4 +29,6 @@
 ] interface HTMLAttachmentElement : HTMLElement {
     attribute File? file;
     readonly attribute DOMString uniqueIdentifier;
+
+    static DOMString getAttachmentIdentifier(HTMLImageElement imageElement);
 };

Modified: trunk/Source/WebCore/html/HTMLImageElement.idl (236633 => 236634)


--- trunk/Source/WebCore/html/HTMLImageElement.idl	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/html/HTMLImageElement.idl	2018-09-29 02:12:57 UTC (rev 236634)
@@ -42,7 +42,7 @@
     attribute unsigned long width;
     [Reflect] attribute DOMString decoding;
 
-    [Conditional=ATTACHMENT_ELEMENT, EnabledAtRuntime=AttachmentElement, ImplementedAs=attachmentIdentifier] readonly attribute DOMString webkitAttachmentIdentifier;
+    [Conditional=ATTACHMENT_ELEMENT, EnabledAtRuntime=AttachmentElement] readonly attribute DOMString attachmentIdentifier;
 
     // Extensions
     readonly attribute boolean complete;

Modified: trunk/Source/WebCore/page/EditorClient.h (236633 => 236634)


--- trunk/Source/WebCore/page/EditorClient.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebCore/page/EditorClient.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -75,8 +75,9 @@
 #if ENABLE(ATTACHMENT_ELEMENT)
     virtual void registerAttachmentIdentifier(const String& /* identifier */, const String& /* contentType */, const String& /* preferredFileName */, Ref<SharedBuffer>&&) { }
     virtual void registerAttachmentIdentifier(const String& /* identifier */, const String& /* contentType */, const String& /* filePath */) { }
+    virtual void registerAttachmentIdentifier(const String& /* identifier */) { }
     virtual void cloneAttachmentData(const String& /* fromIdentifier */, const String& /* toIdentifier */) { }
-    virtual void didInsertAttachmentWithIdentifier(const String& /* identifier */, const String& /* source */) { }
+    virtual void didInsertAttachmentWithIdentifier(const String& /* identifier */, const String& /* source */, bool /* hasEnclosingImage */) { }
     virtual void didRemoveAttachmentWithIdentifier(const String&) { }
     virtual bool supportsClientSideAttachmentData() const { return false; }
 #endif

Modified: trunk/Source/WebKit/ChangeLog (236633 => 236634)


--- trunk/Source/WebKit/ChangeLog	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/ChangeLog	2018-09-29 02:12:57 UTC (rev 236634)
@@ -1,3 +1,63 @@
+2018-09-28  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        No DOM API to instantiate an attachment for an img element
+        https://bugs.webkit.org/show_bug.cgi?id=189934
+        <rdar://problem/44743222>
+
+        Reviewed by Ryosuke Niwa.
+
+        Makes some adjustments to support using _WKAttachment's file wrapper to change the contents of any image element
+        hosting the attachment in its shadow root. To do this, we add some plumbing to allow the UI process to update an
+        attachment element's enclosing image with data from its file wrapper.
+
+        * UIProcess/API/APIAttachment.cpp:
+        (API::Attachment::isEmpty const):
+        (API::Attachment::enclosingImageData const):
+
+        Helper method that creates a SharedBuffer representing image data for the attachment. Only returns a non-null
+        value for attachment elements that are enclosed within an image.
+
+        * UIProcess/API/APIAttachment.h:
+        * UIProcess/API/Cocoa/APIAttachmentCocoa.mm:
+        (API::Attachment::enclosingImageData const):
+        (API::Attachment::isEmpty const):
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _attachmentForIdentifier:]):
+
+        Add new SPI to request a _WKAttachment for a given unique identifier. Currently, this is only used for testing.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Cocoa/WebPageProxyCocoa.mm:
+        (WebKit::WebPageProxy::platformRegisterAttachment):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::updateAttachmentAttributes):
+        (WebKit::WebPageProxy::registerAttachmentIdentifier):
+        (WebKit::WebPageProxy::didInsertAttachmentWithIdentifier):
+
+        Plumb whether or not the attachment is enclosed by an image from the web process to the UI process.
+
+        (WebKit::WebPageProxy::didRemoveAttachmentWithIdentifier):
+        (WebKit::WebPageProxy::didInsertAttachment): Deleted.
+        (WebKit::WebPageProxy::didRemoveAttachment):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+        (WebKit::WebEditorClient::registerAttachmentIdentifier):
+        (WebKit::WebEditorClient::didInsertAttachmentWithIdentifier):
+
+        Update attachment attributes after inserting an attachment. This ensures that an attachment that was created and
+        later inserted via script into the document will be synced with state in the UI process, if the client has
+        changed the contents of the attachment.
+
+        * WebProcess/WebCoreSupport/WebEditorClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updateAttachmentAttributes):
+
+        Plumb attachment data from the UI process to the web process.
+
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2018-09-28  Chris Dumez  <cdu...@apple.com>
 
         Regression(r236512): http/tests/navigation/keyboard-events-during-provisional-navigation.html is flaky

Modified: trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/API/APIAttachment.cpp	2018-09-29 02:12:57 UTC (rev 236634)
@@ -71,6 +71,11 @@
 
 #if !PLATFORM(COCOA)
 
+bool Attachment::isEmpty() const
+{
+    return true;
+}
+
 WTF::String Attachment::mimeType() const
 {
     return m_contentType;
@@ -86,6 +91,11 @@
     return std::nullopt;
 }
 
+RefPtr<WebCore::SharedBuffer> Attachment::enclosingImageData() const
+{
+    return nullptr;
+}
+
 #endif // !PLATFORM(COCOA)
 
 }

Modified: trunk/Source/WebKit/UIProcess/API/APIAttachment.h (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/API/APIAttachment.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/API/APIAttachment.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -77,8 +77,14 @@
     InsertionState insertionState() const { return m_insertionState; }
     void setInsertionState(InsertionState state) { m_insertionState = state; }
 
+    bool isEmpty() const;
+
+    RefPtr<WebCore::SharedBuffer> enclosingImageData() const;
     std::optional<uint64_t> fileSizeForDisplay() const;
 
+    void setHasEnclosingImage(bool hasEnclosingImage) { m_hasEnclosingImage = hasEnclosingImage; }
+    bool hasEnclosingImage() const { return m_hasEnclosingImage; }
+
 private:
     explicit Attachment(const WTF::String& identifier, WebKit::WebPageProxy&);
 
@@ -90,6 +96,7 @@
     WTF::String m_contentType;
     WeakPtr<WebKit::WebPageProxy> m_webPage;
     InsertionState m_insertionState { InsertionState::NotInserted };
+    bool m_hasEnclosingImage { false };
 };
 
 } // namespace API

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm	2018-09-29 02:12:57 UTC (rev 236634)
@@ -27,6 +27,7 @@
 #import "APIAttachment.h"
 
 #import <WebCore/MIMETypeRegistry.h>
+#import <WebCore/SharedBuffer.h>
 #if PLATFORM(IOS)
 #import <MobileCoreServices/MobileCoreServices.h>
 #else
@@ -104,4 +105,24 @@
     return [m_fileWrapper regularFileContents].length;
 }
 
+RefPtr<WebCore::SharedBuffer> Attachment::enclosingImageData() const
+{
+    if (!m_hasEnclosingImage)
+        return nullptr;
+
+    if (![m_fileWrapper isRegularFile])
+        return nullptr;
+
+    NSData *data = "" regularFileContents];
+    if (!data)
+        return nullptr;
+
+    return WebCore::SharedBuffer::create(data);
+}
+
+bool Attachment::isEmpty() const
+{
+    return !m_fileWrapper;
+}
+
 } // namespace API

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2018-09-29 02:12:57 UTC (rev 236634)
@@ -4566,6 +4566,15 @@
 #endif
 }
 
+- (_WKAttachment *)_attachmentForIdentifier:(NSString *)identifier
+{
+#if ENABLE(ATTACHMENT_ELEMENT)
+    if (auto attachment = _page->attachmentForIdentifier(identifier))
+        return wrapper(attachment);
+#endif
+    return nil;
+}
+
 - (void)_pasteAsQuotation:(id)sender
 {
 #if PLATFORM(MAC)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -184,6 +184,7 @@
 - (_WKAttachment *)_insertAttachmentWithFilename:(NSString *)filename contentType:(NSString *)contentType data:(NSData *)data options:(_WKAttachmentDisplayOptions *)options completion:(void(^)(BOOL success))completionHandler WK_API_DEPRECATED_WITH_REPLACEMENT("-_insertAttachmentWithFileWrapper:contentType:options:completion:", macosx(10.13.4, WK_MAC_TBA), ios(11.3, WK_IOS_TBA));
 - (_WKAttachment *)_insertAttachmentWithFileWrapper:(NSFileWrapper *)fileWrapper contentType:(NSString *)contentType options:(_WKAttachmentDisplayOptions *)options completion:(void(^)(BOOL success))completionHandler WK_API_DEPRECATED_WITH_REPLACEMENT("-_insertAttachmentWithFileWrapper:contentType:completion:", macosx(WK_MAC_TBA, WK_MAC_TBA), ios(WK_IOS_TBA, WK_IOS_TBA));
 - (_WKAttachment *)_insertAttachmentWithFileWrapper:(NSFileWrapper *)fileWrapper contentType:(NSString *)contentType completion:(void(^)(BOOL success))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (_WKAttachment *)_attachmentForIdentifier:(NSString *)identifier WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (IBAction)_pasteAsQuotation:(id)sender WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm	2018-09-29 02:12:57 UTC (rev 236634)
@@ -164,6 +164,9 @@
 
 void WebPageProxy::platformRegisterAttachment(Ref<API::Attachment>&& attachment, const String& preferredFileName, const IPC::DataReference& dataReference)
 {
+    if (dataReference.isEmpty())
+        return;
+
     auto buffer = SharedBuffer::create(dataReference.data(), dataReference.size());
     auto fileWrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:buffer->createNSData().autorelease()]);
     [fileWrapper setPreferredFilename:preferredFileName];
@@ -172,6 +175,9 @@
 
 void WebPageProxy::platformRegisterAttachment(Ref<API::Attachment>&& attachment, const String& filePath)
 {
+    if (!filePath)
+        return;
+
     auto fileWrapper = adoptNS([[NSFileWrapper alloc] initWithURL:[NSURL fileURLWithPath:filePath] options:0 error:nil]);
     attachment->setFileWrapper(fileWrapper.get());
 }

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-09-29 02:12:57 UTC (rev 236634)
@@ -78,6 +78,7 @@
 #include "PrintInfo.h"
 #include "SafeBrowsingResult.h"
 #include "ShareSheetCallbackID.h"
+#include "SharedBufferDataReference.h"
 #include "TextChecker.h"
 #include "TextCheckerState.h"
 #include "UIMessagePortChannelProvider.h"
@@ -7775,8 +7776,12 @@
         return;
     }
 
+    IPC::SharedBufferDataReference dataReference;
+    if (auto data = ""
+        dataReference = { *data };
+
     auto callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
-    m_process->send(Messages::WebPage::UpdateAttachmentAttributes(attachment.identifier(), attachment.fileSizeForDisplay(), attachment.contentType(), attachment.fileName(), callbackID), m_pageID);
+    m_process->send(Messages::WebPage::UpdateAttachmentAttributes(attachment.identifier(), attachment.fileSizeForDisplay(), attachment.contentType(), attachment.fileName(), WTFMove(dataReference), callbackID), m_pageID);
 }
 
 void WebPageProxy::registerAttachmentIdentifierFromData(const String& identifier, const String& contentType, const String& preferredFileName, const IPC::DataReference& data)
@@ -7804,6 +7809,12 @@
     platformRegisterAttachment(WTFMove(attachment), filePath);
 }
 
+void WebPageProxy::registerAttachmentIdentifier(const String& identifier)
+{
+    if (!attachmentForIdentifier(identifier))
+        m_attachmentIdentifierToAttachmentMap.set(identifier, ensureAttachment(identifier));
+}
+
 void WebPageProxy::cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier)
 {
     auto newAttachment = ensureAttachment(toIdentifier);
@@ -7845,10 +7856,15 @@
 
 #endif
 
-void WebPageProxy::didInsertAttachmentWithIdentifier(const String& identifier, const String& source)
+void WebPageProxy::didInsertAttachmentWithIdentifier(const String& identifier, const String& source, bool hasEnclosingImage)
 {
     auto attachment = ensureAttachment(identifier);
-    didInsertAttachment(attachment.get(), source);
+    attachment->setHasEnclosingImage(hasEnclosingImage);
+    attachment->setInsertionState(API::Attachment::InsertionState::Inserted);
+    pageClient().didInsertAttachment(attachment.get(), source);
+
+    if (!attachment->isEmpty() && hasEnclosingImage)
+        updateAttachmentAttributes(attachment.get(), [] (auto) { });
 }
 
 void WebPageProxy::didRemoveAttachmentWithIdentifier(const String& identifier)
@@ -7857,12 +7873,6 @@
         didRemoveAttachment(*attachment);
 }
 
-void WebPageProxy::didInsertAttachment(API::Attachment& attachment, const String& source)
-{
-    attachment.setInsertionState(API::Attachment::InsertionState::Inserted);
-    pageClient().didInsertAttachment(attachment, source);
-}
-
 void WebPageProxy::didRemoveAttachment(API::Attachment& attachment)
 {
     attachment.setInsertionState(API::Attachment::InsertionState::NotInserted);

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -1814,8 +1814,9 @@
     void stopAllURLSchemeTasks();
 
 #if ENABLE(ATTACHMENT_ELEMENT)
-    void registerAttachmentIdentifierFromData(const String& identifier, const String& contentType, const String& preferredFileName, const IPC::DataReference&);
-    void registerAttachmentIdentifierFromFilePath(const String& identifier, const String& contentType, const String& filePath);
+    void registerAttachmentIdentifierFromData(const String&, const String& contentType, const String& preferredFileName, const IPC::DataReference&);
+    void registerAttachmentIdentifierFromFilePath(const String&, const String& contentType, const String& filePath);
+    void registerAttachmentIdentifier(const String&);
     void cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier);
 
     void platformRegisterAttachment(Ref<API::Attachment>&&, const String& preferredFileName, const IPC::DataReference&);
@@ -1822,9 +1823,8 @@
     void platformRegisterAttachment(Ref<API::Attachment>&&, const String& filePath);
     void platformCloneAttachment(Ref<API::Attachment>&& fromAttachment, Ref<API::Attachment>&& toAttachment);
 
-    void didInsertAttachmentWithIdentifier(const String& identifier, const String& source);
+    void didInsertAttachmentWithIdentifier(const String& identifier, const String& source, bool hasEnclosingImage);
     void didRemoveAttachmentWithIdentifier(const String& identifier);
-    void didInsertAttachment(API::Attachment&, const String& source);
     void didRemoveAttachment(API::Attachment&);
     Ref<API::Attachment> ensureAttachment(const String& identifier);
     void invalidateAllAttachments();

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in (236633 => 236634)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in	2018-09-29 02:12:57 UTC (rev 236634)
@@ -534,8 +534,9 @@
 #if ENABLE(ATTACHMENT_ELEMENT)
     RegisterAttachmentIdentifierFromData(String identifier, String contentType, String preferredFileName, IPC::SharedBufferDataReference data)
     RegisterAttachmentIdentifierFromFilePath(String identifier, String contentType, String filePath)
+    RegisterAttachmentIdentifier(String identifier)
     CloneAttachmentData(String fromIdentifier, String toIdentifier)
-    DidInsertAttachmentWithIdentifier(String identifier, String source)
+    DidInsertAttachmentWithIdentifier(String identifier, String source, bool hasEnclosingImage)
     DidRemoveAttachmentWithIdentifier(String identifier)
 #endif
 

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp (236633 => 236634)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp	2018-09-29 02:12:57 UTC (rev 236634)
@@ -170,14 +170,19 @@
     m_page->send(Messages::WebPageProxy::RegisterAttachmentIdentifierFromFilePath(identifier, contentType, filePath));
 }
 
+void WebEditorClient::registerAttachmentIdentifier(const String& identifier)
+{
+    m_page->send(Messages::WebPageProxy::RegisterAttachmentIdentifier(identifier));
+}
+
 void WebEditorClient::cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier)
 {
     m_page->send(Messages::WebPageProxy::CloneAttachmentData(fromIdentifier, toIdentifier));
 }
 
-void WebEditorClient::didInsertAttachmentWithIdentifier(const String& identifier, const String& source)
+void WebEditorClient::didInsertAttachmentWithIdentifier(const String& identifier, const String& source, bool hasEnclosingImage)
 {
-    m_page->send(Messages::WebPageProxy::DidInsertAttachmentWithIdentifier(identifier, source));
+    m_page->send(Messages::WebPageProxy::DidInsertAttachmentWithIdentifier(identifier, source, hasEnclosingImage));
 }
 
 void WebEditorClient::didRemoveAttachmentWithIdentifier(const String& identifier)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h (236633 => 236634)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -60,10 +60,11 @@
     bool shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*) final;
 
 #if ENABLE(ATTACHMENT_ELEMENT)
-    void registerAttachmentIdentifier(const String& identifier, const String& contentType, const String& preferredFileName, Ref<WebCore::SharedBuffer>&&) final;
-    void registerAttachmentIdentifier(const String& identifier, const String& contentType, const String& filePath) final;
+    void registerAttachmentIdentifier(const String&, const String& contentType, const String& preferredFileName, Ref<WebCore::SharedBuffer>&&) final;
+    void registerAttachmentIdentifier(const String&, const String& contentType, const String& filePath) final;
+    void registerAttachmentIdentifier(const String&) final;
     void cloneAttachmentData(const String& fromIdentifier, const String& toIdentifier) final;
-    void didInsertAttachmentWithIdentifier(const String& identifier, const String& source) final;
+    void didInsertAttachmentWithIdentifier(const String& identifier, const String& source, bool hasEnclosingImage) final;
     void didRemoveAttachmentWithIdentifier(const String& identifier) final;
     bool supportsClientSideAttachmentData() const final { return true; }
 #endif

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (236633 => 236634)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2018-09-29 02:12:57 UTC (rev 236634)
@@ -6123,11 +6123,12 @@
     send(Messages::WebPageProxy::VoidCallback(callbackID));
 }
 
-void WebPage::updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, const String& fileName, CallbackID callbackID)
+void WebPage::updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, const String& fileName, const IPC::DataReference& enclosingImageData, CallbackID callbackID)
 {
     if (auto attachment = attachmentElementWithIdentifier(identifier)) {
         attachment->document().updateLayout();
         attachment->updateAttributes(WTFMove(fileSize), contentType, fileName);
+        attachment->updateEnclosingImageWithData(contentType, SharedBuffer::create(enclosingImageData.data(), enclosingImageData.size()));
     }
     send(Messages::WebPageProxy::VoidCallback(callbackID));
 }

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (236633 => 236634)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-09-29 02:12:57 UTC (rev 236634)
@@ -1081,7 +1081,7 @@
     
 #if ENABLE(ATTACHMENT_ELEMENT)
     void insertAttachment(const String& identifier, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType, CallbackID);
-    void updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, const String& fileName, CallbackID);
+    void updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, const String& fileName, const IPC::DataReference& enclosingImageData, CallbackID);
 #endif
 
 #if ENABLE(APPLICATION_MANIFEST)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (236633 => 236634)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-09-29 02:12:57 UTC (rev 236634)
@@ -514,7 +514,7 @@
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     InsertAttachment(String identifier, std::optional<uint64_t> fileSize, String fileName, String contentType, WebKit::CallbackID callbackID)
-    UpdateAttachmentAttributes(String identifier, std::optional<uint64_t> fileSize, String contentType, String fileName, WebKit::CallbackID callbackID)
+    UpdateAttachmentAttributes(String identifier, std::optional<uint64_t> fileSize, String contentType, String fileName, IPC::SharedBufferDataReference enclosingImageData, WebKit::CallbackID callbackID)
 #endif
 
 #if ENABLE(APPLICATION_MANIFEST)

Modified: trunk/Tools/ChangeLog (236633 => 236634)


--- trunk/Tools/ChangeLog	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Tools/ChangeLog	2018-09-29 02:12:57 UTC (rev 236634)
@@ -1,3 +1,29 @@
+2018-09-28  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        No DOM API to instantiate an attachment for an img element
+        https://bugs.webkit.org/show_bug.cgi?id=189934
+        <rdar://problem/44743222>
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds 3 new API tests in WKAttachmentTests:
+
+        `AddAttachmentToConnectedImageElement` verifies that an image element that's already in the document can gain an
+        attachment element via `HTMLAttachmentElement.getAttachmentIdentifier`.
+
+        `ChangeFileWrapperForPastedImage` verifies that an image that has been pasted produces a _WKAttachment in the UI
+        process, and changing the file wrapper of that _WKAttachment changes the pasted image.
+
+        `ConnectImageWithAttachmentToDocument` verifies that script can create an image element, ensure that it has an
+        attachment, and set a file wrapper for the generated _WKAttachment. Connecting the image to the document should
+        then result in an image element with the contents of the _WKAttachment's file wrapper.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+        (-[TestWKWebView imageElementSize]):
+        (-[TestWKWebView waitForImageElementSizeToBecome:]):
+        (TestWebKitAPI::TEST):
+        (-[TestWKWebView waitForAttachmentElementSizeToBecome:]): Deleted.
+
 2018-09-28  Chris Dumez  <cdu...@apple.com>
 
         Regression(r236512): http/tests/navigation/keyboard-events-during-provisional-navigation.html is flaky

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm (236633 => 236634)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm	2018-09-29 02:03:51 UTC (rev 236633)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm	2018-09-29 02:12:57 UTC (rev 236634)
@@ -305,10 +305,22 @@
     return size;
 }
 
-- (void)waitForAttachmentElementSizeToBecome:(CGSize)expectedSize
+- (CGSize)imageElementSize
 {
+    __block CGSize size;
+    __block bool doneEvaluatingScript = false;
+    [self evaluateJavaScript:@"r = document.querySelector('img').getBoundingClientRect(); [r.width, r.height]" completionHandler:^(NSArray<NSNumber *> *sizeResult, NSError *) {
+        size = CGSizeMake(sizeResult.firstObject.floatValue, sizeResult.lastObject.floatValue);
+        doneEvaluatingScript = true;
+    }];
+    TestWebKitAPI::Util::run(&doneEvaluatingScript);
+    return size;
+}
+
+- (void)waitForImageElementSizeToBecome:(CGSize)expectedSize
+{
     while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
-        if (CGSizeEqualToSize(self.attachmentElementSize, expectedSize))
+        if (CGSizeEqualToSize(self.imageElementSize, expectedSize))
             break;
     }
 }
@@ -907,7 +919,7 @@
     auto size = platformImageWithData([attachment info].data).size;
     EXPECT_EQ(215., size.width);
     EXPECT_EQ(174., size.height);
-    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
 
     [webView stringByEvaluatingJavaScript:@"getSelection().collapse(document.body, 0)"];
     {
@@ -993,7 +1005,7 @@
 
     [attachment expectRequestedDataToBe:testImageData()];
     EXPECT_WK_STREQ("Lorem ipsum  dolor sit amet.", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]);
-    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
 
     {
         ObserveAttachmentUpdatesForScope observer(webView.get());
@@ -1039,7 +1051,7 @@
     EXPECT_WK_STREQ("application/octet-stream", zipAttachmentType);
 #endif
 
-    EXPECT_WK_STREQ([imageAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+    EXPECT_WK_STREQ([imageAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
     EXPECT_WK_STREQ([pdfAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].uniqueIdentifier"]);
     EXPECT_WK_STREQ([zipAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].uniqueIdentifier"]);
 
@@ -1163,7 +1175,7 @@
     }
     [webView expectElementTagsInOrder:@[ @"IMG", @"ATTACHMENT", @"ATTACHMENT" ]];
     EXPECT_WK_STREQ("cid:foo-bar", [webView valueOfAttribute:@"src" forQuerySelector:@"img"]);
-    EXPECT_WK_STREQ(@"", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('img')[0].webkitAttachmentIdentifier"]);
+    EXPECT_WK_STREQ(@"", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('img')[0].attachmentIdentifier"]);
 }
 
 TEST(WKAttachmentTests, InjectedBundleReplaceURLWhenPastingImage)
@@ -1348,6 +1360,77 @@
     observer.expectAttachmentUpdates(@[ ], @[ pngAttachment.get(), gifAttachment.get() ]);
 }
 
+TEST(WKAttachmentTests, ChangeFileWrapperForPastedImage)
+{
+    platformCopyPNG();
+    auto webView = webViewForTestingAttachments();
+
+    ObserveAttachmentUpdatesForScope observer(webView.get());
+    [webView paste:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
+
+    auto attachment = retainPtr(observer.observer().inserted.firstObject);
+    auto originalImageData = retainPtr([attachment info].fileWrapper);
+    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"HTMLAttachmentElement.getAttachmentIdentifier(document.querySelector('img'))"]);
+
+    auto newImage = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testGIFData()]);
+    [newImage setPreferredFilename:@"foo.gif"];
+    [attachment synchronouslySetFileWrapper:newImage.get() newContentType:nil error:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(52, 64)];
+
+    [attachment synchronouslySetFileWrapper:originalImageData.get() newContentType:@"image/png" error:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
+}
+
+TEST(WKAttachmentTests, AddAttachmentToConnectedImageElement)
+{
+    auto webView = webViewForTestingAttachments();
+    [webView _synchronouslyExecuteEditCommand:@"InsertHTML" argument:@"<img></img>"];
+
+    ObserveAttachmentUpdatesForScope observer(webView.get());
+    NSString *attachmentIdentifier = [webView stringByEvaluatingJavaScript:@"HTMLAttachmentElement.getAttachmentIdentifier(document.querySelector('img'))"];
+    auto attachment = retainPtr([webView _attachmentForIdentifier:attachmentIdentifier]);
+    EXPECT_WK_STREQ(attachmentIdentifier, [attachment uniqueIdentifier]);
+    EXPECT_WK_STREQ(attachmentIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
+    observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
+
+    auto firstImage = adoptNS([[NSFileWrapper alloc] initWithURL:testImageFileURL() options:0 error:nil]);
+    auto secondImage = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testGIFData()]);
+    [secondImage setPreferredFilename:@"foo.gif"];
+
+    [attachment synchronouslySetFileWrapper:firstImage.get() newContentType:@"image/png" error:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
+
+    [attachment synchronouslySetFileWrapper:secondImage.get() newContentType:(__bridge NSString *)kUTTypeGIF error:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(52, 64)];
+
+    [attachment synchronouslySetFileWrapper:firstImage.get() newContentType:nil error:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
+}
+
+TEST(WKAttachmentTests, ConnectImageWithAttachmentToDocument)
+{
+    auto webView = webViewForTestingAttachments();
+    ObserveAttachmentUpdatesForScope observer(webView.get());
+
+    NSString *identifier = [webView stringByEvaluatingJavaScript:@"image = document.createElement('img'); HTMLAttachmentElement.getAttachmentIdentifier(image)"];
+    auto image = adoptNS([[NSFileWrapper alloc] initWithURL:testImageFileURL() options:0 error:nil]);
+    auto attachment = retainPtr([webView _attachmentForIdentifier:identifier]);
+    [attachment synchronouslySetFileWrapper:image.get() newContentType:nil error:nil];
+    EXPECT_FALSE([attachment isConnected]);
+    observer.expectAttachmentUpdates(@[ ], @[ ]);
+
+    [webView evaluateJavaScript:@"document.body.appendChild(image)" completionHandler:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
+    EXPECT_TRUE([attachment isConnected]);
+    observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
+
+    auto newImage = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testGIFData()]);
+    [newImage setPreferredFilename:@"test.gif"];
+    [attachment synchronouslySetFileWrapper:newImage.get() newContentType:nil error:nil];
+    [webView waitForImageElementSizeToBecome:CGSizeMake(52, 64)];
+}
+
 #pragma mark - Platform-specific tests
 
 #if PLATFORM(MAC)
@@ -1373,7 +1456,7 @@
     EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('type')"]);
     EXPECT_WK_STREQ("test.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('title')"]);
 
-    NSString *imageAttachmentIdentifier = [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"];
+    NSString *imageAttachmentIdentifier = [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"];
     if ([testImageData() isEqualToData:[insertedAttachments firstObject].info.data])
         EXPECT_WK_STREQ([insertedAttachments firstObject].uniqueIdentifier, imageAttachmentIdentifier);
     else
@@ -1417,7 +1500,7 @@
             EXPECT_WK_STREQ("application/pdf", attachment.info.contentType);
         else if ([testImageData() isEqualToData:attachment.info.data]) {
             EXPECT_WK_STREQ("image/png", attachment.info.contentType);
-            EXPECT_WK_STREQ(attachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+            EXPECT_WK_STREQ(attachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
         }
     }
 
@@ -1467,7 +1550,7 @@
     EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);
     auto attachment = retainPtr([dragAndDropSimulator insertedAttachments].firstObject);
     [attachment expectRequestedDataToBe:testImageData()];
-    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
 
     {
         ObserveAttachmentUpdatesForScope observer(webView.get());
@@ -1495,7 +1578,7 @@
     auto size = platformImageWithData([attachment info].data).size;
     EXPECT_EQ(215., size.width);
     EXPECT_EQ(174., size.height);
-    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').webkitAttachmentIdentifier"]);
+    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
 
     {
         ObserveAttachmentUpdatesForScope observer(webView.get());
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to