Changeset 235202 in webkit
- Timestamp:
- Aug 22, 2018, 2:35:02 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r235201 r235202 1 2018-08-22 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Attachment Support] Support dragging attachment elements out as files on macOS 4 https://bugs.webkit.org/show_bug.cgi?id=181294 5 <rdar://problem/36298801> 6 7 Reviewed by Tim Horton. 8 9 Serialize a dragged attachment element as a web archive on macOS. This allows us to move attachment elements 10 around a document by dragging, without performing a file upload upon every drop. Ideally, we should do this on 11 iOS as well, but this currently causes attachment data to go missing; further investigation to fix this for iOS 12 is tracked in <https://bugs.webkit.org/show_bug.cgi?id=181514>. 13 14 Tests: WKAttachmentTestsMac.DragAttachmentAsFilePromise 15 WKAttachmentTests.MoveAttachmentElementAsIconByDragging 16 17 * editing/cocoa/EditorCocoa.mm: 18 (WebCore::Editor::getPasteboardTypesAndDataForAttachment): 19 1 20 2018-08-22 Aditya Keerthi <akeerthi@apple.com> 2 21 -
trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm
r234005 r235202 170 170 // inserting attachment elements from web archive data sometimes causes attachment data to be lost; this requires 171 171 // further investigation. 172 #if PLATFORM(MAC) 173 // On macOS, we currently write the attachment as a web archive; we can't do the same for iOS and remove the platform guard above 174 // quite yet without breaking drag moves. This investigation is tracked in <https://bugs.webkit.org/show_bug.cgi?id=181514>. 175 // See the above FIXME for more details. 176 if (auto archive = LegacyWebArchive::create(attachmentRange.ptr())) { 177 if (auto webArchiveData = archive->rawDataRepresentation()) { 178 outTypes.append(WebArchivePboardType); 179 outData.append(SharedBuffer::create(webArchiveData.get())); 180 } 181 } 182 #endif 172 183 } 173 184 -
trunk/Source/WebKit/ChangeLog
r235201 r235202 1 2018-08-22 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Attachment Support] Support dragging attachment elements out as files on macOS 4 https://bugs.webkit.org/show_bug.cgi?id=181294 5 <rdar://problem/36298801> 6 7 Reviewed by Tim Horton. 8 9 Add support for dragging attachment elements on macOS by writing promised files to drag pasteboard. See changes 10 below for more details. 11 12 * UIProcess/API/Cocoa/WKWebView.mm: 13 (-[WKWebView filePromiseProvider:fileNameForType:]): 14 (-[WKWebView filePromiseProvider:writePromiseToURL:completionHandler:]): 15 (-[WKWebView draggingSession:sourceOperationMaskForDraggingContext:]): 16 (-[WKWebView draggingSession:endedAtPoint:operation:]): 17 * UIProcess/API/mac/WKView.mm: 18 (-[WKView filePromiseProvider:fileNameForType:]): 19 (-[WKView filePromiseProvider:writePromiseToURL:completionHandler:]): 20 (-[WKView draggingSession:sourceOperationMaskForDraggingContext:]): 21 (-[WKView draggingSession:endedAtPoint:operation:]): 22 23 Plumb NSFilePromiseProviderDelegate and NSDraggingSource method implementations to WebViewImpl. 24 25 * UIProcess/Cocoa/WebViewImpl.h: 26 * UIProcess/Cocoa/WebViewImpl.mm: 27 (-[WKPromisedAttachmentContext initWithAttachmentInfo:]): 28 (-[WKPromisedAttachmentContext blobURL]): 29 (-[WKPromisedAttachmentContext filename]): 30 (-[WKPromisedAttachmentContext attachmentIdentifier]): 31 32 Add an object that contains the information needed to deliver a dragged attachment element's data via 33 NSFilePromiseProvider. This is stored as the userInfo of the NSFilePromiseProvider created upon drag start. 34 35 (WebKit::WebViewImpl::draggedImage): 36 (WebKit::WebViewImpl::sendDragEndToPage): 37 38 Add a helper method to handle cleanup after the dragging has finished, and call it from -draggedImage:… and 39 -draggingSessionEnded:…. The latter is only triggered in the where -beginDraggingSessionWithItems:… is used, 40 which currently only happens when dragging attachment elements. 41 42 (WebKit::WebViewImpl::fileNameForFilePromiseProvider): 43 (WebKit::webKitUnknownError): 44 (WebKit::WebViewImpl::writeToURLForFilePromiseProvider): 45 46 Deliver either NSFileWrapper data to the destination URL (in the case where an attachment identifier is known 47 and the corresponding API::Attachment is backed by a file wrapper), or save the contents of the blob URL to the 48 destination. 49 50 (WebKit::WebViewImpl::dragSourceOperationMask): 51 (WebKit::WebViewImpl::draggingSessionEnded): 52 (WebKit::WebViewImpl::startDrag): 53 1 54 2018-08-22 Aditya Keerthi <akeerthi@apple.com> 2 55 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r235156 r235202 200 200 } 201 201 #endif 202 #endif 203 204 #if PLATFORM(MAC) && ENABLE(DRAG_SUPPORT) 205 206 @interface WKWebView () <NSFilePromiseProviderDelegate, NSDraggingSource> 207 @end 208 202 209 #endif 203 210 … … 4080 4087 } 4081 4088 4089 #if ENABLE(DRAG_SUPPORT) 4090 4091 - (NSString *)filePromiseProvider:(NSFilePromiseProvider *)filePromiseProvider fileNameForType:(NSString *)fileType 4092 { 4093 return _impl->fileNameForFilePromiseProvider(filePromiseProvider, fileType); 4094 } 4095 4096 - (void)filePromiseProvider:(NSFilePromiseProvider *)filePromiseProvider writePromiseToURL:(NSURL *)url completionHandler:(void (^)(NSError *error))completionHandler 4097 { 4098 _impl->writeToURLForFilePromiseProvider(filePromiseProvider, url, completionHandler); 4099 } 4100 4101 - (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context 4102 { 4103 return _impl->dragSourceOperationMask(session, context); 4104 } 4105 4106 - (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation 4107 { 4108 _impl->draggingSessionEnded(session, screenPoint, operation); 4109 } 4110 4111 #endif // ENABLE(DRAG_SUPPORT) 4112 4082 4113 #endif // PLATFORM(MAC) 4083 4114 -
trunk/Source/WebKit/UIProcess/API/mac/WKView.mm
r234332 r235202 65 65 @interface WKView () <NSTouchBarProvider> 66 66 @end 67 #endif 68 69 #if ENABLE(DRAG_SUPPORT) 70 71 @interface WKView () <NSFilePromiseProviderDelegate, NSDraggingSource> 72 @end 73 67 74 #endif 68 75 … … 1085 1092 #endif // HAVE(TOUCH_BAR) 1086 1093 1094 #if ENABLE(DRAG_SUPPORT) 1095 1096 - (NSString *)filePromiseProvider:(NSFilePromiseProvider *)filePromiseProvider fileNameForType:(NSString *)fileType 1097 { 1098 return _data->_impl->fileNameForFilePromiseProvider(filePromiseProvider, fileType); 1099 } 1100 1101 - (void)filePromiseProvider:(NSFilePromiseProvider *)filePromiseProvider writePromiseToURL:(NSURL *)url completionHandler:(void (^)(NSError *error))completionHandler 1102 { 1103 _data->_impl->writeToURLForFilePromiseProvider(filePromiseProvider, url, completionHandler); 1104 } 1105 1106 - (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context 1107 { 1108 return _data->_impl->dragSourceOperationMask(session, context); 1109 } 1110 1111 - (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation 1112 { 1113 _data->_impl->draggingSessionEnded(session, screenPoint, operation); 1114 } 1115 1116 #endif // ENABLE(DRAG_SUPPORT) 1117 1087 1118 @end 1088 1119 -
trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.h
r234816 r235202 425 425 NSView *hitTestForDragTypes(CGPoint, NSSet *types); 426 426 void registerDraggedTypes(); 427 428 NSDragOperation dragSourceOperationMask(NSDraggingSession *, NSDraggingContext); 429 void draggingSessionEnded(NSDraggingSession *, NSPoint, NSDragOperation); 430 431 NSString *fileNameForFilePromiseProvider(NSFilePromiseProvider *, NSString *fileType); 432 void writeToURLForFilePromiseProvider(NSFilePromiseProvider *, NSURL *, void(^)(NSError *)); 427 433 #endif 428 434 … … 628 634 void flushPendingMouseEventCallbacks(); 629 635 636 #if ENABLE(DRAG_SUPPORT) 637 void sendDragEndToPage(CGPoint endPoint, NSDragOperation); 638 #endif 639 630 640 WeakObjCPtr<NSView<WebViewImplDelegate>> m_view; 631 641 std::unique_ptr<PageClient> m_pageClient; -
trunk/Source/WebKit/UIProcess/Cocoa/WebViewImpl.mm
r235120 r235202 29 29 #if PLATFORM(MAC) 30 30 31 #import "APIAttachment.h" 31 32 #import "APILegacyContextHistoryClient.h" 32 33 #import "APINavigation.h" … … 55 56 #import "ViewGestureController.h" 56 57 #import "WKBrowsingContextControllerInternal.h" 58 #import "WKErrorInternal.h" 57 59 #import "WKFullScreenWindowController.h" 58 60 #import "WKImmediateActionController.h" … … 84 86 #import <WebCore/LocalizedStrings.h> 85 87 #import <WebCore/PlatformEventFactoryMac.h> 88 #import <WebCore/PromisedAttachmentInfo.h> 86 89 #import <WebCore/TextAlternativeWithRange.h> 87 90 #import <WebCore/TextUndoInsertionMarkupMac.h> … … 875 878 @end 876 879 880 @interface WKPromisedAttachmentContext : NSObject { 881 @private 882 RetainPtr<NSURL> _blobURL; 883 RetainPtr<NSString> _filename; 884 RetainPtr<NSString> _attachmentIdentifier; 885 } 886 887 - (instancetype)initWithAttachmentInfo:(const WebCore::PromisedAttachmentInfo&)info; 888 889 @property (nonatomic, readonly) NSURL *blobURL; 890 @property (nonatomic, readonly) NSString *filename; 891 @property (nonatomic, readonly) NSString *attachmentIdentifier; 892 893 @end 894 895 @implementation WKPromisedAttachmentContext 896 897 - (instancetype)initWithAttachmentInfo:(const WebCore::PromisedAttachmentInfo&)info 898 { 899 if (!(self = [super init])) 900 return nil; 901 902 _blobURL = info.blobURL; 903 _filename = info.filename; 904 _attachmentIdentifier = info.attachmentIdentifier; 905 return self; 906 } 907 908 - (NSURL *)blobURL 909 { 910 return _blobURL.get(); 911 } 912 913 - (NSString *)filename 914 { 915 return _filename.get(); 916 } 917 918 - (NSString *)attachmentIdentifier 919 { 920 return _attachmentIdentifier.get(); 921 } 922 923 @end 924 877 925 namespace WebKit { 878 926 … … 3661 3709 3662 3710 #if ENABLE(DRAG_SUPPORT) 3663 void WebViewImpl::draggedImage(NSImage *image, CGPoint endPoint, NSDragOperation operation) 3711 void WebViewImpl::draggedImage(NSImage *, CGPoint endPoint, NSDragOperation operation) 3712 { 3713 sendDragEndToPage(endPoint, operation); 3714 } 3715 3716 void WebViewImpl::sendDragEndToPage(CGPoint endPoint, NSDragOperation operation) 3664 3717 { 3665 3718 #pragma clang diagnostic push … … 3850 3903 } 3851 3904 3905 NSString *WebViewImpl::fileNameForFilePromiseProvider(NSFilePromiseProvider *provider, NSString *) 3906 { 3907 id userInfo = provider.userInfo; 3908 if (![userInfo isKindOfClass:[WKPromisedAttachmentContext class]]) 3909 return nil; 3910 3911 return [(WKPromisedAttachmentContext *)userInfo filename]; 3912 } 3913 3914 static NSError *webKitUnknownError() 3915 { 3916 #if WK_API_ENABLED 3917 return [NSError errorWithDomain:WKErrorDomain code:WKErrorUnknown userInfo:nil]; 3918 #else 3919 return [NSError errorWithDomain:@"WKErrorDomain" code:1 userInfo:nil]; 3920 #endif 3921 } 3922 3923 void WebViewImpl::writeToURLForFilePromiseProvider(NSFilePromiseProvider *provider, NSURL *fileURL, void(^completionHandler)(NSError *)) 3924 { 3925 id userInfo = provider.userInfo; 3926 if (![userInfo isKindOfClass:[WKPromisedAttachmentContext class]]) { 3927 completionHandler(webKitUnknownError()); 3928 return; 3929 } 3930 3931 WKPromisedAttachmentContext *info = (WKPromisedAttachmentContext *)userInfo; 3932 auto attachment = m_page->attachmentForIdentifier(info.attachmentIdentifier); 3933 if (NSFileWrapper *fileWrapper = attachment ? attachment->fileWrapper() : nil) { 3934 NSError *attachmentWritingError = nil; 3935 if ([fileWrapper writeToURL:fileURL options:0 originalContentsURL:nil error:&attachmentWritingError]) 3936 completionHandler(nil); 3937 else 3938 completionHandler(attachmentWritingError); 3939 return; 3940 } 3941 3942 WebCore::URL blobURL { info.blobURL }; 3943 if (blobURL.isEmpty()) { 3944 completionHandler(webKitUnknownError()); 3945 return; 3946 } 3947 3948 m_page->writeBlobToFilePath(blobURL, fileURL.path, [protectedCompletionHandler = makeBlockPtr(completionHandler)] (bool success) { 3949 protectedCompletionHandler(success ? nil : webKitUnknownError()); 3950 }); 3951 } 3952 3953 NSDragOperation WebViewImpl::dragSourceOperationMask(NSDraggingSession *, NSDraggingContext context) 3954 { 3955 if (context == NSDraggingContextOutsideApplication || m_page->currentDragIsOverFileInput()) 3956 return NSDragOperationCopy; 3957 return NSDragOperationGeneric | NSDragOperationMove | NSDragOperationCopy; 3958 } 3959 3960 void WebViewImpl::draggingSessionEnded(NSDraggingSession *, NSPoint endPoint, NSDragOperation operation) 3961 { 3962 sendDragEndToPage(NSPointToCGPoint(endPoint), operation); 3963 } 3964 3852 3965 #endif // ENABLE(DRAG_SUPPORT) 3853 3966 … … 3874 3987 // The call below could release the view. 3875 3988 auto protector = m_view.get(); 3989 auto clientDragLocation = item.dragLocationInWindowCoordinates; 3876 3990 #pragma clang diagnostic push 3877 3991 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 3878 3992 NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; 3879 3993 #pragma clang diagnostic pop 3994 3995 if (auto& attachmentInfo = item.promisedAttachmentInfo) { 3996 auto provider = adoptNS([[NSFilePromiseProvider alloc] initWithFileType:attachmentInfo.contentType delegate:(id <NSFilePromiseProviderDelegate>)m_view.getAutoreleased()]); 3997 [provider setUserInfo:[[[WKPromisedAttachmentContext alloc] initWithAttachmentInfo:attachmentInfo] autorelease]]; 3998 auto draggingItem = adoptNS([[NSDraggingItem alloc] initWithPasteboardWriter:provider.get()]); 3999 [draggingItem setDraggingFrame:NSMakeRect(clientDragLocation.x(), clientDragLocation.y() - size.height(), size.width(), size.height()) contents:dragNSImage.get()]; 4000 [m_view beginDraggingSessionWithItems:@[draggingItem.get()] event:m_lastMouseDownEvent.get() source:(id <NSDraggingSource>)m_view.getAutoreleased()]; 4001 4002 ASSERT(attachmentInfo.additionalTypes.size() == attachmentInfo.additionalData.size()); 4003 if (attachmentInfo.additionalTypes.size() == attachmentInfo.additionalData.size()) { 4004 for (size_t index = 0; index < attachmentInfo.additionalTypes.size(); ++index) { 4005 auto nsData = attachmentInfo.additionalData[index]->createNSData(); 4006 [pasteboard setData:nsData.get() forType:attachmentInfo.additionalTypes[index]]; 4007 } 4008 } 4009 m_page->didStartDrag(); 4010 return; 4011 } 4012 3880 4013 [pasteboard setString:@"" forType:PasteboardTypes::WebDummyPboardType]; 3881 4014 #pragma clang diagnostic push 3882 4015 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 3883 [m_view dragImage:dragNSImage.get() at:NSPointFromCGPoint( item.dragLocationInWindowCoordinates) offset:NSZeroSize event:m_lastMouseDownEvent.get() pasteboard:pasteboard source:m_view.getAutoreleased() slideBack:YES];4016 [m_view dragImage:dragNSImage.get() at:NSPointFromCGPoint(clientDragLocation) offset:NSZeroSize event:m_lastMouseDownEvent.get() pasteboard:pasteboard source:m_view.getAutoreleased() slideBack:YES]; 3884 4017 #pragma clang diagnostic pop 3885 4018 m_page->didStartDrag(); -
trunk/Tools/ChangeLog
r235201 r235202 1 2018-08-22 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [Attachment Support] Support dragging attachment elements out as files on macOS 4 https://bugs.webkit.org/show_bug.cgi?id=181294 5 <rdar://problem/36298801> 6 7 Reviewed by Tim Horton. 8 9 Add DragAndDropSimulator support for intercepting calls to -beginDraggingSessionWithitems:event:source:. This 10 enables us to write API tests for macOS that exercise the attachment SPI in combination with dragging attachment 11 elements. 12 13 * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm: 14 (-[TestWKWebView attachmentElementMidPoint]): 15 16 Add a helper method local to this test suite that grabs the midpoint (in client coordinates) or the first 17 attachment element in the document. 18 19 (TestWebKitAPI::TEST): 20 21 Add a new API test to verify that dragging an attachment element on macOS produces file providers which may be 22 used to write attachment data to a path on disk. Additionally, refactor an existing API test, 23 MoveAttachmentElementAsIconByDragging, so that it runs on both iOS and macOS, to test the ability to move 24 attachment elements around in a document by using drag and drop. 25 26 * TestWebKitAPI/cocoa/DragAndDropSimulator.h: 27 * TestWebKitAPI/mac/DragAndDropSimulatorMac.mm: 28 (-[DragAndDropTestWKWebView beginDraggingSessionWithItems:event:source:]): 29 (-[DragAndDropSimulator initWithWebViewFrame:configuration:]): 30 (-[DragAndDropSimulator dealloc]): 31 (-[DragAndDropSimulator runFrom:to:]): 32 (-[DragAndDropSimulator beginDraggingSessionInWebView:withItems:source:]): 33 34 Begin a drag session and kick off the -continueDragSession loop. Unlike -performDragInWebView:…, which spins 35 the main runloop until dragging ends, this version returns execution to the web view and schedules dragging 36 updates asynchronously. This matches AppKit behavior. 37 38 (-[DragAndDropSimulator continueDragSession]): 39 40 Increment the dragging progress amount, send a drag update to the web view, and continue scheduling calls to 41 itself until the progress reaches 1. 42 43 (-[DragAndDropSimulator performDragInWebView:atLocation:withImage:pasteboard:source:]): 44 (-[DragAndDropSimulator initializeDraggingInfo:dragImage:source:]): 45 46 Pull out common logic for creating a new TestDraggingInfo after starting a drag. 47 48 (-[DragAndDropSimulator insertedAttachments]): 49 (-[DragAndDropSimulator removedAttachments]): 50 (-[DragAndDropSimulator draggingSession]): 51 (-[DragAndDropSimulator receivePromisedFiles]): 52 53 Helper method to save promised files written to the pasteboard after a drag to the temporary directory. These 54 files are tracked by DragAndDropSimulator and automatically cleaned up after the test finishes. 55 56 (-[DragAndDropSimulator endDataTransfer]): 57 58 Add a method stub on macOS, so that MoveAttachmentElementAsIconByDragging can be made cross-platform. 59 60 (-[DragAndDropSimulator _webView:didInsertAttachment:withSource:]): 61 (-[DragAndDropSimulator _webView:didRemoveAttachment:]): 62 63 Implement method stubs to keep track of inserted or removed attachments while simulating a drag. 64 1 65 2018-08-22 Aditya Keerthi <akeerthi@apple.com> 2 66 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm
r235156 r235202 266 266 } 267 267 268 - (CGPoint)attachmentElementMidPoint 269 { 270 __block CGPoint midPoint; 271 __block bool doneEvaluatingScript = false; 272 [self evaluateJavaScript:@"r = document.querySelector('attachment').getBoundingClientRect(); [r.left + r.width / 2, r.top + r.height / 2]" completionHandler:^(NSArray<NSNumber *> *result, NSError *) { 273 midPoint = CGPointMake(result.firstObject.floatValue, result.lastObject.floatValue); 274 doneEvaluatingScript = true; 275 }]; 276 TestWebKitAPI::Util::run(&doneEvaluatingScript); 277 return midPoint; 278 } 279 268 280 - (CGSize)attachmentElementSize 269 281 { … … 1078 1090 } 1079 1091 1092 TEST(WKAttachmentTests, MoveAttachmentElementAsIconByDragging) 1093 { 1094 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 1095 [configuration _setAttachmentElementEnabled:YES]; 1096 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]); 1097 TestWKWebView *webView = [simulator webView]; 1098 [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup]; 1099 1100 auto data = retainPtr(testPDFData()); 1101 auto attachment = retainPtr([webView synchronouslyInsertAttachmentWithFilename:@"document.pdf" contentType:@"application/pdf" data:data.get()]); 1102 1103 [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil]; 1104 [webView _executeEditCommand:@"InsertHTML" argument:@"<strong>text</strong>" completion:nil]; 1105 [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil]; 1106 [webView expectElementTag:@"ATTACHMENT" toComeBefore:@"STRONG"]; 1107 1108 // Drag the attachment element to somewhere below the strong text. 1109 [simulator runFrom:[webView attachmentElementMidPoint] to:CGPointMake(50, 300)]; 1110 1111 EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count); 1112 [attachment expectRequestedDataToBe:data.get()]; 1113 EXPECT_WK_STREQ("document.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]); 1114 EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]); 1115 1116 [webView expectElementTag:@"STRONG" toComeBefore:@"ATTACHMENT"]; 1117 [simulator endDataTransfer]; 1118 } 1119 1080 1120 #pragma mark - Platform-specific tests 1081 1121 … … 1129 1169 [simulator writePromisedFiles:@[ testPDFFileURL(), testImageFileURL() ]]; 1130 1170 1131 ObserveAttachmentUpdatesForScope observer(webView);1132 1171 [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)]; 1133 1172 while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) { 1134 if ( observer.observer().inserted.count == 2)1173 if ([simulator insertedAttachments].count == 2) 1135 1174 break; 1136 1175 } 1137 1176 EXPECT_EQ(2, [[webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"] intValue]); 1138 1177 1139 auto insertedAttachments = retainPtr( observer.observer().inserted);1178 auto insertedAttachments = retainPtr([simulator insertedAttachments]); 1140 1179 NSArray<NSData *> *expectedData = @[ testPDFData(), testImageData() ]; 1141 1180 for (_WKAttachment *attachment in insertedAttachments.get()) { … … 1150 1189 [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil]; 1151 1190 [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil]; 1152 NSArray<_WKAttachment *> *removedAttachments = [observer.observer() removed];1153 EXPECT_EQ(2U, removedAttachments.count);1191 auto removedAttachments = retainPtr([simulator removedAttachments]); 1192 EXPECT_EQ(2U, [removedAttachments count]); 1154 1193 EXPECT_EQ(0, [[webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment').length"] intValue]); 1155 1194 EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments firstObject]]); 1156 1195 EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments lastObject]]); 1196 } 1197 1198 TEST(WKAttachmentTestsMac, DragAttachmentAsFilePromise) 1199 { 1200 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 1201 [configuration _setAttachmentElementEnabled:YES]; 1202 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]); 1203 TestWKWebView *webView = [simulator webView]; 1204 [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup]; 1205 1206 auto fileWrapper = adoptNS([[NSFileWrapper alloc] initWithURL:testPDFFileURL() options:0 error:nil]); 1207 auto attachment = retainPtr([webView synchronouslyInsertAttachmentWithFileWrapper:fileWrapper.get() contentType:nil]); 1208 [simulator runFrom:[webView attachmentElementMidPoint] to:CGPointMake(300, 300)]; 1209 1210 NSArray<NSURL *> *urls = [simulator receivePromisedFiles]; 1211 EXPECT_EQ(1U, urls.count); 1212 EXPECT_TRUE([[NSData dataWithContentsOfURL:urls.firstObject] isEqualToData:testPDFData()]); 1157 1213 } 1158 1214 … … 1368 1424 } 1369 1425 1370 TEST(WKAttachmentTestsIOS, MoveAttachmentElementAsIconByDragging)1371 {1372 auto webView = webViewForTestingAttachments();1373 auto data = retainPtr(testPDFData());1374 RetainPtr<_WKAttachment> attachment;1375 {1376 ObserveAttachmentUpdatesForScope observer(webView.get());1377 attachment = [webView synchronouslyInsertAttachmentWithFilename:@"document.pdf" contentType:@"application/pdf" data:data.get()];1378 observer.expectAttachmentUpdates(@[], @[attachment.get()]);1379 }1380 1381 [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];1382 [webView _executeEditCommand:@"InsertHTML" argument:@"<strong>text</strong>" completion:nil];1383 [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];1384 [webView expectElementTag:@"ATTACHMENT" toComeBefore:@"STRONG"];1385 1386 auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);1387 [dragAndDropSimulator runFrom:CGPointMake(25, 25) to:CGPointMake(25, 425)];1388 1389 attachment = [[dragAndDropSimulator insertedAttachments] firstObject];1390 [attachment expectRequestedDataToBe:data.get()];1391 EXPECT_WK_STREQ("document.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);1392 EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);1393 1394 [webView expectElementTag:@"STRONG" toComeBefore:@"ATTACHMENT"];1395 [dragAndDropSimulator endDataTransfer];1396 }1397 1398 1426 #endif // PLATFORM(IOS) 1399 1427 -
trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h
r234976 r235202 80 80 // The start location, end location, and locations of additional item requests are all in window coordinates. 81 81 - (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation; 82 - (void)endDataTransfer; 82 83 @property (nonatomic, readonly) NSArray<_WKAttachment *> *insertedAttachments; 83 84 @property (nonatomic, readonly) NSArray<_WKAttachment *> *removedAttachments; … … 89 90 - (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation additionalItemRequestLocations:(ProgressToCGPointValueMap)additionalItemRequestLocations; 90 91 - (void)waitForInputSession; 91 - (void)endDataTransfer;92 92 93 93 @property (nonatomic, readonly) DragAndDropPhase phase; … … 122 122 - (void)writePromisedFiles:(NSArray<NSURL *> *)fileURLs; 123 123 - (void)writeFiles:(NSArray<NSURL *> *)fileURLs; 124 - (NSArray<NSURL *> *)receivePromisedFiles; 124 125 125 126 #endif // PLATFORM(MAC) -
trunk/Tools/TestWebKitAPI/mac/DragAndDropSimulatorMac.mm
r234976 r235202 38 38 39 39 @interface DragAndDropSimulator () 40 - (void)beginDraggingSessionInWebView:(DragAndDropTestWKWebView *)webView withItems:(NSArray<NSDraggingItem *> *)items source:(id<NSDraggingSource>)source; 40 41 - (void)performDragInWebView:(DragAndDropTestWKWebView *)webView atLocation:(NSPoint)viewLocation withImage:(NSImage *)image pasteboard:(NSPasteboard *)pasteboard source:(id)source; 42 @property (nonatomic, readonly) NSDraggingSession *draggingSession; 41 43 @end 42 44 … … 58 60 { 59 61 [_dragAndDropSimulator performDragInWebView:self atLocation:viewLocation withImage:image pasteboard:pboard source:sourceObj]; 62 } 63 64 - (NSDraggingSession *)beginDraggingSessionWithItems:(NSArray<NSDraggingItem *> *)items event:(NSEvent *)event source:(id<NSDraggingSource>)source 65 { 66 [_dragAndDropSimulator beginDraggingSessionInWebView:self withItems:items source:source]; 67 return [_dragAndDropSimulator draggingSession]; 60 68 } 61 69 … … 86 94 RetainPtr<NSImage> _externalDragImage; 87 95 RetainPtr<NSArray<NSURL *>> _externalPromisedFiles; 96 RetainPtr<NSMutableArray<_WKAttachment *>> _insertedAttachments; 97 RetainPtr<NSMutableArray<_WKAttachment *>> _removedAttachments; 98 RetainPtr<NSMutableArray<NSURL *>> _filePromiseDestinationURLs; 99 RetainPtr<NSDraggingSession> _draggingSession; 100 RetainPtr<NSMutableArray<NSFilePromiseProvider *>> _filePromiseProviders; 88 101 BlockPtr<void()> _willEndDraggingHandler; 89 102 NSPoint _startLocationInWindow; 90 103 NSPoint _endLocationInWindow; 91 104 double _progress; 105 bool _doneWaitingForDraggingSession; 92 106 } 93 107 … … 104 118 if (self = [super init]) { 105 119 _webView = adoptNS([[DragAndDropTestWKWebView alloc] initWithFrame:frame configuration:configuration ?: [[[WKWebViewConfiguration alloc] init] autorelease] simulator:self]); 120 _filePromiseDestinationURLs = adoptNS([NSMutableArray new]); 106 121 [_webView setUIDelegate:self]; 107 122 } 108 123 return self; 124 } 125 126 - (void)dealloc 127 { 128 for (NSURL *url in _filePromiseDestinationURLs.get()) 129 [[NSFileManager defaultManager] removeItemAtURL:url error:nil]; 130 131 [super dealloc]; 109 132 } 110 133 … … 130 153 - (void)runFrom:(CGPoint)flippedStartLocation to:(CGPoint)flippedEndLocation 131 154 { 155 _insertedAttachments = adoptNS([NSMutableArray new]); 156 _removedAttachments = adoptNS([NSMutableArray new]); 157 _doneWaitingForDraggingSession = true; 132 158 _startLocationInWindow = [self flipAboutXAxisInHostWindow:flippedStartLocation]; 133 159 _endLocationInWindow = [self flipAboutXAxisInHostWindow:flippedEndLocation]; 134 160 _currentDragOperation = NSDragOperationNone; 135 161 _draggingInfo = nil; 162 _draggingSession = nil; 136 163 _progress = 0; 164 _filePromiseProviders = adoptNS([NSMutableArray new]); 137 165 138 166 if (NSPasteboard *pasteboard = self.externalDragPasteboard) { … … 155 183 [_webView waitForPendingMouseEvents]; 156 184 185 TestWebKitAPI::Util::run(&_doneWaitingForDraggingSession); 186 157 187 [_webView mouseUpAtPoint:_endLocationInWindow]; 158 188 [_webView waitForPendingMouseEvents]; 159 189 } 160 190 191 - (void)beginDraggingSessionInWebView:(DragAndDropTestWKWebView *)webView withItems:(NSArray<NSDraggingItem *> *)items source:(id<NSDraggingSource>)source 192 { 193 NSMutableArray *pasteboardObjects = [NSMutableArray arrayWithCapacity:items.count]; 194 NSMutableArray<NSString *> *promisedFileTypes = [NSMutableArray array]; 195 for (NSDraggingItem *item in items) { 196 id pasteboardObject = item.item; 197 [pasteboardObjects addObject:pasteboardObject]; 198 if ([pasteboardObject isKindOfClass:[NSFilePromiseProvider class]]) { 199 [_filePromiseProviders addObject:pasteboardObject]; 200 [promisedFileTypes addObject:[(NSFilePromiseProvider *)pasteboardObject fileType]]; 201 } 202 } 203 204 NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; 205 [pasteboard clearContents]; 206 [pasteboard writeObjects:pasteboardObjects]; 207 if (promisedFileTypes.count) { 208 // Match AppKit behavior by writing legacy file promise types to the pasteboard as well. 209 [pasteboard setPropertyList:promisedFileTypes forType:NSFilesPromisePboardType]; 210 [pasteboard addTypes:@[@"NSPromiseContentsPboardType", (NSString *)kPasteboardTypeFileURLPromise] owner:nil]; 211 } 212 213 _draggingSession = adoptNS([[NSDraggingSession alloc] init]); 214 _doneWaitingForDraggingSession = false; 215 _initialDragImageLocationInView = items[0].draggingFrame.origin; 216 id dragImageContents = items[0].imageComponents.firstObject.contents; 217 [self initializeDraggingInfo:pasteboard dragImage:[dragImageContents isKindOfClass:[NSImage class]] ? dragImageContents : nil source:source]; 218 219 _currentDragOperation = [_webView draggingEntered:_draggingInfo.get()]; 220 [_webView waitForNextPresentationUpdate]; 221 [self performSelector:@selector(continueDragSession) withObject:nil afterDelay:0]; 222 } 223 224 - (void)continueDragSession 225 { 226 _progress = std::min<double>(1, _progress + dragUpdateProgressIncrement); 227 228 if (_progress < 1) { 229 [_draggingInfo setDraggingLocation:[self locationInViewForCurrentProgress]]; 230 _currentDragOperation = [_webView draggingUpdated:_draggingInfo.get()]; 231 [_webView waitForNextPresentationUpdate]; 232 [self performSelector:@selector(continueDragSession) withObject:nil afterDelay:0]; 233 return; 234 } 235 236 [_draggingInfo setDraggingLocation:_endLocationInWindow]; 237 238 if (_willEndDraggingHandler) 239 _willEndDraggingHandler(); 240 241 if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) 242 [_webView performDragOperation:_draggingInfo.get()]; 243 else if (_currentDragOperation == NSDragOperationNone) 244 [_webView draggingExited:_draggingInfo.get()]; 245 [_webView waitForNextPresentationUpdate]; 246 [(id <NSDraggingSource>)_webView.get() draggingSession:_draggingSession.get() endedAtPoint:_endLocationInWindow operation:_currentDragOperation]; 247 248 _doneWaitingForDraggingSession = true; 249 } 250 161 251 - (void)performDragInWebView:(DragAndDropTestWKWebView *)webView atLocation:(NSPoint)viewLocation withImage:(NSImage *)image pasteboard:(NSPasteboard *)pasteboard source:(id)source 162 252 { 163 253 _initialDragImageLocationInView = viewLocation; 254 [self initializeDraggingInfo:pasteboard dragImage:image source:source]; 255 256 _currentDragOperation = [_webView draggingEntered:_draggingInfo.get()]; 257 [_webView waitForNextPresentationUpdate]; 258 259 while (_progress != 1) { 260 _progress = std::min<double>(1, _progress + dragUpdateProgressIncrement); 261 [_draggingInfo setDraggingLocation:[self locationInViewForCurrentProgress]]; 262 _currentDragOperation = [_webView draggingUpdated:_draggingInfo.get()]; 263 [_webView waitForNextPresentationUpdate]; 264 } 265 266 [_draggingInfo setDraggingLocation:_endLocationInWindow]; 267 268 if (_willEndDraggingHandler) 269 _willEndDraggingHandler(); 270 271 if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()]) 272 [_webView performDragOperation:_draggingInfo.get()]; 273 else if (_currentDragOperation == NSDragOperationNone) 274 [_webView draggingExited:_draggingInfo.get()]; 275 [_webView waitForNextPresentationUpdate]; 276 277 if (!self.externalDragPasteboard) { 278 [_webView draggedImage:[_draggingInfo draggedImage] endedAt:_endLocationInWindow operation:_currentDragOperation]; 279 [_webView waitForNextPresentationUpdate]; 280 } 281 } 282 283 - (void)initializeDraggingInfo:(NSPasteboard *)pasteboard dragImage:(NSImage *)image source:(id)source 284 { 164 285 _draggingInfo = adoptNS([[TestDraggingInfo alloc] initWithDragAndDropSimulator:self]); 165 286 [_draggingInfo setDraggedImage:image]; … … 169 290 [_draggingInfo setDraggingSourceOperationMask:NSDragOperationEvery]; 170 291 [_draggingInfo setNumberOfValidItemsForDrop:pasteboard.pasteboardItems.count]; 171 172 _currentDragOperation = [_webView draggingEntered:_draggingInfo.get()];173 [_webView waitForNextPresentationUpdate];174 175 while (_progress != 1) {176 _progress = std::min<double>(1, _progress + dragUpdateProgressIncrement);177 [_draggingInfo setDraggingLocation:[self locationInViewForCurrentProgress]];178 _currentDragOperation = [_webView draggingUpdated:_draggingInfo.get()];179 [_webView waitForNextPresentationUpdate];180 }181 182 [_draggingInfo setDraggingLocation:_endLocationInWindow];183 184 if (_willEndDraggingHandler)185 _willEndDraggingHandler();186 187 if (_currentDragOperation != NSDragOperationNone && [_webView prepareForDragOperation:_draggingInfo.get()])188 [_webView performDragOperation:_draggingInfo.get()];189 else if (_currentDragOperation == NSDragOperationNone)190 [_webView draggingExited:_draggingInfo.get()];191 [_webView waitForNextPresentationUpdate];192 193 if (!self.externalDragPasteboard) {194 [_webView draggedImage:[_draggingInfo draggedImage] endedAt:_endLocationInWindow operation:_currentDragOperation];195 [_webView waitForNextPresentationUpdate];196 }197 292 } 198 293 199 294 - (NSArray<_WKAttachment *> *)insertedAttachments 200 295 { 201 return @[ ];296 return _insertedAttachments.get(); 202 297 } 203 298 204 299 - (NSArray<_WKAttachment *> *)removedAttachments 205 300 { 206 return @[ ];301 return _removedAttachments.get(); 207 302 } 208 303 … … 230 325 { 231 326 return _externalDragImage.get(); 327 } 328 329 - (NSDraggingSession *)draggingSession 330 { 331 return _draggingSession.get(); 232 332 } 233 333 … … 309 409 } 310 410 411 - (NSArray<NSURL *> *)receivePromisedFiles 412 { 413 auto destinationURLs = adoptNS([NSMutableArray new]); 414 for (NSFilePromiseProvider *provider in _filePromiseProviders.get()) { 415 if (!provider.delegate) 416 continue; 417 418 int suffix = 1; 419 NSString *baseFileName = [provider.delegate filePromiseProvider:provider fileNameForType:provider.fileType]; 420 NSString *uniqueFileName = baseFileName; 421 while ([[NSFileManager defaultManager] fileExistsAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:uniqueFileName]]) 422 uniqueFileName = [NSString stringWithFormat:@"%@ %d", baseFileName, ++suffix]; 423 424 NSURL *destinationURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:uniqueFileName]]; 425 __block bool done = false; 426 [provider.delegate filePromiseProvider:provider writePromiseToURL:destinationURL completionHandler:^(NSError *) { 427 done = true; 428 }]; 429 TestWebKitAPI::Util::run(&done); 430 [destinationURLs addObject:destinationURL]; 431 [_filePromiseDestinationURLs addObject:destinationURL]; 432 } 433 return destinationURLs.autorelease(); 434 } 435 436 - (void)endDataTransfer 437 { 438 } 439 440 - (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment withSource:(NSString *)source 441 { 442 [_insertedAttachments addObject:attachment]; 443 } 444 445 - (void)_webView:(WKWebView *)webView didRemoveAttachment:(_WKAttachment *)attachment 446 { 447 [_removedAttachments addObject:attachment]; 448 } 449 311 450 @end 312 451
Note:
See TracChangeset
for help on using the changeset viewer.