Skip to content

Commit b05688d

Browse files
[iOS WK2] Add plumbing for WKContentView to ask the web process for additional drag items
https://bugs.webkit.org/show_bug.cgi?id=176348 Work towards <rdar://problem/31144674> Reviewed by Tim Horton. Source/WebKit: Adds boilerplate plumbing to request additional items to an existing session. This implements some UI-side logic in WKContentView to send an additional drag items request and handle a response from the web process. To start, WebPageProxy::requestAdditionalItemsForDragSession is invoked by -_dragInteraction: itemsForAddingToSession:withTouchAtPoint:completion: in WKContentView, and the response from the web process is handled in -[WKContentView _didHandleAdditionalDragItemsRequest:]. * UIProcess/API/Cocoa/WKWebView.mm: (-[WKWebView _simulateItemsForAddingToSession:atLocation:completion:]): * UIProcess/API/Cocoa/WKWebViewPrivate.h: Add SPI to simulate a request for additional drag items. See Tools/ChangeLog for more detail. * UIProcess/PageClient.h: * UIProcess/WebPageProxy.h: * UIProcess/WebPageProxy.messages.in: Add an IPC message handler for the additional drag items response from the web process. * UIProcess/ios/DragDropInteractionState.h: (WebKit::DragDropInteractionState::BlockPtr<void): * UIProcess/ios/DragDropInteractionState.mm: (WebKit::DragDropInteractionState::shouldRequestAdditionalItemForDragSession const): (WebKit::DragDropInteractionState::dragSessionWillRequestAdditionalItem): Invoke the new additional items completion handler when tearing down to avoid getting UIKit into a bad state. (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd): * UIProcess/ios/PageClientImplIOS.h: * UIProcess/ios/PageClientImplIOS.mm: (WebKit::PageClientImpl::didHandleAdditionalDragItemsRequest): * UIProcess/ios/WKContentViewInteraction.h: * UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView _didHandleAdditionalDragItemsRequest:]): (-[WKContentView _itemsForBeginningOrAddingToSessionWithRegistrationList:stagedDragSource:]): Factors common logic to convert a staged WebItemProviderRegistrationInfoList and DragSourceState into a list of drag items, invoking the private UI delegate in the process. This is called both when starting a drag session, and adding items to an existing drag session. (-[WKContentView _dragInteraction:itemsForAddingToSession:withTouchAtPoint:completion:]): Implements a (proposed) additional drag item delegate that serves as an asynchronous alternative to the API variant, -_dragInteraction:itemsForAddingToSession:withTouchAtPoint:. See <rdar://problem/33146803> for more information. (-[WKContentView dragInteraction:itemsForBeginningSession:]): Refactored to use -_itemsForBeginningOrAddingToSessionWithRegistrationList:stagedDragSource:. (-[WKContentView _simulateItemsForAddingToSession:atLocation:completion:]): * UIProcess/ios/WebPageProxyIOS.mm: (WebKit::WebPageProxy::didHandleAdditionalDragItemsRequest): (WebKit::WebPageProxy::requestAdditionalItemsForDragSession): * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: Add an IPC message handler for the additional drag items request from the UI process. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::requestAdditionalItemsForDragSession): Tools: Introduces new test infrastructure to simulate tapping to add additional items to the current drag session. We add -[DataInteractionSimulator runFrom:to:additionalItemRequestLocations:], for which the last argument is a dictionary mapping progress (a double between 0 and 1) to NSValues representing the location from which the drag and drop simulation will request an additional drag item. During the simulated drag and drop, when the progress value exceeds a value in the map of remaining additional item request locations, we halt drag simulation progress for that runloop and instead request additional items from the location specified. The only (useful) passing test we can create using the new machinery is one that verifies that preventDefault() on dragstart works as expected, preventing additional items from being added. While this trivially passes now, since the web-process-side of the additional items flow is not yet implemented, it should continue to pass after the web process portion is implemented. * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: * TestWebKitAPI/Tests/WebKitCocoa/selected-text-image-link-and-editable.html: Added. Add a new test page that contains some non-editable text, an image, a link, and a rich text editable area. * TestWebKitAPI/Tests/ios/DataInteractionTests.mm: (TestWebKitAPI::TEST): * TestWebKitAPI/ios/DataInteractionSimulator.h: * TestWebKitAPI/ios/DataInteractionSimulator.mm: (-[MockDragDropSession addItems:]): Convenience method to add additional mock drag items to a drag or drop session. (-[DataInteractionSimulator _resetSimulatedState]): (-[DataInteractionSimulator runFrom:to:]): Converted into a convenience wrapper around the latter version, passing in nil for the additional item request locations dictionary. (-[DataInteractionSimulator runFrom:to:additionalItemRequestLocations:]): (-[DataInteractionSimulator _enqueuePendingAdditionalItemRequestLocations]): (-[DataInteractionSimulator _sendQueuedAdditionalItemRequest]): New helper methods to detect when and where additional items should be "added", and subsequently simulate adding drag items at these given locations. (-[DataInteractionSimulator _advanceProgress]): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@221660 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 974557e commit b05688d

22 files changed

+366
-31
lines changed

Source/WebKit/ChangeLog

+69
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,72 @@
1+
2017-09-05 Wenson Hsieh <[email protected]>
2+
3+
[iOS WK2] Add plumbing for WKContentView to ask the web process for additional drag items
4+
https://bugs.webkit.org/show_bug.cgi?id=176348
5+
Work towards <rdar://problem/31144674>
6+
7+
Reviewed by Tim Horton.
8+
9+
Adds boilerplate plumbing to request additional items to an existing session. This implements some UI-side logic
10+
in WKContentView to send an additional drag items request and handle a response from the web process.
11+
To start, WebPageProxy::requestAdditionalItemsForDragSession is invoked by -_dragInteraction:
12+
itemsForAddingToSession:withTouchAtPoint:completion: in WKContentView, and the response from the web process is
13+
handled in -[WKContentView _didHandleAdditionalDragItemsRequest:].
14+
15+
* UIProcess/API/Cocoa/WKWebView.mm:
16+
(-[WKWebView _simulateItemsForAddingToSession:atLocation:completion:]):
17+
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
18+
19+
Add SPI to simulate a request for additional drag items. See Tools/ChangeLog for more detail.
20+
21+
* UIProcess/PageClient.h:
22+
* UIProcess/WebPageProxy.h:
23+
* UIProcess/WebPageProxy.messages.in:
24+
25+
Add an IPC message handler for the additional drag items response from the web process.
26+
27+
* UIProcess/ios/DragDropInteractionState.h:
28+
(WebKit::DragDropInteractionState::BlockPtr<void):
29+
* UIProcess/ios/DragDropInteractionState.mm:
30+
(WebKit::DragDropInteractionState::shouldRequestAdditionalItemForDragSession const):
31+
(WebKit::DragDropInteractionState::dragSessionWillRequestAdditionalItem):
32+
33+
Invoke the new additional items completion handler when tearing down to avoid getting UIKit into a bad state.
34+
35+
(WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):
36+
* UIProcess/ios/PageClientImplIOS.h:
37+
* UIProcess/ios/PageClientImplIOS.mm:
38+
(WebKit::PageClientImpl::didHandleAdditionalDragItemsRequest):
39+
* UIProcess/ios/WKContentViewInteraction.h:
40+
* UIProcess/ios/WKContentViewInteraction.mm:
41+
(-[WKContentView _didHandleAdditionalDragItemsRequest:]):
42+
(-[WKContentView _itemsForBeginningOrAddingToSessionWithRegistrationList:stagedDragSource:]):
43+
44+
Factors common logic to convert a staged WebItemProviderRegistrationInfoList and DragSourceState into a list of
45+
drag items, invoking the private UI delegate in the process. This is called both when starting a drag session,
46+
and adding items to an existing drag session.
47+
48+
(-[WKContentView _dragInteraction:itemsForAddingToSession:withTouchAtPoint:completion:]):
49+
50+
Implements a (proposed) additional drag item delegate that serves as an asynchronous alternative to the API
51+
variant, -_dragInteraction:itemsForAddingToSession:withTouchAtPoint:. See <rdar://problem/33146803> for more
52+
information.
53+
54+
(-[WKContentView dragInteraction:itemsForBeginningSession:]):
55+
56+
Refactored to use -_itemsForBeginningOrAddingToSessionWithRegistrationList:stagedDragSource:.
57+
58+
(-[WKContentView _simulateItemsForAddingToSession:atLocation:completion:]):
59+
* UIProcess/ios/WebPageProxyIOS.mm:
60+
(WebKit::WebPageProxy::didHandleAdditionalDragItemsRequest):
61+
(WebKit::WebPageProxy::requestAdditionalItemsForDragSession):
62+
* WebProcess/WebPage/WebPage.h:
63+
* WebProcess/WebPage/WebPage.messages.in:
64+
65+
Add an IPC message handler for the additional drag items request from the UI process.
66+
67+
* WebProcess/WebPage/ios/WebPageIOS.mm:
68+
(WebKit::WebPage::requestAdditionalItemsForDragSession):
69+
170
2017-09-05 Alex Christensen <[email protected]>
271

372
Add WKUIDelegatePrivate equivalent of WKPageUIClient's mouseDidMoveOverElement

Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

+7
Original file line numberDiff line numberDiff line change
@@ -5831,6 +5831,13 @@ - (NSArray *)_simulatedItemsForSession:(id)session
58315831
#endif
58325832
}
58335833

5834+
- (void)_simulateItemsForAddingToSession:(id)session atLocation:(CGPoint)location completion:(void(^)(NSArray *))completion
5835+
{
5836+
#if ENABLE(DATA_INTERACTION)
5837+
[_contentView _simulateItemsForAddingToSession:session atLocation:location completion:completion];
5838+
#endif
5839+
}
5840+
58345841
- (void)_simulatePrepareForDataInteractionSession:(id)session completion:(dispatch_block_t)completion
58355842
{
58365843
#if ENABLE(DATA_INTERACTION)

Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h

+1
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ typedef NS_ENUM(NSInteger, _WKImmediateActionType) {
373373
- (void)_simulateDataInteractionSessionDidEnd:(id)session WK_API_AVAILABLE(ios(WK_IOS_TBA));
374374
- (void)_simulateWillBeginDataInteractionWithSession:(id)session WK_API_AVAILABLE(ios(WK_IOS_TBA));
375375
- (NSArray *)_simulatedItemsForSession:(id)session WK_API_AVAILABLE(ios(WK_IOS_TBA));
376+
- (void)_simulateItemsForAddingToSession:(id)session atLocation:(CGPoint)location completion:(void(^)(NSArray *))completion WK_API_AVAILABLE(ios(WK_IOS_TBA));
376377
- (void)_simulatePrepareForDataInteractionSession:(id)session completion:(dispatch_block_t)completion WK_API_AVAILABLE(ios(WK_IOS_TBA));
377378
- (void)_simulateLongPressActionAtLocation:(CGPoint)location;
378379

Source/WebKit/UIProcess/PageClient.h

+1
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ class PageClient {
381381
#if ENABLE(DATA_INTERACTION)
382382
virtual void didPerformDataInteractionControllerOperation(bool handled) = 0;
383383
virtual void didHandleStartDataInteractionRequest(bool started) = 0;
384+
virtual void didHandleAdditionalDragItemsRequest(bool added) = 0;
384385
virtual void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle& image) = 0;
385386
virtual void didConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData>) = 0;
386387
virtual void didChangeDataInteractionCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) = 0;

Source/WebKit/UIProcess/WebPageProxy.h

+2
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,9 @@ class WebPageProxy : public API::ObjectImpl<API::Object::Type::Page>
561561
#if ENABLE(DATA_INTERACTION)
562562
void didPerformDataInteractionControllerOperation(bool handled);
563563
void didHandleStartDataInteractionRequest(bool started);
564+
void didHandleAdditionalDragItemsRequest(bool added);
564565
void requestStartDataInteraction(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
566+
void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
565567
void didConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData>);
566568
#endif
567569
#endif

Source/WebKit/UIProcess/WebPageProxy.messages.in

+1
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ messages -> WebPageProxy {
317317
#if ENABLE(DATA_INTERACTION)
318318
DidPerformDataInteractionControllerOperation(bool handled)
319319
DidHandleStartDataInteractionRequest(bool started)
320+
DidHandleAdditionalDragItemsRequest(bool added)
320321
DidConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData> textIndicator)
321322
#endif
322323

Source/WebKit/UIProcess/ios/DragDropInteractionState.h

+4
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class DragDropInteractionState {
7070
void clearStagedDragSource(DidBecomeActive = DidBecomeActive::No);
7171
UITargetedDragPreview *previewForDragItem(UIDragItem *, UIView *contentView, UIView *previewContainer) const;
7272
void dragSessionWillDelaySetDownAnimation(dispatch_block_t completion);
73+
bool shouldRequestAdditionalItemForDragSession(id <UIDragSession>) const;
74+
void dragSessionWillRequestAdditionalItem(void (^completion)(NSArray <UIDragItem *> *));
7375

7476
// These helper methods are unique to UIDropInteraction.
7577
void dropSessionDidEnterOrUpdate(id <UIDropSession>, const WebCore::DragData&);
@@ -86,6 +88,7 @@ class DragDropInteractionState {
8688
id<UIDropSession> dropSession() const { return m_dropSession.get(); }
8789
BlockPtr<void()> takeDragStartCompletionBlock() { return WTFMove(m_dragStartCompletionBlock); }
8890
BlockPtr<void()> takeDragCancelSetDownBlock() { return WTFMove(m_dragCancelSetDownBlock); }
91+
BlockPtr<void(NSArray<UIDragItem *> *)> takeAddDragItemCompletionBlock() { return WTFMove(m_addDragItemCompletionBlock); }
8992

9093
private:
9194
void updatePreviewsForActiveDragSources();
@@ -99,6 +102,7 @@ class DragDropInteractionState {
99102
RetainPtr<id <UIDropSession>> m_dropSession;
100103
BlockPtr<void()> m_dragStartCompletionBlock;
101104
BlockPtr<void()> m_dragCancelSetDownBlock;
105+
BlockPtr<void(NSArray<UIDragItem *> *)> m_addDragItemCompletionBlock;
102106

103107
std::optional<DragSourceState> m_stagedDragSource;
104108
Vector<DragSourceState> m_activeDragSources;

Source/WebKit/UIProcess/ios/DragDropInteractionState.mm

+14
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ static bool shouldUseTextIndicatorToCreatePreviewForDragAction(DragSourceAction
167167
m_dragCancelSetDownBlock = completion;
168168
}
169169

170+
bool DragDropInteractionState::shouldRequestAdditionalItemForDragSession(id <UIDragSession> session) const
171+
{
172+
return m_dragSession == session && !m_addDragItemCompletionBlock && !m_dragStartCompletionBlock;
173+
}
174+
175+
void DragDropInteractionState::dragSessionWillRequestAdditionalItem(void (^completion)(NSArray <UIDragItem *> *))
176+
{
177+
clearStagedDragSource();
178+
m_addDragItemCompletionBlock = completion;
179+
}
180+
170181
void DragDropInteractionState::dropSessionDidEnterOrUpdate(id <UIDropSession> session, const DragData& dragData)
171182
{
172183
m_dropSession = session;
@@ -210,6 +221,9 @@ static bool shouldUseTextIndicatorToCreatePreviewForDragAction(DragSourceAction
210221
if (auto completionBlock = takeDragCancelSetDownBlock())
211222
completionBlock();
212223

224+
if (auto completionBlock = takeAddDragItemCompletionBlock())
225+
completionBlock(@[ ]);
226+
213227
if (auto completionBlock = takeDragStartCompletionBlock())
214228
completionBlock();
215229
}

Source/WebKit/UIProcess/ios/PageClientImplIOS.h

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ class PageClientImpl : public PageClientImplCocoa
205205
#if ENABLE(DATA_INTERACTION)
206206
void didPerformDataInteractionControllerOperation(bool handled) override;
207207
void didHandleStartDataInteractionRequest(bool started) override;
208+
void didHandleAdditionalDragItemsRequest(bool added) override;
208209
void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle& image) override;
209210
void didConcludeEditDataInteraction(std::optional<WebCore::TextIndicatorData>) override;
210211
void didChangeDataInteractionCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) override;

Source/WebKit/UIProcess/ios/PageClientImplIOS.mm

+5
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,11 @@ - (void)redoEditing:(id)sender
786786
[m_contentView _didHandleStartDataInteractionRequest:started];
787787
}
788788

789+
void PageClientImpl::didHandleAdditionalDragItemsRequest(bool added)
790+
{
791+
[m_contentView _didHandleAdditionalDragItemsRequest:added];
792+
}
793+
789794
void PageClientImpl::startDrag(const DragItem& item, const ShareableBitmap::Handle& image)
790795
{
791796
[m_contentView _startDrag:ShareableBitmap::create(image)->makeCGImageCopy() item:item];

Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

+2
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
321321
- (void)_didChangeDragInteractionPolicy;
322322
- (void)_didPerformDataInteractionControllerOperation:(BOOL)handled;
323323
- (void)_didHandleStartDataInteractionRequest:(BOOL)started;
324+
- (void)_didHandleAdditionalDragItemsRequest:(BOOL)added;
324325
- (void)_startDrag:(RetainPtr<CGImageRef>)image item:(const WebCore::DragItem&)item;
325326
- (void)_didConcludeEditDataInteraction:(std::optional<WebCore::TextIndicatorData>)data;
326327
- (void)_didChangeDataInteractionCaretRect:(CGRect)previousRect currentRect:(CGRect)rect;
@@ -333,6 +334,7 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
333334
- (void)_simulateWillBeginDataInteractionWithSession:(id)session;
334335
- (NSArray *)_simulatedItemsForSession:(id)session;
335336
- (void)_simulatePrepareForDataInteractionSession:(id)session completion:(dispatch_block_t)completion;
337+
- (void)_simulateItemsForAddingToSession:(id)session atLocation:(CGPoint)location completion:(void(^)(NSArray *))completion;
336338
#endif
337339

338340
- (void)_simulateLongPressActionAtLocation:(CGPoint)location;

Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

+73-31
Original file line numberDiff line numberDiff line change
@@ -4259,6 +4259,31 @@ - (void)_startDrag:(RetainPtr<CGImageRef>)image item:(const DragItem&)item
42594259
_dragDropInteractionState.stageDragItem(item, dragImage.get());
42604260
}
42614261

4262+
- (void)_didHandleAdditionalDragItemsRequest:(BOOL)added
4263+
{
4264+
auto completion = _dragDropInteractionState.takeAddDragItemCompletionBlock();
4265+
if (!completion)
4266+
return;
4267+
4268+
WebItemProviderRegistrationInfoList *registrationList = [[WebItemProviderPasteboard sharedInstance] takeRegistrationList];
4269+
if (!added || !registrationList || !_dragDropInteractionState.hasStagedDragSource()) {
4270+
_dragDropInteractionState.clearStagedDragSource();
4271+
completion(@[ ]);
4272+
return;
4273+
}
4274+
4275+
auto stagedDragSource = _dragDropInteractionState.stagedDragSource();
4276+
NSArray *dragItemsToAdd = [self _itemsForBeginningOrAddingToSessionWithRegistrationList:registrationList stagedDragSource:stagedDragSource];
4277+
4278+
RELEASE_LOG(DragAndDrop, "Drag session: %p adding %tu items", _dragDropInteractionState.dragSession(), dragItemsToAdd.count);
4279+
_dragDropInteractionState.clearStagedDragSource(dragItemsToAdd.count ? DragDropInteractionState::DidBecomeActive::Yes : DragDropInteractionState::DidBecomeActive::No);
4280+
4281+
completion(dragItemsToAdd);
4282+
4283+
if (dragItemsToAdd.count)
4284+
_page->didStartDrag();
4285+
}
4286+
42624287
- (void)_didHandleStartDataInteractionRequest:(BOOL)started
42634288
{
42644289
BlockPtr<void()> savedCompletionBlock = _dragDropInteractionState.takeDragStartCompletionBlock();
@@ -4454,6 +4479,37 @@ - (void)_restoreCalloutBarIfNeeded
44544479
_shouldRestoreCalloutBarAfterDrop = NO;
44554480
}
44564481

4482+
- (NSArray<UIDragItem *> *)_itemsForBeginningOrAddingToSessionWithRegistrationList:(WebItemProviderRegistrationInfoList *)registrationList stagedDragSource:(const DragSourceState&)stagedDragSource
4483+
{
4484+
UIItemProvider *defaultItemProvider = registrationList.itemProvider;
4485+
if (!defaultItemProvider)
4486+
return @[ ];
4487+
4488+
NSArray *adjustedItemProviders;
4489+
id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
4490+
if ([uiDelegate respondsToSelector:@selector(_webView:adjustedDataInteractionItemProvidersForItemProvider:representingObjects:additionalData:)]) {
4491+
auto representingObjects = adoptNS([[NSMutableArray alloc] init]);
4492+
auto additionalData = adoptNS([[NSMutableDictionary alloc] init]);
4493+
[registrationList enumerateItems:[representingObjects, additionalData] (WebItemProviderRegistrationInfo *item, NSUInteger) {
4494+
if (item.representingObject)
4495+
[representingObjects addObject:item.representingObject];
4496+
if (item.typeIdentifier && item.data)
4497+
[additionalData setObject:item.data forKey:item.typeIdentifier];
4498+
}];
4499+
adjustedItemProviders = [uiDelegate _webView:_webView adjustedDataInteractionItemProvidersForItemProvider:defaultItemProvider representingObjects:representingObjects.get() additionalData:additionalData.get()];
4500+
} else
4501+
adjustedItemProviders = @[ defaultItemProvider ];
4502+
4503+
NSMutableArray *dragItems = [NSMutableArray arrayWithCapacity:adjustedItemProviders.count];
4504+
for (UIItemProvider *itemProvider in adjustedItemProviders) {
4505+
auto item = adoptNS([[UIDragItem alloc] initWithItemProvider:itemProvider]);
4506+
[item _setPrivateLocalContext:@(stagedDragSource.itemIdentifier)];
4507+
[dragItems addObject:item.autorelease()];
4508+
}
4509+
4510+
return dragItems;
4511+
}
4512+
44574513
#pragma mark - UIDragInteractionDelegate
44584514

44594515
- (BOOL)_dragInteraction:(UIDragInteraction *)interaction shouldDelayCompetingGestureRecognizer:(UIGestureRecognizer *)competingGestureRecognizer
@@ -4477,6 +4533,17 @@ - (NSInteger)_dragInteraction:(UIDragInteraction *)interaction dataOwnerForSessi
44774533
return dataOwner;
44784534
}
44794535

4536+
- (void)_dragInteraction:(UIDragInteraction *)interaction itemsForAddingToSession:(id <UIDragSession>)session withTouchAtPoint:(CGPoint)point completion:(void(^)(NSArray<UIDragItem *> *))completion
4537+
{
4538+
if (!_dragDropInteractionState.shouldRequestAdditionalItemForDragSession(session)) {
4539+
completion(@[ ]);
4540+
return;
4541+
}
4542+
4543+
_dragDropInteractionState.dragSessionWillRequestAdditionalItem(completion);
4544+
_page->requestAdditionalItemsForDragSession(roundedIntPoint(point), roundedIntPoint(point));
4545+
}
4546+
44804547
- (void)_dragInteraction:(UIDragInteraction *)interaction prepareForSession:(id <UIDragSession>)session completion:(dispatch_block_t)completion
44814548
{
44824549
[self _cancelLongPressGestureRecognizer];
@@ -4515,37 +4582,7 @@ - (void)_dragInteraction:(UIDragInteraction *)interaction prepareForSession:(id
45154582

45164583
auto stagedDragSource = _dragDropInteractionState.stagedDragSource();
45174584
WebItemProviderRegistrationInfoList *registrationList = [[WebItemProviderPasteboard sharedInstance] takeRegistrationList];
4518-
UIItemProvider *defaultItemProvider = registrationList.itemProvider;
4519-
if (!defaultItemProvider) {
4520-
RELEASE_LOG(DragAndDrop, "Drag session failed: %p (no item providers generated before adjustment)", session);
4521-
_page->dragCancelled();
4522-
_dragDropInteractionState.clearStagedDragSource();
4523-
return @[ ];
4524-
}
4525-
4526-
// Give internal clients such as Mail one final chance to augment the contents of each UIItemProvider before sending the drag items off to UIKit.
4527-
NSArray *adjustedItemProviders;
4528-
id <WKUIDelegatePrivate> uiDelegate = self.webViewUIDelegate;
4529-
if ([uiDelegate respondsToSelector:@selector(_webView:adjustedDataInteractionItemProvidersForItemProvider:representingObjects:additionalData:)]) {
4530-
auto representingObjects = adoptNS([[NSMutableArray alloc] init]);
4531-
auto additionalData = adoptNS([[NSMutableDictionary alloc] init]);
4532-
[registrationList enumerateItems:[representingObjects, additionalData] (WebItemProviderRegistrationInfo *item, NSUInteger) {
4533-
if (item.representingObject)
4534-
[representingObjects addObject:item.representingObject];
4535-
if (item.typeIdentifier && item.data)
4536-
[additionalData setObject:item.data forKey:item.typeIdentifier];
4537-
}];
4538-
adjustedItemProviders = [uiDelegate _webView:_webView adjustedDataInteractionItemProvidersForItemProvider:defaultItemProvider representingObjects:representingObjects.get() additionalData:additionalData.get()];
4539-
} else
4540-
adjustedItemProviders = @[ defaultItemProvider ];
4541-
4542-
NSMutableArray *dragItems = [NSMutableArray arrayWithCapacity:adjustedItemProviders.count];
4543-
for (UIItemProvider *itemProvider in adjustedItemProviders) {
4544-
auto item = adoptNS([[UIDragItem alloc] initWithItemProvider:itemProvider]);
4545-
[item _setPrivateLocalContext:@(stagedDragSource.itemIdentifier)];
4546-
[dragItems addObject:item.autorelease()];
4547-
}
4548-
4585+
NSArray *dragItems = [self _itemsForBeginningOrAddingToSessionWithRegistrationList:registrationList stagedDragSource:stagedDragSource];
45494586
if (![dragItems count])
45504587
_page->dragCancelled();
45514588

@@ -4828,6 +4865,11 @@ - (void)_simulatePrepareForDataInteractionSession:(id)session completion:(dispat
48284865
[self _dragInteraction:_dragInteraction.get() prepareForSession:session completion:completion];
48294866
}
48304867

4868+
- (void)_simulateItemsForAddingToSession:(id)session atLocation:(CGPoint)location completion:(void(^)(NSArray *))completion
4869+
{
4870+
[self _dragInteraction:_dragInteraction.get() itemsForAddingToSession:session withTouchAtPoint:location completion:completion];
4871+
}
4872+
48314873
#endif
48324874

48334875
- (void)_simulateLongPressActionAtLocation:(CGPoint)location

Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm

+11
Original file line numberDiff line numberDiff line change
@@ -1094,12 +1094,23 @@ static bool exceedsRenderTreeSizeSizeThreshold(uint64_t thresholdSize, uint64_t
10941094
m_pageClient.didHandleStartDataInteractionRequest(started);
10951095
}
10961096

1097+
void WebPageProxy::didHandleAdditionalDragItemsRequest(bool added)
1098+
{
1099+
m_pageClient.didHandleAdditionalDragItemsRequest(added);
1100+
}
1101+
10971102
void WebPageProxy::requestStartDataInteraction(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition)
10981103
{
10991104
if (isValid())
11001105
m_process->send(Messages::WebPage::RequestStartDataInteraction(clientPosition, globalPosition), m_pageID);
11011106
}
11021107

1108+
void WebPageProxy::requestAdditionalItemsForDragSession(const IntPoint& clientPosition, const IntPoint& globalPosition)
1109+
{
1110+
if (isValid())
1111+
m_process->send(Messages::WebPage::RequestAdditionalItemsForDragSession(clientPosition, globalPosition), m_pageID);
1112+
}
1113+
11031114
void WebPageProxy::didConcludeEditDataInteraction(std::optional<TextIndicatorData> data)
11041115
{
11051116
m_pageClient.didConcludeEditDataInteraction(data);

0 commit comments

Comments
 (0)