Changeset 245778 in webkit
- Timestamp:
- May 26, 2019 4:31:49 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r245776 r245778 1 2019-05-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Dropped text, attachments, and images should animate into place 4 https://bugs.webkit.org/show_bug.cgi?id=198243 5 <rdar://problem/35205373> 6 7 Reviewed by Tim Horton. 8 9 Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit 10 changelog for more detail. 11 12 Test: DragAndDropTests.DropPreviewForImageInEditableArea 13 14 * loader/EmptyClients.h: 15 * page/ChromeClient.h: 16 * page/Page.cpp: 17 (WebCore::Page::didFinishLoadingImageForElement): 18 * page/Page.h: 19 * rendering/RenderImage.cpp: 20 (WebCore::RenderImage::notifyFinished): 21 1 22 2019-05-25 Zalan Bujtas <zalan@apple.com> 2 23 -
trunk/Source/WebCore/loader/EmptyClients.h
r245174 r245778 41 41 class DiagnosticLoggingClient; 42 42 class EditorClient; 43 class HTMLImageElement; 43 44 class PageConfiguration; 44 45 … … 111 112 IntPoint accessibilityScreenToRootView(const IntPoint& p) const final { return p; }; 112 113 IntRect rootViewToAccessibilityScreen(const IntRect& r) const final { return r; }; 114 115 void didFinishLoadingImageForElement(HTMLImageElement&) final { } 113 116 114 117 PlatformPageClient platformPageClient() const final { return 0; } -
trunk/Source/WebCore/page/ChromeClient.h
r245366 r245778 88 88 class GraphicsLayer; 89 89 class GraphicsLayerFactory; 90 class HTMLImageElement; 90 91 class HTMLInputElement; 91 92 class HTMLMediaElement; … … 183 184 virtual IntRect rootViewToAccessibilityScreen(const IntRect&) const = 0; 184 185 186 virtual void didFinishLoadingImageForElement(HTMLImageElement&) = 0; 187 185 188 virtual PlatformPageClient platformPageClient() const = 0; 186 189 -
trunk/Source/WebCore/page/Page.cpp
r245543 r245778 2997 2997 } 2998 2998 2999 void Page::didFinishLoadingImageForElement(HTMLImageElement& element) 3000 { 3001 chrome().client().didFinishLoadingImageForElement(element); 3002 } 3003 2999 3004 } // namespace WebCore -
trunk/Source/WebCore/page/Page.h
r245072 r245778 528 528 WEBCORE_EXPORT void resumeAnimatingImages(); 529 529 530 void didFinishLoadingImageForElement(HTMLImageElement&); 531 530 532 WEBCORE_EXPORT void addLayoutMilestones(OptionSet<LayoutMilestone>); 531 533 WEBCORE_EXPORT void removeLayoutMilestones(OptionSet<LayoutMilestone>); -
trunk/Source/WebCore/rendering/RenderImage.cpp
r245543 r245778 379 379 contentChanged(ImageChanged); 380 380 } 381 382 if (is<HTMLImageElement>(element())) 383 page().didFinishLoadingImageForElement(downcast<HTMLImageElement>(*element())); 381 384 } 382 385 -
trunk/Source/WebKit/ChangeLog
r245767 r245778 1 2019-05-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Dropped text, attachments, and images should animate into place 4 https://bugs.webkit.org/show_bug.cgi?id=198243 5 <rdar://problem/35205373> 6 7 Reviewed by Tim Horton. 8 9 Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in 10 <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor 11 and augment existing logic for taking snapshots after performing a drop in an editable content. 12 13 Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web 14 view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of 15 the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade 16 from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop 17 preview to the drag caret rect. During this process, snapshot (2) is completely ignored. 18 19 This was effectively a halfway implemention of the desired effect of animating the dropped content into place 20 and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation 21 was not possible in modern WebKit (without using synchronous IPC). 22 23 Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot 24 (2) above and clean up some parts of the drop animation in editable content. See below for more details. 25 26 * UIProcess/API/Cocoa/WKWebView.mm: 27 (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]): 28 29 Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See 30 TestWebKitAPI changes for more detail. 31 32 * UIProcess/API/Cocoa/WKWebViewPrivate.h: 33 * UIProcess/PageClient.h: 34 * UIProcess/WebPageProxy.h: 35 * UIProcess/WebPageProxy.messages.in: 36 37 Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and 38 DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop, 39 until after the final edit drag snapshot has been received. 40 41 * UIProcess/ios/DragDropInteractionState.h: 42 43 Add some new methods to help manage the lifecycle of drop preview provider blocks. 44 45 * UIProcess/ios/DragDropInteractionState.mm: 46 (WebKit::createTargetedDragPreview): 47 48 Drive-by fix: make this return a RetainPtr. 49 50 (WebKit::DragDropInteractionState::prepareForDelayedDropPreview): 51 52 Stores a drop preview provider, given to us by UIKit. 53 54 (WebKit::DragDropInteractionState::deliverDelayedDropPreview): 55 56 Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are 57 taken following an edit drag (this is additionally after all images in the inserted fragment have finished 58 loading). 59 60 (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders): 61 62 Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session 63 cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers 64 are always invoked when cleaning up the drag session. 65 66 (WebKit::DragDropInteractionState::previewForDragItem const): 67 (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd): 68 69 Call clearAllDelayedItemPreviewProviders. 70 71 * UIProcess/ios/PageClientImplIOS.h: 72 * UIProcess/ios/PageClientImplIOS.mm: 73 (WebKit::PageClientImpl::willReceiveEditDragSnapshot): 74 (WebKit::PageClientImpl::didReceiveEditDragSnapshot): 75 (WebKit::PageClientImpl::didConcludeEditDrag): Deleted. 76 77 More plumbing (see changes to DidConcludeEditDrag above). 78 79 * UIProcess/ios/WKContentViewInteraction.h: 80 * UIProcess/ios/WKContentViewInteraction.mm: 81 (-[WKContentView cleanupInteraction]): 82 (-[WKContentView cleanUpDragSourceSessionState]): 83 (-[WKContentView _willReceiveEditDragSnapshot]): 84 (-[WKContentView _didReceiveEditDragSnapshot:]): 85 86 Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and 87 when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of 88 -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is 89 received. 90 91 (-[WKContentView _deliverDelayedDropPreviewIfPossible:]): 92 (-[WKContentView _didPerformDragOperation:]): 93 (-[WKContentView textEffectsWindow]): 94 95 Drive-by fix to remove a workaround for a deprecation warning. 96 97 (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]): 98 (-[WKContentView dropInteraction:concludeDrop:]): 99 100 Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are 101 guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives 102 after the drop is concluded. 103 104 (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]): 105 (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]): 106 107 Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time 108 to update the drop preview. We do this in _didReceiveEditDragSnapshot. 109 110 (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]): 111 (-[WKContentView _didConcludeEditDrag:]): Deleted. 112 * UIProcess/ios/WebPageProxyIOS.mm: 113 (WebKit::WebPageProxy::willReceiveEditDragSnapshot): 114 (WebKit::WebPageProxy::didReceiveEditDragSnapshot): 115 (WebKit::WebPageProxy::didConcludeDrop): 116 (WebKit::WebPageProxy::didConcludeEditDrag): Deleted. 117 * WebProcess/WebCoreSupport/WebChromeClient.cpp: 118 (WebKit::WebChromeClient::didFinishLoadingImageForElement): 119 * WebProcess/WebCoreSupport/WebChromeClient.h: 120 * WebProcess/WebPage/WebPage.cpp: 121 (WebKit::WebPage::didFinishLoadingImageForElement): 122 * WebProcess/WebPage/WebPage.h: 123 * WebProcess/WebPage/WebPage.messages.in: 124 * WebProcess/WebPage/ios/WebPageIOS.mm: 125 (WebKit::WebPage::didConcludeDrop): 126 127 If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear 128 out the set here. 129 130 (WebKit::WebPage::didConcludeEditDrag): 131 132 After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI 133 process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not 134 including any selected content. The other snapshot is of the selected content only. However, when dropping 135 images (or a text selection containing images), these images may not yet have been loaded. If that is the case, 136 these images will appear to be missing from these snapshots. 137 138 To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content 139 range have finished loading. We can tell that all dropped images have finished loading by using a new client 140 hook that is invoked when an image has finished loading. 141 142 (WebKit::WebPage::didFinishLoadingImageForElement): 143 (WebKit::WebPage::computeAndSendEditDragSnapshot): 144 145 Snapshot the selected content and send it to the UI process. 146 1 147 2019-05-24 Youenn Fablet <youenn@apple.com> 2 148 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
r245006 r245778 6890 6890 } 6891 6891 6892 - (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action 6893 { 6894 [_contentView _doAfterReceivingEditDragSnapshotForTesting:action]; 6895 } 6896 6892 6897 #endif // PLATFORM(IOS_FAMILY) 6893 6898 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
r245294 r245778 489 489 490 490 @property (nonatomic, readonly) CGRect _dragCaretRect WK_API_AVAILABLE(ios(11.0)); 491 492 - (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action WK_API_AVAILABLE(ios(WK_IOS_TBA)); 491 493 492 494 - (void)_requestActivatedElementAtPosition:(CGPoint)position completionBlock:(void (^)(_WKActivatedElementInfo *))block WK_API_AVAILABLE(ios(11.0)); -
trunk/Source/WebKit/UIProcess/PageClient.h
r245112 r245778 480 480 virtual void didHandleDragStartRequest(bool started) = 0; 481 481 virtual void didHandleAdditionalDragItemsRequest(bool added) = 0; 482 virtual void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>) = 0; 482 virtual void willReceiveEditDragSnapshot() = 0; 483 virtual void didReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData>) = 0; 483 484 virtual void didChangeDragCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) = 0; 484 485 #endif -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r245679 r245778 727 727 void requestDocumentEditingContext(WebKit::DocumentEditingContextRequest, CompletionHandler<void(WebKit::DocumentEditingContext)>&&); 728 728 void generateSyntheticEditingCommand(SyntheticEditingCommandType); 729 #if ENABLE(D ATA_INTERACTION)729 #if ENABLE(DRAG_SUPPORT) 730 730 void didHandleDragStartRequest(bool started); 731 731 void didHandleAdditionalDragItemsRequest(bool added); 732 732 void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions); 733 733 void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions); 734 void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>); 734 void willReceiveEditDragSnapshot(); 735 void didReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData>); 736 void didConcludeDrop(); 735 737 #endif 736 738 #endif // PLATFORM(IOS_FAMILY) -
trunk/Source/WebKit/UIProcess/WebPageProxy.messages.in
r245565 r245778 334 334 DidHandleDragStartRequest(bool started) 335 335 DidHandleAdditionalDragItemsRequest(bool added) 336 DidConcludeEditDrag(Optional<WebCore::TextIndicatorData> textIndicator) 336 WillReceiveEditDragSnapshot() 337 DidReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData> textIndicator) 337 338 #endif 338 339 -
trunk/Source/WebKit/UIProcess/ios/DragDropInteractionState.h
r244955 r245778 41 41 namespace WebCore { 42 42 struct DragItem; 43 struct TextIndicatorData; 43 44 } 44 45 … … 57 58 58 59 NSInteger itemIdentifier { 0 }; 60 }; 61 62 struct ItemAndPreviewProvider { 63 RetainPtr<UIDragItem> item; 64 BlockPtr<void(UITargetedDragPreview *)> provider; 59 65 }; 60 66 … … 93 99 BlockPtr<void(NSArray<UIDragItem *> *)> takeAddDragItemCompletionBlock() { return WTFMove(m_addDragItemCompletionBlock); } 94 100 101 void prepareForDelayedDropPreview(UIDragItem *, void(^provider)(UITargetedDragPreview *preview)); 102 void deliverDelayedDropPreview(UIView *contentView, UIView *previewContainer, const WebCore::TextIndicatorData&); 103 void clearAllDelayedItemPreviewProviders(); 104 95 105 private: 96 106 void updatePreviewsForActiveDragSources(); … … 109 119 Optional<DragSourceState> m_stagedDragSource; 110 120 Vector<DragSourceState> m_activeDragSources; 121 Vector<ItemAndPreviewProvider> m_delayedItemPreviewProviders; 111 122 }; 112 123 -
trunk/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm
r239427 r245778 45 45 } 46 46 47 static UITargetedDragPreview *createTargetedDragPreview(UIImage *image, UIView *rootView, UIView *previewContainer, const FloatRect& frameInRootViewCoordinates, const Vector<FloatRect>& clippingRectsInFrameCoordinates, UIColor *backgroundColor, UIBezierPath *visiblePath)47 static RetainPtr<UITargetedDragPreview> createTargetedDragPreview(UIImage *image, UIView *rootView, UIView *previewContainer, const FloatRect& frameInRootViewCoordinates, const Vector<FloatRect>& clippingRectsInFrameCoordinates, UIColor *backgroundColor, UIBezierPath *visiblePath) 48 48 { 49 49 if (frameInRootViewCoordinates.isEmpty() || !image) … … 79 79 CGPoint centerInContainerCoordinates = { CGRectGetMidX(frameInContainerCoordinates), CGRectGetMidY(frameInContainerCoordinates) }; 80 80 auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:previewContainer center:centerInContainerCoordinates]); 81 auto dragPreview = adoptNS([[UITargetedDragPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:target.get()]); 82 return dragPreview.autorelease(); 81 return adoptNS([[UITargetedDragPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:target.get()]); 83 82 } 84 83 … … 185 184 m_didBeginDragging = true; 186 185 updatePreviewsForActiveDragSources(); 186 } 187 188 void DragDropInteractionState::prepareForDelayedDropPreview(UIDragItem *item, void(^provider)(UITargetedDragPreview *preview)) 189 { 190 m_delayedItemPreviewProviders.append({ item, provider }); 191 } 192 193 void DragDropInteractionState::deliverDelayedDropPreview(UIView *contentView, UIView *previewContainer, const WebCore::TextIndicatorData& indicator) 194 { 195 if (m_delayedItemPreviewProviders.isEmpty()) 196 return; 197 198 auto textIndicatorImage = uiImageForImage(indicator.contentImage.get()); 199 auto preview = createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)], nil); 200 for (auto& itemAndPreviewProvider : m_delayedItemPreviewProviders) 201 itemAndPreviewProvider.provider(preview.get()); 202 m_delayedItemPreviewProviders.clear(); 203 } 204 205 void DragDropInteractionState::clearAllDelayedItemPreviewProviders() 206 { 207 for (auto& itemAndPreviewProvider : m_delayedItemPreviewProviders) 208 itemAndPreviewProvider.provider(nil); 209 m_delayedItemPreviewProviders.clear(); 187 210 } 188 211 … … 198 221 auto path = source.visiblePath.value(); 199 222 UIBezierPath *visiblePath = [UIBezierPath bezierPathWithCGPath:path.ensurePlatformPath()]; 200 return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, visiblePath) ;223 return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, visiblePath).autorelease(); 201 224 } 202 return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, nil) ;225 return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, nil).autorelease(); 203 226 } 204 227 … … 206 229 auto indicator = source.indicatorData.value(); 207 230 auto textIndicatorImage = uiImageForImage(indicator.contentImage.get()); 208 return createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)], nil) ;231 return createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)], nil).autorelease(); 209 232 } 210 233 … … 267 290 void DragDropInteractionState::dragAndDropSessionsDidEnd() 268 291 { 292 clearAllDelayedItemPreviewProviders(); 293 269 294 // If any of UIKit's completion blocks are still in-flight when the drag interaction ends, we need to ensure that they are still invoked 270 295 // to prevent UIKit from getting into an inconsistent state. -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h
r245112 r245778 238 238 void didHandleAdditionalDragItemsRequest(bool added) override; 239 239 void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle& image) override; 240 void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>) override; 240 void willReceiveEditDragSnapshot() override; 241 void didReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData>) override; 241 242 void didChangeDragCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) override; 242 243 #endif -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
r245268 r245778 821 821 } 822 822 823 void PageClientImpl::didConcludeEditDrag(Optional<TextIndicatorData> data) 824 { 825 [m_contentView _didConcludeEditDrag:data]; 823 void PageClientImpl::willReceiveEditDragSnapshot() 824 { 825 [m_contentView _willReceiveEditDragSnapshot]; 826 } 827 828 void PageClientImpl::didReceiveEditDragSnapshot(Optional<TextIndicatorData> data) 829 { 830 [m_contentView _didReceiveEditDragSnapshot:data]; 826 831 } 827 832 -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
r245268 r245778 335 335 336 336 BOOL _focusRequiresStrongPasswordAssistance; 337 BOOL _waitingForEditDragSnapshot; 337 338 338 339 BOOL _hasSetUpInteractions; … … 346 347 RetainPtr<UIDropInteraction> _dropInteraction; 347 348 BOOL _shouldRestoreCalloutBarAfterDrop; 348 BOOL _isAnimatingConcludeEditDrag;349 349 RetainPtr<UIView> _visibleContentViewSnapshot; 350 RetainPtr<UIView> _unselectedContentSnapshot; 350 351 RetainPtr<_UITextDragCaretView> _editDropCaretView; 352 BlockPtr<void()> _actionToPerformAfterReceivingEditDragSnapshot; 351 353 #endif 352 354 … … 491 493 - (void)_didHandleAdditionalDragItemsRequest:(BOOL)added; 492 494 - (void)_startDrag:(RetainPtr<CGImageRef>)image item:(const WebCore::DragItem&)item; 493 - (void)_didConcludeEditDrag:(Optional<WebCore::TextIndicatorData>)data; 495 - (void)_willReceiveEditDragSnapshot; 496 - (void)_didReceiveEditDragSnapshot:(Optional<WebCore::TextIndicatorData>)data; 494 497 - (void)_didChangeDragCaretRect:(CGRect)previousRect currentRect:(CGRect)rect; 495 498 #endif … … 518 521 - (void)setTimePickerValueToHour:(NSInteger)hour minute:(NSInteger)minute; 519 522 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem; 523 - (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action; 520 524 521 525 @property (nonatomic, readonly) NSString *textContentTypeForTesting; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r245691 r245778 842 842 843 843 _focusRequiresStrongPasswordAssistance = NO; 844 _waitingForEditDragSnapshot = NO; 844 845 845 846 #if USE(UIKIT_KEYBOARD_ADDITIONS) … … 6270 6271 - (void)cleanUpDragSourceSessionState 6271 6272 { 6273 if (_waitingForEditDragSnapshot) 6274 return; 6275 6272 6276 if (_dragDropInteractionState.dragSession() || _dragDropInteractionState.isPerformingDrop()) 6273 6277 RELEASE_LOG(DragAndDrop, "Cleaning up dragging state (has pending operation: %d)", [[WebItemProviderPasteboard sharedInstance] hasPendingOperation]); … … 6282 6286 [self _restoreCalloutBarIfNeeded]; 6283 6287 6284 [_visibleContentViewSnapshot removeFromSuperview]; 6285 _visibleContentViewSnapshot = nil; 6288 [std::exchange(_visibleContentViewSnapshot, nil) removeFromSuperview]; 6286 6289 [_editDropCaretView remove]; 6287 6290 _editDropCaretView = nil; 6288 _isAnimatingConcludeEditDrag = NO;6289 6291 _shouldRestoreCalloutBarAfterDrop = NO; 6290 6292 … … 6308 6310 } 6309 6311 6310 - (void)_didConcludeEditDrag:(Optional<WebCore::TextIndicatorData>)data 6311 { 6312 - (void)_willReceiveEditDragSnapshot 6313 { 6314 _waitingForEditDragSnapshot = YES; 6315 } 6316 6317 - (void)_didReceiveEditDragSnapshot:(Optional<WebCore::TextIndicatorData>)data 6318 { 6319 _waitingForEditDragSnapshot = NO; 6320 6321 [self _deliverDelayedDropPreviewIfPossible:data]; 6322 [self cleanUpDragSourceSessionState]; 6323 6324 if (auto action = WTFMove(_actionToPerformAfterReceivingEditDragSnapshot)) 6325 action(); 6326 } 6327 6328 - (void)_deliverDelayedDropPreviewIfPossible:(Optional<WebCore::TextIndicatorData>)data 6329 { 6330 if (!_visibleContentViewSnapshot) 6331 return; 6332 6312 6333 if (!data) 6334 return; 6335 6336 if (!data->contentImage) 6313 6337 return; 6314 6338 … … 6322 6346 6323 6347 auto unselectedContentImageForEditDrag = adoptNS([[UIImage alloc] initWithCGImage:unselectedSnapshotImage.get() scale:_page->deviceScaleFactor() orientation:UIImageOrientationUp]); 6324 auto unselectedContentSnapshot = adoptNS([[UIImageView alloc] initWithImage:unselectedContentImageForEditDrag.get()]); 6325 [unselectedContentSnapshot setFrame:data->contentImageWithoutSelectionRectInRootViewCoordinates]; 6326 6327 auto protectedSelf = retainPtr(self); 6328 auto visibleContentViewSnapshot = adoptNS(_visibleContentViewSnapshot.leakRef()); 6329 6330 _isAnimatingConcludeEditDrag = YES; 6331 [self insertSubview:unselectedContentSnapshot.get() belowSubview:visibleContentViewSnapshot.get()]; 6332 [UIView animateWithDuration:0.25 animations:^() { 6333 [visibleContentViewSnapshot setAlpha:0]; 6334 } completion:^(BOOL completed) { 6335 [visibleContentViewSnapshot removeFromSuperview]; 6336 [UIView animateWithDuration:0.25 animations:^() { 6337 [protectedSelf _stopSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning]; 6338 [unselectedContentSnapshot setAlpha:0]; 6339 } completion:^(BOOL completed) { 6340 [unselectedContentSnapshot removeFromSuperview]; 6341 }]; 6342 }]; 6348 _unselectedContentSnapshot = adoptNS([[UIImageView alloc] initWithImage:unselectedContentImageForEditDrag.get()]); 6349 [_unselectedContentSnapshot setFrame:data->contentImageWithoutSelectionRectInRootViewCoordinates]; 6350 6351 [self insertSubview:_unselectedContentSnapshot.get() belowSubview:_visibleContentViewSnapshot.get()]; 6352 _dragDropInteractionState.deliverDelayedDropPreview(self, self.unscaledView, data.value()); 6343 6353 } 6344 6354 … … 6350 6360 if ([self.webViewUIDelegate respondsToSelector:@selector(_webView:dataInteractionOperationWasHandled:forSession:itemProviders:)]) 6351 6361 [self.webViewUIDelegate _webView:_webView dataInteractionOperationWasHandled:handled forSession:dropSession itemProviders:[WebItemProviderPasteboard sharedInstance].itemProviders]; 6352 6353 if (!_isAnimatingConcludeEditDrag)6354 [self _stopSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning];6355 6362 6356 6363 CGPoint global; … … 6510 6517 } 6511 6518 6519 - (UIView *)textEffectsWindow 6520 { 6521 #if HAVE(UISCENE) 6522 return [UITextEffectsWindow sharedTextEffectsWindowForWindowScene:self.window.windowScene]; 6523 #else 6524 return [UITextEffectsWindow sharedTextEffectsWindow]; 6525 #endif 6526 } 6527 6512 6528 - (NSDictionary *)_autofillContext 6513 6529 { … … 6891 6907 } 6892 6908 6909 - (void)dropInteraction:(UIDropInteraction *)interaction item:(UIDragItem *)item willAnimateDropWithAnimator:(id <UIDragAnimating>)animator 6910 { 6911 [animator addCompletion:[strongSelf = retainPtr(self)] (UIViewAnimatingPosition) { 6912 [std::exchange(strongSelf->_unselectedContentSnapshot, nil) removeFromSuperview]; 6913 }]; 6914 } 6915 6916 - (void)dropInteraction:(UIDropInteraction *)interaction concludeDrop:(id <UIDropSession>)session 6917 { 6918 [self _stopSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning]; 6919 [std::exchange(_visibleContentViewSnapshot, nil) removeFromSuperview]; 6920 [std::exchange(_unselectedContentSnapshot, nil) removeFromSuperview]; 6921 _dragDropInteractionState.clearAllDelayedItemPreviewProviders(); 6922 _page->didConcludeDrop(); 6923 } 6924 6893 6925 - (UITargetedDragPreview *)dropInteraction:(UIDropInteraction *)interaction previewForDroppingItem:(UIDragItem *)item withDefault:(UITargetedDragPreview *)defaultPreview 6894 6926 { … … 6897 6929 return nil; 6898 6930 6899 ALLOW_DEPRECATED_DECLARATIONS_BEGIN 6900 // FIXME: <rdar://problem/31074376> [WK2] Performing an edit drag should transition from the initial drag preview to the final drop preview 6901 // This is blocked on UIKit support, since we aren't able to update the text clipping rects of a UITargetedDragPreview mid-flight. For now, 6902 // just zoom to the center of the caret rect while shrinking the drop preview. 6903 auto caretRectInWindowCoordinates = [self convertRect:caretRect toView:[UITextEffectsWindow sharedTextEffectsWindow]]; 6931 UIView *textEffectsWindow = self.textEffectsWindow; 6932 auto caretRectInWindowCoordinates = [self convertRect:caretRect toView:textEffectsWindow]; 6904 6933 auto caretCenterInWindowCoordinates = CGPointMake(CGRectGetMidX(caretRectInWindowCoordinates), CGRectGetMidY(caretRectInWindowCoordinates)); 6905 auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:[UITextEffectsWindow sharedTextEffectsWindow] center:caretCenterInWindowCoordinates transform:CGAffineTransformMakeScale(0, 0)]);6906 ALLOW_DEPRECATED_DECLARATIONS_END 6934 auto targetPreviewCenterInWindowCoordinates = CGPointMake(caretCenterInWindowCoordinates.x + defaultPreview.size.width / 2, caretCenterInWindowCoordinates.y + defaultPreview.size.height / 2); 6935 auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:textEffectsWindow center:targetPreviewCenterInWindowCoordinates transform:CGAffineTransformIdentity]); 6907 6936 return [defaultPreview retargetedPreviewWithTarget:target.get()]; 6937 } 6938 6939 - (void)_dropInteraction:(UIDropInteraction *)interaction delayedPreviewProviderForDroppingItem:(UIDragItem *)item previewProvider:(void(^)(UITargetedDragPreview *preview))previewProvider 6940 { 6941 // FIXME: This doesn't currently handle multiple items in a drop session. 6942 _dragDropInteractionState.prepareForDelayedDropPreview(item, previewProvider); 6908 6943 } 6909 6944 … … 7166 7201 7167 7202 @implementation WKContentView (WKTesting) 7203 7204 - (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action 7205 { 7206 #if ENABLE(DRAG_SUPPORT) 7207 ASSERT(!_actionToPerformAfterReceivingEditDragSnapshot); 7208 if (_waitingForEditDragSnapshot) { 7209 _actionToPerformAfterReceivingEditDragSnapshot = action; 7210 return; 7211 } 7212 #endif 7213 action(); 7214 } 7168 7215 7169 7216 - (WKFormInputControl *)formInputControl -
trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
r245679 r245778 1220 1220 } 1221 1221 1222 void WebPageProxy::didConcludeEditDrag(Optional<TextIndicatorData> data) 1223 { 1224 pageClient().didConcludeEditDrag(data); 1222 void WebPageProxy::willReceiveEditDragSnapshot() 1223 { 1224 pageClient().willReceiveEditDragSnapshot(); 1225 } 1226 1227 void WebPageProxy::didReceiveEditDragSnapshot(Optional<TextIndicatorData> data) 1228 { 1229 pageClient().didReceiveEditDragSnapshot(data); 1230 } 1231 1232 void WebPageProxy::didConcludeDrop() 1233 { 1234 m_process->send(Messages::WebPage::DidConcludeDrop(), m_pageID); 1225 1235 } 1226 1236 -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
r245540 r245778 588 588 } 589 589 590 void WebChromeClient::didFinishLoadingImageForElement(HTMLImageElement& element) 591 { 592 m_page.didFinishLoadingImageForElement(element); 593 } 594 590 595 PlatformPageClient WebChromeClient::platformPageClient() const 591 596 { -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
r245366 r245778 30 30 31 31 namespace WebCore { 32 class HTMLImageElement; 32 33 class RegistrableDomain; 33 34 enum class StorageAccessPromptWasShown : bool; … … 121 122 WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const final; 122 123 WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const final; 124 125 void didFinishLoadingImageForElement(WebCore::HTMLImageElement&) final; 123 126 124 127 PlatformPageClient platformPageClient() const final; -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r245716 r245778 6741 6741 #endif 6742 6742 6743 #if !PLATFORM(IOS_FAMILY) || !ENABLE(DRAG_SUPPORT) 6744 6745 void WebPage::didFinishLoadingImageForElement(WebCore::HTMLImageElement&) 6746 { 6747 } 6748 6749 #endif 6750 6743 6751 } // namespace WebKit 6744 6752 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r245679 r245778 155 155 class FrameView; 156 156 class GraphicsContext; 157 class HTMLImageElement; 157 158 class HTMLMenuElement; 158 159 class HTMLMenuItemElement; … … 1114 1115 void setUseIconLoadingClient(bool); 1115 1116 1116 #if ENABLE(DATA_INTERACTION)1117 #if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT) 1117 1118 void didConcludeEditDrag(); 1118 #endif 1119 void didConcludeDrop(); 1120 #endif 1121 1122 void didFinishLoadingImageForElement(WebCore::HTMLImageElement&); 1119 1123 1120 1124 WebURLSchemeHandlerProxy* urlSchemeHandlerForScheme(const String&); … … 1259 1263 void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t allowedActions); 1260 1264 void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t allowedActions); 1265 void computeAndSendEditDragSnapshot(); 1261 1266 #endif 1262 1267 … … 1769 1774 bool m_isStartingDrag { false }; 1770 1775 WebCore::DragSourceAction m_allowedDragSourceActions { WebCore::DragSourceActionAny }; 1776 #endif 1777 1778 #if ENABLE(DRAG_SUPPORT) && PLATFORM(IOS_FAMILY) 1779 HashSet<RefPtr<WebCore::HTMLImageElement>> m_pendingImageElementsForDropSnapshot; 1771 1780 #endif 1772 1781 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
r245678 r245778 304 304 #endif 305 305 306 #if ENABLE(DATA_INTERACTION)306 #if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT) 307 307 RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t allowedActions) 308 308 RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t allowedActions) 309 DidConcludeDrop() 309 310 #endif 310 311 -
trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
r245716 r245778 826 826 } 827 827 828 void WebPage::didConcludeDrop() 829 { 830 m_pendingImageElementsForDropSnapshot.clear(); 831 } 832 828 833 void WebPage::didConcludeEditDrag() 829 834 { 835 send(Messages::WebPageProxy::WillReceiveEditDragSnapshot()); 836 837 layoutIfNeeded(); 838 839 m_pendingImageElementsForDropSnapshot.clear(); 840 841 bool waitingForAnyImageToLoad = false; 842 auto& frame = m_page->focusController().focusedOrMainFrame(); 843 if (auto range = frame.selection().selection().toNormalizedRange()) { 844 for (TextIterator iterator(range.get()); !iterator.atEnd(); iterator.advance()) { 845 auto* node = iterator.node(); 846 if (!is<HTMLImageElement>(node)) 847 continue; 848 849 auto& imageElement = downcast<HTMLImageElement>(*node); 850 auto* cachedImage = imageElement.cachedImage(); 851 if (cachedImage && cachedImage->image() && cachedImage->image()->isNull()) { 852 m_pendingImageElementsForDropSnapshot.add(&imageElement); 853 waitingForAnyImageToLoad = true; 854 } 855 } 856 } 857 858 if (!waitingForAnyImageToLoad) 859 computeAndSendEditDragSnapshot(); 860 } 861 862 void WebPage::didFinishLoadingImageForElement(WebCore::HTMLImageElement& element) 863 { 864 if (m_pendingImageElementsForDropSnapshot.isEmpty()) 865 return; 866 867 m_pendingImageElementsForDropSnapshot.remove(&element); 868 869 if (m_pendingImageElementsForDropSnapshot.isEmpty()) 870 computeAndSendEditDragSnapshot(); 871 } 872 873 void WebPage::computeAndSendEditDragSnapshot() 874 { 830 875 Optional<TextIndicatorData> textIndicatorData; 831 832 876 static auto defaultTextIndicatorOptionsForEditDrag = TextIndicatorOptionIncludeSnapshotOfAllVisibleContentWithoutSelection | TextIndicatorOptionExpandClipBeyondVisibleRect | TextIndicatorOptionPaintAllContent | TextIndicatorOptionIncludeMarginIfRangeMatchesSelection | TextIndicatorOptionPaintBackgrounds | TextIndicatorOptionComputeEstimatedBackgroundColor| TextIndicatorOptionUseSelectionRectForSizing | TextIndicatorOptionIncludeSnapshotWithSelectionHighlight; 833 877 auto& frame = m_page->focusController().focusedOrMainFrame(); 834 878 if (auto range = frame.selection().selection().toNormalizedRange()) { 835 if (auto textIndicator = TextIndicator::createWithRange(*range, defaultTextIndicatorOptionsForEditDrag, TextIndicatorPresentationTransition::None, FloatSize()))879 if (auto textIndicator = TextIndicator::createWithRange(*range, defaultTextIndicatorOptionsForEditDrag, TextIndicatorPresentationTransition::None, { })) 836 880 textIndicatorData = textIndicator->data(); 837 881 } 838 839 send(Messages::WebPageProxy::DidConcludeEditDrag(WTFMove(textIndicatorData))); 840 } 882 send(Messages::WebPageProxy::DidReceiveEditDragSnapshot(WTFMove(textIndicatorData))); 883 } 884 841 885 #endif 842 886 -
trunk/Source/WebKitLegacy/mac/ChangeLog
r245596 r245778 1 2019-05-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Dropped text, attachments, and images should animate into place 4 https://bugs.webkit.org/show_bug.cgi?id=198243 5 <rdar://problem/35205373> 6 7 Reviewed by Tim Horton. 8 9 Add a new chrome client method. See other changelogs for more detail. 10 11 * WebCoreSupport/WebChromeClient.h: 12 * WebCoreSupport/WebChromeClient.mm: 13 (WebChromeClient::didFinishLoadingImageForElement): 14 1 15 2019-05-21 Alex Christensen <achristensen@webkit.org> 2 16 -
trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h
r244633 r245778 32 32 #import <wtf/Forward.h> 33 33 34 namespace WebCore { 35 class HTMLImageElement; 36 } 37 34 38 @class WebView; 35 39 … … 102 106 WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const final; 103 107 WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const final; 108 109 void didFinishLoadingImageForElement(WebCore::HTMLImageElement&) final; 104 110 105 111 PlatformPageClient platformPageClient() const final; -
trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm
r244440 r245778 611 611 } 612 612 613 void WebChromeClient::didFinishLoadingImageForElement(HTMLImageElement&) 614 { 615 } 616 613 617 PlatformPageClient WebChromeClient::platformPageClient() const 614 618 { -
trunk/Source/WebKitLegacy/win/ChangeLog
r244932 r245778 1 2019-05-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Dropped text, attachments, and images should animate into place 4 https://bugs.webkit.org/show_bug.cgi?id=198243 5 <rdar://problem/35205373> 6 7 Reviewed by Tim Horton. 8 9 * WebCoreSupport/WebChromeClient.cpp: 10 (WebChromeClient::didFinishLoadingImageForElement): 11 * WebCoreSupport/WebChromeClient.h: 12 1 13 2019-05-03 Daniel Bates <dabates@apple.com> 2 14 -
trunk/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.cpp
r244633 r245778 704 704 } 705 705 706 void WebChromeClient::didFinishLoadingImageForElement(WebCore::HTMLImageElement&) 707 { 708 } 709 706 710 void WebChromeClient::setCursor(const Cursor& cursor) 707 711 { -
trunk/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.h
r244633 r245778 173 173 RefPtr<WebCore::Icon> createIconForFiles(const Vector<String>&) final; 174 174 175 void didFinishLoadingImageForElement(WebCore::HTMLImageElement&) final; 176 175 177 private: 176 178 COMPtr<IWebUIDelegate> uiDelegate(); -
trunk/Tools/ChangeLog
r245777 r245778 1 2019-05-26 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 [iOS] Dropped text, attachments, and images should animate into place 4 https://bugs.webkit.org/show_bug.cgi?id=198243 5 <rdar://problem/35205373> 6 7 Reviewed by Tim Horton. 8 9 Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail. 10 11 * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm: 12 (TestWebKitAPI::isCompletelyWhite): 13 (TestWebKitAPI::TEST): 14 15 Add a test that drags and drops an image into a contenteditable element, and then observes the resulting 16 UITargetedDragPreviews upon drop. 17 18 * TestWebKitAPI/cocoa/DragAndDropSimulator.h: 19 * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm: 20 (-[DragAndDropSimulator _resetSimulatedState]): 21 (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]): 22 (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]): 23 24 Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction 25 delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer 26 the end of the simulated drag and drop until after drag previews have been received during an edit drag. 27 28 (-[DragAndDropSimulator dropPreviews]): 29 (-[DragAndDropSimulator delayedDropPreviews]): 30 31 Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which 32 previews were provided asynchronously. 33 34 (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]): 35 * TestWebKitAPI/ios/UIKitSPI.h: 36 37 Stage the new private drop interacton delegate method. 38 1 39 2019-05-25 Simon Fraser <simon.fraser@apple.com> 2 40 -
trunk/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm
r244955 r245778 2108 2108 } 2109 2109 2110 static BOOL isCompletelyWhite(UIImage *image) 2111 { 2112 auto data = adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage))); 2113 auto* dataPtr = CFDataGetBytePtr(data.get()); 2114 int imageWidth = image.size.width; 2115 for (int row = 0; row < image.size.height; ++row) { 2116 for (int column = 0; column < imageWidth; ++column) { 2117 int pixelOffset = ((imageWidth * row) + column) * 4; 2118 if (dataPtr[pixelOffset] != 0xFF || dataPtr[pixelOffset + 1] != 0xFF || dataPtr[pixelOffset + 2] != 0xFF) 2119 return NO; 2120 } 2121 } 2122 return YES; 2123 } 2124 2125 TEST(DragAndDropTests, DropPreviewForImageInEditableArea) 2126 { 2127 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); 2128 [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"]; 2129 2130 // Ensure that the resulting snapshot on drop contains only the dragged image. 2131 [webView stringByEvaluatingJavaScript:@"editor.style.border = 'none'; editor.style.outline = 'none'"]; 2132 2133 auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]); 2134 [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)]; 2135 2136 NSArray *dropPreviews = [simulator dropPreviews]; 2137 NSArray *delayedDropPreviews = [simulator delayedDropPreviews]; 2138 EXPECT_EQ(1U, dropPreviews.count); 2139 EXPECT_EQ(1U, delayedDropPreviews.count); 2140 EXPECT_EQ(UITargetedDragPreview.class, [dropPreviews.firstObject class]); 2141 EXPECT_EQ(UITargetedDragPreview.class, [delayedDropPreviews.firstObject class]); 2142 2143 UITargetedDragPreview *finalPreview = (UITargetedDragPreview *)delayedDropPreviews.firstObject; 2144 EXPECT_EQ(UIImageView.class, finalPreview.view.class); 2145 EXPECT_FALSE(isCompletelyWhite([(UIImageView *)finalPreview.view image])); 2146 } 2147 2110 2148 } // namespace TestWebKitAPI 2111 2149 -
trunk/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h
r244955 r245778 112 112 @property (nonatomic, readonly) CGRect lastKnownDragCaretRect; 113 113 @property (nonatomic, readonly) NSArray<UITargetedDragPreview *> *liftPreviews; 114 @property (nonatomic, readonly) NSArray *dropPreviews; 115 @property (nonatomic, readonly) NSArray *delayedDropPreviews; 114 116 @property (nonatomic, readonly) BOOL suppressedSelectionCommandsDuringDrop; 115 117 -
trunk/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm
r244955 r245778 35 35 #import <UIKit/UIDragInteraction.h> 36 36 #import <UIKit/UIDragItem.h> 37 #import <UIKit/UIDropInteraction.h> 37 38 #import <UIKit/UIInteraction.h> 38 39 #import <WebKit/WKWebViewPrivate.h> … … 311 312 RetainPtr<NSMutableArray<NSValue *>>_queuedAdditionalItemRequestLocations; 312 313 RetainPtr<NSMutableArray<UITargetedDragPreview *>> _liftPreviews; 314 RetainPtr<NSMutableArray> _dropPreviews; 315 RetainPtr<NSMutableArray> _delayedDropPreviews; 313 316 314 317 RetainPtr<NSMutableArray<_WKAttachment *>> _insertedAttachments; … … 318 321 double _currentProgress; 319 322 bool _isDoneWithCurrentRun; 323 bool _isDoneWaitingForDelayedDropPreviews; 320 324 DragAndDropPhase _phase; 321 325 … … 374 378 _currentProgress = 0; 375 379 _isDoneWithCurrentRun = false; 380 _isDoneWaitingForDelayedDropPreviews = true; 376 381 _observedEventNames = adoptNS([[NSMutableArray alloc] init]); 377 382 _insertedAttachments = adoptNS([[NSMutableArray alloc] init]); … … 385 390 _queuedAdditionalItemRequestLocations = adoptNS([[NSMutableArray alloc] init]); 386 391 _liftPreviews = adoptNS([[NSMutableArray alloc] init]); 392 _dropPreviews = adoptNS([[NSMutableArray alloc] init]); 393 _delayedDropPreviews = adoptNS([[NSMutableArray alloc] init]); 387 394 _hasStartedInputSession = false; 388 395 } … … 455 462 456 463 Util::run(&_isDoneWithCurrentRun); 464 Util::run(&_isDoneWaitingForDelayedDropPreviews); 457 465 [_webView clearMessageHandlers:dragAndDropEventNames()]; 458 466 _finalSelectionRects = [_webView selectionRectsAfterPresentationUpdate]; … … 471 479 auto operation = [_lastKnownDropProposal operation]; 472 480 if (operation != UIDropOperationCancel && operation != UIDropOperationForbidden) { 481 NSInteger dropPreviewIndex = 0; 482 __block NSUInteger numberOfPendingPreviews = [_dropSession items].count; 483 _isDoneWaitingForDelayedDropPreviews = !numberOfPendingPreviews; 484 for (UIDragItem *item in [_dropSession items]) { 485 auto defaultPreview = adoptNS([[UITargetedDragPreview alloc] initWithView:_webView.get()]); 486 id <UIDropInteractionDelegate_Staging_31075005> delegate = (id <UIDropInteractionDelegate_Staging_31075005>)[_webView dropInteractionDelegate]; 487 UIDropInteraction *interaction = [_webView dropInteraction]; 488 [_dropPreviews addObject:[delegate dropInteraction:interaction previewForDroppingItem:item withDefault:defaultPreview.get()] ?: NSNull.null]; 489 [_delayedDropPreviews addObject:NSNull.null]; 490 [delegate _dropInteraction:interaction delayedPreviewProviderForDroppingItem:item previewProvider:^(UITargetedDragPreview *preview) { 491 if (preview) 492 [_delayedDropPreviews setObject:preview atIndexedSubscript:dropPreviewIndex]; 493 494 if (!--numberOfPendingPreviews) 495 _isDoneWaitingForDelayedDropPreviews = true; 496 }]; 497 ++dropPreviewIndex; 498 } 473 499 [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] performDrop:_dropSession.get()]; 474 500 _phase = DragAndDropPhasePerformingDrop; 475 501 } else { 476 _isDoneWithCurrentRun = YES;502 _isDoneWithCurrentRun = true; 477 503 _phase = DragAndDropPhaseCancelled; 504 [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] concludeDrop:_dropSession.get()]; 478 505 } 479 506 … … 645 672 } 646 673 674 - (NSArray<UITargetedDragPreview *> *)dropPreviews 675 { 676 return _dropPreviews.get(); 677 } 678 679 - (NSArray<UITargetedDragPreview *> *)delayedDropPreviews 680 { 681 return _delayedDropPreviews.get(); 682 } 683 647 684 - (CGRect)lastKnownDragCaretRect 648 685 { … … 730 767 { 731 768 _suppressedSelectionCommandsDuringDrop = [_webView textInputContentView]._shouldSuppressSelectionCommands; 732 _isDoneWithCurrentRun = true;733 769 734 770 if (self.dropCompletionBlock) 735 771 self.dropCompletionBlock(handled, itemProviders); 772 773 [_webView _doAfterReceivingEditDragSnapshotForTesting:^{ 774 [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] concludeDrop:_dropSession.get()]; 775 _isDoneWithCurrentRun = true; 776 }]; 736 777 } 737 778 -
trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h
r244955 r245778 184 184 @end 185 185 186 #if PLATFORM(IOS) 187 188 @protocol UIDropInteractionDelegate_Staging_31075005 <UIDropInteractionDelegate> 189 - (void)_dropInteraction:(UIDropInteraction *)interaction delayedPreviewProviderForDroppingItem:(UIDragItem *)item previewProvider:(void(^)(UITargetedDragPreview *preview))previewProvider; 190 @end 191 192 #endif // PLATFORM(IOS) 193 186 194 #endif // PLATFORM(IOS_FAMILY)
Note: See TracChangeset
for help on using the changeset viewer.