Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (222655 => 222656)
--- trunk/Source/WebCore/CMakeLists.txt 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/CMakeLists.txt 2017-09-29 18:46:51 UTC (rev 222656)
@@ -1799,6 +1799,7 @@
editing/VisibleSelection.cpp
editing/VisibleUnits.cpp
editing/WebContentReader.cpp
+ editing/WebCorePasteboardFileReader.cpp
editing/WrapContentsInDummySpanCommand.cpp
editing/markup.cpp
Modified: trunk/Source/WebCore/ChangeLog (222655 => 222656)
--- trunk/Source/WebCore/ChangeLog 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/ChangeLog 2017-09-29 18:46:51 UTC (rev 222656)
@@ -1,3 +1,104 @@
+2017-09-28 Ryosuke Niwa <[email protected]>
+
+ Image pasting is not working on tineye.com / gmail.com / GitHub.com due to lack of support for DataTransfer.items
+ https://bugs.webkit.org/show_bug.cgi?id=170449
+ <rdar://problem/31432525>
+
+ Reviewed by Wenson Hsieh.
+
+ The bug was caused by image types in NSPasteboard or UIPasteboard not being treated as file items in dataTransfer.
+ Because there is no Web API to get binary data out of dataTransfer unlike text data, we need to treat any image
+ data as files even if they're entirely in the memory.
+
+ This patch introduces the notion of pasteboard types to be treated as files and expose them on dataTransfer.files
+ as well as dataTransfer.items of type "file". Because in-memory images are stored as TIFF in macOS and websites
+ don't typically support image/tiff, we convert all such in-memory TIFF images into PNG images ourselves for
+ a better web compatibility. This is done inside read(PasteboardFileReader&) in PasteboardCocoa.mm.
+
+ Note that PasteboardFileReader cannot directly have RefPtr<File> as a member variable as code in WebCore/platform
+ including Pasteboard code is not supposed to depend on WebCore types. WebCorePasteboardFileReader, a subclass of
+ PasteboardFileReader was introduced to resolve this reverse dependency.
+
+ In addition, this patch removes the restriction on dataTransfer.items that it only includes files of the supported
+ MIME types. This was unwarranted since 1. we don't have any restriction on what an user can drag & drop into a web
+ page via input element so there is no security benefit in this, and 2. the user should be able to copy & paste
+ whatever file he/she desires regardless of the MIME type on websites like Google Drive.
+
+ Tests: PasteImage
+
+ * CMakeLists.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCore/PlatformMac.cmake:
+ * dom/DataTransfer.cpp:
+ (WebCore::DataTransfer::types const): Now excludes image/gif, image/png, image/jpeg, and image/tiff.
+ (WebCore::DataTransfer::files const): Add fake files we create for in-memory images but only when there are no real
+ files in the pasteboard since it's expensive to copy image data across UI/Web processes to create a blob URL.
+ * dom/DataTransferItemList.cpp:
+ (WebCore::DataTransferItemList::ensureItems const): Just expose every file type. If the user had decided to paste
+ a file, it's okay for the page to access that file regardless of whether it's a zip file, JPEG image, etc...
+ * editing/WebCorePasteboardFileReader.cpp:
+ (WebCorePasteboardFileReader::~WebCorePasteboardFileReader):
+ (WebCorePasteboardFileReader::read):
+ * editing/WebCorePasteboardFileReader.h:
+ (WebCorePasteboardFileReader):
+ * platform/Pasteboard.cpp:
+ (WebCore::PasteboardImage::PasteboardImage): Moved from platform specific translation units.
+ (WebCore::PasteboardImage::~PasteboardImage): Ditto.
+ * platform/Pasteboard.h:
+ (PasteboardFileReader): Added.
+ (* platform/StaticPasteboard.h:
+ (StaticPasteboard::typesForBindings): Added.
+ (StaticPasteboard::typesTreatedAsFiles): Added. Returns an empty list we don't support the web content writing image
+ files into pasteboard at the moment.
+ * platform/cocoa/PasteboardCocoa.mm: Added.
+ (WebCore::PasteboardWebContent::PasteboardWebContent): Moved from PasteboardMac.mm and PasteboardIOS.mm.
+ (WebCore::PasteboardWebContent::~PasteboardWebContent):
+ (WebCore::cocoaTypeToImageType): Added.
+ (WebCore::imageTypeToMIMEType): Added. Pretends to have image/png when the Cocoa type is image/tiff since most of
+ websites don't support image/tiff.
+ (WebCore::imageTypeToFakeFilename): Added.
+ (WebCore::mimeTypeToImageType): Added.
+ (WebCore::Pasteboard::shouldTreatCocoaTypeAsFile): Added. Pasteboard::typesForBindings excludes the type for which
+ this function returns true.
+ (WebCore::Pasteboard::typesTreatedAsFiles): Returns the list of all in-memory image types in the pasteboard.
+ (WebCore::Pasteboard::read): Added. On macOS, we convert TIFF to PNG for web compatibility. We don't do this rather
+ memory intensive coercion on iOS where most of apps like Photos put PNG file into the pasteboard in the first place.
+ * platform/gtk/PasteboardGtk.cpp:
+ (WebCore::PasteboardImage::PasteboardImage): Deleted.
+ (WebCore::PasteboardImage::~PasteboardImage): Deleted.
+ (WebCore::Pasteboard::read):
+ (WebCore::Pasteboard::typesForBindings): Renamed from types.
+ (WebCore::Pasteboard::typesTreatedAsFiles):
+ * platform/ios/PasteboardIOS.mm:
+ (WebCore::addHTMLClipboardTypesForCocoaType):
+ (WebCore::Pasteboard::typesForBindings):
+ (WebCore::PasteboardWebContent::PasteboardWebContent): Deleted.
+ (WebCore::PasteboardWebContent::~PasteboardWebContent): Deleted.
+ (WebCore::PasteboardImage::PasteboardImage): Deleted.
+ (WebCore::PasteboardImage::~PasteboardImage): Deleted.
+ (WebCore::Pasteboard::types): Deleted.
+ * platform/ios/PlatformPasteboardIOS.mm:
+ (WebCore::safeTypeForDOMToReadAndWriteForPlatformType): Add "Files" to dataTransfer.types when there is an in-memory
+ image type in the pasteboard.
+ * platform/mac/PasteboardMac.mm:
+ (WebCore::PasteboardWebContent::PasteboardWebContent): Deleted.
+ (WebCore::PasteboardWebContent::~PasteboardWebContent): Deleted.
+ (WebCore::PasteboardImage::PasteboardImage): Deleted.
+ (WebCore::PasteboardImage::~PasteboardImage): Deleted.
+ (WebCore::addHTMLClipboardTypesForCocoaType): Moved the check for the legacy NeXT plain text check here. Also add
+ "Files" to dataTransfer.types when there is an in-memory image type in the pasteboard.
+ (WebCore::Pasteboard::typesForBindings): Renamed from types.
+ * platform/mac/PlatformPasteboardMac.mm:
+ (WebCore::safeTypeForDOMToReadAndWriteForPlatformType): Ditto to add "Files".
+ * platform/win/PasteboardWin.cpp:
+ (WebCore::Pasteboard::typesForBindings): Renamed from types.
+ (WebCore::Pasteboard::typesTreatedAsFiles):
+ (WebCore::Pasteboard::read):
+ * platform/wpe/PasteboardWPE.cpp:
+ (WebCore::Pasteboard::typesForBindings): Renamed from types.
+ (WebCore::Pasteboard::typesTreatedAsFiles):
+ (WebCore::Pasteboard::read):
+
2017-09-29 Wenson Hsieh <[email protected]>
[iOS WK2] Implement -[WKContentView hasText] for compatibility with the UITextInput protocol
Modified: trunk/Source/WebCore/PlatformMac.cmake (222655 => 222656)
--- trunk/Source/WebCore/PlatformMac.cmake 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/PlatformMac.cmake 2017-09-29 18:46:51 UTC (rev 222656)
@@ -321,6 +321,7 @@
platform/cocoa/MachSendRight.cpp
platform/cocoa/NetworkExtensionContentFilter.mm
platform/cocoa/ParentalControlsContentFilter.mm
+ platform/cocoa/PasteboardCocoa.mm
platform/cocoa/RuntimeApplicationChecksCocoa.mm
platform/cocoa/ScrollController.mm
platform/cocoa/ScrollSnapAnimatorState.mm
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (222655 => 222656)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-09-29 18:46:51 UTC (rev 222656)
@@ -4345,8 +4345,10 @@
9BD8A95A18BEFC7600987E9A /* CollectionIndexCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BD8A95918BEFC7600987E9A /* CollectionIndexCache.cpp */; };
9BDA64D71B975CE5009C4387 /* JSShadowRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B6BC9601B975966005AE1F0 /* JSShadowRoot.cpp */; };
9BDA64D81B975CF2009C4387 /* JSShadowRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B6BC9611B975966005AE1F0 /* JSShadowRoot.h */; };
+ 9BDD18271F7E05F400E8E577 /* WebCorePasteboardFileReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BDD18261F7E05F400E8E577 /* WebCorePasteboardFileReader.cpp */; };
9BE6710B1D5AEB2100345514 /* JSCustomElementRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BE671091D5AEB0400345514 /* JSCustomElementRegistry.cpp */; };
9BE6710C1D5AEB2500345514 /* JSCustomElementRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BE6710A1D5AEB0400345514 /* JSCustomElementRegistry.h */; };
+ 9BED2CB11F7CC06200666018 /* PasteboardCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BED2CAF1F7CC06200666018 /* PasteboardCocoa.mm */; };
9BF9A8801648DD2F001C6B23 /* JSHTMLFormControlsCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BF9A87E1648DD2F001C6B23 /* JSHTMLFormControlsCollection.cpp */; };
9BF9A8811648DD2F001C6B23 /* JSHTMLFormControlsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BF9A87F1648DD2F001C6B23 /* JSHTMLFormControlsCollection.h */; };
9D6380101AF173220031A15C /* StyleSelfAlignmentData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D63800F1AF16E160031A15C /* StyleSelfAlignmentData.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -12788,8 +12790,11 @@
9BD4E9181C462CFC005065BC /* CustomElementRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomElementRegistry.cpp; sourceTree = "<group>"; };
9BD4E9191C462CFC005065BC /* CustomElementRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomElementRegistry.h; sourceTree = "<group>"; };
9BD8A95918BEFC7600987E9A /* CollectionIndexCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CollectionIndexCache.cpp; sourceTree = "<group>"; };
+ 9BDD18251F7E059900E8E577 /* WebCorePasteboardFileReader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebCorePasteboardFileReader.h; sourceTree = "<group>"; };
+ 9BDD18261F7E05F400E8E577 /* WebCorePasteboardFileReader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebCorePasteboardFileReader.cpp; sourceTree = "<group>"; };
9BE671091D5AEB0400345514 /* JSCustomElementRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomElementRegistry.cpp; sourceTree = "<group>"; };
9BE6710A1D5AEB0400345514 /* JSCustomElementRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomElementRegistry.h; sourceTree = "<group>"; };
+ 9BED2CAF1F7CC06200666018 /* PasteboardCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteboardCocoa.mm; sourceTree = "<group>"; };
9BF433761F67619B00E1FD71 /* WebContentReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebContentReader.h; sourceTree = "<group>"; };
9BF9A87E1648DD2F001C6B23 /* JSHTMLFormControlsCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLFormControlsCollection.cpp; sourceTree = "<group>"; };
9BF9A87F1648DD2F001C6B23 /* JSHTMLFormControlsCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSHTMLFormControlsCollection.h; sourceTree = "<group>"; };
@@ -20601,6 +20606,8 @@
93309DCF099E64910056E581 /* VisibleUnits.h */,
9B6116491F6A593300E923B8 /* WebContentReader.cpp */,
9BF433761F67619B00E1FD71 /* WebContentReader.h */,
+ 9BDD18261F7E05F400E8E577 /* WebCorePasteboardFileReader.cpp */,
+ 9BDD18251F7E059900E8E577 /* WebCorePasteboardFileReader.h */,
93309DD4099E64910056E581 /* WrapContentsInDummySpanCommand.cpp */,
93309DD5099E64910056E581 /* WrapContentsInDummySpanCommand.h */,
9BAF3B2312C1A39800014BF1 /* WritingDirection.h */,
@@ -21773,6 +21780,7 @@
A19D93481AA11B1E00B46C24 /* NetworkExtensionContentFilter.mm */,
A18890AD1AA13F250026C301 /* ParentalControlsContentFilter.h */,
A18890AC1AA13F250026C301 /* ParentalControlsContentFilter.mm */,
+ 9BED2CAF1F7CC06200666018 /* PasteboardCocoa.mm */,
52B0D4BD1C57FD1E0077CE53 /* PlatformView.h */,
CDA29A081CBD99F400901CCF /* PlaybackSessionInterface.h */,
CDA29A0A1CBD9A7400901CCF /* PlaybackSessionModel.h */,
@@ -33489,6 +33497,7 @@
57B5F7EC1E57F1E300F34F90 /* PasswordCredential.cpp in Sources */,
F55B3DC91251F12D003EF269 /* PasswordInputType.cpp in Sources */,
2EE02A1F1F7324280006AF72 /* Pasteboard.cpp in Sources */,
+ 9BED2CB11F7CC06200666018 /* PasteboardCocoa.mm in Sources */,
E453901E0EAFCACA003695C8 /* PasteboardIOS.mm in Sources */,
4B2709830AF2E5E00065127F /* PasteboardMac.mm in Sources */,
1AF5E4E21E5779B1004A1F01 /* PasteboardWriter.mm in Sources */,
@@ -34426,6 +34435,7 @@
C5B4C24E1509236C00A6EF37 /* WebCoreNSURLExtras.mm in Sources */,
CD225C0B1C46FBF400140761 /* WebCoreNSURLSession.mm in Sources */,
B50F5B810E96CD9900AD71A6 /* WebCoreObjCExtras.mm in Sources */,
+ 9BDD18271F7E05F400E8E577 /* WebCorePasteboardFileReader.cpp in Sources */,
E180810E16FCECDF00B80D07 /* WebCoreResourceHandleAsDelegate.mm in Sources */,
E152551616FD2350003D7ADB /* WebCoreResourceHandleAsOperationQueueDelegate.mm in Sources */,
93EB169509F880B00091F8FF /* WebCoreSystemInterface.mm in Sources */,
Modified: trunk/Source/WebCore/dom/DataTransfer.cpp (222655 => 222656)
--- trunk/Source/WebCore/dom/DataTransfer.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/dom/DataTransfer.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -38,6 +38,7 @@
#include "Image.h"
#include "Pasteboard.h"
#include "StaticPasteboard.h"
+#include "WebCorePasteboardFileReader.h"
namespace WebCore {
@@ -171,7 +172,7 @@
if (!canReadTypes())
return { };
- return m_pasteboard->types();
+ return m_pasteboard->typesForBindings();
}
FileList& DataTransfer::files() const
@@ -195,6 +196,14 @@
if (newlyCreatedFileList) {
for (auto& filename : m_pasteboard->readFilenames())
m_fileList->append(File::create(filename));
+ if (m_fileList->isEmpty()) {
+ for (auto& type : m_pasteboard->typesTreatedAsFiles()) {
+ WebCorePasteboardFileReader reader(type);
+ m_pasteboard->read(reader);
+ if (reader.file)
+ m_fileList->append(reader.file.releaseNonNull());
+ }
+ }
}
return *m_fileList;
}
Modified: trunk/Source/WebCore/dom/DataTransferItemList.cpp (222655 => 222656)
--- trunk/Source/WebCore/dom/DataTransferItemList.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/dom/DataTransferItemList.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -131,11 +131,8 @@
items.append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(*const_cast<DataTransferItemList*>(this)), lowercasedType));
}
- for (auto& file : m_dataTransfer.files().files()) {
- auto type = File::contentTypeForFile(file->path()).convertToASCIILowercase();
- if (isSupportedType(type) || file->isDirectory())
- items.append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(*const_cast<DataTransferItemList*>(this)), type, file.copyRef()));
- }
+ for (auto& file : m_dataTransfer.files().files())
+ items.append(DataTransferItem::create(m_weakPtrFactory.createWeakPtr(*const_cast<DataTransferItemList*>(this)), file->type(), file.copyRef()));
m_items = WTFMove(items);
Added: trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp (0 => 222656)
--- trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp (rev 0)
+++ trunk/Source/WebCore/editing/WebCorePasteboardFileReader.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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 "WebCorePasteboardFileReader.h"
+
+#include "File.h"
+#include "SharedBuffer.h"
+
+namespace WebCore {
+
+WebCorePasteboardFileReader::~WebCorePasteboardFileReader() = default;
+
+void WebCorePasteboardFileReader::read(const String& filename, Ref<SharedBuffer>&& buffer)
+{
+ Vector<uint8_t> data;
+ data.append(buffer->data(), buffer->size());
+ file = File::create(Blob::create(WTFMove(data), type), filename);
+}
+
+}
+
Added: trunk/Source/WebCore/editing/WebCorePasteboardFileReader.h (0 => 222656)
--- trunk/Source/WebCore/editing/WebCorePasteboardFileReader.h (rev 0)
+++ trunk/Source/WebCore/editing/WebCorePasteboardFileReader.h 2017-09-29 18:46:51 UTC (rev 222656)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Pasteboard.h"
+
+namespace WebCore {
+
+class File;
+
+struct WebCorePasteboardFileReader final : PasteboardFileReader {
+ WebCorePasteboardFileReader(const String& type)
+ : PasteboardFileReader(type)
+ { }
+
+ ~WebCorePasteboardFileReader();
+
+ void read(const String&, Ref<SharedBuffer>&&) final;
+
+ RefPtr<File> file;
+};
+
+}
+
Modified: trunk/Source/WebCore/editing/wpe/EditorWPE.cpp (222655 => 222656)
--- trunk/Source/WebCore/editing/wpe/EditorWPE.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/editing/wpe/EditorWPE.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -38,7 +38,7 @@
{
chosePlainText = false;
- Vector<String> types = pasteboard.types();
+ Vector<String> types = pasteboard.typesForBindings();
if (types.isEmpty())
return nullptr;
Modified: trunk/Source/WebCore/platform/Pasteboard.cpp (222655 => 222656)
--- trunk/Source/WebCore/platform/Pasteboard.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/Pasteboard.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -35,6 +35,10 @@
namespace WebCore {
+// Making this non-inline so that WebKit 2's decoding doesn't have to include Image.h.
+PasteboardImage::PasteboardImage() = default;
+PasteboardImage::~PasteboardImage() = default;
+
bool isSafeTypeForDOMToReadAndWrite(const String& type)
{
return type == "text/plain" || type == "text/html" || type == "text/uri-list";
Modified: trunk/Source/WebCore/platform/Pasteboard.h (222655 => 222656)
--- trunk/Source/WebCore/platform/Pasteboard.h 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/Pasteboard.h 2017-09-29 18:46:51 UTC (rev 222656)
@@ -66,7 +66,7 @@
// For writing to the pasteboard. Generally sorted with the richest formats on top.
struct PasteboardWebContent {
-#if !(PLATFORM(GTK) || PLATFORM(WIN) || PLATFORM(WPE))
+#if PLATFORM(COCOA)
WEBCORE_EXPORT PasteboardWebContent();
WEBCORE_EXPORT ~PasteboardWebContent();
bool canSmartCopyOrDelete;
@@ -146,6 +146,17 @@
#endif
};
+struct PasteboardFileReader {
+ PasteboardFileReader(const String& type)
+ : type(type)
+ { }
+ virtual ~PasteboardFileReader() = default;
+
+ virtual void read(const String&, Ref<SharedBuffer>&&) = 0;
+
+ const String type;
+};
+
// FIXME: We need to ensure that the contents of sameOriginCustomData are not accessible across different origins.
struct PasteboardCustomData {
Vector<String> orderedTypes;
@@ -184,7 +195,8 @@
virtual bool isStatic() const { return false; }
virtual bool hasData();
- virtual Vector<String> types();
+ virtual Vector<String> typesForBindings();
+ virtual Vector<String> typesTreatedAsFiles();
virtual String readStringForBindings(const String& type);
virtual void writeString(const String& type, const String& data);
@@ -193,6 +205,7 @@
virtual void read(PasteboardPlainText&);
virtual void read(PasteboardWebContentReader&);
+ virtual void read(PasteboardFileReader&);
virtual void write(const PasteboardURL&);
virtual void writeTrustworthyWebURLsPboardType(const PasteboardURL&);
@@ -234,6 +247,7 @@
#if PLATFORM(COCOA)
explicit Pasteboard(const String& pasteboardName);
+ static bool shouldTreatCocoaTypeAsFile(const String&);
WEBCORE_EXPORT static NSArray *supportedFileUploadPasteboardTypes();
const String& name() const { return m_pasteboardName; }
long changeCount() const;
Modified: trunk/Source/WebCore/platform/StaticPasteboard.h (222655 => 222656)
--- trunk/Source/WebCore/platform/StaticPasteboard.h 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/StaticPasteboard.h 2017-09-29 18:46:51 UTC (rev 222656)
@@ -41,7 +41,8 @@
bool isStatic() const final { return true; }
bool hasData() final;
- Vector<String> types() final { return m_types; }
+ Vector<String> typesForBindings() final { return m_types; }
+ Vector<String> typesTreatedAsFiles() final { return { }; }
String readStringForBindings(const String& type) final;
void writeString(const String& type, const String& data) final;
Added: trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm (0 => 222656)
--- trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm (rev 0)
+++ trunk/Source/WebCore/platform/cocoa/PasteboardCocoa.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2017 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 "Pasteboard.h"
+
+#include "PasteboardStrategy.h"
+#include "PlatformStrategies.h"
+#include "SharedBuffer.h"
+#include <ImageIO/ImageIO.h>
+#include <wtf/ListHashSet.h>
+#include <wtf/text/StringHash.h>
+
+#if PLATFORM(IOS)
+#include <MobileCoreServices/MobileCoreServices.h>
+#endif
+
+namespace WebCore {
+
+// Making this non-inline so that WebKit 2's decoding doesn't have to include SharedBuffer.h.
+PasteboardWebContent::PasteboardWebContent() = default;
+PasteboardWebContent::~PasteboardWebContent() = default;
+
+enum class ImageType {
+ Invalid = 0,
+ TIFF,
+ PNG,
+ JPEG,
+ GIF,
+};
+
+static ImageType cocoaTypeToImageType(const String& cocoaType)
+{
+#if PLATFORM(MAC)
+ if (cocoaType == String(NSTIFFPboardType))
+ return ImageType::TIFF;
+#endif
+ if (cocoaType == String(kUTTypeTIFF))
+ return ImageType::TIFF;
+#if PLATFORM(MAC)
+ if (cocoaType == "Apple PNG pasteboard type") // NSPNGPboardType
+ return ImageType::PNG;
+#endif
+ if (cocoaType == String(kUTTypePNG))
+ return ImageType::PNG;
+ if (cocoaType == String(kUTTypeJPEG))
+ return ImageType::JPEG;
+ if (cocoaType == String(kUTTypeGIF))
+ return ImageType::GIF;
+ return ImageType::Invalid;
+}
+
+static const char* imageTypeToMIMEType(ImageType type)
+{
+ switch (type) {
+ case ImageType::Invalid:
+ return nullptr;
+ case ImageType::TIFF:
+#if PLATFORM(MAC)
+ return "image/png"; // For Web compatibility, we pretend to have PNG instead.
+#else
+ return nullptr; // Don't support TIFF on iOS for now.
+#endif
+ case ImageType::PNG:
+ return "image/png";
+ case ImageType::JPEG:
+ return "image/jpeg";
+ case ImageType::GIF:
+ return "image/gif";
+ }
+}
+
+static const char* imageTypeToFakeFilename(ImageType type)
+{
+ switch (type) {
+ case ImageType::Invalid:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ case ImageType::TIFF:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ case ImageType::PNG:
+ return "image.png";
+ case ImageType::JPEG:
+ return "image.jpeg";
+ case ImageType::GIF:
+ return "image.gif";
+ }
+}
+
+static ImageType mimeTypeToImageType(const String& mimeType)
+{
+#if PLATFORM(MAC)
+ if (mimeType == "image/tiff")
+ return ImageType::TIFF;
+#endif
+ if (mimeType == "image/png")
+ return ImageType::PNG;
+ if (mimeType == "image/jpeg")
+ return ImageType::JPEG;
+ if (mimeType == "image/gif")
+ return ImageType::GIF;
+ return ImageType::Invalid;
+}
+
+bool Pasteboard::shouldTreatCocoaTypeAsFile(const String& cocoaType)
+{
+ return cocoaTypeToImageType(cocoaType) != ImageType::Invalid;
+}
+
+Vector<String> Pasteboard::typesTreatedAsFiles()
+{
+ Vector<String> cocoaTypes;
+ platformStrategies()->pasteboardStrategy()->getTypes(cocoaTypes, m_pasteboardName);
+
+ // Enforce changeCount ourselves for security. We check after reading instead of before to be
+ // sure it doesn't change between our testing the change count and accessing the data.
+ if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
+ return { };
+
+ ListHashSet<String> result;
+ for (auto& cocoaType : cocoaTypes) {
+ if (auto* mimeType = imageTypeToMIMEType(cocoaTypeToImageType(cocoaType)))
+ result.add(mimeType);
+ }
+
+ Vector<String> types;
+ copyToVector(result, types);
+ return types;
+}
+
+void Pasteboard::read(PasteboardFileReader& reader)
+{
+ auto imageType = mimeTypeToImageType(reader.type);
+ if (imageType == ImageType::Invalid)
+ return;
+
+ String cocoaTypeToRead;
+ String tiffCocoaTypeInPasteboard;
+ Vector<String> cocoaTypes;
+ platformStrategies()->pasteboardStrategy()->getTypes(cocoaTypes, m_pasteboardName);
+ for (auto& cocoaType : cocoaTypes) {
+ auto imageTypeInPasteboard = cocoaTypeToImageType(cocoaType);
+ if (imageTypeInPasteboard == imageType) {
+ cocoaTypeToRead = cocoaType;
+ break;
+ }
+ if (tiffCocoaTypeInPasteboard.isNull() && imageTypeInPasteboard == ImageType::TIFF)
+ tiffCocoaTypeInPasteboard = cocoaType;
+ }
+
+ bool tiffWasTreatedAsPNGForWebCompatibility = imageType == ImageType::PNG && cocoaTypeToRead.isNull() && !tiffCocoaTypeInPasteboard.isNull();
+ if (tiffWasTreatedAsPNGForWebCompatibility)
+ cocoaTypeToRead = tiffCocoaTypeInPasteboard;
+
+ RefPtr<SharedBuffer> buffer = platformStrategies()->pasteboardStrategy()->bufferForType(cocoaTypeToRead, m_pasteboardName);
+
+ // Enforce changeCount ourselves for security. We check after reading instead of before to be
+ // sure it doesn't change between our testing the change count and accessing the data.
+ if (!buffer || m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
+ return;
+
+#if PLATFORM(MAC)
+ if (tiffWasTreatedAsPNGForWebCompatibility) {
+ auto tiffData = buffer->createNSData();
+ auto image = adoptNS([[NSBitmapImageRep alloc] initWithData: tiffData.get()]);
+ NSData *pngData = [image representationUsingType:NSPNGFileType properties:@{ }];
+ reader.read(imageTypeToFakeFilename(imageType), SharedBuffer::create(pngData));
+ return;
+ }
+#endif
+ reader.read(imageTypeToFakeFilename(imageType), buffer.releaseNonNull());
+}
+
+}
+
Modified: trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp (222655 => 222656)
--- trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/gtk/PasteboardGtk.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -63,15 +63,6 @@
}
#endif
-// Making this non-inline so that WebKit 2's decoding doesn't have to include Image.h.
-PasteboardImage::PasteboardImage()
-{
-}
-
-PasteboardImage::~PasteboardImage()
-{
-}
-
Pasteboard::Pasteboard(SelectionData& selectionData)
: m_selectionData(selectionData)
{
@@ -251,6 +242,10 @@
{
}
+void Pasteboard::read(PasteboardFileReader&)
+{
+}
+
bool Pasteboard::hasData()
{
readFromClipboard();
@@ -257,7 +252,7 @@
return m_selectionData->hasText() || m_selectionData->hasMarkup() || m_selectionData->hasURIList() || m_selectionData->hasImage() || m_selectionData->hasUnknownTypeData();
}
-Vector<String> Pasteboard::types()
+Vector<String> Pasteboard::typesForBindings()
{
readFromClipboard();
@@ -285,6 +280,11 @@
return types;
}
+Vector<String> Pasteboard::typesTreatedAsFiles()
+{
+ return { };
+}
+
String Pasteboard::readStringForBindings(const String& type)
{
readFromClipboard();
Modified: trunk/Source/WebCore/platform/ios/PasteboardIOS.mm (222655 => 222656)
--- trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -98,24 +98,6 @@
// FIXME: Does this need to be declared in the header file?
WEBCORE_EXPORT NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type";
-// Making this non-inline so that WebKit 2's decoding doesn't have to include SharedBuffer.h.
-PasteboardWebContent::PasteboardWebContent()
-{
-}
-
-PasteboardWebContent::~PasteboardWebContent()
-{
-}
-
-// Making this non-inline so that WebKit 2's decoding doesn't have to include Image.h.
-PasteboardImage::PasteboardImage()
-{
-}
-
-PasteboardImage::~PasteboardImage()
-{
-}
-
Pasteboard::Pasteboard()
: m_changeCount(0)
{
@@ -417,6 +399,10 @@
resultTypes.add(ASCIILiteral("text/uri-list"));
return;
}
+ if (Pasteboard::shouldTreatCocoaTypeAsFile(cocoaType)) {
+ resultTypes.add(ASCIILiteral("Files"));
+ return;
+ }
String utiType = utiTypeFromCocoaType(cocoaType);
if (!utiType.isEmpty()) {
resultTypes.add(utiType);
@@ -435,7 +421,7 @@
platformStrategies()->pasteboardStrategy()->writeToPasteboard(cocoaType.get(), data, m_pasteboardName);
}
-Vector<String> Pasteboard::types()
+Vector<String> Pasteboard::typesForBindings()
{
Vector<String> types;
if (Settings::customPasteboardDataEnabled())
Modified: trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm (222655 => 222656)
--- trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -431,6 +431,9 @@
if (UTTypeConformsTo(cfType.get(), kUTTypeURL))
return ASCIILiteral("text/uri-list");
+ if (Pasteboard::shouldTreatCocoaTypeAsFile(platformType))
+ return ASCIILiteral("Files");
+
return nullptr;
}
Modified: trunk/Source/WebCore/platform/mac/PasteboardMac.mm (222655 => 222656)
--- trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -70,24 +70,6 @@
const char WebURLPboardType[] = "public.url";
const char WebURLsWithTitlesPboardType[] = "WebURLsWithTitlesPboardType";
-// Making this non-inline so that WebKit 2's decoding doesn't have to include SharedBuffer.h.
-PasteboardWebContent::PasteboardWebContent()
-{
-}
-
-PasteboardWebContent::~PasteboardWebContent()
-{
-}
-
-// Making this non-inline so that WebKit 2's decoding doesn't have to include Image.h.
-PasteboardImage::PasteboardImage()
-{
-}
-
-PasteboardImage::~PasteboardImage()
-{
-}
-
static const Vector<String> writableTypesForURL()
{
Vector<String> types;
@@ -554,6 +536,9 @@
static void addHTMLClipboardTypesForCocoaType(ListHashSet<String>& resultTypes, const String& cocoaType, const String& pasteboardName)
{
+ if (cocoaType == "NeXT plain ascii pasteboard type")
+ return; // Skip this ancient type that gets auto-supplied by some system conversion.
+
// UTI may not do these right, so make sure we get the right, predictable result
if (cocoaType == String(NSStringPboardType) || cocoaType == String(NSPasteboardTypeString)) {
resultTypes.add(ASCIILiteral("text/plain"));
@@ -573,6 +558,10 @@
resultTypes.add(ASCIILiteral("Files"));
return;
}
+ if (Pasteboard::shouldTreatCocoaTypeAsFile(cocoaType)) {
+ resultTypes.add(ASCIILiteral("Files"));
+ return;
+ }
String utiType = utiTypeFromCocoaType(cocoaType);
if (!utiType.isEmpty()) {
resultTypes.add(utiType);
@@ -609,7 +598,7 @@
}
}
-Vector<String> Pasteboard::types()
+Vector<String> Pasteboard::typesForBindings()
{
Vector<String> types;
if (Settings::customPasteboardDataEnabled())
@@ -626,15 +615,9 @@
return types;
ListHashSet<String> result;
- // FIXME: This loop could be split into two stages. One which adds all the HTML5 specified types
- // and a second which adds all the extra types from the cocoa clipboard (which is Mac-only behavior).
- for (size_t i = 0; i < types.size(); i++) {
- if (types[i] == "NeXT plain ascii pasteboard type")
- continue; // skip this ancient type that gets auto-supplied by some system conversion
+ for (auto& cocoaType : types)
+ addHTMLClipboardTypesForCocoaType(result, cocoaType, m_pasteboardName);
- addHTMLClipboardTypesForCocoaType(result, types[i], m_pasteboardName);
- }
-
copyToVector(result, types);
return types;
}
Modified: trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm (222655 => 222656)
--- trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -105,7 +105,7 @@
if (platformType == String(NSHTMLPboardType))
return ASCIILiteral("text/html");
- if (platformType == String(NSFilenamesPboardType) || platformType == String(NSFilesPromisePboardType))
+ if (platformType == String(NSFilenamesPboardType) || platformType == String(NSFilesPromisePboardType) || Pasteboard::shouldTreatCocoaTypeAsFile(platformType))
return ASCIILiteral("Files");
return nullptr;
Modified: trunk/Source/WebCore/platform/win/PasteboardWin.cpp (222655 => 222656)
--- trunk/Source/WebCore/platform/win/PasteboardWin.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/win/PasteboardWin.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -243,7 +243,7 @@
}
}
-Vector<String> Pasteboard::types()
+Vector<String> Pasteboard::typesForBindings()
{
ListHashSet<String> results;
@@ -277,6 +277,11 @@
return vector;
}
+Vector<String> Pasteboard::typesTreatedAsFiles()
+{
+ return { };
+}
+
String Pasteboard::readStringForBindings(const String& type)
{
if (!m_dataObject && m_dragDataMap.isEmpty())
@@ -1050,6 +1055,10 @@
{
}
+void Pasteboard::read(PasteboardFileReader&)
+{
+}
+
void Pasteboard::write(const PasteboardImage&)
{
}
Modified: trunk/Source/WebCore/platform/wpe/PasteboardWPE.cpp (222655 => 222656)
--- trunk/Source/WebCore/platform/wpe/PasteboardWPE.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebCore/platform/wpe/PasteboardWPE.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -49,7 +49,7 @@
return !types.isEmpty();
}
-Vector<String> Pasteboard::types()
+Vector<String> Pasteboard::typesForBindings()
{
Vector<String> types;
platformStrategies()->pasteboardStrategy()->getTypes(types);
@@ -56,6 +56,11 @@
return types;
}
+Vector<String> Pasteboard::typesTreatedAsFiles()
+{
+ return { };
+}
+
String Pasteboard::readStringForBindings(const String& type)
{
return platformStrategies()->pasteboardStrategy()->readStringFromPasteboard(0, type);
@@ -84,6 +89,10 @@
notImplemented();
}
+void Pasteboard::read(PasteboardFileReader&)
+{
+}
+
void Pasteboard::write(const PasteboardURL& url)
{
platformStrategies()->pasteboardStrategy()->writeToPasteboard("text/plain;charset=utf-8", url.url.string());
Modified: trunk/Source/WebKit/ChangeLog (222655 => 222656)
--- trunk/Source/WebKit/ChangeLog 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebKit/ChangeLog 2017-09-29 18:46:51 UTC (rev 222656)
@@ -1,3 +1,22 @@
+2017-09-28 Ryosuke Niwa <[email protected]>
+
+ Image pasting is not working on tineye.com / gmail.com / GitHub.com due to lack of support for DataTransfer.items
+ https://bugs.webkit.org/show_bug.cgi?id=170449
+ <rdar://problem/31432525>
+
+ Reviewed by Wenson Hsieh.
+
+ Add sandbox extensions for files in the pasteboard to make copying & pasting image files work.
+ This is what we do for drag & drop but we should consider adding a mechanism to rekoke the extension in the future.
+
+ * UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
+ (WebKit::WebPasteboardProxy::getPasteboardPathnamesForType): Add sandbox extensions to the pasted files.
+ * UIProcess/WebPasteboardProxy.h:
+ * UIProcess/WebPasteboardProxy.messages.in:
+ * WebProcess/WebCoreSupport/WebPlatformStrategies.cpp:
+ (WebKit::WebPlatformStrategies::getPathnamesForType): Consume the sandbox tokens sent by the UI process permanently
+ since WebCore will now create File objects for these pasted files.
+
2017-09-29 Wenson Hsieh <[email protected]>
[iOS WK2] Implement -[WKContentView hasText] for compatibility with the UITextInput protocol
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm (222655 => 222656)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -25,8 +25,9 @@
#import "config.h"
#import "WebPasteboardProxy.h"
+
+#import "SandboxExtension.h"
#import "WebProcessProxy.h"
-
#import <WebCore/Color.h>
#import <WebCore/PlatformPasteboard.h>
#import <WebCore/SharedBuffer.h>
@@ -41,9 +42,26 @@
PlatformPasteboard(pasteboardName).getTypes(pasteboardTypes);
}
-void WebPasteboardProxy::getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames)
+void WebPasteboardProxy::getPasteboardPathnamesForType(IPC::Connection& connection, const String& pasteboardName, const String& pasteboardType,
+ Vector<String>& pathnames, SandboxExtension::HandleArray& sandboxExtensions)
{
- PlatformPasteboard(pasteboardName).getPathnamesForType(pathnames, pasteboardType);
+ for (auto* webProcessProxy : m_webProcessProxyList) {
+ if (!webProcessProxy->hasConnection(connection))
+ continue;
+
+ PlatformPasteboard(pasteboardName).getPathnamesForType(pathnames, pasteboardType);
+
+#if PLATFORM(MAC)
+ // On iOS, files are copied into app's container upon paste.
+ sandboxExtensions.allocate(pathnames.size());
+ for (size_t i = 0; i < pathnames.size(); i++) {
+ auto& filename = pathnames[i];
+ if (![[NSFileManager defaultManager] fileExistsAtPath:filename])
+ continue;
+ SandboxExtension::createHandle(filename, SandboxExtension::Type::ReadOnly, sandboxExtensions[i]);
+ }
+#endif
+ }
}
void WebPasteboardProxy::getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String& string)
Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h (222655 => 222656)
--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.h 2017-09-29 18:46:51 UTC (rev 222656)
@@ -26,6 +26,7 @@
#pragma once
#include "MessageReceiver.h"
+#include "SandboxExtension.h"
#include "SharedMemory.h"
#include <wtf/Forward.h>
#include <wtf/HashSet.h>
@@ -82,7 +83,7 @@
#if PLATFORM(COCOA)
void getNumberOfFiles(const String& pasteboardName, uint64_t& numberOfFiles);
void getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes);
- void getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames);
+ void getPasteboardPathnamesForType(IPC::Connection&, const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames, SandboxExtension::HandleArray&);
void getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String&);
void getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle&, uint64_t& size);
void pasteboardCopy(const String& fromPasteboard, const String& toPasteboard, uint64_t& newChangeCount);
Modified: trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in (222655 => 222656)
--- trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebKit/UIProcess/WebPasteboardProxy.messages.in 2017-09-29 18:46:51 UTC (rev 222656)
@@ -42,7 +42,7 @@
# Pasteboard messages.
GetNumberOfFiles(String pasteboardName) -> (uint64_t numberOfFiles)
GetPasteboardTypes(String pasteboardName) -> (Vector<String> types)
- GetPasteboardPathnamesForType(String pasteboardName, String pasteboardType) -> (Vector<String> pathnames)
+ GetPasteboardPathnamesForType(String pasteboardName, String pasteboardType) -> (Vector<String> pathnames, WebKit::SandboxExtension::HandleArray sandboxExtensions) WantsConnection
GetPasteboardStringForType(String pasteboardName, String pasteboardType) -> (String string)
GetPasteboardBufferForType(String pasteboardName, String pasteboardType) -> (WebKit::SharedMemory::Handle handle, uint64_t size)
PasteboardCopy(String fromPasteboard, String toPasteboard) -> (uint64_t changeCount)
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp (222655 => 222656)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp 2017-09-29 18:46:51 UTC (rev 222656)
@@ -192,7 +192,14 @@
void WebPlatformStrategies::getPathnamesForType(Vector<String>& pathnames, const String& pasteboardType, const String& pasteboardName)
{
- WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardPathnamesForType(pasteboardName, pasteboardType), Messages::WebPasteboardProxy::GetPasteboardPathnamesForType::Reply(pathnames), 0);
+ SandboxExtension::HandleArray sandboxExtensionsHandleArray;
+ WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardPathnamesForType(pasteboardName, pasteboardType),
+ Messages::WebPasteboardProxy::GetPasteboardPathnamesForType::Reply(pathnames, sandboxExtensionsHandleArray), 0);
+ ASSERT(pathnames.size() == sandboxExtensionsHandleArray.size());
+ for (size_t i = 0; i < sandboxExtensionsHandleArray.size(); i++) {
+ if (RefPtr<SandboxExtension> extension = SandboxExtension::create(sandboxExtensionsHandleArray[i]))
+ extension->consumePermanently();
+ }
}
String WebPlatformStrategies::stringForType(const String& pasteboardType, const String& pasteboardName)
Modified: trunk/Tools/ChangeLog (222655 => 222656)
--- trunk/Tools/ChangeLog 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Tools/ChangeLog 2017-09-29 18:46:51 UTC (rev 222656)
@@ -1,3 +1,26 @@
+2017-09-28 Ryosuke Niwa <[email protected]>
+
+ Image pasting is not working on tineye.com / gmail.com / GitHub.com due to lack of support for DataTransfer.items
+ https://bugs.webkit.org/show_bug.cgi?id=170449
+ <rdar://problem/31432525>
+
+ Reviewed by Wenson Hsieh.
+
+ Added an API test to paste an image from pasteboard. The test is shared between iOS and macOS.
+
+ The tests to paste image files are only enabled on macOS since putting files into pasteboard isn't a thing on iOS.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm: Added.
+ (writeImageDataToPasteboard):
+ (writeBundleFileToPasteboard):
+ * TestWebKitAPI/Tests/WebKitCocoa/paste-image.html: Added.
+ * TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-100px.tiff: Added.
+ * TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-200px.png: Added.
+ * TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-400px.gif: Added.
+ * TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-600px.jpg: Added.
+ * TestWebKitAPI/Tests/ios/DataInteractionTests.mm: Rebaselined the test now that types contain "Files".
+
2017-09-29 Wenson Hsieh <[email protected]>
[iOS WK2] Implement -[WKContentView hasText] for compatibility with the UITextInput protocol
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (222655 => 222656)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-09-29 18:46:51 UTC (rev 222656)
@@ -544,6 +544,12 @@
9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
9BD4239A1E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */; };
9BD4239C1E04C01C00200395 /* chinese-character-with-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD4239B1E04BFD000200395 /* chinese-character-with-image.html */; };
+ 9BD6D3A21F7B218300BD4962 /* sunset-in-cupertino-100px.tiff in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D3A11F7B202100BD4962 /* sunset-in-cupertino-100px.tiff */; };
+ 9BD6D3A31F7B218300BD4962 /* sunset-in-cupertino-200px.png in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D3A01F7B202000BD4962 /* sunset-in-cupertino-200px.png */; };
+ 9BD6D3A41F7B218300BD4962 /* sunset-in-cupertino-400px.gif in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D39F1F7B202000BD4962 /* sunset-in-cupertino-400px.gif */; };
+ 9BD6D3A51F7B218300BD4962 /* sunset-in-cupertino-600px.jpg in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D39E1F7B201E00BD4962 /* sunset-in-cupertino-600px.jpg */; };
+ 9BD6D3A71F7B21DC00BD4962 /* paste-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9BD6D3A61F7B21CC00BD4962 /* paste-image.html */; };
+ 9BDCCD871F7D0B0700009A18 /* PasteImage.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BDCCD851F7D0B0700009A18 /* PasteImage.mm */; };
9C64DC321D76198A004B598E /* YouTubePluginReplacement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9C64DC311D76198A004B598E /* YouTubePluginReplacement.cpp */; };
A10F047E1E3AD29C00C95E19 /* NSFileManagerExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = A10F047C1E3AD29C00C95E19 /* NSFileManagerExtras.mm */; };
A1146A8D1D2D7115000FE710 /* ContentFiltering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1146A8A1D2D704F000FE710 /* ContentFiltering.mm */; };
@@ -968,6 +974,7 @@
A1C4FB731BACD1CA003742D0 /* pages.pages in Copy Resources */,
A57A34F216AF6B2B00C2501F /* PageVisibilityStateWithWindowChanges.html in Copy Resources */,
A1409AD91E7254D4004949D9 /* password-protected.pages in Copy Resources */,
+ 9BD6D3A71F7B21DC00BD4962 /* paste-image.html in Copy Resources */,
3FCC4FE81EC4E8CA0076E37C /* PictureInPictureDelegate.html in Copy Resources */,
F415086D1DA040C50044BE9B /* play-audio-on-click.html in Copy Resources */,
F41AB9A81EF4696B0083FA08 /* prevent-operation.html in Copy Resources */,
@@ -991,6 +998,10 @@
C01A23F21266156700C9ED55 /* spacebar-scrolling.html in Copy Resources */,
E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */,
515BE16F1D428BB100DD7C68 /* StoreBlobToBeDeleted.html in Copy Resources */,
+ 9BD6D3A21F7B218300BD4962 /* sunset-in-cupertino-100px.tiff in Copy Resources */,
+ 9BD6D3A31F7B218300BD4962 /* sunset-in-cupertino-200px.png in Copy Resources */,
+ 9BD6D3A41F7B218300BD4962 /* sunset-in-cupertino-400px.gif in Copy Resources */,
+ 9BD6D3A51F7B218300BD4962 /* sunset-in-cupertino-600px.jpg in Copy Resources */,
CD59F53519E9110D00CF1835 /* test-mse.mp4 in Copy Resources */,
C95984F71E36BCEF002C0D45 /* test-without-audio-track.mp4 in Copy Resources */,
524BBCA119E30C77002F1AF1 /* test.mp4 in Copy Resources */,
@@ -1492,6 +1503,12 @@
9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstResponderScrollingPosition.mm; sourceTree = "<group>"; };
9BD423991E04BD9800200395 /* AttributedSubstringForProposedRangeWithImage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AttributedSubstringForProposedRangeWithImage.mm; sourceTree = "<group>"; };
9BD4239B1E04BFD000200395 /* chinese-character-with-image.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "chinese-character-with-image.html"; sourceTree = "<group>"; };
+ 9BD6D39E1F7B201E00BD4962 /* sunset-in-cupertino-600px.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "sunset-in-cupertino-600px.jpg"; sourceTree = "<group>"; };
+ 9BD6D39F1F7B202000BD4962 /* sunset-in-cupertino-400px.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "sunset-in-cupertino-400px.gif"; sourceTree = "<group>"; };
+ 9BD6D3A01F7B202000BD4962 /* sunset-in-cupertino-200px.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "sunset-in-cupertino-200px.png"; sourceTree = "<group>"; };
+ 9BD6D3A11F7B202100BD4962 /* sunset-in-cupertino-100px.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "sunset-in-cupertino-100px.tiff"; sourceTree = "<group>"; };
+ 9BD6D3A61F7B21CC00BD4962 /* paste-image.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "paste-image.html"; sourceTree = "<group>"; };
+ 9BDCCD851F7D0B0700009A18 /* PasteImage.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = PasteImage.mm; sourceTree = "<group>"; };
9C64DC311D76198A004B598E /* YouTubePluginReplacement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YouTubePluginReplacement.cpp; sourceTree = "<group>"; };
A10F047C1E3AD29C00C95E19 /* NSFileManagerExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NSFileManagerExtras.mm; sourceTree = "<group>"; };
A1146A8A1D2D704F000FE710 /* ContentFiltering.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentFiltering.mm; sourceTree = "<group>"; };
@@ -1988,6 +2005,7 @@
37A22AA51DCAA27200AFBFC4 /* ObservedRenderingProgressEventsAfterCrash.mm */,
CEA6CF2219CCF5BD0064F5A7 /* OpenAndCloseWindow.mm */,
CEBCA12E1E3A660100C73293 /* OverrideContentSecurityPolicy.mm */,
+ 9BDCCD851F7D0B0700009A18 /* PasteImage.mm */,
3FCC4FE41EC4E8520076E37C /* PictureInPictureDelegate.mm */,
83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */,
C95501BE19AD2FAF0049BE3E /* Preferences.mm */,
@@ -2280,6 +2298,7 @@
CEBCA1361E3A803400C73293 /* page-without-csp-iframe.html */,
CEBCA1371E3A803400C73293 /* page-without-csp.html */,
A1409AD81E7254AC004949D9 /* password-protected.pages */,
+ 9BD6D3A61F7B21CC00BD4962 /* paste-image.html */,
3FCC4FE61EC4E87E0076E37C /* PictureInPictureDelegate.html */,
F415086C1DA040C10044BE9B /* play-audio-on-click.html */,
F41AB9941EF4692C0083FA08 /* prevent-operation.html */,
@@ -2290,6 +2309,10 @@
C9B4AD291ECA6EA500F5FEA0 /* silence-long.m4a */,
F4F405BB1D4C0CF8007A9707 /* skinny-autoplaying-video-with-audio.html */,
515BE16E1D4288FF00DD7C68 /* StoreBlobToBeDeleted.html */,
+ 9BD6D3A11F7B202100BD4962 /* sunset-in-cupertino-100px.tiff */,
+ 9BD6D3A01F7B202000BD4962 /* sunset-in-cupertino-200px.png */,
+ 9BD6D39F1F7B202000BD4962 /* sunset-in-cupertino-400px.gif */,
+ 9BD6D39E1F7B201E00BD4962 /* sunset-in-cupertino-600px.jpg */,
2E9896141D8F092B00739892 /* text-and-password-inputs.html */,
F41AB9951EF4692C0083FA08 /* textarea-to-input.html */,
F4451C751EB8FD7C0020C5DA /* two-paragraph-contenteditable.html */,
@@ -3339,6 +3362,7 @@
7CCE7F091A411AE600447C4C /* ParentFrame.cpp in Sources */,
7C83E0511D0A641800FEBCF3 /* ParsedContentRange.cpp in Sources */,
7CCE7F0A1A411AE600447C4C /* PasteboardNotifications.mm in Sources */,
+ 9BDCCD871F7D0B0700009A18 /* PasteImage.mm in Sources */,
7C83E0531D0A643A00FEBCF3 /* PendingAPIRequestURL.cpp in Sources */,
3FCC4FE51EC4E8520076E37C /* PictureInPictureDelegate.mm in Sources */,
7CCE7EAF1A411A3800447C4C /* PlatformUtilities.cpp in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm (0 => 222656)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PasteImage.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2017 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"
+
+#if WK_API_ENABLED && PLATFORM(COCOA)
+
+#import "AppKitSPI.h"
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import <wtf/BlockPtr.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/text/WTFString.h>
+
+#if PLATFORM(IOS)
+#include <MobileCoreServices/MobileCoreServices.h>
+#endif
+
+@interface WKWebView ()
+- (void)paste:(id)sender;
+@end
+
+#if PLATFORM(MAC)
+void writeImageDataToPasteboard(NSString *type, NSData *data)
+{
+ [[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:type] owner:nil];
+ [[NSPasteboard generalPasteboard] setData:data forType:type];
+}
+#else
+void writeImageDataToPasteboard(NSString *type, NSData *data)
+{
+ [[UIPasteboard generalPasteboard] setItems:@[[NSDictionary dictionaryWithObject:data forKey:type]]];
+}
+#endif
+
+TEST(PasteImage, PasteGIFImage)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ auto *data = "" dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sunset-in-cupertino-400px" ofType:@"gif" inDirectory:@"TestWebKitAPI.resources"]];
+ writeImageDataToPasteboard((NSString *)kUTTypeGIF, data);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/gif').toString()"]);
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/tiff').toString()"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"gifItem = dataTransfer.items.find((item) => item.type == 'image/gif'); (!!gifItem).toString()"]);
+ EXPECT_WK_STREQ("file", [webView stringByEvaluatingJavaScript:@"gifItem.kind"]);
+ EXPECT_WK_STREQ("image/gif", [webView stringByEvaluatingJavaScript:@"gifItem.file.type"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.includes(gifItem.file).toString()"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(gifItem.file)"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("400", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+TEST(PasteImage, PasteJPEGImage)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ auto *data = "" dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sunset-in-cupertino-600px" ofType:@"jpg" inDirectory:@"TestWebKitAPI.resources"]];
+ writeImageDataToPasteboard((NSString *)kUTTypeJPEG, data);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/gif').toString()"]);
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/tiff').toString()"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"jpegItem = dataTransfer.items.find((item) => item.type == 'image/jpeg'); (!!jpegItem).toString()"]);
+ EXPECT_WK_STREQ("file", [webView stringByEvaluatingJavaScript:@"jpegItem.kind"]);
+ EXPECT_WK_STREQ("image/jpeg", [webView stringByEvaluatingJavaScript:@"jpegItem.file.type"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.includes(jpegItem.file).toString()"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(jpegItem.file)"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("600", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+TEST(PasteImage, PastePNGImage)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ auto *data = "" dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sunset-in-cupertino-200px" ofType:@"png" inDirectory:@"TestWebKitAPI.resources"]];
+ writeImageDataToPasteboard((NSString *)kUTTypePNG, data);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/gif').toString()"]);
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/tiff').toString()"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"pngItem = dataTransfer.items.find((item) => item.type == 'image/png'); (!!pngItem).toString()"]);
+ EXPECT_WK_STREQ("file", [webView stringByEvaluatingJavaScript:@"pngItem.kind"]);
+ EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"pngItem.file.type"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.includes(pngItem.file).toString()"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(pngItem.file)"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("200", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+#if PLATFORM(MAC)
+void writeBundleFileToPasteboard(id object)
+{
+ [[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
+ [[NSPasteboard generalPasteboard] writeObjects:[NSArray arrayWithObjects:object, nil]];
+}
+
+TEST(PasteImage, PasteGIFFile)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ NSURL *url = "" mainBundle] URLForResource:@"sunset-in-cupertino-400px" withExtension:@"gif" subdirectory:@"TestWebKitAPI.resources"];
+ writeBundleFileToPasteboard(url);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/png').toString()"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.items.filter((item) => item.kind == 'file').length"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.length"]);
+ EXPECT_WK_STREQ("image/gif", [webView stringByEvaluatingJavaScript:@"file = dataTransfer.files[0]; file.type"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(file)"];
+ [webView waitForMessage:@"loaded"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("400", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+TEST(PasteImage, PasteJPEGFile)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ NSURL *url = "" mainBundle] URLForResource:@"sunset-in-cupertino-600px" withExtension:@"jpg" subdirectory:@"TestWebKitAPI.resources"];
+ writeBundleFileToPasteboard(url);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/jpeg').toString()"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.items.filter((item) => item.kind == 'file').length"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.length"]);
+ EXPECT_WK_STREQ("image/jpeg", [webView stringByEvaluatingJavaScript:@"file = dataTransfer.files[0]; file.type"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(file)"];
+ [webView waitForMessage:@"loaded"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("600", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+TEST(PasteImage, PastePNGFile)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ NSURL *url = "" mainBundle] URLForResource:@"sunset-in-cupertino-200px" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"];
+ writeBundleFileToPasteboard(url);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/png').toString()"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.items.filter((item) => item.kind == 'file').length"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.length"]);
+ EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"file = dataTransfer.files[0]; file.type"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(file)"];
+ [webView waitForMessage:@"loaded"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("200", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+TEST(PasteImage, PasteTIFFFile)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ NSURL *url = "" mainBundle] URLForResource:@"sunset-in-cupertino-100px" withExtension:@"tiff" subdirectory:@"TestWebKitAPI.resources"];
+ writeBundleFileToPasteboard(url);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/tiff').toString()"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.items.filter((item) => item.kind == 'file').length"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.length"]);
+ EXPECT_WK_STREQ("image/tiff", [webView stringByEvaluatingJavaScript:@"file = dataTransfer.files[0]; file.type"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(file)"];
+ [webView waitForMessage:@"loaded"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("100", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+TEST(PasteImage, PasteLegacyTIFFImage)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ auto *data = "" dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sunset-in-cupertino-100px" ofType:@"tiff" inDirectory:@"TestWebKitAPI.resources"]];
+ writeImageDataToPasteboard(NSTIFFPboardType, data);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/png').toString()"]);
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/tiff').toString()"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.items.filter((item) => item.kind == 'file').length"]);
+ EXPECT_WK_STREQ("1", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.length"]);
+ EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"file = dataTransfer.files[0]; file.type"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(file)"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("100", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+
+TEST(PasteImage, PasteTIFFImage)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView synchronouslyLoadTestPageNamed:@"paste-image"];
+
+ auto *data = "" dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sunset-in-cupertino-100px" ofType:@"tiff" inDirectory:@"TestWebKitAPI.resources"]];
+ writeImageDataToPasteboard((NSString *)kUTTypeTIFF, data);
+ [webView paste:nil];
+
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/gif').toString()"]);
+ EXPECT_WK_STREQ("false", [webView stringByEvaluatingJavaScript:@"dataTransfer.types.includes('image/png').toString()"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"pngItem = dataTransfer.items.find((item) => item.type == 'image/png'); (!!pngItem).toString()"]);
+ EXPECT_WK_STREQ("file", [webView stringByEvaluatingJavaScript:@"pngItem.kind"]);
+ EXPECT_WK_STREQ("image/png", [webView stringByEvaluatingJavaScript:@"pngItem.file.type"]);
+ EXPECT_WK_STREQ("true", [webView stringByEvaluatingJavaScript:@"dataTransfer.files.includes(pngItem.file).toString()"]);
+
+ [webView stringByEvaluatingJavaScript:@"insertFileAsImage(pngItem.file)"];
+ EXPECT_WK_STREQ("blob:", [webView stringByEvaluatingJavaScript:@"url = "" URL(imageElement.src); url.protocol"]);
+ EXPECT_WK_STREQ("100", [webView stringByEvaluatingJavaScript:@"imageElement.width"]);
+}
+#endif
+
+#endif // WK_API_ENABLED && PLATFORM(MAC)
+
+
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/paste-image.html (0 => 222656)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/paste-image.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/paste-image.html 2017-09-29 18:46:51 UTC (rev 222656)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="editor" contenteditable></div>
+<script>
+const editor = document.getElementById('editor');
+editor.focus();
+
+var dataTransfer = {};
+editor.addEventListener('paste', (event) => {
+ dataTransfer.types = Array.from(event.clipboardData.types);
+ dataTransfer.files = Array.from(event.clipboardData.files);
+ dataTransfer.items = Array.from(event.clipboardData.items).map(cloneItem);
+});
+
+function cloneItem(item) {
+ return {
+ kind: item.kind,
+ type: item.type,
+ file: item.getAsFile(),
+ }
+}
+
+var imageElement;
+function insertFileAsImage(file) {
+ imageElement = document.createElement('img');
+ imageElement._onload_ = () => window.webkit.messageHandlers.testHandler.postMessage('loaded');
+ imageElement.src = ""
+ document.body.appendChild(imageElement);
+}
+
+</script>
+</body>
+</html>
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-100px.tiff
(Binary files differ)
Index: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-100px.tiff
===================================================================
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-100px.tiff 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-100px.tiff 2017-09-29 18:46:51 UTC (rev 222656)
Property changes on: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-100px.tiff
___________________________________________________________________
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-200px.png
(Binary files differ)
Index: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-200px.png
===================================================================
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-200px.png 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-200px.png 2017-09-29 18:46:51 UTC (rev 222656)
Property changes on: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-200px.png
___________________________________________________________________
Added: svn:mime-type
+image/png
\ No newline at end of property
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-400px.gif
(Binary files differ)
Index: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-400px.gif
===================================================================
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-400px.gif 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-400px.gif 2017-09-29 18:46:51 UTC (rev 222656)
Property changes on: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-400px.gif
___________________________________________________________________
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-600px.jpg
(Binary files differ)
Index: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-600px.jpg
===================================================================
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-600px.jpg 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-600px.jpg 2017-09-29 18:46:51 UTC (rev 222656)
Property changes on: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/sunset-in-cupertino-600px.jpg
___________________________________________________________________
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
Modified: trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm (222655 => 222656)
--- trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm 2017-09-29 18:37:28 UTC (rev 222655)
+++ trunk/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm 2017-09-29 18:46:51 UTC (rev 222656)
@@ -1557,8 +1557,8 @@
// File URLs should never be exposed directly to web content, so DataTransfer.getData should return an empty string here.
checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{
- @"dragover": @{ @"text/uri-list" : @"" },
- @"drop": @{ @"text/uri-list" : @"" }
+ @"dragover": @{ @"Files": @"", @"text/uri-list" : @"" },
+ @"drop": @{ @"Files": @"", @"text/uri-list" : @"" }
});
}