Diff
Modified: trunk/Tools/ChangeLog (234975 => 234976)
--- trunk/Tools/ChangeLog 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/ChangeLog 2018-08-17 04:58:49 UTC (rev 234976)
@@ -1,3 +1,84 @@
+2018-08-16 Wenson Hsieh <[email protected]>
+
+ [macOS] [WK2] Add infrastructure to test receiving file promises on drop
+ https://bugs.webkit.org/show_bug.cgi?id=188583
+
+ Reviewed by Andy Estes.
+
+ Enable testing file promise drop handling on the WebKit2 port of macOS by introducing a subclass of
+ NSFilePromiseReceiver and implementing `-enumerateDraggingItemsWithOptions:forView:…` on TestDraggingInfo (the
+ concrete NSDraggingInfo implementation used by DragAndDropSimulator) using the mock file receiver. Also
+ introduces 3 new macOS tests. See below for more details.
+
+ A large portion of this logic is ported over from DumpRenderTree testing infrastructure added in r229297. In a
+ future patch, we should introduce a way to write code common to both API tests, WebKitTestRunner and
+ DumpRenderTree, and make this code shared among all three testing harnesses.
+
+ Tests: DragAndDropTests.DragImageElementIntoFileUpload
+ DragAndDropTests.DragPromisedImageFileIntoFileUpload
+ DragAndDropTests.DragImageFileIntoFileUpload
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm:
+ (TEST):
+
+ Drive-by fix: Replace NSMakePoint with CGPointMake.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/image-and-file-upload.html:
+
+ Add a new test page consisting of an image and a "file upload" area that updates exercises DataTransfer API to
+ load the dropped image.
+
+ * TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm:
+ (waitForConditionWithLogging):
+
+ Add a helper function to wait for a condition to evaluate to true. To make failures more informative,
+ additionally add a mechanism to log a warning message after a given timeout, if the condition has yet to be met.
+
+ (TEST):
+
+ Add new tests to exercise a few cases of file upload in WebKit, including: (1) dragging from an image element,
+ (2) dragging files written to the pasteboard as promises, and (3) files written to the pasteboard as file URLs.
+
+ * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+
+ Surface the new functionality provided by the file promise receiver mock via two new methods on
+ DragAndDropSimulator to (1) write files as file promises to the pasteboard, and (2) write files as file paths
+ directly to the pasteboard.
+
+ * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm:
+ (-[DragAndDropSimulator performDragInWebView:atLocation:withImage:pasteboard:source:]):
+ (-[DragAndDropSimulator externalPromisedFiles]):
+ (getFilePathsAndTypeIdentifiers):
+ (-[DragAndDropSimulator writePromisedFiles:]):
+ (-[DragAndDropSimulator writeFiles:]):
+ * TestWebKitAPI/mac/TestDraggingInfo.h:
+ * TestWebKitAPI/mac/TestDraggingInfo.mm:
+ (-[TestDraggingInfo initWithDragAndDropSimulator:]):
+ (-[TestDraggingInfo filePromiseReceivers]):
+ (-[TestDraggingInfo enumerateDraggingItemsWithOptions:forView:classes:searchOptions:usingBlock:]):
+
+ Implement this by invoking the given block with a TestFilePromiseReceiver. While all other classes are
+ unhandled by this testing code, WebKit only calls into this with [NSFilePromiseReceiver class], this is
+ currently sufficient for testing purposes.
+
+ * TestWebKitAPI/mac/TestFilePromiseReceiver.h: Copied from Tools/TestWebKitAPI/mac/TestDraggingInfo.h.
+ * TestWebKitAPI/mac/TestFilePromiseReceiver.mm: Added.
+ (-[TestFilePromiseReceiver initWithPromisedTypeIdentifiers:dragAndDropSimulator:]):
+ (-[TestFilePromiseReceiver fileTypes]):
+ (-[TestFilePromiseReceiver fileNames]):
+ (-[TestFilePromiseReceiver dealloc]):
+ (-[TestFilePromiseReceiver draggingSource]):
+ (-[TestFilePromiseReceiver setDraggingSource:]):
+ (fileNameWithNumericSuffix):
+ (copyFile):
+
+ Add a helper to copy a file into a destination directory. Used to implement the main functionality of our
+ NSFilePromiseReceiver subclass, which copies the files specified by test code into the directory determined by
+ WebKit.
+
+ (-[TestFilePromiseReceiver receivePromisedFilesAtDestination:options:operationQueue:reader:]):
+
2018-08-16 Alex Christensen <[email protected]>
Add entitlement to MiniBrowser to allow it to communicate with com.apple.Safari.SafeBrowsing.Service
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (234975 => 234976)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2018-08-17 04:58:49 UTC (rev 234976)
@@ -842,9 +842,11 @@
F4D5E4E81F0C5D38008C1A49 /* dragstart-clear-selection.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4D5E4E71F0C5D27008C1A49 /* dragstart-clear-selection.html */; };
F4D65DA81F5E4704009D8C27 /* selected-text-image-link-and-editable.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4D65DA71F5E46C0009D8C27 /* selected-text-image-link-and-editable.html */; };
F4DEF6ED1E9B4DB60048EF61 /* image-in-link-and-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4DEF6EC1E9B4D950048EF61 /* image-in-link-and-input.html */; };
- F4E0A296211FC5FB00AF7C7F /* selected-text-and-textarea.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E0A295211FC5A300AF7C7F /* selected-text-and-textarea.html */; };
F4E0A28B211E4A2B00AF7C7F /* full-page-dropzone.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F46128D8211E496300D9FADB /* full-page-dropzone.html */; };
F4E0A28F211E5D5B00AF7C7F /* DragAndDropTestsMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4E0A28E211E5D5B00AF7C7F /* DragAndDropTestsMac.mm */; };
+ F4E0A296211FC5FB00AF7C7F /* selected-text-and-textarea.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E0A295211FC5A300AF7C7F /* selected-text-and-textarea.html */; };
+ F4E0A2B42122402B00AF7C7F /* image-and-file-upload.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E0A2B321223F2D00AF7C7F /* image-and-file-upload.html */; };
+ F4E0A2B82122847400AF7C7F /* TestFilePromiseReceiver.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */; };
F4E3D80820F70BB9007B58C5 /* significant-text-milestone-article.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */; };
F4F137921D9B683E002BEC57 /* large-video-test-now-playing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */; };
F4F405BC1D4C0D1C007A9707 /* full-size-autoplaying-video-with-audio.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4F405BA1D4C0CF8007A9707 /* full-size-autoplaying-video-with-audio.html */; };
@@ -1042,6 +1044,7 @@
510477741D298DDD009747EB /* IDBDeleteRecovery.sqlite3-wal in Copy Resources */,
5110FCF11E01CD64006F8D0B /* IDBIndexUpgradeToV2.html in Copy Resources */,
F41AB9A41EF4696B0083FA08 /* image-and-contenteditable.html in Copy Resources */,
+ F4E0A2B42122402B00AF7C7F /* image-and-file-upload.html in Copy Resources */,
F41AB9A51EF4696B0083FA08 /* image-and-textarea.html in Copy Resources */,
F4DEF6ED1E9B4DB60048EF61 /* image-in-link-and-input.html in Copy Resources */,
F45B63FB1F197F4A009D38B9 /* image-map.html in Copy Resources */,
@@ -2088,8 +2091,11 @@
F4D5E4E71F0C5D27008C1A49 /* dragstart-clear-selection.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "dragstart-clear-selection.html"; sourceTree = "<group>"; };
F4D65DA71F5E46C0009D8C27 /* selected-text-image-link-and-editable.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "selected-text-image-link-and-editable.html"; sourceTree = "<group>"; };
F4DEF6EC1E9B4D950048EF61 /* image-in-link-and-input.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "image-in-link-and-input.html"; sourceTree = "<group>"; };
+ F4E0A28E211E5D5B00AF7C7F /* DragAndDropTestsMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropTestsMac.mm; sourceTree = "<group>"; };
F4E0A295211FC5A300AF7C7F /* selected-text-and-textarea.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "selected-text-and-textarea.html"; sourceTree = "<group>"; };
- F4E0A28E211E5D5B00AF7C7F /* DragAndDropTestsMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropTestsMac.mm; sourceTree = "<group>"; };
+ F4E0A2B321223F2D00AF7C7F /* image-and-file-upload.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "image-and-file-upload.html"; sourceTree = "<group>"; };
+ F4E0A2B62122847400AF7C7F /* TestFilePromiseReceiver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestFilePromiseReceiver.h; sourceTree = "<group>"; };
+ F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestFilePromiseReceiver.mm; sourceTree = "<group>"; };
F4E3D80720F708E4007B58C5 /* significant-text-milestone-article.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "significant-text-milestone-article.html"; sourceTree = "<group>"; };
F4F137911D9B6832002BEC57 /* large-video-test-now-playing.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-video-test-now-playing.html"; sourceTree = "<group>"; };
F4F405BA1D4C0CF8007A9707 /* full-size-autoplaying-video-with-audio.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "full-size-autoplaying-video-with-audio.html"; sourceTree = "<group>"; };
@@ -2662,6 +2668,7 @@
510477711D298D85009747EB /* IDBDeleteRecovery.sqlite3-wal */,
5110FCF01E01CD53006F8D0B /* IDBIndexUpgradeToV2.html */,
F41AB9991EF4692C0083FA08 /* image-and-contenteditable.html */,
+ F4E0A2B321223F2D00AF7C7F /* image-and-file-upload.html */,
F41AB9931EF4692C0083FA08 /* image-and-textarea.html */,
F4DEF6EC1E9B4D950048EF61 /* image-in-link-and-input.html */,
F45B63FA1F197F33009D38B9 /* image-map.html */,
@@ -3147,6 +3154,8 @@
29AB8AA2164C7A9300D49BEC /* TestBrowsingContextLoadDelegate.mm */,
F46128C9211D475100D9FADB /* TestDraggingInfo.h */,
F46128CA211D475100D9FADB /* TestDraggingInfo.mm */,
+ F4E0A2B62122847400AF7C7F /* TestFilePromiseReceiver.h */,
+ F4E0A2B72122847400AF7C7F /* TestFilePromiseReceiver.mm */,
C08587BE13FE956C001EF4E5 /* WebKitAgnosticTest.h */,
C08587BD13FE956C001EF4E5 /* WebKitAgnosticTest.mm */,
);
@@ -3962,6 +3971,7 @@
7CCE7F161A411AE600447C4C /* TerminateTwice.cpp in Sources */,
7CCE7EA91A411A1D00447C4C /* TestBrowsingContextLoadDelegate.mm in Sources */,
F46128CB211D475100D9FADB /* TestDraggingInfo.mm in Sources */,
+ F4E0A2B82122847400AF7C7F /* TestFilePromiseReceiver.mm in Sources */,
F45E15762112CE6200307E82 /* TestInputDelegate.mm in Sources */,
2D1C04A71D76298B000A6816 /* TestNavigationDelegate.mm in Sources */,
A14FC5901B8AE36F00D107EB /* TestProtocol.mm in Sources */,
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm (234975 => 234976)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DragAndDropTests.mm 2018-08-17 04:58:49 UTC (rev 234976)
@@ -34,7 +34,7 @@
{
auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:CGRectMake(0, 0, 400, 400)]);
[[simulator webView] synchronouslyLoadTestPageNamed:@"link-in-iframe-and-input"];
- [simulator runFrom:NSMakePoint(200, 375) to:NSMakePoint(200, 125)];
+ [simulator runFrom:CGPointMake(200, 375) to:CGPointMake(200, 125)];
EXPECT_WK_STREQ("https://www.apple.com/", [[simulator webView] stringByEvaluatingJavaScript:@"document.querySelector('input').value"]);
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/image-and-file-upload.html (0 => 234976)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/image-and-file-upload.html (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/image-and-file-upload.html 2018-08-17 04:58:49 UTC (rev 234976)
@@ -0,0 +1,47 @@
+<DOCTYPE !html>
+<html>
+<head>
+<meta charset="utf8">
+<meta name="viewport" content="width=device-width">
+<style>
+ body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ }
+
+ #source, #destination {
+ width: 200px;
+ height: 200px;
+ }
+
+ #destination {
+ border: red 1px solid;
+ }
+</style>
+<script>
+ function runTest() {
+ destination.addEventListener("dragenter", event => event.preventDefault());
+ destination.addEventListener("dragover", event => event.preventDefault());
+ destination.addEventListener("drop", event => {
+ filecount.textContent = event.dataTransfer.files.length;
+ destination.setAttribute("src", URL.createObjectURL(event.dataTransfer.files[0]));
+ event.preventDefault();
+ });
+ }
+
+ function destinationLoaded() {
+ imageload.textContent = "true";
+ imageload.style.color = "green";
+ }
+</script>
+</head>
+<body _onload_="runTest()">
+ <div><img id="source" src=""
+ <img _onload_="destinationLoaded()" src="" id="destination"></img>
+ <div id="output">
+ <div>Number of files: <span id="filecount">N/A</span></div>
+ <div>Image loaded? <span style="color: red" id="imageload">false</span></div>
+ </div>
+</body>
+</html>
Modified: trunk/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm (234975 => 234976)
--- trunk/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm 2018-08-17 04:58:49 UTC (rev 234976)
@@ -30,6 +30,25 @@
#if WK_API_ENABLED && ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)
+static void waitForConditionWithLogging(BOOL(^condition)(), NSTimeInterval loggingTimeout, NSString *message, ...)
+{
+ NSDate *startTime = [NSDate date];
+ BOOL exceededLoggingTimeout = NO;
+ while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
+ if (condition())
+ break;
+
+ if (exceededLoggingTimeout || [[NSDate date] timeIntervalSinceDate:startTime] < loggingTimeout)
+ continue;
+
+ va_list args;
+ va_start(args, message);
+ NSLogv(message, args);
+ va_end(args);
+ exceededLoggingTimeout = YES;
+ }
+}
+
TEST(DragAndDropTests, NumberOfValidItemsForDrop)
{
NSPasteboard *pasteboard = [NSPasteboard pasteboardWithUniqueName];
@@ -39,10 +58,6 @@
auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400)]);
TestWKWebView *webView = [simulator webView];
[simulator setExternalDragPasteboard:pasteboard];
-
- auto hostWindow = adoptNS([[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 400, 400) styleMask:0 backing:NSBackingStoreBuffered defer:NO]);
- [hostWindow setFrameOrigin:NSMakePoint(0, 0)];
- [[hostWindow contentView] addSubview:webView];
[webView synchronouslyLoadTestPageNamed:@"full-page-dropzone"];
NSInteger numberOfValidItemsForDrop = 0;
@@ -75,4 +90,49 @@
}
#endif // ENABLE(INPUT_TYPE_COLOR)
+TEST(DragAndDropTests, DragImageElementIntoFileUpload)
+{
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400)]);
+ TestWKWebView *webView = [simulator webView];
+ [webView synchronouslyLoadTestPageNamed:@"image-and-file-upload"];
+ [simulator runFrom:NSMakePoint(100, 100) to:NSMakePoint(100, 300)];
+
+ waitForConditionWithLogging([&] () -> BOOL {
+ return [webView stringByEvaluatingJavaScript:@"imageload.textContent"].boolValue;
+ }, 2, @"Expected image to finish loading.");
+ EXPECT_EQ(1, [webView stringByEvaluatingJavaScript:@"filecount.textContent"].integerValue);
+}
+
+TEST(DragAndDropTests, DragPromisedImageFileIntoFileUpload)
+{
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400)]);
+ TestWKWebView *webView = [simulator webView];
+ [webView synchronouslyLoadTestPageNamed:@"image-and-file-upload"];
+
+ NSURL *imageURL = [NSBundle.mainBundle URLForResource:@"apple" withExtension:@"gif" subdirectory:@"TestWebKitAPI.resources"];
+ [simulator writePromisedFiles:@[ imageURL ]];
+ [simulator runFrom:NSMakePoint(100, 100) to:NSMakePoint(100, 300)];
+
+ waitForConditionWithLogging([&] () -> BOOL {
+ return [webView stringByEvaluatingJavaScript:@"imageload.textContent"].boolValue;
+ }, 2, @"Expected image to finish loading.");
+ EXPECT_EQ(1, [webView stringByEvaluatingJavaScript:@"filecount.textContent"].integerValue);
+}
+
+TEST(DragAndDropTests, DragImageFileIntoFileUpload)
+{
+ auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400)]);
+ TestWKWebView *webView = [simulator webView];
+ [webView synchronouslyLoadTestPageNamed:@"image-and-file-upload"];
+
+ NSURL *imageURL = [NSBundle.mainBundle URLForResource:@"apple" withExtension:@"gif" subdirectory:@"TestWebKitAPI.resources"];
+ [simulator writeFiles:@[ imageURL ]];
+ [simulator runFrom:NSMakePoint(100, 100) to:NSMakePoint(100, 300)];
+
+ waitForConditionWithLogging([&] () -> BOOL {
+ return [webView stringByEvaluatingJavaScript:@"imageload.textContent"].boolValue;
+ }, 2, @"Expected image to finish loading.");
+ EXPECT_EQ(1, [webView stringByEvaluatingJavaScript:@"filecount.textContent"].integerValue);
+}
+
#endif // WK_API_ENABLED && ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)
Modified: trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h (234975 => 234976)
--- trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2018-08-17 04:58:49 UTC (rev 234976)
@@ -116,8 +116,12 @@
@property (nonatomic, readonly) NSDragOperation currentDragOperation;
@property (nonatomic, strong) NSPasteboard *externalDragPasteboard;
@property (nonatomic, strong) NSImage *externalDragImage;
+@property (nonatomic, readonly) NSArray<NSURL *> *externalPromisedFiles;
@property (nonatomic, copy) dispatch_block_t willEndDraggingHandler;
+- (void)writePromisedFiles:(NSArray<NSURL *> *)fileURLs;
+- (void)writeFiles:(NSArray<NSURL *> *)fileURLs;
+
#endif // PLATFORM(MAC)
@end
Modified: trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm (234975 => 234976)
--- trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm 2018-08-17 04:58:49 UTC (rev 234976)
@@ -84,6 +84,7 @@
RetainPtr<TestDraggingInfo> _draggingInfo;
RetainPtr<NSPasteboard> _externalDragPasteboard;
RetainPtr<NSImage> _externalDragImage;
+ RetainPtr<NSArray<NSURL *>> _externalPromisedFiles;
BlockPtr<void()> _willEndDraggingHandler;
NSPoint _startLocationInWindow;
NSPoint _endLocationInWindow;
@@ -160,7 +161,7 @@
- (void)performDragInWebView:(DragAndDropTestWKWebView *)webView atLocation:(NSPoint)viewLocation withImage:(NSImage *)image pasteboard:(NSPasteboard *)pasteboard source:(id)source
{
_initialDragImageLocationInView = viewLocation;
- _draggingInfo = adoptNS([[TestDraggingInfo alloc] init]);
+ _draggingInfo = adoptNS([[TestDraggingInfo alloc] initWithDragAndDropSimulator:self]);
[_draggingInfo setDraggedImage:image];
[_draggingInfo setDraggingPasteboard:pasteboard];
[_draggingInfo setDraggingSource:source];
@@ -245,6 +246,68 @@
_willEndDraggingHandler = makeBlockPtr(willEndDraggingHandler);
}
+- (NSArray<NSURL *> *)externalPromisedFiles
+{
+ return _externalPromisedFiles.get();
+}
+
+static BOOL getFilePathsAndTypeIdentifiers(NSArray<NSURL *> *fileURLs, NSArray<NSString *> **outFilePaths, NSArray<NSString *> **outTypeIdentifiers)
+{
+ NSMutableArray *filePaths = [NSMutableArray arrayWithCapacity:fileURLs.count];
+ NSMutableArray *typeIdentifiers = [NSMutableArray arrayWithCapacity:fileURLs.count];
+ for (NSURL *url in fileURLs) {
+ NSString *typeIdentifier = nil;
+ NSError *error = nil;
+ BOOL foundUTI = [url getResourceValue:&typeIdentifier forKey:NSURLTypeIdentifierKey error:&error];
+ if (!foundUTI || error) {
+ [NSException raise:@"DragAndDropSimulator" format:@"Failed to get UTI for promised file: %@ with error: %@", url, error];
+ continue;
+ }
+ [typeIdentifiers addObject:typeIdentifier];
+ [filePaths addObject:url.path];
+ }
+
+ if (fileURLs.count != filePaths.count)
+ return NO;
+
+ if (outTypeIdentifiers)
+ *outTypeIdentifiers = typeIdentifiers;
+
+ if (outFilePaths)
+ *outFilePaths = filePaths;
+
+ return YES;
+}
+
+- (void)writePromisedFiles:(NSArray<NSURL *> *)fileURLs
+{
+ NSArray *paths = nil;
+ NSArray *types = nil;
+ if (!getFilePathsAndTypeIdentifiers(fileURLs, &paths, &types))
+ return;
+
+ NSMutableArray *names = [NSMutableArray arrayWithCapacity:paths.count];
+ for (NSString *path in paths)
+ [names addObject:path.lastPathComponent];
+
+ _externalPromisedFiles = fileURLs;
+ _externalDragPasteboard = [NSPasteboard pasteboardWithUniqueName];
+ [_externalDragPasteboard declareTypes:@[NSFilesPromisePboardType, NSFilenamesPboardType] owner:nil];
+ [_externalDragPasteboard setPropertyList:types forType:NSFilesPromisePboardType];
+ [_externalDragPasteboard setPropertyList:names forType:NSFilenamesPboardType];
+}
+
+- (void)writeFiles:(NSArray<NSURL *> *)fileURLs
+{
+ NSArray *paths = nil;
+ if (!getFilePathsAndTypeIdentifiers(fileURLs, &paths, nil))
+ return;
+
+ _externalDragPasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
+ [_externalDragPasteboard declareTypes:@[NSFilenamesPboardType] owner:nil];
+ [_externalDragPasteboard setPropertyList:paths forType:NSFilenamesPboardType];
+}
+
@end
#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(MAC) && WK_API_ENABLED
Modified: trunk/Tools/TestWebKitAPI/mac/TestDraggingInfo.h (234975 => 234976)
--- trunk/Tools/TestWebKitAPI/mac/TestDraggingInfo.h 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/TestWebKitAPI/mac/TestDraggingInfo.h 2018-08-17 04:58:49 UTC (rev 234976)
@@ -29,8 +29,13 @@
#import <AppKit/NSDragging.h>
+@class DragAndDropSimulator;
+
@interface TestDraggingInfo : NSObject <NSDraggingInfo>
+- (instancetype)initWithDragAndDropSimulator:(DragAndDropSimulator *)simulator NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
@property (nonatomic) NSPoint draggingLocation;
@property (nonatomic) NSPoint draggedImageLocation;
@property (nonatomic) NSInteger draggingSequenceNumber;
@@ -38,6 +43,7 @@
@property (nonatomic, strong) NSPasteboard *draggingPasteboard;
@property (nonatomic, strong) NSImage *draggedImage;
@property (nonatomic, weak) id draggingSource;
+@property (nonatomic, readonly) NSArray<NSFilePromiseReceiver *> *filePromiseReceivers;
@end
Modified: trunk/Tools/TestWebKitAPI/mac/TestDraggingInfo.mm (234975 => 234976)
--- trunk/Tools/TestWebKitAPI/mac/TestDraggingInfo.mm 2018-08-17 03:06:40 UTC (rev 234975)
+++ trunk/Tools/TestWebKitAPI/mac/TestDraggingInfo.mm 2018-08-17 04:58:49 UTC (rev 234976)
@@ -28,19 +28,41 @@
#if ENABLE(DRAG_SUPPORT) && PLATFORM(MAC) && WK_API_ENABLED
+#import "DragAndDropSimulator.h"
+#import "TestFilePromiseReceiver.h"
#import <wtf/WeakObjCPtr.h>
+@interface NSDraggingItem ()
+@property (nonatomic, strong) id item;
+@end
+
@implementation TestDraggingInfo {
WeakObjCPtr<id> _source;
+ WeakObjCPtr<DragAndDropSimulator> _dragAndDropSimulator;
RetainPtr<NSPasteboard> _pasteboard;
RetainPtr<NSImage> _draggedImage;
+ RetainPtr<NSMutableArray<NSFilePromiseReceiver *>> _filePromiseReceivers;
}
+- (instancetype)initWithDragAndDropSimulator:(DragAndDropSimulator *)simulator
+{
+ if (self = [super init]) {
+ _filePromiseReceivers = adoptNS([NSMutableArray new]);
+ _dragAndDropSimulator = simulator;
+ }
+ return self;
+}
+
@synthesize draggingSourceOperationMask=_draggingSourceOperationMask;
@synthesize draggingLocation=_draggingLocation;
@synthesize draggingFormation=_draggingFormation;
@synthesize numberOfValidItemsForDrop=_numberOfValidItemsForDrop;
+- (NSArray<NSFilePromiseReceiver *> *)filePromiseReceivers
+{
+ return _filePromiseReceivers.get();
+}
+
- (NSPasteboard *)draggingPasteboard
{
return _pasteboard.get();
@@ -61,9 +83,45 @@
_source = draggingSource;
}
-- (void)enumerateDraggingItemsWithOptions:(NSDraggingItemEnumerationOptions)enumOpts forView:(NSView *)view classes:(NSArray<Class> *)classArray searchOptions:(NSDictionary<NSString *, id> *)searchOptions usingBlock:(void (^)(NSDraggingItem *, NSInteger, BOOL *))block
+- (void)enumerateDraggingItemsWithOptions:(NSDraggingItemEnumerationOptions)enumerationOptions forView:(NSView *)view classes:(NSArray<Class> *)classes searchOptions:(NSDictionary<NSString *, id> *)searchOptions usingBlock:(void (^)(NSDraggingItem *, NSInteger, BOOL *))block
{
- // FIXME: Implement this to test file promise drop handling.
+ // FIXME: Much of this can be shared with existing drag and drop testing code in DumpRenderTree.
+
+ if (enumerationOptions) {
+ [NSException raise:@"DragAndDropSimulator" format:@"Dragging item enumeration options are currently unsupported. (got: %tu)", enumerationOptions];
+ return;
+ }
+
+ if (searchOptions.count) {
+ [NSException raise:@"DragAndDropSimulator" format:@"Search options are currently unsupported. (got: %@)", searchOptions];
+ return;
+ }
+
+ BOOL stop = NO;
+ for (Class classObject in classes) {
+ if (classObject != NSFilePromiseReceiver.class)
+ continue;
+
+ id promisedTypeIdentifiers = [_pasteboard propertyListForType:NSFilesPromisePboardType];
+ if (![promisedTypeIdentifiers isKindOfClass:NSArray.class])
+ break;
+
+ for (id object in promisedTypeIdentifiers) {
+ if (![object isKindOfClass:NSString.class])
+ break;
+ }
+
+ auto receiver = adoptNS([[TestFilePromiseReceiver alloc] initWithPromisedTypeIdentifiers:promisedTypeIdentifiers dragAndDropSimulator:_dragAndDropSimulator.getAutoreleased()]);
+ [receiver setDraggingSource:_source.get().get()];
+ [_filePromiseReceivers addObject:receiver.get()];
+
+ auto item = adoptNS([NSDraggingItem new]);
+ [item setItem:receiver.get()];
+
+ block(item.get(), 0, &stop);
+ if (stop)
+ break;
+ }
}
// The following methods are not currently used by WebKit.
Copied: trunk/Tools/TestWebKitAPI/mac/TestFilePromiseReceiver.h (from rev 234975, trunk/Tools/TestWebKitAPI/mac/TestDraggingInfo.h) (0 => 234976)
--- trunk/Tools/TestWebKitAPI/mac/TestFilePromiseReceiver.h (rev 0)
+++ trunk/Tools/TestWebKitAPI/mac/TestFilePromiseReceiver.h 2018-08-17 04:58:49 UTC (rev 234976)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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
+
+#if PLATFORM(MAC) && WK_API_ENABLED
+
+#import <AppKit/NSFilePromiseReceiver.h>
+
+@class DragAndDropSimulator;
+
+@interface TestFilePromiseReceiver : NSFilePromiseReceiver
+
+- (instancetype)initWithPromisedTypeIdentifiers:(NSArray<NSString *> *)promisedTypeIdentifiers dragAndDropSimulator:(DragAndDropSimulator *)simulator NS_DESIGNATED_INITIALIZER;
+- (instancetype)init NS_UNAVAILABLE;
+
+@property (nonatomic, weak) id draggingSource;
+
+@end
+
+#endif
Added: trunk/Tools/TestWebKitAPI/mac/TestFilePromiseReceiver.mm (0 => 234976)
--- trunk/Tools/TestWebKitAPI/mac/TestFilePromiseReceiver.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/mac/TestFilePromiseReceiver.mm 2018-08-17 04:58:49 UTC (rev 234976)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "TestFilePromiseReceiver.h"
+
+#if PLATFORM(MAC) && WK_API_ENABLED
+
+#import "DragAndDropSimulator.h"
+#import <wtf/RetainPtr.h>
+#import <wtf/WeakObjCPtr.h>
+
+@implementation TestFilePromiseReceiver {
+ RetainPtr<NSArray<NSString *>> _promisedTypeIdentifiers;
+ RetainPtr<NSMutableArray<NSURL *>> _destinationURLs;
+ WeakObjCPtr<id> _draggingSource;
+ WeakObjCPtr<DragAndDropSimulator> _dragAndDropSimulator;
+}
+
+- (instancetype)initWithPromisedTypeIdentifiers:(NSArray<NSString *> *)promisedTypeIdentifiers dragAndDropSimulator:(DragAndDropSimulator *)simulator
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _dragAndDropSimulator = simulator;
+ _promisedTypeIdentifiers = adoptNS([promisedTypeIdentifiers copy]);
+ _destinationURLs = adoptNS([NSMutableArray new]);
+ return self;
+}
+
+- (NSArray<NSString *> *)fileTypes
+{
+ return _promisedTypeIdentifiers.get();
+}
+
+- (NSArray<NSString *> *)fileNames
+{
+ NSMutableArray *fileNames = [NSMutableArray arrayWithCapacity:[_destinationURLs count]];
+ for (NSURL *url in _destinationURLs.get())
+ [fileNames addObject:url.lastPathComponent];
+ return fileNames;
+}
+
+- (void)dealloc
+{
+ for (NSURL *destinationURL in _destinationURLs.get())
+ [[NSFileManager defaultManager] removeItemAtURL:destinationURL error:nil];
+
+ [super dealloc];
+}
+
+- (id)draggingSource
+{
+ return _draggingSource.get().get();
+}
+
+- (void)setDraggingSource:(id)draggingSource
+{
+ _draggingSource = draggingSource;
+}
+
+static NSString *fileNameWithNumericSuffix(NSString *fileName, NSUInteger suffix)
+{
+ return [NSString stringWithFormat:@"%@ %zu.%@", fileName.stringByDeletingPathExtension, suffix, fileName.pathExtension];
+}
+
+static NSURL *copyFile(NSURL *sourceURL, NSURL *destinationDirectory, NSError **outError)
+{
+ NSUInteger suffix = 0;
+ NSString *fileName = sourceURL.lastPathComponent;
+ NSURL *destinationURL = [NSURL fileURLWithPath:fileName relativeToURL:destinationDirectory];
+ NSError *error;
+ while (![NSFileManager.defaultManager copyItemAtURL:sourceURL toURL:destinationURL error:&error]) {
+ if (error.domain != NSCocoaErrorDomain || error.code != NSFileWriteFileExistsError) {
+ if (outError)
+ *outError = error;
+ return nil;
+ }
+ destinationURL = [NSURL fileURLWithPath:fileNameWithNumericSuffix(fileName, ++suffix) relativeToURL:destinationDirectory];
+ }
+ return destinationURL;
+}
+
+- (void)receivePromisedFilesAtDestination:(NSURL *)destinationDirectory options:(NSDictionary *)options operationQueue:(NSOperationQueue *)queue reader:(void (^)(NSURL *, NSError *))reader
+{
+ for (NSURL *sourceURL in [_dragAndDropSimulator externalPromisedFiles]) {
+ [queue addOperationWithBlock:^{
+ NSError *error = nil;
+ NSURL *destination = copyFile(sourceURL, destinationDirectory, &error);
+ if (destination) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [_destinationURLs addObject:destination];
+ });
+ }
+ reader(destination, error);
+ }];
+ }
+}
+
+@end
+
+#endif // PLATFORM(MAC) && WK_API_ENABLED