Title: [251100] trunk/Source
Revision
251100
Author
wenson_hs...@apple.com
Date
2019-10-14 14:52:26 -0700 (Mon, 14 Oct 2019)

Log Message

[Clipboard API] Support writing multiple PasteboardCustomData with SharedBuffers to the pasteboard
https://bugs.webkit.org/show_bug.cgi?id=202851

Reviewed by Darin Adler.

Source/WebCore:

This patch refactors some logic around WebCore::PasteboardCustomData, in preparation for implementing the async
clipboard API. There are two main goals of this refactoring:

1. Enable writing multiple items (each backed by PasteboardCustomData) to the platform pasteboard.
2. Enable writing platform data in the form of SharedBuffers to the platform pasteboard.

See below for more details; no tests, as there is no change in behavior yet.

* Headers.cmake:
* Sources.txt:
* SourcesCocoa.txt:
* WebCore.xcodeproj/project.pbxproj:

Move PasteboardCustomData out of Pasteboard.h and into its own file.

* dom/DataTransfer.cpp:
(WebCore::DataTransfer::commitToPasteboard):
* editing/cocoa/EditorCocoa.mm:
(WebCore::Editor::getPasteboardTypesAndDataForAttachment):
* platform/Pasteboard.cpp:
(WebCore::PasteboardCustomData::createSharedBuffer const): Deleted.
(WebCore::PasteboardCustomData::fromSharedBuffer): Deleted.

Moved these method implementations to PasteboardCustomData.cpp.

* platform/Pasteboard.h:

Refactor PasteboardCustomData so that its member variables are now private, and encapsulated behind methods
Additionally, make it so that the only way to set data on PasteboardCustomData is to use the writeString,
writeData, and writeStringInCustomData methods, which ensure that the PasteboardCustomData is always in a
consistent state.

* platform/PasteboardCustomData.cpp: Added.
(WebCore::copyPlatformData):
(WebCore::PasteboardCustomData::Entry::Entry):
(WebCore::PasteboardCustomData::Entry::operator=):

Refactor the implementation of PasteboardCustomData, so that it contains a list of PasteboardCustomData entries
instead of individual Vectors and HashMaps.

(WebCore::PasteboardCustomData::PasteboardCustomData):
(WebCore::PasteboardCustomData::createSharedBuffer const):
(WebCore::PasteboardCustomData::fromSharedBuffer):
(WebCore::PasteboardCustomData::writeString):
(WebCore::PasteboardCustomData::writeData):
(WebCore::PasteboardCustomData::writeStringInCustomData):
(WebCore::PasteboardCustomData::addOrMoveEntryToEnd):

Move logic from StaticPasteboard into PasteboardCustomData, and refactor these methods to handle
Vector<PasteboardCustomData::Entry>.

(WebCore::PasteboardCustomData::clear):
(WebCore::PasteboardCustomData::operator=):
(WebCore::PasteboardCustomData::orderedTypes const):
(WebCore::PasteboardCustomData::hasData const):
(WebCore::PasteboardCustomData::hasSameOriginCustomData const):
(WebCore::PasteboardCustomData::sameOriginCustomStringData const):
(WebCore::PasteboardCustomData::readBuffer const):
(WebCore::PasteboardCustomData::readString const):
(WebCore::PasteboardCustomData::readStringInCustomData const):
(WebCore::PasteboardCustomData::forEachType const):
(WebCore::PasteboardCustomData::forEachPlatformString const):
(WebCore::PasteboardCustomData::forEachCustomString const):
(WebCore::PasteboardCustomData::forEachPlatformStringOrBuffer const):

Moved these method implementations from StaticPasteboard to PasteboardCustomData, and also introduced some new
methods to help iterate through types and data.

* platform/PasteboardCustomData.h: Added.
(WebCore::PasteboardCustomData::origin const):
(WebCore::PasteboardCustomData::setOrigin):
(WebCore::PasteboardCustomData::data const):
* platform/PasteboardStrategy.h:
* platform/PlatformPasteboard.h:
* platform/SharedBuffer.cpp:
(WebCore::SharedBuffer::decoder const):
* platform/SharedBuffer.h:
* platform/StaticPasteboard.cpp:
(WebCore::StaticPasteboard::hasData):
(WebCore::StaticPasteboard::typesSafeForBindings):
(WebCore::StaticPasteboard::typesForLegacyUnsafeBindings):
(WebCore::StaticPasteboard::readString):
(WebCore::StaticPasteboard::readStringInCustomData):
(WebCore::StaticPasteboard::writeString):
(WebCore::StaticPasteboard::writeData):
(WebCore::StaticPasteboard::writeStringInCustomData):
(WebCore::StaticPasteboard::clear):
(WebCore::StaticPasteboard::takeCustomData):
(WebCore::StaticPasteboard::StaticPasteboard): Deleted.

Refactor StaticPasteboard to now contain a PasteboardCustomData; additionally, adjust several methods in
StaticPasteboard to simply call into PasteboardCustomData to write, read, or clear data.

(WebCore::updateTypes): Deleted.
* platform/StaticPasteboard.h:
* platform/cocoa/PasteboardCocoa.mm:
(WebCore::Pasteboard::readStringInCustomData):
(WebCore::Pasteboard::readOrigin):
(WebCore::PasteboardCustomData::cocoaType): Deleted.

Moved the implementation of PasteboardCustomData::cocoaType from PasteboardCocoa.mm to
PasteboardCustomDataCocoa.mm.

* platform/cocoa/PasteboardCustomDataCocoa.mm: Added.
(WebCore::PasteboardCustomData::cocoaType):
* platform/ios/AbstractPasteboard.h:
* platform/ios/PlatformPasteboardIOS.mm:
(WebCore::PlatformPasteboard::changeCount const):
(WebCore::registerItemsToPasteboard):
(WebCore::registerItemToPasteboard):
(WebCore::PlatformPasteboard::write):

Support writing multiple PasteboardCustomData objects to the platform pasteboard on iOS, by generating
NSItemProviders for each one. This refactors the existing `registerItemToPasteboard` helper to handle multiple
registration lists, renames it to `registerItemsToPasteboard` (plural), and then reimplements
`registerItemToPasteboard` in terms of `registerItemsToPasteboard`.

(WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const):
(WebCore::createItemProviderRegistrationList):

Adjust these to use getters on PasteboardCustomData instead of accessing the member variables directly.

* platform/ios/WebItemProviderPasteboard.mm:
(-[WebItemProviderPasteboard init]):
(-[WebItemProviderPasteboard stageRegistrationLists:]):
(-[WebItemProviderPasteboard clearRegistrationLists]):
(-[WebItemProviderPasteboard takeRegistrationLists]):

Refactor registration list staging on WebItemProviderPasteboard to support multiple registration lists, each
representing a single item provider.

(-[WebItemProviderPasteboard stageRegistrationList:]): Deleted.
(-[WebItemProviderPasteboard takeRegistrationList]): Deleted.
* platform/mac/PasteboardMac.mm:
(WebCore::Pasteboard::write):
* platform/mac/PasteboardWriter.mm:
(WebCore::createPasteboardWriter):
* platform/mac/PlatformPasteboardMac.mm:
(WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const):
(WebCore::PlatformPasteboard::write):

Support writing multiple PasteboardCustomData objects to the platform pasteboard on macOS, by creating and
setting NSPasteboardItems for each custom data. This means that instead of using legacy macOS pasteboard types,
we need to use the "modern" NSPasteboardTypes when writing each item. This is because NSPasteboardItem quietly
fails when attempting to set data for a legacy pasteboard type.

(WebCore::createPasteboardItem):

Source/WebKit:

See WebCore ChangeLog for more details.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<PasteboardCustomData::Entry>::encode):
(IPC::ArgumentCoder<PasteboardCustomData::Entry>::decode):

Add helpers to encode and decode PasteboardCustomData::Entry.

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

Add support for encoding and decoding PasteboardCustomData by encoding and decoding each of its items (see
above).

* UIProcess/Cocoa/WebViewImpl.mm:
(WebKit::WebViewImpl::requestDOMPasteAccess):
* UIProcess/WebPasteboardProxy.h:
* UIProcess/WebPasteboardProxy.messages.in:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView canPerformActionForWebView:withSender:]):
(allPasteboardItemOriginsMatchOrigin):
(-[WKContentView _didHandleAdditionalDragItemsRequest:]):

Tweak several methods to use the new methods on PasteboardCustomData instead of accessing the member variables
directly.

(-[WKContentView cleanUpDragSourceSessionState]):
(-[WKContentView _prepareToDragPromisedAttachment:]):
(-[WKContentView _itemsForBeginningOrAddingToSessionWithRegistrationLists:stagedDragSource:]):
(-[WKContentView dragInteraction:itemsForBeginningSession:]):
(-[WKContentView _itemsForBeginningOrAddingToSessionWithRegistrationList:stagedDragSource:]): Deleted.

Adjust these methods to handle multiple staged item providers (for now, it remains that iOS drag and drop
codepaths will still only write a single item to the pasteboard).

Source/WebKitLegacy/mac:

See WebCore ChangeLog for more details.

* WebCoreSupport/WebPlatformStrategies.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (251099 => 251100)


--- trunk/Source/WebCore/ChangeLog	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/ChangeLog	2019-10-14 21:52:26 UTC (rev 251100)
@@ -1,3 +1,158 @@
+2019-10-14  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Clipboard API] Support writing multiple PasteboardCustomData with SharedBuffers to the pasteboard
+        https://bugs.webkit.org/show_bug.cgi?id=202851
+
+        Reviewed by Darin Adler.
+
+        This patch refactors some logic around WebCore::PasteboardCustomData, in preparation for implementing the async
+        clipboard API. There are two main goals of this refactoring:
+
+        1. Enable writing multiple items (each backed by PasteboardCustomData) to the platform pasteboard.
+        2. Enable writing platform data in the form of SharedBuffers to the platform pasteboard.
+
+        See below for more details; no tests, as there is no change in behavior yet.
+
+        * Headers.cmake:
+        * Sources.txt:
+        * SourcesCocoa.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        Move PasteboardCustomData out of Pasteboard.h and into its own file.
+
+        * dom/DataTransfer.cpp:
+        (WebCore::DataTransfer::commitToPasteboard):
+        * editing/cocoa/EditorCocoa.mm:
+        (WebCore::Editor::getPasteboardTypesAndDataForAttachment):
+        * platform/Pasteboard.cpp:
+        (WebCore::PasteboardCustomData::createSharedBuffer const): Deleted.
+        (WebCore::PasteboardCustomData::fromSharedBuffer): Deleted.
+
+        Moved these method implementations to PasteboardCustomData.cpp.
+
+        * platform/Pasteboard.h:
+
+        Refactor PasteboardCustomData so that its member variables are now private, and encapsulated behind methods
+        Additionally, make it so that the only way to set data on PasteboardCustomData is to use the writeString,
+        writeData, and writeStringInCustomData methods, which ensure that the PasteboardCustomData is always in a
+        consistent state.
+
+        * platform/PasteboardCustomData.cpp: Added.
+        (WebCore::copyPlatformData):
+        (WebCore::PasteboardCustomData::Entry::Entry):
+        (WebCore::PasteboardCustomData::Entry::operator=):
+
+        Refactor the implementation of PasteboardCustomData, so that it contains a list of PasteboardCustomData entries
+        instead of individual Vectors and HashMaps.
+
+        (WebCore::PasteboardCustomData::PasteboardCustomData):
+        (WebCore::PasteboardCustomData::createSharedBuffer const):
+        (WebCore::PasteboardCustomData::fromSharedBuffer):
+        (WebCore::PasteboardCustomData::writeString):
+        (WebCore::PasteboardCustomData::writeData):
+        (WebCore::PasteboardCustomData::writeStringInCustomData):
+        (WebCore::PasteboardCustomData::addOrMoveEntryToEnd):
+
+        Move logic from StaticPasteboard into PasteboardCustomData, and refactor these methods to handle
+        Vector<PasteboardCustomData::Entry>.
+
+        (WebCore::PasteboardCustomData::clear):
+        (WebCore::PasteboardCustomData::operator=):
+        (WebCore::PasteboardCustomData::orderedTypes const):
+        (WebCore::PasteboardCustomData::hasData const):
+        (WebCore::PasteboardCustomData::hasSameOriginCustomData const):
+        (WebCore::PasteboardCustomData::sameOriginCustomStringData const):
+        (WebCore::PasteboardCustomData::readBuffer const):
+        (WebCore::PasteboardCustomData::readString const):
+        (WebCore::PasteboardCustomData::readStringInCustomData const):
+        (WebCore::PasteboardCustomData::forEachType const):
+        (WebCore::PasteboardCustomData::forEachPlatformString const):
+        (WebCore::PasteboardCustomData::forEachCustomString const):
+        (WebCore::PasteboardCustomData::forEachPlatformStringOrBuffer const):
+
+        Moved these method implementations from StaticPasteboard to PasteboardCustomData, and also introduced some new
+        methods to help iterate through types and data.
+
+        * platform/PasteboardCustomData.h: Added.
+        (WebCore::PasteboardCustomData::origin const):
+        (WebCore::PasteboardCustomData::setOrigin):
+        (WebCore::PasteboardCustomData::data const):
+        * platform/PasteboardStrategy.h:
+        * platform/PlatformPasteboard.h:
+        * platform/SharedBuffer.cpp:
+        (WebCore::SharedBuffer::decoder const):
+        * platform/SharedBuffer.h:
+        * platform/StaticPasteboard.cpp:
+        (WebCore::StaticPasteboard::hasData):
+        (WebCore::StaticPasteboard::typesSafeForBindings):
+        (WebCore::StaticPasteboard::typesForLegacyUnsafeBindings):
+        (WebCore::StaticPasteboard::readString):
+        (WebCore::StaticPasteboard::readStringInCustomData):
+        (WebCore::StaticPasteboard::writeString):
+        (WebCore::StaticPasteboard::writeData):
+        (WebCore::StaticPasteboard::writeStringInCustomData):
+        (WebCore::StaticPasteboard::clear):
+        (WebCore::StaticPasteboard::takeCustomData):
+        (WebCore::StaticPasteboard::StaticPasteboard): Deleted.
+
+        Refactor StaticPasteboard to now contain a PasteboardCustomData; additionally, adjust several methods in
+        StaticPasteboard to simply call into PasteboardCustomData to write, read, or clear data.
+
+        (WebCore::updateTypes): Deleted.
+        * platform/StaticPasteboard.h:
+        * platform/cocoa/PasteboardCocoa.mm:
+        (WebCore::Pasteboard::readStringInCustomData):
+        (WebCore::Pasteboard::readOrigin):
+        (WebCore::PasteboardCustomData::cocoaType): Deleted.
+
+        Moved the implementation of PasteboardCustomData::cocoaType from PasteboardCocoa.mm to
+        PasteboardCustomDataCocoa.mm.
+
+        * platform/cocoa/PasteboardCustomDataCocoa.mm: Added.
+        (WebCore::PasteboardCustomData::cocoaType):
+        * platform/ios/AbstractPasteboard.h:
+        * platform/ios/PlatformPasteboardIOS.mm:
+        (WebCore::PlatformPasteboard::changeCount const):
+        (WebCore::registerItemsToPasteboard):
+        (WebCore::registerItemToPasteboard):
+        (WebCore::PlatformPasteboard::write):
+
+        Support writing multiple PasteboardCustomData objects to the platform pasteboard on iOS, by generating
+        NSItemProviders for each one. This refactors the existing `registerItemToPasteboard` helper to handle multiple
+        registration lists, renames it to `registerItemsToPasteboard` (plural), and then reimplements
+        `registerItemToPasteboard` in terms of `registerItemsToPasteboard`.
+
+        (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const):
+        (WebCore::createItemProviderRegistrationList):
+
+        Adjust these to use getters on PasteboardCustomData instead of accessing the member variables directly.
+
+        * platform/ios/WebItemProviderPasteboard.mm:
+        (-[WebItemProviderPasteboard init]):
+        (-[WebItemProviderPasteboard stageRegistrationLists:]):
+        (-[WebItemProviderPasteboard clearRegistrationLists]):
+        (-[WebItemProviderPasteboard takeRegistrationLists]):
+
+        Refactor registration list staging on WebItemProviderPasteboard to support multiple registration lists, each
+        representing a single item provider.
+
+        (-[WebItemProviderPasteboard stageRegistrationList:]): Deleted.
+        (-[WebItemProviderPasteboard takeRegistrationList]): Deleted.
+        * platform/mac/PasteboardMac.mm:
+        (WebCore::Pasteboard::write):
+        * platform/mac/PasteboardWriter.mm:
+        (WebCore::createPasteboardWriter):
+        * platform/mac/PlatformPasteboardMac.mm:
+        (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const):
+        (WebCore::PlatformPasteboard::write):
+
+        Support writing multiple PasteboardCustomData objects to the platform pasteboard on macOS, by creating and
+        setting NSPasteboardItems for each custom data. This means that instead of using legacy macOS pasteboard types,
+        we need to use the "modern" NSPasteboardTypes when writing each item. This is because NSPasteboardItem quietly
+        fails when attempting to set data for a legacy pasteboard type.
+
+        (WebCore::createPasteboardItem):
+
 2019-10-14  Truitt Savell  <tsav...@apple.com>
 
         Unreviewed, rolling out r251081.

Modified: trunk/Source/WebCore/Headers.cmake (251099 => 251100)


--- trunk/Source/WebCore/Headers.cmake	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/Headers.cmake	2019-10-14 21:52:26 UTC (rev 251100)
@@ -929,6 +929,7 @@
     platform/PODIntervalTree.h
     platform/PODRedBlackTree.h
     platform/Pasteboard.h
+    platform/PasteboardCustomData.h
     platform/PasteboardItemInfo.h
     platform/PasteboardStrategy.h
     platform/PasteboardWriterData.h

Modified: trunk/Source/WebCore/Sources.txt (251099 => 251100)


--- trunk/Source/WebCore/Sources.txt	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/Sources.txt	2019-10-14 21:52:26 UTC (rev 251100)
@@ -1725,6 +1725,7 @@
 platform/MainThreadSharedTimer.cpp
 platform/NotImplemented.cpp
 platform/Pasteboard.cpp
+platform/PasteboardCustomData.cpp
 platform/PasteboardWriterData.cpp
 platform/PlatformKeyboardEvent.cpp
 platform/PlatformSpeechSynthesisUtterance.cpp

Modified: trunk/Source/WebCore/SourcesCocoa.txt (251099 => 251100)


--- trunk/Source/WebCore/SourcesCocoa.txt	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/SourcesCocoa.txt	2019-10-14 21:52:26 UTC (rev 251100)
@@ -198,6 +198,7 @@
 platform/cocoa/NetworkExtensionContentFilter.mm
 platform/cocoa/ParentalControlsContentFilter.mm
 platform/cocoa/PasteboardCocoa.mm
+platform/cocoa/PasteboardCustomDataCocoa.mm
 platform/cocoa/PlatformPasteboardCocoa.mm
 platform/cocoa/PlaybackSessionModelMediaElement.mm
 platform/cocoa/RuntimeApplicationChecksCocoa.mm

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (251099 => 251100)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-10-14 21:52:26 UTC (rev 251100)
@@ -4904,6 +4904,7 @@
 		F4D43D662188038B00ECECAC /* SerializedAttachmentData.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D43D64218802E600ECECAC /* SerializedAttachmentData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F4E57EDC213F3F5F004EA98E /* FontAttributeChanges.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E57EDA213F3F5F004EA98E /* FontAttributeChanges.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F4E57EE1213F434A004EA98E /* WebCoreNSFontManagerExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E57EDF213F434A004EA98E /* WebCoreNSFontManagerExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		F4FB34FC2350C85D00F0094A /* PasteboardCustomData.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FB34FA2350C85D00F0094A /* PasteboardCustomData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F50664F8157F52DC00AC226F /* FormController.h in Headers */ = {isa = PBXBuildFile; fileRef = F50664F6157F52DC00AC226F /* FormController.h */; };
 		F513A3EA15FF4841001526DB /* ValidationMessageClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F513A3E915FF4841001526DB /* ValidationMessageClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		F544F78915CFB2A800AF33A8 /* PlatformLocale.h in Headers */ = {isa = PBXBuildFile; fileRef = F544F78715CFB2A800AF33A8 /* PlatformLocale.h */; };
@@ -15237,6 +15238,9 @@
 		F4E57EDA213F3F5F004EA98E /* FontAttributeChanges.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FontAttributeChanges.h; sourceTree = "<group>"; };
 		F4E57EDF213F434A004EA98E /* WebCoreNSFontManagerExtras.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCoreNSFontManagerExtras.h; sourceTree = "<group>"; };
 		F4E57EE0213F434A004EA98E /* WebCoreNSFontManagerExtras.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreNSFontManagerExtras.mm; sourceTree = "<group>"; };
+		F4FB34FA2350C85D00F0094A /* PasteboardCustomData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PasteboardCustomData.h; sourceTree = "<group>"; };
+		F4FB34FB2350C85D00F0094A /* PasteboardCustomData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PasteboardCustomData.cpp; sourceTree = "<group>"; };
+		F4FB35002350C96200F0094A /* PasteboardCustomDataCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteboardCustomDataCocoa.mm; sourceTree = "<group>"; };
 		F50664F5157F52DC00AC226F /* FormController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormController.cpp; sourceTree = "<group>"; };
 		F50664F6157F52DC00AC226F /* FormController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormController.h; sourceTree = "<group>"; };
 		F513A3E915FF4841001526DB /* ValidationMessageClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidationMessageClient.h; sourceTree = "<group>"; };
@@ -22723,6 +22727,7 @@
 				A18890AD1AA13F250026C301 /* ParentalControlsContentFilter.h */,
 				A18890AC1AA13F250026C301 /* ParentalControlsContentFilter.mm */,
 				9BED2CAF1F7CC06200666018 /* PasteboardCocoa.mm */,
+				F4FB35002350C96200F0094A /* PasteboardCustomDataCocoa.mm */,
 				F4628A9E234D3BBF00BC884C /* PlatformPasteboardCocoa.mm */,
 				52B0D4BD1C57FD1E0077CE53 /* PlatformView.h */,
 				CDA29A081CBD99F400901CCF /* PlaybackSessionInterface.h */,
@@ -25588,6 +25593,8 @@
 				4184F5151EAF059800F18BF0 /* OrientationNotifier.h */,
 				2EE02A1E1F7324280006AF72 /* Pasteboard.cpp */,
 				4B2708C50AF19EE40065127F /* Pasteboard.h */,
+				F4FB34FB2350C85D00F0094A /* PasteboardCustomData.cpp */,
+				F4FB34FA2350C85D00F0094A /* PasteboardCustomData.h */,
 				F49786871FF45FA500E060AB /* PasteboardItemInfo.h */,
 				C5F765B414E1D414006C899B /* PasteboardStrategy.h */,
 				1AF5E4D21E56735A004A1F01 /* PasteboardWriterData.cpp */,
@@ -31183,6 +31190,7 @@
 				536D5A23193E8E0C00CE4CAB /* ParsingUtilities.h in Headers */,
 				F55B3DCA1251F12D003EF269 /* PasswordInputType.h in Headers */,
 				4B2708C70AF19EE40065127F /* Pasteboard.h in Headers */,
+				F4FB34FC2350C85D00F0094A /* PasteboardCustomData.h in Headers */,
 				F49786881FF45FA500E060AB /* PasteboardItemInfo.h in Headers */,
 				C598905714E9C28000E8D18B /* PasteboardStrategy.h in Headers */,
 				1AF5E4E31E5779B1004A1F01 /* PasteboardWriter.h in Headers */,

Modified: trunk/Source/WebCore/dom/DataTransfer.cpp (251099 => 251100)


--- trunk/Source/WebCore/dom/DataTransfer.cpp	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/dom/DataTransfer.cpp	2019-10-14 21:52:26 UTC (rev 251100)
@@ -426,15 +426,18 @@
     ASSERT(is<StaticPasteboard>(*m_pasteboard) && !is<StaticPasteboard>(nativePasteboard));
     PasteboardCustomData customData = downcast<StaticPasteboard>(*m_pasteboard).takeCustomData();
     if (RuntimeEnabledFeatures::sharedFeatures().customPasteboardDataEnabled()) {
-        customData.origin = m_originIdentifier;
+        customData.setOrigin(m_originIdentifier);
         nativePasteboard.writeCustomData(customData);
         return;
     }
 
-    for (auto& entry : customData.platformData)
-        nativePasteboard.writeString(entry.key, entry.value);
-    for (auto& entry : customData.sameOriginCustomData)
-        nativePasteboard.writeString(entry.key, entry.value);
+    customData.forEachPlatformString([&] (auto& type, auto& string) {
+        nativePasteboard.writeString(type, string);
+    });
+
+    customData.forEachCustomString([&] (auto& type, auto& string) {
+        nativePasteboard.writeString(type, string);
+    });
 }
 
 #if !ENABLE(DRAG_SUPPORT)

Modified: trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm (251099 => 251100)


--- trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -94,7 +94,7 @@
     client()->getClientPasteboardDataForRange(elementRange.ptr(), outTypes, outData);
 
     outTypes.append(PasteboardCustomData::cocoaType());
-    outData.append(PasteboardCustomData { document.originIdentifierForPasteboard(), { }, { }, { } }.createSharedBuffer());
+    outData.append(PasteboardCustomData { document.originIdentifierForPasteboard(), { } }.createSharedBuffer());
 
     if (auto archive = LegacyWebArchive::create(elementRange.ptr())) {
         if (auto webArchiveData = archive->rawDataRepresentation()) {

Modified: trunk/Source/WebCore/platform/Pasteboard.cpp (251099 => 251100)


--- trunk/Source/WebCore/platform/Pasteboard.cpp	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/Pasteboard.cpp	2019-10-14 21:52:26 UTC (rev 251100)
@@ -30,8 +30,6 @@
 #include "PlatformStrategies.h"
 #include "Settings.h"
 #include "SharedBuffer.h"
-#include <wtf/URLParser.h>
-#include <wtf/persistence/PersistentCoders.h>
 #include <wtf/text/StringHash.h>
 
 namespace WebCore {
@@ -51,40 +49,6 @@
     return url.protocolIsInHTTPFamily() || url.protocolIsBlob() || url.protocolIsData();
 }
 
-Ref<SharedBuffer> PasteboardCustomData::createSharedBuffer() const
-{
-    const static unsigned currentCustomDataSerializationVersion = 1;
-
-    WTF::Persistence::Encoder encoder;
-    encoder << currentCustomDataSerializationVersion;
-    encoder << origin;
-    encoder << sameOriginCustomData;
-    encoder << orderedTypes;
-    return SharedBuffer::create(encoder.buffer(), encoder.bufferSize());
-}
-
-PasteboardCustomData PasteboardCustomData::fromSharedBuffer(const SharedBuffer& buffer)
-{
-    const static unsigned maxSupportedDataSerializationVersionNumber = 1;
-
-    PasteboardCustomData result;
-    WTF::Persistence::Decoder decoder { reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size() };
-    unsigned version;
-    if (!decoder.decode(version) || version > maxSupportedDataSerializationVersionNumber)
-        return { };
-
-    if (!decoder.decode(result.origin))
-        return { };
-
-    if (!decoder.decode(result.sameOriginCustomData))
-        return { };
-
-    if (!decoder.decode(result.orderedTypes))
-        return { };
-
-    return result;
-}
-
 #if !PLATFORM(COCOA)
 
 Vector<String> Pasteboard::readAllStrings(const String& type)

Modified: trunk/Source/WebCore/platform/Pasteboard.h (251099 => 251100)


--- trunk/Source/WebCore/platform/Pasteboard.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/Pasteboard.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "DragImage.h"
+#include "PasteboardCustomData.h"
 #include "PasteboardItemInfo.h"
 #include <wtf/HashMap.h>
 #include <wtf/ListHashSet.h>
@@ -161,21 +162,6 @@
     virtual void readBuffer(const String& filename, const String& type, Ref<SharedBuffer>&&) = 0;
 };
 
-// FIXME: We need to ensure that the contents of sameOriginCustomData are not accessible across different origins.
-struct PasteboardCustomData {
-    String origin;
-    Vector<String> orderedTypes;
-    HashMap<String, String> platformData;
-    HashMap<String, String> sameOriginCustomData;
-
-    WEBCORE_EXPORT Ref<SharedBuffer> createSharedBuffer() const;
-    WEBCORE_EXPORT static PasteboardCustomData fromSharedBuffer(const SharedBuffer&);
-
-#if PLATFORM(COCOA)
-    WEBCORE_EXPORT static const char* cocoaType();
-#endif
-};
-
 class Pasteboard {
     WTF_MAKE_NONCOPYABLE(Pasteboard); WTF_MAKE_FAST_ALLOCATED;
 public:

Added: trunk/Source/WebCore/platform/PasteboardCustomData.cpp (0 => 251100)


--- trunk/Source/WebCore/platform/PasteboardCustomData.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/PasteboardCustomData.cpp	2019-10-14 21:52:26 UTC (rev 251100)
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PasteboardCustomData.h"
+
+#include "SharedBuffer.h"
+#include <wtf/URLParser.h>
+#include <wtf/persistence/PersistentCoders.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+static Variant<String, Ref<SharedBuffer>> copyPlatformData(const Variant<String, Ref<SharedBuffer>>& other)
+{
+    if (WTF::holds_alternative<String>(other))
+        return { WTF::get<String>(other) };
+
+    if (WTF::holds_alternative<Ref<SharedBuffer>>(other))
+        return { WTF::get<Ref<SharedBuffer>>(other).copyRef() };
+
+    return { };
+}
+
+PasteboardCustomData::Entry::Entry(const Entry& entry)
+    : type(entry.type)
+    , customData(entry.customData)
+    , platformData(copyPlatformData(entry.platformData))
+{
+}
+
+PasteboardCustomData::Entry::Entry(const String& dataType)
+    : type(dataType)
+{
+}
+
+PasteboardCustomData::Entry::Entry() = default;
+PasteboardCustomData::Entry::Entry(Entry&&) = default;
+
+PasteboardCustomData::Entry& PasteboardCustomData::Entry::operator=(const Entry& entry)
+{
+    type = entry.type;
+    customData = entry.customData;
+    platformData = copyPlatformData(entry.platformData);
+    return *this;
+}
+
+PasteboardCustomData::Entry& PasteboardCustomData::Entry::operator=(Entry&&) = default;
+
+PasteboardCustomData::PasteboardCustomData() = default;
+PasteboardCustomData::PasteboardCustomData(const PasteboardCustomData&) = default;
+PasteboardCustomData::PasteboardCustomData(PasteboardCustomData&&) = default;
+PasteboardCustomData::~PasteboardCustomData() = default;
+
+PasteboardCustomData::PasteboardCustomData(String&& origin, Vector<Entry>&& data)
+    : m_origin(WTFMove(origin))
+    , m_data(WTFMove(data))
+{
+}
+
+Ref<SharedBuffer> PasteboardCustomData::createSharedBuffer() const
+{
+    constexpr unsigned currentCustomDataSerializationVersion = 1;
+
+    WTF::Persistence::Encoder encoder;
+    encoder << currentCustomDataSerializationVersion;
+    encoder << m_origin;
+    encoder << sameOriginCustomStringData();
+    encoder << orderedTypes();
+    return SharedBuffer::create(encoder.buffer(), encoder.bufferSize());
+}
+
+PasteboardCustomData PasteboardCustomData::fromSharedBuffer(const SharedBuffer& buffer)
+{
+    constexpr unsigned maxSupportedDataSerializationVersionNumber = 1;
+
+    PasteboardCustomData result;
+    auto decoder = buffer.decoder();
+    unsigned version;
+    if (!decoder.decode(version) || version > maxSupportedDataSerializationVersionNumber)
+        return { };
+
+    if (!decoder.decode(result.m_origin))
+        return { };
+
+    HashMap<String, String> sameOriginCustomStringData;
+    if (!decoder.decode(sameOriginCustomStringData))
+        return { };
+
+    Vector<String> orderedTypes;
+    if (!decoder.decode(orderedTypes))
+        return { };
+
+    for (auto& type : orderedTypes)
+        result.writeStringInCustomData(type, sameOriginCustomStringData.get(type));
+
+    return result;
+}
+
+void PasteboardCustomData::writeString(const String& type, const String& value)
+{
+    addOrMoveEntryToEnd(type).platformData = { value };
+}
+
+void PasteboardCustomData::writeData(const String& type, Ref<SharedBuffer>&& data)
+{
+    addOrMoveEntryToEnd(type).platformData = { WTFMove(data) };
+}
+
+void PasteboardCustomData::writeStringInCustomData(const String& type, const String& value)
+{
+    addOrMoveEntryToEnd(type).customData = value;
+}
+
+PasteboardCustomData::Entry& PasteboardCustomData::addOrMoveEntryToEnd(const String& type)
+{
+    auto index = m_data.findMatching([&] (auto& entry) {
+        return entry.type == type;
+    });
+    auto entry = index == notFound ? Entry(type) : m_data[index];
+    if (index != notFound)
+        m_data.remove(index);
+    m_data.append(WTFMove(entry));
+    return m_data.last();
+}
+
+void PasteboardCustomData::clear()
+{
+    m_data.clear();
+}
+
+void PasteboardCustomData::clear(const String& type)
+{
+    m_data.removeFirstMatching([&] (auto& entry) {
+        return entry.type == type;
+    });
+}
+
+PasteboardCustomData& PasteboardCustomData::operator=(const PasteboardCustomData& other)
+{
+    m_origin = other.origin();
+    m_data = other.m_data;
+    return *this;
+}
+
+Vector<String> PasteboardCustomData::orderedTypes() const
+{
+    return m_data.map([&] (auto& entry) {
+        return entry.type;
+    });
+}
+
+bool PasteboardCustomData::hasData() const
+{
+    return !m_data.isEmpty();
+}
+
+bool PasteboardCustomData::hasSameOriginCustomData() const
+{
+    return notFound != m_data.findMatching([&] (auto& entry) {
+        return !entry.customData.isNull();
+    });
+}
+
+HashMap<String, String> PasteboardCustomData::sameOriginCustomStringData() const
+{
+    HashMap<String, String> customData;
+    for (auto& entry : m_data)
+        customData.set(entry.type, entry.customData);
+    return customData;
+}
+
+RefPtr<SharedBuffer> PasteboardCustomData::readBuffer(const String& type) const
+{
+    for (auto& entry : m_data) {
+        if (entry.type != type)
+            continue;
+
+        if (WTF::holds_alternative<Ref<SharedBuffer>>(entry.platformData))
+            return makeRefPtr(WTF::get<Ref<SharedBuffer>>(entry.platformData).get());
+
+        return nullptr;
+    }
+    return nullptr;
+}
+
+String PasteboardCustomData::readString(const String& type) const
+{
+    for (auto& entry : m_data) {
+        if (entry.type != type)
+            continue;
+
+        if (WTF::holds_alternative<String>(entry.platformData))
+            return WTF::get<String>(entry.platformData);
+
+        return { };
+    }
+    return { };
+}
+
+String PasteboardCustomData::readStringInCustomData(const String& type) const
+{
+    for (auto& entry : m_data) {
+        if (entry.type == type)
+            return entry.customData;
+    }
+    return { };
+}
+
+void PasteboardCustomData::forEachType(Function<void(const String&)>&& function) const
+{
+    for (auto& entry : m_data)
+        function(entry.type);
+}
+
+void PasteboardCustomData::forEachPlatformString(Function<void(const String& type, const String& data)>&& function) const
+{
+    for (auto& entry : m_data) {
+        if (!WTF::holds_alternative<String>(entry.platformData))
+            continue;
+
+        auto string = WTF::get<String>(entry.platformData);
+        if (!string.isNull())
+            function(entry.type, string);
+    }
+}
+
+void PasteboardCustomData::forEachCustomString(Function<void(const String& type, const String& data)>&& function) const
+{
+    for (auto& entry : m_data) {
+        if (!entry.customData.isNull())
+            function(entry.type, entry.customData);
+    }
+}
+
+void PasteboardCustomData::forEachPlatformStringOrBuffer(Function<void(const String& type, const Variant<String, Ref<SharedBuffer>>& data)>&& function) const
+{
+    for (auto& entry : m_data) {
+        auto& data = ""
+        if ((WTF::holds_alternative<String>(data) && !WTF::get<String>(data).isNull()) || WTF::holds_alternative<Ref<SharedBuffer>>(data))
+            function(entry.type, data);
+    }
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/platform/PasteboardCustomData.h (0 => 251100)


--- trunk/Source/WebCore/platform/PasteboardCustomData.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/PasteboardCustomData.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Function.h>
+#include <wtf/HashMap.h>
+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class SharedBuffer;
+
+class PasteboardCustomData {
+public:
+    struct Entry {
+        WEBCORE_EXPORT Entry();
+        WEBCORE_EXPORT Entry(const Entry&);
+        WEBCORE_EXPORT Entry(Entry&&);
+        WEBCORE_EXPORT Entry& operator=(const Entry& otherData);
+        WEBCORE_EXPORT Entry& operator=(Entry&& otherData);
+        Entry(const String& type);
+
+        String type;
+        String customData;
+        Variant<String, Ref<SharedBuffer>> platformData;
+    };
+
+    WEBCORE_EXPORT PasteboardCustomData();
+    WEBCORE_EXPORT PasteboardCustomData(String&& origin, Vector<Entry>&&);
+    WEBCORE_EXPORT PasteboardCustomData(PasteboardCustomData&&);
+    WEBCORE_EXPORT PasteboardCustomData(const PasteboardCustomData&);
+    WEBCORE_EXPORT ~PasteboardCustomData();
+
+    const String& origin() const { return m_origin; }
+    void setOrigin(const String& origin) { m_origin = origin; }
+
+    WEBCORE_EXPORT Ref<SharedBuffer> createSharedBuffer() const;
+    WEBCORE_EXPORT static PasteboardCustomData fromSharedBuffer(const SharedBuffer&);
+
+    String readString(const String& type) const;
+    RefPtr<SharedBuffer> readBuffer(const String& type) const;
+    String readStringInCustomData(const String& type) const;
+
+    void writeString(const String& type, const String& value);
+    void writeData(const String& type, Ref<SharedBuffer>&& data);
+    void writeStringInCustomData(const String& type, const String& value);
+
+    void clear();
+    void clear(const String& type);
+
+#if PLATFORM(COCOA)
+    WEBCORE_EXPORT static const char* cocoaType();
+#endif
+
+    void forEachType(Function<void(const String&)>&&) const;
+    void forEachPlatformString(Function<void(const String& type, const String& data)>&&) const;
+    void forEachPlatformStringOrBuffer(Function<void(const String& type, const Variant<String, Ref<SharedBuffer>>& data)>&&) const;
+    void forEachCustomString(Function<void(const String& type, const String& data)>&&) const;
+
+    bool hasData() const;
+    bool hasSameOriginCustomData() const;
+
+    Vector<String> orderedTypes() const;
+    WEBCORE_EXPORT PasteboardCustomData& operator=(const PasteboardCustomData& otherData);
+
+    const Vector<Entry>& data() const { return m_data; }
+
+private:
+    HashMap<String, String> sameOriginCustomStringData() const;
+    Entry& addOrMoveEntryToEnd(const String&);
+
+    String m_origin;
+    Vector<Entry> m_data;
+};
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/platform/PasteboardStrategy.h (251099 => 251100)


--- trunk/Source/WebCore/platform/PasteboardStrategy.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/PasteboardStrategy.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -31,6 +31,7 @@
 namespace WebCore {
 
 class Color;
+class PasteboardCustomData;
 class SelectionData;
 class SharedBuffer;
 struct PasteboardImage;
@@ -37,7 +38,6 @@
 struct PasteboardItemInfo;
 struct PasteboardURL;
 struct PasteboardWebContent;
-struct PasteboardCustomData;
 
 class PasteboardStrategy {
 public:

Modified: trunk/Source/WebCore/platform/PlatformPasteboard.h (251099 => 251100)


--- trunk/Source/WebCore/platform/PlatformPasteboard.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/PlatformPasteboard.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -47,9 +47,9 @@
 namespace WebCore {
 
 class Color;
+class PasteboardCustomData;
 class SelectionData;
 class SharedBuffer;
-struct PasteboardCustomData;
 struct PasteboardImage;
 struct PasteboardItemInfo;
 struct PasteboardURL;
@@ -96,7 +96,7 @@
     WEBCORE_EXPORT URL readURL(size_t index, String& title) const;
     WEBCORE_EXPORT int count() const;
     WEBCORE_EXPORT int numberOfFiles() const;
-
+    WEBCORE_EXPORT void write(const Vector<PasteboardCustomData>&);
     WEBCORE_EXPORT long write(const PasteboardCustomData&);
     WEBCORE_EXPORT Vector<String> typesSafeForDOMToReadAndWrite(const String& origin) const;
 

Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (251099 => 251100)


--- trunk/Source/WebCore/platform/SharedBuffer.cpp	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp	2019-10-14 21:52:26 UTC (rev 251100)
@@ -29,6 +29,7 @@
 #include "SharedBuffer.h"
 
 #include <algorithm>
+#include <wtf/persistence/PersistentCoders.h>
 #include <wtf/unicode/UTF8Conversion.h>
 
 namespace WebCore {
@@ -239,6 +240,11 @@
 }
 #endif
 
+WTF::Persistence::Decoder SharedBuffer::decoder() const
+{
+    return { reinterpret_cast<const uint8_t*>(data()), size() };
+}
+
 bool SharedBuffer::operator==(const SharedBuffer& other) const
 {
     if (this == &other)

Modified: trunk/Source/WebCore/platform/SharedBuffer.h (251099 => 251100)


--- trunk/Source/WebCore/platform/SharedBuffer.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/SharedBuffer.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -57,6 +57,12 @@
 OBJC_CLASS NSData;
 #endif
 
+namespace WTF {
+namespace Persistence {
+class Decoder;
+}
+}
+
 namespace WebCore {
 
 class SharedBufferDataView;
@@ -190,6 +196,8 @@
 
     void hintMemoryNotNeededSoon() const;
 
+    WTF::Persistence::Decoder decoder() const;
+
     bool operator==(const SharedBuffer&) const;
     bool operator!=(const SharedBuffer& other) const { return !operator==(other); }
 

Modified: trunk/Source/WebCore/platform/StaticPasteboard.cpp (251099 => 251100)


--- trunk/Source/WebCore/platform/StaticPasteboard.cpp	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/StaticPasteboard.cpp	2019-10-14 21:52:26 UTC (rev 251100)
@@ -26,65 +26,66 @@
 #include "config.h"
 #include "StaticPasteboard.h"
 
+#include "SharedBuffer.h"
+
 namespace WebCore {
 
-StaticPasteboard::StaticPasteboard()
+StaticPasteboard::StaticPasteboard() = default;
+StaticPasteboard::~StaticPasteboard() = default;
+
+bool StaticPasteboard::hasData()
 {
+    return m_customData.hasData();
 }
 
-bool StaticPasteboard::hasData()
+Vector<String> StaticPasteboard::typesSafeForBindings(const String&)
 {
-    return !m_platformData.isEmpty() || !m_customData.isEmpty();
+    return m_customData.orderedTypes();
 }
 
+Vector<String> StaticPasteboard::typesForLegacyUnsafeBindings()
+{
+    return m_customData.orderedTypes();
+}
+
 String StaticPasteboard::readString(const String& type)
 {
-    return m_platformData.get(type);
+    return m_customData.readString(type);
 }
 
 String StaticPasteboard::readStringInCustomData(const String& type)
 {
-    return m_customData.get(type);
+    return m_customData.readStringInCustomData(type);
 }
 
-static void updateTypes(Vector<String>& types, String type, bool moveToEnd)
+void StaticPasteboard::writeString(const String& type, const String& value)
 {
-    if (moveToEnd)
-        types.removeFirst(type);
-    ASSERT(!types.contains(type));
-    types.append(type);
+    m_customData.writeString(type, value);
 }
 
-void StaticPasteboard::writeString(const String& type, const String& value)
+void StaticPasteboard::writeData(const String& type, Ref<SharedBuffer>&& data)
 {
-    bool typeWasAlreadyPresent = !m_platformData.set(type, value).isNewEntry || m_customData.contains(type);
-    updateTypes(m_types, type, typeWasAlreadyPresent);
+    m_customData.writeData(type, WTFMove(data));
 }
 
 void StaticPasteboard::writeStringInCustomData(const String& type, const String& value)
 {
-    bool typeWasAlreadyPresent = !m_customData.set(type, value).isNewEntry || m_platformData.contains(type);
-    updateTypes(m_types, type, typeWasAlreadyPresent);
+    m_customData.writeStringInCustomData(type, value);
 }
 
 void StaticPasteboard::clear()
 {
     m_customData.clear();
-    m_platformData.clear();
-    m_types.clear();
 }
 
 void StaticPasteboard::clear(const String& type)
 {
-    if (!m_platformData.remove(type) && !m_customData.remove(type))
-        return;
-    m_types.removeFirst(type);
-    ASSERT(!m_types.contains(type));
+    m_customData.clear(type);
 }
 
 PasteboardCustomData StaticPasteboard::takeCustomData()
 {
-    return { { }, WTFMove(m_types), WTFMove(m_platformData), WTFMove(m_customData) };
+    return std::exchange(m_customData, { });
 }
 
 }

Modified: trunk/Source/WebCore/platform/StaticPasteboard.h (251099 => 251100)


--- trunk/Source/WebCore/platform/StaticPasteboard.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/StaticPasteboard.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -32,9 +32,12 @@
 
 namespace WebCore {
 
+class SharedBuffer;
+
 class StaticPasteboard final : public Pasteboard {
 public:
     StaticPasteboard();
+    ~StaticPasteboard();
 
     PasteboardCustomData takeCustomData();
 
@@ -41,13 +44,14 @@
     bool isStatic() const final { return true; }
 
     bool hasData() final;
-    Vector<String> typesSafeForBindings(const String&) final { return m_types; }
-    Vector<String> typesForLegacyUnsafeBindings() final { return m_types; }
+    Vector<String> typesSafeForBindings(const String&) final;
+    Vector<String> typesForLegacyUnsafeBindings() final;
     String readOrigin() final { return { }; }
     String readString(const String& type) final;
     String readStringInCustomData(const String& type) final;
 
     void writeString(const String& type, const String& data) final;
+    void writeData(const String& type, Ref<SharedBuffer>&& data);
     void writeStringInCustomData(const String& type, const String& data);
     void clear() final;
     void clear(const String& type) final;
@@ -72,9 +76,7 @@
 #endif
 
 private:
-    Vector<String> m_types;
-    HashMap<String, String> m_platformData;
-    HashMap<String, String> m_customData;
+    PasteboardCustomData m_customData;
 };
 
 }

Modified: trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm (251099 => 251100)


--- trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -51,11 +51,6 @@
 PasteboardWebContent::PasteboardWebContent() = default;
 PasteboardWebContent::~PasteboardWebContent() = default;
 
-const char* PasteboardCustomData::cocoaType()
-{
-    return "com.apple.WebKit.custom-pasteboard-data";
-}
-
 enum class ImageType {
     Invalid = 0,
     TIFF,
@@ -260,12 +255,12 @@
 
 String Pasteboard::readStringInCustomData(const String& type)
 {
-    return readCustomData().sameOriginCustomData.get(type);
+    return readCustomData().readStringInCustomData(type);
 }
 
 String Pasteboard::readOrigin()
 {
-    return readCustomData().origin;
+    return readCustomData().origin();
 }
 
 const PasteboardCustomData& Pasteboard::readCustomData()

Added: trunk/Source/WebCore/platform/cocoa/PasteboardCustomDataCocoa.mm (0 => 251100)


--- trunk/Source/WebCore/platform/cocoa/PasteboardCustomDataCocoa.mm	                        (rev 0)
+++ trunk/Source/WebCore/platform/cocoa/PasteboardCustomDataCocoa.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "PasteboardCustomData.h"
+
+#if PLATFORM(COCOA)
+
+namespace WebCore {
+
+const char* PasteboardCustomData::cocoaType()
+{
+    return "com.apple.WebKit.custom-pasteboard-data";
+}
+
+} // namespace WebCore
+
+#endif // PLATFORM(COCOA)

Modified: trunk/Source/WebCore/platform/ios/AbstractPasteboard.h (251099 => 251100)


--- trunk/Source/WebCore/platform/ios/AbstractPasteboard.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/ios/AbstractPasteboard.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -29,18 +29,13 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
 @class WebItemProviderRegistrationInfoList;
-#endif
 
 @protocol AbstractPasteboard <NSObject>
 @required
 
 @property (readonly, nonatomic) NSInteger numberOfItems;
-
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
 @property (nonatomic, copy, nullable) NSArray<__kindof NSItemProvider *> *itemProviders;
-#endif
 
 - (NSArray<NSString *> *)pasteboardTypes;
 - (NSData *)dataForPasteboardType:(NSString *)pasteboardType;
@@ -49,10 +44,9 @@
 - (NSInteger)changeCount;
 
 @optional
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
-- (void)stageRegistrationList:(nullable WebItemProviderRegistrationInfoList *)info;
-- (nullable WebItemProviderRegistrationInfoList *)takeRegistrationList;
-#endif
+- (void)stageRegistrationLists:(NSArray<WebItemProviderRegistrationInfoList *> *)infoLists;
+- (void)clearRegistrationLists;
+- (NSArray<WebItemProviderRegistrationInfoList *> *)takeRegistrationLists;
 - (void)setItems:(NSArray<NSDictionary *> *)items;
 @property (readonly, nonatomic) NSInteger numberOfFiles;
 @property (readonly, nonatomic) NSArray<NSURL *> *allDroppedFileURLs;

Modified: trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm (251099 => 251100)


--- trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -266,7 +266,7 @@
 
 long PlatformPasteboard::changeCount() const
 {
-    return [(id<AbstractPasteboard>)m_pasteboard.get() changeCount];
+    return [m_pasteboard changeCount];
 }
 
 String PlatformPasteboard::uniqueName()
@@ -292,31 +292,43 @@
 
 static NSString *webIOSPastePboardType = @"iOS rich content paste pasteboard type";
 
-static void registerItemToPasteboard(WebItemProviderRegistrationInfoList *representationsToRegister, id <AbstractPasteboard> pasteboard)
+static void registerItemsToPasteboard(NSArray<WebItemProviderRegistrationInfoList *> *itemLists, id <AbstractPasteboard> pasteboard)
 {
 #if PLATFORM(MACCATALYST)
     // In macCatalyst, -[UIPasteboard setItemProviders:] is not yet supported, so we fall back to setting an item dictionary when
     // populating the pasteboard upon copy.
     if ([pasteboard isKindOfClass:PAL::getUIPasteboardClass()]) {
-        auto itemDictionary = adoptNS([[NSMutableDictionary alloc] init]);
-        [representationsToRegister enumerateItems:[itemDictionary] (id <WebItemProviderRegistrar> item, NSUInteger) {
-            if ([item respondsToSelector:@selector(typeIdentifierForClient)] && [item respondsToSelector:@selector(dataForClient)])
-                [itemDictionary setObject:item.dataForClient forKey:item.typeIdentifierForClient];
-        }];
-        [pasteboard setItems:@[ itemDictionary.get() ]];
+        auto itemDictionaries = adoptNS([[NSMutableArray alloc] initWithCapacity:itemLists.count]);
+        for (WebItemProviderRegistrationInfoList *representationsToRegister in itemLists) {
+            auto itemDictionary = adoptNS([[NSMutableDictionary alloc] initWithCapacity:representationsToRegister.numberOfItems]);
+            [representationsToRegister enumerateItems:[itemDictionary] (id <WebItemProviderRegistrar> item, NSUInteger) {
+                if ([item respondsToSelector:@selector(typeIdentifierForClient)] && [item respondsToSelector:@selector(dataForClient)])
+                    [itemDictionary setObject:item.dataForClient forKey:item.typeIdentifierForClient];
+            }];
+            [itemDictionaries addObject:itemDictionary.get()];
+        }
+        [pasteboard setItems:itemDictionaries.get()];
         return;
     }
 #endif // PLATFORM(MACCATALYST)
 
-    if (NSItemProvider *itemProvider = representationsToRegister.itemProvider)
-        [pasteboard setItemProviders:@[ itemProvider ]];
-    else
-        [pasteboard setItemProviders:@[ ]];
+    auto itemProviders = adoptNS([[NSMutableArray alloc] initWithCapacity:itemLists.count]);
+    for (WebItemProviderRegistrationInfoList *representationsToRegister in itemLists) {
+        if (auto *itemProvider = representationsToRegister.itemProvider)
+            [itemProviders addObject:itemProvider];
+    }
 
-    if ([pasteboard respondsToSelector:@selector(stageRegistrationList:)])
-        [pasteboard stageRegistrationList:representationsToRegister];
+    [pasteboard setItemProviders:itemProviders.get()];
+
+    if ([pasteboard respondsToSelector:@selector(stageRegistrationLists:)])
+        [pasteboard stageRegistrationLists:itemLists];
 }
 
+static void registerItemToPasteboard(WebItemProviderRegistrationInfoList *representationsToRegister, id <AbstractPasteboard> pasteboard)
+{
+    registerItemsToPasteboard(@[ representationsToRegister ], pasteboard);
+}
+
 long PlatformPasteboard::setColor(const Color& color)
 {
     auto representationsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
@@ -393,7 +405,7 @@
         addRepresentationsForPlainText(representationsToRegister.get(), content.dataInStringFormat);
 
     PasteboardCustomData customData;
-    customData.origin = content.contentOrigin;
+    customData.setOrigin(content.contentOrigin);
     [representationsToRegister addData:customData.createSharedBuffer()->createNSData().get() forType:@(PasteboardCustomData::cocoaType())];
 
     registerItemToPasteboard(representationsToRegister.get(), m_pasteboard.get());
@@ -516,8 +528,8 @@
 
     if (NSData *serializedCustomData = [m_pasteboard dataForPasteboardType:@(PasteboardCustomData::cocoaType())]) {
         auto data = ""
-        if (data.origin == origin) {
-            for (auto& type : data.orderedTypes)
+        if (data.origin() == origin) {
+            for (auto& type : data.orderedTypes())
                 domPasteboardTypes.add(type);
         }
     }
@@ -548,12 +560,12 @@
     return copyToVector(domPasteboardTypes);
 }
 
-long PlatformPasteboard::write(const PasteboardCustomData& data)
+static RetainPtr<WebItemProviderRegistrationInfoList> createItemProviderRegistrationList(const PasteboardCustomData& data)
 {
     auto representationsToRegister = adoptNS([[WebItemProviderRegistrationInfoList alloc] init]);
     [representationsToRegister setPreferredPresentationStyle:WebPreferredPresentationStyleInline];
 
-    if (data.sameOriginCustomData.size()) {
+    if (data.hasSameOriginCustomData() || !data.origin().isEmpty()) {
         if (auto serializedSharedBuffer = data.createSharedBuffer()->createNSData()) {
             // We stash the list of supplied pasteboard types in teamData here for compatibility with drag and drop.
             // Since the contents of item providers cannot be loaded prior to drop, but the pasteboard types are
@@ -562,19 +574,19 @@
             // all of the custom types. We use the teamData property, available on NSItemProvider on iOS, to store
             // this information, since the contents of teamData are immediately available prior to the drop.
             NSMutableArray<NSString *> *typesAsNSArray = [NSMutableArray array];
-            for (auto& type : data.orderedTypes)
+            for (auto& type : data.orderedTypes())
                 [typesAsNSArray addObject:type];
-            [representationsToRegister setTeamData:securelyArchivedDataWithRootObject(@{ @(originKeyForTeamData) : data.origin, @(customTypesKeyForTeamData) : typesAsNSArray })];
+            [representationsToRegister setTeamData:securelyArchivedDataWithRootObject(@{ @(originKeyForTeamData) : data.origin(), @(customTypesKeyForTeamData) : typesAsNSArray })];
             [representationsToRegister addData:serializedSharedBuffer.get() forType:@(PasteboardCustomData::cocoaType())];
         }
     }
 
-    for (auto& type : data.orderedTypes) {
-        NSString *stringValue = data.platformData.get(type);
+    data.forEachPlatformString([&] (auto& type, auto& value) {
+        NSString *stringValue = value;
         if (!stringValue.length)
-            continue;
+            return;
 
-        auto cocoaType = platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type).createCFString();
+        auto cocoaType = PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type).createCFString();
         if (UTTypeConformsTo(cocoaType.get(), kUTTypeURL))
             [representationsToRegister addRepresentingObject:[NSURL URLWithString:stringValue]];
         else if (UTTypeConformsTo(cocoaType.get(), kUTTypePlainText))
@@ -581,12 +593,21 @@
             [representationsToRegister addRepresentingObject:stringValue];
         else
             [representationsToRegister addData:[stringValue dataUsingEncoding:NSUTF8StringEncoding] forType:(NSString *)cocoaType.get()];
-    }
+    });
 
-    registerItemToPasteboard(representationsToRegister.get(), m_pasteboard.get());
-    return [(id<AbstractPasteboard>)m_pasteboard.get() changeCount];
+    return representationsToRegister;
 }
 
+void PlatformPasteboard::write(const Vector<PasteboardCustomData>& itemData)
+{
+    auto registrationLists = adoptNS([[NSMutableArray alloc] initWithCapacity:itemData.size()]);
+    for (auto& data : itemData) {
+        if (auto itemList = createItemProviderRegistrationList(data))
+            [registrationLists addObject:itemList.get()];
+    }
+    registerItemsToPasteboard(registrationLists.get(), m_pasteboard.get());
+}
+
 #else
 
 long PlatformPasteboard::setColor(const Color&)
@@ -620,9 +641,8 @@
     return { };
 }
 
-long PlatformPasteboard::write(const PasteboardCustomData&)
+void PlatformPasteboard::write(const Vector<PasteboardCustomData>&)
 {
-    return 0;
 }
 
 #endif
@@ -721,6 +741,12 @@
     [m_pasteboard updateSupportedTypeIdentifiers:typesArray];
 }
 
+long PlatformPasteboard::write(const PasteboardCustomData& data)
+{
+    write(Vector<PasteboardCustomData> { data });
+    return [m_pasteboard changeCount];
 }
 
+}
+
 #endif // PLATFORM(IOS_FAMILY)

Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm (251099 => 251100)


--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -462,7 +462,7 @@
     // FIXME: These ivars should be refactored to be Vector<RetainPtr<Type>> instead of generic NSArrays.
     RetainPtr<NSArray> _itemProviders;
     RetainPtr<NSArray> _supportedTypeIdentifiers;
-    RetainPtr<WebItemProviderRegistrationInfoList> _stagedRegistrationInfoList;
+    RetainPtr<NSArray<WebItemProviderRegistrationInfoList *>> _stagedRegistrationInfoLists;
 
     Vector<RetainPtr<WebItemProviderLoadResult>> _loadResults;
 }
@@ -484,7 +484,7 @@
         _changeCount = 0;
         _pendingOperationCount = 0;
         _supportedTypeIdentifiers = nil;
-        _stagedRegistrationInfoList = nil;
+        _stagedRegistrationInfoLists = nil;
         _loadResults = { };
     }
     return self;
@@ -853,18 +853,22 @@
     [_itemProviders enumerateObjectsUsingBlock:block];
 }
 
-- (void)stageRegistrationList:(nullable WebItemProviderRegistrationInfoList *)info
+- (void)stageRegistrationLists:(NSArray<WebItemProviderRegistrationInfoList *> *)lists
 {
-    _stagedRegistrationInfoList = info.numberOfItems ? info : nil;
+    ASSERT(lists.count);
+    _stagedRegistrationInfoLists = lists;
 }
 
-- (WebItemProviderRegistrationInfoList *)takeRegistrationList
+- (void)clearRegistrationLists
 {
-    auto stagedRegistrationInfoList = _stagedRegistrationInfoList;
-    _stagedRegistrationInfoList = nil;
-    return stagedRegistrationInfoList.autorelease();
+    _stagedRegistrationInfoLists = nil;
 }
 
+- (NSArray<WebItemProviderRegistrationInfoList *> *)takeRegistrationLists
+{
+    return _stagedRegistrationInfoLists.autorelease();
+}
+
 @end
 
 #endif // ENABLE(DATA_INTERACTION)

Modified: trunk/Source/WebCore/platform/mac/PasteboardMac.mm (251099 => 251100)


--- trunk/Source/WebCore/platform/mac/PasteboardMac.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/mac/PasteboardMac.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -161,7 +161,7 @@
         m_changeCount = platformStrategies()->pasteboardStrategy()->setStringForType(content.dataInStringFormat, legacyStringPasteboardType(), m_pasteboardName);
 
     PasteboardCustomData data;
-    data.origin = content.contentOrigin;
+    data.setOrigin(content.contentOrigin);
     m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(data.createSharedBuffer().ptr(), PasteboardCustomData::cocoaType(), m_pasteboardName);
 
 }

Modified: trunk/Source/WebCore/platform/mac/PasteboardWriter.mm (251099 => 251100)


--- trunk/Source/WebCore/platform/mac/PasteboardWriter.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/mac/PasteboardWriter.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -118,7 +118,7 @@
             [pasteboardItem setData:webContent->clientData[i]->createNSData().get() forType:toUTIUnlessAlreadyUTI(webContent->clientTypes[i]).get()];
 
         PasteboardCustomData customData;
-        customData.origin = webContent->contentOrigin;
+        customData.setOrigin(webContent->contentOrigin);
         [pasteboardItem setData:customData.createSharedBuffer()->createNSData().get() forType:toUTIUnlessAlreadyUTI(String(PasteboardCustomData::cocoaType())).get()];
     }
 

Modified: trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm (251099 => 251100)


--- trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -198,8 +198,8 @@
     ListHashSet<String> domPasteboardTypes;
     if (NSData *serializedCustomData = [m_pasteboard dataForType:@(PasteboardCustomData::cocoaType())]) {
         auto data = ""
-        if (data.origin == origin) {
-            for (auto& type : data.orderedTypes)
+        if (data.origin() == origin) {
+            for (auto& type : data.orderedTypes())
                 domPasteboardTypes.add(type);
         }
     }
@@ -225,21 +225,24 @@
 long PlatformPasteboard::write(const PasteboardCustomData& data)
 {
     NSMutableArray *types = [NSMutableArray array];
-    for (auto& entry : data.platformData)
-        [types addObject:platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(entry.key)];
-    if (data.sameOriginCustomData.size())
+    data.forEachType([&] (auto& type) {
+        [types addObject:platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type)];
+    });
+
+    bool hasSameOriginCustomData = data.hasSameOriginCustomData();
+    if (hasSameOriginCustomData)
         [types addObject:@(PasteboardCustomData::cocoaType())];
 
     [m_pasteboard declareTypes:types owner:nil];
 
-    for (auto& entry : data.platformData) {
-        auto platformType = platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(entry.key);
+    data.forEachPlatformString([&] (auto& type, auto& data) {
+        auto platformType = platformPasteboardTypeForSafeTypeForDOMToReadAndWrite(type);
         ASSERT(!platformType.isEmpty());
         if (!platformType.isEmpty())
-            [m_pasteboard setString:entry.value forType:platformType];
-    }
+            [m_pasteboard setString:data forType:platformType];
+    });
 
-    if (data.sameOriginCustomData.size()) {
+    if (hasSameOriginCustomData) {
         if (auto serializedCustomData = data.createSharedBuffer()->createNSData())
             [m_pasteboard setData:serializedCustomData.get() forType:@(PasteboardCustomData::cocoaType())];
     }
@@ -463,6 +466,43 @@
     return [m_pasteboard pasteboardItems].count;
 }
 
+static RetainPtr<NSPasteboardItem> createPasteboardItem(const PasteboardCustomData& data)
+{
+    auto item = adoptNS([[NSPasteboardItem alloc] init]);
+
+    if (data.hasSameOriginCustomData() || !data.origin().isEmpty()) {
+        if (auto serializedCustomData = data.createSharedBuffer()->createNSData())
+            [item setData:serializedCustomData.get() forType:@(PasteboardCustomData::cocoaType())];
+    }
+
+    data.forEachPlatformStringOrBuffer([&] (auto& type, auto& stringOrBuffer) {
+        auto platformType = modernPasteboardTypeForWebSafeMIMEType(type);
+        if (!platformType)
+            return;
+
+        if (WTF::holds_alternative<String>(stringOrBuffer)) {
+            [item setString:WTF::get<String>(stringOrBuffer) forType:platformType];
+            return;
+        }
+
+        if (WTF::holds_alternative<Ref<SharedBuffer>>(stringOrBuffer)) {
+            if (auto platformData = WTF::get<Ref<SharedBuffer>>(stringOrBuffer)->createNSData())
+                [item setData:platformData.get() forType:platformType];
+        }
+    });
+
+    return item;
+}
+
+void PlatformPasteboard::write(const Vector<PasteboardCustomData>& itemData)
+{
+    auto platformItems = adoptNS([[NSMutableArray alloc] initWithCapacity:itemData.size()]);
+    for (auto& data : itemData)
+        [platformItems addObject:createPasteboardItem(data).get()];
+    [m_pasteboard clearContents];
+    [m_pasteboard writeObjects:platformItems.get()];
+}
+
 PasteboardItemInfo PlatformPasteboard::informationForItemAtIndex(size_t index)
 {
     NSPasteboardItem *item = itemAtIndex(index);

Modified: trunk/Source/WebKit/ChangeLog (251099 => 251100)


--- trunk/Source/WebKit/ChangeLog	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKit/ChangeLog	2019-10-14 21:52:26 UTC (rev 251100)
@@ -1,3 +1,46 @@
+2019-10-14  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Clipboard API] Support writing multiple PasteboardCustomData with SharedBuffers to the pasteboard
+        https://bugs.webkit.org/show_bug.cgi?id=202851
+
+        Reviewed by Darin Adler.
+
+        See WebCore ChangeLog for more details.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<PasteboardCustomData::Entry>::encode):
+        (IPC::ArgumentCoder<PasteboardCustomData::Entry>::decode):
+
+        Add helpers to encode and decode PasteboardCustomData::Entry.
+
+        (IPC::ArgumentCoder<PasteboardCustomData>::encode):
+        (IPC::ArgumentCoder<PasteboardCustomData>::decode):
+        * Shared/WebCoreArgumentCoders.h:
+
+        Add support for encoding and decoding PasteboardCustomData by encoding and decoding each of its items (see
+        above).
+
+        * UIProcess/Cocoa/WebViewImpl.mm:
+        (WebKit::WebViewImpl::requestDOMPasteAccess):
+        * UIProcess/WebPasteboardProxy.h:
+        * UIProcess/WebPasteboardProxy.messages.in:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView canPerformActionForWebView:withSender:]):
+        (allPasteboardItemOriginsMatchOrigin):
+        (-[WKContentView _didHandleAdditionalDragItemsRequest:]):
+
+        Tweak several methods to use the new methods on PasteboardCustomData instead of accessing the member variables
+        directly.
+
+        (-[WKContentView cleanUpDragSourceSessionState]):
+        (-[WKContentView _prepareToDragPromisedAttachment:]):
+        (-[WKContentView _itemsForBeginningOrAddingToSessionWithRegistrationLists:stagedDragSource:]):
+        (-[WKContentView dragInteraction:itemsForBeginningSession:]):
+        (-[WKContentView _itemsForBeginningOrAddingToSessionWithRegistrationList:stagedDragSource:]): Deleted.
+
+        Adjust these methods to handle multiple staged item providers (for now, it remains that iOS drag and drop
+        codepaths will still only write a single item to the pasteboard).
+
 2019-10-14  Per Arne Vollan  <pvol...@apple.com>
 
         [macOS] Sandbox extensions should be created with audit tokens, not PIDs

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (251099 => 251100)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2019-10-14 21:52:26 UTC (rev 251100)
@@ -1636,31 +1636,83 @@
 }
 #endif
 
-void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
+template<> struct ArgumentCoder<PasteboardCustomData::Entry> {
+    static void encode(Encoder&, const PasteboardCustomData::Entry&);
+    static bool decode(Decoder&, PasteboardCustomData::Entry&);
+};
+
+void ArgumentCoder<PasteboardCustomData::Entry>::encode(Encoder& encoder, const PasteboardCustomData::Entry& data)
 {
-    encoder << data.origin;
-    encoder << data.orderedTypes;
-    encoder << data.platformData;
-    encoder << data.sameOriginCustomData;
+    encoder << data.type << data.customData;
+
+    auto& platformData = data.platformData;
+    bool hasString = WTF::holds_alternative<String>(platformData);
+    encoder << hasString;
+    if (hasString)
+        encoder << WTF::get<String>(platformData);
+
+    bool hasBuffer = WTF::holds_alternative<Ref<SharedBuffer>>(platformData);
+    encoder << hasBuffer;
+    if (hasBuffer)
+        encodeSharedBuffer(encoder, WTF::get<Ref<SharedBuffer>>(platformData).ptr());
 }
 
-bool ArgumentCoder<PasteboardCustomData>::decode(Decoder& decoder, PasteboardCustomData& data)
+bool ArgumentCoder<PasteboardCustomData::Entry>::decode(Decoder& decoder, PasteboardCustomData::Entry& data)
 {
-    if (!decoder.decode(data.origin))
+    if (!decoder.decode(data.type))
         return false;
 
-    if (!decoder.decode(data.orderedTypes))
+    if (!decoder.decode(data.customData))
         return false;
 
-    if (!decoder.decode(data.platformData))
+    bool hasString;
+    if (!decoder.decode(hasString))
         return false;
 
-    if (!decoder.decode(data.sameOriginCustomData))
+    if (hasString) {
+        String value;
+        if (!decoder.decode(value))
+            return false;
+        data.platformData = { WTFMove(value) };
+    }
+
+    bool hasBuffer;
+    if (!decoder.decode(hasBuffer))
         return false;
 
+    if (hasString && hasBuffer)
+        return false;
+
+    if (hasBuffer) {
+        RefPtr<SharedBuffer> value;
+        if (!decodeSharedBuffer(decoder, value))
+            return false;
+        data.platformData = { value.releaseNonNull() };
+    }
+
     return true;
 }
 
+void ArgumentCoder<PasteboardCustomData>::encode(Encoder& encoder, const PasteboardCustomData& data)
+{
+    encoder << data.origin();
+    encoder << data.data();
+}
+
+bool ArgumentCoder<PasteboardCustomData>::decode(Decoder& decoder, PasteboardCustomData& data)
+{
+    String origin;
+    if (!decoder.decode(origin))
+        return false;
+
+    Vector<PasteboardCustomData::Entry> items;
+    if (!decoder.decode(items))
+        return false;
+
+    data = "" WTFMove(items));
+    return true;
+}
+
 void ArgumentCoder<PasteboardURL>::encode(Encoder& encoder, const PasteboardURL& content)
 {
     encoder << content.url;

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h (251099 => 251100)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -89,6 +89,7 @@
 class LayoutPoint;
 class LinearTimingFunction;
 class Notification;
+class PasteboardCustomData;
 class Path;
 class ProtectionSpace;
 class Region;
@@ -117,7 +118,6 @@
 struct GrammarDetail;
 struct MimeClassInfo;
 struct PasteboardImage;
-struct PasteboardCustomData;
 struct PasteboardURL;
 struct PluginInfo;
 struct PromisedAttachmentInfo;

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm (251099 => 251100)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -4318,7 +4318,7 @@
 
     NSData *data = "" dataForType:@(WebCore::PasteboardCustomData::cocoaType())];
     auto buffer = WebCore::SharedBuffer::create(data);
-    if (WebCore::PasteboardCustomData::fromSharedBuffer(buffer.get()).origin == originIdentifier) {
+    if (WebCore::PasteboardCustomData::fromSharedBuffer(buffer.get()).origin() == originIdentifier) {
         completion(WebCore::DOMPasteAccessResponse::GrantedForGesture);
         return;
     }

Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h (251099 => 251100)


--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 class Color;
-struct PasteboardCustomData;
+class PasteboardCustomData;
 struct PasteboardImage;
 struct PasteboardItemInfo;
 struct PasteboardURL;

Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in (251099 => 251100)


--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in	2019-10-14 21:52:26 UTC (rev 251100)
@@ -29,7 +29,7 @@
     UpdateSupportedTypeIdentifiers(Vector<String> identifiers, String pasteboardName)
 #endif
 
-    WriteCustomData(struct WebCore::PasteboardCustomData data, String pasteboardName) -> (uint64_t changeCount) Synchronous
+    WriteCustomData(WebCore::PasteboardCustomData data, String pasteboardName) -> (uint64_t changeCount) Synchronous
     TypesSafeForDOMToReadAndWrite(String pasteboardName, String origin) -> (Vector<String> types) Synchronous
     AllPasteboardItemInfo(String pasteboardName) -> (Vector<WebCore::PasteboardItemInfo> allInfo) Synchronous
     InformationForItemAtIndex(uint64_t index, String pasteboardName) -> (struct WebCore::PasteboardItemInfo info) Synchronous

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (251099 => 251100)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2019-10-14 21:52:26 UTC (rev 251100)
@@ -3233,7 +3233,7 @@
         NSArray *allCustomPasteboardData = [pasteboard dataForPasteboardType:@(WebCore::PasteboardCustomData::cocoaType()) inItemSet:indices];
         for (NSData *data in allCustomPasteboardData) {
             auto buffer = WebCore::SharedBuffer::create(data);
-            if (WebCore::PasteboardCustomData::fromSharedBuffer(buffer.get()).origin == focusedDocumentOrigin)
+            if (WebCore::PasteboardCustomData::fromSharedBuffer(buffer.get()).origin() == focusedDocumentOrigin)
                 return YES;
         }
         return NO;
@@ -5731,7 +5731,7 @@
             continue;
 
         auto buffer = WebCore::SharedBuffer::create(data);
-        if (WebCore::PasteboardCustomData::fromSharedBuffer(buffer.get()).origin != originIdentifier)
+        if (WebCore::PasteboardCustomData::fromSharedBuffer(buffer.get()).origin() != originIdentifier)
             return NO;
 
         foundAtLeastOneMatchingIdentifier = YES;
@@ -6706,8 +6706,8 @@
     if (!completion)
         return;
 
-    WebItemProviderRegistrationInfoList *registrationList = [[WebItemProviderPasteboard sharedInstance] takeRegistrationList];
-    if (!added || !registrationList || !_dragDropInteractionState.hasStagedDragSource()) {
+    auto *registrationLists = [[WebItemProviderPasteboard sharedInstance] takeRegistrationLists];
+    if (!added || ![registrationLists count] || !_dragDropInteractionState.hasStagedDragSource()) {
         _dragDropInteractionState.clearStagedDragSource();
         completion(@[ ]);
         return;
@@ -6714,7 +6714,7 @@
     }
 
     auto stagedDragSource = _dragDropInteractionState.stagedDragSource();
-    NSArray *dragItemsToAdd = [self _itemsForBeginningOrAddingToSessionWithRegistrationList:registrationList stagedDragSource:stagedDragSource];
+    NSArray *dragItemsToAdd = [self _itemsForBeginningOrAddingToSessionWithRegistrationLists:registrationLists stagedDragSource:stagedDragSource];
 
     RELEASE_LOG(DragAndDrop, "Drag session: %p adding %tu items", _dragDropInteractionState.dragSession(), dragItemsToAdd.count);
     _dragDropInteractionState.clearStagedDragSource(dragItemsToAdd.count ? WebKit::DragDropInteractionState::DidBecomeActive::Yes : WebKit::DragDropInteractionState::DidBecomeActive::No);
@@ -6793,7 +6793,7 @@
         [[WebItemProviderPasteboard sharedInstance] setItemProviders:nil];
     }
 
-    [[WebItemProviderPasteboard sharedInstance] stageRegistrationList:nil];
+    [[WebItemProviderPasteboard sharedInstance] clearRegistrationLists];
     [self _restoreCalloutBarIfNeeded];
 
     [std::exchange(_visibleContentViewSnapshot, nil) removeFromSuperview];
@@ -6960,7 +6960,7 @@
 
     WebItemProviderPasteboard *pasteboard = [WebItemProviderPasteboard sharedInstance];
     pasteboard.itemProviders = @[ [registrationList itemProvider] ];
-    [pasteboard stageRegistrationList:registrationList.get()];
+    [pasteboard stageRegistrationLists:@[ registrationList.get() ]];
 }
 
 - (WKDragDestinationAction)_dragDestinationActionForDropSession:(id <UIDropSession>)session
@@ -6999,27 +6999,39 @@
     _shouldRestoreCalloutBarAfterDrop = NO;
 }
 
-- (NSArray<UIDragItem *> *)_itemsForBeginningOrAddingToSessionWithRegistrationList:(WebItemProviderRegistrationInfoList *)registrationList stagedDragSource:(const WebKit::DragSourceState&)stagedDragSource
+- (NSArray<UIDragItem *> *)_itemsForBeginningOrAddingToSessionWithRegistrationLists:(NSArray<WebItemProviderRegistrationInfoList *> *)registrationLists stagedDragSource:(const WebKit::DragSourceState&)stagedDragSource
 {
-    NSItemProvider *defaultItemProvider = registrationList.itemProvider;
-    if (!defaultItemProvider)
+    if (!registrationLists.count)
         return @[ ];
 
-    NSArray *adjustedItemProviders;
+    NSMutableArray *adjustedItemProviders = [NSMutableArray array];
     id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
     if ([uiDelegate respondsToSelector:@selector(_webView:adjustedDataInteractionItemProvidersForItemProvider:representingObjects:additionalData:)]) {
-        auto representingObjects = adoptNS([[NSMutableArray alloc] init]);
-        auto additionalData = adoptNS([[NSMutableDictionary alloc] init]);
-        [registrationList enumerateItems:[representingObjects, additionalData] (id <WebItemProviderRegistrar> item, NSUInteger) {
-            if ([item respondsToSelector:@selector(representingObjectForClient)])
-                [representingObjects addObject:item.representingObjectForClient];
-            if ([item respondsToSelector:@selector(typeIdentifierForClient)] && [item respondsToSelector:@selector(dataForClient)])
-                [additionalData setObject:item.dataForClient forKey:item.typeIdentifierForClient];
-        }];
-        adjustedItemProviders = [uiDelegate _webView:_webView adjustedDataInteractionItemProvidersForItemProvider:defaultItemProvider representingObjects:representingObjects.get() additionalData:additionalData.get()];
-    } else
-        adjustedItemProviders = @[ defaultItemProvider ];
+        // FIXME: We should consider a new UI delegate hook that accepts a list of item providers, so we don't need to invoke this delegate method repeatedly for multiple items.
+        for (WebItemProviderRegistrationInfoList *list in registrationLists) {
+            NSItemProvider *defaultItemProvider = list.itemProvider;
+            if (!defaultItemProvider)
+                continue;
 
+            auto representingObjects = adoptNS([[NSMutableArray alloc] init]);
+            auto additionalData = adoptNS([[NSMutableDictionary alloc] init]);
+            [list enumerateItems:[representingObjects, additionalData] (id <WebItemProviderRegistrar> item, NSUInteger) {
+                if ([item respondsToSelector:@selector(representingObjectForClient)])
+                    [representingObjects addObject:item.representingObjectForClient];
+                if ([item respondsToSelector:@selector(typeIdentifierForClient)] && [item respondsToSelector:@selector(dataForClient)])
+                    [additionalData setObject:item.dataForClient forKey:item.typeIdentifierForClient];
+            }];
+            NSArray *adjustedItems = [uiDelegate _webView:_webView adjustedDataInteractionItemProvidersForItemProvider:defaultItemProvider representingObjects:representingObjects.get() additionalData:additionalData.get()];
+            if (adjustedItems.count)
+                [adjustedItemProviders addObjectsFromArray:adjustedItems];
+        }
+    } else {
+        for (WebItemProviderRegistrationInfoList *list in registrationLists) {
+            if (auto *defaultItemProvider = list.itemProvider)
+                [adjustedItemProviders addObject:defaultItemProvider];
+        }
+    }
+
     NSMutableArray *dragItems = [NSMutableArray arrayWithCapacity:adjustedItemProviders.count];
     for (NSItemProvider *itemProvider in adjustedItemProviders) {
         auto item = adoptNS([[UIDragItem alloc] initWithItemProvider:itemProvider]);
@@ -7261,8 +7273,8 @@
     }
 
     auto stagedDragSource = _dragDropInteractionState.stagedDragSource();
-    WebItemProviderRegistrationInfoList *registrationList = [[WebItemProviderPasteboard sharedInstance] takeRegistrationList];
-    NSArray *dragItems = [self _itemsForBeginningOrAddingToSessionWithRegistrationList:registrationList stagedDragSource:stagedDragSource];
+    auto *registrationLists = [[WebItemProviderPasteboard sharedInstance] takeRegistrationLists];
+    NSArray *dragItems = [self _itemsForBeginningOrAddingToSessionWithRegistrationLists:registrationLists stagedDragSource:stagedDragSource];
     if (![dragItems count])
         _page->dragCancelled();
 

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (251099 => 251100)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2019-10-14 21:52:26 UTC (rev 251100)
@@ -1,3 +1,14 @@
+2019-10-14  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Clipboard API] Support writing multiple PasteboardCustomData with SharedBuffers to the pasteboard
+        https://bugs.webkit.org/show_bug.cgi?id=202851
+
+        Reviewed by Darin Adler.
+
+        See WebCore ChangeLog for more details.
+
+        * WebCoreSupport/WebPlatformStrategies.h:
+
 2019-10-09  Wenson Hsieh  <wenson_hs...@apple.com>
 
         [Clipboard API] Refactor Pasteboard item reading functions to work on both iOS and macOS

Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h (251099 => 251100)


--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h	2019-10-14 21:42:18 UTC (rev 251099)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebPlatformStrategies.h	2019-10-14 21:52:26 UTC (rev 251100)
@@ -29,9 +29,9 @@
 #include <WebCore/PasteboardStrategy.h>
 #include <WebCore/PlatformStrategies.h>
 
+class PasteboardCustomData;
 struct PasteboardImage;
 struct PasteboardWebContent;
-struct PasteboardCustomData;
 
 class WebPlatformStrategies : public WebCore::PlatformStrategies, private WebCore::PasteboardStrategy {
 public:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to