Diff
Modified: trunk/Source/WebCore/ChangeLog (245838 => 245839)
--- trunk/Source/WebCore/ChangeLog 2019-05-29 02:27:20 UTC (rev 245838)
+++ trunk/Source/WebCore/ChangeLog 2019-05-29 02:56:09 UTC (rev 245839)
@@ -1,3 +1,39 @@
+2019-05-28 Wenson Hsieh <[email protected]>
+
+ [iOS] Respect NSItemProvider's registered types when dropping files that are loaded in-place
+ https://bugs.webkit.org/show_bug.cgi?id=198315
+ <rdar://problem/51183762>
+
+ Reviewed by Tim Horton.
+
+ Currently, logic in PasteboardIOS.mm and WebContentReaderCocoa.mm attempts to deduce the content type from the
+ file path when dropping attachments on iOS. Instead, we should be plumbing the content type through to the
+ reader.
+
+ Test: WKAttachmentTestsIOS.InsertDroppedImageWithNonImageFileExtension
+
+ * editing/WebContentReader.h:
+ * editing/cocoa/WebContentReaderCocoa.mm:
+ (WebCore::typeForAttachmentElement):
+
+ Add a helper method to determine which type to use in attachment elements. This makes the paste
+ (attachmentForData) and drop (attachmentForFilePaths) behave the same way, with respect to the type attribute
+ used to represent the attachment.
+
+ (WebCore::attachmentForFilePath):
+
+ Use the content type, if specified; otherwise, fall back to deducing it from the file path.
+
+ (WebCore::attachmentForData):
+ (WebCore::WebContentReader::readFilePath):
+ * platform/Pasteboard.h:
+ (WebCore::PasteboardWebContentReader::readFilePath):
+
+ Pass the highest fidelity representation's content type to the web content reader.
+
+ * platform/ios/PasteboardIOS.mm:
+ (WebCore::Pasteboard::readRespectingUTIFidelities):
+
2019-05-28 Myles C. Maxfield <[email protected]>
Move idempotent text autosizing to StyleTreeResolver
Modified: trunk/Source/WebCore/editing/WebContentReader.h (245838 => 245839)
--- trunk/Source/WebCore/editing/WebContentReader.h 2019-05-29 02:27:20 UTC (rev 245838)
+++ trunk/Source/WebCore/editing/WebContentReader.h 2019-05-29 02:56:09 UTC (rev 245839)
@@ -71,7 +71,7 @@
private:
#if PLATFORM(COCOA)
bool readWebArchive(SharedBuffer&) override;
- bool readFilePath(const String&, Optional<FloatSize> preferredPresentationSize = { }) override;
+ bool readFilePath(const String&, Optional<FloatSize> preferredPresentationSize = { }, const String& contentType = { }) override;
bool readFilePaths(const Vector<String>&) override;
bool readHTML(const String&) override;
bool readRTFD(SharedBuffer&) override;
@@ -95,7 +95,7 @@
private:
#if PLATFORM(COCOA)
bool readWebArchive(SharedBuffer&) override;
- bool readFilePath(const String&, Optional<FloatSize> = { }) override { return false; }
+ bool readFilePath(const String&, Optional<FloatSize> = { }, const String& = { }) override { return false; }
bool readFilePaths(const Vector<String>&) override { return false; }
bool readHTML(const String&) override;
bool readRTFD(SharedBuffer&) override;
Modified: trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm (245838 => 245839)
--- trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2019-05-29 02:27:20 UTC (rev 245838)
+++ trunk/Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm 2019-05-29 02:56:09 UTC (rev 245839)
@@ -695,8 +695,17 @@
#if ENABLE(ATTACHMENT_ELEMENT)
-static Ref<HTMLElement> attachmentForFilePath(Frame& frame, const String& path, Optional<FloatSize> preferredSize)
+static String typeForAttachmentElement(const String& contentType)
{
+ if (contentType.isEmpty())
+ return { };
+
+ auto mimeType = mimeTypeFromContentType(contentType);
+ return mimeType.isEmpty() ? contentType : mimeType;
+}
+
+static Ref<HTMLElement> attachmentForFilePath(Frame& frame, const String& path, Optional<FloatSize> preferredSize, const String& explicitContentType)
+{
auto document = makeRef(*frame.document());
auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, document);
if (!supportsClientSideAttachmentData(frame)) {
@@ -704,17 +713,23 @@
return attachment;
}
- String contentType;
+ bool isDirectory = FileSystem::fileIsDirectory(path, FileSystem::ShouldFollowSymbolicLinks::Yes);
+ String contentType = typeForAttachmentElement(explicitContentType);
+ if (contentType.isEmpty()) {
+ if (isDirectory)
+ contentType = kUTTypeDirectory;
+ else {
+ contentType = File::contentTypeForFile(path);
+ if (contentType.isEmpty())
+ contentType = kUTTypeData;
+ }
+ }
+
Optional<uint64_t> fileSizeForDisplay;
- if (FileSystem::fileIsDirectory(path, FileSystem::ShouldFollowSymbolicLinks::Yes))
- contentType = kUTTypeDirectory;
- else {
+ if (!isDirectory) {
long long fileSize;
FileSystem::getFileSize(path, fileSize);
fileSizeForDisplay = fileSize;
- contentType = File::contentTypeForFile(path);
- if (contentType.isEmpty())
- contentType = kUTTypeData;
}
frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), contentType, path);
@@ -738,8 +753,7 @@
{
auto document = makeRef(*frame.document());
auto attachment = HTMLAttachmentElement::create(HTMLNames::attachmentTag, document);
- auto mimeType = mimeTypeFromContentType(contentType);
- auto typeForAttachmentElement = mimeType.isEmpty() ? contentType : mimeType;
+ auto attachmentType = typeForAttachmentElement(contentType);
// FIXME: We should instead ask CoreServices for a preferred name corresponding to the given content type.
static const char* defaultAttachmentName = "file";
@@ -751,15 +765,15 @@
fileName = name;
if (!supportsClientSideAttachmentData(frame)) {
- attachment->setFile(File::create(Blob::create(buffer, WTFMove(typeForAttachmentElement)), fileName));
+ attachment->setFile(File::create(Blob::create(buffer, WTFMove(attachmentType)), fileName));
return attachment;
}
- frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), typeForAttachmentElement, fileName, buffer);
+ frame.editor().registerAttachmentIdentifier(attachment->ensureUniqueIdentifier(), attachmentType, fileName, buffer);
- if (contentTypeIsSuitableForInlineImageRepresentation(typeForAttachmentElement)) {
+ if (contentTypeIsSuitableForInlineImageRepresentation(attachmentType)) {
auto image = HTMLImageElement::create(document);
- image->setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(document, File::create(Blob::create(buffer, WTFMove(typeForAttachmentElement)), WTFMove(fileName))));
+ image->setAttributeWithoutSynchronization(HTMLNames::srcAttr, DOMURL::createObjectURL(document, File::create(Blob::create(buffer, WTFMove(attachmentType)), WTFMove(fileName))));
image->setAttachmentElement(WTFMove(attachment));
if (preferredSize) {
image->setAttributeWithoutSynchronization(HTMLNames::widthAttr, AtomicString::number(preferredSize->width()));
@@ -768,13 +782,13 @@
return image;
}
- attachment->updateAttributes({ buffer.size() }, WTFMove(typeForAttachmentElement), WTFMove(fileName));
+ attachment->updateAttributes({ buffer.size() }, WTFMove(attachmentType), WTFMove(fileName));
return attachment;
}
#endif // ENABLE(ATTACHMENT_ELEMENT)
-bool WebContentReader::readFilePath(const String& path, Optional<FloatSize> preferredPresentationSize)
+bool WebContentReader::readFilePath(const String& path, Optional<FloatSize> preferredPresentationSize, const String& contentType)
{
if (path.isEmpty() || !frame.document())
return false;
@@ -785,7 +799,7 @@
#if ENABLE(ATTACHMENT_ELEMENT)
if (RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled())
- fragment->appendChild(attachmentForFilePath(frame, path, preferredPresentationSize));
+ fragment->appendChild(attachmentForFilePath(frame, path, preferredPresentationSize, contentType));
#endif
return true;
Modified: trunk/Source/WebCore/platform/Pasteboard.h (245838 => 245839)
--- trunk/Source/WebCore/platform/Pasteboard.h 2019-05-29 02:27:20 UTC (rev 245838)
+++ trunk/Source/WebCore/platform/Pasteboard.h 2019-05-29 02:56:09 UTC (rev 245839)
@@ -136,7 +136,7 @@
#if PLATFORM(COCOA)
virtual bool readWebArchive(SharedBuffer&) = 0;
- virtual bool readFilePath(const String&, Optional<FloatSize> preferredPresentationSize = { }) = 0;
+ virtual bool readFilePath(const String&, Optional<FloatSize> preferredPresentationSize = { }, const String& contentType = { }) = 0;
virtual bool readFilePaths(const Vector<String>&) = 0;
virtual bool readHTML(const String&) = 0;
virtual bool readRTFD(SharedBuffer&) = 0;
Modified: trunk/Source/WebCore/platform/ios/PasteboardIOS.mm (245838 => 245839)
--- trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2019-05-29 02:27:20 UTC (rev 245838)
+++ trunk/Source/WebCore/platform/ios/PasteboardIOS.mm 2019-05-29 02:56:09 UTC (rev 245839)
@@ -345,9 +345,10 @@
auto info = strategy.informationForItemAtIndex(index, m_pasteboardName);
auto attachmentFilePath = info.pathForHighestFidelityItem();
bool canReadAttachment = policy == WebContentReadingPolicy::AnyType && RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() && !attachmentFilePath.isEmpty();
+ auto contentType = info.contentTypeForHighestFidelityItem();
if (canReadAttachment && prefersAttachmentRepresentation(info)) {
- readURLAlongsideAttachmentIfNecessary(reader, strategy, info.contentTypeForHighestFidelityItem(), m_pasteboardName, index);
- reader.readFilePath(WTFMove(attachmentFilePath), info.preferredPresentationSize);
+ readURLAlongsideAttachmentIfNecessary(reader, strategy, contentType, m_pasteboardName, index);
+ reader.readFilePath(WTFMove(attachmentFilePath), info.preferredPresentationSize, contentType);
continue;
}
#endif
@@ -366,7 +367,7 @@
}
#if ENABLE(ATTACHMENT_ELEMENT)
if (canReadAttachment && result == ReaderResult::DidNotReadType)
- reader.readFilePath(WTFMove(attachmentFilePath), info.preferredPresentationSize);
+ reader.readFilePath(WTFMove(attachmentFilePath), info.preferredPresentationSize, contentType);
#endif
}
}
Modified: trunk/Tools/ChangeLog (245838 => 245839)
--- trunk/Tools/ChangeLog 2019-05-29 02:27:20 UTC (rev 245838)
+++ trunk/Tools/ChangeLog 2019-05-29 02:56:09 UTC (rev 245839)
@@ -1,3 +1,21 @@
+2019-05-28 Wenson Hsieh <[email protected]>
+
+ [iOS] Respect NSItemProvider's registered types when dropping files that are loaded in-place
+ https://bugs.webkit.org/show_bug.cgi?id=198315
+ <rdar://problem/51183762>
+
+ Reviewed by Tim Horton.
+
+ Adds a new API test to verify that when dropping a file that is loaded in-place with a file extension that is
+ not a .png (but was registered to the item provider as "public.png"), the resulting attachment is contained in
+ an image element, and the resulting attachment info indicates that the dropped attachment is a png file.
+
+ Additionally, rebaseline some existing tests.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+ (runTestWithTemporaryImageFile):
+ (TestWebKitAPI::TEST):
+
2019-05-28 Yusuke Suzuki <[email protected]>
GCHeapInspector should accept weird filename
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm (245838 => 245839)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2019-05-29 02:27:20 UTC (rev 245838)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm 2019-05-29 02:56:09 UTC (rev 245839)
@@ -410,6 +410,24 @@
}
}
+#if PLATFORM(IOS_FAMILY)
+
+static void runTestWithTemporaryImageFile(NSString *fileName, void(^runTest)(NSURL *fileURL))
+{
+ NSFileManager *defaultManager = [NSFileManager defaultManager];
+ auto temporaryFilePath = retainPtr([NSTemporaryDirectory() stringByAppendingPathComponent:fileName]);
+ auto temporaryFileURL = retainPtr([NSURL fileURLWithPath:temporaryFilePath.get()]);
+ [defaultManager removeItemAtURL:temporaryFileURL.get() error:nil];
+ [testImageData() writeToFile:temporaryFilePath.get() atomically:YES];
+ @try {
+ runTest(temporaryFileURL.get());
+ } @finally {
+ [defaultManager removeItemAtURL:temporaryFileURL.get() error:nil];
+ }
+}
+
+#endif // PLATFORM(IOS_FAMILY)
+
static void simulateFolderDragWithURL(DragAndDropSimulator *simulator, NSURL *folderURL)
{
#if PLATFORM(MAC)
@@ -788,8 +806,13 @@
TestWKWebView *webView = [simulator webView];
auto attachment = retainPtr([simulator insertedAttachments].firstObject);
+#if PLATFORM(IOS_FAMILY)
+ NSString *expectedType = (__bridge NSString *)kUTTypeFolder;
+#else
+ NSString *expectedType = (__bridge NSString *)kUTTypeDirectory;
+#endif
EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
- EXPECT_WK_STREQ((__bridge NSString *)kUTTypeDirectory, [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
+ EXPECT_WK_STREQ(expectedType, [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
EXPECT_WK_STREQ(folderURL.lastPathComponent, [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
NSFileWrapper *image = [attachment info].fileWrapper.fileWrappers[@"image.png"];
@@ -1704,9 +1727,9 @@
[webView expectElementCount:2 querySelector:@"ATTACHMENT"];
EXPECT_WK_STREQ("hello.rtf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]);
- EXPECT_WK_STREQ("text/rtf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
+ EXPECT_WK_STREQ((__bridge NSString *)kUTTypeFlatRTFD, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
EXPECT_WK_STREQ("world.txt", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('title')"]);
- EXPECT_WK_STREQ("text/plain", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]);
+ EXPECT_WK_STREQ((__bridge NSString *)kUTTypeUTF8PlainText, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]);
}
TEST(WKAttachmentTestsIOS, InsertDroppedZipArchiveAsAttachment)
@@ -1763,7 +1786,7 @@
[webView expectElementTagsInOrder:@[ @"ATTACHMENT", @"A", @"ATTACHMENT" ]];
EXPECT_WK_STREQ("first.txt", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]);
- EXPECT_WK_STREQ("text/plain", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
+ EXPECT_WK_STREQ((__bridge NSString *)kUTTypeUTF8PlainText, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
EXPECT_WK_STREQ([appleURL absoluteString], [webView valueOfAttribute:@"href" forQuerySelector:@"a"]);
EXPECT_WK_STREQ("second.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('title')"]);
EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]);
@@ -1966,6 +1989,32 @@
EXPECT_TRUE([webView canPerformAction:@selector(paste:) withSender:nil]);
}
+TEST(WKAttachmentTestsIOS, InsertDroppedImageWithNonImageFileExtension)
+{
+ runTestWithTemporaryImageFile(@"image.hello", ^(NSURL *fileURL) {
+ auto item = adoptNS([[NSItemProvider alloc] init]);
+ [item setSuggestedName:@"image.hello"];
+ [item registerFileRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypePNG fileOptions:NSItemProviderFileOptionOpenInPlace visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(void (^callback)(NSURL *, BOOL, NSError *))
+ {
+ callback(fileURL, YES, nil);
+ return nil;
+ }];
+
+ auto webView = webViewForTestingAttachments();
+ auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
+ [dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
+ [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];
+
+ EXPECT_EQ(1U, [dragAndDropSimulator insertedAttachments].count);
+ _WKAttachment *attachment = [dragAndDropSimulator insertedAttachments].firstObject;
+ _WKAttachmentInfo *info = attachment.info;
+ EXPECT_WK_STREQ("image/png", info.contentType);
+ EXPECT_WK_STREQ("image.hello", info.filePath.lastPathComponent);
+ EXPECT_WK_STREQ("image.hello", info.name);
+ [webView expectElementCount:1 querySelector:@"IMG"];
+ });
+}
+
#if HAVE(PENCILKIT)
static BOOL forEachViewInHierarchy(UIView *view, void(^mapFunction)(UIView *subview, BOOL *stop))
{