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
|
|
|
}
|
|
|
|
|
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);
|
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
|
|
|
|
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)
|
2017-10-06 07:30:20 +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.writeString(type, value);
|
2017-10-06 07:30:20 +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
|
|
|
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));
|
2017-10-06 07:30:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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();
|
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);
|
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()
|
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
|
|
|
}
|