[Cocoa] Attachment dropped from one web view to another is missing its file wrapper
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Oct 2018 05:29:17 +0000 (05:29 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 31 Oct 2018 05:29:17 +0000 (05:29 +0000)
commit98d82616bbaf7c9ab7de00e4494bedbee5b5c9c3
tree76b49726c6c0148104ac841ec361a2805e181b66
parent28184a44a4898bddf77964dd546180048985217f
[Cocoa] Attachment dropped from one web view to another is missing its file wrapper
https://bugs.webkit.org/show_bug.cgi?id=190530
<rdar://problem/45232149>

Reviewed by Tim Horton.

Source/WebCore:

Add support for copying and pasting attachment elements across web views by encoding and adding file wrapper
data as subresources in the web archive when writing selected web content to the pasteboard, and then decoding
and creating NSFileWrappers upon reading web content.

Test: WKAttachmentTests.CopyAndPasteBetweenWebViews

* WebCore.xcodeproj/project.pbxproj:
* editing/Editor.cpp:
(WebCore::Editor::registerAttachments):
* editing/Editor.h:

Add registerAttachments(), which registers _WKAttachments in the UI process given a list of
SerializedAttachmentData. This behaves similarly to registerAttachmentIdentifiers(), but differs in that (1) it
sends serialized file wrapper data, and (2) it sends a list of serialized attachments, rather than information
about just a single attachment.

* editing/SerializedAttachmentData.h:

Introduce SerializedAttachmentData, a struct containing information needed to serialize and deserialize an
attachment. These are used both when writing attachment data to the pasteboard, and when consuming attachment
data upon paste.

* editing/cocoa/WebContentReaderCocoa.mm:
(WebCore::replaceRichContentWithAttachments):

Add a step when pasting rich content with attachments, to collect and send serialized attachments to the client.
Also, drive-by fix: don't WTFMove() the Ref here if it's still going to be used below.

* html/HTMLAttachmentElement.cpp:
(WebCore::HTMLAttachmentElement::archiveResourceURL):
* html/HTMLAttachmentElement.h:

Add a static helper function to compute a URL that represents the data for the given attachment identifier, for
use in a web archive resource.

* loader/archive/cf/LegacyWebArchive.cpp:
(WebCore::addSubresourcesForAttachmentElementsIfNecessary):

Add a helper function to create and append ArchiveResources representing attachment element data when writing
attachments to the pasteboard via web archive data.

(WebCore::LegacyWebArchive::create):
* page/EditorClient.h:
(WebCore::EditorClient::registerAttachments):
(WebCore::EditorClient::serializedAttachmentDataForIdentifiers):

Source/WebKit:

See WebCore ChangeLog for more details.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<SerializedAttachmentData>::encode):
(IPC::ArgumentCoder<SerializedAttachmentData>::decode):
* Shared/WebCoreArgumentCoders.h:

Add IPC encoding/decoding support for SerializedAttachmentData.

* UIProcess/API/APIAttachment.cpp:
(API::Attachment::createSerializedRepresentation const):
(API::Attachment::updateFromSerializedRepresentation):
* UIProcess/API/APIAttachment.h:
* UIProcess/API/Cocoa/APIAttachmentCocoa.mm:
(API::Attachment::createSerializedRepresentation const):

Add a method to serialize and return attachment info as a blob of data.

(API::Attachment::updateFromSerializedRepresentation):

Add a method to update the attachment, given a serialized blob of data. On Cocoa platforms, this fails
gracefully if the serialized data cannot be decoded.

* UIProcess/Cocoa/PageClientImplCocoa.h:
* UIProcess/Cocoa/PageClientImplCocoa.mm:
(WebKit::PageClientImplCocoa::allocFileWrapperInstance const):
(WebKit::PageClientImplCocoa::serializableFileWrapperClasses const):
(WebKit::PageClientImplCocoa::allocFileWrapperInstance): Deleted.

Add an additional hook to return the list of NSFileWrapper subclasses suitable for deserialization. This
array contains (at minimum) NSFileWrapper, but may additionally include a custom NSFileWrapper subclass, if
configured.

* UIProcess/PageClient.h:
(WebKit::PageClient::allocFileWrapperInstance const):
(WebKit::PageClient::serializableFileWrapperClasses const):
(WebKit::PageClient::allocFileWrapperInstance): Deleted.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::registerAttachmentsFromSerializedData):

Registers the given serialized attachment data, creating new _WKAttachment instances if necessary. Currently,
this does not update the file wrappers of existing _WKAttachments; we should revisit this in the future to see
if we can additionally update file wrappers for existing attachments, without breaking the case where the user
copies and pastes or drags and drops attachments within a single web view and the client expects _WKAttachment
instances to be reused.

(WebKit::WebPageProxy::serializedAttachmentDataForIdentifiers):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::registerAttachments):
(WebKit::WebEditorClient::serializedAttachmentDataForIdentifiers):

Implement a new IPC hook to fetch an array of serialized attachment data blobs, given a list of attachment
identifiers.

* WebProcess/WebCoreSupport/WebEditorClient.h:

Tools:

Add a test to verify that copying different types of attachments and pasting in a new web view inserts
attachments in the second web view that are backed by _WKAttachment objects, whose NSFileWrappers hold data that
is equivalent to the original file wrappers used to insert attachments in the first web view.

Existing API tests verify that when copying and pasting within a single web view, the pasted attachment element
is still backed by the same NSFileWrapper instance.

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

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237624 268f45cc-cd09-0410-ab3c-d52691b4dbfc
26 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/editing/SerializedAttachmentData.h [new file with mode: 0644]
Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm
Source/WebCore/html/HTMLAttachmentElement.cpp
Source/WebCore/html/HTMLAttachmentElement.h
Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
Source/WebCore/page/EditorClient.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/UIProcess/API/APIAttachment.cpp
Source/WebKit/UIProcess/API/APIAttachment.h
Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm
Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h
Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm
Source/WebKit/UIProcess/PageClient.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm