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: