Source/WebCore/ChangeLog

 12017-09-13 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 [iOS DnD] Support DataTransfer.setDragImage when starting a drag on iOS
 4 https://bugs.webkit.org/show_bug.cgi?id=176721
 5 <rdar://problem/34373660>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Adds support for setting the drag lift preview frame in the case where DataTransfer.setDragImage is being used
 10 to override the default drag preview. Currently, the frame of the drag preview we supply in this case is the
 11 same as the bounds of the source element in root view coordinates, but this means that any custom drag image
 12 the page supplies will be stretched to fill the frame of the source element. Instead, when handling a DHTML drag,
 13 position the lift and cancel drag previews relative to the event location, respecting any drag offset specified
 14 in setDragImage. The size of this preview matches the size of the drag image source (since this is all in root
 15 view coordinates, this means the drag preview will also enlarge if the user pinches to zoom in). If a
 16 disconnected image source element was provided, then we just fall back to the image size.
 17
 18 Additionally, renames DragItem's elementBounds to dragPreviewFrameInRootViewCoordinates to better reflect the
 19 purpose of this variable. This patch also introduces API test plumbing to grab targeted drag previews from the
 20 drag interaction delegate (i.e. WKContentView), and uses this in a new API test that checks the frame of the
 21 resulting UITargetedDragPreview after initiating a drag in various circumstances (see changes in Tools/ for more
 22 detail).
 23
 24 Test: DataInteractionTests.DragLiftPreviewDataTransferSetDragImage
 25
 26 * dom/DataTransfer.cpp:
 27 (WebCore::DataTransfer::dragImageElement const):
 28 * dom/DataTransfer.h:
 29 * page/DragController.cpp:
 30 (WebCore::dragLocForDHTMLDrag):
 31
 32 The logic to flip the y offset when computing the drag location is only relevant on Mac, but currently, this is
 33 guarded by #if PLATFORM(COCOA), which causes the y offset to shift the drag image in the opposite direction on
 34 iOS. To fix this, simply change the platform define to Mac.
 35
 36 (WebCore::DragController::doSystemDrag):
 37 * platform/DragItem.h:
 38 (WebCore::DragItem::encode const):
 39 (WebCore::DragItem::decode):
 40
1412017-09-12 Wenson Hsieh <wenson_hsieh@apple.com>
242
343 [iOS DnD] Support DataTransfer.getData and DataTransfer.setData when dragging or dropping

Source/WebKit/ChangeLog

 12017-09-13 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 [iOS DnD] Support DataTransfer.setDragImage when starting a drag on iOS
 4 https://bugs.webkit.org/show_bug.cgi?id=176721
 5 <rdar://problem/34373660>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Rename elementBounds => dragPreviewFrameInRootViewCoordinates.
 10
 11 * UIProcess/ios/DragDropInteractionState.h:
 12 * UIProcess/ios/DragDropInteractionState.mm:
 13 (WebKit::DragDropInteractionState::previewForDragItem const):
 14 (WebKit::DragDropInteractionState::stageDragItem):
 15
1162017-09-11 Wenson Hsieh <wenson_hsieh@apple.com>
217
318 [iOS WK2] Support tapping to add items to the current drag session in web content

Source/WebKitLegacy/mac/ChangeLog

 12017-09-13 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 [iOS DnD] Support DataTransfer.setDragImage when starting a drag on iOS
 4 https://bugs.webkit.org/show_bug.cgi?id=176721
 5 <rdar://problem/34373660>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Rename elementBounds => dragPreviewFrameInRootViewCoordinates. (Note: Unfortunately, _draggedElementBounds in
 10 WebViewPrivate.h can't be renamed yet, due to binary and SDK compatibility with UIKit).
 11
 12 * WebView/WebView.mm:
 13 (-[WebView _startDrag:]):
 14 (-[WebView _draggedElementBounds]):
 15 (-[WebView _endedDataInteraction:global:]):
 16 * WebView/WebViewData.h:
 17
1182017-09-11 Andy Estes <aestes@apple.com>
219
320 [Mac] Upstream QTKit-related WebKitSystemInterface functions

Source/WebCore/dom/DataTransfer.cpp

@@void DataTransfer::updateDragImage()
303303 m_pasteboard->setDragImage(WTFMove(computedImage), computedHotSpot);
304304}
305305
 306RefPtr<Element> DataTransfer::dragImageElement() const
 307{
 308 return m_dragImageElement;
 309}
 310
306311#if !PLATFORM(MAC)
307312
308313DragImageRef DataTransfer::createDragImage(IntPoint& location) const

Source/WebCore/dom/DataTransfer.h

@@public:
9292 void setDragHasStarted() { m_shouldUpdateDragImage = true; }
9393 DragImageRef createDragImage(IntPoint& dragLocation) const;
9494 void updateDragImage();
 95 RefPtr<Element> dragImageElement() const;
9596#endif
9697
9798private:

Source/WebCore/page/DragController.cpp

@@static void selectElement(Element& element)
830830static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const IntPoint& dragOrigin, const IntPoint& dragImageOffset, bool isLinkImage)
831831{
832832 // dragImageOffset is the cursor position relative to the lower-left corner of the image.
833 #if PLATFORM(COCOA)
 833#if PLATFORM(MAC)
834834 // We add in the Y dimension because we are a flipped view, so adding moves the image down.
835835 const int yOffset = dragImageOffset.y();
836836#else

@@void DragController::doSystemDrag(DragImage image, const IntPoint& dragLoc, cons
12281228 DragItem item;
12291229 item.image = WTFMove(image);
12301230 item.sourceAction = state.type;
1231  item.eventPositionInContentCoordinates = viewProtector->rootViewToContents(frame.view()->contentsToRootView(eventPos));
1232  item.dragLocationInContentCoordinates = viewProtector->rootViewToContents(frame.view()->contentsToRootView(dragLoc));
 1231
 1232 auto eventPositionInRootViewCoordinates = frame.view()->contentsToRootView(eventPos);
 1233 auto dragLocationInRootViewCoordinates = frame.view()->contentsToRootView(dragLoc);
 1234 item.eventPositionInContentCoordinates = viewProtector->rootViewToContents(eventPositionInRootViewCoordinates);
 1235 item.dragLocationInContentCoordinates = viewProtector->rootViewToContents(dragLocationInRootViewCoordinates);
12331236 item.eventPositionInWindowCoordinates = frame.view()->contentsToWindow(item.eventPositionInContentCoordinates);
12341237 item.dragLocationInWindowCoordinates = frame.view()->contentsToWindow(item.dragLocationInContentCoordinates);
12351238 if (auto element = state.source) {
1236  item.elementBounds = element->boundsInRootViewSpace();
 1239 auto dataTransferImageElement = state.dataTransfer->dragImageElement();
 1240 if (state.type == DragSourceActionDHTML) {
 1241 // If the drag image has been customized, fall back to positioning the preview relative to the drag event location.
 1242 IntSize dragPreviewSize;
 1243 if (dataTransferImageElement)
 1244 dragPreviewSize = dataTransferImageElement->boundsInRootViewSpace().size();
 1245 else {
 1246 dragPreviewSize = dragImageSize(item.image.get());
 1247 if (auto* page = frame.page())
 1248 dragPreviewSize.scale(1 / page->deviceScaleFactor());
 1249 }
 1250 item.dragPreviewFrameInRootViewCoordinates = { dragLocationInRootViewCoordinates, WTFMove(dragPreviewSize) };
 1251 } else {
 1252 // We can simply position the preview simply using the bounds of the drag source element.
 1253 item.dragPreviewFrameInRootViewCoordinates = element->boundsInRootViewSpace();
 1254 }
 1255
12371256 RefPtr<Element> link;
12381257 if (element->isLink())
12391258 link = element;

Source/WebCore/platform/DragItem.h

@@struct DragItem final {
4646 IntPoint dragLocationInWindowCoordinates;
4747 String title;
4848 URL url;
49  IntRect elementBounds;
 49 IntRect dragPreviewFrameInRootViewCoordinates;
5050
5151 PasteboardWriterData data;
5252

@@void DragItem::encode(Encoder& encoder) const
6060 // FIXME(173815): We should encode and decode PasteboardWriterData and platform drag image data
6161 // here too, as part of moving off of the legacy dragging codepath.
6262 encoder.encodeEnum(sourceAction);
63  encoder << imageAnchorPoint << eventPositionInContentCoordinates << dragLocationInContentCoordinates << eventPositionInWindowCoordinates << dragLocationInWindowCoordinates << title << url << elementBounds;
 63 encoder << imageAnchorPoint << eventPositionInContentCoordinates << dragLocationInContentCoordinates << eventPositionInWindowCoordinates << dragLocationInWindowCoordinates << title << url << dragPreviewFrameInRootViewCoordinates;
6464 bool hasIndicatorData = image.hasIndicatorData();
6565 encoder << hasIndicatorData;
6666 if (hasIndicatorData)

@@bool DragItem::decode(Decoder& decoder, DragItem& result)
8686 return false;
8787 if (!decoder.decode(result.url))
8888 return false;
89  if (!decoder.decode(result.elementBounds))
 89 if (!decoder.decode(result.dragPreviewFrameInRootViewCoordinates))
9090 return false;
9191 bool hasIndicatorData;
9292 if (!decoder.decode(hasIndicatorData))

Source/WebKit/UIProcess/ios/DragDropInteractionState.h

@@namespace WebKit {
4646struct DragSourceState {
4747 WebCore::DragSourceAction action { WebCore::DragSourceActionNone };
4848 CGPoint adjustedOrigin { CGPointZero };
49  CGRect elementBounds { CGRectZero };
 49 CGRect dragPreviewFrameInRootViewCoordinates { CGRectZero };
5050 RetainPtr<UIImage> image;
5151 std::optional<WebCore::TextIndicatorData> indicatorData;
5252 String linkTitle;

Source/WebKit/UIProcess/ios/DragDropInteractionState.mm

@@UITargetedDragPreview *DragDropInteractionState::previewForDragItem(UIDragItem *
159159 return nil;
160160
161161 auto& source = foundSource.value();
162  if (shouldUseDragImageToCreatePreviewForDragSource(source)) {
163  Vector<FloatRect> emptyClippingRects;
164  return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.elementBounds, emptyClippingRects, nil);
165  }
 162 if (shouldUseDragImageToCreatePreviewForDragSource(source))
 163 return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil);
166164
167165 if (shouldUseTextIndicatorToCreatePreviewForDragSource(source)) {
168166 auto indicator = source.indicatorData.value();

@@void DragDropInteractionState::stageDragItem(const DragItem& item, UIImage *drag
203201 m_stagedDragSource = {{
204202 static_cast<DragSourceAction>(item.sourceAction),
205203 item.eventPositionInContentCoordinates,
206  item.elementBounds,
 204 item.dragPreviewFrameInRootViewCoordinates,
207205 dragImage,
208206 item.image.indicatorData(),
209207 item.title.isEmpty() ? nil : (NSString *)item.title,

Source/WebKitLegacy/mac/WebView/WebView.mm

@@- (void)_startDrag:(const DragItem&)dragItem
18121812 _private->textIndicatorData = adoptNS([[WebUITextIndicatorData alloc] initWithImage:image scale:_private->page->deviceScaleFactor()]);
18131813 _private->draggedLinkURL = dragItem.url.isEmpty() ? nil : (NSURL *)dragItem.url;
18141814 _private->draggedLinkTitle = dragItem.title.isEmpty() ? nil : (NSString *)dragItem.title;
1815  _private->draggedElementBounds = dragItem.elementBounds;
 1815 _private->dragPreviewFrameInRootViewCoordinates = dragItem.dragPreviewFrameInRootViewCoordinates;
18161816 _private->dragSourceAction = static_cast<WebDragSourceAction>(dragItem.sourceAction);
18171817}
18181818

@@- (NSURL *)_draggedLinkURL
18471847
18481848- (CGRect)_draggedElementBounds
18491849{
1850  return _private->draggedElementBounds;
 1850 return _private->dragPreviewFrameInRootViewCoordinates;
18511851}
18521852
18531853- (WebUITextIndicatorData *)_getDataInteractionData

@@- (void)_endedDataInteraction:(CGPoint)clientPosition global:(CGPoint)globalPosi
19031903 WebThreadLock();
19041904 _private->page->dragController().dragEnded();
19051905 _private->dataOperationTextIndicator = nullptr;
1906  _private->draggedElementBounds = CGRectNull;
 1906 _private->dragPreviewFrameInRootViewCoordinates = CGRectNull;
19071907 _private->dragSourceAction = WebDragSourceActionNone;
19081908 _private->draggedLinkTitle = nil;
19091909 _private->draggedLinkURL = nil;

Source/WebKitLegacy/mac/WebView/WebViewData.h

@@private:
301301#if ENABLE(DATA_INTERACTION)
302302 RetainPtr<WebUITextIndicatorData> textIndicatorData;
303303 RetainPtr<WebUITextIndicatorData> dataOperationTextIndicator;
304  CGRect draggedElementBounds;
 304 CGRect dragPreviewFrameInRootViewCoordinates;
305305 WebDragSourceAction dragSourceAction;
306306 RetainPtr<NSURL> draggedLinkURL;
307307 RetainPtr<NSString> draggedLinkTitle;

Tools/ChangeLog

 12017-09-13 Wenson Hsieh <wenson_hsieh@apple.com>
 2
 3 [iOS DnD] Support DataTransfer.setDragImage when starting a drag on iOS
 4 https://bugs.webkit.org/show_bug.cgi?id=176721
 5 <rdar://problem/34373660>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 In DataInteractionSimulator, ask the UIDragInteractionDelegate (WKContentView) for targeted drag previews after
 10 retrieving UIDragItems during a lift. Remember these previews after the drag and drop simulation is complete, so
 11 API tests (currently, just DragLiftPreviewDataTransferSetDragImage) can verify that the generated drag previews
 12 are as expected.
 13
 14 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
 15 * TestWebKitAPI/Tests/WebKitCocoa/DataTransfer-setDragImage.html: Added.
 16
 17 Adds a new test harness containing 5 draggable elements, each generating a drag image using different codepaths.
 18 DragLiftPreviewDataTransferSetDragImage uses this page to check that the frame of the targeted drag preview in
 19 each scenario is as expected.
 20
 21 * TestWebKitAPI/Tests/ios/DataInteractionTests.mm:
 22 (checkCGRectIsEqualToCGRectWithLogging):
 23 (TestWebKitAPI::TEST):
 24 * TestWebKitAPI/ios/DataInteractionSimulator.h:
 25 * TestWebKitAPI/ios/DataInteractionSimulator.mm:
 26 (-[DataInteractionSimulator _resetSimulatedState]):
 27 (-[DataInteractionSimulator _advanceProgress]):
 28 (-[DataInteractionSimulator liftPreviews]):
 29
1302017-09-12 Wenson Hsieh <wenson_hsieh@apple.com>
231
332 [iOS DnD] Support DataTransfer.getData and DataTransfer.setData when dragging or dropping

Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

689689 F46A095B1ED8A6E600D4AA55 /* gif-and-file-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F47D30ED1ED28A6C000482E1 /* gif-and-file-input.html */; };
690690 F47728991E4AE3C1007ABF6A /* full-page-contenteditable.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F47728981E4AE3AD007ABF6A /* full-page-contenteditable.html */; };
691691 F4856CA31E649EA8009D7EE7 /* attachment-element.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4856CA21E6498A8009D7EE7 /* attachment-element.html */; };
 692 F486B1D01F67952300F34BDD /* DataTransfer-setDragImage.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F486B1CF1F6794FF00F34BDD /* DataTransfer-setDragImage.html */; };
692693 F4A32EC41F05F3850047C544 /* dragstart-change-selection-offscreen.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */; };
693694 F4A32ECB1F0643370047C544 /* contenteditable-in-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4A32ECA1F0642F40047C544 /* contenteditable-in-iframe.html */; };
694695 F4AB578A1F65165400DB0DA1 /* custom-draggable-div.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */; };

774775 dstPath = TestWebKitAPI.resources;
775776 dstSubfolderSpec = 7;
776777 files = (
 778 F486B1D01F67952300F34BDD /* DataTransfer-setDragImage.html in Copy Resources */,
777779 1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
778780 379028B914FAC24C007E6B43 /* acceptsFirstMouse.html in Copy Resources */,
779781 1C2B81871C8925A000A5529F /* Ahem.ttf in Copy Resources */,

17251727 F47D30EB1ED28619000482E1 /* apple.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = apple.gif; sourceTree = "<group>"; };
17261728 F47D30ED1ED28A6C000482E1 /* gif-and-file-input.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "gif-and-file-input.html"; sourceTree = "<group>"; };
17271729 F4856CA21E6498A8009D7EE7 /* attachment-element.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "attachment-element.html"; sourceTree = "<group>"; };
 1730 F486B1CF1F6794FF00F34BDD /* DataTransfer-setDragImage.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "DataTransfer-setDragImage.html"; sourceTree = "<group>"; };
17281731 F493247C1F44DF8D006F4336 /* UIKitSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIKitSPI.h; sourceTree = "<group>"; };
17291732 F4A32EC31F05F3780047C544 /* dragstart-change-selection-offscreen.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "dragstart-change-selection-offscreen.html"; sourceTree = "<group>"; };
17301733 F4A32ECA1F0642F40047C544 /* contenteditable-in-iframe.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "contenteditable-in-iframe.html"; sourceTree = "<group>"; };

21662169 5C2936941D5BFD1900DEAB1E /* CookieMessage.html */,
21672170 F4AB57891F65164B00DB0DA1 /* custom-draggable-div.html */,
21682171 F4512E121F60C43400BB369E /* DataTransferItem-getAsEntry.html */,
 2172 F486B1CF1F6794FF00F34BDD /* DataTransfer-setDragImage.html */,
21692173 0799C34A1EBA32F4003B7532 /* disableGetUserMedia.html */,
21702174 F41AB99E1EF4692C0083FA08 /* div-and-large-image.html */,
21712175 837A35F01D9A1E6400663C57 /* DownloadRequestBlobURL.html */,

Tools/TestWebKitAPI/Tests/WebKitCocoa/DataTransfer-setDragImage.html

 1<!DOCTYPE html>
 2<html>
 3<meta name="viewport" content="width=device-width">
 4<head>
 5<style>
 6 body, html {
 7 width: 100%;
 8 height: 100%;
 9 }
 10
 11 body {
 12 margin: 0;
 13 }
 14
 15 #red {
 16 background-color: red;
 17 width: 300px;
 18 height: 100px;
 19 }
 20
 21 #green {
 22 background-color: green;
 23 width: 300px;
 24 height: 100px;
 25 }
 26
 27 #blue {
 28 background-color: blue;
 29 width: 300px;
 30 height: 100px;
 31 }
 32
 33 #cyan {
 34 background-color: cyan;
 35 width: 300px;
 36 height: 100px;
 37 }
 38</style>
 39</head>
 40
 41<div id="red" draggable="true"></div>
 42<div id="green" draggable="true"></div>
 43<div id="blue" draggable="true"></div>
 44<div id="cyan" draggable="true"></div>
 45<img id="icon" src="icon.png"></img>
 46<div><code>To manually test, attempt to drag each of the colored blocks.</code></div>
 47
 48<script>
 49red.addEventListener("dragstart", event => {
 50 event.dataTransfer.setDragImage(icon, 0, 0);
 51 event.dataTransfer.setData("text/plain", "red");
 52});
 53
 54green.addEventListener("dragstart", event => {
 55 event.dataTransfer.setDragImage(icon, 100, 100);
 56 event.dataTransfer.setData("text/plain", "green");
 57});
 58
 59blue.addEventListener("dragstart", event => {
 60 let image = new Image();
 61 image.src = icon.src;
 62 event.dataTransfer.setDragImage(image, 0, 0);
 63 event.dataTransfer.setData("text/plain", "blue");
 64});
 65
 66cyan.addEventListener("dragstart", event => {
 67 event.dataTransfer.setData("text/plain", "cyan");
 68});
 69</script>
 70</html>

Tools/TestWebKitAPI/Tests/ios/DataInteractionTests.mm

@@static NSValue *makeCGRectValue(CGFloat x, CGFloat y, CGFloat width, CGFloat hei
102102 return [NSValue valueWithCGRect:CGRectMake(x, y, width, height)];
103103}
104104
 105static void checkCGRectIsEqualToCGRectWithLogging(CGRect expected, CGRect observed)
 106{
 107 BOOL isEqual = CGRectEqualToRect(expected, observed);
 108 EXPECT_TRUE(isEqual);
 109 if (!isEqual)
 110 NSLog(@"Expected: %@ but observed: %@", NSStringFromCGRect(expected), NSStringFromCGRect(observed));
 111}
 112
105113static void checkSelectionRectsWithLogging(NSArray *expected, NSArray *observed)
106114{
107115 if (![expected isEqualToArray:observed])

@@TEST(DataInteractionTests, AdditionalLinkAndImageIntoContentEditable)
14331441 EXPECT_WK_STREQ("https://www.apple.com/", [webView stringByEvaluatingJavaScript:@"editor.querySelector('a').href"]);
14341442}
14351443
 1444TEST(DataInteractionTests, DragLiftPreviewDataTransferSetDragImage)
 1445{
 1446 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
 1447 [webView synchronouslyLoadTestPageNamed:@"DataTransfer-setDragImage"];
 1448 auto simulator = adoptNS([[DataInteractionSimulator alloc] initWithWebView:webView.get()]);
 1449
 1450 // Use DataTransfer.setDragImage to specify an existing image element in the DOM.
 1451 [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(250, 50)];
 1452 checkCGRectIsEqualToCGRectWithLogging({{100, 50}, {215, 174}}, [simulator liftPreviews][0].view.frame);
 1453
 1454 // Use DataTransfer.setDragImage to specify an existing image element in the DOM, with x and y offsets.
 1455 [simulator runFrom:CGPointMake(10, 150) to:CGPointMake(250, 150)];
 1456 checkCGRectIsEqualToCGRectWithLogging({{-90, 50}, {215, 174}}, [simulator liftPreviews][0].view.frame);
 1457
 1458 // Use DataTransfer.setDragImage to specify a newly created Image, disconnected from the DOM.
 1459 [simulator runFrom:CGPointMake(100, 250) to:CGPointMake(250, 250)];
 1460 checkCGRectIsEqualToCGRectWithLogging({{100, 250}, {215, 174}}, [simulator liftPreviews][0].view.frame);
 1461
 1462 // Don't use DataTransfer.setDragImage and fall back to snapshotting the dragged element.
 1463 [simulator runFrom:CGPointMake(50, 350) to:CGPointMake(250, 350)];
 1464 checkCGRectIsEqualToCGRectWithLogging({{0, 300}, {300, 100}}, [simulator liftPreviews][0].view.frame);
 1465
 1466 // Perform a normal drag on an image.
 1467 [simulator runFrom:CGPointMake(50, 450) to:CGPointMake(250, 450)];
 1468 checkCGRectIsEqualToCGRectWithLogging({{0, 400}, {215, 174}}, [simulator liftPreviews][0].view.frame);
 1469}
 1470
14361471} // namespace TestWebKitAPI
14371472
14381473#endif // ENABLE(DATA_INTERACTION)

Tools/TestWebKitAPI/ios/DataInteractionSimulator.h

@@typedef NS_ENUM(NSInteger, DataInteractionPhase) {
136136
137137 RetainPtr<NSMutableDictionary<NSNumber *, NSValue *>>_remainingAdditionalItemRequestLocationsByProgress;
138138 RetainPtr<NSMutableArray<NSValue *>>_queuedAdditionalItemRequestLocations;
 139 RetainPtr<NSMutableArray<UITargetedDragPreview *>> _liftPreviews;
139140
140141 bool _isDoneWaitingForInputSession;
141142 BOOL _shouldPerformOperation;

@@typedef NS_ENUM(NSInteger, DataInteractionPhase) {
165166@property (nonatomic, readonly) NSArray *finalSelectionRects;
166167@property (nonatomic, readonly) DataInteractionPhase phase;
167168@property (nonatomic, readonly) CGRect lastKnownDragCaretRect;
 169@property (nonatomic, readonly) NSArray<UITargetedDragPreview *> *liftPreviews;
168170
169171@end
170172

Tools/TestWebKitAPI/ios/DataInteractionSimulator.mm

@@- (void)_resetSimulatedState
343343 _lastKnownDragCaretRect = CGRectZero;
344344 _remainingAdditionalItemRequestLocationsByProgress = nil;
345345 _queuedAdditionalItemRequestLocations = adoptNS([[NSMutableArray alloc] init]);
 346 _liftPreviews = adoptNS([[NSMutableArray alloc] init]);
346347}
347348
348349- (NSArray *)observedEventNames

@@- (void)_advanceProgress
501502 [itemProviders addObject:item.itemProvider];
502503 UITargetedDragPreview *liftPreview = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] previewForLiftingItem:item session:_dragSession.get()];
503504 EXPECT_TRUE(!!liftPreview);
 505 if (liftPreview)
 506 [_liftPreviews addObject:liftPreview];
504507 }
505508
506509 _dropSession = adoptNS([[MockDropSession alloc] initWithProviders:itemProviders location:self._currentLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]);

@@- (DataInteractionPhase)phase
572575 return _phase;
573576}
574577
 578- (NSArray<UITargetedDragPreview *> *)liftPreviews
 579{
 580 return _liftPreviews.get();
 581}
 582
575583- (CGRect)lastKnownDragCaretRect
576584{
577585 return _lastKnownDragCaretRect;