haikuwebkit/Source/WebCore/platform/StaticPasteboard.cpp

163 lines
4.6 KiB
C++
Raw Permalink Normal View History

Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
/*
* Copyright (C) 2016 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 "StaticPasteboard.h"
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
#include "SharedBuffer.h"
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
namespace WebCore {
Plumb an Optional<PageIdentifier> through Pasteboard-related codepaths https://bugs.webkit.org/show_bug.cgi?id=221987 Reviewed by Tim Horton. Source/WebCore: In order to facilitate tagging pasteboard reads and writes with a data owner type on iOS sourced from `WKContentView`, we add infrastructure to (indirectly) tag `Pasteboard` with an optional `PageIdentifier` to indicate which page is triggering the pasteboard operation. However, since the `Pasteboard` class should only be responsible for interfacing with platform-dependent strategies for reading or writing data, we can't directly add a `PageIdentifier` member to `Pasteboard`. Instead, we introduce a separate `PasteboardContext` object, and let `Pasteboard` hold a unique pointer to this context (which is set during construction). `PasteboardContext` is then subclassed by `PagePasteboardContext`, which holds a `PageIdentifier` and is created from call sites of the `Pasteboard` constructor that have access to page identifiers (e.g. `Editor`, `Clipboard`, `EventHandler`). In a future patch, this opaque `PasteboardContext` will be converted back to a `PagePasteboardContext` in order to retrieve the page identifier in the WebKit client layer. * Headers.cmake: * Modules/async-clipboard/Clipboard.cpp: (WebCore::Clipboard::readText): (WebCore::Clipboard::writeText): (WebCore::Clipboard::read): (WebCore::Clipboard::ItemWriter::ItemWriter): Here (and in many places below), create `PagePasteboardContext` objects and use them to create `Pasteboard`s, passing them in as opaque `PasteboardContext`s. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::createForDrag): * dom/DataTransfer.h: * editing/Editor.cpp: (WebCore::createDataTransferForClipboardEvent): (WebCore::dispatchClipboardEvent): (WebCore::Editor::pasteAsPlainTextBypassingDHTML): (WebCore::Editor::performCutOrCopy): (WebCore::Editor::paste): (WebCore::Editor::pasteAsPlainText): (WebCore::Editor::pasteAsQuotation): (WebCore::Editor::copyURL): (WebCore::Editor::copyImage): * editing/EditorCommand.cpp: (WebCore::executePasteGlobalSelection): * editing/mac/EditorMac.mm: (WebCore::Editor::readSelectionFromPasteboard): (WebCore::Editor::replaceNodeFromPasteboard): * inspector/CommandLineAPIHost.cpp: (WebCore::CommandLineAPIHost::copyText): * inspector/InspectorFrontendHost.cpp: (WebCore::InspectorFrontendHost::copyText): * page/DragController.cpp: (WebCore::documentFragmentFromDragData): (WebCore::DragController::dragExited): (WebCore::DragController::performDragOperation): (WebCore::DragController::tryDHTMLDrag): (WebCore::DragController::tryToUpdateDroppedImagePlaceholders): * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): * page/PagePasteboardContext.h: Added. Add `PagePasteboardContext`, a `PasteboardContext` subclass that contains a `PageIdentifier` indicating which `Page` is requesting pasteboard access. (isType): * platform/DragData.cpp: (WebCore::DragData::DragData): (WebCore::DragData::createPasteboardContext const): Also plumb a `PageIdentifier` through `DragData`, and use it to implement a helper method that returns a context object for `Pasteboard`. * platform/DragData.h: Additionally make `operator=` platform-agnostic, instead of limited to GTK. (It isn't clear why this needs to be limited to the GTK port). (WebCore::DragData::DragData): (WebCore::DragData::pageID const): * platform/Pasteboard.h: Augment `Pasteboard`'s (numerous) platform-specific constructors to take in a `PasteboardContext` unique pointer as well, and store it in `m_context`. (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::context const): * platform/PasteboardContext.h: Added. Add `PasteboardContext`, which provides additional context for an arbitrary pasteboard operation in an opaque fashion. See `PagePasteboardContext` above. (WebCore::PasteboardContext::isPagePasteboardContext const): * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::StaticPasteboard): * platform/cocoa/DragDataCocoa.mm: (WebCore::DragData::DragData): (WebCore::DragData::canSmartReplace const): (WebCore::DragData::asPlainText const): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::createForCopyAndPaste): (WebCore::Pasteboard::createForGlobalSelection): (WebCore::Pasteboard::createForDragAndDrop): (WebCore::Pasteboard::create): (WebCore::Pasteboard::Pasteboard): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::createForDragAndDrop): (WebCore::Pasteboard::create): (WebCore::Pasteboard::createForCopyAndPaste): * platform/libwpe/PasteboardLibWPE.cpp: (WebCore::Pasteboard::createForCopyAndPaste): (WebCore::Pasteboard::Pasteboard): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::createForCopyAndPaste): (WebCore::Pasteboard::createForDragAndDrop): (WebCore::Pasteboard::create): * platform/win/DragDataWin.cpp: (WebCore::DragData::DragData): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::createForCopyAndPaste): (WebCore::Pasteboard::createForDragAndDrop): (WebCore::Pasteboard::create): (WebCore::Pasteboard::Pasteboard): Source/WebKit: Update more `DragData` and `Pasteboard` initialization sites by passing in a `PageIdentifier` or `PasteboardContext`, respectively. See WebCore ChangeLog for more details. * Shared/WebCoreArgumentCoders.cpp: (IPC::ArgumentCoder<DragData>::encode): (IPC::ArgumentCoder<DragData>::decode): * UIProcess/Cocoa/WebViewImpl.mm: (WebKit::WebViewImpl::draggingEntered): (WebKit::WebViewImpl::draggingUpdated): (WebKit::WebViewImpl::draggingExited): * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView dragDataForDropSession:dragDestinationAction:]): * WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp: (WebKit::WebEditorClient::updateGlobalSelection): * WebProcess/WebCoreSupport/mac/WebDragClientMac.mm: (WebKit::WebDragClient::declareAndWriteDragImage): * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::performDragControllerAction): * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::performActionOnElement): Source/WebKitLegacy/mac: Create and pass in a `PasteboardContext` when creating a `Pasteboard`. See WebCore ChangeLog for more details. * WebCoreSupport/WebDragClient.mm: (WebDragClient::declareAndWriteDragImage): Canonical link: https://commits.webkit.org/234275@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@273077 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-18 16:56:42 +00:00
StaticPasteboard::StaticPasteboard()
: Pasteboard({ })
{
}
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
StaticPasteboard::~StaticPasteboard() = default;
bool StaticPasteboard::hasData()
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
{
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
return m_customData.hasData();
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
}
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
Vector<String> StaticPasteboard::typesSafeForBindings(const String&)
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
{
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
return m_customData.orderedTypes();
}
Vector<String> StaticPasteboard::typesForLegacyUnsafeBindings()
{
return m_customData.orderedTypes();
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
}
Share more pasteboard code between iOS and macOS and remove dependency on Settings https://bugs.webkit.org/show_bug.cgi?id=177700 Reviewed by Wenson Hsieh. Moved more code from PasteboardIOS.mm and PasteboardMac.mm into PasteboardCocoa.mm to share code. This patch also removes the layering violation inadvertently introduced in r222595 whereby which Pasteboard code depends on Settings. To do this, this patch splits readStringForBindings is into readString and readStringInCustomData and typesForBindings into typesSafeForBindings and typesForLegacyUnsafeBindings, and moves the logic to decide whether a given type or string is read off of the native pasteboard entry or our custom data entry is moved to DataTransfer. No new tests since there should be no behavioral change. * dom/DataTransfer.cpp: (WebCore::DataTransfer::getData const): Moved the code to decide whether string is read off of custom data or native pasteboard from readStringForBindings. (WebCore::DataTransfer::types const): Ditto from typesForBindings. * platform/Pasteboard.cpp: (WebCore::Pasteboard::isSafeTypeForDOMToReadAndWrite): Moved into Pasteboard. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::readString): Renamed from readStringForBindings. (WebCore::StaticPasteboard::readStringInCustomData): Added. (WebCore::StaticPasteboard::writeString): * platform/StaticPasteboard.h: * platform/cocoa/PasteboardCocoa.mm: (WebCore::Pasteboard::typesSafeForBindings): Extracted out of typesForBindings in PasteboardIOS.mm and PasteboardMac.mm. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Ditto. (WebCore::Pasteboard::readString): Ditto. (WebCore::Pasteboard::readStringInCustomData): Ditto. (WebCore::Pasteboard::writeCustomData): Moved here from PasteboardIOS.mm and PasteboardCocoa.mm. (WebCore::Pasteboard::changeCount const): Ditto. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): (WebCore::Pasteboard::readStringInCustomData): Added. * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeCustomData): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::changeCount const): Ditto. (WebCore::Pasteboard::readPlatformValueAsString): Moved into Pasteboard. (WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Ditto. (WebCore::Pasteboard::readStringForBindings): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::typesForBindings): Ditto. * platform/ios/PlatformPasteboardIOS.mm: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::changeCount const): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::writeCustomData): Ditto. (WebCore::Pasteboard::readPlatformValueAsString): Moved into Pasteboard. (WebCore::Pasteboard::readStringForBindings): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Moved into Pasteboard. (WebCore::Pasteboard::typesForBindings): Moved to PasteboardCocoa.mm. * platform/mac/PlatformPasteboardMac.mm: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): Renamed from readStringForBindings. (WebCore::Pasteboard::readStringInCustomData): Added. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::PasteboardtypesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): Renamed from readStringForBindings. (WebCore::Pasteboard::readStringInCustomData): Added. Canonical link: https://commits.webkit.org/193964@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-30 10:31:05 +00:00
String StaticPasteboard::readString(const String& type)
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
{
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
return m_customData.readString(type);
Share more pasteboard code between iOS and macOS and remove dependency on Settings https://bugs.webkit.org/show_bug.cgi?id=177700 Reviewed by Wenson Hsieh. Moved more code from PasteboardIOS.mm and PasteboardMac.mm into PasteboardCocoa.mm to share code. This patch also removes the layering violation inadvertently introduced in r222595 whereby which Pasteboard code depends on Settings. To do this, this patch splits readStringForBindings is into readString and readStringInCustomData and typesForBindings into typesSafeForBindings and typesForLegacyUnsafeBindings, and moves the logic to decide whether a given type or string is read off of the native pasteboard entry or our custom data entry is moved to DataTransfer. No new tests since there should be no behavioral change. * dom/DataTransfer.cpp: (WebCore::DataTransfer::getData const): Moved the code to decide whether string is read off of custom data or native pasteboard from readStringForBindings. (WebCore::DataTransfer::types const): Ditto from typesForBindings. * platform/Pasteboard.cpp: (WebCore::Pasteboard::isSafeTypeForDOMToReadAndWrite): Moved into Pasteboard. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::readString): Renamed from readStringForBindings. (WebCore::StaticPasteboard::readStringInCustomData): Added. (WebCore::StaticPasteboard::writeString): * platform/StaticPasteboard.h: * platform/cocoa/PasteboardCocoa.mm: (WebCore::Pasteboard::typesSafeForBindings): Extracted out of typesForBindings in PasteboardIOS.mm and PasteboardMac.mm. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Ditto. (WebCore::Pasteboard::readString): Ditto. (WebCore::Pasteboard::readStringInCustomData): Ditto. (WebCore::Pasteboard::writeCustomData): Moved here from PasteboardIOS.mm and PasteboardCocoa.mm. (WebCore::Pasteboard::changeCount const): Ditto. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): (WebCore::Pasteboard::readStringInCustomData): Added. * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeCustomData): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::changeCount const): Ditto. (WebCore::Pasteboard::readPlatformValueAsString): Moved into Pasteboard. (WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Ditto. (WebCore::Pasteboard::readStringForBindings): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::typesForBindings): Ditto. * platform/ios/PlatformPasteboardIOS.mm: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::changeCount const): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::writeCustomData): Ditto. (WebCore::Pasteboard::readPlatformValueAsString): Moved into Pasteboard. (WebCore::Pasteboard::readStringForBindings): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Moved into Pasteboard. (WebCore::Pasteboard::typesForBindings): Moved to PasteboardCocoa.mm. * platform/mac/PlatformPasteboardMac.mm: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): Renamed from readStringForBindings. (WebCore::Pasteboard::readStringInCustomData): Added. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::PasteboardtypesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): Renamed from readStringForBindings. (WebCore::Pasteboard::readStringInCustomData): Added. Canonical link: https://commits.webkit.org/193964@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-30 10:31:05 +00:00
}
Drag event DataTransfer has unexpected types "dyn.ah62d4..." https://bugs.webkit.org/show_bug.cgi?id=172526 <rdar://problem/32396081> Reviewed by Ryosuke Niwa. Source/WebCore: Currently, the pasteboard types we expose to web content are simply the types that appear on the platform pasteboard (i.e. the general NSPasteboard on Mac, and either the general UIPasteboard or a UIDragSession's NSItemProviders on iOS). This leads to DataTransfer.types exposing many private pasteboard types written by apps around the system to the page, such as dynamic UTIs, CorePasteboardFlavorTypes, or the "Apple WebKit dummy pasteboard type". These are not only confusing and not useful for web content (since they mostly hold values of empty string anyways), but can additionally pose privacy concerns by exposing information meant only for native applications to unvetted web content. To address this problem, other browsers (e.g. Chrome and Firefox on Mac) white-list MIME types in DataTransfer's list of types. By default, when dragging or copying, these are "text/plain", "text/html" and "text/uri-list". However, this policy alone is insufficient, because the page may also supply its own types, in which case our naive whitelist would prevent us from delivering them to the page. To address this additional constraint, both Chrome and Firefox write any custom data supplied by the page to custom pasteboard UTIs (org.chromium.drag-dummy-type and org.mozilla.custom-clipdata, respectively). The corresponding data is a map of custom UTI => custom data supplied by the page; upon drop or paste, this mapping is consulted if the page calls getData() with a custom UTI. This patch adopts this same approach in WebKit, and introduces the com.apple.WebKit.custom-pasteboard-data UTI (refer to per-method comments below for more information). These changes are covered by 18 new layout and API tests, as well as existing drag-and-drop tests. Tests: editing/pasteboard/data-transfer-get-data-on-drop-custom.html editing/pasteboard/data-transfer-get-data-on-drop-plain-text.html editing/pasteboard/data-transfer-get-data-on-drop-rich-text.html editing/pasteboard/data-transfer-get-data-on-drop-url.html editing/pasteboard/data-transfer-get-data-on-paste-custom.html editing/pasteboard/data-transfer-get-data-on-paste-plain-text.html editing/pasteboard/data-transfer-get-data-on-paste-rich-text.html DataInteractionTests.DataTransferGetDataWhenDroppingPlainText DataInteractionTests.DataTransferGetDataWhenDroppingCustomData DataInteractionTests.DataTransferGetDataWhenDroppingURL DataInteractionTests.DataTransferGetDataWhenDroppingImageWithFileURL DataInteractionTests.DataTransferGetDataWhenDroppingRespectsPresentationStyle DataInteractionTests.DataTransferSetDataCannotWritePlatformTypes DataInteractionTests.DataTransferGetDataCannotReadPrivatePlatformTypes UIPasteboardTests.DataTransferGetDataWhenPastingURL UIPasteboardTests.DataTransferGetDataWhenPastingPlatformRepresentations UIPasteboardTests.DataTransferSetDataCannotWritePlatformTypes UIPasteboardTests.DataTransferGetDataCannotReadPrivatePlatformTypes * CMakeLists.txt: Add Pasteboard.cpp to the WebCore CMakeList. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::getData const): (WebCore::DataTransfer::createForDragStartEvent): Make a new static helper function to create a StaticPasteboard-backed DataTransfer when dispatching a dragstart event. Any data supplied by the page will be written to the static pasteboard of this DataTransfer. (WebCore::DataTransfer::moveDragState): Add a new helper on DataTransfer to transfer the data required to initiate a drag from one DataTransfer to another. This is used in EventHandler to transfer the contents of the temporary DataTransfer modified by the page during the dragstart event over to the DataTransfer used for the rest of the drag initiation codepath, which is actually connected to the platform. This includes committing the contents of the other DataTransfer's StaticPasteboard to the new platform-connected Pasteboard. (WebCore::DataTransfer::hasDragImage const): * dom/DataTransfer.h: * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::selectionInHTMLFormat): (WebCore::Editor::writeSelectionToPasteboard): (WebCore::Editor::writeSelection): Write an additional HTML markup string on iOS. We already do this for Mac, but this data previously had no use on iOS. This is needed for to vend the "text/html" representation to the page on iOS when pasting. * editing/mac/EditorMac.mm: (WebCore::Editor::selectionInHTMLFormat): Deleted. * editing/wpe/EditorWPE.cpp: (WebCore::createFragmentFromPasteboardData): * page/EventHandler.cpp: (WebCore::EventHandler::dispatchDragStartEventOnSourceElement): Renamed from dispatchDragStartEvent to dispatchDragStartEventOnSourceElement. Additionally, simplified the logic significantly, so that we now just check to see if the StaticPasteboard exposed to the page has any data, instead of using platform-dependent logic to compare changeCounts. We can do this because StaticPasteboard is guaranteed to only contain content that the page has supplied during the dragstart event, since it is empty upon initialization and cannot be written to by the rest of the platform. (WebCore::EventHandler::handleDrag): Tweak dispatchDragStartEvent to take a DataTransfer to expose to bindings; at the call site in handleDrag, create a new DataTransfer backed by a StaticPasteboard that the page may mutate over the course of the dragstart event. After dispatching to the page, move the dragging information present on the drag start DataTransfer over to the DragState's DataTransfer. If the drag image has not been set, compute and set the default drag image element on the DragState's DataTransfer. (WebCore::EventHandler::dispatchDragStartEvent): Deleted. * page/EventHandler.h: * page/Settings.cpp: (WebCore::Settings::customPasteboardDataEnabled): * page/Settings.h: (WebCore::Settings::setCustomPasteboardDataEnabled): * page/ios/EventHandlerIOS.mm: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. * page/mac/EventHandlerMac.mm: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. * page/win/EventHandlerWin.cpp: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. Remove this helper on both iOS and Mac. This only called createForDrag() before, with the addition of clearing the platform pasteboard prior to returning. Now that a StaticPasteboard is used when starting a drag, we clear out the platform pasteboard in platform-invariant code in EventHandler::handleDrag, so these helpers are no longer useful. * platform/Pasteboard.cpp: Added. (WebCore::isSafeTypeForDOMToReadAndWrite): Add a new helper to determine whether or not a pasteboard type is one of the standard DOM-exposed types. These are "text/plain", "text/html" and "text/uri-list". (WebCore::sharedBufferFromCustomData): (WebCore::customDataFromSharedBuffer): Add helper methods to serialize and deserialize custom data. The serialized data blob consists of: (1) versioning information, (2) a dictionary mapping each custom type to a value, and (3) a full list of types written by the page, in the order they were written. * platform/Pasteboard.h: Rename Pasteboard::readString to Pasteboard::readStringForBindings, to reflect that the string being read and the given type are exposed to and from the DOM. * platform/PasteboardStrategy.h: * platform/PasteboardWriterData.h: * platform/PlatformPasteboard.h: * platform/StaticPasteboard.cpp: Split m_stringContents out into m_platformData and m_customData. The former contains type-to-data entries for the DOM-exposed types, while the second contains entries that don't belong in the former. (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::readStringForBindings): (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::clear): (WebCore::StaticPasteboard::commitToPasteboard): Rather than propagate each entry to the client layer one at a time, populate a new PasteboardCustomData struct and send it to the client layer in one go. This new struct consists of an array of types in the order they were written by the page, a dictionary of public types (types we want to write directly to the platform pasteboard) and private types (custom types we want to package under our custom data blob). (WebCore::StaticPasteboard::readString): Deleted. * platform/StaticPasteboard.h: * platform/glib/EventHandlerGLib.cpp: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::writeCustomData): (WebCore::Pasteboard::readString): Deleted. * platform/gtk/PlatformPasteboardGtk.cpp: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): (WebCore::PlatformPasteboard::write): Add stub implementations for new custom pasteboard data methods. * platform/ios/AbstractPasteboard.h: * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeCustomData): Add new plumbing to ship a custom data (PasteboardCustomData) struct from WebCore to the client layer. (WebCore::cocoaTypeFromHTMLClipboardType): (WebCore::readPlatformValueAsString): (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::types): Rewritten to ask the client layer for DOM-exposed types rather than all types, in the case where custom pasteboard data is enabled in Settings. (WebCore::Pasteboard::readString): Deleted. * platform/ios/PlatformPasteboardIOS.mm: (WebCore::PlatformPasteboard::bufferForType): (WebCore::PlatformPasteboard::getPathnamesForType const): (WebCore::PlatformPasteboard::numberOfFiles const): (WebCore::PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite): Add a new helper to map DOM-safe pasteboard types to their platform counterparts. (WebCore::PlatformPasteboard::write): (WebCore::safeTypeForDOMToReadAndWriteForPlatformType): Add a new helper to map platform pasteboard types to their DOM-safe counterparts. (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Fetch a list of DOM-exposed types. On iOS, for drag and drop, we have the additional constraint of not being able to read any data before the drop happens. This is problematic, since the page needs to know the list of types during 'dragover' events. To support this, we instead keep the array of types in the teamData property of the generated item provider, which is immediately available, even when dragging across different apps. Note that we still need to check if the pasteboard contains the full custom data blob here to handle the case where we copy on Mac and perform a continuity paste on iOS, since teamData does not exist on Mac. (WebCore::PlatformPasteboard::readString): Tweak to account for how UIPasteboard may return data blobs when reading values. (WebCore::PlatformPasteboard::getPathnamesForType): Deleted. (WebCore::PlatformPasteboard::numberOfFiles): Deleted. * platform/ios/WebItemProviderPasteboard.h: * platform/ios/WebItemProviderPasteboard.mm: (-[WebItemProviderRegistrationInfoList itemProvider]): (+[WebItemProviderLoadResult loadResultWithItemProvider:typesToLoad:]): (-[WebItemProviderLoadResult initWithItemProvider:typesToLoad:]): (-[WebItemProviderLoadResult typesToLoad]): (-[WebItemProviderLoadResult setFileURL:forType:]): (-[WebItemProviderLoadResult itemProvider]): (-[WebItemProviderPasteboard setItemProviders:]): (-[WebItemProviderPasteboard dataForPasteboardType:]): (-[WebItemProviderPasteboard typeIdentifiersToLoadForRegisteredTypeIdentfiers:]): (-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout:]): (+[WebItemProviderLoadResult emptyLoadResult]): Deleted. (+[WebItemProviderLoadResult loadResultWithFileURLMap:presentationStyle:]): Deleted. (-[WebItemProviderLoadResult initWithFileURLMap:presentationStyle:]): Deleted. (-[WebItemProviderPasteboard typeIdentifierToLoadForRegisteredTypeIdentfiers:]): Deleted. In the case of drag and drop on iOS, we cannot load any data prior to performing the drop; additionally, any attempts to load data immediately after the drop is performed in the UI process will fail. This means any and all data that the web process may require in the future when handling the drop must be loaded out of the item providers and saved when the drop is being handled in the UI process. Currently, we only load the highest fidelity type we can handle (or, if we don't know what we can handle, we select the highest fidelity representation conforming to "public.content"). This is a problematic for supporting DataTransfer.getData() on drop on iOS, because the page can ask for any of the three web-exposed types. To address this, we refactor WebItemProviderPasteboard to support loading multiple representations per item being dropped. At minimum, we will load anything conforming to "public.html", "public.plain-text", "public.url", and the new "com.apple.WebKit.custom-pasteboard-data" so we have means to answer any question that the page could ask via DataTransfer.getData(). We additonally load the highest fidelity supported (or content-conformant) type, if it has not already been loaded as a result of the former. To make this possible, we refactor WebItemProviderLoadResult to take an item provider and a list of types to load. -doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout: then creates a list of load results and uses each one to represent the results of loading data from its item provider (i.e. a map of UTI => file URL). * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::writeCustomData): (WebCore::cocoaTypeFromHTMLClipboardType): (WebCore::readPlatformValueAsString): (WebCore::Pasteboard::readStringForBindings): Change readStringForBindings (formerly, readString) so that if support for custom pasteboard data is enabled, we only allow reading directly from the platform pasteboard if the given type is DOM-safe; otherwise, we consult the custom data blob, if it exists. Otherwise, if support for custom pasteboard data is disabled, we fall back to our current behavior. (WebCore::Pasteboard::types): (WebCore::Pasteboard::readString): Deleted. * platform/mac/PlatformPasteboardMac.mm: (WebCore::PlatformPasteboard::numberOfFiles const): (WebCore::PlatformPasteboard::getPathnamesForType const): (WebCore::PlatformPasteboard::stringForType): (WebCore::safeTypeForDOMToReadAndWriteForPlatformType): (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Add support for reading DOM-exposed types and fetching DOM-exposed data off of the pasteboard. The overall idea here is similar to iOS, though implementation details vary (e.g. no item provider support). (WebCore::PlatformPasteboard::write): (WebCore::PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite): (WebCore::PlatformPasteboard::numberOfFiles): Deleted. (WebCore::PlatformPasteboard::getPathnamesForType): Deleted. * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::writeCustomData): (WebCore::Pasteboard::readString): Deleted. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::writeCustomData): (WebCore::Pasteboard::readString): Deleted. * platform/wpe/PlatformPasteboardWPE.cpp: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): (WebCore::PlatformPasteboard::write): * testing/InternalSettings.cpp: (WebCore::InternalSettings::Backup::Backup): (WebCore::InternalSettings::Backup::restoreTo): (WebCore::InternalSettings::setCustomPasteboardDataEnabled): Add a new internal settings hook for layout tests to opt in to using custom pasteboard data. By default, custom pasteboard data is enabled only in Safari, or on applications linked on or after certain releases of iOS and macOS. * testing/InternalSettings.h: * testing/InternalSettings.idl: Source/WebKit: Add boilerplate plumbing and encoder/decoder support for new pasteboard codepaths. See WebCore ChangeLog for more details. * Scripts/webkit/messages.py: (headers_for_type): * Shared/WebCoreArgumentCoders.cpp: (IPC::ArgumentCoder<PasteboardCustomData>::encode): (IPC::ArgumentCoder<PasteboardCustomData>::decode): Add encoder/decoder support for PasteboardCustomData. (IPC::ArgumentCoder<PasteboardWebContent>::encode): (IPC::ArgumentCoder<PasteboardWebContent>::decode): Encode and decode dataInHTMLFormat. * Shared/WebCoreArgumentCoders.h: * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm: (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite): (WebKit::WebPasteboardProxy::writeCustomData): * UIProcess/WebPasteboardProxy.cpp: (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite): (WebKit::WebPasteboardProxy::writeCustomData): * UIProcess/WebPasteboardProxy.h: * UIProcess/WebPasteboardProxy.messages.in: * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: (WebKit::WebPlatformStrategies::typesSafeForDOMToReadAndWrite): (WebKit::WebPlatformStrategies::writeCustomData): * WebProcess/WebCoreSupport/WebPlatformStrategies.h: Source/WebKitLegacy/mac: Adjust for changes in WebCore. See WebCore ChangeLog for more details. * WebCoreSupport/WebPlatformStrategies.h: * WebCoreSupport/WebPlatformStrategies.mm: (WebPlatformStrategies::webExposedTypes): (WebPlatformStrategies::writeCustomData): Tools: Adds new API tests on iOS to cover various cases of using DataTransfer.setData, DataTransfer.getData, and DataTransfer.types, as well as their interaction with platform objects (source NSItemProviders in the case of drag and drop, and the general UIPasteboard for copy and paste). * TestWebKitAPI/PlatformUtilities.h: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Added. Introduce a new API test harness that both drag-and-drop and copy-and-paste tests use to dump DataTransfer's web-exposed types and values. * TestWebKitAPI/Tests/ios/DataInteractionTests.mm: (checkFirstTypeIsPresentAndSecondTypeIsMissing): (checkJSONWithLogging): (TestWebKitAPI::TEST): (checkTypeIdentifierAndIsNotOtherTypeIdentifier): Deleted. * TestWebKitAPI/Tests/ios/UIPasteboardTests.mm: (TestWebKitAPI::checkJSONWithLogging): (TestWebKitAPI::setUpWebViewForPasteboardTests): (TestWebKitAPI::TEST): * TestWebKitAPI/cocoa/PlatformUtilitiesCocoa.mm: (TestWebKitAPI::Util::jsonMatchesExpectedValues): LayoutTests: Add new layout tests on Mac and iOS to test various cases of using DataTransfer.setData, DataTransfer.getData, and DataTransfer.types for drag-and-drop (tests for Mac WK1 only) and copy-and-paste (all platforms). * TestExpectations: * editing/pasteboard/data-transfer-get-data-on-drop-custom-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-custom.html: Added. * editing/pasteboard/data-transfer-get-data-on-drop-plain-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-plain-text.html: Added. * editing/pasteboard/data-transfer-get-data-on-drop-rich-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-rich-text.html: Added. * editing/pasteboard/data-transfer-get-data-on-drop-url-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-url.html: Added. * editing/pasteboard/data-transfer-get-data-on-paste-custom-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-paste-custom.html: Added. * editing/pasteboard/data-transfer-get-data-on-paste-plain-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-paste-plain-text.html: Added. * editing/pasteboard/data-transfer-get-data-on-paste-rich-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-paste-rich-text.html: Added. * platform/ios-simulator-wk1/TestExpectations: Mark new copy and paste tests as [ Pass ], since editing/pasteboard/ is skipped by default for iOS WK1. * platform/ios-wk1/editing/pasteboard/data-transfer-get-data-on-paste-rich-text-expected.txt: Added. * platform/ios-wk2/editing/pasteboard/data-transfer-get-data-on-paste-rich-text-expected.txt: Added. Add iOS-specific baselines. This is due to the generated HTML markup for "text/html" being slightly different when pasting. * platform/mac-wk1/TestExpectations: Canonical link: https://commits.webkit.org/193880@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222595 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-28 02:29:16 +00:00
Share more pasteboard code between iOS and macOS and remove dependency on Settings https://bugs.webkit.org/show_bug.cgi?id=177700 Reviewed by Wenson Hsieh. Moved more code from PasteboardIOS.mm and PasteboardMac.mm into PasteboardCocoa.mm to share code. This patch also removes the layering violation inadvertently introduced in r222595 whereby which Pasteboard code depends on Settings. To do this, this patch splits readStringForBindings is into readString and readStringInCustomData and typesForBindings into typesSafeForBindings and typesForLegacyUnsafeBindings, and moves the logic to decide whether a given type or string is read off of the native pasteboard entry or our custom data entry is moved to DataTransfer. No new tests since there should be no behavioral change. * dom/DataTransfer.cpp: (WebCore::DataTransfer::getData const): Moved the code to decide whether string is read off of custom data or native pasteboard from readStringForBindings. (WebCore::DataTransfer::types const): Ditto from typesForBindings. * platform/Pasteboard.cpp: (WebCore::Pasteboard::isSafeTypeForDOMToReadAndWrite): Moved into Pasteboard. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::readString): Renamed from readStringForBindings. (WebCore::StaticPasteboard::readStringInCustomData): Added. (WebCore::StaticPasteboard::writeString): * platform/StaticPasteboard.h: * platform/cocoa/PasteboardCocoa.mm: (WebCore::Pasteboard::typesSafeForBindings): Extracted out of typesForBindings in PasteboardIOS.mm and PasteboardMac.mm. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Ditto. (WebCore::Pasteboard::readString): Ditto. (WebCore::Pasteboard::readStringInCustomData): Ditto. (WebCore::Pasteboard::writeCustomData): Moved here from PasteboardIOS.mm and PasteboardCocoa.mm. (WebCore::Pasteboard::changeCount const): Ditto. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): (WebCore::Pasteboard::readStringInCustomData): Added. * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeCustomData): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::changeCount const): Ditto. (WebCore::Pasteboard::readPlatformValueAsString): Moved into Pasteboard. (WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Ditto. (WebCore::Pasteboard::readStringForBindings): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::typesForBindings): Ditto. * platform/ios/PlatformPasteboardIOS.mm: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::changeCount const): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::writeCustomData): Ditto. (WebCore::Pasteboard::readPlatformValueAsString): Moved into Pasteboard. (WebCore::Pasteboard::readStringForBindings): Moved to PasteboardCocoa.mm. (WebCore::Pasteboard::addHTMLClipboardTypesForCocoaType): Moved into Pasteboard. (WebCore::Pasteboard::typesForBindings): Moved to PasteboardCocoa.mm. * platform/mac/PlatformPasteboardMac.mm: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::Pasteboard::typesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): Renamed from readStringForBindings. (WebCore::Pasteboard::readStringInCustomData): Added. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::typesSafeForBindings): Added. (WebCore::PasteboardtypesForLegacyUnsafeBindings): Renamed from readStringForBindings. (WebCore::Pasteboard::readString): Renamed from readStringForBindings. (WebCore::Pasteboard::readStringInCustomData): Added. Canonical link: https://commits.webkit.org/193964@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-30 10:31:05 +00:00
String StaticPasteboard::readStringInCustomData(const String& type)
{
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
return m_customData.readStringInCustomData(type);
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
}
dataTransfer.types is empty when handling the "dragstart" event https://bugs.webkit.org/show_bug.cgi?id=212685 <rdar://problem/61368402> Reviewed by Andy Estes. Source/WebCore: Implements several currently stubbed methods on StaticPasteboard, so that the DataTransfer provided to the page on the "dragstart" event contains the DOM-exposed data types that will be written to the system pasteboard. This includes "text/html", "text/plain", and "text/uri-list". Tests: DragAndDropTests.DataTransferTypesOnDragStartForTextSelection DragAndDropTests.DataTransferTypesOnDragStartForImage DragAndDropTests.DataTransferTypesOnDragStartForLink ...as well as several existing tests in DragAndDropTestsIOS.mm that attempt to set pasteboard data during the dragstart event: DragAndDropTests.DataTransferSanitizeHTML DragAndDropTests.DataTransferSetDataCannotWritePlatformTypes DragAndDropTests.DataTransferSetDataInvalidURL DragAndDropTests.DataTransferSetDataUnescapedURL DragAndDropTests.DataTransferSetDataValidURL * dom/DataTransfer.cpp: (WebCore::DataTransfer::commitToPasteboard): Only commit data to the native pasteboard if the page actually tried to write or modify the data. This allows us to preserve existing behavior by allowing DragController to write dragged data to the pasteboard normally in the case where the page didn't specify any custom data. In the case where the page does specify custom data, we will write this custom data *in addition* to any default data that was written to the static pasteboard. While this is a departure from our current behavior (which is to treat the pasteboard as a blank slate that contains only whatever custom data was provided by the page), it matches behavior in both Chrome and Firefox, and is likely more compatible with webpages that don't have UA-specific logic targeting WebKit. * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::writeSelectionToPasteboard): Avoid calling into the injected bundle (as well as writing a few particular non-web-exposed types, such as web archive data) in the case where we're writing to a static pasteboard (there's no point in doing this for the static pasteboard, and in the worst case, it could confuse some internal clients). * editing/ios/EditorIOS.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. * editing/mac/EditorMac.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. But additionally, introduce a markup string to PasteboardImage, so that we will expose the "text/html" type when starting a drag on an image element. * page/DragController.cpp: (WebCore::DragController::startDrag): Only attempt to call into `Pasteboard::writeTrustworthyWebURLsPboardType` in the case where the pasteboard supports this type (i.e. on macOS). This fixes an existing assertion that was hit by my new API test, which attempts to override the contents of the pasteboard with custom data while starting a drag on a link. * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): Since the StaticPasteboard contains data before the page has written anything, don't use `Pasteboard::hasData()` to determine whether there's custom data; instead, use the new `hasNonDefaultData()` method on `StaticPasteboard` (see below). * platform/Pasteboard.cpp: (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): On non-macOS ports, return false. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::hasNonDefaultData const): Keep track of whether the page attempted to stage any custom data during "dragstart" by maintaining the set of types written by the page, via calls to `writeString()` and similar. I'm using a set of types here instead of a simple `bool` flag to ensure correctness in the case where the page adds a type, and then later removes that same custom type, such that there is no longer non-default data. (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::writeData): (WebCore::StaticPasteboard::writeStringInCustomData): (WebCore::StaticPasteboard::clear): See above. (WebCore::StaticPasteboard::writeMarkup): (WebCore::StaticPasteboard::writePlainText): (WebCore::StaticPasteboard::write): Implement these methods by writing to the `PasteboardCustomData`. These methods are invoked by our own code rather than the bindings, and should only be used to stage default data types when starting a drag. * platform/StaticPasteboard.h: * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::write): (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): Tools: Adds new API tests and test infrastructure to verify that DataTransfer types and data are accessible during the "dragstart" event. See below for more details. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: (-[TestWKWebView selectElementWithID:]): (-[DragAndDropSimulator dragFromElementWithID:to:]): Add a few (very specialized) helper methods to assist with simulating drags over the various elements in the new drag and drop test harness page below (dragstart-data.html). (runDragStartDataTestCase): Test the following scenarios (split between three API tests) by dumping the resulting DataTransfer types and their data strings, and observing the results: - Dragging a normal text selection. - Dragging a normal text selection, and then adding a URL string. - Dragging a normal text selection, and then adding a custom pasteboard type. - Dragging a normal text selection, but then replacing the data with just a URL string. - Dragging a normal text selection, but then replacing the data with just a custom data type. - Dragging an image element. - Dragging an image element, and then overriding the plain text data. - Dragging a link (anchor element). - Dragging a link, and then adding a custom type. * TestWebKitAPI/Tests/WebKitCocoa/dragstart-data.html: Added. Add a new test harness to help test DataTransfer types when starting a drag. This test page can also be used as a manual test harness, by simply opening the test page, starting drags on the various elements and observing the output in the textarea. * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Tweak this test page to replace the DataTransfer with custom data (rather than simply append it) by calling `DataTransfer.clearData()` prior to writing the custom types. * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebViewHostWindow initWithWebView:contentRect:styleMask:backing:defer:]): Add a `__weak` reference on TestWKWebViewHostWindow back to the TestWKWebView, so that we can consult `-eventTimestamp` when synthesizing mouse events on macOS during API tests. (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:]): (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:]): (-[TestWKWebViewHostWindow initWithWebView:frame:]): (-[TestWKWebView _setUpTestWindow:]): (-[TestWKWebView setEventTimestampOffset:]): (-[TestWKWebView eventTimestamp]): Add a mechanism to offset synthetic event timestamps by a given time interval (i.e. the event timestamp offset). (-[TestWKWebView mouseMoveToPoint:withFlags:]): (-[TestWKWebView _mouseEventWithType:atLocation:]): (-[TestWKWebView typeCharacter:]): * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: (-[DragAndDropSimulator runFrom:to:]): While simulating drag and drop on macOS, use `-setEventTimestampOffset:` to "leap forward" in time, so that the 150 millisecond delay when dragging a text selection doesn't prevent drags from beginning. Canonical link: https://commits.webkit.org/225531@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 19:41:50 +00:00
bool StaticPasteboard::hasNonDefaultData() const
{
return !m_nonDefaultDataTypes.isEmpty();
}
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
void StaticPasteboard::writeString(const String& type, const String& value)
{
dataTransfer.types is empty when handling the "dragstart" event https://bugs.webkit.org/show_bug.cgi?id=212685 <rdar://problem/61368402> Reviewed by Andy Estes. Source/WebCore: Implements several currently stubbed methods on StaticPasteboard, so that the DataTransfer provided to the page on the "dragstart" event contains the DOM-exposed data types that will be written to the system pasteboard. This includes "text/html", "text/plain", and "text/uri-list". Tests: DragAndDropTests.DataTransferTypesOnDragStartForTextSelection DragAndDropTests.DataTransferTypesOnDragStartForImage DragAndDropTests.DataTransferTypesOnDragStartForLink ...as well as several existing tests in DragAndDropTestsIOS.mm that attempt to set pasteboard data during the dragstart event: DragAndDropTests.DataTransferSanitizeHTML DragAndDropTests.DataTransferSetDataCannotWritePlatformTypes DragAndDropTests.DataTransferSetDataInvalidURL DragAndDropTests.DataTransferSetDataUnescapedURL DragAndDropTests.DataTransferSetDataValidURL * dom/DataTransfer.cpp: (WebCore::DataTransfer::commitToPasteboard): Only commit data to the native pasteboard if the page actually tried to write or modify the data. This allows us to preserve existing behavior by allowing DragController to write dragged data to the pasteboard normally in the case where the page didn't specify any custom data. In the case where the page does specify custom data, we will write this custom data *in addition* to any default data that was written to the static pasteboard. While this is a departure from our current behavior (which is to treat the pasteboard as a blank slate that contains only whatever custom data was provided by the page), it matches behavior in both Chrome and Firefox, and is likely more compatible with webpages that don't have UA-specific logic targeting WebKit. * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::writeSelectionToPasteboard): Avoid calling into the injected bundle (as well as writing a few particular non-web-exposed types, such as web archive data) in the case where we're writing to a static pasteboard (there's no point in doing this for the static pasteboard, and in the worst case, it could confuse some internal clients). * editing/ios/EditorIOS.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. * editing/mac/EditorMac.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. But additionally, introduce a markup string to PasteboardImage, so that we will expose the "text/html" type when starting a drag on an image element. * page/DragController.cpp: (WebCore::DragController::startDrag): Only attempt to call into `Pasteboard::writeTrustworthyWebURLsPboardType` in the case where the pasteboard supports this type (i.e. on macOS). This fixes an existing assertion that was hit by my new API test, which attempts to override the contents of the pasteboard with custom data while starting a drag on a link. * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): Since the StaticPasteboard contains data before the page has written anything, don't use `Pasteboard::hasData()` to determine whether there's custom data; instead, use the new `hasNonDefaultData()` method on `StaticPasteboard` (see below). * platform/Pasteboard.cpp: (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): On non-macOS ports, return false. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::hasNonDefaultData const): Keep track of whether the page attempted to stage any custom data during "dragstart" by maintaining the set of types written by the page, via calls to `writeString()` and similar. I'm using a set of types here instead of a simple `bool` flag to ensure correctness in the case where the page adds a type, and then later removes that same custom type, such that there is no longer non-default data. (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::writeData): (WebCore::StaticPasteboard::writeStringInCustomData): (WebCore::StaticPasteboard::clear): See above. (WebCore::StaticPasteboard::writeMarkup): (WebCore::StaticPasteboard::writePlainText): (WebCore::StaticPasteboard::write): Implement these methods by writing to the `PasteboardCustomData`. These methods are invoked by our own code rather than the bindings, and should only be used to stage default data types when starting a drag. * platform/StaticPasteboard.h: * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::write): (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): Tools: Adds new API tests and test infrastructure to verify that DataTransfer types and data are accessible during the "dragstart" event. See below for more details. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: (-[TestWKWebView selectElementWithID:]): (-[DragAndDropSimulator dragFromElementWithID:to:]): Add a few (very specialized) helper methods to assist with simulating drags over the various elements in the new drag and drop test harness page below (dragstart-data.html). (runDragStartDataTestCase): Test the following scenarios (split between three API tests) by dumping the resulting DataTransfer types and their data strings, and observing the results: - Dragging a normal text selection. - Dragging a normal text selection, and then adding a URL string. - Dragging a normal text selection, and then adding a custom pasteboard type. - Dragging a normal text selection, but then replacing the data with just a URL string. - Dragging a normal text selection, but then replacing the data with just a custom data type. - Dragging an image element. - Dragging an image element, and then overriding the plain text data. - Dragging a link (anchor element). - Dragging a link, and then adding a custom type. * TestWebKitAPI/Tests/WebKitCocoa/dragstart-data.html: Added. Add a new test harness to help test DataTransfer types when starting a drag. This test page can also be used as a manual test harness, by simply opening the test page, starting drags on the various elements and observing the output in the textarea. * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Tweak this test page to replace the DataTransfer with custom data (rather than simply append it) by calling `DataTransfer.clearData()` prior to writing the custom types. * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebViewHostWindow initWithWebView:contentRect:styleMask:backing:defer:]): Add a `__weak` reference on TestWKWebViewHostWindow back to the TestWKWebView, so that we can consult `-eventTimestamp` when synthesizing mouse events on macOS during API tests. (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:]): (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:]): (-[TestWKWebViewHostWindow initWithWebView:frame:]): (-[TestWKWebView _setUpTestWindow:]): (-[TestWKWebView setEventTimestampOffset:]): (-[TestWKWebView eventTimestamp]): Add a mechanism to offset synthetic event timestamps by a given time interval (i.e. the event timestamp offset). (-[TestWKWebView mouseMoveToPoint:withFlags:]): (-[TestWKWebView _mouseEventWithType:atLocation:]): (-[TestWKWebView typeCharacter:]): * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: (-[DragAndDropSimulator runFrom:to:]): While simulating drag and drop on macOS, use `-setEventTimestampOffset:` to "leap forward" in time, so that the 150 millisecond delay when dragging a text selection doesn't prevent drags from beginning. Canonical link: https://commits.webkit.org/225531@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 19:41:50 +00:00
m_nonDefaultDataTypes.add(type);
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
m_customData.writeString(type, value);
}
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
void StaticPasteboard::writeData(const String& type, Ref<SharedBuffer>&& data)
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
{
dataTransfer.types is empty when handling the "dragstart" event https://bugs.webkit.org/show_bug.cgi?id=212685 <rdar://problem/61368402> Reviewed by Andy Estes. Source/WebCore: Implements several currently stubbed methods on StaticPasteboard, so that the DataTransfer provided to the page on the "dragstart" event contains the DOM-exposed data types that will be written to the system pasteboard. This includes "text/html", "text/plain", and "text/uri-list". Tests: DragAndDropTests.DataTransferTypesOnDragStartForTextSelection DragAndDropTests.DataTransferTypesOnDragStartForImage DragAndDropTests.DataTransferTypesOnDragStartForLink ...as well as several existing tests in DragAndDropTestsIOS.mm that attempt to set pasteboard data during the dragstart event: DragAndDropTests.DataTransferSanitizeHTML DragAndDropTests.DataTransferSetDataCannotWritePlatformTypes DragAndDropTests.DataTransferSetDataInvalidURL DragAndDropTests.DataTransferSetDataUnescapedURL DragAndDropTests.DataTransferSetDataValidURL * dom/DataTransfer.cpp: (WebCore::DataTransfer::commitToPasteboard): Only commit data to the native pasteboard if the page actually tried to write or modify the data. This allows us to preserve existing behavior by allowing DragController to write dragged data to the pasteboard normally in the case where the page didn't specify any custom data. In the case where the page does specify custom data, we will write this custom data *in addition* to any default data that was written to the static pasteboard. While this is a departure from our current behavior (which is to treat the pasteboard as a blank slate that contains only whatever custom data was provided by the page), it matches behavior in both Chrome and Firefox, and is likely more compatible with webpages that don't have UA-specific logic targeting WebKit. * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::writeSelectionToPasteboard): Avoid calling into the injected bundle (as well as writing a few particular non-web-exposed types, such as web archive data) in the case where we're writing to a static pasteboard (there's no point in doing this for the static pasteboard, and in the worst case, it could confuse some internal clients). * editing/ios/EditorIOS.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. * editing/mac/EditorMac.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. But additionally, introduce a markup string to PasteboardImage, so that we will expose the "text/html" type when starting a drag on an image element. * page/DragController.cpp: (WebCore::DragController::startDrag): Only attempt to call into `Pasteboard::writeTrustworthyWebURLsPboardType` in the case where the pasteboard supports this type (i.e. on macOS). This fixes an existing assertion that was hit by my new API test, which attempts to override the contents of the pasteboard with custom data while starting a drag on a link. * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): Since the StaticPasteboard contains data before the page has written anything, don't use `Pasteboard::hasData()` to determine whether there's custom data; instead, use the new `hasNonDefaultData()` method on `StaticPasteboard` (see below). * platform/Pasteboard.cpp: (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): On non-macOS ports, return false. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::hasNonDefaultData const): Keep track of whether the page attempted to stage any custom data during "dragstart" by maintaining the set of types written by the page, via calls to `writeString()` and similar. I'm using a set of types here instead of a simple `bool` flag to ensure correctness in the case where the page adds a type, and then later removes that same custom type, such that there is no longer non-default data. (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::writeData): (WebCore::StaticPasteboard::writeStringInCustomData): (WebCore::StaticPasteboard::clear): See above. (WebCore::StaticPasteboard::writeMarkup): (WebCore::StaticPasteboard::writePlainText): (WebCore::StaticPasteboard::write): Implement these methods by writing to the `PasteboardCustomData`. These methods are invoked by our own code rather than the bindings, and should only be used to stage default data types when starting a drag. * platform/StaticPasteboard.h: * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::write): (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): Tools: Adds new API tests and test infrastructure to verify that DataTransfer types and data are accessible during the "dragstart" event. See below for more details. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: (-[TestWKWebView selectElementWithID:]): (-[DragAndDropSimulator dragFromElementWithID:to:]): Add a few (very specialized) helper methods to assist with simulating drags over the various elements in the new drag and drop test harness page below (dragstart-data.html). (runDragStartDataTestCase): Test the following scenarios (split between three API tests) by dumping the resulting DataTransfer types and their data strings, and observing the results: - Dragging a normal text selection. - Dragging a normal text selection, and then adding a URL string. - Dragging a normal text selection, and then adding a custom pasteboard type. - Dragging a normal text selection, but then replacing the data with just a URL string. - Dragging a normal text selection, but then replacing the data with just a custom data type. - Dragging an image element. - Dragging an image element, and then overriding the plain text data. - Dragging a link (anchor element). - Dragging a link, and then adding a custom type. * TestWebKitAPI/Tests/WebKitCocoa/dragstart-data.html: Added. Add a new test harness to help test DataTransfer types when starting a drag. This test page can also be used as a manual test harness, by simply opening the test page, starting drags on the various elements and observing the output in the textarea. * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Tweak this test page to replace the DataTransfer with custom data (rather than simply append it) by calling `DataTransfer.clearData()` prior to writing the custom types. * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebViewHostWindow initWithWebView:contentRect:styleMask:backing:defer:]): Add a `__weak` reference on TestWKWebViewHostWindow back to the TestWKWebView, so that we can consult `-eventTimestamp` when synthesizing mouse events on macOS during API tests. (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:]): (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:]): (-[TestWKWebViewHostWindow initWithWebView:frame:]): (-[TestWKWebView _setUpTestWindow:]): (-[TestWKWebView setEventTimestampOffset:]): (-[TestWKWebView eventTimestamp]): Add a mechanism to offset synthetic event timestamps by a given time interval (i.e. the event timestamp offset). (-[TestWKWebView mouseMoveToPoint:withFlags:]): (-[TestWKWebView _mouseEventWithType:atLocation:]): (-[TestWKWebView typeCharacter:]): * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: (-[DragAndDropSimulator runFrom:to:]): While simulating drag and drop on macOS, use `-setEventTimestampOffset:` to "leap forward" in time, so that the 150 millisecond delay when dragging a text selection doesn't prevent drags from beginning. Canonical link: https://commits.webkit.org/225531@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 19:41:50 +00:00
m_nonDefaultDataTypes.add(type);
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
m_customData.writeData(type, WTFMove(data));
}
void StaticPasteboard::writeStringInCustomData(const String& type, const String& value)
{
dataTransfer.types is empty when handling the "dragstart" event https://bugs.webkit.org/show_bug.cgi?id=212685 <rdar://problem/61368402> Reviewed by Andy Estes. Source/WebCore: Implements several currently stubbed methods on StaticPasteboard, so that the DataTransfer provided to the page on the "dragstart" event contains the DOM-exposed data types that will be written to the system pasteboard. This includes "text/html", "text/plain", and "text/uri-list". Tests: DragAndDropTests.DataTransferTypesOnDragStartForTextSelection DragAndDropTests.DataTransferTypesOnDragStartForImage DragAndDropTests.DataTransferTypesOnDragStartForLink ...as well as several existing tests in DragAndDropTestsIOS.mm that attempt to set pasteboard data during the dragstart event: DragAndDropTests.DataTransferSanitizeHTML DragAndDropTests.DataTransferSetDataCannotWritePlatformTypes DragAndDropTests.DataTransferSetDataInvalidURL DragAndDropTests.DataTransferSetDataUnescapedURL DragAndDropTests.DataTransferSetDataValidURL * dom/DataTransfer.cpp: (WebCore::DataTransfer::commitToPasteboard): Only commit data to the native pasteboard if the page actually tried to write or modify the data. This allows us to preserve existing behavior by allowing DragController to write dragged data to the pasteboard normally in the case where the page didn't specify any custom data. In the case where the page does specify custom data, we will write this custom data *in addition* to any default data that was written to the static pasteboard. While this is a departure from our current behavior (which is to treat the pasteboard as a blank slate that contains only whatever custom data was provided by the page), it matches behavior in both Chrome and Firefox, and is likely more compatible with webpages that don't have UA-specific logic targeting WebKit. * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::writeSelectionToPasteboard): Avoid calling into the injected bundle (as well as writing a few particular non-web-exposed types, such as web archive data) in the case where we're writing to a static pasteboard (there's no point in doing this for the static pasteboard, and in the worst case, it could confuse some internal clients). * editing/ios/EditorIOS.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. * editing/mac/EditorMac.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. But additionally, introduce a markup string to PasteboardImage, so that we will expose the "text/html" type when starting a drag on an image element. * page/DragController.cpp: (WebCore::DragController::startDrag): Only attempt to call into `Pasteboard::writeTrustworthyWebURLsPboardType` in the case where the pasteboard supports this type (i.e. on macOS). This fixes an existing assertion that was hit by my new API test, which attempts to override the contents of the pasteboard with custom data while starting a drag on a link. * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): Since the StaticPasteboard contains data before the page has written anything, don't use `Pasteboard::hasData()` to determine whether there's custom data; instead, use the new `hasNonDefaultData()` method on `StaticPasteboard` (see below). * platform/Pasteboard.cpp: (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): On non-macOS ports, return false. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::hasNonDefaultData const): Keep track of whether the page attempted to stage any custom data during "dragstart" by maintaining the set of types written by the page, via calls to `writeString()` and similar. I'm using a set of types here instead of a simple `bool` flag to ensure correctness in the case where the page adds a type, and then later removes that same custom type, such that there is no longer non-default data. (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::writeData): (WebCore::StaticPasteboard::writeStringInCustomData): (WebCore::StaticPasteboard::clear): See above. (WebCore::StaticPasteboard::writeMarkup): (WebCore::StaticPasteboard::writePlainText): (WebCore::StaticPasteboard::write): Implement these methods by writing to the `PasteboardCustomData`. These methods are invoked by our own code rather than the bindings, and should only be used to stage default data types when starting a drag. * platform/StaticPasteboard.h: * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::write): (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): Tools: Adds new API tests and test infrastructure to verify that DataTransfer types and data are accessible during the "dragstart" event. See below for more details. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: (-[TestWKWebView selectElementWithID:]): (-[DragAndDropSimulator dragFromElementWithID:to:]): Add a few (very specialized) helper methods to assist with simulating drags over the various elements in the new drag and drop test harness page below (dragstart-data.html). (runDragStartDataTestCase): Test the following scenarios (split between three API tests) by dumping the resulting DataTransfer types and their data strings, and observing the results: - Dragging a normal text selection. - Dragging a normal text selection, and then adding a URL string. - Dragging a normal text selection, and then adding a custom pasteboard type. - Dragging a normal text selection, but then replacing the data with just a URL string. - Dragging a normal text selection, but then replacing the data with just a custom data type. - Dragging an image element. - Dragging an image element, and then overriding the plain text data. - Dragging a link (anchor element). - Dragging a link, and then adding a custom type. * TestWebKitAPI/Tests/WebKitCocoa/dragstart-data.html: Added. Add a new test harness to help test DataTransfer types when starting a drag. This test page can also be used as a manual test harness, by simply opening the test page, starting drags on the various elements and observing the output in the textarea. * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Tweak this test page to replace the DataTransfer with custom data (rather than simply append it) by calling `DataTransfer.clearData()` prior to writing the custom types. * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebViewHostWindow initWithWebView:contentRect:styleMask:backing:defer:]): Add a `__weak` reference on TestWKWebViewHostWindow back to the TestWKWebView, so that we can consult `-eventTimestamp` when synthesizing mouse events on macOS during API tests. (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:]): (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:]): (-[TestWKWebViewHostWindow initWithWebView:frame:]): (-[TestWKWebView _setUpTestWindow:]): (-[TestWKWebView setEventTimestampOffset:]): (-[TestWKWebView eventTimestamp]): Add a mechanism to offset synthetic event timestamps by a given time interval (i.e. the event timestamp offset). (-[TestWKWebView mouseMoveToPoint:withFlags:]): (-[TestWKWebView _mouseEventWithType:atLocation:]): (-[TestWKWebView typeCharacter:]): * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: (-[DragAndDropSimulator runFrom:to:]): While simulating drag and drop on macOS, use `-setEventTimestampOffset:` to "leap forward" in time, so that the 150 millisecond delay when dragging a text selection doesn't prevent drags from beginning. Canonical link: https://commits.webkit.org/225531@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 19:41:50 +00:00
m_nonDefaultDataTypes.add(type);
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
m_customData.writeStringInCustomData(type, value);
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
}
On iOS, getData can't get text set by setData during copy event https://bugs.webkit.org/show_bug.cgi?id=176980 <rdar://problem/34453915> Reviewed by Darin Adler. Source/WebCore: The bug was caused by iOS port not implementing Pasteboard::createPrivate(). Rather than implementing this in iOS, replace its use for copy & paste events by StaticPasteboard Wenson added for input events. This makes read-write pasteboard platform agnostic and paves the way to make writing to pasteboard in a single IPC in WebKit2. Also fixed a bug that iOS port's Pasteboard::types returned the list of all supported types instead of ones actually present in the pasteboard. This patch also adds a vector of types to StaticPasteboard to maintain the type order. Tests: editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html editing/pasteboard/dataTransfer-types-pasting-plaintext.html * dom/DataTransfer.cpp: (WebCore::DataTransfer::createForCopyAndPaste): Make StaticPasteboard instead of a private pasteboard. (WebCore::DataTransfer::createForInputEvent): * editing/Editor.cpp: (WebCore::dispatchClipboardEvent): Call newly added commitToPasteboard on StaticPasteboard. * platform/Pasteboard.h: (WebCore::Pasteboard::isStatic const): * platform/PasteboardStrategy.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::create): Deleted. (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): Deleted. Now simply returns m_type. (WebCore::StaticPasteboard::readString): Added. (WebCore::StaticPasteboard::writeString): Added. (WebCore::StaticPasteboard::clear): Added. (WebCore::StaticPasteboard::commitToPasteboard): Added. (isType): Added. * platform/StaticPasteboard.h: (WebCore::Pasteboard::isStatic const): Added. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. (WebCore::addHTMLClipboardTypesForCocoaType): (WebCore::Pasteboard::types): Return the actual list of types in the pasteboard. * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. Source/WebKit: * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: (WebKit::WebPlatformStrategies::copy): Deleted. * WebProcess/WebCoreSupport/WebPlatformStrategies.h: Source/WebKitLegacy/mac: * WebCoreSupport/WebPlatformStrategies.h: * WebCoreSupport/WebPlatformStrategies.mm: (WebPlatformStrategies::copy): Deleted. LayoutTests: Added regression tests to make sure dataTransfer.types returns an empty list when writing to a pasteboard (copy), and doesn't contain image types when pasting plain text. Unfortunately, pasting image does result in plain text content being present in the pasteboard in the form of URL so we can't test that scenario. Also removed failing expectations from a number of tests that are now passing on iOS. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy-expected.txt: Added. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext-expected.txt: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext.html: Added. * platform/ios/TestExpectations: Canonical link: https://commits.webkit.org/193550@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222228 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-19 21:50:03 +00:00
void StaticPasteboard::clear()
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
{
dataTransfer.types is empty when handling the "dragstart" event https://bugs.webkit.org/show_bug.cgi?id=212685 <rdar://problem/61368402> Reviewed by Andy Estes. Source/WebCore: Implements several currently stubbed methods on StaticPasteboard, so that the DataTransfer provided to the page on the "dragstart" event contains the DOM-exposed data types that will be written to the system pasteboard. This includes "text/html", "text/plain", and "text/uri-list". Tests: DragAndDropTests.DataTransferTypesOnDragStartForTextSelection DragAndDropTests.DataTransferTypesOnDragStartForImage DragAndDropTests.DataTransferTypesOnDragStartForLink ...as well as several existing tests in DragAndDropTestsIOS.mm that attempt to set pasteboard data during the dragstart event: DragAndDropTests.DataTransferSanitizeHTML DragAndDropTests.DataTransferSetDataCannotWritePlatformTypes DragAndDropTests.DataTransferSetDataInvalidURL DragAndDropTests.DataTransferSetDataUnescapedURL DragAndDropTests.DataTransferSetDataValidURL * dom/DataTransfer.cpp: (WebCore::DataTransfer::commitToPasteboard): Only commit data to the native pasteboard if the page actually tried to write or modify the data. This allows us to preserve existing behavior by allowing DragController to write dragged data to the pasteboard normally in the case where the page didn't specify any custom data. In the case where the page does specify custom data, we will write this custom data *in addition* to any default data that was written to the static pasteboard. While this is a departure from our current behavior (which is to treat the pasteboard as a blank slate that contains only whatever custom data was provided by the page), it matches behavior in both Chrome and Firefox, and is likely more compatible with webpages that don't have UA-specific logic targeting WebKit. * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::writeSelectionToPasteboard): Avoid calling into the injected bundle (as well as writing a few particular non-web-exposed types, such as web archive data) in the case where we're writing to a static pasteboard (there's no point in doing this for the static pasteboard, and in the worst case, it could confuse some internal clients). * editing/ios/EditorIOS.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. * editing/mac/EditorMac.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. But additionally, introduce a markup string to PasteboardImage, so that we will expose the "text/html" type when starting a drag on an image element. * page/DragController.cpp: (WebCore::DragController::startDrag): Only attempt to call into `Pasteboard::writeTrustworthyWebURLsPboardType` in the case where the pasteboard supports this type (i.e. on macOS). This fixes an existing assertion that was hit by my new API test, which attempts to override the contents of the pasteboard with custom data while starting a drag on a link. * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): Since the StaticPasteboard contains data before the page has written anything, don't use `Pasteboard::hasData()` to determine whether there's custom data; instead, use the new `hasNonDefaultData()` method on `StaticPasteboard` (see below). * platform/Pasteboard.cpp: (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): On non-macOS ports, return false. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::hasNonDefaultData const): Keep track of whether the page attempted to stage any custom data during "dragstart" by maintaining the set of types written by the page, via calls to `writeString()` and similar. I'm using a set of types here instead of a simple `bool` flag to ensure correctness in the case where the page adds a type, and then later removes that same custom type, such that there is no longer non-default data. (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::writeData): (WebCore::StaticPasteboard::writeStringInCustomData): (WebCore::StaticPasteboard::clear): See above. (WebCore::StaticPasteboard::writeMarkup): (WebCore::StaticPasteboard::writePlainText): (WebCore::StaticPasteboard::write): Implement these methods by writing to the `PasteboardCustomData`. These methods are invoked by our own code rather than the bindings, and should only be used to stage default data types when starting a drag. * platform/StaticPasteboard.h: * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::write): (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): Tools: Adds new API tests and test infrastructure to verify that DataTransfer types and data are accessible during the "dragstart" event. See below for more details. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: (-[TestWKWebView selectElementWithID:]): (-[DragAndDropSimulator dragFromElementWithID:to:]): Add a few (very specialized) helper methods to assist with simulating drags over the various elements in the new drag and drop test harness page below (dragstart-data.html). (runDragStartDataTestCase): Test the following scenarios (split between three API tests) by dumping the resulting DataTransfer types and their data strings, and observing the results: - Dragging a normal text selection. - Dragging a normal text selection, and then adding a URL string. - Dragging a normal text selection, and then adding a custom pasteboard type. - Dragging a normal text selection, but then replacing the data with just a URL string. - Dragging a normal text selection, but then replacing the data with just a custom data type. - Dragging an image element. - Dragging an image element, and then overriding the plain text data. - Dragging a link (anchor element). - Dragging a link, and then adding a custom type. * TestWebKitAPI/Tests/WebKitCocoa/dragstart-data.html: Added. Add a new test harness to help test DataTransfer types when starting a drag. This test page can also be used as a manual test harness, by simply opening the test page, starting drags on the various elements and observing the output in the textarea. * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Tweak this test page to replace the DataTransfer with custom data (rather than simply append it) by calling `DataTransfer.clearData()` prior to writing the custom types. * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebViewHostWindow initWithWebView:contentRect:styleMask:backing:defer:]): Add a `__weak` reference on TestWKWebViewHostWindow back to the TestWKWebView, so that we can consult `-eventTimestamp` when synthesizing mouse events on macOS during API tests. (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:]): (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:]): (-[TestWKWebViewHostWindow initWithWebView:frame:]): (-[TestWKWebView _setUpTestWindow:]): (-[TestWKWebView setEventTimestampOffset:]): (-[TestWKWebView eventTimestamp]): Add a mechanism to offset synthetic event timestamps by a given time interval (i.e. the event timestamp offset). (-[TestWKWebView mouseMoveToPoint:withFlags:]): (-[TestWKWebView _mouseEventWithType:atLocation:]): (-[TestWKWebView typeCharacter:]): * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: (-[DragAndDropSimulator runFrom:to:]): While simulating drag and drop on macOS, use `-setEventTimestampOffset:` to "leap forward" in time, so that the 150 millisecond delay when dragging a text selection doesn't prevent drags from beginning. Canonical link: https://commits.webkit.org/225531@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 19:41:50 +00:00
m_nonDefaultDataTypes.clear();
m_fileContentState = Pasteboard::FileContentState::NoFileOrImageData;
Drag event DataTransfer has unexpected types "dyn.ah62d4..." https://bugs.webkit.org/show_bug.cgi?id=172526 <rdar://problem/32396081> Reviewed by Ryosuke Niwa. Source/WebCore: Currently, the pasteboard types we expose to web content are simply the types that appear on the platform pasteboard (i.e. the general NSPasteboard on Mac, and either the general UIPasteboard or a UIDragSession's NSItemProviders on iOS). This leads to DataTransfer.types exposing many private pasteboard types written by apps around the system to the page, such as dynamic UTIs, CorePasteboardFlavorTypes, or the "Apple WebKit dummy pasteboard type". These are not only confusing and not useful for web content (since they mostly hold values of empty string anyways), but can additionally pose privacy concerns by exposing information meant only for native applications to unvetted web content. To address this problem, other browsers (e.g. Chrome and Firefox on Mac) white-list MIME types in DataTransfer's list of types. By default, when dragging or copying, these are "text/plain", "text/html" and "text/uri-list". However, this policy alone is insufficient, because the page may also supply its own types, in which case our naive whitelist would prevent us from delivering them to the page. To address this additional constraint, both Chrome and Firefox write any custom data supplied by the page to custom pasteboard UTIs (org.chromium.drag-dummy-type and org.mozilla.custom-clipdata, respectively). The corresponding data is a map of custom UTI => custom data supplied by the page; upon drop or paste, this mapping is consulted if the page calls getData() with a custom UTI. This patch adopts this same approach in WebKit, and introduces the com.apple.WebKit.custom-pasteboard-data UTI (refer to per-method comments below for more information). These changes are covered by 18 new layout and API tests, as well as existing drag-and-drop tests. Tests: editing/pasteboard/data-transfer-get-data-on-drop-custom.html editing/pasteboard/data-transfer-get-data-on-drop-plain-text.html editing/pasteboard/data-transfer-get-data-on-drop-rich-text.html editing/pasteboard/data-transfer-get-data-on-drop-url.html editing/pasteboard/data-transfer-get-data-on-paste-custom.html editing/pasteboard/data-transfer-get-data-on-paste-plain-text.html editing/pasteboard/data-transfer-get-data-on-paste-rich-text.html DataInteractionTests.DataTransferGetDataWhenDroppingPlainText DataInteractionTests.DataTransferGetDataWhenDroppingCustomData DataInteractionTests.DataTransferGetDataWhenDroppingURL DataInteractionTests.DataTransferGetDataWhenDroppingImageWithFileURL DataInteractionTests.DataTransferGetDataWhenDroppingRespectsPresentationStyle DataInteractionTests.DataTransferSetDataCannotWritePlatformTypes DataInteractionTests.DataTransferGetDataCannotReadPrivatePlatformTypes UIPasteboardTests.DataTransferGetDataWhenPastingURL UIPasteboardTests.DataTransferGetDataWhenPastingPlatformRepresentations UIPasteboardTests.DataTransferSetDataCannotWritePlatformTypes UIPasteboardTests.DataTransferGetDataCannotReadPrivatePlatformTypes * CMakeLists.txt: Add Pasteboard.cpp to the WebCore CMakeList. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::getData const): (WebCore::DataTransfer::createForDragStartEvent): Make a new static helper function to create a StaticPasteboard-backed DataTransfer when dispatching a dragstart event. Any data supplied by the page will be written to the static pasteboard of this DataTransfer. (WebCore::DataTransfer::moveDragState): Add a new helper on DataTransfer to transfer the data required to initiate a drag from one DataTransfer to another. This is used in EventHandler to transfer the contents of the temporary DataTransfer modified by the page during the dragstart event over to the DataTransfer used for the rest of the drag initiation codepath, which is actually connected to the platform. This includes committing the contents of the other DataTransfer's StaticPasteboard to the new platform-connected Pasteboard. (WebCore::DataTransfer::hasDragImage const): * dom/DataTransfer.h: * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::selectionInHTMLFormat): (WebCore::Editor::writeSelectionToPasteboard): (WebCore::Editor::writeSelection): Write an additional HTML markup string on iOS. We already do this for Mac, but this data previously had no use on iOS. This is needed for to vend the "text/html" representation to the page on iOS when pasting. * editing/mac/EditorMac.mm: (WebCore::Editor::selectionInHTMLFormat): Deleted. * editing/wpe/EditorWPE.cpp: (WebCore::createFragmentFromPasteboardData): * page/EventHandler.cpp: (WebCore::EventHandler::dispatchDragStartEventOnSourceElement): Renamed from dispatchDragStartEvent to dispatchDragStartEventOnSourceElement. Additionally, simplified the logic significantly, so that we now just check to see if the StaticPasteboard exposed to the page has any data, instead of using platform-dependent logic to compare changeCounts. We can do this because StaticPasteboard is guaranteed to only contain content that the page has supplied during the dragstart event, since it is empty upon initialization and cannot be written to by the rest of the platform. (WebCore::EventHandler::handleDrag): Tweak dispatchDragStartEvent to take a DataTransfer to expose to bindings; at the call site in handleDrag, create a new DataTransfer backed by a StaticPasteboard that the page may mutate over the course of the dragstart event. After dispatching to the page, move the dragging information present on the drag start DataTransfer over to the DragState's DataTransfer. If the drag image has not been set, compute and set the default drag image element on the DragState's DataTransfer. (WebCore::EventHandler::dispatchDragStartEvent): Deleted. * page/EventHandler.h: * page/Settings.cpp: (WebCore::Settings::customPasteboardDataEnabled): * page/Settings.h: (WebCore::Settings::setCustomPasteboardDataEnabled): * page/ios/EventHandlerIOS.mm: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. * page/mac/EventHandlerMac.mm: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. * page/win/EventHandlerWin.cpp: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. Remove this helper on both iOS and Mac. This only called createForDrag() before, with the addition of clearing the platform pasteboard prior to returning. Now that a StaticPasteboard is used when starting a drag, we clear out the platform pasteboard in platform-invariant code in EventHandler::handleDrag, so these helpers are no longer useful. * platform/Pasteboard.cpp: Added. (WebCore::isSafeTypeForDOMToReadAndWrite): Add a new helper to determine whether or not a pasteboard type is one of the standard DOM-exposed types. These are "text/plain", "text/html" and "text/uri-list". (WebCore::sharedBufferFromCustomData): (WebCore::customDataFromSharedBuffer): Add helper methods to serialize and deserialize custom data. The serialized data blob consists of: (1) versioning information, (2) a dictionary mapping each custom type to a value, and (3) a full list of types written by the page, in the order they were written. * platform/Pasteboard.h: Rename Pasteboard::readString to Pasteboard::readStringForBindings, to reflect that the string being read and the given type are exposed to and from the DOM. * platform/PasteboardStrategy.h: * platform/PasteboardWriterData.h: * platform/PlatformPasteboard.h: * platform/StaticPasteboard.cpp: Split m_stringContents out into m_platformData and m_customData. The former contains type-to-data entries for the DOM-exposed types, while the second contains entries that don't belong in the former. (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::readStringForBindings): (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::clear): (WebCore::StaticPasteboard::commitToPasteboard): Rather than propagate each entry to the client layer one at a time, populate a new PasteboardCustomData struct and send it to the client layer in one go. This new struct consists of an array of types in the order they were written by the page, a dictionary of public types (types we want to write directly to the platform pasteboard) and private types (custom types we want to package under our custom data blob). (WebCore::StaticPasteboard::readString): Deleted. * platform/StaticPasteboard.h: * platform/glib/EventHandlerGLib.cpp: (WebCore::EventHandler::createDraggingDataTransfer const): Deleted. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::writeCustomData): (WebCore::Pasteboard::readString): Deleted. * platform/gtk/PlatformPasteboardGtk.cpp: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): (WebCore::PlatformPasteboard::write): Add stub implementations for new custom pasteboard data methods. * platform/ios/AbstractPasteboard.h: * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeCustomData): Add new plumbing to ship a custom data (PasteboardCustomData) struct from WebCore to the client layer. (WebCore::cocoaTypeFromHTMLClipboardType): (WebCore::readPlatformValueAsString): (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::types): Rewritten to ask the client layer for DOM-exposed types rather than all types, in the case where custom pasteboard data is enabled in Settings. (WebCore::Pasteboard::readString): Deleted. * platform/ios/PlatformPasteboardIOS.mm: (WebCore::PlatformPasteboard::bufferForType): (WebCore::PlatformPasteboard::getPathnamesForType const): (WebCore::PlatformPasteboard::numberOfFiles const): (WebCore::PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite): Add a new helper to map DOM-safe pasteboard types to their platform counterparts. (WebCore::PlatformPasteboard::write): (WebCore::safeTypeForDOMToReadAndWriteForPlatformType): Add a new helper to map platform pasteboard types to their DOM-safe counterparts. (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Fetch a list of DOM-exposed types. On iOS, for drag and drop, we have the additional constraint of not being able to read any data before the drop happens. This is problematic, since the page needs to know the list of types during 'dragover' events. To support this, we instead keep the array of types in the teamData property of the generated item provider, which is immediately available, even when dragging across different apps. Note that we still need to check if the pasteboard contains the full custom data blob here to handle the case where we copy on Mac and perform a continuity paste on iOS, since teamData does not exist on Mac. (WebCore::PlatformPasteboard::readString): Tweak to account for how UIPasteboard may return data blobs when reading values. (WebCore::PlatformPasteboard::getPathnamesForType): Deleted. (WebCore::PlatformPasteboard::numberOfFiles): Deleted. * platform/ios/WebItemProviderPasteboard.h: * platform/ios/WebItemProviderPasteboard.mm: (-[WebItemProviderRegistrationInfoList itemProvider]): (+[WebItemProviderLoadResult loadResultWithItemProvider:typesToLoad:]): (-[WebItemProviderLoadResult initWithItemProvider:typesToLoad:]): (-[WebItemProviderLoadResult typesToLoad]): (-[WebItemProviderLoadResult setFileURL:forType:]): (-[WebItemProviderLoadResult itemProvider]): (-[WebItemProviderPasteboard setItemProviders:]): (-[WebItemProviderPasteboard dataForPasteboardType:]): (-[WebItemProviderPasteboard typeIdentifiersToLoadForRegisteredTypeIdentfiers:]): (-[WebItemProviderPasteboard doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout:]): (+[WebItemProviderLoadResult emptyLoadResult]): Deleted. (+[WebItemProviderLoadResult loadResultWithFileURLMap:presentationStyle:]): Deleted. (-[WebItemProviderLoadResult initWithFileURLMap:presentationStyle:]): Deleted. (-[WebItemProviderPasteboard typeIdentifierToLoadForRegisteredTypeIdentfiers:]): Deleted. In the case of drag and drop on iOS, we cannot load any data prior to performing the drop; additionally, any attempts to load data immediately after the drop is performed in the UI process will fail. This means any and all data that the web process may require in the future when handling the drop must be loaded out of the item providers and saved when the drop is being handled in the UI process. Currently, we only load the highest fidelity type we can handle (or, if we don't know what we can handle, we select the highest fidelity representation conforming to "public.content"). This is a problematic for supporting DataTransfer.getData() on drop on iOS, because the page can ask for any of the three web-exposed types. To address this, we refactor WebItemProviderPasteboard to support loading multiple representations per item being dropped. At minimum, we will load anything conforming to "public.html", "public.plain-text", "public.url", and the new "com.apple.WebKit.custom-pasteboard-data" so we have means to answer any question that the page could ask via DataTransfer.getData(). We additonally load the highest fidelity supported (or content-conformant) type, if it has not already been loaded as a result of the former. To make this possible, we refactor WebItemProviderLoadResult to take an item provider and a list of types to load. -doAfterLoadingProvidedContentIntoFileURLs:synchronousTimeout: then creates a list of load results and uses each one to represent the results of loading data from its item provider (i.e. a map of UTI => file URL). * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::writeCustomData): (WebCore::cocoaTypeFromHTMLClipboardType): (WebCore::readPlatformValueAsString): (WebCore::Pasteboard::readStringForBindings): Change readStringForBindings (formerly, readString) so that if support for custom pasteboard data is enabled, we only allow reading directly from the platform pasteboard if the given type is DOM-safe; otherwise, we consult the custom data blob, if it exists. Otherwise, if support for custom pasteboard data is disabled, we fall back to our current behavior. (WebCore::Pasteboard::types): (WebCore::Pasteboard::readString): Deleted. * platform/mac/PlatformPasteboardMac.mm: (WebCore::PlatformPasteboard::numberOfFiles const): (WebCore::PlatformPasteboard::getPathnamesForType const): (WebCore::PlatformPasteboard::stringForType): (WebCore::safeTypeForDOMToReadAndWriteForPlatformType): (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Add support for reading DOM-exposed types and fetching DOM-exposed data off of the pasteboard. The overall idea here is similar to iOS, though implementation details vary (e.g. no item provider support). (WebCore::PlatformPasteboard::write): (WebCore::PlatformPasteboard::platformPasteboardTypeForSafeTypeForDOMToReadAndWrite): (WebCore::PlatformPasteboard::numberOfFiles): Deleted. (WebCore::PlatformPasteboard::getPathnamesForType): Deleted. * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::writeCustomData): (WebCore::Pasteboard::readString): Deleted. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::readStringForBindings): (WebCore::Pasteboard::writeCustomData): (WebCore::Pasteboard::readString): Deleted. * platform/wpe/PlatformPasteboardWPE.cpp: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): (WebCore::PlatformPasteboard::write): * testing/InternalSettings.cpp: (WebCore::InternalSettings::Backup::Backup): (WebCore::InternalSettings::Backup::restoreTo): (WebCore::InternalSettings::setCustomPasteboardDataEnabled): Add a new internal settings hook for layout tests to opt in to using custom pasteboard data. By default, custom pasteboard data is enabled only in Safari, or on applications linked on or after certain releases of iOS and macOS. * testing/InternalSettings.h: * testing/InternalSettings.idl: Source/WebKit: Add boilerplate plumbing and encoder/decoder support for new pasteboard codepaths. See WebCore ChangeLog for more details. * Scripts/webkit/messages.py: (headers_for_type): * Shared/WebCoreArgumentCoders.cpp: (IPC::ArgumentCoder<PasteboardCustomData>::encode): (IPC::ArgumentCoder<PasteboardCustomData>::decode): Add encoder/decoder support for PasteboardCustomData. (IPC::ArgumentCoder<PasteboardWebContent>::encode): (IPC::ArgumentCoder<PasteboardWebContent>::decode): Encode and decode dataInHTMLFormat. * Shared/WebCoreArgumentCoders.h: * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm: (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite): (WebKit::WebPasteboardProxy::writeCustomData): * UIProcess/WebPasteboardProxy.cpp: (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite): (WebKit::WebPasteboardProxy::writeCustomData): * UIProcess/WebPasteboardProxy.h: * UIProcess/WebPasteboardProxy.messages.in: * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: (WebKit::WebPlatformStrategies::typesSafeForDOMToReadAndWrite): (WebKit::WebPlatformStrategies::writeCustomData): * WebProcess/WebCoreSupport/WebPlatformStrategies.h: Source/WebKitLegacy/mac: Adjust for changes in WebCore. See WebCore ChangeLog for more details. * WebCoreSupport/WebPlatformStrategies.h: * WebCoreSupport/WebPlatformStrategies.mm: (WebPlatformStrategies::webExposedTypes): (WebPlatformStrategies::writeCustomData): Tools: Adds new API tests on iOS to cover various cases of using DataTransfer.setData, DataTransfer.getData, and DataTransfer.types, as well as their interaction with platform objects (source NSItemProviders in the case of drag and drop, and the general UIPasteboard for copy and paste). * TestWebKitAPI/PlatformUtilities.h: * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Added. Introduce a new API test harness that both drag-and-drop and copy-and-paste tests use to dump DataTransfer's web-exposed types and values. * TestWebKitAPI/Tests/ios/DataInteractionTests.mm: (checkFirstTypeIsPresentAndSecondTypeIsMissing): (checkJSONWithLogging): (TestWebKitAPI::TEST): (checkTypeIdentifierAndIsNotOtherTypeIdentifier): Deleted. * TestWebKitAPI/Tests/ios/UIPasteboardTests.mm: (TestWebKitAPI::checkJSONWithLogging): (TestWebKitAPI::setUpWebViewForPasteboardTests): (TestWebKitAPI::TEST): * TestWebKitAPI/cocoa/PlatformUtilitiesCocoa.mm: (TestWebKitAPI::Util::jsonMatchesExpectedValues): LayoutTests: Add new layout tests on Mac and iOS to test various cases of using DataTransfer.setData, DataTransfer.getData, and DataTransfer.types for drag-and-drop (tests for Mac WK1 only) and copy-and-paste (all platforms). * TestExpectations: * editing/pasteboard/data-transfer-get-data-on-drop-custom-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-custom.html: Added. * editing/pasteboard/data-transfer-get-data-on-drop-plain-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-plain-text.html: Added. * editing/pasteboard/data-transfer-get-data-on-drop-rich-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-rich-text.html: Added. * editing/pasteboard/data-transfer-get-data-on-drop-url-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-drop-url.html: Added. * editing/pasteboard/data-transfer-get-data-on-paste-custom-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-paste-custom.html: Added. * editing/pasteboard/data-transfer-get-data-on-paste-plain-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-paste-plain-text.html: Added. * editing/pasteboard/data-transfer-get-data-on-paste-rich-text-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-paste-rich-text.html: Added. * platform/ios-simulator-wk1/TestExpectations: Mark new copy and paste tests as [ Pass ], since editing/pasteboard/ is skipped by default for iOS WK1. * platform/ios-wk1/editing/pasteboard/data-transfer-get-data-on-paste-rich-text-expected.txt: Added. * platform/ios-wk2/editing/pasteboard/data-transfer-get-data-on-paste-rich-text-expected.txt: Added. Add iOS-specific baselines. This is due to the generated HTML markup for "text/html" being slightly different when pasting. * platform/mac-wk1/TestExpectations: Canonical link: https://commits.webkit.org/193880@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222595 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-28 02:29:16 +00:00
m_customData.clear();
On iOS, getData can't get text set by setData during copy event https://bugs.webkit.org/show_bug.cgi?id=176980 <rdar://problem/34453915> Reviewed by Darin Adler. Source/WebCore: The bug was caused by iOS port not implementing Pasteboard::createPrivate(). Rather than implementing this in iOS, replace its use for copy & paste events by StaticPasteboard Wenson added for input events. This makes read-write pasteboard platform agnostic and paves the way to make writing to pasteboard in a single IPC in WebKit2. Also fixed a bug that iOS port's Pasteboard::types returned the list of all supported types instead of ones actually present in the pasteboard. This patch also adds a vector of types to StaticPasteboard to maintain the type order. Tests: editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html editing/pasteboard/dataTransfer-types-pasting-plaintext.html * dom/DataTransfer.cpp: (WebCore::DataTransfer::createForCopyAndPaste): Make StaticPasteboard instead of a private pasteboard. (WebCore::DataTransfer::createForInputEvent): * editing/Editor.cpp: (WebCore::dispatchClipboardEvent): Call newly added commitToPasteboard on StaticPasteboard. * platform/Pasteboard.h: (WebCore::Pasteboard::isStatic const): * platform/PasteboardStrategy.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::create): Deleted. (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): Deleted. Now simply returns m_type. (WebCore::StaticPasteboard::readString): Added. (WebCore::StaticPasteboard::writeString): Added. (WebCore::StaticPasteboard::clear): Added. (WebCore::StaticPasteboard::commitToPasteboard): Added. (isType): Added. * platform/StaticPasteboard.h: (WebCore::Pasteboard::isStatic const): Added. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. (WebCore::addHTMLClipboardTypesForCocoaType): (WebCore::Pasteboard::types): Return the actual list of types in the pasteboard. * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. Source/WebKit: * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: (WebKit::WebPlatformStrategies::copy): Deleted. * WebProcess/WebCoreSupport/WebPlatformStrategies.h: Source/WebKitLegacy/mac: * WebCoreSupport/WebPlatformStrategies.h: * WebCoreSupport/WebPlatformStrategies.mm: (WebPlatformStrategies::copy): Deleted. LayoutTests: Added regression tests to make sure dataTransfer.types returns an empty list when writing to a pasteboard (copy), and doesn't contain image types when pasting plain text. Unfortunately, pasting image does result in plain text content being present in the pasteboard in the form of URL so we can't test that scenario. Also removed failing expectations from a number of tests that are now passing on iOS. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy-expected.txt: Added. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext-expected.txt: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext.html: Added. * platform/ios/TestExpectations: Canonical link: https://commits.webkit.org/193550@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222228 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-19 21:50:03 +00:00
}
void StaticPasteboard::clear(const String& type)
{
dataTransfer.types is empty when handling the "dragstart" event https://bugs.webkit.org/show_bug.cgi?id=212685 <rdar://problem/61368402> Reviewed by Andy Estes. Source/WebCore: Implements several currently stubbed methods on StaticPasteboard, so that the DataTransfer provided to the page on the "dragstart" event contains the DOM-exposed data types that will be written to the system pasteboard. This includes "text/html", "text/plain", and "text/uri-list". Tests: DragAndDropTests.DataTransferTypesOnDragStartForTextSelection DragAndDropTests.DataTransferTypesOnDragStartForImage DragAndDropTests.DataTransferTypesOnDragStartForLink ...as well as several existing tests in DragAndDropTestsIOS.mm that attempt to set pasteboard data during the dragstart event: DragAndDropTests.DataTransferSanitizeHTML DragAndDropTests.DataTransferSetDataCannotWritePlatformTypes DragAndDropTests.DataTransferSetDataInvalidURL DragAndDropTests.DataTransferSetDataUnescapedURL DragAndDropTests.DataTransferSetDataValidURL * dom/DataTransfer.cpp: (WebCore::DataTransfer::commitToPasteboard): Only commit data to the native pasteboard if the page actually tried to write or modify the data. This allows us to preserve existing behavior by allowing DragController to write dragged data to the pasteboard normally in the case where the page didn't specify any custom data. In the case where the page does specify custom data, we will write this custom data *in addition* to any default data that was written to the static pasteboard. While this is a departure from our current behavior (which is to treat the pasteboard as a blank slate that contains only whatever custom data was provided by the page), it matches behavior in both Chrome and Firefox, and is likely more compatible with webpages that don't have UA-specific logic targeting WebKit. * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::writeSelectionToPasteboard): Avoid calling into the injected bundle (as well as writing a few particular non-web-exposed types, such as web archive data) in the case where we're writing to a static pasteboard (there's no point in doing this for the static pasteboard, and in the worst case, it could confuse some internal clients). * editing/ios/EditorIOS.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. * editing/mac/EditorMac.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. But additionally, introduce a markup string to PasteboardImage, so that we will expose the "text/html" type when starting a drag on an image element. * page/DragController.cpp: (WebCore::DragController::startDrag): Only attempt to call into `Pasteboard::writeTrustworthyWebURLsPboardType` in the case where the pasteboard supports this type (i.e. on macOS). This fixes an existing assertion that was hit by my new API test, which attempts to override the contents of the pasteboard with custom data while starting a drag on a link. * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): Since the StaticPasteboard contains data before the page has written anything, don't use `Pasteboard::hasData()` to determine whether there's custom data; instead, use the new `hasNonDefaultData()` method on `StaticPasteboard` (see below). * platform/Pasteboard.cpp: (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): On non-macOS ports, return false. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::hasNonDefaultData const): Keep track of whether the page attempted to stage any custom data during "dragstart" by maintaining the set of types written by the page, via calls to `writeString()` and similar. I'm using a set of types here instead of a simple `bool` flag to ensure correctness in the case where the page adds a type, and then later removes that same custom type, such that there is no longer non-default data. (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::writeData): (WebCore::StaticPasteboard::writeStringInCustomData): (WebCore::StaticPasteboard::clear): See above. (WebCore::StaticPasteboard::writeMarkup): (WebCore::StaticPasteboard::writePlainText): (WebCore::StaticPasteboard::write): Implement these methods by writing to the `PasteboardCustomData`. These methods are invoked by our own code rather than the bindings, and should only be used to stage default data types when starting a drag. * platform/StaticPasteboard.h: * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::write): (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): Tools: Adds new API tests and test infrastructure to verify that DataTransfer types and data are accessible during the "dragstart" event. See below for more details. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: (-[TestWKWebView selectElementWithID:]): (-[DragAndDropSimulator dragFromElementWithID:to:]): Add a few (very specialized) helper methods to assist with simulating drags over the various elements in the new drag and drop test harness page below (dragstart-data.html). (runDragStartDataTestCase): Test the following scenarios (split between three API tests) by dumping the resulting DataTransfer types and their data strings, and observing the results: - Dragging a normal text selection. - Dragging a normal text selection, and then adding a URL string. - Dragging a normal text selection, and then adding a custom pasteboard type. - Dragging a normal text selection, but then replacing the data with just a URL string. - Dragging a normal text selection, but then replacing the data with just a custom data type. - Dragging an image element. - Dragging an image element, and then overriding the plain text data. - Dragging a link (anchor element). - Dragging a link, and then adding a custom type. * TestWebKitAPI/Tests/WebKitCocoa/dragstart-data.html: Added. Add a new test harness to help test DataTransfer types when starting a drag. This test page can also be used as a manual test harness, by simply opening the test page, starting drags on the various elements and observing the output in the textarea. * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Tweak this test page to replace the DataTransfer with custom data (rather than simply append it) by calling `DataTransfer.clearData()` prior to writing the custom types. * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebViewHostWindow initWithWebView:contentRect:styleMask:backing:defer:]): Add a `__weak` reference on TestWKWebViewHostWindow back to the TestWKWebView, so that we can consult `-eventTimestamp` when synthesizing mouse events on macOS during API tests. (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:]): (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:]): (-[TestWKWebViewHostWindow initWithWebView:frame:]): (-[TestWKWebView _setUpTestWindow:]): (-[TestWKWebView setEventTimestampOffset:]): (-[TestWKWebView eventTimestamp]): Add a mechanism to offset synthetic event timestamps by a given time interval (i.e. the event timestamp offset). (-[TestWKWebView mouseMoveToPoint:withFlags:]): (-[TestWKWebView _mouseEventWithType:atLocation:]): (-[TestWKWebView typeCharacter:]): * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: (-[DragAndDropSimulator runFrom:to:]): While simulating drag and drop on macOS, use `-setEventTimestampOffset:` to "leap forward" in time, so that the 150 millisecond delay when dragging a text selection doesn't prevent drags from beginning. Canonical link: https://commits.webkit.org/225531@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 19:41:50 +00:00
m_nonDefaultDataTypes.remove(type);
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
m_customData.clear(type);
On iOS, getData can't get text set by setData during copy event https://bugs.webkit.org/show_bug.cgi?id=176980 <rdar://problem/34453915> Reviewed by Darin Adler. Source/WebCore: The bug was caused by iOS port not implementing Pasteboard::createPrivate(). Rather than implementing this in iOS, replace its use for copy & paste events by StaticPasteboard Wenson added for input events. This makes read-write pasteboard platform agnostic and paves the way to make writing to pasteboard in a single IPC in WebKit2. Also fixed a bug that iOS port's Pasteboard::types returned the list of all supported types instead of ones actually present in the pasteboard. This patch also adds a vector of types to StaticPasteboard to maintain the type order. Tests: editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html editing/pasteboard/dataTransfer-types-pasting-plaintext.html * dom/DataTransfer.cpp: (WebCore::DataTransfer::createForCopyAndPaste): Make StaticPasteboard instead of a private pasteboard. (WebCore::DataTransfer::createForInputEvent): * editing/Editor.cpp: (WebCore::dispatchClipboardEvent): Call newly added commitToPasteboard on StaticPasteboard. * platform/Pasteboard.h: (WebCore::Pasteboard::isStatic const): * platform/PasteboardStrategy.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::create): Deleted. (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): Deleted. Now simply returns m_type. (WebCore::StaticPasteboard::readString): Added. (WebCore::StaticPasteboard::writeString): Added. (WebCore::StaticPasteboard::clear): Added. (WebCore::StaticPasteboard::commitToPasteboard): Added. (isType): Added. * platform/StaticPasteboard.h: (WebCore::Pasteboard::isStatic const): Added. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. (WebCore::addHTMLClipboardTypesForCocoaType): (WebCore::Pasteboard::types): Return the actual list of types in the pasteboard. * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. Source/WebKit: * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: (WebKit::WebPlatformStrategies::copy): Deleted. * WebProcess/WebCoreSupport/WebPlatformStrategies.h: Source/WebKitLegacy/mac: * WebCoreSupport/WebPlatformStrategies.h: * WebCoreSupport/WebPlatformStrategies.mm: (WebPlatformStrategies::copy): Deleted. LayoutTests: Added regression tests to make sure dataTransfer.types returns an empty list when writing to a pasteboard (copy), and doesn't contain image types when pasting plain text. Unfortunately, pasting image does result in plain text content being present in the pasteboard in the form of URL so we can't test that scenario. Also removed failing expectations from a number of tests that are now passing on iOS. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy-expected.txt: Added. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext-expected.txt: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext.html: Added. * platform/ios/TestExpectations: Canonical link: https://commits.webkit.org/193550@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222228 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-19 21:50:03 +00:00
}
Sanitize URL in pasteboard for other applications and cross origin content https://bugs.webkit.org/show_bug.cgi?id=178060 <rdar://problem/34874518> Reviewed by Wenson Hsieh. Source/WebCore: This patch introduces the sanitization of URL when written from a web content to prevent web content from exploiting the URL parser of other applications in the system particularly of those that actively monitor system pasteboard (a.k.a. clipboard on non-Cocoa platforms) and decode or otherwise process URLs. Because the Web compatibility requires that DataTransfer exposes the original URL to any document in the same origin as the one which wrote the URL into the pasteboard, we store a string which uniquely identifies the origin of an originating document into our custom pasteboard data. Note that we expose any URL which didn't come from WebKit since we don't expect URLs to reveal privacy sensitive information. We use UUID for the origin identifier of a null origin document. An alternative approach is to store the pasteboard data from the same origin into the document and invalidate it when the system pasteboard changes. However, Pasteboard object cannot know about Document (as Pasteboard is a platform object and Document is a WebCore object), this turns out be quite tricky as there are multiple places where we create Pasteboard objects, and they all need to be aware of this special same origin Pasteboard object that hangs off of Document. Also, this approach would result in the same origin code paths to diverge between null origin and non-null origin documents. Tests: editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document.html editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin.html editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin.html editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url.html CopyURL.ValidURL CopyURL.UnescapedURL CopyURL.MalformedURL DataInteractionTests.DataTransferSetDataValidURL DataInteractionTests.DataTransferSetDataUnescapedURL DataInteractionTests.DataTransferSetDataInvalidURL * dom/DataTransfer.cpp: (WebCore::originForDocument): Extracted from createForCopyAndPaste. (WebCore::DataTransfer::createForCopyAndPaste): (WebCore::DataTransfer::getDataForItem const): Read the URL from the custom data when the originating content is of the same origin. When the originating content is cross origin, or there is no custom data (e.g. written by another native application; or sanitization didn't result in any difference), then callback to native value. (WebCore::DataTransfer::setDataFromItemList): Sanitize the URL before writing it to the native pasteboard. Store the original value if the sanitization resulted in any difference. (WebCore::DataTransfer::types const): (WebCore::DataTransfer::commitToPasteboard): Moved the code to write custom data to Pasteboard since we need to write the origin string with it. (WebCore::DataTransfer::createForDragStartEvent): Added Document as an argument to compute the origin string. (WebCore::DataTransfer::createForDrop): Ditto. (WebCore::DataTransfer::createForUpdatingDropTarget): (WebCore::DataTransfer::moveDragState): * dom/DataTransfer.h: * dom/Document.cpp: (WebCore::Document::uniqueIdentifier): Added. See above. * dom/Document.h: * editing/Editor.cpp: (WebCore::createDataTransferForClipboardEvent): (WebCore::dispatchClipboardEvent): * page/DragController.cpp: (WebCore::DragController::dispatchTextInputEventFor): * page/EventHandler.cpp: (WebCore::EventHandler::performDragAndDrop): (WebCore::EventHandler::handleDrag): * platform/Pasteboard.h: * platform/PasteboardStrategy.h: * platform/PlatformPasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::takeCustomData): Moved the logic to write to native pasteboard to DataTransfer. * platform/StaticPasteboard.h: * platform/cocoa/PasteboardCocoa.mm: (WebCore::Pasteboard::typesSafeForBindings): (WebCore::Pasteboard::readStringInCustomData): Rewritten using readCustomData. See below. (WebCore::Pasteboard::readOrigin): Added. (WebCore::Pasteboard::readCustomData): Added. Populates the cache. Because a single Pasteboard object is never allowed to read values once its content is updated by other applications, we can permanently cache the result. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string. (WebCore::Pasteboard::readOrigin): Added. * platform/gtk/PlatformPasteboardGtk.cpp: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Now takes the unused origin string. * platform/ios/PlatformPasteboardIOS.mm: (WebCore::originKeyKeyForTeamData): Added. (WebCore::customTypesKeyForTeamData): Added. Replaces the use of PasteboardCustomData::cocoaType() in the team data for clarity since the team data key isn't same as the pasteboard type. We don't have to worry about the backwards compatibility since drag & drop session doesn't persist across iOS upgrades, and there is no publicly released iOS with this team data support. (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Read the origin string and the custom data off the team data. Don't expose custom types that are written by cross origin documents. (WebCore::PlatformPasteboard::write): Add the orign string with custom pasteboard types in the team data. (WebCore::PlatformPasteboard::readURL): Fixed a bug that this function was not reading NSURL when UIPasteboard serializes NSURL as a plist. This code is exercised by CopyURL.ValidURL. * platform/mac/PlatformPasteboardMac.mm: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Don't add custom pasteboard types that are added by cross origin documents. * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string. (WebCore::Pasteboard::readOrigin): Added. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::typesSafeForBindings): Now takes the unused origin string. (WebCore::Pasteboard::readOrigin): Added. * platform/wpe/PlatformPasteboardWPE.cpp: (WebCore::PlatformPasteboard::typesSafeForDOMToReadAndWrite const): Now takes the unused origin string. Source/WebKit: Plubmed the origin identifier through IPC from Pasteboard in WebContent process to PlatformPasteboard in UIProcess. * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm: (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite): * UIProcess/WebPasteboardProxy.cpp: (WebKit::WebPasteboardProxy::typesSafeForDOMToReadAndWrite): * UIProcess/WebPasteboardProxy.h: * UIProcess/WebPasteboardProxy.messages.in: * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: (WebKit::WebPlatformStrategies::typesSafeForDOMToReadAndWrite): * WebProcess/WebCoreSupport/WebPlatformStrategies.h: Source/WebKitLegacy/mac: * WebCoreSupport/WebPlatformStrategies.h: * WebCoreSupport/WebPlatformStrategies.mm: (WebPlatformStrategies::typesSafeForDOMToReadAndWrite): Tools: Added API tests for sanitizing URLs copied from web content, and that the original URL is exposed to the web content. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/CopyURL.mm: Added. (readURLFromPasteboard): A helper function. * TestWebKitAPI/Tests/WebKitCocoa/copy-url.html: Added. * TestWebKitAPI/Tests/ios/DataInteractionTests.mm: (DataInteractionTests.DataTransferGetDataWhenDroppingCustomData): Rebaselined. https://www.apple.com is no longer normalized to https://www.apple.com/ by NSURL / UIPasteboard as expected. (DataInteractionTests.DataTransferSetDataValidURL): Added. (DataInteractionTests.DataTransferSetDataUnescapedURL): Added. (DataInteractionTests.qDataTransferSetDataInvalidURL): Added. LayoutTests: Added tests for copying & pasting URLs. URLs should be %-escaped and any invalid URL should be stripped away and invisible to a cross-origin content or a null origin document but the same origin content should have access to its original form. * TestExpectations: * editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document-expected.txt: Added. * editing/pasteboard/data-transfer-get-data-on-copying-pasting-malformed-url-in-same-document.html: Added. * editing/pasteboard/data-transfer-get-data-on-drop-custom-expected.txt: Rebaselined. We no longer normalize "https://www.apple.com" into "https://www.apple.com/" by NSURL / UIPasteboard within the same origin content. * editing/pasteboard/data-transfer-get-data-on-paste-custom-expected.txt: Ditto. * editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-expected.txt: Added. * editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin-expected.txt: Added. * editing/pasteboard/data-transfer-set-data-ignore-copied-walformed-url-in-null-origin.html: Added. * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin-expected.txt: Added. * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-copying-in-null-origin.html: Added. * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin-expected.txt: Added. * editing/pasteboard/data-transfer-set-data-sanitlize-url-when-dragging-in-null-origin.html: Added. * editing/pasteboard/dataTransfer-setData-getData-expected.txt: Rebaselined. More test cases are passing. * editing/pasteboard/dataTransfer-setData-getData.html: Updated expectations as the original URL is now preserved. * http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url-expected.txt: Added. * http/tests/security/clipboard/copy-paste-url-across-origin-sanitizes-url.html: Added. * http/tests/security/clipboard/resources/copy.html: Added. * platform/mac-wk1/TestExpectations: Canonical link: https://commits.webkit.org/194427@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223195 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-11 19:01:10 +00:00
PasteboardCustomData StaticPasteboard::takeCustomData()
On iOS, getData can't get text set by setData during copy event https://bugs.webkit.org/show_bug.cgi?id=176980 <rdar://problem/34453915> Reviewed by Darin Adler. Source/WebCore: The bug was caused by iOS port not implementing Pasteboard::createPrivate(). Rather than implementing this in iOS, replace its use for copy & paste events by StaticPasteboard Wenson added for input events. This makes read-write pasteboard platform agnostic and paves the way to make writing to pasteboard in a single IPC in WebKit2. Also fixed a bug that iOS port's Pasteboard::types returned the list of all supported types instead of ones actually present in the pasteboard. This patch also adds a vector of types to StaticPasteboard to maintain the type order. Tests: editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html editing/pasteboard/dataTransfer-types-pasting-plaintext.html * dom/DataTransfer.cpp: (WebCore::DataTransfer::createForCopyAndPaste): Make StaticPasteboard instead of a private pasteboard. (WebCore::DataTransfer::createForInputEvent): * editing/Editor.cpp: (WebCore::dispatchClipboardEvent): Call newly added commitToPasteboard on StaticPasteboard. * platform/Pasteboard.h: (WebCore::Pasteboard::isStatic const): * platform/PasteboardStrategy.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::create): Deleted. (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): Deleted. Now simply returns m_type. (WebCore::StaticPasteboard::readString): Added. (WebCore::StaticPasteboard::writeString): Added. (WebCore::StaticPasteboard::clear): Added. (WebCore::StaticPasteboard::commitToPasteboard): Added. (isType): Added. * platform/StaticPasteboard.h: (WebCore::Pasteboard::isStatic const): Added. * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. (WebCore::addHTMLClipboardTypesForCocoaType): (WebCore::Pasteboard::types): Return the actual list of types in the pasteboard. * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. * platform/wpe/PasteboardWPE.cpp: (WebCore::Pasteboard::createPrivate): Deleted. (WebCore::Pasteboard::writePasteboard): Deleted. Source/WebKit: * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp: (WebKit::WebPlatformStrategies::copy): Deleted. * WebProcess/WebCoreSupport/WebPlatformStrategies.h: Source/WebKitLegacy/mac: * WebCoreSupport/WebPlatformStrategies.h: * WebCoreSupport/WebPlatformStrategies.mm: (WebPlatformStrategies::copy): Deleted. LayoutTests: Added regression tests to make sure dataTransfer.types returns an empty list when writing to a pasteboard (copy), and doesn't contain image types when pasting plain text. Unfortunately, pasting image does result in plain text content being present in the pasteboard in the form of URL so we can't test that scenario. Also removed failing expectations from a number of tests that are now passing on iOS. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy-expected.txt: Added. * editing/pasteboard/dataTransfer-types-is-initially-empty-on-copy.html: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext-expected.txt: Added. * editing/pasteboard/dataTransfer-types-pasting-plaintext.html: Added. * platform/ios/TestExpectations: Canonical link: https://commits.webkit.org/193550@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222228 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-09-19 21:50:03 +00:00
{
[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: Canonical link: https://commits.webkit.org/216383@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251100 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-14 21:52:26 +00:00
return std::exchange(m_customData, { });
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
}
dataTransfer.types is empty when handling the "dragstart" event https://bugs.webkit.org/show_bug.cgi?id=212685 <rdar://problem/61368402> Reviewed by Andy Estes. Source/WebCore: Implements several currently stubbed methods on StaticPasteboard, so that the DataTransfer provided to the page on the "dragstart" event contains the DOM-exposed data types that will be written to the system pasteboard. This includes "text/html", "text/plain", and "text/uri-list". Tests: DragAndDropTests.DataTransferTypesOnDragStartForTextSelection DragAndDropTests.DataTransferTypesOnDragStartForImage DragAndDropTests.DataTransferTypesOnDragStartForLink ...as well as several existing tests in DragAndDropTestsIOS.mm that attempt to set pasteboard data during the dragstart event: DragAndDropTests.DataTransferSanitizeHTML DragAndDropTests.DataTransferSetDataCannotWritePlatformTypes DragAndDropTests.DataTransferSetDataInvalidURL DragAndDropTests.DataTransferSetDataUnescapedURL DragAndDropTests.DataTransferSetDataValidURL * dom/DataTransfer.cpp: (WebCore::DataTransfer::commitToPasteboard): Only commit data to the native pasteboard if the page actually tried to write or modify the data. This allows us to preserve existing behavior by allowing DragController to write dragged data to the pasteboard normally in the case where the page didn't specify any custom data. In the case where the page does specify custom data, we will write this custom data *in addition* to any default data that was written to the static pasteboard. While this is a departure from our current behavior (which is to treat the pasteboard as a blank slate that contains only whatever custom data was provided by the page), it matches behavior in both Chrome and Firefox, and is likely more compatible with webpages that don't have UA-specific logic targeting WebKit. * editing/cocoa/EditorCocoa.mm: (WebCore::Editor::writeSelectionToPasteboard): Avoid calling into the injected bundle (as well as writing a few particular non-web-exposed types, such as web archive data) in the case where we're writing to a static pasteboard (there's no point in doing this for the static pasteboard, and in the worst case, it could confuse some internal clients). * editing/ios/EditorIOS.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. * editing/mac/EditorMac.mm: (WebCore::Editor::writeImageToPasteboard): Ditto. But additionally, introduce a markup string to PasteboardImage, so that we will expose the "text/html" type when starting a drag on an image element. * page/DragController.cpp: (WebCore::DragController::startDrag): Only attempt to call into `Pasteboard::writeTrustworthyWebURLsPboardType` in the case where the pasteboard supports this type (i.e. on macOS). This fixes an existing assertion that was hit by my new API test, which attempts to override the contents of the pasteboard with custom data while starting a drag on a link. * page/EventHandler.cpp: (WebCore::EventHandler::handleDrag): Since the StaticPasteboard contains data before the page has written anything, don't use `Pasteboard::hasData()` to determine whether there's custom data; instead, use the new `hasNonDefaultData()` method on `StaticPasteboard` (see below). * platform/Pasteboard.cpp: (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): On non-macOS ports, return false. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: (WebCore::StaticPasteboard::hasNonDefaultData const): Keep track of whether the page attempted to stage any custom data during "dragstart" by maintaining the set of types written by the page, via calls to `writeString()` and similar. I'm using a set of types here instead of a simple `bool` flag to ensure correctness in the case where the page adds a type, and then later removes that same custom type, such that there is no longer non-default data. (WebCore::StaticPasteboard::writeString): (WebCore::StaticPasteboard::writeData): (WebCore::StaticPasteboard::writeStringInCustomData): (WebCore::StaticPasteboard::clear): See above. (WebCore::StaticPasteboard::writeMarkup): (WebCore::StaticPasteboard::writePlainText): (WebCore::StaticPasteboard::write): Implement these methods by writing to the `PasteboardCustomData`. These methods are invoked by our own code rather than the bindings, and should only be used to stage default data types when starting a drag. * platform/StaticPasteboard.h: * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::write): (WebCore::Pasteboard::canWriteTrustworthyWebURLsPboardType): Tools: Adds new API tests and test infrastructure to verify that DataTransfer types and data are accessible during the "dragstart" event. See below for more details. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm: (-[TestWKWebView selectElementWithID:]): (-[DragAndDropSimulator dragFromElementWithID:to:]): Add a few (very specialized) helper methods to assist with simulating drags over the various elements in the new drag and drop test harness page below (dragstart-data.html). (runDragStartDataTestCase): Test the following scenarios (split between three API tests) by dumping the resulting DataTransfer types and their data strings, and observing the results: - Dragging a normal text selection. - Dragging a normal text selection, and then adding a URL string. - Dragging a normal text selection, and then adding a custom pasteboard type. - Dragging a normal text selection, but then replacing the data with just a URL string. - Dragging a normal text selection, but then replacing the data with just a custom data type. - Dragging an image element. - Dragging an image element, and then overriding the plain text data. - Dragging a link (anchor element). - Dragging a link, and then adding a custom type. * TestWebKitAPI/Tests/WebKitCocoa/dragstart-data.html: Added. Add a new test harness to help test DataTransfer types when starting a drag. This test page can also be used as a manual test harness, by simply opening the test page, starting drags on the various elements and observing the output in the textarea. * TestWebKitAPI/Tests/WebKitCocoa/dump-datatransfer-types.html: Tweak this test page to replace the DataTransfer with custom data (rather than simply append it) by calling `DataTransfer.clearData()` prior to writing the custom types. * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: * TestWebKitAPI/cocoa/TestWKWebView.h: * TestWebKitAPI/cocoa/TestWKWebView.mm: (-[TestWKWebViewHostWindow initWithWebView:contentRect:styleMask:backing:defer:]): Add a `__weak` reference on TestWKWebViewHostWindow back to the TestWKWebView, so that we can consult `-eventTimestamp` when synthesizing mouse events on macOS during API tests. (-[TestWKWebViewHostWindow _mouseDownAtPoint:simulatePressure:clickCount:]): (-[TestWKWebViewHostWindow _mouseUpAtPoint:clickCount:]): (-[TestWKWebViewHostWindow initWithWebView:frame:]): (-[TestWKWebView _setUpTestWindow:]): (-[TestWKWebView setEventTimestampOffset:]): (-[TestWKWebView eventTimestamp]): Add a mechanism to offset synthetic event timestamps by a given time interval (i.e. the event timestamp offset). (-[TestWKWebView mouseMoveToPoint:withFlags:]): (-[TestWKWebView _mouseEventWithType:atLocation:]): (-[TestWKWebView typeCharacter:]): * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: (-[DragAndDropSimulator runFrom:to:]): While simulating drag and drop on macOS, use `-setEventTimestampOffset:` to "leap forward" in time, so that the 150 millisecond delay when dragging a text selection doesn't prevent drags from beginning. Canonical link: https://commits.webkit.org/225531@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-06-03 19:41:50 +00:00
void StaticPasteboard::writeMarkup(const String& markup)
{
m_customData.writeString("text/html"_s, markup);
}
void StaticPasteboard::writePlainText(const String& text, SmartReplaceOption)
{
m_customData.writeString("text/plain"_s, text);
}
void StaticPasteboard::write(const PasteboardURL& url)
{
m_customData.writeString("text/uri-list"_s, url.url.string());
}
void StaticPasteboard::write(const PasteboardImage& image)
{
// FIXME: This should ideally remember the image data, so that when this StaticPasteboard
// is committed to the native pasteboard, we'll preserve the image as well. For now, stick
// with our existing behavior, which prevents image data from being copied in the case where
// any non-default data was written by the page.
m_fileContentState = Pasteboard::FileContentState::InMemoryImage;
#if PLATFORM(MAC)
if (!image.dataInHTMLFormat.isEmpty())
writeMarkup(image.dataInHTMLFormat);
#else
UNUSED_PARAM(image);
#endif
#if !PLATFORM(WIN)
if (Pasteboard::canExposeURLToDOMWhenPasteboardContainsFiles(image.url.url.string()))
write(image.url);
#endif
}
void StaticPasteboard::write(const PasteboardWebContent& content)
{
String markup;
String text;
#if PLATFORM(COCOA)
markup = content.dataInHTMLFormat;
text = content.dataInStringFormat;
#elif PLATFORM(GTK) || USE(LIBWPE)
markup = content.markup;
text = content.text;
#endif
if (!markup.isEmpty())
writeMarkup(markup);
if (!text.isEmpty())
writePlainText(text, SmartReplaceOption::CannotSmartReplace);
}
Support InputEvent.dataTransfer for the InputEvent spec https://bugs.webkit.org/show_bug.cgi?id=163213 <rdar://problem/28700407> Reviewed by Ryosuke Niwa. Source/WebCore: Adds support for the dataTransfer attribute of InputEvent, which contains both HTML and plain text representations of inserted content corresponding to input types "insertFromPaste", "insertFromDrop" and "insertReplacementText". The specification calls for the data transfer's drag data item list to contain this information via two entries with type strings "text/html" and "text/plain". However, WebKit does not yet support the DataTransfer.items -- in lieu of this, we will provide this information for now via getData("text/plain") and getData("text/html"), respectively. To support this attribute, we need a special type of DataTransfer which is readonly and returns canned data given a type string. To implement this, we introduce StaticPasteboard, a type of Pasteboard which is initialized with a map of type string to data. When asked for its data via getData, the StaticPasteboard searches its map for the requested type and returns the result, if any. An editing command may now create a new DataTransfer via DataTransfer::createForInputEvent from HTML and plaintext strings, and then vend this information to its dispatched input events by overriding CompositeEditCommand::inputEventDataTransfer. Some further work will be needed to ensure that all information exposed via this DataTransfer does not contain hidden content. To do this, we should create a new Document, "paste" the contents of our copied HTML string into it, then simulate selecting the content and generating markup from the selection to create a sanitized DocumentFragment corresponding to the original copied HTML. This will be addressed in a future patch. Tests: fast/events/input-events-paste-rich-datatransfer.html fast/events/input-events-spell-checking-datatransfer.html * PlatformEfl.cmake: * PlatformGTK.cmake: * PlatformWin.cmake: Add StaticPasteboard.cpp. * WebCore.xcodeproj/project.pbxproj: * dom/DataTransfer.cpp: (WebCore::DataTransfer::DataTransfer): (WebCore::DataTransfer::createForInputEvent): Initializes a new DataTransfer for the purposes of input events. This takes a HTML and plain text representations of the data being inserted and creates a new readonly DataTransfer backed by a StaticPasteboard that only knows how to map the "text/plain" data type to the given plaintext string and "text/html" to the given HTML text. * dom/DataTransfer.h: * dom/InputEvent.cpp: (WebCore::InputEvent::create): (WebCore::InputEvent::InputEvent): (WebCore::InputEvent::dataTransfer): * dom/InputEvent.h: * dom/InputEvent.idl: Add the InputEvent.dataTransfer attribute. * dom/Node.cpp: * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::inputEventDataTransfer): Add a new hook for CompositeEditCommands to vend a DataTransfer for the purposes of input events. By default, this is null. * editing/CompositeEditCommand.h: * editing/Editor.cpp: (WebCore::dispatchBeforeInputEvent): (WebCore::dispatchInputEvent): (WebCore::dispatchBeforeInputEvents): (WebCore::dispatchInputEvents): (WebCore::Editor::willApplyEditing): (WebCore::Editor::appliedEditing): * editing/ReplaceRangeWithTextCommand.cpp: (WebCore::ReplaceRangeWithTextCommand::willApplyCommand): (WebCore::ReplaceRangeWithTextCommand::doApply): (WebCore::ReplaceRangeWithTextCommand::inputEventDataTransfer): * editing/ReplaceRangeWithTextCommand.h: * editing/ReplaceSelectionCommand.cpp: (WebCore::ReplaceSelectionCommand::willApplyCommand): Initialize the ReplacementFragment here before applying the command, adjusting the DocumentFragment to be inserted in the process. (WebCore::ReplaceSelectionCommand::doApply): (WebCore::ReplaceSelectionCommand::inputEventDataTransfer): (WebCore::ReplaceSelectionCommand::ensureReplacementFragment): Returns the ReplacementFragment used to apply the command, initializing it if necessary and stripping extraneous nodes off of the document fragment in the process. Since ReplaceSelectionCommand may be used as a top-level editing command or a child of another CompositeEditCommand such as the ReplaceRangeWithTextCommand, the ReplacementFragment may be initialized either in willApplyCommand or in doApply. * editing/ReplaceSelectionCommand.h: * editing/SpellingCorrectionCommand.cpp: (WebCore::SpellingCorrectionCommand::willApplyCommand): (WebCore::SpellingCorrectionCommand::doApply): (WebCore::SpellingCorrectionCommand::inputEventDataTransfer): * editing/SpellingCorrectionCommand.h: Using the replacement text fragment, create and return a DataTransfer for input events. * platform/Pasteboard.h: * platform/StaticPasteboard.cpp: Added. (WebCore::StaticPasteboard::create): (WebCore::StaticPasteboard::StaticPasteboard): (WebCore::StaticPasteboard::hasData): (WebCore::StaticPasteboard::types): (WebCore::StaticPasteboard::readString): * platform/StaticPasteboard.h: Copied from Source/WebCore/dom/InputEvent.cpp. * platform/efl/PasteboardEfl.cpp: (WebCore::Pasteboard::writeMarkup): (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): * platform/gtk/PasteboardGtk.cpp: (WebCore::Pasteboard::writeMarkup): * platform/ios/PasteboardIOS.mm: (WebCore::Pasteboard::writeMarkup): * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::Pasteboard): (WebCore::Pasteboard::writeMarkup): * platform/win/PasteboardWin.cpp: (WebCore::Pasteboard::write): (WebCore::Pasteboard::read): To account for virtual methods on Pasteboard, add implementations for methods that were previously defined but unimplemented on these platforms. LayoutTests: Adds 2 new layout tests verifying that input events dispatched as a result of pasting or spell checking contain DataTransfers that have rich and plain text representations of the contents being inserted. * fast/events/input-events-fired-when-typing-expected.txt: * fast/events/input-events-fired-when-typing.html: * fast/events/input-events-paste-rich-datatransfer-expected.txt: Added. * fast/events/input-events-paste-rich-datatransfer.html: Added. * fast/events/input-events-spell-checking-datatransfer-expected.txt: Added. * fast/events/input-events-spell-checking-datatransfer.html: Added. * platform/ios-simulator/TestExpectations: Canonical link: https://commits.webkit.org/181698@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207841 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-25 20:23:10 +00:00
}