WebKit Bugzilla
Attachment 346836 Details for
Bug 188439
: [iOS WK2] Rename and refactor DataInteractionTests and DataInteractionSimulator
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188439-20180809081711.patch (text/plain), 290.83 KB, created by
Wenson Hsieh
on 2018-08-09 08:17:12 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Wenson Hsieh
Created:
2018-08-09 08:17:12 PDT
Size:
290.83 KB
patch
obsolete
>Subversion Revision: 234691 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 5beae2a31bd37f2cfddf518eb8684bae1b306128..7f2a86efc408813b238abb2a386506a39c431060 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,116 @@ >+2018-08-09 Wenson Hsieh <wenson_hsieh@apple.com> >+ >+ [iOS WK2] Rename DataInteractionSimulator to DraggingSimulator >+ https://bugs.webkit.org/show_bug.cgi?id=188439 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Refactor DataInteractionSimulator (currently used for drag and drop testing on iOS) so that it exists across >+ macOS and iOS, and rename it to DraggingSimulator. Additionally, rename DataInteractionTests to >+ DragAndDropTests. >+ >+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: >+ * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm: >+ (TestWebKitAPI::TEST): >+ * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: Renamed from Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm. >+ (testIconImage): >+ (testZIPArchive): >+ (-[UIItemProvider registerDataRepresentationForTypeIdentifier:withData:]): >+ (-[TestWKWebView editorContainsImageElement]): >+ (-[TestWKWebView editorValue]): >+ (makeCGRectValue): >+ (checkCGRectIsEqualToCGRectWithLogging): >+ (checkSelectionRectsWithLogging): >+ (checkRichTextTypePrecedesPlainTextType): >+ (checkFirstTypeIsPresentAndSecondTypeIsMissing): >+ (checkTypeIdentifierIsRegisteredAtIndex): >+ (checkEstimatedSize): >+ (checkSuggestedNameAndEstimatedSize): >+ (checkStringArraysAreEqual): >+ (checkDragCaretRectIsContainedInRect): >+ (checkJSONWithLogging): >+ (testIconImageData): >+ (runTestWithTemporaryTextFile): >+ (runTestWithTemporaryFolder): >+ (TestWebKitAPI::TEST): >+ (TestWebKitAPI::setUpTestWebViewForDataTransferItems): >+ (TestWebKitAPI::testDragAndDropOntoTargetElements): >+ (TestWebKitAPI::testIconImageData): >+ * TestWebKitAPI/cocoa/DraggingSimulator.h: Renamed from Tools/TestWebKitAPI/ios/DataInteractionSimulator.h. >+ * TestWebKitAPI/ios/DraggingSimulatorIOS.mm: Renamed from Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm. >+ (-[WKWebView dropInteractionDelegate]): >+ (-[WKWebView dragInteractionDelegate]): >+ (-[WKWebView dropInteraction]): >+ (-[WKWebView dragInteraction]): >+ (-[MockDragDropSession initWithItems:location:window:allowMove:]): >+ (-[MockDragDropSession allowsMoveOperation]): >+ (-[MockDragDropSession isRestrictedToDraggingApplication]): >+ (-[MockDragDropSession hasItemsConformingToTypeIdentifiers:]): >+ (-[MockDragDropSession canLoadObjectsOfClass:]): >+ (-[MockDragDropSession canLoadObjectsOfClasses:]): >+ (-[MockDragDropSession items]): >+ (-[MockDragDropSession setItems:]): >+ (-[MockDragDropSession addItems:]): >+ (-[MockDragDropSession locationInView:]): >+ (-[MockDropSession initWithProviders:location:window:allowMove:]): >+ (-[MockDropSession isLocal]): >+ (-[MockDropSession progress]): >+ (-[MockDropSession setProgressIndicatorStyle:]): >+ (-[MockDropSession progressIndicatorStyle]): >+ (-[MockDropSession operationMask]): >+ (-[MockDropSession localDragSession]): >+ (-[MockDropSession hasItemsConformingToTypeIdentifier:]): >+ (-[MockDropSession canCreateItemsOfClass:]): >+ (-[MockDropSession loadObjectsOfClass:completion:]): >+ (-[MockDragSession initWithWindow:allowMove:]): >+ (-[MockDragSession localOperationMask]): >+ (-[MockDragSession externalOperationMask]): >+ (-[MockDragSession session]): >+ (-[MockDragSession localContext]): >+ (-[MockDragSession setLocalContext:]): >+ (dragAndDropEventNames): >+ (-[DraggingSimulatorApplication _cancelAllTouches]): >+ (-[DraggingSimulator initWithWebView:]): >+ (-[DraggingSimulator dealloc]): >+ (-[DraggingSimulator _resetSimulatedState]): >+ (-[DraggingSimulator observedEventNames]): >+ (-[DraggingSimulator simulateAllTouchesCanceled:]): >+ (-[DraggingSimulator runFrom:to:]): >+ (-[DraggingSimulator runFrom:to:additionalItemRequestLocations:]): >+ (-[DraggingSimulator finalSelectionRects]): >+ (-[DraggingSimulator _concludeDropAndPerformOperationIfNecessary]): >+ (-[DraggingSimulator _enqueuePendingAdditionalItemRequestLocations]): >+ (-[DraggingSimulator _sendQueuedAdditionalItemRequest]): >+ (-[DraggingSimulator _advanceProgress]): >+ (-[DraggingSimulator _currentLocation]): >+ (-[DraggingSimulator _scheduleAdvanceProgress]): >+ (-[DraggingSimulator sourceItemProviders]): >+ (-[DraggingSimulator externalItemProviders]): >+ (-[DraggingSimulator setExternalItemProviders:]): >+ (-[DraggingSimulator phase]): >+ (-[DraggingSimulator liftPreviews]): >+ (-[DraggingSimulator lastKnownDragCaretRect]): >+ (-[DraggingSimulator waitForInputSession]): >+ (-[DraggingSimulator insertedAttachments]): >+ (-[DraggingSimulator removedAttachments]): >+ (-[DraggingSimulator endDataTransfer]): >+ (-[DraggingSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]): >+ (-[DraggingSimulator _webView:willUpdateDataInteractionOperationToOperation:forSession:]): >+ (-[DraggingSimulator _webView:adjustedDataInteractionItemProvidersForItemProvider:representingObjects:additionalData:]): >+ (-[DraggingSimulator _webView:showCustomSheetForElement:]): >+ (-[DraggingSimulator _webView:willPerformDropWithSession:]): >+ (-[DraggingSimulator _webView:didInsertAttachment:]): >+ (-[DraggingSimulator _webView:didRemoveAttachment:]): >+ (-[DraggingSimulator _webView:focusShouldStartInputSession:]): >+ (-[DraggingSimulator _webView:didStartInputSession:]): >+ * TestWebKitAPI/ios/UIKitSPI.h: >+ * TestWebKitAPI/mac/DraggingSimulatorMac.mm: Added. >+ (-[DraggingSimulator initWithWebView:]): >+ (-[DraggingSimulator dealloc]): >+ (-[DraggingSimulator runFrom:to:]): >+ (-[DraggingSimulator insertedAttachments]): >+ (-[DraggingSimulator removedAttachments]): >+ > 2018-08-08 Wenson Hsieh <wenson_hsieh@apple.com> > > [iOS] fast/events/ios/contenteditable-autocapitalize.html is a flaky failure >diff --git a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >index 3e036c33fd46179f40039012bd08d45fcf609b13..f2eafd5a6bf6986d9c20b7c9827c9aa86854aa58 100644 >--- a/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >+++ b/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj >@@ -808,6 +808,7 @@ > F45B63FE1F19D410009D38B9 /* ActionSheetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45B63FC1F19D410009D38B9 /* ActionSheetTests.mm */; }; > F45E15732112CE2900307E82 /* KeyboardInputTestsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */; }; > F45E15762112CE6200307E82 /* TestInputDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = F45E15752112CE6200307E82 /* TestInputDelegate.mm */; }; >+ F46128B7211C8ED500D9FADB /* DraggingSimulatorMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = F46128B6211C8ED500D9FADB /* DraggingSimulatorMac.mm */; }; > F464AF9220BB66EA007F9B18 /* RenderingProgressTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F464AF9120BB66EA007F9B18 /* RenderingProgressTests.mm */; }; > F46849BE1EEF58E400B937FE /* UIPasteboardTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F46849BD1EEF58E400B937FE /* UIPasteboardTests.mm */; }; > F46849C01EEF5EF300B937FE /* rich-and-plain-text.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F46849BF1EEF5EDC00B937FE /* rich-and-plain-text.html */; }; >@@ -829,8 +830,8 @@ > F4CD74C620FDACFA00DE3794 /* text-with-async-script.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4CD74C520FDACF500DE3794 /* text-with-async-script.html */; }; > F4CD74C920FDB49600DE3794 /* TestURLSchemeHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4CD74C820FDB49600DE3794 /* TestURLSchemeHandler.mm */; }; > F4D2986E20FEE7370092D636 /* RunScriptAfterDocumentLoad.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D2986D20FEE7370092D636 /* RunScriptAfterDocumentLoad.mm */; }; >- F4D4F3B61E4E2BCB00BB2767 /* DataInteractionSimulator.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B41E4E2BCB00BB2767 /* DataInteractionSimulator.mm */; }; >- F4D4F3B91E4E36E400BB2767 /* DataInteractionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */; }; >+ F4D4F3B61E4E2BCB00BB2767 /* DraggingSimulatorIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B41E4E2BCB00BB2767 /* DraggingSimulatorIOS.mm */; }; >+ F4D4F3B91E4E36E400BB2767 /* DragAndDropTestsIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4D4F3B71E4E36E400BB2767 /* DragAndDropTestsIOS.mm */; }; > 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 */; }; >@@ -2032,6 +2033,8 @@ > F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyboardInputTestsIOS.mm; sourceTree = "<group>"; }; > F45E15742112CE6200307E82 /* TestInputDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestInputDelegate.h; sourceTree = "<group>"; }; > F45E15752112CE6200307E82 /* TestInputDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestInputDelegate.mm; sourceTree = "<group>"; }; >+ F46128B4211C861A00D9FADB /* DraggingSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DraggingSimulator.h; path = cocoa/DraggingSimulator.h; sourceTree = "<group>"; }; >+ F46128B6211C8ED500D9FADB /* DraggingSimulatorMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DraggingSimulatorMac.mm; sourceTree = "<group>"; }; > F464AF9120BB66EA007F9B18 /* RenderingProgressTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderingProgressTests.mm; sourceTree = "<group>"; }; > F46849BD1EEF58E400B937FE /* UIPasteboardTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UIPasteboardTests.mm; sourceTree = "<group>"; }; > F46849BF1EEF5EDC00B937FE /* rich-and-plain-text.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "rich-and-plain-text.html"; sourceTree = "<group>"; }; >@@ -2055,9 +2058,8 @@ > F4CD74C720FDB49600DE3794 /* TestURLSchemeHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestURLSchemeHandler.h; sourceTree = "<group>"; }; > F4CD74C820FDB49600DE3794 /* TestURLSchemeHandler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestURLSchemeHandler.mm; sourceTree = "<group>"; }; > F4D2986D20FEE7370092D636 /* RunScriptAfterDocumentLoad.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = RunScriptAfterDocumentLoad.mm; sourceTree = "<group>"; }; >- F4D4F3B41E4E2BCB00BB2767 /* DataInteractionSimulator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataInteractionSimulator.mm; sourceTree = "<group>"; }; >- F4D4F3B51E4E2BCB00BB2767 /* DataInteractionSimulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataInteractionSimulator.h; sourceTree = "<group>"; }; >- F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataInteractionTests.mm; sourceTree = "<group>"; }; >+ F4D4F3B41E4E2BCB00BB2767 /* DraggingSimulatorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DraggingSimulatorIOS.mm; sourceTree = "<group>"; }; >+ F4D4F3B71E4E36E400BB2767 /* DragAndDropTestsIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DragAndDropTestsIOS.mm; sourceTree = "<group>"; }; > 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>"; }; >@@ -2195,6 +2197,7 @@ > A13EBB441B87332B00097110 /* WebProcessPlugIn */, > F4517B682054E0AC00C26721 /* ClassMethodSwizzler.h */, > F4517B692054E0AC00C26721 /* ClassMethodSwizzler.mm */, >+ F46128B4211C861A00D9FADB /* DraggingSimulator.h */, > F44D06481F3962E3001A0E29 /* EditingTestHarness.h */, > F44D06491F3962E3001A0E29 /* EditingTestHarness.mm */, > 5C726D6D1D3EE06800C5E1A1 /* InstanceMethodSwizzler.h */, >@@ -2410,8 +2413,7 @@ > 2E9660DC16C07D7B00371B42 /* ios */ = { > isa = PBXGroup; > children = ( >- F4D4F3B51E4E2BCB00BB2767 /* DataInteractionSimulator.h */, >- F4D4F3B41E4E2BCB00BB2767 /* DataInteractionSimulator.mm */, >+ F4D4F3B41E4E2BCB00BB2767 /* DraggingSimulatorIOS.mm */, > 2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */, > F4517B652054C49500C26721 /* TestWKWebViewController.h */, > F4517B662054C49500C26721 /* TestWKWebViewController.mm */, >@@ -2496,7 +2498,7 @@ > A1C4FB6F1BACCEFA003742D0 /* Resources */, > 2E205BA31F527746005952DD /* AccessibilityTestsIOS.mm */, > F45B63FC1F19D410009D38B9 /* ActionSheetTests.mm */, >- F4D4F3B71E4E36E400BB2767 /* DataInteractionTests.mm */, >+ F4D4F3B71E4E36E400BB2767 /* DragAndDropTestsIOS.mm */, > F45E15722112CE2900307E82 /* KeyboardInputTestsIOS.mm */, > 574F55CE204D3763002948C6 /* LocalAuthenticator.mm */, > 7560917719259C59009EF06E /* MemoryCacheAddImageToCacheIOS.mm */, >@@ -3096,6 +3098,7 @@ > BCA61C3A11700B9400460D1E /* mac */ = { > isa = PBXGroup; > children = ( >+ F46128B6211C8ED500D9FADB /* DraggingSimulatorMac.mm */, > 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */, > C081224013FC172400DC39AE /* JavaScriptTestMac.mm */, > 2E7765CE16C4D81100BA2BB1 /* mainMac.mm */, >@@ -3670,8 +3673,6 @@ > 46A911592108E6780078D40D /* CustomUserAgent.mm in Sources */, > 751B05D61F8EAC410028A09E /* DatabaseTrackerTest.mm in Sources */, > 2DC4CF771D2D9DD800ECCC94 /* DataDetection.mm in Sources */, >- F4D4F3B61E4E2BCB00BB2767 /* DataInteractionSimulator.mm in Sources */, >- F4D4F3B91E4E36E400BB2767 /* DataInteractionTests.mm in Sources */, > 518EE51D20A78D3600E024F3 /* DecidePolicyForNavigationAction.mm in Sources */, > 2D1646E21D1862CD00015A1A /* DeferredViewInWindowStateChange.mm in Sources */, > 7CCE7EB91A411A7E00447C4C /* DeviceScaleFactorInDashboardRegions.mm in Sources */, >@@ -3694,6 +3695,9 @@ > 7CCE7F231A411AF600447C4C /* Download.mm in Sources */, > 7CCE7EEE1A411AE600447C4C /* DownloadDecideDestinationCrash.cpp in Sources */, > F4BFA68E1E4AD08000154298 /* DragAndDropPasteboardTests.mm in Sources */, >+ F4D4F3B91E4E36E400BB2767 /* DragAndDropTestsIOS.mm in Sources */, >+ F4D4F3B61E4E2BCB00BB2767 /* DraggingSimulatorIOS.mm in Sources */, >+ F46128B7211C8ED500D9FADB /* DraggingSimulatorMac.mm in Sources */, > A155022A1E05020B00A24C57 /* DuplicateCompletionHandlerCalls.mm in Sources */, > 7CCE7EBE1A411A7E00447C4C /* DynamicDeviceScaleFactor.mm in Sources */, > 5C0BF8921DD599B600B00328 /* EarlyKVOCrash.mm in Sources */, >diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm >index 4689da43b3b7b191ab081df1ecbab4281dc038bf..aefa75a9d615e979a5bb8018055c2f34278c3940 100644 >--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm >+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm >@@ -25,7 +25,7 @@ > > #import "config.h" > >-#import "DataInteractionSimulator.h" >+#import "DraggingSimulator.h" > #import "PlatformUtilities.h" > #import "TestWKWebView.h" > #import "WKWebViewConfigurationExtras.h" >@@ -1194,7 +1194,7 @@ TEST(WKAttachmentTestsMac, InsertPastedFileURLsAsAttachments) > TEST(WKAttachmentTestsIOS, InsertDroppedImageAsAttachment) > { > auto webView = webViewForTestingAttachments(); >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > auto item = adoptNS([[NSItemProvider alloc] init]); > [item registerData:testImageData() type:(NSString *)kUTTypePNG]; > [draggingSimulator setExternalItemProviders:@[ item.get() ]]; >@@ -1217,7 +1217,7 @@ TEST(WKAttachmentTestsIOS, InsertDroppedImageAsAttachment) > TEST(WKAttachmentTestsIOS, InsertDroppedAttributedStringContainingAttachment) > { > auto webView = webViewForTestingAttachments(); >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(NSString *)kUTTypePNG]); > auto item = adoptNS([[NSItemProvider alloc] init]); > [item registerObject:[NSAttributedString attributedStringWithAttachment:image.get()] visibility:NSItemProviderRepresentationVisibilityAll]; >@@ -1260,7 +1260,7 @@ TEST(WKAttachmentTestsIOS, InsertDroppedRichAndPlainTextFilesAsAttachments) > [plainTextItem setSuggestedName:@"world.txt"]; > > auto webView = webViewForTestingAttachments(); >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator setExternalItemProviders:@[ richTextItem.get(), plainTextItem.get() ]]; > [draggingSimulator runFrom:CGPointZero to:CGPointMake(50, 50)]; > >@@ -1293,7 +1293,7 @@ TEST(WKAttachmentTestsIOS, InsertDroppedZipArchiveAsAttachment) > [item setSuggestedName:@"archive.zip"]; > > auto webView = webViewForTestingAttachments(); >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator setExternalItemProviders:@[ item.get() ]]; > [draggingSimulator runFrom:CGPointZero to:CGPointMake(50, 50)]; > >@@ -1323,7 +1323,7 @@ TEST(WKAttachmentTestsIOS, InsertDroppedItemProvidersInOrder) > [secondAttachmentItem setSuggestedName:@"second.pdf"]; > > auto webView = webViewForTestingAttachments(); >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator setExternalItemProviders:@[ firstAttachmentItem.get(), inlineTextItem.get(), secondAttachmentItem.get() ]]; > [draggingSimulator runFrom:CGPointZero to:CGPointMake(50, 50)]; > >@@ -1355,7 +1355,7 @@ TEST(WKAttachmentTestsIOS, DragAttachmentInsertedAsFile) > [item setSuggestedName:@"document.pdf"]; > > auto webView = webViewForTestingAttachments(); >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator setExternalItemProviders:@[ item.get() ]]; > [draggingSimulator runFrom:CGPointZero to:CGPointMake(50, 50)]; > >@@ -1396,7 +1396,7 @@ TEST(WKAttachmentTestsIOS, DragAttachmentInsertedAsData) > EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]); > > [webView evaluateJavaScript:@"getSelection().removeAllRanges()" completionHandler:nil]; >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator runFrom:CGPointMake(25, 25) to:CGPointMake(-100, -100)]; > > // Next, verify that dragging the attachment produces an item provider with a PDF attachment. >@@ -1425,7 +1425,7 @@ TEST(WKAttachmentTestsIOS, DragInPlaceVideoAttachmentElement) > EXPECT_WK_STREQ("video/mp4", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]); > > [webView evaluateJavaScript:@"getSelection().removeAllRanges()" completionHandler:nil]; >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator runFrom:CGPointMake(25, 25) to:CGPointMake(-100, -100)]; > > EXPECT_EQ(1U, [draggingSimulator sourceItemProviders].count); >@@ -1452,7 +1452,7 @@ TEST(WKAttachmentTestsIOS, MoveAttachmentElementAsIconByDragging) > [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil]; > [webView expectElementTag:@"ATTACHMENT" toComeBefore:@"STRONG"]; > >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator runFrom:CGPointMake(25, 25) to:CGPointMake(25, 425)]; > > attachment = [[draggingSimulator insertedAttachments] firstObject]; >@@ -1481,7 +1481,7 @@ TEST(WKAttachmentTestsIOS, MoveInPlaceAttachmentElementByDragging) > [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil]; > [webView expectElementTag:@"ATTACHMENT" toComeBefore:@"STRONG"]; > >- auto draggingSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >+ auto draggingSimulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); > [draggingSimulator runFrom:CGPointMake(25, 25) to:CGPointMake(25, 425)]; > > attachment = [[draggingSimulator insertedAttachments] firstObject]; >diff --git a/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm b/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm >deleted file mode 100644 >index e5ba87bbb41daf9737431d08a86dac02d1a5a9a5..0000000000000000000000000000000000000000 >--- a/Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm >+++ /dev/null >@@ -1,1911 +0,0 @@ >-/* >- * 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 ENABLE(DATA_INTERACTION) >- >-#import "DataInteractionSimulator.h" >-#import "PlatformUtilities.h" >-#import "TestWKWebView.h" >-#import "UIKitSPI.h" >-#import "WKWebViewConfigurationExtras.h" >-#import <MobileCoreServices/MobileCoreServices.h> >-#import <UIKit/NSItemProvider+UIKitAdditions.h> >-#import <WebKit/WKPreferencesPrivate.h> >-#import <WebKit/WKPreferencesRefPrivate.h> >-#import <WebKit/WKProcessPoolPrivate.h> >-#import <WebKit/WKWebViewConfigurationPrivate.h> >-#import <WebKit/WebItemProviderPasteboard.h> >-#import <WebKit/_WKProcessPoolConfiguration.h> >-#import <wtf/Seconds.h> >- >-typedef void (^FileLoadCompletionBlock)(NSURL *, BOOL, NSError *); >-typedef void (^DataLoadCompletionBlock)(NSData *, NSError *); >-typedef void (^UIItemProviderDataLoadCompletionBlock)(NSData *, NSError *); >- >-#if !USE(APPLE_INTERNAL_SDK) >- >-@interface UIItemProviderRepresentationOptions : NSObject >-@end >- >-#endif >- >-@interface UIItemProvider() >-+ (UIItemProvider *)itemProviderWithURL:(NSURL *)url title:(NSString *)title; >-- (void) registerDataRepresentationForTypeIdentifier:(NSString *)typeIdentifier options:(UIItemProviderRepresentationOptions*)options loadHandler:(NSProgress * (^)(void (^UIItemProviderDataLoadCompletionBlock)(NSData *item, NSError *error))) loadHandler; >-@end >- >-static NSString *InjectedBundlePasteboardDataType = @"org.webkit.data"; >- >-static UIImage *testIconImage() >-{ >- return [UIImage imageNamed:@"TestWebKitAPI.resources/icon.png"]; >-} >- >-static NSData *testZIPArchive() >-{ >- NSURL *zipFileURL = [[NSBundle mainBundle] URLForResource:@"compressed-files" withExtension:@"zip" subdirectory:@"TestWebKitAPI.resources"]; >- return [NSData dataWithContentsOfURL:zipFileURL]; >-} >- >-@implementation UIItemProvider (DataInteractionTests) >- >-- (void)registerDataRepresentationForTypeIdentifier:(NSString *)typeIdentifier withData:(NSData *)data >-{ >- RetainPtr<NSData> retainedData = data; >- [self registerDataRepresentationForTypeIdentifier:typeIdentifier visibility:UIItemProviderRepresentationOptionsVisibilityAll loadHandler: [retainedData] (DataLoadCompletionBlock block) -> NSProgress * { >- block(retainedData.get(), nil); >- return [NSProgress discreteProgressWithTotalUnitCount:100]; >- }]; >-} >- >-@end >- >-@implementation TestWKWebView (DataInteractionTests) >- >-- (BOOL)editorContainsImageElement >-{ >- return [self stringByEvaluatingJavaScript:@"!!editor.querySelector('img')"].boolValue; >-} >- >-- (NSString *)editorValue >-{ >- return [self stringByEvaluatingJavaScript:@"editor.value"]; >-} >- >-@end >- >-static NSValue *makeCGRectValue(CGFloat x, CGFloat y, CGFloat width, CGFloat height) >-{ >- return [NSValue valueWithCGRect:CGRectMake(x, y, width, height)]; >-} >- >-static void checkCGRectIsEqualToCGRectWithLogging(CGRect expected, CGRect observed) >-{ >- BOOL isEqual = CGRectEqualToRect(expected, observed); >- EXPECT_TRUE(isEqual); >- if (!isEqual) >- NSLog(@"Expected: %@ but observed: %@", NSStringFromCGRect(expected), NSStringFromCGRect(observed)); >-} >- >-static void checkSelectionRectsWithLogging(NSArray *expected, NSArray *observed) >-{ >- if (![expected isEqualToArray:observed]) >- NSLog(@"Expected selection rects: %@ but observed: %@", expected, observed); >- EXPECT_TRUE([expected isEqualToArray:observed]); >-} >- >-static void checkRichTextTypePrecedesPlainTextType(DataInteractionSimulator *simulator) >-{ >- // At least one of "com.apple.flat-rtfd" or "public.rtf" is expected to have higher precedence than "public.utf8-plain-text". >- NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers]; >- auto indexOfRTFType = [registeredTypes indexOfObject:(NSString *)kUTTypeRTF]; >- auto indexOfFlatRTFDType = [registeredTypes indexOfObject:(NSString *)kUTTypeFlatRTFD]; >- auto indexOfPlainTextType = [registeredTypes indexOfObject:(NSString *)kUTTypeUTF8PlainText]; >- EXPECT_NE((NSInteger)indexOfPlainTextType, NSNotFound); >- EXPECT_TRUE((indexOfRTFType != NSNotFound && indexOfRTFType < indexOfPlainTextType) || (indexOfFlatRTFDType != NSNotFound && indexOfFlatRTFDType < indexOfPlainTextType)); >-} >- >-static void checkFirstTypeIsPresentAndSecondTypeIsMissing(DataInteractionSimulator *simulator, CFStringRef firstType, CFStringRef secondType) >-{ >- NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers]; >- EXPECT_TRUE([registeredTypes containsObject:(NSString *)firstType]); >- EXPECT_FALSE([registeredTypes containsObject:(NSString *)secondType]); >-} >- >-static void checkTypeIdentifierIsRegisteredAtIndex(DataInteractionSimulator *simulator, NSString *type, NSUInteger index) >-{ >- NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers]; >- EXPECT_GT(registeredTypes.count, index); >- EXPECT_WK_STREQ(type.UTF8String, [registeredTypes[index] UTF8String]); >-} >- >-static void checkEstimatedSize(DataInteractionSimulator *simulator, CGSize estimatedSize) >-{ >- UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject; >- EXPECT_EQ(estimatedSize.width, sourceItemProvider.preferredPresentationSize.width); >- EXPECT_EQ(estimatedSize.height, sourceItemProvider.preferredPresentationSize.height); >-} >- >-static void checkSuggestedNameAndEstimatedSize(DataInteractionSimulator *simulator, NSString *suggestedName, CGSize estimatedSize) >-{ >- UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject; >- EXPECT_WK_STREQ(suggestedName.UTF8String, sourceItemProvider.suggestedName.UTF8String); >- EXPECT_EQ(estimatedSize.width, sourceItemProvider.preferredPresentationSize.width); >- EXPECT_EQ(estimatedSize.height, sourceItemProvider.preferredPresentationSize.height); >-} >- >-static void checkStringArraysAreEqual(NSArray<NSString *> *expected, NSArray<NSString *> *observed) >-{ >- EXPECT_EQ(expected.count, observed.count); >- for (NSUInteger index = 0; index < expected.count; ++index) { >- NSString *expectedString = [expected objectAtIndex:index]; >- NSString *observedString = [observed objectAtIndex:index]; >- EXPECT_WK_STREQ(expectedString, observedString); >- if (![expectedString isEqualToString:observedString]) >- NSLog(@"Expected observed string: %@ to match expected string: %@ at index: %tu", observedString, expectedString, index); >- } >-} >- >-static void checkDragCaretRectIsContainedInRect(CGRect caretRect, CGRect containerRect) >-{ >- BOOL contained = CGRectContainsRect(containerRect, caretRect); >- EXPECT_TRUE(contained); >- if (!contained) >- NSLog(@"Expected caret rect: %@ to fit within container rect: %@", NSStringFromCGRect(caretRect), NSStringFromCGRect(containerRect)); >-} >- >-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >- >-static void checkJSONWithLogging(NSString *jsonString, NSDictionary *expected) >-{ >- BOOL success = TestWebKitAPI::Util::jsonMatchesExpectedValues(jsonString, expected); >- EXPECT_TRUE(success); >- if (!success) >- NSLog(@"Expected JSON: %@ to match values: %@", jsonString, expected); >-} >- >-static NSData *testIconImageData() >-{ >- return [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"icon" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]]; >-} >- >-static void runTestWithTemporaryTextFile(void(^runTest)(NSURL *fileURL)) >-{ >- NSString *fileName = [NSString stringWithFormat:@"drag-drop-text-file-%@.txt", [NSUUID UUID].UUIDString]; >- RetainPtr<NSURL> temporaryFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName] isDirectory:NO]; >- [[NSFileManager defaultManager] removeItemAtURL:temporaryFile.get() error:nil]; >- >- NSError *error = nil; >- [@"This is a tiny blob of text." writeToURL:temporaryFile.get() atomically:YES encoding:NSUTF8StringEncoding error:&error]; >- >- if (error) >- NSLog(@"Error writing temporary file: %@", error); >- >- @try { >- runTest(temporaryFile.get()); >- } @finally { >- [[NSFileManager defaultManager] removeItemAtURL:temporaryFile.get() error:nil]; >- } >-} >- >-static void runTestWithTemporaryFolder(void(^runTest)(NSURL *folderURL)) >-{ >- NSString *folderName = [NSString stringWithFormat:@"some.directory-%@", [NSUUID UUID].UUIDString]; >- RetainPtr<NSURL> temporaryFolder = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:folderName] isDirectory:YES]; >- [[NSFileManager defaultManager] removeItemAtURL:temporaryFolder.get() error:nil]; >- >- NSError *error = nil; >- NSFileManager *defaultManager = [NSFileManager defaultManager]; >- [defaultManager createDirectoryAtURL:temporaryFolder.get() withIntermediateDirectories:NO attributes:nil error:&error]; >- [testIconImageData() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"icon.png" isDirectory:NO] atomically:YES]; >- [testZIPArchive() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"archive.zip" isDirectory:NO] atomically:YES]; >- >- NSURL *firstSubdirectory = [temporaryFolder.get() URLByAppendingPathComponent:@"subdirectory1" isDirectory:YES]; >- [defaultManager createDirectoryAtURL:firstSubdirectory withIntermediateDirectories:NO attributes:nil error:&error]; >- [@"I am a text file in the first subdirectory." writeToURL:[firstSubdirectory URLByAppendingPathComponent:@"text-file-1.txt" isDirectory:NO] atomically:YES encoding:NSUTF8StringEncoding error:&error]; >- >- NSURL *secondSubdirectory = [temporaryFolder.get() URLByAppendingPathComponent:@"subdirectory2" isDirectory:YES]; >- [defaultManager createDirectoryAtURL:secondSubdirectory withIntermediateDirectories:NO attributes:nil error:&error]; >- [@"I am a text file in the second subdirectory." writeToURL:[secondSubdirectory URLByAppendingPathComponent:@"text-file-2.txt" isDirectory:NO] atomically:YES encoding:NSUTF8StringEncoding error:&error]; >- >- if (error) >- NSLog(@"Error writing temporary file: %@", error); >- >- @try { >- runTest(temporaryFolder.get()); >- } @finally { >- [[NSFileManager defaultManager] removeItemAtURL:temporaryFolder.get() error:nil]; >- } >-} >- >-#endif // __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >- >-namespace TestWebKitAPI { >- >-TEST(DataInteractionTests, ImageToContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_TRUE([webView editorContainsImageElement]); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [dataInteractionSimulator finalSelectionRects]); >- checkFirstTypeIsPresentAndSecondTypeIsMissing(dataInteractionSimulator.get(), kUTTypePNG, kUTTypeFileURL); >- checkEstimatedSize(dataInteractionSimulator.get(), { 215, 174 }); >-} >- >-TEST(DataInteractionTests, CanStartDragOnEnormousImage) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadHTMLString:@"<img src='enormous.svg'></img>"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)]; >- >- NSArray *registeredTypes = [[dataInteractionSimulator sourceItemProviders].firstObject registeredTypeIdentifiers]; >- EXPECT_WK_STREQ((NSString *)kUTTypeScalableVectorGraphics, [registeredTypes firstObject]); >-} >- >-TEST(DataInteractionTests, ImageToTextarea) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"image-and-textarea"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("", [webView editorValue]); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]); >- checkFirstTypeIsPresentAndSecondTypeIsMissing(dataInteractionSimulator.get(), kUTTypePNG, kUTTypeFileURL); >- checkEstimatedSize(dataInteractionSimulator.get(), { 215, 174 }); >-} >- >-TEST(DataInteractionTests, ImageInLinkToInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]); >- checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"icon.png", { 215, 174 }); >- checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, 0); >-} >- >-TEST(DataInteractionTests, ImageInLinkWithoutHREFToInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"]; >- [webView stringByEvaluatingJavaScript:@"link.href = ''"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("", [webView editorValue]); >- checkEstimatedSize(dataInteractionSimulator.get(), { 215, 174 }); >- checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypePNG, 0); >-} >- >-TEST(DataInteractionTests, ImageDoesNotUseElementSizeAsEstimatedSize) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"gif-and-file-input"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom: { 100, 100 } to: { 100, 300 }]; >- >- checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeGIF, 0); >- checkSuggestedNameAndEstimatedSize(dataInteractionSimulator.get(), @"apple.gif", { 52, 64 }); >- EXPECT_WK_STREQ("apple.gif (image/gif)", [webView stringByEvaluatingJavaScript:@"output.textContent"]); >-} >- >-TEST(DataInteractionTests, ContentEditableToContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView loadTestPageNamed:@"autofocus-contenteditable"]; >- [dataInteractionSimulator waitForInputSession]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL); >- EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 961, 227) ], [dataInteractionSimulator finalSelectionRects]); >- checkRichTextTypePrecedesPlainTextType(dataInteractionSimulator.get()); >-} >- >-TEST(DataInteractionTests, ContentEditableToTextarea) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView loadTestPageNamed:@"contenteditable-and-textarea"]; >- [dataInteractionSimulator waitForInputSession]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL); >- EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(6, 203, 990, 232) ], [dataInteractionSimulator finalSelectionRects]); >- checkRichTextTypePrecedesPlainTextType(dataInteractionSimulator.get()); >-} >- >-TEST(DataInteractionTests, ContentEditableMoveParagraphs) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView loadTestPageNamed:@"two-paragraph-contenteditable"]; >- [dataInteractionSimulator waitForInputSession]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 450)]; >- >- NSString *finalTextContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"]; >- NSUInteger firstParagraphOffset = [finalTextContent rangeOfString:@"This is the first paragraph"].location; >- NSUInteger secondParagraphOffset = [finalTextContent rangeOfString:@"This is the second paragraph"].location; >- >- EXPECT_FALSE(firstParagraphOffset == NSNotFound); >- EXPECT_FALSE(secondParagraphOffset == NSNotFound); >- EXPECT_GT(firstParagraphOffset, secondParagraphOffset); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(190, 100, 130, 20), makeCGRectValue(0, 120, 320, 100), makeCGRectValue(0, 220, 252, 20) ], [dataInteractionSimulator finalSelectionRects]); >-} >- >-TEST(DataInteractionTests, DragImageFromContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView synchronouslyLoadTestPageNamed:@"contenteditable-and-target"]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]); >-} >- >-TEST(DataInteractionTests, TextAreaToInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView loadTestPageNamed:@"textarea-to-input"]; >- [dataInteractionSimulator waitForInputSession]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL); >- EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 990, 232) ], [dataInteractionSimulator finalSelectionRects]); >-} >- >-TEST(DataInteractionTests, SinglePlainTextWordTypeIdentifiers) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView loadTestPageNamed:@"textarea-to-input"]; >- [dataInteractionSimulator waitForInputSession]; >- [webView stringByEvaluatingJavaScript:@"source.value = 'pneumonoultramicroscopicsilicovolcanoconiosis'"]; >- [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"]; >- [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- NSItemProvider *itemProvider = [dataInteractionSimulator sourceItemProviders].firstObject; >- NSArray *registeredTypes = [itemProvider registeredTypeIdentifiers]; >- EXPECT_EQ(1UL, registeredTypes.count); >- EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.firstObject UTF8String]); >- EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL); >- EXPECT_EQ(UIPreferredPresentationStyleInline, itemProvider.preferredPresentationStyle); >- EXPECT_WK_STREQ("pneumonoultramicroscopicsilicovolcanoconiosis", [webView editorValue].UTF8String); >-} >- >-TEST(DataInteractionTests, SinglePlainTextURLTypeIdentifiers) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView loadTestPageNamed:@"textarea-to-input"]; >- [dataInteractionSimulator waitForInputSession]; >- [webView stringByEvaluatingJavaScript:@"source.value = 'https://webkit.org/'"]; >- [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"]; >- [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- NSItemProvider *itemProvider = [dataInteractionSimulator sourceItemProviders].firstObject; >- NSArray *registeredTypes = [itemProvider registeredTypeIdentifiers]; >- EXPECT_EQ(2UL, registeredTypes.count); >- EXPECT_WK_STREQ([(NSString *)kUTTypeURL UTF8String], [registeredTypes.firstObject UTF8String]); >- EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.lastObject UTF8String]); >- EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"source.value"].length); >- EXPECT_EQ(UIPreferredPresentationStyleInline, itemProvider.preferredPresentationStyle); >- EXPECT_WK_STREQ("https://webkit.org/", [webView editorValue].UTF8String); >-} >- >-TEST(DataInteractionTests, LinkToInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"link-and-input"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String); >- >- __block bool doneLoadingURL = false; >- UIItemProvider *sourceItemProvider = [dataInteractionSimulator sourceItemProviders].firstObject; >- [sourceItemProvider loadObjectOfClass:[NSURL class] completionHandler:^(id object, NSError *error) { >- NSURL *url = object; >- EXPECT_WK_STREQ("Hello world", url._title.UTF8String ?: ""); >- doneLoadingURL = true; >- }]; >- TestWebKitAPI::Util::run(&doneLoadingURL); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 273, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]); >- checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeURL, 0); >-} >- >-TEST(DataInteractionTests, BackgroundImageLinkToInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"background-image-link-and-input"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionPerformOperationEventName]); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [dataInteractionSimulator finalSelectionRects]); >- checkTypeIdentifierIsRegisteredAtIndex(dataInteractionSimulator.get(), (NSString *)kUTTypeURL, 0); >-} >- >-TEST(DataInteractionTests, CanPreventStart) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"prevent-start"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]); >- EXPECT_FALSE([webView editorContainsImageElement]); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_FALSE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_FALSE([observedEventNames containsObject:DataInteractionOverEventName]); >- checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]); >-} >- >-TEST(DataInteractionTests, CanPreventOperation) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"prevent-operation"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_FALSE([webView editorContainsImageElement]); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]); >-} >- >-TEST(DataInteractionTests, EnterAndLeaveEvents) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"link-and-input"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 450)]; >- >- EXPECT_WK_STREQ("", [webView editorValue].UTF8String); >- >- NSArray *observedEventNames = [dataInteractionSimulator observedEventNames]; >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionEnterEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionOverEventName]); >- EXPECT_TRUE([observedEventNames containsObject:DataInteractionLeaveEventName]); >- EXPECT_FALSE([observedEventNames containsObject:DataInteractionPerformOperationEventName]); >- checkSelectionRectsWithLogging(@[ ], [dataInteractionSimulator finalSelectionRects]); >-} >- >-TEST(DataInteractionTests, CanStartDragOnDivWithDraggableAttribute) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"custom-draggable-div"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 250)]; >- >- EXPECT_GT([dataInteractionSimulator sourceItemProviders].count, 0UL); >- NSItemProvider *itemProvider = [dataInteractionSimulator sourceItemProviders].firstObject; >- EXPECT_EQ(UIPreferredPresentationStyleInline, itemProvider.preferredPresentationStyle); >- EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!destination.querySelector('#item')"]); >- EXPECT_WK_STREQ(@"PASS", [webView stringByEvaluatingJavaScript:@"item.textContent"]); >-} >- >-TEST(DataInteractionTests, ExternalSourcePlainTextToIFrame) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"contenteditable-in-iframe"]; >- >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- [itemProvider registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(160, 250)]; >- >- auto containerLeft = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().left"].floatValue; >- auto containerTop = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().top"].floatValue; >- auto containerWidth = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().width"].floatValue; >- auto containerHeight = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().height"].floatValue; >- checkDragCaretRectIsContainedInRect([simulator lastKnownDragCaretRect], CGRectMake(containerLeft, containerTop, containerWidth, containerHeight)); >-} >- >-TEST(DataInteractionTests, ExternalSourceInlineTextToFileInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleInline]; >- [simulatedItemProvider registerObject:@"This item provider requested inline presentation style." visibility:NSItemProviderRepresentationVisibilityAll]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >- >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"output.value"]); >-} >- >-TEST(DataInteractionTests, ExternalSourceJSONToFileInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto simulatedJSONItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *jsonData = [@"{ \"foo\": \"bar\", \"bar\": \"baz\" }" dataUsingEncoding:NSUTF8StringEncoding]; >- [simulatedJSONItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJSON withData:jsonData]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedJSONItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >- >- EXPECT_WK_STREQ("application/json", [webView stringByEvaluatingJavaScript:@"output.value"]); >-} >- >-TEST(DataInteractionTests, ExternalSourceImageToFileInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >- [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("image/jpeg", outputValue.UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceHTMLToUploadArea) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >- [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >- [simulatedHTMLItemProvider setSuggestedName:@"index.html"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setShouldAllowMoveOperation:NO]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("text/html", outputValue.UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceMoveOperationNotAllowed) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- [webView stringByEvaluatingJavaScript:@"upload.dropEffect = 'move'"]; >- >- auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >- [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setShouldAllowMoveOperation:NO]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"output.value"]); >-} >- >-TEST(DataInteractionTests, ExternalSourceZIPArchiveAndURLToSingleFileInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto archiveProvider = adoptNS([[UIItemProvider alloc] init]); >- [archiveProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()]; >- >- auto urlProvider = adoptNS([[UIItemProvider alloc] init]); >- [urlProvider registerObject:[NSURL URLWithString:@"https://webkit.org"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ archiveProvider.get(), urlProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("application/zip", outputValue.UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceZIPArchiveToUploadArea) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("application/zip", outputValue.UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceImageAndHTMLToSingleFileInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >- [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >- >- auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >- [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("", outputValue.UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceImageAndHTMLToMultipleFileInput) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- [webView stringByEvaluatingJavaScript:@"input.setAttribute('multiple', '')"]; >- >- auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >- [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >- >- auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >- [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("image/jpeg, text/html", outputValue.UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceImageAndHTMLToUploadArea) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >- [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >- >- auto firstSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >- [firstSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData]; >- >- auto secondSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *secondHTMLData = [@"<html><body>hello world</body></html>" dataUsingEncoding:NSUTF8StringEncoding]; >- [secondSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:secondHTMLData]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setShouldAllowMoveOperation:NO]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), firstSimulatedHTMLItemProvider.get(), secondSimulatedHTMLItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("image/jpeg, text/html, text/html", outputValue.UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceHTMLToContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *htmlData = [@"<h1>This is a test</h1>" dataUsingEncoding:NSUTF8StringEncoding]; >- [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >- [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- NSString *textContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"]; >- EXPECT_WK_STREQ("This is a test", textContent.UTF8String); >- EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!editor.querySelector('h1')"].boolValue); >-} >- >-TEST(DataInteractionTests, ExternalSourceBoldSystemAttributedStringToContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:20] }; >- NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"This is a test" attributes:textAttributes]; >- auto itemProvider = adoptNS([[UIItemProvider alloc] initWithObject:richText]); >- [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("This is a test", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceColoredAttributedStringToContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- NSDictionary *textAttributes = @{ NSForegroundColorAttributeName: [UIColor redColor] }; >- NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"This is a test" attributes:textAttributes]; >- auto itemProvider = adoptNS([[UIItemProvider alloc] initWithObject:richText]); >- [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(document.querySelector('p')).color"]); >- EXPECT_WK_STREQ("This is a test", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >-} >- >-TEST(DataInteractionTests, ExternalSourceMultipleURLsToContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- auto firstItem = adoptNS([[UIItemProvider alloc] init]); >- [firstItem registerObject:[NSURL URLWithString:@"https://www.apple.com/iphone/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- auto secondItem = adoptNS([[UIItemProvider alloc] init]); >- [secondItem registerObject:[NSURL URLWithString:@"https://www.apple.com/mac/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- auto thirdItem = adoptNS([[UIItemProvider alloc] init]); >- [thirdItem registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [dataInteractionSimulator setExternalItemProviders:@[ firstItem.get(), secondItem.get(), thirdItem.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- NSArray *droppedURLs = [webView objectByEvaluatingJavaScript:@"Array.from(editor.querySelectorAll('a')).map(a => a.href)"]; >- EXPECT_EQ(3UL, droppedURLs.count); >- EXPECT_WK_STREQ("https://www.apple.com/iphone/", droppedURLs[0]); >- EXPECT_WK_STREQ("https://www.apple.com/mac/", droppedURLs[1]); >- EXPECT_WK_STREQ("https://webkit.org/", droppedURLs[2]); >- >- NSArray *linksSeparatedByLine = [[webView objectByEvaluatingJavaScript:@"editor.innerText"] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; >- EXPECT_EQ(3UL, linksSeparatedByLine.count); >- EXPECT_WK_STREQ("https://www.apple.com/iphone/", linksSeparatedByLine[0]); >- EXPECT_WK_STREQ("https://www.apple.com/mac/", linksSeparatedByLine[1]); >- EXPECT_WK_STREQ("https://webkit.org/", linksSeparatedByLine[2]); >-} >- >-TEST(DataInteractionTests, RespectsExternalSourceFidelityRankings) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- // Here, our source item provider vends two representations: plain text, and then an image. If we don't respect the >- // fidelity order requested by the source, we'll end up assuming that the image is a higher fidelity representation >- // than the plain text, and erroneously insert the image. If we respect source fidelities, we'll insert text rather >- // than an image. >- auto simulatedItemProviderWithTextFirst = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProviderWithTextFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [simulatedItemProviderWithTextFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithTextFirst.get() ]]; >- >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >- EXPECT_FALSE([webView editorContainsImageElement]); >- [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''"]; >- >- // Now we register the item providers in reverse, and expect the image to be inserted instead of text. >- auto simulatedItemProviderWithImageFirst = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProviderWithImageFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [simulatedItemProviderWithImageFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProviderWithImageFirst.get() ]]; >- >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >- EXPECT_TRUE([webView editorContainsImageElement]); >-} >- >-TEST(DataInteractionTests, ExternalSourceUTF8PlainTextOnly) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- >- NSString *textPayload = @"Ceci n'est pas une string"; >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >- { >- completionBlock([textPayload dataUsingEncoding:NSUTF8StringEncoding], nil); >- return [NSProgress discreteProgressWithTotalUnitCount:100]; >- }]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- EXPECT_WK_STREQ(textPayload.UTF8String, [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 1936, 227) ], [dataInteractionSimulator finalSelectionRects]); >-} >- >-TEST(DataInteractionTests, ExternalSourceJPEGOnly) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeJPEG options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >- { >- completionBlock(UIImageJPEGRepresentation(testIconImage(), 0.5), nil); >- return [NSProgress discreteProgressWithTotalUnitCount:100]; >- }]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- EXPECT_TRUE([webView editorContainsImageElement]); >- checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [dataInteractionSimulator finalSelectionRects]); >-} >- >-TEST(DataInteractionTests, ExternalSourceTitledNSURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- NSURL *titledURL = [NSURL URLWithString:@"https://www.apple.com"]; >- titledURL._title = @"Apple"; >- auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProvider registerObject:titledURL visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("Apple", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').textContent"]); >- EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]); >-} >- >-TEST(DataInteractionTests, ExternalSourceFileURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- NSURL *URL = [NSURL URLWithString:@"file:///some/file/that/is/not/real"]; >- UIItemProvider *simulatedItemProvider = [UIItemProvider itemProviderWithURL:URL title:@""]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"!!editor.querySelector('a')"] boolValue]); >- EXPECT_WK_STREQ("Hello world\nfile:///some/file/that/is/not/real", [webView stringByEvaluatingJavaScript:@"document.body.innerText"]); >-} >- >-TEST(DataInteractionTests, ExternalSourceOverrideDropFileUpload) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >- >- auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >- [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >- >- auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >- [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData]; >- [simulatedHTMLItemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >- { >- EXPECT_EQ(2UL, session.items.count); >- UIDragItem *firstItem = session.items[0]; >- UIDragItem *secondItem = session.items[1]; >- EXPECT_TRUE([firstItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeJPEG ]]); >- EXPECT_TRUE([secondItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeHTML ]]); >- return @[ secondItem ]; >- }]; >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), simulatedHTMLItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >- >- NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >- EXPECT_WK_STREQ("text/html", outputValue.UTF8String); >-} >- >-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >- >-static RetainPtr<TestWKWebView> setUpTestWebViewForDataTransferItems() >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"DataTransferItem-getAsEntry"]; >- >- auto preferences = (WKPreferencesRef)[[webView configuration] preferences]; >- WKPreferencesSetDataTransferItemsEnabled(preferences, true); >- WKPreferencesSetDirectoryUploadEnabled(preferences, true); >- >- return webView; >-} >- >-TEST(DataInteractionTests, ExternalSourceDataTransferItemGetFolderAsEntry) >-{ >- // The expected output is sorted by alphabetical order here for consistent behavior across different test environments. >- // See DataTransferItem-getAsEntry.html for more details. >- NSArray<NSString *> *expectedOutput = @[ >- @"Found data transfer item (kind: 'file', type: '')", >- @"DIR: /somedirectory", >- @"DIR: /somedirectory/subdirectory1", >- @"DIR: /somedirectory/subdirectory2", >- [NSString stringWithFormat:@"FILE: /somedirectory/archive.zip ('application/zip', %tu bytes)", testZIPArchive().length], >- [NSString stringWithFormat:@"FILE: /somedirectory/icon.png ('image/png', %tu bytes)", testIconImageData().length], >- @"FILE: /somedirectory/subdirectory1/text-file-1.txt ('text/plain', 43 bytes)", >- @"FILE: /somedirectory/subdirectory2/text-file-2.txt ('text/plain', 44 bytes)" >- ]; >- >- auto webView = setUpTestWebViewForDataTransferItems(); >- __block bool done = false; >- [webView performAfterReceivingMessage:@"dropped" action:^() { >- done = true; >- }]; >- >- runTestWithTemporaryFolder(^(NSURL *folderURL) { >- auto itemProvider = adoptNS([[NSItemProvider alloc] init]); >- [itemProvider setSuggestedName:@"somedirectory"]; >- [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypeFolder fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[capturedFolderURL = retainPtr(folderURL)] (FileLoadCompletionBlock completionHandler) -> NSProgress * { >- completionHandler(capturedFolderURL.get(), NO, nil); >- return nil; >- }]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >- }); >- >- TestWebKitAPI::Util::run(&done); >- EXPECT_WK_STREQ([expectedOutput componentsJoinedByString:@"\n"], [webView stringByEvaluatingJavaScript:@"output.value"]); >-} >- >-TEST(DataInteractionTests, ExternalSourceDataTransferItemGetPlainTextFileAsEntry) >-{ >- NSArray<NSString *> *expectedOutput = @[ >- @"Found data transfer item (kind: 'file', type: 'text/plain')", >- @"FILE: /foo.txt ('text/plain', 28 bytes)" >- ]; >- >- auto webView = setUpTestWebViewForDataTransferItems(); >- __block bool done = false; >- [webView performAfterReceivingMessage:@"dropped" action:^() { >- done = true; >- }]; >- >- runTestWithTemporaryTextFile(^(NSURL *fileURL) { >- auto itemProvider = adoptNS([[NSItemProvider alloc] init]); >- [itemProvider setSuggestedName:@"foo"]; >- [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[capturedFileURL = retainPtr(fileURL)](FileLoadCompletionBlock completionHandler) -> NSProgress * { >- completionHandler(capturedFileURL.get(), NO, nil); >- return nil; >- }]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >- }); >- >- TestWebKitAPI::Util::run(&done); >- EXPECT_WK_STREQ([expectedOutput componentsJoinedByString:@"\n"], [webView stringByEvaluatingJavaScript:@"output.value"]); >-} >- >-#endif // __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >- >-TEST(DataInteractionTests, ExternalSourceOverrideDropInsertURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >- { >- NSMutableArray<UIDragItem *> *allowedItems = [NSMutableArray array]; >- for (UIDragItem *item in session.items) { >- if ([item.itemProvider.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]) >- [allowedItems addObject:item]; >- } >- EXPECT_EQ(1UL, allowedItems.count); >- return allowedItems; >- }]; >- >- auto firstItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [firstItemProvider registerObject:@"This is a string." visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- auto secondItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [secondItemProvider registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [dataInteractionSimulator setExternalItemProviders:@[ firstItemProvider.get(), secondItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >-} >- >-TEST(DataInteractionTests, OverrideDataInteractionOperation) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"simple"]; >- >- auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:[@"<body></body>" dataUsingEncoding:NSUTF8StringEncoding]]; >- >- __block bool finishedLoadingData = false; >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >- [dataInteractionSimulator setOverrideDataInteractionOperationBlock:^NSUInteger(NSUInteger operation, id session) >- { >- EXPECT_EQ(0U, operation); >- return UIDropOperationCopy; >- }]; >- [dataInteractionSimulator setDataInteractionOperationCompletionBlock:^(BOOL handled, NSArray *itemProviders) { >- EXPECT_FALSE(handled); >- [itemProviders.firstObject loadDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML completionHandler:^(NSData *data, NSError *error) { >- NSString *text = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; >- EXPECT_WK_STREQ("<body></body>", text.UTF8String); >- EXPECT_FALSE(!!error); >- finishedLoadingData = true; >- }]; >- }]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- TestWebKitAPI::Util::run(&finishedLoadingData); >-} >- >-TEST(DataInteractionTests, InjectedBundleOverridePerformTwoStepDrop) >-{ >- WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >- [configuration.processPool _setObject:@YES forBundleParameter:@"BundleOverridePerformTwoStepDrop"]; >- >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >- [webView loadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >- { >- completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil); >- return [NSProgress discreteProgressWithTotalUnitCount:100]; >- }]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"editor.textContent"].length); >-} >- >-TEST(DataInteractionTests, InjectedBundleAllowPerformTwoStepDrop) >-{ >- WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >- [configuration.processPool _setObject:@NO forBundleParameter:@"BundleOverridePerformTwoStepDrop"]; >- >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >- [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >- [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >- >- auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >- [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >- { >- completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil); >- return [NSProgress discreteProgressWithTotalUnitCount:100]; >- }]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >- [dataInteractionSimulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >- >- EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >-} >- >-TEST(DataInteractionTests, InjectedBundleImageElementData) >-{ >- WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >- [configuration _setAttachmentElementEnabled:YES]; >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >- [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"]; >- >- __block RetainPtr<NSString> injectedString; >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data) >- { >- injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]); >- return @[ itemProvider ]; >- }]; >- >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 250)]; >- >- EXPECT_WK_STREQ("hello", [injectedString UTF8String]); >-} >- >-TEST(DataInteractionTests, InjectedBundleAttachmentElementData) >-{ >- WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >- [configuration _setAttachmentElementEnabled:YES]; >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >- [webView synchronouslyLoadTestPageNamed:@"attachment-element"]; >- >- __block RetainPtr<NSString> injectedString; >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data) >- { >- injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]); >- return @[ itemProvider ]; >- }]; >- >- [dataInteractionSimulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400)]; >- >- EXPECT_WK_STREQ("hello", [injectedString UTF8String]); >- EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"getSelection().isCollapsed"].boolValue); >-} >- >-TEST(DataInteractionTests, LargeImageToTargetDiv) >-{ >- auto testWebViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]); >- [[testWebViewConfiguration preferences] _setLargeImageAsyncDecodingEnabled:NO]; >- >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:testWebViewConfiguration.get()]); >- [webView synchronouslyLoadTestPageNamed:@"div-and-large-image"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(200, 400) to:CGPointMake(200, 150)]; >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String); >- checkFirstTypeIsPresentAndSecondTypeIsMissing(dataInteractionSimulator.get(), kUTTypePNG, kUTTypeFileURL); >- checkEstimatedSize(dataInteractionSimulator.get(), { 2000, 2000 }); >-} >- >-TEST(DataInteractionTests, LinkWithEmptyHREF) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"link-and-input"]; >- [webView stringByEvaluatingJavaScript:@"document.querySelector('a').href = ''"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- >- EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]); >- EXPECT_WK_STREQ("", [webView editorValue].UTF8String); >-} >- >-TEST(DataInteractionTests, CancelledLiftDoesNotCauseSubsequentDragsToFail) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *, NSArray *, NSDictionary *) >- { >- return @[ ]; >- }]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- EXPECT_EQ(DataInteractionCancelled, [dataInteractionSimulator phase]); >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"target.textContent"]); >- NSString *outputText = [webView stringByEvaluatingJavaScript:@"output.textContent"]; >- checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]); >- >- [webView stringByEvaluatingJavaScript:@"output.innerHTML = ''"]; >- [dataInteractionSimulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *) >- { >- return @[ itemProvider ]; >- }]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]); >- [webView stringByEvaluatingJavaScript:@"output.textContent"]; >- checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]); >-} >- >-static void testDragAndDropOntoTargetElements(TestWKWebView *webView) >-{ >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView]); >- [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 250)]; >- EXPECT_WK_STREQ("rgb(0, 128, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(target1).backgroundColor"]); >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target1.textContent"]); >- >- [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(250, 50)]; >- EXPECT_WK_STREQ("rgb(0, 128, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(target2).backgroundColor"]); >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target2.textContent"]); >- >- [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(250, 250)]; >- EXPECT_WK_STREQ("rgb(0, 128, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(target3).backgroundColor"]); >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target3.textContent"]); >-} >- >-TEST(DataInteractionTests, DragEventClientCoordinatesBasic) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >- >- testDragAndDropOntoTargetElements(webView.get()); >-} >- >-TEST(DataInteractionTests, DragEventClientCoordinatesWithScrollOffset) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >- [webView stringByEvaluatingJavaScript:@"document.body.style.margin = '1000px 0'"]; >- [webView stringByEvaluatingJavaScript:@"document.scrollingElement.scrollTop = 1000"]; >- [webView waitForNextPresentationUpdate]; >- >- testDragAndDropOntoTargetElements(webView.get()); >-} >- >-TEST(DataInteractionTests, DragEventPageCoordinatesBasic) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >- [webView stringByEvaluatingJavaScript:@"window.usePageCoordinates = true"]; >- >- testDragAndDropOntoTargetElements(webView.get()); >-} >- >-TEST(DataInteractionTests, DragEventPageCoordinatesWithScrollOffset) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >- [webView stringByEvaluatingJavaScript:@"document.body.style.margin = '1000px 0'"]; >- [webView stringByEvaluatingJavaScript:@"document.scrollingElement.scrollTop = 1000"]; >- [webView stringByEvaluatingJavaScript:@"window.usePageCoordinates = true"]; >- [webView waitForNextPresentationUpdate]; >- >- testDragAndDropOntoTargetElements(webView.get()); >-} >- >-TEST(DataInteractionTests, DoNotCrashWhenSelectionIsClearedInDragStart) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dragstart-clear-selection"]; >- >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)]; >- >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"paragraph.textContent"]); >-} >- >-// FIXME: Re-enable this test once we resolve <https://bugs.webkit.org/show_bug.cgi?id=175204> >-#if __IPHONE_OS_VERSION_MAX_ALLOWED <= 110401 >-TEST(DataInteractionTests, CustomActionSheetPopover) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"]; >- >- auto dataInteractionSimulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [dataInteractionSimulator setShouldEnsureUIApplication:YES]; >- >- __block BOOL didInvokeCustomActionSheet = NO; >- [dataInteractionSimulator setShowCustomActionSheetBlock:^BOOL(_WKActivatedElementInfo *element) >- { >- EXPECT_EQ(_WKActivatedElementTypeLink, element.type); >- EXPECT_WK_STREQ("Hello world", element.title.UTF8String); >- didInvokeCustomActionSheet = YES; >- return YES; >- }]; >- [dataInteractionSimulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >- EXPECT_TRUE(didInvokeCustomActionSheet); >- EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String); >-} >-#endif >- >-TEST(DataInteractionTests, UnresponsivePageDoesNotHangUI) >-{ >- _WKProcessPoolConfiguration *processPoolConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease]; >- processPoolConfiguration.ignoreSynchronousMessagingTimeoutsForTesting = YES; >- >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:[[[WKWebViewConfiguration alloc] init] autorelease] processPoolConfiguration:processPoolConfiguration]); >- [webView synchronouslyLoadTestPageNamed:@"simple"]; >- [webView evaluateJavaScript:@"while(1);" completionHandler:nil]; >- >- // The test passes if we can prepare for data interaction without timing out. >- auto dragSession = adoptNS([[MockDragSession alloc] init]); >- [(id <UIDragInteractionDelegate_ForWebKitOnly>)[webView dragInteractionDelegate] _dragInteraction:[webView dragInteraction] prepareForSession:dragSession.get() completion:^() { }]; >-} >- >-TEST(DataInteractionTests, WebItemProviderPasteboardLoading) >-{ >- static NSString *fastString = @"This data loads quickly"; >- static NSString *slowString = @"This data loads slowly"; >- >- WebItemProviderPasteboard *pasteboard = [WebItemProviderPasteboard sharedInstance]; >- auto fastItem = adoptNS([[UIItemProvider alloc] init]); >- [fastItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >- { >- completionBlock([fastString dataUsingEncoding:NSUTF8StringEncoding], nil); >- return nil; >- }]; >- >- auto slowItem = adoptNS([[UIItemProvider alloc] init]); >- [slowItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >- { >- sleep(2_s); >- completionBlock([slowString dataUsingEncoding:NSUTF8StringEncoding], nil); >- return nil; >- }]; >- >- __block bool hasRunFirstCompletionBlock = false; >- pasteboard.itemProviders = @[ fastItem.get(), slowItem.get() ]; >- [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) { >- EXPECT_EQ(2UL, urls.count); >- auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]); >- auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]); >- EXPECT_WK_STREQ(fastString, [firstString UTF8String]); >- EXPECT_WK_STREQ(slowString, [secondString UTF8String]); >- hasRunFirstCompletionBlock = true; >- } synchronousTimeout:600]; >- EXPECT_TRUE(hasRunFirstCompletionBlock); >- >- __block bool hasRunSecondCompletionBlock = false; >- [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) { >- EXPECT_EQ(2UL, urls.count); >- auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]); >- auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]); >- EXPECT_WK_STREQ(fastString, [firstString UTF8String]); >- EXPECT_WK_STREQ(slowString, [secondString UTF8String]); >- hasRunSecondCompletionBlock = true; >- } synchronousTimeout:0]; >- EXPECT_FALSE(hasRunSecondCompletionBlock); >- TestWebKitAPI::Util::run(&hasRunSecondCompletionBlock); >-} >- >-TEST(DataInteractionTests, DoNotCrashWhenSelectionMovesOffscreenAfterDragStart) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dragstart-change-selection-offscreen"]; >- >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)]; >- >- EXPECT_WK_STREQ("FAR OFFSCREEN", [webView stringByEvaluatingJavaScript:@"getSelection().getRangeAt(0).toString()"]); >-} >- >-TEST(DataInteractionTests, AdditionalItemsCanBePreventedOnDragStart) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"selected-text-image-link-and-editable"]; >- [webView stringByEvaluatingJavaScript:@"link.addEventListener('dragstart', e => e.preventDefault())"]; >- [webView stringByEvaluatingJavaScript:@"image.addEventListener('dragstart', e => e.preventDefault())"]; >- >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400) additionalItemRequestLocations:@{ >- @0.33: [NSValue valueWithCGPoint:CGPointMake(50, 150)], >- @0.66: [NSValue valueWithCGPoint:CGPointMake(50, 250)] >- }]; >- EXPECT_WK_STREQ("ABCD", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >-} >- >-TEST(DataInteractionTests, AdditionalLinkAndImageIntoContentEditable) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"selected-text-image-link-and-editable"]; >- >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400) additionalItemRequestLocations:@{ >- @0.33: [NSValue valueWithCGPoint:CGPointMake(50, 150)], >- @0.66: [NSValue valueWithCGPoint:CGPointMake(50, 250)] >- }]; >- EXPECT_WK_STREQ("ABCDA link", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >- EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!editor.querySelector('img')"]); >- EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]); >-} >- >-TEST(DataInteractionTests, DragLiftPreviewDataTransferSetDragImage) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"DataTransfer-setDragImage"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- // Use DataTransfer.setDragImage to specify an existing image element in the DOM. >- [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 50)]; >- checkCGRectIsEqualToCGRectWithLogging({{100, 50}, {215, 174}}, [simulator liftPreviews][0].view.frame); >- >- // Use DataTransfer.setDragImage to specify an existing image element in the DOM, with x and y offsets. >- [simulator runFrom:CGPointMake(10, 150) to:CGPointMake(250, 150)]; >- checkCGRectIsEqualToCGRectWithLogging({{-90, 50}, {215, 174}}, [simulator liftPreviews][0].view.frame); >- >- // Use DataTransfer.setDragImage to specify a newly created Image, disconnected from the DOM. >- [simulator runFrom:CGPointMake(100, 250) to:CGPointMake(250, 250)]; >- checkCGRectIsEqualToCGRectWithLogging({{100, 250}, {215, 174}}, [simulator liftPreviews][0].view.frame); >- >- // Don't use DataTransfer.setDragImage and fall back to snapshotting the dragged element. >- [simulator runFrom:CGPointMake(50, 350) to:CGPointMake(250, 350)]; >- checkCGRectIsEqualToCGRectWithLogging({{0, 300}, {300, 100}}, [simulator liftPreviews][0].view.frame); >- >- // Perform a normal drag on an image. >- [simulator runFrom:CGPointMake(50, 450) to:CGPointMake(250, 450)]; >- checkCGRectIsEqualToCGRectWithLogging({{0, 400}, {215, 174}}, [simulator liftPreviews][0].view.frame); >-} >- >-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >- >-static NSData *testIconImageData() >-{ >- return [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png" inDirectory:@"TestWebKitAPI.resources"]]; >-} >- >-TEST(DataInteractionTests, DataTransferGetDataWhenDroppingImageAndMarkup) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- WKPreferencesSetCustomPasteboardDataEnabled((WKPreferencesRef)[webView configuration].preferences, true); >- [webView synchronouslyLoadTestPageNamed:@"DataTransfer"]; >- >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypePNG withData:testIconImageData()]; >- NSString *markupString = @"<script>bar()</script><strong onmousedown=javascript:void(0)>HELLO WORLD</strong>"; >- [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:[markupString dataUsingEncoding:NSUTF8StringEncoding]]; >- [itemProvider setSuggestedName:@"icon"]; >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [simulator runFrom:CGPointZero to:CGPointMake(50, 100)]; >- >- EXPECT_WK_STREQ("Files, text/html", [webView stringByEvaluatingJavaScript:@"types.textContent"]); >- EXPECT_WK_STREQ("(STRING, text/html), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]); >- EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]); >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]); >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]); >- EXPECT_WK_STREQ("HELLO WORLD", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]); >- EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"rawHTMLData.textContent"] containsString:@"script"]); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataWhenDroppingPlainText) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"select(plain)"]; >- [simulator runFrom:CGPointMake(50, 75) to:CGPointMake(50, 375)]; >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ @"text/plain" : @"" }, >- @"drop": @{ @"text/plain" : @"Plain text" } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataWhenDroppingCustomData) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"select(rich)"]; >- [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >- [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover" : @{ >- @"text/plain" : @"", >- @"foo/plain" : @"", >- @"text/html" : @"", >- @"bar/html" : @"", >- @"text/uri-list" : @"", >- @"baz/uri-list" : @"" >- }, >- @"drop" : @{ >- @"text/plain" : @"ben bitdiddle", >- @"foo/plain" : @"eva lu ator", >- @"text/html" : @"<b>bold text</b>", >- @"bar/html" : @"<i>italic text</i>", >- @"text/uri-list" : @"https://www.apple.com", >- @"baz/uri-list" : @"https://www.webkit.org" >- } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataWhenDroppingURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"rich.innerHTML = '<a href=\"https://www.apple.com/\">This is a link.</a>'"]; >- [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ >- @"text/uri-list" : @"", >- @"text/plain" : @"" >- }, >- @"drop": @{ >- @"text/uri-list" : @"https://www.apple.com/", >- @"text/plain" : @"https://www.apple.com/" >- } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataWhenDroppingImageWithFileURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSURL *iconURL = [[NSBundle mainBundle] URLForResource:@"icon" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]; >- [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypePNG fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[protectedIconURL = retainPtr(iconURL)] (FileLoadCompletionBlock completionHandler) -> NSProgress * { >- completionHandler(protectedIconURL.get(), NO, nil); >- return nil; >- }]; >- [itemProvider registerObject:iconURL visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- >- [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >- >- // 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": @{ @"Files": @"", @"text/uri-list": @"" }, >- @"drop": @{ @"Files": @"", @"text/uri-list": @"" } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataWhenDroppingImageWithHTTPURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(DataLoadCompletionBlock completionHandler) >- { >- completionHandler(UIImageJPEGRepresentation(testIconImage(), 0.5), nil); >- return nil; >- }]; >- [itemProvider registerObject:[NSURL URLWithString:@"http://webkit.org"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- >- [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ @"Files": @"", @"text/uri-list": @"" }, >- @"drop": @{ @"Files": @"", @"text/uri-list": @"http://webkit.org/" } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataWhenDroppingRespectsPresentationStyle) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- runTestWithTemporaryTextFile(^(NSURL *fileURL) { >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[protectedFileURL = retainPtr(fileURL)] (FileLoadCompletionBlock completionHandler) -> NSProgress * { >- completionHandler(protectedFileURL.get(), NO, nil); >- return nil; >- }]; >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- >- [itemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment]; >- [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ @"Files" : @"" }, >- @"drop": @{ @"Files" : @"" } >- }); >- >- [itemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleInline]; >- [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ @"text/plain" : @"" }, >- @"drop": @{ @"text/plain" : @"This is a tiny blob of text." } >- }); >- }); >-} >- >-TEST(DataInteractionTests, DataTransferSetDataCannotWritePlatformTypes) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"select(rich)"]; >- [webView stringByEvaluatingJavaScript:@"customData = { 'text/plain' : 'foo', 'com.adobe.pdf' : 'try and decode me!' }"]; >- [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >- >- [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >- checkFirstTypeIsPresentAndSecondTypeIsMissing(simulator.get(), kUTTypeUTF8PlainText, kUTTypePDF); >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ >- @"text/plain": @"", >- @"com.adobe.pdf": @"" >- }, >- @"drop": @{ >- @"text/plain": @"foo", >- @"com.adobe.pdf": @"try and decode me!" >- } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataReadPlainAndRichText) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"DataTransfer"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:20] }; >- NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"WebKit" attributes:textAttributes]; >- [itemProvider registerObject:richText visibility:NSItemProviderRepresentationVisibilityAll]; >- [itemProvider registerObject:[NSURL URLWithString:@"https://www.webkit.org/"] visibility:NSItemProviderRepresentationVisibilityAll]; >- [itemProvider registerObject:@"WebKit" visibility:NSItemProviderRepresentationVisibilityAll]; >- >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [simulator runFrom:CGPointZero to:CGPointMake(50, 100)]; >- >- EXPECT_WK_STREQ("text/html, text/plain, text/uri-list", [webView stringByEvaluatingJavaScript:@"types.textContent"]); >- EXPECT_WK_STREQ("WebKit", [webView stringByEvaluatingJavaScript:@"textData.textContent"]); >- EXPECT_WK_STREQ("https://www.webkit.org/", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]); >- EXPECT_WK_STREQ("WebKit", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]); >- EXPECT_WK_STREQ("(STRING, text/html), (STRING, text/plain), (STRING, text/uri-list)", [webView stringByEvaluatingJavaScript:@"items.textContent"]); >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"files.textContent"]); >-} >- >-TEST(DataInteractionTests, DataTransferSuppressGetDataDueToPresenceOfTextFile) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"DataTransfer"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- [itemProvider registerObject:@"Hello world" visibility:NSItemProviderRepresentationVisibilityAll]; >- [itemProvider setSuggestedName:@"hello.txt"]; >- >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [simulator runFrom:CGPointZero to:CGPointMake(50, 100)]; >- >- EXPECT_WK_STREQ("Files", [webView stringByEvaluatingJavaScript:@"types.textContent"]); >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]); >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]); >- EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]); >- EXPECT_WK_STREQ("(FILE, text/plain)", [webView stringByEvaluatingJavaScript:@"items.textContent"]); >- EXPECT_WK_STREQ("('hello.txt', text/plain)", [webView stringByEvaluatingJavaScript:@"files.textContent"]); >-} >- >-TEST(DataInteractionTests, DataTransferGetDataCannotReadPrivateArbitraryTypes) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >- [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeMP3 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(DataLoadCompletionBlock completionHandler) >- { >- completionHandler([@"this is a test" dataUsingEncoding:NSUTF8StringEncoding], nil); >- return nil; >- }]; >- [itemProvider registerDataRepresentationForTypeIdentifier:@"org.WebKit.TestWebKitAPI.custom-pasteboard-type" visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(DataLoadCompletionBlock completionHandler) >- { >- completionHandler([@"this is another test" dataUsingEncoding:NSUTF8StringEncoding], nil); >- return nil; >- }]; >- [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >- [itemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleInline]; >- [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ }, >- @"drop": @{ } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferSetDataValidURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"select(rich)"]; >- [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'https://webkit.org/b/123' }"]; >- [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >- >- __block bool done = false; >- [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >- { >- EXPECT_EQ(1UL, session.items.count); >- auto *item = session.items[0].itemProvider; >- EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]); >- EXPECT_TRUE([item canLoadObjectOfClass: [NSURL class]]); >- [item loadObjectOfClass:[NSURL class] completionHandler:^(id<NSItemProviderReading> url, NSError *error) { >- EXPECT_TRUE([url isKindOfClass: [NSURL class]]); >- EXPECT_WK_STREQ([(NSURL *)url absoluteString], @"https://webkit.org/b/123"); >- done = true; >- }]; >- return session.items; >- }]; >- [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >- >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ >- @"text/uri-list": @"", >- }, >- @"drop": @{ >- @"text/uri-list": @"https://webkit.org/b/123", >- } >- }); >- TestWebKitAPI::Util::run(&done); >-} >- >-TEST(DataInteractionTests, DataTransferSetDataUnescapedURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"select(rich)"]; >- [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'http://webkit.org/b/\u4F60\u597D;?x=8 + 6' }"]; >- [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >- >- __block bool done = false; >- [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >- { >- EXPECT_EQ(1UL, session.items.count); >- auto *item = session.items[0].itemProvider; >- EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]); >- EXPECT_TRUE([item canLoadObjectOfClass: [NSURL class]]); >- [item loadObjectOfClass:[NSURL class] completionHandler:^(id<NSItemProviderReading> url, NSError *error) { >- EXPECT_TRUE([url isKindOfClass: [NSURL class]]); >- EXPECT_WK_STREQ([(NSURL *)url absoluteString], @"http://webkit.org/b/%E4%BD%A0%E5%A5%BD;?x=8%20+%206"); >- done = true; >- }]; >- return session.items; >- }]; >- [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >- >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ >- @"text/uri-list": @"", >- }, >- @"drop": @{ >- @"text/uri-list": @"http://webkit.org/b/\u4F60\u597D;?x=8 + 6", >- } >- }); >- TestWebKitAPI::Util::run(&done); >-} >- >-TEST(DataInteractionTests, DataTransferSetDataInvalidURL) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"select(rich)"]; >- [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'some random string' }"]; >- [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >- >- [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >- NSArray *registeredTypes = [simulator.get().sourceItemProviders.firstObject registeredTypeIdentifiers]; >- EXPECT_FALSE([registeredTypes containsObject:(NSString *)kUTTypeURL]); >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ >- @"text/uri-list": @"", >- }, >- @"drop": @{ >- @"text/uri-list": @"some random string", >- } >- }); >-} >- >-TEST(DataInteractionTests, DataTransferSanitizeHTML) >-{ >- auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >- [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >- auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]); >- >- [webView stringByEvaluatingJavaScript:@"select(rich)"]; >- [webView stringByEvaluatingJavaScript:@"customData = { 'text/html' : '<meta content=\"secret\">" >- "<b onmouseover=\"dangerousCode()\">hello</b><!-- secret-->, world<script>dangerousCode()</script>' }"]; >- [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >- >- __block bool done = false; >- [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >- { >- EXPECT_EQ(1UL, session.items.count); >- auto *item = session.items[0].itemProvider; >- EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeHTML]); >- [item loadDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML completionHandler:^(NSData *data, NSError *error) { >- NSString *markup = [[[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding] autorelease]; >- EXPECT_TRUE([markup containsString:@"hello"]); >- EXPECT_TRUE([markup containsString:@", world"]); >- EXPECT_FALSE([markup containsString:@"secret"]); >- EXPECT_FALSE([markup containsString:@"dangerousCode"]); >- done = true; >- }]; >- return session.items; >- }]; >- [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >- >- checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >- @"dragover": @{ >- @"text/html": @"", >- }, >- @"drop": @{ >- @"text/html": @"<meta content=\"secret\"><b onmouseover=\"dangerousCode()\">hello</b><!-- secret-->, world<script>dangerousCode()</script>", >- } >- }); >- TestWebKitAPI::Util::run(&done); >-} >- >-#endif // __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >- >-} // namespace TestWebKitAPI >- >-#endif // ENABLE(DATA_INTERACTION) >diff --git a/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm b/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..16e1f31b7f214185ca6b824197a18096e2801096 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm >@@ -0,0 +1,1911 @@ >+/* >+ * 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 ENABLE(DRAG_SUPPORT) && PLATFORM(IOS) >+ >+#import "DraggingSimulator.h" >+#import "PlatformUtilities.h" >+#import "TestWKWebView.h" >+#import "UIKitSPI.h" >+#import "WKWebViewConfigurationExtras.h" >+#import <MobileCoreServices/MobileCoreServices.h> >+#import <UIKit/NSItemProvider+UIKitAdditions.h> >+#import <WebKit/WKPreferencesPrivate.h> >+#import <WebKit/WKPreferencesRefPrivate.h> >+#import <WebKit/WKProcessPoolPrivate.h> >+#import <WebKit/WKWebViewConfigurationPrivate.h> >+#import <WebKit/WebItemProviderPasteboard.h> >+#import <WebKit/_WKProcessPoolConfiguration.h> >+#import <wtf/Seconds.h> >+ >+typedef void (^FileLoadCompletionBlock)(NSURL *, BOOL, NSError *); >+typedef void (^DataLoadCompletionBlock)(NSData *, NSError *); >+typedef void (^UIItemProviderDataLoadCompletionBlock)(NSData *, NSError *); >+ >+#if !USE(APPLE_INTERNAL_SDK) >+ >+@interface UIItemProviderRepresentationOptions : NSObject >+@end >+ >+#endif >+ >+@interface UIItemProvider() >++ (UIItemProvider *)itemProviderWithURL:(NSURL *)url title:(NSString *)title; >+- (void) registerDataRepresentationForTypeIdentifier:(NSString *)typeIdentifier options:(UIItemProviderRepresentationOptions*)options loadHandler:(NSProgress * (^)(void (^UIItemProviderDataLoadCompletionBlock)(NSData *item, NSError *error))) loadHandler; >+@end >+ >+static NSString *InjectedBundlePasteboardDataType = @"org.webkit.data"; >+ >+static UIImage *testIconImage() >+{ >+ return [UIImage imageNamed:@"TestWebKitAPI.resources/icon.png"]; >+} >+ >+static NSData *testZIPArchive() >+{ >+ NSURL *zipFileURL = [[NSBundle mainBundle] URLForResource:@"compressed-files" withExtension:@"zip" subdirectory:@"TestWebKitAPI.resources"]; >+ return [NSData dataWithContentsOfURL:zipFileURL]; >+} >+ >+@implementation UIItemProvider (DragAndDropTests) >+ >+- (void)registerDataRepresentationForTypeIdentifier:(NSString *)typeIdentifier withData:(NSData *)data >+{ >+ RetainPtr<NSData> retainedData = data; >+ [self registerDataRepresentationForTypeIdentifier:typeIdentifier visibility:UIItemProviderRepresentationOptionsVisibilityAll loadHandler: [retainedData] (DataLoadCompletionBlock block) -> NSProgress * { >+ block(retainedData.get(), nil); >+ return [NSProgress discreteProgressWithTotalUnitCount:100]; >+ }]; >+} >+ >+@end >+ >+@implementation TestWKWebView (DragAndDropTests) >+ >+- (BOOL)editorContainsImageElement >+{ >+ return [self stringByEvaluatingJavaScript:@"!!editor.querySelector('img')"].boolValue; >+} >+ >+- (NSString *)editorValue >+{ >+ return [self stringByEvaluatingJavaScript:@"editor.value"]; >+} >+ >+@end >+ >+static NSValue *makeCGRectValue(CGFloat x, CGFloat y, CGFloat width, CGFloat height) >+{ >+ return [NSValue valueWithCGRect:CGRectMake(x, y, width, height)]; >+} >+ >+static void checkCGRectIsEqualToCGRectWithLogging(CGRect expected, CGRect observed) >+{ >+ BOOL isEqual = CGRectEqualToRect(expected, observed); >+ EXPECT_TRUE(isEqual); >+ if (!isEqual) >+ NSLog(@"Expected: %@ but observed: %@", NSStringFromCGRect(expected), NSStringFromCGRect(observed)); >+} >+ >+static void checkSelectionRectsWithLogging(NSArray *expected, NSArray *observed) >+{ >+ if (![expected isEqualToArray:observed]) >+ NSLog(@"Expected selection rects: %@ but observed: %@", expected, observed); >+ EXPECT_TRUE([expected isEqualToArray:observed]); >+} >+ >+static void checkRichTextTypePrecedesPlainTextType(DraggingSimulator *simulator) >+{ >+ // At least one of "com.apple.flat-rtfd" or "public.rtf" is expected to have higher precedence than "public.utf8-plain-text". >+ NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers]; >+ auto indexOfRTFType = [registeredTypes indexOfObject:(NSString *)kUTTypeRTF]; >+ auto indexOfFlatRTFDType = [registeredTypes indexOfObject:(NSString *)kUTTypeFlatRTFD]; >+ auto indexOfPlainTextType = [registeredTypes indexOfObject:(NSString *)kUTTypeUTF8PlainText]; >+ EXPECT_NE((NSInteger)indexOfPlainTextType, NSNotFound); >+ EXPECT_TRUE((indexOfRTFType != NSNotFound && indexOfRTFType < indexOfPlainTextType) || (indexOfFlatRTFDType != NSNotFound && indexOfFlatRTFDType < indexOfPlainTextType)); >+} >+ >+static void checkFirstTypeIsPresentAndSecondTypeIsMissing(DraggingSimulator *simulator, CFStringRef firstType, CFStringRef secondType) >+{ >+ NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers]; >+ EXPECT_TRUE([registeredTypes containsObject:(NSString *)firstType]); >+ EXPECT_FALSE([registeredTypes containsObject:(NSString *)secondType]); >+} >+ >+static void checkTypeIdentifierIsRegisteredAtIndex(DraggingSimulator *simulator, NSString *type, NSUInteger index) >+{ >+ NSArray *registeredTypes = [simulator.sourceItemProviders.firstObject registeredTypeIdentifiers]; >+ EXPECT_GT(registeredTypes.count, index); >+ EXPECT_WK_STREQ(type.UTF8String, [registeredTypes[index] UTF8String]); >+} >+ >+static void checkEstimatedSize(DraggingSimulator *simulator, CGSize estimatedSize) >+{ >+ UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject; >+ EXPECT_EQ(estimatedSize.width, sourceItemProvider.preferredPresentationSize.width); >+ EXPECT_EQ(estimatedSize.height, sourceItemProvider.preferredPresentationSize.height); >+} >+ >+static void checkSuggestedNameAndEstimatedSize(DraggingSimulator *simulator, NSString *suggestedName, CGSize estimatedSize) >+{ >+ UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject; >+ EXPECT_WK_STREQ(suggestedName.UTF8String, sourceItemProvider.suggestedName.UTF8String); >+ EXPECT_EQ(estimatedSize.width, sourceItemProvider.preferredPresentationSize.width); >+ EXPECT_EQ(estimatedSize.height, sourceItemProvider.preferredPresentationSize.height); >+} >+ >+static void checkStringArraysAreEqual(NSArray<NSString *> *expected, NSArray<NSString *> *observed) >+{ >+ EXPECT_EQ(expected.count, observed.count); >+ for (NSUInteger index = 0; index < expected.count; ++index) { >+ NSString *expectedString = [expected objectAtIndex:index]; >+ NSString *observedString = [observed objectAtIndex:index]; >+ EXPECT_WK_STREQ(expectedString, observedString); >+ if (![expectedString isEqualToString:observedString]) >+ NSLog(@"Expected observed string: %@ to match expected string: %@ at index: %tu", observedString, expectedString, index); >+ } >+} >+ >+static void checkDragCaretRectIsContainedInRect(CGRect caretRect, CGRect containerRect) >+{ >+ BOOL contained = CGRectContainsRect(containerRect, caretRect); >+ EXPECT_TRUE(contained); >+ if (!contained) >+ NSLog(@"Expected caret rect: %@ to fit within container rect: %@", NSStringFromCGRect(caretRect), NSStringFromCGRect(containerRect)); >+} >+ >+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >+ >+static void checkJSONWithLogging(NSString *jsonString, NSDictionary *expected) >+{ >+ BOOL success = TestWebKitAPI::Util::jsonMatchesExpectedValues(jsonString, expected); >+ EXPECT_TRUE(success); >+ if (!success) >+ NSLog(@"Expected JSON: %@ to match values: %@", jsonString, expected); >+} >+ >+static NSData *testIconImageData() >+{ >+ return [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"icon" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]]; >+} >+ >+static void runTestWithTemporaryTextFile(void(^runTest)(NSURL *fileURL)) >+{ >+ NSString *fileName = [NSString stringWithFormat:@"drag-drop-text-file-%@.txt", [NSUUID UUID].UUIDString]; >+ RetainPtr<NSURL> temporaryFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName] isDirectory:NO]; >+ [[NSFileManager defaultManager] removeItemAtURL:temporaryFile.get() error:nil]; >+ >+ NSError *error = nil; >+ [@"This is a tiny blob of text." writeToURL:temporaryFile.get() atomically:YES encoding:NSUTF8StringEncoding error:&error]; >+ >+ if (error) >+ NSLog(@"Error writing temporary file: %@", error); >+ >+ @try { >+ runTest(temporaryFile.get()); >+ } @finally { >+ [[NSFileManager defaultManager] removeItemAtURL:temporaryFile.get() error:nil]; >+ } >+} >+ >+static void runTestWithTemporaryFolder(void(^runTest)(NSURL *folderURL)) >+{ >+ NSString *folderName = [NSString stringWithFormat:@"some.directory-%@", [NSUUID UUID].UUIDString]; >+ RetainPtr<NSURL> temporaryFolder = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:folderName] isDirectory:YES]; >+ [[NSFileManager defaultManager] removeItemAtURL:temporaryFolder.get() error:nil]; >+ >+ NSError *error = nil; >+ NSFileManager *defaultManager = [NSFileManager defaultManager]; >+ [defaultManager createDirectoryAtURL:temporaryFolder.get() withIntermediateDirectories:NO attributes:nil error:&error]; >+ [testIconImageData() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"icon.png" isDirectory:NO] atomically:YES]; >+ [testZIPArchive() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"archive.zip" isDirectory:NO] atomically:YES]; >+ >+ NSURL *firstSubdirectory = [temporaryFolder.get() URLByAppendingPathComponent:@"subdirectory1" isDirectory:YES]; >+ [defaultManager createDirectoryAtURL:firstSubdirectory withIntermediateDirectories:NO attributes:nil error:&error]; >+ [@"I am a text file in the first subdirectory." writeToURL:[firstSubdirectory URLByAppendingPathComponent:@"text-file-1.txt" isDirectory:NO] atomically:YES encoding:NSUTF8StringEncoding error:&error]; >+ >+ NSURL *secondSubdirectory = [temporaryFolder.get() URLByAppendingPathComponent:@"subdirectory2" isDirectory:YES]; >+ [defaultManager createDirectoryAtURL:secondSubdirectory withIntermediateDirectories:NO attributes:nil error:&error]; >+ [@"I am a text file in the second subdirectory." writeToURL:[secondSubdirectory URLByAppendingPathComponent:@"text-file-2.txt" isDirectory:NO] atomically:YES encoding:NSUTF8StringEncoding error:&error]; >+ >+ if (error) >+ NSLog(@"Error writing temporary file: %@", error); >+ >+ @try { >+ runTest(temporaryFolder.get()); >+ } @finally { >+ [[NSFileManager defaultManager] removeItemAtURL:temporaryFolder.get() error:nil]; >+ } >+} >+ >+#endif // __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >+ >+namespace TestWebKitAPI { >+ >+TEST(DragAndDropTests, ImageToContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_TRUE([webView editorContainsImageElement]); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"drop"]); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [simulator finalSelectionRects]); >+ checkFirstTypeIsPresentAndSecondTypeIsMissing(simulator.get(), kUTTypePNG, kUTTypeFileURL); >+ checkEstimatedSize(simulator.get(), { 215, 174 }); >+} >+ >+TEST(DragAndDropTests, CanStartDragOnEnormousImage) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadHTMLString:@"<img src='enormous.svg'></img>"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)]; >+ >+ NSArray *registeredTypes = [[simulator sourceItemProviders].firstObject registeredTypeIdentifiers]; >+ EXPECT_WK_STREQ((NSString *)kUTTypeScalableVectorGraphics, [registeredTypes firstObject]); >+} >+ >+TEST(DragAndDropTests, ImageToTextarea) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"image-and-textarea"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("", [webView editorValue]); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"drop"]); >+ checkFirstTypeIsPresentAndSecondTypeIsMissing(simulator.get(), kUTTypePNG, kUTTypeFileURL); >+ checkEstimatedSize(simulator.get(), { 215, 174 }); >+} >+ >+TEST(DragAndDropTests, ImageInLinkToInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [simulator finalSelectionRects]); >+ checkSuggestedNameAndEstimatedSize(simulator.get(), @"icon.png", { 215, 174 }); >+ checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (NSString *)kUTTypePNG, 0); >+} >+ >+TEST(DragAndDropTests, ImageInLinkWithoutHREFToInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"image-in-link-and-input"]; >+ [webView stringByEvaluatingJavaScript:@"link.href = ''"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("", [webView editorValue]); >+ checkEstimatedSize(simulator.get(), { 215, 174 }); >+ checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (NSString *)kUTTypePNG, 0); >+} >+ >+TEST(DragAndDropTests, ImageDoesNotUseElementSizeAsEstimatedSize) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"gif-and-file-input"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom: { 100, 100 } to: { 100, 300 }]; >+ >+ checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (NSString *)kUTTypeGIF, 0); >+ checkSuggestedNameAndEstimatedSize(simulator.get(), @"apple.gif", { 52, 64 }); >+ EXPECT_WK_STREQ("apple.gif (image/gif)", [webView stringByEvaluatingJavaScript:@"output.textContent"]); >+} >+ >+TEST(DragAndDropTests, ContentEditableToContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView loadTestPageNamed:@"autofocus-contenteditable"]; >+ [simulator waitForInputSession]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL); >+ EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"drop"]); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 961, 227) ], [simulator finalSelectionRects]); >+ checkRichTextTypePrecedesPlainTextType(simulator.get()); >+} >+ >+TEST(DragAndDropTests, ContentEditableToTextarea) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView loadTestPageNamed:@"contenteditable-and-textarea"]; >+ [simulator waitForInputSession]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.textContent"].length, 0UL); >+ EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"drop"]); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(6, 203, 990, 232) ], [simulator finalSelectionRects]); >+ checkRichTextTypePrecedesPlainTextType(simulator.get()); >+} >+ >+TEST(DragAndDropTests, ContentEditableMoveParagraphs) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView loadTestPageNamed:@"two-paragraph-contenteditable"]; >+ [simulator waitForInputSession]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 450)]; >+ >+ NSString *finalTextContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"]; >+ NSUInteger firstParagraphOffset = [finalTextContent rangeOfString:@"This is the first paragraph"].location; >+ NSUInteger secondParagraphOffset = [finalTextContent rangeOfString:@"This is the second paragraph"].location; >+ >+ EXPECT_FALSE(firstParagraphOffset == NSNotFound); >+ EXPECT_FALSE(secondParagraphOffset == NSNotFound); >+ EXPECT_GT(firstParagraphOffset, secondParagraphOffset); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(190, 100, 130, 20), makeCGRectValue(0, 120, 320, 100), makeCGRectValue(0, 220, 252, 20) ], [simulator finalSelectionRects]); >+} >+ >+TEST(DragAndDropTests, DragImageFromContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView synchronouslyLoadTestPageNamed:@"contenteditable-and-target"]; >+ [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]); >+} >+ >+TEST(DragAndDropTests, TextAreaToInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView loadTestPageNamed:@"textarea-to-input"]; >+ [simulator waitForInputSession]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL); >+ EXPECT_WK_STREQ("Hello world", [webView editorValue].UTF8String); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 990, 232) ], [simulator finalSelectionRects]); >+} >+ >+TEST(DragAndDropTests, SinglePlainTextWordTypeIdentifiers) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView loadTestPageNamed:@"textarea-to-input"]; >+ [simulator waitForInputSession]; >+ [webView stringByEvaluatingJavaScript:@"source.value = 'pneumonoultramicroscopicsilicovolcanoconiosis'"]; >+ [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"]; >+ [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ NSItemProvider *itemProvider = [simulator sourceItemProviders].firstObject; >+ NSArray *registeredTypes = [itemProvider registeredTypeIdentifiers]; >+ EXPECT_EQ(1UL, registeredTypes.count); >+ EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.firstObject UTF8String]); >+ EXPECT_EQ([webView stringByEvaluatingJavaScript:@"source.value"].length, 0UL); >+ EXPECT_EQ(UIPreferredPresentationStyleInline, itemProvider.preferredPresentationStyle); >+ EXPECT_WK_STREQ("pneumonoultramicroscopicsilicovolcanoconiosis", [webView editorValue].UTF8String); >+} >+ >+TEST(DragAndDropTests, SinglePlainTextURLTypeIdentifiers) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView loadTestPageNamed:@"textarea-to-input"]; >+ [simulator waitForInputSession]; >+ [webView stringByEvaluatingJavaScript:@"source.value = 'https://webkit.org/'"]; >+ [webView stringByEvaluatingJavaScript:@"source.selectionStart = 0"]; >+ [webView stringByEvaluatingJavaScript:@"source.selectionEnd = source.value.length"]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ NSItemProvider *itemProvider = [simulator sourceItemProviders].firstObject; >+ NSArray *registeredTypes = [itemProvider registeredTypeIdentifiers]; >+ EXPECT_EQ(2UL, registeredTypes.count); >+ EXPECT_WK_STREQ([(NSString *)kUTTypeURL UTF8String], [registeredTypes.firstObject UTF8String]); >+ EXPECT_WK_STREQ([(NSString *)kUTTypeUTF8PlainText UTF8String], [registeredTypes.lastObject UTF8String]); >+ EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"source.value"].length); >+ EXPECT_EQ(UIPreferredPresentationStyleInline, itemProvider.preferredPresentationStyle); >+ EXPECT_WK_STREQ("https://webkit.org/", [webView editorValue].UTF8String); >+} >+ >+TEST(DragAndDropTests, LinkToInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"link-and-input"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String); >+ >+ __block bool doneLoadingURL = false; >+ UIItemProvider *sourceItemProvider = [simulator sourceItemProviders].firstObject; >+ [sourceItemProvider loadObjectOfClass:[NSURL class] completionHandler:^(id object, NSError *error) { >+ NSURL *url = object; >+ EXPECT_WK_STREQ("Hello world", url._title.UTF8String ?: ""); >+ doneLoadingURL = true; >+ }]; >+ TestWebKitAPI::Util::run(&doneLoadingURL); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"drop"]); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 273, 2057, 232) ], [simulator finalSelectionRects]); >+ checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (NSString *)kUTTypeURL, 0); >+} >+ >+TEST(DragAndDropTests, BackgroundImageLinkToInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"background-image-link-and-input"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("https://www.apple.com/", [webView editorValue].UTF8String); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"drop"]); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(101, 241, 2057, 232) ], [simulator finalSelectionRects]); >+ checkTypeIdentifierIsRegisteredAtIndex(simulator.get(), (NSString *)kUTTypeURL, 0); >+} >+ >+TEST(DragAndDropTests, CanPreventStart) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"prevent-start"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_EQ(DragAndDropPhaseCancelled, [simulator phase]); >+ EXPECT_FALSE([webView editorContainsImageElement]); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_FALSE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_FALSE([observedEventNames containsObject:@"dragover"]); >+ checkSelectionRectsWithLogging(@[ ], [simulator finalSelectionRects]); >+} >+ >+TEST(DragAndDropTests, CanPreventOperation) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"prevent-operation"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_FALSE([webView editorContainsImageElement]); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ checkSelectionRectsWithLogging(@[ ], [simulator finalSelectionRects]); >+} >+ >+TEST(DragAndDropTests, EnterAndLeaveEvents) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"link-and-input"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 450)]; >+ >+ EXPECT_WK_STREQ("", [webView editorValue].UTF8String); >+ >+ NSArray *observedEventNames = [simulator observedEventNames]; >+ EXPECT_TRUE([observedEventNames containsObject:@"dragenter"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragover"]); >+ EXPECT_TRUE([observedEventNames containsObject:@"dragleave"]); >+ EXPECT_FALSE([observedEventNames containsObject:@"drop"]); >+ checkSelectionRectsWithLogging(@[ ], [simulator finalSelectionRects]); >+} >+ >+TEST(DragAndDropTests, CanStartDragOnDivWithDraggableAttribute) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"custom-draggable-div"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 250)]; >+ >+ EXPECT_GT([simulator sourceItemProviders].count, 0UL); >+ NSItemProvider *itemProvider = [simulator sourceItemProviders].firstObject; >+ EXPECT_EQ(UIPreferredPresentationStyleInline, itemProvider.preferredPresentationStyle); >+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!destination.querySelector('#item')"]); >+ EXPECT_WK_STREQ(@"PASS", [webView stringByEvaluatingJavaScript:@"item.textContent"]); >+} >+ >+TEST(DragAndDropTests, ExternalSourcePlainTextToIFrame) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"contenteditable-in-iframe"]; >+ >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [itemProvider registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(160, 250)]; >+ >+ auto containerLeft = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().left"].floatValue; >+ auto containerTop = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().top"].floatValue; >+ auto containerWidth = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().width"].floatValue; >+ auto containerHeight = [webView stringByEvaluatingJavaScript:@"container.getBoundingClientRect().height"].floatValue; >+ checkDragCaretRectIsContainedInRect([simulator lastKnownDragCaretRect], CGRectMake(containerLeft, containerTop, containerWidth, containerHeight)); >+} >+ >+TEST(DragAndDropTests, ExternalSourceInlineTextToFileInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleInline]; >+ [simulatedItemProvider registerObject:@"This item provider requested inline presentation style." visibility:NSItemProviderRepresentationVisibilityAll]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >+ >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"output.value"]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceJSONToFileInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto simulatedJSONItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *jsonData = [@"{ \"foo\": \"bar\", \"bar\": \"baz\" }" dataUsingEncoding:NSUTF8StringEncoding]; >+ [simulatedJSONItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJSON withData:jsonData]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedJSONItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >+ >+ EXPECT_WK_STREQ("application/json", [webView stringByEvaluatingJavaScript:@"output.value"]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceImageToFileInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >+ [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedImageItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("image/jpeg", outputValue.UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceHTMLToUploadArea) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >+ [simulatedHTMLItemProvider setSuggestedName:@"index.html"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setShouldAllowMoveOperation:NO]; >+ [simulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("text/html", outputValue.UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceMoveOperationNotAllowed) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ [webView stringByEvaluatingJavaScript:@"upload.dropEffect = 'move'"]; >+ >+ auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setShouldAllowMoveOperation:NO]; >+ [simulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"output.value"]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceZIPArchiveAndURLToSingleFileInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto archiveProvider = adoptNS([[UIItemProvider alloc] init]); >+ [archiveProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()]; >+ >+ auto urlProvider = adoptNS([[UIItemProvider alloc] init]); >+ [urlProvider registerObject:[NSURL URLWithString:@"https://webkit.org"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ archiveProvider.get(), urlProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("application/zip", outputValue.UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceZIPArchiveToUploadArea) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeZipArchive withData:testZIPArchive()]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("application/zip", outputValue.UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceImageAndHTMLToSingleFileInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >+ [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >+ >+ auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("", outputValue.UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceImageAndHTMLToMultipleFileInput) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ [webView stringByEvaluatingJavaScript:@"input.setAttribute('multiple', '')"]; >+ >+ auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >+ [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >+ >+ auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *htmlData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedHTMLItemProvider.get(), simulatedImageItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 100) to:CGPointMake(100, 100)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("image/jpeg, text/html", outputValue.UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceImageAndHTMLToUploadArea) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >+ [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >+ >+ auto firstSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [firstSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData]; >+ >+ auto secondSimulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *secondHTMLData = [@"<html><body>hello world</body></html>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [secondSimulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:secondHTMLData]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setShouldAllowMoveOperation:NO]; >+ [simulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), firstSimulatedHTMLItemProvider.get(), secondSimulatedHTMLItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("image/jpeg, text/html, text/html", outputValue.UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceHTMLToContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *htmlData = [@"<h1>This is a test</h1>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:htmlData]; >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ NSString *textContent = [webView stringByEvaluatingJavaScript:@"editor.textContent"]; >+ EXPECT_WK_STREQ("This is a test", textContent.UTF8String); >+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!editor.querySelector('h1')"].boolValue); >+} >+ >+TEST(DragAndDropTests, ExternalSourceBoldSystemAttributedStringToContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:20] }; >+ NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"This is a test" attributes:textAttributes]; >+ auto itemProvider = adoptNS([[UIItemProvider alloc] initWithObject:richText]); >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("This is a test", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceColoredAttributedStringToContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ NSDictionary *textAttributes = @{ NSForegroundColorAttributeName: [UIColor redColor] }; >+ NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"This is a test" attributes:textAttributes]; >+ auto itemProvider = adoptNS([[UIItemProvider alloc] initWithObject:richText]); >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("rgb(255, 0, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(document.querySelector('p')).color"]); >+ EXPECT_WK_STREQ("This is a test", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >+} >+ >+TEST(DragAndDropTests, ExternalSourceMultipleURLsToContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ auto firstItem = adoptNS([[UIItemProvider alloc] init]); >+ [firstItem registerObject:[NSURL URLWithString:@"https://www.apple.com/iphone/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ auto secondItem = adoptNS([[UIItemProvider alloc] init]); >+ [secondItem registerObject:[NSURL URLWithString:@"https://www.apple.com/mac/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ auto thirdItem = adoptNS([[UIItemProvider alloc] init]); >+ [thirdItem registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulator setExternalItemProviders:@[ firstItem.get(), secondItem.get(), thirdItem.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ NSArray *droppedURLs = [webView objectByEvaluatingJavaScript:@"Array.from(editor.querySelectorAll('a')).map(a => a.href)"]; >+ EXPECT_EQ(3UL, droppedURLs.count); >+ EXPECT_WK_STREQ("https://www.apple.com/iphone/", droppedURLs[0]); >+ EXPECT_WK_STREQ("https://www.apple.com/mac/", droppedURLs[1]); >+ EXPECT_WK_STREQ("https://webkit.org/", droppedURLs[2]); >+ >+ NSArray *linksSeparatedByLine = [[webView objectByEvaluatingJavaScript:@"editor.innerText"] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; >+ EXPECT_EQ(3UL, linksSeparatedByLine.count); >+ EXPECT_WK_STREQ("https://www.apple.com/iphone/", linksSeparatedByLine[0]); >+ EXPECT_WK_STREQ("https://www.apple.com/mac/", linksSeparatedByLine[1]); >+ EXPECT_WK_STREQ("https://webkit.org/", linksSeparatedByLine[2]); >+} >+ >+TEST(DragAndDropTests, RespectsExternalSourceFidelityRankings) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ // Here, our source item provider vends two representations: plain text, and then an image. If we don't respect the >+ // fidelity order requested by the source, we'll end up assuming that the image is a higher fidelity representation >+ // than the plain text, and erroneously insert the image. If we respect source fidelities, we'll insert text rather >+ // than an image. >+ auto simulatedItemProviderWithTextFirst = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProviderWithTextFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulatedItemProviderWithTextFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulator setExternalItemProviders:@[ simulatedItemProviderWithTextFirst.get() ]]; >+ >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >+ EXPECT_FALSE([webView editorContainsImageElement]); >+ [webView stringByEvaluatingJavaScript:@"editor.innerHTML = ''"]; >+ >+ // Now we register the item providers in reverse, and expect the image to be inserted instead of text. >+ auto simulatedItemProviderWithImageFirst = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProviderWithImageFirst registerObject:testIconImage() visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulatedItemProviderWithImageFirst registerObject:@"Hello world" visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulator setExternalItemProviders:@[ simulatedItemProviderWithImageFirst.get() ]]; >+ >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >+ EXPECT_TRUE([webView editorContainsImageElement]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceUTF8PlainTextOnly) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ >+ NSString *textPayload = @"Ceci n'est pas une string"; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >+ { >+ completionBlock([textPayload dataUsingEncoding:NSUTF8StringEncoding], nil); >+ return [NSProgress discreteProgressWithTotalUnitCount:100]; >+ }]; >+ [simulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ EXPECT_WK_STREQ(textPayload.UTF8String, [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 1936, 227) ], [simulator finalSelectionRects]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceJPEGOnly) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeJPEG options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >+ { >+ completionBlock(UIImageJPEGRepresentation(testIconImage(), 0.5), nil); >+ return [NSProgress discreteProgressWithTotalUnitCount:100]; >+ }]; >+ [simulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ EXPECT_TRUE([webView editorContainsImageElement]); >+ checkSelectionRectsWithLogging(@[ makeCGRectValue(1, 201, 215, 174) ], [simulator finalSelectionRects]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceTitledNSURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ NSURL *titledURL = [NSURL URLWithString:@"https://www.apple.com"]; >+ titledURL._title = @"Apple"; >+ auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProvider registerObject:titledURL visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("Apple", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').textContent"]); >+ EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceFileURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ NSURL *URL = [NSURL URLWithString:@"file:///some/file/that/is/not/real"]; >+ UIItemProvider *simulatedItemProvider = [UIItemProvider itemProviderWithURL:URL title:@""]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedItemProvider ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"!!editor.querySelector('a')"] boolValue]); >+ EXPECT_WK_STREQ("Hello world\nfile:///some/file/that/is/not/real", [webView stringByEvaluatingJavaScript:@"document.body.innerText"]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceOverrideDropFileUpload) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"file-uploading"]; >+ >+ auto simulatedImageItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *imageData = UIImageJPEGRepresentation(testIconImage(), 0.5); >+ [simulatedImageItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG withData:imageData]; >+ >+ auto simulatedHTMLItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSData *firstHTMLData = [@"<body contenteditable></body>" dataUsingEncoding:NSUTF8StringEncoding]; >+ [simulatedHTMLItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:firstHTMLData]; >+ [simulatedHTMLItemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >+ { >+ EXPECT_EQ(2UL, session.items.count); >+ UIDragItem *firstItem = session.items[0]; >+ UIDragItem *secondItem = session.items[1]; >+ EXPECT_TRUE([firstItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeJPEG ]]); >+ EXPECT_TRUE([secondItem.itemProvider.registeredTypeIdentifiers isEqual:@[ (NSString *)kUTTypeHTML ]]); >+ return @[ secondItem ]; >+ }]; >+ [simulator setExternalItemProviders:@[ simulatedImageItemProvider.get(), simulatedHTMLItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(200, 300) to:CGPointMake(100, 300)]; >+ >+ NSString *outputValue = [webView stringByEvaluatingJavaScript:@"output.value"]; >+ EXPECT_WK_STREQ("text/html", outputValue.UTF8String); >+} >+ >+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >+ >+static RetainPtr<TestWKWebView> setUpTestWebViewForDataTransferItems() >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"DataTransferItem-getAsEntry"]; >+ >+ auto preferences = (WKPreferencesRef)[[webView configuration] preferences]; >+ WKPreferencesSetDataTransferItemsEnabled(preferences, true); >+ WKPreferencesSetDirectoryUploadEnabled(preferences, true); >+ >+ return webView; >+} >+ >+TEST(DragAndDropTests, ExternalSourceDataTransferItemGetFolderAsEntry) >+{ >+ // The expected output is sorted by alphabetical order here for consistent behavior across different test environments. >+ // See DataTransferItem-getAsEntry.html for more details. >+ NSArray<NSString *> *expectedOutput = @[ >+ @"Found data transfer item (kind: 'file', type: '')", >+ @"DIR: /somedirectory", >+ @"DIR: /somedirectory/subdirectory1", >+ @"DIR: /somedirectory/subdirectory2", >+ [NSString stringWithFormat:@"FILE: /somedirectory/archive.zip ('application/zip', %tu bytes)", testZIPArchive().length], >+ [NSString stringWithFormat:@"FILE: /somedirectory/icon.png ('image/png', %tu bytes)", testIconImageData().length], >+ @"FILE: /somedirectory/subdirectory1/text-file-1.txt ('text/plain', 43 bytes)", >+ @"FILE: /somedirectory/subdirectory2/text-file-2.txt ('text/plain', 44 bytes)" >+ ]; >+ >+ auto webView = setUpTestWebViewForDataTransferItems(); >+ __block bool done = false; >+ [webView performAfterReceivingMessage:@"dropped" action:^() { >+ done = true; >+ }]; >+ >+ runTestWithTemporaryFolder(^(NSURL *folderURL) { >+ auto itemProvider = adoptNS([[NSItemProvider alloc] init]); >+ [itemProvider setSuggestedName:@"somedirectory"]; >+ [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypeFolder fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[capturedFolderURL = retainPtr(folderURL)] (FileLoadCompletionBlock completionHandler) -> NSProgress * { >+ completionHandler(capturedFolderURL.get(), NO, nil); >+ return nil; >+ }]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >+ }); >+ >+ TestWebKitAPI::Util::run(&done); >+ EXPECT_WK_STREQ([expectedOutput componentsJoinedByString:@"\n"], [webView stringByEvaluatingJavaScript:@"output.value"]); >+} >+ >+TEST(DragAndDropTests, ExternalSourceDataTransferItemGetPlainTextFileAsEntry) >+{ >+ NSArray<NSString *> *expectedOutput = @[ >+ @"Found data transfer item (kind: 'file', type: 'text/plain')", >+ @"FILE: /foo.txt ('text/plain', 28 bytes)" >+ ]; >+ >+ auto webView = setUpTestWebViewForDataTransferItems(); >+ __block bool done = false; >+ [webView performAfterReceivingMessage:@"dropped" action:^() { >+ done = true; >+ }]; >+ >+ runTestWithTemporaryTextFile(^(NSURL *fileURL) { >+ auto itemProvider = adoptNS([[NSItemProvider alloc] init]); >+ [itemProvider setSuggestedName:@"foo"]; >+ [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[capturedFileURL = retainPtr(fileURL)](FileLoadCompletionBlock completionHandler) -> NSProgress * { >+ completionHandler(capturedFileURL.get(), NO, nil); >+ return nil; >+ }]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(150, 50)]; >+ }); >+ >+ TestWebKitAPI::Util::run(&done); >+ EXPECT_WK_STREQ([expectedOutput componentsJoinedByString:@"\n"], [webView stringByEvaluatingJavaScript:@"output.value"]); >+} >+ >+#endif // __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >+ >+TEST(DragAndDropTests, ExternalSourceOverrideDropInsertURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >+ { >+ NSMutableArray<UIDragItem *> *allowedItems = [NSMutableArray array]; >+ for (UIDragItem *item in session.items) { >+ if ([item.itemProvider.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]) >+ [allowedItems addObject:item]; >+ } >+ EXPECT_EQ(1UL, allowedItems.count); >+ return allowedItems; >+ }]; >+ >+ auto firstItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [firstItemProvider registerObject:@"This is a string." visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ auto secondItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [secondItemProvider registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulator setExternalItemProviders:@[ firstItemProvider.get(), secondItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >+} >+ >+TEST(DragAndDropTests, OverrideDrop) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"simple"]; >+ >+ auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:[@"<body></body>" dataUsingEncoding:NSUTF8StringEncoding]]; >+ >+ __block bool finishedLoadingData = false; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >+ [simulator setOverrideDragUpdateBlock:^NSUInteger(NSUInteger operation, id session) >+ { >+ EXPECT_EQ(0U, operation); >+ return UIDropOperationCopy; >+ }]; >+ [simulator setDropCompletionBlock:^(BOOL handled, NSArray *itemProviders) { >+ EXPECT_FALSE(handled); >+ [itemProviders.firstObject loadDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML completionHandler:^(NSData *data, NSError *error) { >+ NSString *text = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; >+ EXPECT_WK_STREQ("<body></body>", text.UTF8String); >+ EXPECT_FALSE(!!error); >+ finishedLoadingData = true; >+ }]; >+ }]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ TestWebKitAPI::Util::run(&finishedLoadingData); >+} >+ >+TEST(DragAndDropTests, InjectedBundleOverridePerformTwoStepDrop) >+{ >+ WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >+ [configuration.processPool _setObject:@YES forBundleParameter:@"BundleOverridePerformTwoStepDrop"]; >+ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >+ [webView loadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >+ { >+ completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil); >+ return [NSProgress discreteProgressWithTotalUnitCount:100]; >+ }]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ EXPECT_EQ(0UL, [webView stringByEvaluatingJavaScript:@"editor.textContent"].length); >+} >+ >+TEST(DragAndDropTests, InjectedBundleAllowPerformTwoStepDrop) >+{ >+ WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >+ [configuration.processPool _setObject:@NO forBundleParameter:@"BundleOverridePerformTwoStepDrop"]; >+ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >+ [webView synchronouslyLoadTestPageNamed:@"autofocus-contenteditable"]; >+ [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"]; >+ >+ auto simulatedItemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [simulatedItemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >+ { >+ completionBlock([@"Hello world" dataUsingEncoding:NSUTF8StringEncoding], nil); >+ return [NSProgress discreteProgressWithTotalUnitCount:100]; >+ }]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setExternalItemProviders:@[ simulatedItemProvider.get() ]]; >+ [simulator runFrom:CGPointMake(300, 400) to:CGPointMake(100, 300)]; >+ >+ EXPECT_WK_STREQ("Hello world", [webView stringByEvaluatingJavaScript:@"editor.textContent"].UTF8String); >+} >+ >+TEST(DragAndDropTests, InjectedBundleImageElementData) >+{ >+ WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >+ [configuration _setAttachmentElementEnabled:YES]; >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >+ [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"]; >+ >+ __block RetainPtr<NSString> injectedString; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data) >+ { >+ injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]); >+ return @[ itemProvider ]; >+ }]; >+ >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 250)]; >+ >+ EXPECT_WK_STREQ("hello", [injectedString UTF8String]); >+} >+ >+TEST(DragAndDropTests, InjectedBundleAttachmentElementData) >+{ >+ WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"BundleEditingDelegatePlugIn"]; >+ [configuration _setAttachmentElementEnabled:YES]; >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]); >+ [webView synchronouslyLoadTestPageNamed:@"attachment-element"]; >+ >+ __block RetainPtr<NSString> injectedString; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *data) >+ { >+ injectedString = adoptNS([[NSString alloc] initWithData:data[InjectedBundlePasteboardDataType] encoding:NSUTF8StringEncoding]); >+ return @[ itemProvider ]; >+ }]; >+ >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400)]; >+ >+ EXPECT_WK_STREQ("hello", [injectedString UTF8String]); >+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"getSelection().isCollapsed"].boolValue); >+} >+ >+TEST(DragAndDropTests, LargeImageToTargetDiv) >+{ >+ auto testWebViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]); >+ [[testWebViewConfiguration preferences] _setLargeImageAsyncDecodingEnabled:NO]; >+ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:testWebViewConfiguration.get()]); >+ [webView synchronouslyLoadTestPageNamed:@"div-and-large-image"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(200, 400) to:CGPointMake(200, 150)]; >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String); >+ checkFirstTypeIsPresentAndSecondTypeIsMissing(simulator.get(), kUTTypePNG, kUTTypeFileURL); >+ checkEstimatedSize(simulator.get(), { 2000, 2000 }); >+} >+ >+TEST(DragAndDropTests, LinkWithEmptyHREF) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"link-and-input"]; >+ [webView stringByEvaluatingJavaScript:@"document.querySelector('a').href = ''"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ >+ EXPECT_EQ(DragAndDropPhaseCancelled, [simulator phase]); >+ EXPECT_WK_STREQ("", [webView editorValue].UTF8String); >+} >+ >+TEST(DragAndDropTests, CancelledLiftDoesNotCauseSubsequentDragsToFail) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *, NSArray *, NSDictionary *) >+ { >+ return @[ ]; >+ }]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ EXPECT_EQ(DragAndDropPhaseCancelled, [simulator phase]); >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"target.textContent"]); >+ NSString *outputText = [webView stringByEvaluatingJavaScript:@"output.textContent"]; >+ checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]); >+ >+ [webView stringByEvaluatingJavaScript:@"output.innerHTML = ''"]; >+ [simulator setConvertItemProvidersBlock:^NSArray *(UIItemProvider *itemProvider, NSArray *, NSDictionary *) >+ { >+ return @[ itemProvider ]; >+ }]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"]); >+ [webView stringByEvaluatingJavaScript:@"output.textContent"]; >+ checkStringArraysAreEqual(@[@"dragstart", @"dragend"], [outputText componentsSeparatedByString:@" "]); >+} >+ >+static void testDragAndDropOntoTargetElements(TestWKWebView *webView) >+{ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView]); >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 250)]; >+ EXPECT_WK_STREQ("rgb(0, 128, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(target1).backgroundColor"]); >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target1.textContent"]); >+ >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(250, 50)]; >+ EXPECT_WK_STREQ("rgb(0, 128, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(target2).backgroundColor"]); >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target2.textContent"]); >+ >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(250, 250)]; >+ EXPECT_WK_STREQ("rgb(0, 128, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(target3).backgroundColor"]); >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target3.textContent"]); >+} >+ >+TEST(DragAndDropTests, DragEventClientCoordinatesBasic) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >+ >+ testDragAndDropOntoTargetElements(webView.get()); >+} >+ >+TEST(DragAndDropTests, DragEventClientCoordinatesWithScrollOffset) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >+ [webView stringByEvaluatingJavaScript:@"document.body.style.margin = '1000px 0'"]; >+ [webView stringByEvaluatingJavaScript:@"document.scrollingElement.scrollTop = 1000"]; >+ [webView waitForNextPresentationUpdate]; >+ >+ testDragAndDropOntoTargetElements(webView.get()); >+} >+ >+TEST(DragAndDropTests, DragEventPageCoordinatesBasic) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >+ [webView stringByEvaluatingJavaScript:@"window.usePageCoordinates = true"]; >+ >+ testDragAndDropOntoTargetElements(webView.get()); >+} >+ >+TEST(DragAndDropTests, DragEventPageCoordinatesWithScrollOffset) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"drop-targets"]; >+ [webView stringByEvaluatingJavaScript:@"document.body.style.margin = '1000px 0'"]; >+ [webView stringByEvaluatingJavaScript:@"document.scrollingElement.scrollTop = 1000"]; >+ [webView stringByEvaluatingJavaScript:@"window.usePageCoordinates = true"]; >+ [webView waitForNextPresentationUpdate]; >+ >+ testDragAndDropOntoTargetElements(webView.get()); >+} >+ >+TEST(DragAndDropTests, DoNotCrashWhenSelectionIsClearedInDragStart) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dragstart-clear-selection"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)]; >+ >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"paragraph.textContent"]); >+} >+ >+// FIXME: Re-enable this test once we resolve <https://bugs.webkit.org/show_bug.cgi?id=175204> >+#if __IPHONE_OS_VERSION_MAX_ALLOWED <= 110401 >+TEST(DragAndDropTests, CustomActionSheetPopover) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"link-and-target-div"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator setShouldEnsureUIApplication:YES]; >+ >+ __block BOOL didInvokeCustomActionSheet = NO; >+ [simulator setShowCustomActionSheetBlock:^BOOL(_WKActivatedElementInfo *element) >+ { >+ EXPECT_EQ(_WKActivatedElementTypeLink, element.type); >+ EXPECT_WK_STREQ("Hello world", element.title.UTF8String); >+ didInvokeCustomActionSheet = YES; >+ return YES; >+ }]; >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; >+ EXPECT_TRUE(didInvokeCustomActionSheet); >+ EXPECT_WK_STREQ("PASS", [webView stringByEvaluatingJavaScript:@"target.textContent"].UTF8String); >+} >+#endif >+ >+TEST(DragAndDropTests, UnresponsivePageDoesNotHangUI) >+{ >+ _WKProcessPoolConfiguration *processPoolConfiguration = [[[_WKProcessPoolConfiguration alloc] init] autorelease]; >+ processPoolConfiguration.ignoreSynchronousMessagingTimeoutsForTesting = YES; >+ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:[[[WKWebViewConfiguration alloc] init] autorelease] processPoolConfiguration:processPoolConfiguration]); >+ [webView synchronouslyLoadTestPageNamed:@"simple"]; >+ [webView evaluateJavaScript:@"while(1);" completionHandler:nil]; >+ >+ // The test passes if we can prepare for a drag session without timing out. >+ auto dragSession = adoptNS([[MockDragSession alloc] init]); >+ [(id <UIDragInteractionDelegate_ForWebKitOnly>)[webView dragInteractionDelegate] _dragInteraction:[webView dragInteraction] prepareForSession:dragSession.get() completion:^() { }]; >+} >+ >+TEST(DragAndDropTests, WebItemProviderPasteboardLoading) >+{ >+ static NSString *fastString = @"This data loads quickly"; >+ static NSString *slowString = @"This data loads slowly"; >+ >+ WebItemProviderPasteboard *pasteboard = [WebItemProviderPasteboard sharedInstance]; >+ auto fastItem = adoptNS([[UIItemProvider alloc] init]); >+ [fastItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >+ { >+ completionBlock([fastString dataUsingEncoding:NSUTF8StringEncoding], nil); >+ return nil; >+ }]; >+ >+ auto slowItem = adoptNS([[UIItemProvider alloc] init]); >+ [slowItem registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock) >+ { >+ sleep(2_s); >+ completionBlock([slowString dataUsingEncoding:NSUTF8StringEncoding], nil); >+ return nil; >+ }]; >+ >+ __block bool hasRunFirstCompletionBlock = false; >+ pasteboard.itemProviders = @[ fastItem.get(), slowItem.get() ]; >+ [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) { >+ EXPECT_EQ(2UL, urls.count); >+ auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]); >+ auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]); >+ EXPECT_WK_STREQ(fastString, [firstString UTF8String]); >+ EXPECT_WK_STREQ(slowString, [secondString UTF8String]); >+ hasRunFirstCompletionBlock = true; >+ } synchronousTimeout:600]; >+ EXPECT_TRUE(hasRunFirstCompletionBlock); >+ >+ __block bool hasRunSecondCompletionBlock = false; >+ [pasteboard doAfterLoadingProvidedContentIntoFileURLs:^(NSArray<NSURL *> *urls) { >+ EXPECT_EQ(2UL, urls.count); >+ auto firstString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[0] encoding:NSUTF8StringEncoding error:nil]); >+ auto secondString = adoptNS([[NSString alloc] initWithContentsOfURL:urls[1] encoding:NSUTF8StringEncoding error:nil]); >+ EXPECT_WK_STREQ(fastString, [firstString UTF8String]); >+ EXPECT_WK_STREQ(slowString, [secondString UTF8String]); >+ hasRunSecondCompletionBlock = true; >+ } synchronousTimeout:0]; >+ EXPECT_FALSE(hasRunSecondCompletionBlock); >+ TestWebKitAPI::Util::run(&hasRunSecondCompletionBlock); >+} >+ >+TEST(DragAndDropTests, DoNotCrashWhenSelectionMovesOffscreenAfterDragStart) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dragstart-change-selection-offscreen"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(100, 100) to:CGPointMake(100, 100)]; >+ >+ EXPECT_WK_STREQ("FAR OFFSCREEN", [webView stringByEvaluatingJavaScript:@"getSelection().getRangeAt(0).toString()"]); >+} >+ >+TEST(DragAndDropTests, AdditionalItemsCanBePreventedOnDragStart) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"selected-text-image-link-and-editable"]; >+ [webView stringByEvaluatingJavaScript:@"link.addEventListener('dragstart', e => e.preventDefault())"]; >+ [webView stringByEvaluatingJavaScript:@"image.addEventListener('dragstart', e => e.preventDefault())"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400) additionalItemRequestLocations:@{ >+ @0.33: [NSValue valueWithCGPoint:CGPointMake(50, 150)], >+ @0.66: [NSValue valueWithCGPoint:CGPointMake(50, 250)] >+ }]; >+ EXPECT_WK_STREQ("ABCD", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >+} >+ >+TEST(DragAndDropTests, AdditionalLinkAndImageIntoContentEditable) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"selected-text-image-link-and-editable"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 400) additionalItemRequestLocations:@{ >+ @0.33: [NSValue valueWithCGPoint:CGPointMake(50, 150)], >+ @0.66: [NSValue valueWithCGPoint:CGPointMake(50, 250)] >+ }]; >+ EXPECT_WK_STREQ("ABCDA link", [webView stringByEvaluatingJavaScript:@"editor.textContent"]); >+ EXPECT_TRUE([webView stringByEvaluatingJavaScript:@"!!editor.querySelector('img')"]); >+ EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]); >+} >+ >+TEST(DragAndDropTests, DragLiftPreviewDataTransferSetDragImage) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"DataTransfer-setDragImage"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ // Use DataTransfer.setDragImage to specify an existing image element in the DOM. >+ [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 50)]; >+ checkCGRectIsEqualToCGRectWithLogging({{100, 50}, {215, 174}}, [simulator liftPreviews][0].view.frame); >+ >+ // Use DataTransfer.setDragImage to specify an existing image element in the DOM, with x and y offsets. >+ [simulator runFrom:CGPointMake(10, 150) to:CGPointMake(250, 150)]; >+ checkCGRectIsEqualToCGRectWithLogging({{-90, 50}, {215, 174}}, [simulator liftPreviews][0].view.frame); >+ >+ // Use DataTransfer.setDragImage to specify a newly created Image, disconnected from the DOM. >+ [simulator runFrom:CGPointMake(100, 250) to:CGPointMake(250, 250)]; >+ checkCGRectIsEqualToCGRectWithLogging({{100, 250}, {215, 174}}, [simulator liftPreviews][0].view.frame); >+ >+ // Don't use DataTransfer.setDragImage and fall back to snapshotting the dragged element. >+ [simulator runFrom:CGPointMake(50, 350) to:CGPointMake(250, 350)]; >+ checkCGRectIsEqualToCGRectWithLogging({{0, 300}, {300, 100}}, [simulator liftPreviews][0].view.frame); >+ >+ // Perform a normal drag on an image. >+ [simulator runFrom:CGPointMake(50, 450) to:CGPointMake(250, 450)]; >+ checkCGRectIsEqualToCGRectWithLogging({{0, 400}, {215, 174}}, [simulator liftPreviews][0].view.frame); >+} >+ >+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >+ >+static NSData *testIconImageData() >+{ >+ return [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png" inDirectory:@"TestWebKitAPI.resources"]]; >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataWhenDroppingImageAndMarkup) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ WKPreferencesSetCustomPasteboardDataEnabled((WKPreferencesRef)[webView configuration].preferences, true); >+ [webView synchronouslyLoadTestPageNamed:@"DataTransfer"]; >+ >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypePNG withData:testIconImageData()]; >+ NSString *markupString = @"<script>bar()</script><strong onmousedown=javascript:void(0)>HELLO WORLD</strong>"; >+ [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML withData:[markupString dataUsingEncoding:NSUTF8StringEncoding]]; >+ [itemProvider setSuggestedName:@"icon"]; >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointZero to:CGPointMake(50, 100)]; >+ >+ EXPECT_WK_STREQ("Files, text/html", [webView stringByEvaluatingJavaScript:@"types.textContent"]); >+ EXPECT_WK_STREQ("(STRING, text/html), (FILE, image/png)", [webView stringByEvaluatingJavaScript:@"items.textContent"]); >+ EXPECT_WK_STREQ("('icon.png', image/png)", [webView stringByEvaluatingJavaScript:@"files.textContent"]); >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]); >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]); >+ EXPECT_WK_STREQ("HELLO WORLD", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]); >+ EXPECT_FALSE([[webView stringByEvaluatingJavaScript:@"rawHTMLData.textContent"] containsString:@"script"]); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataWhenDroppingPlainText) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"select(plain)"]; >+ [simulator runFrom:CGPointMake(50, 75) to:CGPointMake(50, 375)]; >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ @"text/plain" : @"" }, >+ @"drop": @{ @"text/plain" : @"Plain text" } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataWhenDroppingCustomData) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"select(rich)"]; >+ [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >+ [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover" : @{ >+ @"text/plain" : @"", >+ @"foo/plain" : @"", >+ @"text/html" : @"", >+ @"bar/html" : @"", >+ @"text/uri-list" : @"", >+ @"baz/uri-list" : @"" >+ }, >+ @"drop" : @{ >+ @"text/plain" : @"ben bitdiddle", >+ @"foo/plain" : @"eva lu ator", >+ @"text/html" : @"<b>bold text</b>", >+ @"bar/html" : @"<i>italic text</i>", >+ @"text/uri-list" : @"https://www.apple.com", >+ @"baz/uri-list" : @"https://www.webkit.org" >+ } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataWhenDroppingURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"rich.innerHTML = '<a href=\"https://www.apple.com/\">This is a link.</a>'"]; >+ [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ >+ @"text/uri-list" : @"", >+ @"text/plain" : @"" >+ }, >+ @"drop": @{ >+ @"text/uri-list" : @"https://www.apple.com/", >+ @"text/plain" : @"https://www.apple.com/" >+ } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataWhenDroppingImageWithFileURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSURL *iconURL = [[NSBundle mainBundle] URLForResource:@"icon" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]; >+ [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypePNG fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[protectedIconURL = retainPtr(iconURL)] (FileLoadCompletionBlock completionHandler) -> NSProgress * { >+ completionHandler(protectedIconURL.get(), NO, nil); >+ return nil; >+ }]; >+ [itemProvider registerObject:iconURL visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ >+ [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >+ >+ // 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": @{ @"Files": @"", @"text/uri-list": @"" }, >+ @"drop": @{ @"Files": @"", @"text/uri-list": @"" } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataWhenDroppingImageWithHTTPURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeJPEG visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(DataLoadCompletionBlock completionHandler) >+ { >+ completionHandler(UIImageJPEGRepresentation(testIconImage(), 0.5), nil); >+ return nil; >+ }]; >+ [itemProvider registerObject:[NSURL URLWithString:@"http://webkit.org"] visibility:UIItemProviderRepresentationOptionsVisibilityAll]; >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ >+ [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ @"Files": @"", @"text/uri-list": @"" }, >+ @"drop": @{ @"Files": @"", @"text/uri-list": @"http://webkit.org/" } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataWhenDroppingRespectsPresentationStyle) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ runTestWithTemporaryTextFile(^(NSURL *fileURL) { >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [itemProvider registerFileRepresentationForTypeIdentifier:(NSString *)kUTTypeUTF8PlainText fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[protectedFileURL = retainPtr(fileURL)] (FileLoadCompletionBlock completionHandler) -> NSProgress * { >+ completionHandler(protectedFileURL.get(), NO, nil); >+ return nil; >+ }]; >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ >+ [itemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment]; >+ [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ @"Files" : @"" }, >+ @"drop": @{ @"Files" : @"" } >+ }); >+ >+ [itemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleInline]; >+ [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ @"text/plain" : @"" }, >+ @"drop": @{ @"text/plain" : @"This is a tiny blob of text." } >+ }); >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferSetDataCannotWritePlatformTypes) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"select(rich)"]; >+ [webView stringByEvaluatingJavaScript:@"customData = { 'text/plain' : 'foo', 'com.adobe.pdf' : 'try and decode me!' }"]; >+ [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >+ >+ [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >+ checkFirstTypeIsPresentAndSecondTypeIsMissing(simulator.get(), kUTTypeUTF8PlainText, kUTTypePDF); >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ >+ @"text/plain": @"", >+ @"com.adobe.pdf": @"" >+ }, >+ @"drop": @{ >+ @"text/plain": @"foo", >+ @"com.adobe.pdf": @"try and decode me!" >+ } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataReadPlainAndRichText) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"DataTransfer"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ NSDictionary *textAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:20] }; >+ NSAttributedString *richText = [[NSAttributedString alloc] initWithString:@"WebKit" attributes:textAttributes]; >+ [itemProvider registerObject:richText visibility:NSItemProviderRepresentationVisibilityAll]; >+ [itemProvider registerObject:[NSURL URLWithString:@"https://www.webkit.org/"] visibility:NSItemProviderRepresentationVisibilityAll]; >+ [itemProvider registerObject:@"WebKit" visibility:NSItemProviderRepresentationVisibilityAll]; >+ >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointZero to:CGPointMake(50, 100)]; >+ >+ EXPECT_WK_STREQ("text/html, text/plain, text/uri-list", [webView stringByEvaluatingJavaScript:@"types.textContent"]); >+ EXPECT_WK_STREQ("WebKit", [webView stringByEvaluatingJavaScript:@"textData.textContent"]); >+ EXPECT_WK_STREQ("https://www.webkit.org/", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]); >+ EXPECT_WK_STREQ("WebKit", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]); >+ EXPECT_WK_STREQ("(STRING, text/html), (STRING, text/plain), (STRING, text/uri-list)", [webView stringByEvaluatingJavaScript:@"items.textContent"]); >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"files.textContent"]); >+} >+ >+TEST(DragAndDropTests, DataTransferSuppressGetDataDueToPresenceOfTextFile) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"DataTransfer"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [itemProvider registerObject:@"Hello world" visibility:NSItemProviderRepresentationVisibilityAll]; >+ [itemProvider setSuggestedName:@"hello.txt"]; >+ >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [simulator runFrom:CGPointZero to:CGPointMake(50, 100)]; >+ >+ EXPECT_WK_STREQ("Files", [webView stringByEvaluatingJavaScript:@"types.textContent"]); >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"textData.textContent"]); >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"urlData.textContent"]); >+ EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"htmlData.textContent"]); >+ EXPECT_WK_STREQ("(FILE, text/plain)", [webView stringByEvaluatingJavaScript:@"items.textContent"]); >+ EXPECT_WK_STREQ("('hello.txt', text/plain)", [webView stringByEvaluatingJavaScript:@"files.textContent"]); >+} >+ >+TEST(DragAndDropTests, DataTransferGetDataCannotReadPrivateArbitraryTypes) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ auto itemProvider = adoptNS([[UIItemProvider alloc] init]); >+ [itemProvider registerDataRepresentationForTypeIdentifier:(NSString *)kUTTypeMP3 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(DataLoadCompletionBlock completionHandler) >+ { >+ completionHandler([@"this is a test" dataUsingEncoding:NSUTF8StringEncoding], nil); >+ return nil; >+ }]; >+ [itemProvider registerDataRepresentationForTypeIdentifier:@"org.WebKit.TestWebKitAPI.custom-pasteboard-type" visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(DataLoadCompletionBlock completionHandler) >+ { >+ completionHandler([@"this is another test" dataUsingEncoding:NSUTF8StringEncoding], nil); >+ return nil; >+ }]; >+ [simulator setExternalItemProviders:@[ itemProvider.get() ]]; >+ [itemProvider setPreferredPresentationStyle:UIPreferredPresentationStyleInline]; >+ [simulator runFrom:CGPointMake(300, 375) to:CGPointMake(50, 375)]; >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ }, >+ @"drop": @{ } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferSetDataValidURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"select(rich)"]; >+ [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'https://webkit.org/b/123' }"]; >+ [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >+ >+ __block bool done = false; >+ [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >+ { >+ EXPECT_EQ(1UL, session.items.count); >+ auto *item = session.items[0].itemProvider; >+ EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]); >+ EXPECT_TRUE([item canLoadObjectOfClass: [NSURL class]]); >+ [item loadObjectOfClass:[NSURL class] completionHandler:^(id<NSItemProviderReading> url, NSError *error) { >+ EXPECT_TRUE([url isKindOfClass: [NSURL class]]); >+ EXPECT_WK_STREQ([(NSURL *)url absoluteString], @"https://webkit.org/b/123"); >+ done = true; >+ }]; >+ return session.items; >+ }]; >+ [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >+ >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ >+ @"text/uri-list": @"", >+ }, >+ @"drop": @{ >+ @"text/uri-list": @"https://webkit.org/b/123", >+ } >+ }); >+ TestWebKitAPI::Util::run(&done); >+} >+ >+TEST(DragAndDropTests, DataTransferSetDataUnescapedURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"select(rich)"]; >+ [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'http://webkit.org/b/\u4F60\u597D;?x=8 + 6' }"]; >+ [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >+ >+ __block bool done = false; >+ [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >+ { >+ EXPECT_EQ(1UL, session.items.count); >+ auto *item = session.items[0].itemProvider; >+ EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeURL]); >+ EXPECT_TRUE([item canLoadObjectOfClass: [NSURL class]]); >+ [item loadObjectOfClass:[NSURL class] completionHandler:^(id<NSItemProviderReading> url, NSError *error) { >+ EXPECT_TRUE([url isKindOfClass: [NSURL class]]); >+ EXPECT_WK_STREQ([(NSURL *)url absoluteString], @"http://webkit.org/b/%E4%BD%A0%E5%A5%BD;?x=8%20+%206"); >+ done = true; >+ }]; >+ return session.items; >+ }]; >+ [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >+ >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ >+ @"text/uri-list": @"", >+ }, >+ @"drop": @{ >+ @"text/uri-list": @"http://webkit.org/b/\u4F60\u597D;?x=8 + 6", >+ } >+ }); >+ TestWebKitAPI::Util::run(&done); >+} >+ >+TEST(DragAndDropTests, DataTransferSetDataInvalidURL) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"select(rich)"]; >+ [webView stringByEvaluatingJavaScript:@"customData = { 'url' : 'some random string' }"]; >+ [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >+ >+ [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >+ NSArray *registeredTypes = [simulator.get().sourceItemProviders.firstObject registeredTypeIdentifiers]; >+ EXPECT_FALSE([registeredTypes containsObject:(NSString *)kUTTypeURL]); >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ >+ @"text/uri-list": @"", >+ }, >+ @"drop": @{ >+ @"text/uri-list": @"some random string", >+ } >+ }); >+} >+ >+TEST(DragAndDropTests, DataTransferSanitizeHTML) >+{ >+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); >+ [webView synchronouslyLoadTestPageNamed:@"dump-datatransfer-types"]; >+ auto simulator = adoptNS([[DraggingSimulator alloc] initWithWebView:webView.get()]); >+ >+ [webView stringByEvaluatingJavaScript:@"select(rich)"]; >+ [webView stringByEvaluatingJavaScript:@"customData = { 'text/html' : '<meta content=\"secret\">" >+ "<b onmouseover=\"dangerousCode()\">hello</b><!-- secret-->, world<script>dangerousCode()</script>' }"]; >+ [webView stringByEvaluatingJavaScript:@"writeCustomData = true"]; >+ >+ __block bool done = false; >+ [simulator.get() setOverridePerformDropBlock:^NSArray<UIDragItem *> *(id <UIDropSession> session) >+ { >+ EXPECT_EQ(1UL, session.items.count); >+ auto *item = session.items[0].itemProvider; >+ EXPECT_TRUE([item.registeredTypeIdentifiers containsObject:(NSString *)kUTTypeHTML]); >+ [item loadDataRepresentationForTypeIdentifier:(NSString *)kUTTypeHTML completionHandler:^(NSData *data, NSError *error) { >+ NSString *markup = [[[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding] autorelease]; >+ EXPECT_TRUE([markup containsString:@"hello"]); >+ EXPECT_TRUE([markup containsString:@", world"]); >+ EXPECT_FALSE([markup containsString:@"secret"]); >+ EXPECT_FALSE([markup containsString:@"dangerousCode"]); >+ done = true; >+ }]; >+ return session.items; >+ }]; >+ [simulator runFrom:CGPointMake(50, 225) to:CGPointMake(50, 375)]; >+ >+ checkJSONWithLogging([webView stringByEvaluatingJavaScript:@"output.value"], @{ >+ @"dragover": @{ >+ @"text/html": @"", >+ }, >+ @"drop": @{ >+ @"text/html": @"<meta content=\"secret\"><b onmouseover=\"dangerousCode()\">hello</b><!-- secret-->, world<script>dangerousCode()</script>", >+ } >+ }); >+ TestWebKitAPI::Util::run(&done); >+} >+ >+#endif // __IPHONE_OS_VERSION_MIN_REQUIRED >= 110300 >+ >+} // namespace TestWebKitAPI >+ >+#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(IOS) >diff --git a/Tools/TestWebKitAPI/cocoa/DraggingSimulator.h b/Tools/TestWebKitAPI/cocoa/DraggingSimulator.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0cf55c506e8cea3e673e5dc9c5864872c18b28db >--- /dev/null >+++ b/Tools/TestWebKitAPI/cocoa/DraggingSimulator.h >@@ -0,0 +1,111 @@ >+/* >+ * 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. >+ */ >+ >+#pragma once >+ >+#if ENABLE(DRAG_SUPPORT) >+ >+#import "TestWKWebView.h" >+#import <WebKit/WKUIDelegatePrivate.h> >+#import <WebKit/_WKInputDelegate.h> >+#import <wtf/BlockPtr.h> >+ >+#if PLATFORM(IOS) >+#import "UIKitSPI.h" >+#import <UIKit/NSItemProvider+UIKitAdditions.h> >+#endif >+ >+typedef NS_ENUM(NSInteger, DragAndDropPhase) { >+ DragAndDropPhaseCancelled = 0, >+ DragAndDropPhaseBeginning = 1, >+ DragAndDropPhaseBegan = 2, >+ DragAndDropPhaseEntered = 3, >+ DragAndDropPhasePerformingDrop = 4 >+}; >+ >+#if PLATFORM(IOS) >+ >+typedef NSDictionary<NSNumber *, NSValue *> *ProgressToCGPointValueMap; >+ >+@interface MockDragDropSession : NSObject <UIDragDropSession> { >+@private >+ RetainPtr<NSArray> _mockItems; >+ RetainPtr<UIWindow> _window; >+} >+@property (nonatomic) CGPoint mockLocationInWindow; >+@property (nonatomic) BOOL allowMove; >+@end >+ >+@interface MockDropSession : MockDragDropSession <UIDropSession> >+@end >+ >+@interface MockDragSession : MockDragDropSession <UIDragSession> >+@end >+ >+@interface WKWebView (DragAndDropTesting) >+- (id <UIDropInteractionDelegate>)dropInteractionDelegate; >+- (id <UIDragInteractionDelegate>)dragInteractionDelegate; >+- (UIDropInteraction *)dropInteraction; >+- (UIDragInteraction *)dragInteraction; >+@end >+ >+#endif // PLATFORM(IOS) >+ >+@interface DraggingSimulator : NSObject<WKUIDelegatePrivate, _WKInputDelegate> >+ >+- (instancetype)initWithWebView:(TestWKWebView *)webView; >+// The start location, end location, and locations of additional item requests are all in window coordinates. >+- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation; >+@property (nonatomic, readonly) NSArray<_WKAttachment *> *insertedAttachments; >+@property (nonatomic, readonly) NSArray<_WKAttachment *> *removedAttachments; >+@property (nonatomic, readonly) DragAndDropPhase phase; >+ >+#if PLATFORM(IOS) >+ >+- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation additionalItemRequestLocations:(ProgressToCGPointValueMap)additionalItemRequestLocations; >+- (void)waitForInputSession; >+- (void)endDataTransfer; >+ >+@property (nonatomic) BOOL allowsFocusToStartInputSession; >+@property (nonatomic) BOOL shouldEnsureUIApplication; >+@property (nonatomic) BOOL shouldAllowMoveOperation; >+@property (nonatomic) BlockPtr<BOOL(_WKActivatedElementInfo *)> showCustomActionSheetBlock; >+@property (nonatomic) BlockPtr<NSArray *(UIItemProvider *, NSArray *, NSDictionary *)> convertItemProvidersBlock; >+@property (nonatomic) BlockPtr<NSArray *(id <UIDropSession>)> overridePerformDropBlock; >+@property (nonatomic, strong) NSArray *externalItemProviders; >+@property (nonatomic) BlockPtr<NSUInteger(NSUInteger, id)> overrideDragUpdateBlock; >+@property (nonatomic) BlockPtr<void(BOOL, NSArray *)> dropCompletionBlock; >+ >+@property (nonatomic, readonly) NSArray *sourceItemProviders; >+@property (nonatomic, readonly) NSArray *observedEventNames; >+@property (nonatomic, readonly) NSArray *finalSelectionRects; >+@property (nonatomic, readonly) CGRect lastKnownDragCaretRect; >+@property (nonatomic, readonly) NSArray<UITargetedDragPreview *> *liftPreviews; >+ >+#endif // PLATFORM(IOS) >+ >+@end >+ >+#endif // ENABLE(DRAG_SUPPORT) >diff --git a/Tools/TestWebKitAPI/ios/DataInteractionSimulator.h b/Tools/TestWebKitAPI/ios/DataInteractionSimulator.h >deleted file mode 100644 >index 3d372058c496766a62c090ba8773f4c51882a003..0000000000000000000000000000000000000000 >--- a/Tools/TestWebKitAPI/ios/DataInteractionSimulator.h >+++ /dev/null >@@ -1,178 +0,0 @@ >-/* >- * 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. >- */ >- >-#pragma once >- >-#if ENABLE(DATA_INTERACTION) >- >-#import "TestWKWebView.h" >-#import <UIKit/NSItemProvider+UIKitAdditions.h> >- >-#if USE(APPLE_INTERNAL_SDK) >-#import <UIKit/NSString+UIItemProvider.h> >-#import <UIKit/NSURL+UIItemProvider.h> >-#import <UIKit/UIImage+UIItemProvider.h> >-#import <UIKit/UIItemProvider.h> >-#import <UIKit/UIItemProvider_Private.h> >-#else >- >-@interface NSURL () >-@property (nonatomic, copy, setter=_setTitle:) NSString *_title; >-@end >- >-#define UIItemProviderRepresentationOptionsVisibilityAll NSItemProviderRepresentationVisibilityAll >- >-@protocol UIItemProviderReading <NSItemProviderReading> >- >-@required >-- (instancetype)initWithItemProviderData:(NSData *)data typeIdentifier:(NSString *)typeIdentifier error:(NSError **)outError; >- >-@end >- >-@protocol UIItemProviderWriting <NSItemProviderWriting> >- >-@required >-- (NSProgress *)loadDataWithTypeIdentifier:(NSString *)typeIdentifier forItemProviderCompletionHandler:(void (^)(NSData *, NSError *))completionHandler; >- >-@end >- >-@interface NSAttributedString () <UIItemProviderReading, UIItemProviderWriting> >-@end >-@interface NSString () <UIItemProviderReading, UIItemProviderWriting> >-@end >-@interface NSURL () <UIItemProviderReading, UIItemProviderWriting> >-@end >-@interface UIImage () <UIItemProviderReading, UIItemProviderWriting> >-@end >- >-@interface UIItemProvider : NSItemProvider >-@end >- >-#endif >- >-#import <UIKit/UIKit.h> >-#import <WebKit/WKUIDelegatePrivate.h> >-#import <WebKit/_WKInputDelegate.h> >-#import <wtf/BlockPtr.h> >- >-@class MockDropSession; >-@class MockDragSession; >- >-@interface MockDragDropSession : NSObject <UIDragDropSession> { >-@private >- RetainPtr<NSArray> _mockItems; >- RetainPtr<UIWindow> _window; >-} >-@property (nonatomic) CGPoint mockLocationInWindow; >-@property (nonatomic) BOOL allowMove; >-@end >- >-@interface MockDropSession : MockDragDropSession <UIDropSession> >-@end >- >-@interface MockDragSession : MockDragDropSession <UIDragSession> >-@end >- >-extern NSString * const DataInteractionEnterEventName; >-extern NSString * const DataInteractionOverEventName; >-extern NSString * const DataInteractionPerformOperationEventName; >-extern NSString * const DataInteractionLeaveEventName; >-extern NSString * const DataInteractionStartEventName; >- >-typedef NSDictionary<NSNumber *, NSValue *> *ProgressToCGPointValueMap; >- >-typedef NS_ENUM(NSInteger, DataInteractionPhase) { >- DataInteractionCancelled = 0, >- DataInteractionBeginning = 1, >- DataInteractionBegan = 2, >- DataInteractionEntered = 3, >- DataInteractionPerforming = 4 >-}; >- >-@interface WKWebView (DragAndDropTesting) >-- (id <UIDropInteractionDelegate>)dropInteractionDelegate; >-- (id <UIDragInteractionDelegate>)dragInteractionDelegate; >-- (UIDropInteraction *)dropInteraction; >-- (UIDragInteraction *)dragInteraction; >-@end >- >-@interface DataInteractionSimulator : NSObject<WKUIDelegatePrivate, _WKInputDelegate> { >-@private >- RetainPtr<TestWKWebView> _webView; >- RetainPtr<MockDragSession> _dragSession; >- RetainPtr<MockDropSession> _dropSession; >- RetainPtr<NSMutableArray> _observedEventNames; >- RetainPtr<NSArray> _externalItemProviders; >- RetainPtr<NSArray *> _sourceItemProviders; >- RetainPtr<NSArray *> _finalSelectionRects; >- CGPoint _startLocation; >- CGPoint _endLocation; >- CGRect _lastKnownDragCaretRect; >- >- RetainPtr<NSMutableDictionary<NSNumber *, NSValue *>>_remainingAdditionalItemRequestLocationsByProgress; >- RetainPtr<NSMutableArray<NSValue *>>_queuedAdditionalItemRequestLocations; >- RetainPtr<NSMutableArray<UITargetedDragPreview *>> _liftPreviews; >- >- RetainPtr<NSMutableArray<_WKAttachment *>> _insertedAttachments; >- RetainPtr<NSMutableArray<_WKAttachment *>> _removedAttachments; >- >- bool _isDoneWaitingForInputSession; >- double _currentProgress; >- bool _isDoneWithCurrentRun; >- DataInteractionPhase _phase; >- >- RetainPtr<UIDropProposal> _currentDropProposal; >-} >- >-- (instancetype)initWithWebView:(TestWKWebView *)webView; >-// The start location, end location, and locations of additional item requests are all in window coordinates. >-- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation; >-- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation additionalItemRequestLocations:(ProgressToCGPointValueMap)additionalItemRequestLocations; >-- (void)waitForInputSession; >-- (void)endDataTransfer; >- >-@property (nonatomic) BOOL allowsFocusToStartInputSession; >-@property (nonatomic) BOOL shouldEnsureUIApplication; >-@property (nonatomic) BOOL shouldAllowMoveOperation; >-@property (nonatomic) BlockPtr<BOOL(_WKActivatedElementInfo *)> showCustomActionSheetBlock; >-@property (nonatomic) BlockPtr<NSArray *(UIItemProvider *, NSArray *, NSDictionary *)> convertItemProvidersBlock; >-@property (nonatomic) BlockPtr<NSArray *(id <UIDropSession>)> overridePerformDropBlock; >-@property (nonatomic, strong) NSArray *externalItemProviders; >-@property (nonatomic) BlockPtr<NSUInteger(NSUInteger, id)> overrideDataInteractionOperationBlock; >-@property (nonatomic) BlockPtr<void(BOOL, NSArray *)> dataInteractionOperationCompletionBlock; >- >-@property (nonatomic, readonly) NSArray *sourceItemProviders; >-@property (nonatomic, readonly) NSArray *observedEventNames; >-@property (nonatomic, readonly) NSArray *finalSelectionRects; >-@property (nonatomic, readonly) DataInteractionPhase phase; >-@property (nonatomic, readonly) CGRect lastKnownDragCaretRect; >-@property (nonatomic, readonly) NSArray<UITargetedDragPreview *> *liftPreviews; >- >-@property (nonatomic, readonly) NSArray<_WKAttachment *> *insertedAttachments; >-@property (nonatomic, readonly) NSArray<_WKAttachment *> *removedAttachments; >- >-@end >- >-#endif // ENABLE(DATA_INTERACTION) >diff --git a/Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm b/Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm >deleted file mode 100644 >index 856b0b1ff3bff0b4b98f7d7d1a87cb87b2c30844..0000000000000000000000000000000000000000 >--- a/Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm >+++ /dev/null >@@ -1,675 +0,0 @@ >-/* >- * 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 "DataInteractionSimulator.h" >- >-#if ENABLE(DATA_INTERACTION) >- >-#import "InstanceMethodSwizzler.h" >-#import "PlatformUtilities.h" >-#import "UIKitSPI.h" >- >-#import <UIKit/UIDragInteraction.h> >-#import <UIKit/UIDragItem.h> >-#import <UIKit/UIInteraction.h> >-#import <WebKit/WKWebViewPrivate.h> >-#import <WebKit/_WKFocusedElementInfo.h> >-#import <WebKit/_WKFormInputSession.h> >-#import <wtf/RetainPtr.h> >-#import <wtf/SoftLinking.h> >- >-SOFT_LINK_FRAMEWORK(UIKit) >-SOFT_LINK(UIKit, UIApplicationInstantiateSingleton, void, (Class singletonClass), (singletonClass)) >- >-using namespace TestWebKitAPI; >- >-@implementation WKWebView (DragAndDropTesting) >- >-- (UIView *)_dragDropInteractionView >-{ >- return [self valueForKey:@"_currentContentView"]; >-} >- >-- (id <UIDropInteractionDelegate>)dropInteractionDelegate >-{ >- return (id <UIDropInteractionDelegate>)self._dragDropInteractionView; >-} >- >-- (id <UIDragInteractionDelegate>)dragInteractionDelegate >-{ >- return (id <UIDragInteractionDelegate>)self._dragDropInteractionView; >-} >- >-- (UIDropInteraction *)dropInteraction >-{ >- UIView *interactionView = self._dragDropInteractionView; >- for (id <UIInteraction> interaction in interactionView.interactions) { >- if ([interaction isKindOfClass:[UIDropInteraction class]]) >- return (UIDropInteraction *)interaction; >- } >- return nil; >-} >- >-- (UIDragInteraction *)dragInteraction >-{ >- UIView *interactionView = self._dragDropInteractionView; >- for (id <UIInteraction> interaction in interactionView.interactions) { >- if ([interaction isKindOfClass:[UIDragInteraction class]]) >- return (UIDragInteraction *)interaction; >- } >- return nil; >-} >- >-@end >- >-@implementation MockDragDropSession >- >-- (instancetype)initWithItems:(NSArray <UIDragItem *>*)items location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove >-{ >- if (self = [super init]) { >- _mockItems = items; >- _mockLocationInWindow = locationInWindow; >- _window = window; >- _allowMove = allowMove; >- } >- return self; >-} >- >-- (BOOL)allowsMoveOperation >-{ >- return _allowMove; >-} >- >-- (BOOL)isRestrictedToDraggingApplication >-{ >- return NO; >-} >- >-- (BOOL)hasItemsConformingToTypeIdentifiers:(NSArray<NSString *> *)typeIdentifiers >-{ >- for (NSString *typeIdentifier in typeIdentifiers) { >- BOOL hasItemConformingToType = NO; >- for (UIDragItem *item in self.items) >- hasItemConformingToType |= [[item.itemProvider registeredTypeIdentifiers] containsObject:typeIdentifier]; >- if (!hasItemConformingToType) >- return NO; >- } >- return YES; >-} >- >-- (BOOL)canLoadObjectsOfClass:(Class<UIItemProviderReading>)aClass >-{ >- for (UIDragItem *item in self.items) { >- if ([item.itemProvider canLoadObjectOfClass:aClass]) >- return YES; >- } >- return NO; >-} >- >-- (BOOL)canLoadObjectsOfClasses:(NSArray<Class<UIItemProviderReading>> *)classes >-{ >- for (Class<UIItemProviderReading> aClass in classes) { >- BOOL canLoad = NO; >- for (UIDragItem *item in self.items) >- canLoad |= [item.itemProvider canLoadObjectOfClass:aClass]; >- if (!canLoad) >- return NO; >- } >- return YES; >-} >- >-- (NSArray<UIDragItem *> *)items >-{ >- return _mockItems.get(); >-} >- >-- (void)setItems:(NSArray<UIDragItem *> *)items >-{ >- _mockItems = items; >-} >- >-- (void)addItems:(NSArray<UIDragItem *> *)items >-{ >- if (![items count]) >- return; >- >- if (![_mockItems count]) >- _mockItems = items; >- else >- _mockItems = [_mockItems arrayByAddingObjectsFromArray:items]; >-} >- >-- (CGPoint)locationInView:(UIView *)view >-{ >- return [_window convertPoint:_mockLocationInWindow toView:view]; >-} >- >-@end >- >-NSString * const DataInteractionEnterEventName = @"dragenter"; >-NSString * const DataInteractionOverEventName = @"dragover"; >-NSString * const DataInteractionPerformOperationEventName = @"drop"; >-NSString * const DataInteractionLeaveEventName = @"dragleave"; >-NSString * const DataInteractionStartEventName = @"dragstart"; >- >-@implementation MockDropSession >- >-- (instancetype)initWithProviders:(NSArray<UIItemProvider *> *)providers location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove >-{ >- auto items = adoptNS([[NSMutableArray alloc] init]); >- for (UIItemProvider *itemProvider in providers) >- [items addObject:[[[UIDragItem alloc] initWithItemProvider:itemProvider] autorelease]]; >- >- return [super initWithItems:items.get() location:locationInWindow window:window allowMove:allowMove]; >-} >- >-- (BOOL)isLocal >-{ >- return YES; >-} >- >-- (NSProgress *)progress >-{ >- return [NSProgress discreteProgressWithTotalUnitCount:100]; >-} >- >-- (void)setProgressIndicatorStyle:(UIDropSessionProgressIndicatorStyle)progressIndicatorStyle >-{ >-} >- >-- (UIDropSessionProgressIndicatorStyle)progressIndicatorStyle >-{ >- return UIDropSessionProgressIndicatorStyleNone; >-} >- >-- (NSUInteger)operationMask >-{ >- return 0; >-} >- >-- (id <UIDragSession>)localDragSession >-{ >- return nil; >-} >- >-- (BOOL)hasItemsConformingToTypeIdentifier:(NSString *)typeIdentifier >-{ >- ASSERT_NOT_REACHED(); >- return NO; >-} >- >-- (BOOL)canCreateItemsOfClass:(Class<UIItemProviderReading>)aClass >-{ >- ASSERT_NOT_REACHED(); >- return NO; >-} >- >-- (NSProgress *)loadObjectsOfClass:(Class<NSItemProviderReading>)aClass completion:(void(^)(NSArray<__kindof id <NSItemProviderReading>> *objects))completion >-{ >- ASSERT_NOT_REACHED(); >- return nil; >-} >- >-@end >- >-@implementation MockDragSession { >- RetainPtr<id> _localContext; >-} >- >-- (instancetype)initWithWindow:(UIWindow *)window allowMove:(BOOL)allowMove >-{ >- return [super initWithItems:@[ ] location:CGPointZero window:window allowMove:allowMove]; >-} >- >-- (NSUInteger)localOperationMask >-{ >- ASSERT_NOT_REACHED(); >- return 0; >-} >- >-- (NSUInteger)externalOperationMask >-{ >- ASSERT_NOT_REACHED(); >- return 0; >-} >- >-- (id)session >-{ >- return nil; >-} >- >-- (id)localContext >-{ >- return _localContext.get(); >-} >- >-- (void)setLocalContext:(id)localContext >-{ >- _localContext = localContext; >-} >- >-@end >- >-static double progressIncrementStep = 0.033; >-static double progressTimeStep = 0.016; >-static NSString *TestWebKitAPISimulateCancelAllTouchesNotificationName = @"TestWebKitAPISimulateCancelAllTouchesNotificationName"; >- >-static NSArray *dataInteractionEventNames() >-{ >- static NSArray *eventNames = nil; >- static dispatch_once_t onceToken; >- dispatch_once(&onceToken, ^() { >- eventNames = @[ DataInteractionEnterEventName, DataInteractionOverEventName, DataInteractionPerformOperationEventName, DataInteractionLeaveEventName, DataInteractionStartEventName ]; >- }); >- return eventNames; >-} >- >-@interface DataInteractionSimulatorApplication : UIApplication >-@end >- >-@implementation DataInteractionSimulatorApplication >-- (void)_cancelAllTouches >-{ >- [[NSNotificationCenter defaultCenter] postNotificationName:TestWebKitAPISimulateCancelAllTouchesNotificationName object:nil]; >-} >-@end >- >-@implementation DataInteractionSimulator >- >-- (instancetype)initWithWebView:(TestWKWebView *)webView >-{ >- if (self = [super init]) { >- _webView = webView; >- _shouldEnsureUIApplication = NO; >- _shouldAllowMoveOperation = YES; >- _isDoneWaitingForInputSession = true; >- [_webView setUIDelegate:self]; >- [_webView _setInputDelegate:self]; >- } >- return self; >-} >- >-- (void)dealloc >-{ >- if ([_webView UIDelegate] == self) >- [_webView setUIDelegate:nil]; >- >- if ([_webView _inputDelegate] == self) >- [_webView _setInputDelegate:nil]; >- >- [super dealloc]; >-} >- >-- (void)_resetSimulatedState >-{ >- _phase = DataInteractionBeginning; >- _currentProgress = 0; >- _isDoneWithCurrentRun = false; >- _observedEventNames = adoptNS([[NSMutableArray alloc] init]); >- _insertedAttachments = adoptNS([[NSMutableArray alloc] init]); >- _removedAttachments = adoptNS([[NSMutableArray alloc] init]); >- _finalSelectionRects = @[ ]; >- _dragSession = nil; >- _dropSession = nil; >- _currentDropProposal = nil; >- _lastKnownDragCaretRect = CGRectZero; >- _remainingAdditionalItemRequestLocationsByProgress = nil; >- _queuedAdditionalItemRequestLocations = adoptNS([[NSMutableArray alloc] init]); >- _liftPreviews = adoptNS([[NSMutableArray alloc] init]); >-} >- >-- (NSArray *)observedEventNames >-{ >- return _observedEventNames.get(); >-} >- >-- (void)simulateAllTouchesCanceled:(NSNotification *)notification >-{ >- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_advanceProgress) object:nil]; >- _phase = DataInteractionCancelled; >- _currentProgress = 1; >- _isDoneWithCurrentRun = true; >- if (_dragSession) >- [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:UIDropOperationCancel]; >-} >- >-- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation >-{ >- [self runFrom:startLocation to:endLocation additionalItemRequestLocations:nil]; >-} >- >-- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation additionalItemRequestLocations:(ProgressToCGPointValueMap)additionalItemRequestLocations >-{ >- NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; >- [defaultCenter addObserver:self selector:@selector(simulateAllTouchesCanceled:) name:TestWebKitAPISimulateCancelAllTouchesNotificationName object:nil]; >- >- if (_shouldEnsureUIApplication) >- UIApplicationInstantiateSingleton([DataInteractionSimulatorApplication class]); >- >- [self _resetSimulatedState]; >- >- if (additionalItemRequestLocations) >- _remainingAdditionalItemRequestLocationsByProgress = adoptNS([additionalItemRequestLocations mutableCopy]); >- >- RetainPtr<DataInteractionSimulator> strongSelf = self; >- for (NSString *eventName in dataInteractionEventNames()) { >- DataInteractionSimulator *weakSelf = strongSelf.get(); >- [weakSelf->_webView performAfterReceivingMessage:eventName action:^() { >- [weakSelf->_observedEventNames addObject:eventName]; >- }]; >- } >- >- _startLocation = startLocation; >- _endLocation = endLocation; >- >- if (self.externalItemProviders.count) { >- _dropSession = adoptNS([[MockDropSession alloc] initWithProviders:self.externalItemProviders location:_startLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]); >- _phase = DataInteractionBegan; >- [self _advanceProgress]; >- } else { >- _dragSession = adoptNS([[MockDragSession alloc] initWithWindow:[_webView window] allowMove:self.shouldAllowMoveOperation]); >- [_dragSession setMockLocationInWindow:_startLocation]; >- [(id <UIDragInteractionDelegate_ForWebKitOnly>)[_webView dragInteractionDelegate] _dragInteraction:[_webView dragInteraction] prepareForSession:_dragSession.get() completion:^() { >- DataInteractionSimulator *weakSelf = strongSelf.get(); >- if (weakSelf->_phase == DataInteractionCancelled) >- return; >- >- weakSelf->_phase = DataInteractionBeginning; >- [weakSelf _advanceProgress]; >- }]; >- } >- >- Util::run(&_isDoneWithCurrentRun); >- [_webView clearMessageHandlers:dataInteractionEventNames()]; >- _finalSelectionRects = [_webView selectionRectsAfterPresentationUpdate]; >- >- [defaultCenter removeObserver:self]; >-} >- >-- (NSArray *)finalSelectionRects >-{ >- return _finalSelectionRects.get(); >-} >- >-- (void)_concludeDataInteractionAndPerformOperationIfNecessary >-{ >- _lastKnownDragCaretRect = [_webView _dragCaretRect]; >- auto operation = [_currentDropProposal operation]; >- if (operation != UIDropOperationCancel && operation != UIDropOperationForbidden) { >- [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] performDrop:_dropSession.get()]; >- _phase = DataInteractionPerforming; >- } else { >- _isDoneWithCurrentRun = YES; >- _phase = DataInteractionCancelled; >- } >- >- [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnd:_dropSession.get()]; >- >- if (_dragSession) >- [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:operation]; >-} >- >-- (void)_enqueuePendingAdditionalItemRequestLocations >-{ >- NSMutableArray *progressValuesToRemove = [NSMutableArray array]; >- for (NSNumber *progressValue in _remainingAdditionalItemRequestLocationsByProgress.get()) { >- double progress = progressValue.doubleValue; >- if (progress > _currentProgress) >- continue; >- [progressValuesToRemove addObject:progressValue]; >- [_queuedAdditionalItemRequestLocations addObject:[_remainingAdditionalItemRequestLocationsByProgress objectForKey:progressValue]]; >- } >- >- for (NSNumber *progressToRemove in progressValuesToRemove) >- [_remainingAdditionalItemRequestLocationsByProgress removeObjectForKey:progressToRemove]; >-} >- >-- (BOOL)_sendQueuedAdditionalItemRequest >-{ >- if (![_queuedAdditionalItemRequestLocations count]) >- return NO; >- >- RetainPtr<NSValue> requestLocationValue = [_queuedAdditionalItemRequestLocations objectAtIndex:0]; >- [_queuedAdditionalItemRequestLocations removeObjectAtIndex:0]; >- >- auto requestLocation = [[_webView window] convertPoint:[requestLocationValue CGPointValue] toView:_webView.get()]; >- [(id <UIDragInteractionDelegate_Proposed_SPI_33146803>)[_webView dragInteractionDelegate] _dragInteraction:[_webView dragInteraction] itemsForAddingToSession:_dragSession.get() withTouchAtPoint:requestLocation completion:[dragSession = _dragSession, dropSession = _dropSession] (NSArray *items) { >- [dragSession addItems:items]; >- [dropSession addItems:items]; >- }]; >- return YES; >-} >- >-- (void)_advanceProgress >-{ >- [self _enqueuePendingAdditionalItemRequestLocations]; >- if ([self _sendQueuedAdditionalItemRequest]) { >- [self _scheduleAdvanceProgress]; >- return; >- } >- >- _lastKnownDragCaretRect = [_webView _dragCaretRect]; >- _currentProgress += progressIncrementStep; >- CGPoint locationInWindow = self._currentLocation; >- [_dragSession setMockLocationInWindow:locationInWindow]; >- [_dropSession setMockLocationInWindow:locationInWindow]; >- >- if (_currentProgress >= 1) { >- _currentProgress = 1; >- [self _concludeDataInteractionAndPerformOperationIfNecessary]; >- return; >- } >- >- switch (_phase) { >- case DataInteractionBeginning: { >- NSMutableArray<UIItemProvider *> *itemProviders = [NSMutableArray array]; >- NSArray *items = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] itemsForBeginningSession:_dragSession.get()]; >- if (!items.count) { >- _phase = DataInteractionCancelled; >- _currentProgress = 1; >- _isDoneWithCurrentRun = true; >- return; >- } >- >- for (UIDragItem *item in items) { >- [itemProviders addObject:item.itemProvider]; >- UITargetedDragPreview *liftPreview = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] previewForLiftingItem:item session:_dragSession.get()]; >- EXPECT_TRUE(!!liftPreview); >- if (liftPreview) >- [_liftPreviews addObject:liftPreview]; >- } >- >- _dropSession = adoptNS([[MockDropSession alloc] initWithProviders:itemProviders location:self._currentLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]); >- [_dragSession setItems:items]; >- _sourceItemProviders = itemProviders; >- if (self.showCustomActionSheetBlock) { >- // Defer progress until the custom action sheet is dismissed. >- auto startLocationInView = [[_webView window] convertPoint:_startLocation toView:_webView.get()]; >- [_webView _simulateLongPressActionAtLocation:startLocationInView]; >- return; >- } >- >- [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] sessionWillBegin:_dragSession.get()]; >- >- RetainPtr<WKWebView> retainedWebView = _webView; >- dispatch_async(dispatch_get_main_queue(), ^() { >- [retainedWebView resignFirstResponder]; >- }); >- >- _phase = DataInteractionBegan; >- break; >- } >- case DataInteractionBegan: >- [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnter:_dropSession.get()]; >- _phase = DataInteractionEntered; >- break; >- case DataInteractionEntered: { >- _currentDropProposal = [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidUpdate:_dropSession.get()]; >- if (![self shouldAllowMoveOperation] && [_currentDropProposal operation] == UIDropOperationMove) >- _currentDropProposal = adoptNS([[UIDropProposal alloc] initWithDropOperation:UIDropOperationCancel]); >- break; >- } >- default: >- break; >- } >- >- [self _scheduleAdvanceProgress]; >-} >- >-- (CGPoint)_currentLocation >-{ >- CGFloat distanceX = _endLocation.x - _startLocation.x; >- CGFloat distanceY = _endLocation.y - _startLocation.y; >- return CGPointMake(_startLocation.x + _currentProgress * distanceX, _startLocation.y + _currentProgress * distanceY); >-} >- >-- (void)_scheduleAdvanceProgress >-{ >- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_advanceProgress) object:nil]; >- [self performSelector:@selector(_advanceProgress) withObject:nil afterDelay:progressTimeStep]; >-} >- >-- (NSArray *)sourceItemProviders >-{ >- return _sourceItemProviders.get(); >-} >- >-- (NSArray *)externalItemProviders >-{ >- return _externalItemProviders.get(); >-} >- >-- (void)setExternalItemProviders:(NSArray *)externalItemProviders >-{ >- _externalItemProviders = adoptNS([externalItemProviders copy]); >-} >- >-- (DataInteractionPhase)phase >-{ >- return _phase; >-} >- >-- (NSArray<UITargetedDragPreview *> *)liftPreviews >-{ >- return _liftPreviews.get(); >-} >- >-- (CGRect)lastKnownDragCaretRect >-{ >- return _lastKnownDragCaretRect; >-} >- >-- (void)waitForInputSession >-{ >- _isDoneWaitingForInputSession = false; >- >- // Waiting for an input session implies that we should allow input sessions to begin. >- self.allowsFocusToStartInputSession = YES; >- >- Util::run(&_isDoneWaitingForInputSession); >-} >- >-- (NSArray<_WKAttachment *> *)insertedAttachments >-{ >- return _insertedAttachments.get(); >-} >- >-- (NSArray<_WKAttachment *> *)removedAttachments >-{ >- return _removedAttachments.get(); >-} >- >-- (void)endDataTransfer >-{ >- [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] sessionDidTransferItems:_dragSession.get()]; >-} >- >-#pragma mark - WKUIDelegatePrivate >- >-- (void)_webView:(WKWebView *)webView dataInteractionOperationWasHandled:(BOOL)handled forSession:(id)session itemProviders:(NSArray<UIItemProvider *> *)itemProviders >-{ >- _isDoneWithCurrentRun = true; >- >- if (self.dataInteractionOperationCompletionBlock) >- self.dataInteractionOperationCompletionBlock(handled, itemProviders); >-} >- >-- (NSUInteger)_webView:(WKWebView *)webView willUpdateDataInteractionOperationToOperation:(NSUInteger)operation forSession:(id)session >-{ >- return self.overrideDataInteractionOperationBlock ? self.overrideDataInteractionOperationBlock(operation, session) : operation; >-} >- >-- (NSArray *)_webView:(WKWebView *)webView adjustedDataInteractionItemProvidersForItemProvider:(UIItemProvider *)itemProvider representingObjects:(NSArray *)representingObjects additionalData:(NSDictionary *)additionalData >-{ >- return self.convertItemProvidersBlock ? self.convertItemProvidersBlock(itemProvider, representingObjects, additionalData) : @[ itemProvider ]; >-} >- >-- (BOOL)_webView:(WKWebView *)webView showCustomSheetForElement:(_WKActivatedElementInfo *)element >-{ >- if (!self.showCustomActionSheetBlock) >- return NO; >- >- RetainPtr<DataInteractionSimulator> strongSelf = self; >- dispatch_async(dispatch_get_main_queue(), ^() { >- DataInteractionSimulator *weakSelf = strongSelf.get(); >- [[weakSelf->_webView dragInteractionDelegate] dragInteraction:[weakSelf->_webView dragInteraction] sessionWillBegin:weakSelf->_dragSession.get()]; >- weakSelf->_phase = DataInteractionBegan; >- [weakSelf _scheduleAdvanceProgress]; >- }); >- >- return self.showCustomActionSheetBlock(element); >-} >- >-- (NSArray<UIDragItem *> *)_webView:(WKWebView *)webView willPerformDropWithSession:(id <UIDropSession>)session >-{ >- return self.overridePerformDropBlock ? self.overridePerformDropBlock(session) : session.items; >-} >- >-- (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment >-{ >- [_insertedAttachments addObject:attachment]; >-} >- >-- (void)_webView:(WKWebView *)webView didRemoveAttachment:(_WKAttachment *)attachment >-{ >- [_removedAttachments addObject:attachment]; >-} >- >-#pragma mark - _WKInputDelegate >- >-- (BOOL)_webView:(WKWebView *)webView focusShouldStartInputSession:(id <_WKFocusedElementInfo>)info >-{ >- return _allowsFocusToStartInputSession; >-} >- >-- (void)_webView:(WKWebView *)webView didStartInputSession:(id <_WKFormInputSession>)inputSession >-{ >- _isDoneWaitingForInputSession = true; >-} >- >-@end >- >-#endif // ENABLE(DATA_INTERACTION) >diff --git a/Tools/TestWebKitAPI/ios/DraggingSimulatorIOS.mm b/Tools/TestWebKitAPI/ios/DraggingSimulatorIOS.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..6666bd703d5954d2d1b93a40c943e616437b9c0f >--- /dev/null >+++ b/Tools/TestWebKitAPI/ios/DraggingSimulatorIOS.mm >@@ -0,0 +1,689 @@ >+/* >+ * 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 "DraggingSimulator.h" >+ >+#if ENABLE(DRAG_SUPPORT) && PLATFORM(IOS) >+ >+#import "InstanceMethodSwizzler.h" >+#import "PlatformUtilities.h" >+#import "UIKitSPI.h" >+ >+#import <UIKit/UIDragInteraction.h> >+#import <UIKit/UIDragItem.h> >+#import <UIKit/UIInteraction.h> >+#import <WebKit/WKWebViewPrivate.h> >+#import <WebKit/_WKFocusedElementInfo.h> >+#import <WebKit/_WKFormInputSession.h> >+#import <wtf/RetainPtr.h> >+#import <wtf/SoftLinking.h> >+ >+SOFT_LINK_FRAMEWORK(UIKit) >+SOFT_LINK(UIKit, UIApplicationInstantiateSingleton, void, (Class singletonClass), (singletonClass)) >+ >+using namespace TestWebKitAPI; >+ >+@implementation WKWebView (DragAndDropTesting) >+ >+- (UIView *)_dragDropInteractionView >+{ >+ return [self valueForKey:@"_currentContentView"]; >+} >+ >+- (id <UIDropInteractionDelegate>)dropInteractionDelegate >+{ >+ return (id <UIDropInteractionDelegate>)self._dragDropInteractionView; >+} >+ >+- (id <UIDragInteractionDelegate>)dragInteractionDelegate >+{ >+ return (id <UIDragInteractionDelegate>)self._dragDropInteractionView; >+} >+ >+- (UIDropInteraction *)dropInteraction >+{ >+ UIView *interactionView = self._dragDropInteractionView; >+ for (id <UIInteraction> interaction in interactionView.interactions) { >+ if ([interaction isKindOfClass:[UIDropInteraction class]]) >+ return (UIDropInteraction *)interaction; >+ } >+ return nil; >+} >+ >+- (UIDragInteraction *)dragInteraction >+{ >+ UIView *interactionView = self._dragDropInteractionView; >+ for (id <UIInteraction> interaction in interactionView.interactions) { >+ if ([interaction isKindOfClass:[UIDragInteraction class]]) >+ return (UIDragInteraction *)interaction; >+ } >+ return nil; >+} >+ >+@end >+ >+@implementation MockDragDropSession >+ >+- (instancetype)initWithItems:(NSArray <UIDragItem *>*)items location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove >+{ >+ if (self = [super init]) { >+ _mockItems = items; >+ _mockLocationInWindow = locationInWindow; >+ _window = window; >+ _allowMove = allowMove; >+ } >+ return self; >+} >+ >+- (BOOL)allowsMoveOperation >+{ >+ return _allowMove; >+} >+ >+- (BOOL)isRestrictedToDraggingApplication >+{ >+ return NO; >+} >+ >+- (BOOL)hasItemsConformingToTypeIdentifiers:(NSArray<NSString *> *)typeIdentifiers >+{ >+ for (NSString *typeIdentifier in typeIdentifiers) { >+ BOOL hasItemConformingToType = NO; >+ for (UIDragItem *item in self.items) >+ hasItemConformingToType |= [[item.itemProvider registeredTypeIdentifiers] containsObject:typeIdentifier]; >+ if (!hasItemConformingToType) >+ return NO; >+ } >+ return YES; >+} >+ >+- (BOOL)canLoadObjectsOfClass:(Class<UIItemProviderReading>)aClass >+{ >+ for (UIDragItem *item in self.items) { >+ if ([item.itemProvider canLoadObjectOfClass:aClass]) >+ return YES; >+ } >+ return NO; >+} >+ >+- (BOOL)canLoadObjectsOfClasses:(NSArray<Class<UIItemProviderReading>> *)classes >+{ >+ for (Class<UIItemProviderReading> aClass in classes) { >+ BOOL canLoad = NO; >+ for (UIDragItem *item in self.items) >+ canLoad |= [item.itemProvider canLoadObjectOfClass:aClass]; >+ if (!canLoad) >+ return NO; >+ } >+ return YES; >+} >+ >+- (NSArray<UIDragItem *> *)items >+{ >+ return _mockItems.get(); >+} >+ >+- (void)setItems:(NSArray<UIDragItem *> *)items >+{ >+ _mockItems = items; >+} >+ >+- (void)addItems:(NSArray<UIDragItem *> *)items >+{ >+ if (![items count]) >+ return; >+ >+ if (![_mockItems count]) >+ _mockItems = items; >+ else >+ _mockItems = [_mockItems arrayByAddingObjectsFromArray:items]; >+} >+ >+- (CGPoint)locationInView:(UIView *)view >+{ >+ return [_window convertPoint:_mockLocationInWindow toView:view]; >+} >+ >+@end >+ >+@implementation MockDropSession >+ >+- (instancetype)initWithProviders:(NSArray<UIItemProvider *> *)providers location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove >+{ >+ auto items = adoptNS([[NSMutableArray alloc] init]); >+ for (UIItemProvider *itemProvider in providers) >+ [items addObject:[[[UIDragItem alloc] initWithItemProvider:itemProvider] autorelease]]; >+ >+ return [super initWithItems:items.get() location:locationInWindow window:window allowMove:allowMove]; >+} >+ >+- (BOOL)isLocal >+{ >+ return YES; >+} >+ >+- (NSProgress *)progress >+{ >+ return [NSProgress discreteProgressWithTotalUnitCount:100]; >+} >+ >+- (void)setProgressIndicatorStyle:(UIDropSessionProgressIndicatorStyle)progressIndicatorStyle >+{ >+} >+ >+- (UIDropSessionProgressIndicatorStyle)progressIndicatorStyle >+{ >+ return UIDropSessionProgressIndicatorStyleNone; >+} >+ >+- (NSUInteger)operationMask >+{ >+ return 0; >+} >+ >+- (id <UIDragSession>)localDragSession >+{ >+ return nil; >+} >+ >+- (BOOL)hasItemsConformingToTypeIdentifier:(NSString *)typeIdentifier >+{ >+ ASSERT_NOT_REACHED(); >+ return NO; >+} >+ >+- (BOOL)canCreateItemsOfClass:(Class<UIItemProviderReading>)aClass >+{ >+ ASSERT_NOT_REACHED(); >+ return NO; >+} >+ >+- (NSProgress *)loadObjectsOfClass:(Class<NSItemProviderReading>)aClass completion:(void(^)(NSArray<__kindof id <NSItemProviderReading>> *objects))completion >+{ >+ ASSERT_NOT_REACHED(); >+ return nil; >+} >+ >+@end >+ >+@implementation MockDragSession { >+ RetainPtr<id> _localContext; >+} >+ >+- (instancetype)initWithWindow:(UIWindow *)window allowMove:(BOOL)allowMove >+{ >+ return [super initWithItems:@[ ] location:CGPointZero window:window allowMove:allowMove]; >+} >+ >+- (NSUInteger)localOperationMask >+{ >+ ASSERT_NOT_REACHED(); >+ return 0; >+} >+ >+- (NSUInteger)externalOperationMask >+{ >+ ASSERT_NOT_REACHED(); >+ return 0; >+} >+ >+- (id)session >+{ >+ return nil; >+} >+ >+- (id)localContext >+{ >+ return _localContext.get(); >+} >+ >+- (void)setLocalContext:(id)localContext >+{ >+ _localContext = localContext; >+} >+ >+@end >+ >+static double progressIncrementStep = 0.033; >+static double progressTimeStep = 0.016; >+static NSString *TestWebKitAPISimulateCancelAllTouchesNotificationName = @"TestWebKitAPISimulateCancelAllTouchesNotificationName"; >+ >+static NSArray *dragAndDropEventNames() >+{ >+ static NSArray *eventNames = nil; >+ static dispatch_once_t onceToken; >+ dispatch_once(&onceToken, ^() { >+ eventNames = @[ @"dragenter", @"dragover", @"drop", @"dragleave", @"dragstart" ]; >+ }); >+ return eventNames; >+} >+ >+@interface DraggingSimulatorApplication : UIApplication >+@end >+ >+@implementation DraggingSimulatorApplication >+- (void)_cancelAllTouches >+{ >+ [[NSNotificationCenter defaultCenter] postNotificationName:TestWebKitAPISimulateCancelAllTouchesNotificationName object:nil]; >+} >+@end >+ >+@implementation DraggingSimulator { >+ RetainPtr<TestWKWebView> _webView; >+ RetainPtr<MockDragSession> _dragSession; >+ RetainPtr<MockDropSession> _dropSession; >+ RetainPtr<NSMutableArray> _observedEventNames; >+ RetainPtr<NSArray> _externalItemProviders; >+ RetainPtr<NSArray *> _sourceItemProviders; >+ RetainPtr<NSArray *> _finalSelectionRects; >+ CGPoint _startLocation; >+ CGPoint _endLocation; >+ CGRect _lastKnownDragCaretRect; >+ >+ RetainPtr<NSMutableDictionary<NSNumber *, NSValue *>>_remainingAdditionalItemRequestLocationsByProgress; >+ RetainPtr<NSMutableArray<NSValue *>>_queuedAdditionalItemRequestLocations; >+ RetainPtr<NSMutableArray<UITargetedDragPreview *>> _liftPreviews; >+ >+ RetainPtr<NSMutableArray<_WKAttachment *>> _insertedAttachments; >+ RetainPtr<NSMutableArray<_WKAttachment *>> _removedAttachments; >+ >+ bool _isDoneWaitingForInputSession; >+ double _currentProgress; >+ bool _isDoneWithCurrentRun; >+ DragAndDropPhase _phase; >+ >+ RetainPtr<UIDropProposal> _currentDropProposal; >+} >+ >+- (instancetype)initWithWebView:(TestWKWebView *)webView >+{ >+ if (self = [super init]) { >+ _webView = webView; >+ _shouldEnsureUIApplication = NO; >+ _shouldAllowMoveOperation = YES; >+ _isDoneWaitingForInputSession = true; >+ [_webView setUIDelegate:self]; >+ [_webView _setInputDelegate:self]; >+ } >+ return self; >+} >+ >+- (void)dealloc >+{ >+ if ([_webView UIDelegate] == self) >+ [_webView setUIDelegate:nil]; >+ >+ if ([_webView _inputDelegate] == self) >+ [_webView _setInputDelegate:nil]; >+ >+ [super dealloc]; >+} >+ >+- (void)_resetSimulatedState >+{ >+ _phase = DragAndDropPhaseBeginning; >+ _currentProgress = 0; >+ _isDoneWithCurrentRun = false; >+ _observedEventNames = adoptNS([[NSMutableArray alloc] init]); >+ _insertedAttachments = adoptNS([[NSMutableArray alloc] init]); >+ _removedAttachments = adoptNS([[NSMutableArray alloc] init]); >+ _finalSelectionRects = @[ ]; >+ _dragSession = nil; >+ _dropSession = nil; >+ _currentDropProposal = nil; >+ _lastKnownDragCaretRect = CGRectZero; >+ _remainingAdditionalItemRequestLocationsByProgress = nil; >+ _queuedAdditionalItemRequestLocations = adoptNS([[NSMutableArray alloc] init]); >+ _liftPreviews = adoptNS([[NSMutableArray alloc] init]); >+} >+ >+- (NSArray *)observedEventNames >+{ >+ return _observedEventNames.get(); >+} >+ >+- (void)simulateAllTouchesCanceled:(NSNotification *)notification >+{ >+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_advanceProgress) object:nil]; >+ _phase = DragAndDropPhaseCancelled; >+ _currentProgress = 1; >+ _isDoneWithCurrentRun = true; >+ if (_dragSession) >+ [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:UIDropOperationCancel]; >+} >+ >+- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation >+{ >+ [self runFrom:startLocation to:endLocation additionalItemRequestLocations:nil]; >+} >+ >+- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation additionalItemRequestLocations:(ProgressToCGPointValueMap)additionalItemRequestLocations >+{ >+ NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; >+ [defaultCenter addObserver:self selector:@selector(simulateAllTouchesCanceled:) name:TestWebKitAPISimulateCancelAllTouchesNotificationName object:nil]; >+ >+ if (_shouldEnsureUIApplication) >+ UIApplicationInstantiateSingleton([DraggingSimulatorApplication class]); >+ >+ [self _resetSimulatedState]; >+ >+ if (additionalItemRequestLocations) >+ _remainingAdditionalItemRequestLocationsByProgress = adoptNS([additionalItemRequestLocations mutableCopy]); >+ >+ for (NSString *eventName in dragAndDropEventNames()) { >+ [_webView performAfterReceivingMessage:eventName action:[strongSelf = retainPtr(self), name = retainPtr(eventName)] { >+ [strongSelf->_observedEventNames addObject:name.get()]; >+ }]; >+ } >+ >+ _startLocation = startLocation; >+ _endLocation = endLocation; >+ >+ if (self.externalItemProviders.count) { >+ _dropSession = adoptNS([[MockDropSession alloc] initWithProviders:self.externalItemProviders location:_startLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]); >+ _phase = DragAndDropPhaseBegan; >+ [self _advanceProgress]; >+ } else { >+ _dragSession = adoptNS([[MockDragSession alloc] initWithWindow:[_webView window] allowMove:self.shouldAllowMoveOperation]); >+ [_dragSession setMockLocationInWindow:_startLocation]; >+ [(id <UIDragInteractionDelegate_ForWebKitOnly>)[_webView dragInteractionDelegate] _dragInteraction:[_webView dragInteraction] prepareForSession:_dragSession.get() completion:[strongSelf = retainPtr(self)] { >+ if (strongSelf->_phase == DragAndDropPhaseCancelled) >+ return; >+ >+ strongSelf->_phase = DragAndDropPhaseBeginning; >+ [strongSelf _advanceProgress]; >+ }]; >+ } >+ >+ Util::run(&_isDoneWithCurrentRun); >+ [_webView clearMessageHandlers:dragAndDropEventNames()]; >+ _finalSelectionRects = [_webView selectionRectsAfterPresentationUpdate]; >+ >+ [defaultCenter removeObserver:self]; >+} >+ >+- (NSArray *)finalSelectionRects >+{ >+ return _finalSelectionRects.get(); >+} >+ >+- (void)_concludeDropAndPerformOperationIfNecessary >+{ >+ _lastKnownDragCaretRect = [_webView _dragCaretRect]; >+ auto operation = [_currentDropProposal operation]; >+ if (operation != UIDropOperationCancel && operation != UIDropOperationForbidden) { >+ [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] performDrop:_dropSession.get()]; >+ _phase = DragAndDropPhasePerformingDrop; >+ } else { >+ _isDoneWithCurrentRun = YES; >+ _phase = DragAndDropPhaseCancelled; >+ } >+ >+ [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnd:_dropSession.get()]; >+ >+ if (_dragSession) >+ [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:operation]; >+} >+ >+- (void)_enqueuePendingAdditionalItemRequestLocations >+{ >+ NSMutableArray *progressValuesToRemove = [NSMutableArray array]; >+ for (NSNumber *progressValue in _remainingAdditionalItemRequestLocationsByProgress.get()) { >+ double progress = progressValue.doubleValue; >+ if (progress > _currentProgress) >+ continue; >+ [progressValuesToRemove addObject:progressValue]; >+ [_queuedAdditionalItemRequestLocations addObject:[_remainingAdditionalItemRequestLocationsByProgress objectForKey:progressValue]]; >+ } >+ >+ for (NSNumber *progressToRemove in progressValuesToRemove) >+ [_remainingAdditionalItemRequestLocationsByProgress removeObjectForKey:progressToRemove]; >+} >+ >+- (BOOL)_sendQueuedAdditionalItemRequest >+{ >+ if (![_queuedAdditionalItemRequestLocations count]) >+ return NO; >+ >+ RetainPtr<NSValue> requestLocationValue = [_queuedAdditionalItemRequestLocations objectAtIndex:0]; >+ [_queuedAdditionalItemRequestLocations removeObjectAtIndex:0]; >+ >+ auto requestLocation = [[_webView window] convertPoint:[requestLocationValue CGPointValue] toView:_webView.get()]; >+ [(id <UIDragInteractionDelegate_Proposed_SPI_33146803>)[_webView dragInteractionDelegate] _dragInteraction:[_webView dragInteraction] itemsForAddingToSession:_dragSession.get() withTouchAtPoint:requestLocation completion:[dragSession = _dragSession, dropSession = _dropSession] (NSArray *items) { >+ [dragSession addItems:items]; >+ [dropSession addItems:items]; >+ }]; >+ return YES; >+} >+ >+- (void)_advanceProgress >+{ >+ [self _enqueuePendingAdditionalItemRequestLocations]; >+ if ([self _sendQueuedAdditionalItemRequest]) { >+ [self _scheduleAdvanceProgress]; >+ return; >+ } >+ >+ _lastKnownDragCaretRect = [_webView _dragCaretRect]; >+ _currentProgress += progressIncrementStep; >+ CGPoint locationInWindow = self._currentLocation; >+ [_dragSession setMockLocationInWindow:locationInWindow]; >+ [_dropSession setMockLocationInWindow:locationInWindow]; >+ >+ if (_currentProgress >= 1) { >+ _currentProgress = 1; >+ [self _concludeDropAndPerformOperationIfNecessary]; >+ return; >+ } >+ >+ switch (_phase) { >+ case DragAndDropPhaseBeginning: { >+ NSMutableArray<UIItemProvider *> *itemProviders = [NSMutableArray array]; >+ NSArray *items = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] itemsForBeginningSession:_dragSession.get()]; >+ if (!items.count) { >+ _phase = DragAndDropPhaseCancelled; >+ _currentProgress = 1; >+ _isDoneWithCurrentRun = true; >+ return; >+ } >+ >+ for (UIDragItem *item in items) { >+ [itemProviders addObject:item.itemProvider]; >+ UITargetedDragPreview *liftPreview = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] previewForLiftingItem:item session:_dragSession.get()]; >+ EXPECT_TRUE(!!liftPreview); >+ if (liftPreview) >+ [_liftPreviews addObject:liftPreview]; >+ } >+ >+ _dropSession = adoptNS([[MockDropSession alloc] initWithProviders:itemProviders location:self._currentLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]); >+ [_dragSession setItems:items]; >+ _sourceItemProviders = itemProviders; >+ if (self.showCustomActionSheetBlock) { >+ // Defer progress until the custom action sheet is dismissed. >+ auto startLocationInView = [[_webView window] convertPoint:_startLocation toView:_webView.get()]; >+ [_webView _simulateLongPressActionAtLocation:startLocationInView]; >+ return; >+ } >+ >+ [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] sessionWillBegin:_dragSession.get()]; >+ >+ RetainPtr<WKWebView> retainedWebView = _webView; >+ dispatch_async(dispatch_get_main_queue(), ^() { >+ [retainedWebView resignFirstResponder]; >+ }); >+ >+ _phase = DragAndDropPhaseBegan; >+ break; >+ } >+ case DragAndDropPhaseBegan: >+ [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnter:_dropSession.get()]; >+ _phase = DragAndDropPhaseEntered; >+ break; >+ case DragAndDropPhaseEntered: { >+ _currentDropProposal = [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidUpdate:_dropSession.get()]; >+ if (![self shouldAllowMoveOperation] && [_currentDropProposal operation] == UIDropOperationMove) >+ _currentDropProposal = adoptNS([[UIDropProposal alloc] initWithDropOperation:UIDropOperationCancel]); >+ break; >+ } >+ default: >+ break; >+ } >+ >+ [self _scheduleAdvanceProgress]; >+} >+ >+- (CGPoint)_currentLocation >+{ >+ CGFloat distanceX = _endLocation.x - _startLocation.x; >+ CGFloat distanceY = _endLocation.y - _startLocation.y; >+ return CGPointMake(_startLocation.x + _currentProgress * distanceX, _startLocation.y + _currentProgress * distanceY); >+} >+ >+- (void)_scheduleAdvanceProgress >+{ >+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_advanceProgress) object:nil]; >+ [self performSelector:@selector(_advanceProgress) withObject:nil afterDelay:progressTimeStep]; >+} >+ >+- (NSArray *)sourceItemProviders >+{ >+ return _sourceItemProviders.get(); >+} >+ >+- (NSArray *)externalItemProviders >+{ >+ return _externalItemProviders.get(); >+} >+ >+- (void)setExternalItemProviders:(NSArray *)externalItemProviders >+{ >+ _externalItemProviders = adoptNS([externalItemProviders copy]); >+} >+ >+- (DragAndDropPhase)phase >+{ >+ return _phase; >+} >+ >+- (NSArray<UITargetedDragPreview *> *)liftPreviews >+{ >+ return _liftPreviews.get(); >+} >+ >+- (CGRect)lastKnownDragCaretRect >+{ >+ return _lastKnownDragCaretRect; >+} >+ >+- (void)waitForInputSession >+{ >+ _isDoneWaitingForInputSession = false; >+ >+ // Waiting for an input session implies that we should allow input sessions to begin. >+ self.allowsFocusToStartInputSession = YES; >+ >+ Util::run(&_isDoneWaitingForInputSession); >+} >+ >+- (NSArray<_WKAttachment *> *)insertedAttachments >+{ >+ return _insertedAttachments.get(); >+} >+ >+- (NSArray<_WKAttachment *> *)removedAttachments >+{ >+ return _removedAttachments.get(); >+} >+ >+- (void)endDataTransfer >+{ >+ [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] sessionDidTransferItems:_dragSession.get()]; >+} >+ >+#pragma mark - WKUIDelegatePrivate >+ >+- (void)_webView:(WKWebView *)webView dataInteractionOperationWasHandled:(BOOL)handled forSession:(id)session itemProviders:(NSArray<UIItemProvider *> *)itemProviders >+{ >+ _isDoneWithCurrentRun = true; >+ >+ if (self.dropCompletionBlock) >+ self.dropCompletionBlock(handled, itemProviders); >+} >+ >+- (NSUInteger)_webView:(WKWebView *)webView willUpdateDataInteractionOperationToOperation:(NSUInteger)operation forSession:(id)session >+{ >+ return self.overrideDragUpdateBlock ? self.overrideDragUpdateBlock(operation, session) : operation; >+} >+ >+- (NSArray *)_webView:(WKWebView *)webView adjustedDataInteractionItemProvidersForItemProvider:(UIItemProvider *)itemProvider representingObjects:(NSArray *)representingObjects additionalData:(NSDictionary *)additionalData >+{ >+ return self.convertItemProvidersBlock ? self.convertItemProvidersBlock(itemProvider, representingObjects, additionalData) : @[ itemProvider ]; >+} >+ >+- (BOOL)_webView:(WKWebView *)webView showCustomSheetForElement:(_WKActivatedElementInfo *)element >+{ >+ if (!self.showCustomActionSheetBlock) >+ return NO; >+ >+ dispatch_async(dispatch_get_main_queue(), [strongSelf = retainPtr(self)] { >+ [[strongSelf->_webView dragInteractionDelegate] dragInteraction:[strongSelf->_webView dragInteraction] sessionWillBegin:strongSelf->_dragSession.get()]; >+ strongSelf->_phase = DragAndDropPhaseBegan; >+ [strongSelf _scheduleAdvanceProgress]; >+ }); >+ >+ return self.showCustomActionSheetBlock(element); >+} >+ >+- (NSArray<UIDragItem *> *)_webView:(WKWebView *)webView willPerformDropWithSession:(id <UIDropSession>)session >+{ >+ return self.overridePerformDropBlock ? self.overridePerformDropBlock(session) : session.items; >+} >+ >+- (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment >+{ >+ [_insertedAttachments addObject:attachment]; >+} >+ >+- (void)_webView:(WKWebView *)webView didRemoveAttachment:(_WKAttachment *)attachment >+{ >+ [_removedAttachments addObject:attachment]; >+} >+ >+#pragma mark - _WKInputDelegate >+ >+- (BOOL)_webView:(WKWebView *)webView focusShouldStartInputSession:(id <_WKFocusedElementInfo>)info >+{ >+ return _allowsFocusToStartInputSession; >+} >+ >+- (void)_webView:(WKWebView *)webView didStartInputSession:(id <_WKFormInputSession>)inputSession >+{ >+ _isDoneWaitingForInputSession = true; >+} >+ >+@end >+ >+#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(IOS) >diff --git a/Tools/TestWebKitAPI/ios/UIKitSPI.h b/Tools/TestWebKitAPI/ios/UIKitSPI.h >index 8edd052a0384b0c794f99ed707bf45a1e7290ff2..8ecf305efbe771438d024f770e95deec50d1f1d2 100644 >--- a/Tools/TestWebKitAPI/ios/UIKitSPI.h >+++ b/Tools/TestWebKitAPI/ios/UIKitSPI.h >@@ -39,7 +39,12 @@ > @protocol UIDragSession; > @class UIDragInteraction; > @class UIDragItem; >+#import <UIKit/NSString+UIItemProvider.h> >+#import <UIKit/NSURL+UIItemProvider.h> > #import <UIKit/UIDragInteraction_Private.h> >+#import <UIKit/UIImage+UIItemProvider.h> >+#import <UIKit/UIItemProvider.h> >+#import <UIKit/UIItemProvider_Private.h> > #endif // ENABLE(DRAG_SUPPORT) > > #else >@@ -70,6 +75,42 @@ WTF_EXTERN_C_END > - (void)handleKeyWebEvent:(WebEvent *)theEvent withCompletionHandler:(void (^)(WebEvent *, BOOL))completionHandler; > @end > >+#if ENABLE(DRAG_SUPPORT) >+ >+@interface NSURL () >+@property (nonatomic, copy, setter=_setTitle:) NSString *_title; >+@end >+ >+#define UIItemProviderRepresentationOptionsVisibilityAll NSItemProviderRepresentationVisibilityAll >+ >+@protocol UIItemProviderReading <NSItemProviderReading> >+ >+@required >+- (instancetype)initWithItemProviderData:(NSData *)data typeIdentifier:(NSString *)typeIdentifier error:(NSError **)outError; >+ >+@end >+ >+@protocol UIItemProviderWriting <NSItemProviderWriting> >+ >+@required >+- (NSProgress *)loadDataWithTypeIdentifier:(NSString *)typeIdentifier forItemProviderCompletionHandler:(void (^)(NSData *, NSError *))completionHandler; >+ >+@end >+ >+@interface NSAttributedString () <UIItemProviderReading, UIItemProviderWriting> >+@end >+@interface NSString () <UIItemProviderReading, UIItemProviderWriting> >+@end >+@interface NSURL () <UIItemProviderReading, UIItemProviderWriting> >+@end >+@interface UIImage () <UIItemProviderReading, UIItemProviderWriting> >+@end >+ >+@interface UIItemProvider : NSItemProvider >+@end >+ >+#endif >+ > #endif > > @protocol UITextInputTraits_Private_Proposed_SPI_34583628 <UITextInputPrivate> >diff --git a/Tools/TestWebKitAPI/mac/DraggingSimulatorMac.mm b/Tools/TestWebKitAPI/mac/DraggingSimulatorMac.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..9ea3cc5da026db20a794808601732be8d6c22c2b >--- /dev/null >+++ b/Tools/TestWebKitAPI/mac/DraggingSimulatorMac.mm >@@ -0,0 +1,76 @@ >+/* >+ * 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 "DraggingSimulator.h" >+ >+@implementation DraggingSimulator { >+ RetainPtr<TestWKWebView> _webView; >+} >+ >+- (instancetype)initWithWebView:(TestWKWebView *)webView >+{ >+ if (self = [super init]) { >+ _webView = webView; >+ [_webView setUIDelegate:self]; >+ [_webView _setInputDelegate:self]; >+ } >+ return self; >+} >+ >+- (void)dealloc >+{ >+ if ([_webView UIDelegate] == self) >+ [_webView setUIDelegate:nil]; >+ >+ if ([_webView _inputDelegate] == self) >+ [_webView _setInputDelegate:nil]; >+ >+ [super dealloc]; >+} >+ >+- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation >+{ >+ // FIXME: Add a mechanism to simulate dragging on macOS. >+ UNUSED_PARAM(startLocation); >+ UNUSED_PARAM(endLocation); >+} >+ >+- (NSArray<_WKAttachment *> *)insertedAttachments >+{ >+ return @[ ]; >+} >+ >+- (NSArray<_WKAttachment *> *)removedAttachments >+{ >+ return @[ ]; >+} >+ >+- (DragAndDropPhase)phase >+{ >+ return DragAndDropPhaseCancelled; >+} >+ >+@end
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188439
:
346836
|
346837
|
346838
|
346849