<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[245781] branches/safari-608.1.24.20-branch</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/245781">245781</a></dd>
<dt>Author</dt> <dd>bshafiei@apple.com</dd>
<dt>Date</dt> <dd>2019-05-26 11:21:55 -0700 (Sun, 26 May 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Cherry-pick <a href="http://trac.webkit.org/projects/webkit/changeset/245778">r245778</a>. rdar://problem/35205373

    [iOS] Dropped text, attachments, and images should animate into place
    https://bugs.webkit.org/show_bug.cgi?id=198243
    <rdar://problem/35205373>

    Reviewed by Tim Horton.

    Source/WebCore:

    Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit
    changelog for more detail.

    Test: DragAndDropTests.DropPreviewForImageInEditableArea

    * loader/EmptyClients.h:
    * page/ChromeClient.h:
    * page/Page.cpp:
    (WebCore::Page::didFinishLoadingImageForElement):
    * page/Page.h:
    * rendering/RenderImage.cpp:
    (WebCore::RenderImage::notifyFinished):

    Source/WebKit:

    Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in
    <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor
    and augment existing logic for taking snapshots after performing a drop in an editable content.

    Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web
    view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of
    the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade
    from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop
    preview to the drag caret rect. During this process, snapshot (2) is completely ignored.

    This was effectively a halfway implemention of the desired effect of animating the dropped content into place
    and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation
    was not possible in modern WebKit (without using synchronous IPC).

    Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot
    (2) above and clean up some parts of the drop animation in editable content. See below for more details.

    * UIProcess/API/Cocoa/WKWebView.mm:
    (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]):

    Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See
    TestWebKitAPI changes for more detail.

    * UIProcess/API/Cocoa/WKWebViewPrivate.h:
    * UIProcess/PageClient.h:
    * UIProcess/WebPageProxy.h:
    * UIProcess/WebPageProxy.messages.in:

    Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and
    DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop,
    until after the final edit drag snapshot has been received.

    * UIProcess/ios/DragDropInteractionState.h:

    Add some new methods to help manage the lifecycle of drop preview provider blocks.

    * UIProcess/ios/DragDropInteractionState.mm:
    (WebKit::createTargetedDragPreview):

    Drive-by fix: make this return a RetainPtr.

    (WebKit::DragDropInteractionState::prepareForDelayedDropPreview):

    Stores a drop preview provider, given to us by UIKit.

    (WebKit::DragDropInteractionState::deliverDelayedDropPreview):

    Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are
    taken following an edit drag (this is additionally after all images in the inserted fragment have finished
    loading).

    (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders):

    Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session
    cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers
    are always invoked when cleaning up the drag session.

    (WebKit::DragDropInteractionState::previewForDragItem const):
    (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):

    Call clearAllDelayedItemPreviewProviders.

    * UIProcess/ios/PageClientImplIOS.h:
    * UIProcess/ios/PageClientImplIOS.mm:
    (WebKit::PageClientImpl::willReceiveEditDragSnapshot):
    (WebKit::PageClientImpl::didReceiveEditDragSnapshot):
    (WebKit::PageClientImpl::didConcludeEditDrag): Deleted.

    More plumbing (see changes to DidConcludeEditDrag above).

    * UIProcess/ios/WKContentViewInteraction.h:
    * UIProcess/ios/WKContentViewInteraction.mm:
    (-[WKContentView cleanupInteraction]):
    (-[WKContentView cleanUpDragSourceSessionState]):
    (-[WKContentView _willReceiveEditDragSnapshot]):
    (-[WKContentView _didReceiveEditDragSnapshot:]):

    Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and
    when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of
    -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is
    received.

    (-[WKContentView _deliverDelayedDropPreviewIfPossible:]):
    (-[WKContentView _didPerformDragOperation:]):
    (-[WKContentView textEffectsWindow]):

    Drive-by fix to remove a workaround for a deprecation warning.

    (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]):
    (-[WKContentView dropInteraction:concludeDrop:]):

    Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are
    guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives
    after the drop is concluded.

    (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
    (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]):

    Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time
    to update the drop preview. We do this in _didReceiveEditDragSnapshot.

    (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]):
    (-[WKContentView _didConcludeEditDrag:]): Deleted.
    * UIProcess/ios/WebPageProxyIOS.mm:
    (WebKit::WebPageProxy::willReceiveEditDragSnapshot):
    (WebKit::WebPageProxy::didReceiveEditDragSnapshot):
    (WebKit::WebPageProxy::didConcludeDrop):
    (WebKit::WebPageProxy::didConcludeEditDrag): Deleted.
    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
    (WebKit::WebChromeClient::didFinishLoadingImageForElement):
    * WebProcess/WebCoreSupport/WebChromeClient.h:
    * WebProcess/WebPage/WebPage.cpp:
    (WebKit::WebPage::didFinishLoadingImageForElement):
    * WebProcess/WebPage/WebPage.h:
    * WebProcess/WebPage/WebPage.messages.in:
    * WebProcess/WebPage/ios/WebPageIOS.mm:
    (WebKit::WebPage::didConcludeDrop):

    If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear
    out the set here.

    (WebKit::WebPage::didConcludeEditDrag):

    After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI
    process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not
    including any selected content. The other snapshot is of the selected content only. However, when dropping
    images (or a text selection containing images), these images may not yet have been loaded. If that is the case,
    these images will appear to be missing from these snapshots.

    To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content
    range have finished loading. We can tell that all dropped images have finished loading by using a new client
    hook that is invoked when an image has finished loading.

    (WebKit::WebPage::didFinishLoadingImageForElement):
    (WebKit::WebPage::computeAndSendEditDragSnapshot):

    Snapshot the selected content and send it to the UI process.

    Source/WebKitLegacy/mac:

    Add a new chrome client method. See other changelogs for more detail.

    * WebCoreSupport/WebChromeClient.h:
    * WebCoreSupport/WebChromeClient.mm:
    (WebChromeClient::didFinishLoadingImageForElement):

    Source/WebKitLegacy/win:

    * WebCoreSupport/WebChromeClient.cpp:
    (WebChromeClient::didFinishLoadingImageForElement):
    * WebCoreSupport/WebChromeClient.h:

    Tools:

    Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail.

    * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
    (TestWebKitAPI::isCompletelyWhite):
    (TestWebKitAPI::TEST):

    Add a test that drags and drops an image into a contenteditable element, and then observes the resulting
    UITargetedDragPreviews upon drop.

    * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
    * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
    (-[DragAndDropSimulator _resetSimulatedState]):
    (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
    (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]):

    Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction
    delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer
    the end of the simulated drag and drop until after drag previews have been received during an edit drag.

    (-[DragAndDropSimulator dropPreviews]):
    (-[DragAndDropSimulator delayedDropPreviews]):

    Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which
    previews were provided asynchronously.

    (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
    * TestWebKitAPI/ios/UIKitSPI.h:

    Stage the new private drop interacton delegate method.

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245778 268f45cc-cd09-0410-ab3c-d52691b4dbfc</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari60812420branchSourceWebCoreChangeLog">branches/safari-608.1.24.20-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari60812420branchSourceWebCoreloaderEmptyClientsh">branches/safari-608.1.24.20-branch/Source/WebCore/loader/EmptyClients.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebCorepageChromeClienth">branches/safari-608.1.24.20-branch/Source/WebCore/page/ChromeClient.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebCorepagePagecpp">branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.cpp</a></li>
<li><a href="#branchessafari60812420branchSourceWebCorepagePageh">branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebCorerenderingRenderImagecpp">branches/safari-608.1.24.20-branch/Source/WebCore/rendering/RenderImage.cpp</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitChangeLog">branches/safari-608.1.24.20-branch/Source/WebKit/ChangeLog</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessAPICocoaWKWebViewmm">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessAPICocoaWKWebViewPrivateh">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessPageClienth">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/PageClient.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessWebPageProxyh">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessWebPageProxymessagesin">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessiosDragDropInteractionStateh">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessiosDragDropInteractionStatemm">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessiosPageClientImplIOSh">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessiosPageClientImplIOSmm">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessiosWKContentViewInteractionh">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessiosWKContentViewInteractionmm">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitUIProcessiosWebPageProxyIOSmm">branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitWebProcessWebCoreSupportWebChromeClientcpp">branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitWebProcessWebCoreSupportWebChromeClienth">branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitWebProcessWebPageWebPagecpp">branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitWebProcessWebPageWebPageh">branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitWebProcessWebPageWebPagemessagesin">branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitWebProcessWebPageiosWebPageIOSmm">branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitLegacymacChangeLog">branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/ChangeLog</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitLegacymacWebCoreSupportWebChromeClienth">branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitLegacymacWebCoreSupportWebChromeClientmm">branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitLegacywinChangeLog">branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/ChangeLog</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitLegacywinWebCoreSupportWebChromeClientcpp">branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.cpp</a></li>
<li><a href="#branchessafari60812420branchSourceWebKitLegacywinWebCoreSupportWebChromeClienth">branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.h</a></li>
<li><a href="#branchessafari60812420branchToolsChangeLog">branches/safari-608.1.24.20-branch/Tools/ChangeLog</a></li>
<li><a href="#branchessafari60812420branchToolsTestWebKitAPITestsiosDragAndDropTestsIOSmm">branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm</a></li>
<li><a href="#branchessafari60812420branchToolsTestWebKitAPIcocoaDragAndDropSimulatorh">branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h</a></li>
<li><a href="#branchessafari60812420branchToolsTestWebKitAPIiosDragAndDropSimulatorIOSmm">branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm</a></li>
<li><a href="#branchessafari60812420branchToolsTestWebKitAPIiosUIKitSPIh">branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/UIKitSPI.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari60812420branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebCore/ChangeLog (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebCore/ChangeLog      2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebCore/ChangeLog 2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -1,5 +1,239 @@
</span><span class="cx"> 2019-05-26  Babak Shafiei  <bshafiei@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r245778. rdar://problem/35205373
+
+    [iOS] Dropped text, attachments, and images should animate into place
+    https://bugs.webkit.org/show_bug.cgi?id=198243
+    <rdar://problem/35205373>
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebCore:
+    
+    Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit
+    changelog for more detail.
+    
+    Test: DragAndDropTests.DropPreviewForImageInEditableArea
+    
+    * loader/EmptyClients.h:
+    * page/ChromeClient.h:
+    * page/Page.cpp:
+    (WebCore::Page::didFinishLoadingImageForElement):
+    * page/Page.h:
+    * rendering/RenderImage.cpp:
+    (WebCore::RenderImage::notifyFinished):
+    
+    Source/WebKit:
+    
+    Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in
+    <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor
+    and augment existing logic for taking snapshots after performing a drop in an editable content.
+    
+    Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web
+    view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of
+    the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade
+    from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop
+    preview to the drag caret rect. During this process, snapshot (2) is completely ignored.
+    
+    This was effectively a halfway implemention of the desired effect of animating the dropped content into place
+    and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation
+    was not possible in modern WebKit (without using synchronous IPC).
+    
+    Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot
+    (2) above and clean up some parts of the drop animation in editable content. See below for more details.
+    
+    * UIProcess/API/Cocoa/WKWebView.mm:
+    (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]):
+    
+    Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See
+    TestWebKitAPI changes for more detail.
+    
+    * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and
+    DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop,
+    until after the final edit drag snapshot has been received.
+    
+    * UIProcess/ios/DragDropInteractionState.h:
+    
+    Add some new methods to help manage the lifecycle of drop preview provider blocks.
+    
+    * UIProcess/ios/DragDropInteractionState.mm:
+    (WebKit::createTargetedDragPreview):
+    
+    Drive-by fix: make this return a RetainPtr.
+    
+    (WebKit::DragDropInteractionState::prepareForDelayedDropPreview):
+    
+    Stores a drop preview provider, given to us by UIKit.
+    
+    (WebKit::DragDropInteractionState::deliverDelayedDropPreview):
+    
+    Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are
+    taken following an edit drag (this is additionally after all images in the inserted fragment have finished
+    loading).
+    
+    (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders):
+    
+    Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session
+    cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers
+    are always invoked when cleaning up the drag session.
+    
+    (WebKit::DragDropInteractionState::previewForDragItem const):
+    (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):
+    
+    Call clearAllDelayedItemPreviewProviders.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::willReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didConcludeEditDrag): Deleted.
+    
+    More plumbing (see changes to DidConcludeEditDrag above).
+    
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView cleanupInteraction]):
+    (-[WKContentView cleanUpDragSourceSessionState]):
+    (-[WKContentView _willReceiveEditDragSnapshot]):
+    (-[WKContentView _didReceiveEditDragSnapshot:]):
+    
+    Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and
+    when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of
+    -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is
+    received.
+    
+    (-[WKContentView _deliverDelayedDropPreviewIfPossible:]):
+    (-[WKContentView _didPerformDragOperation:]):
+    (-[WKContentView textEffectsWindow]):
+    
+    Drive-by fix to remove a workaround for a deprecation warning.
+    
+    (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]):
+    (-[WKContentView dropInteraction:concludeDrop:]):
+    
+    Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are
+    guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives
+    after the drop is concluded.
+    
+    (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
+    (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]):
+    
+    Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time
+    to update the drop preview. We do this in _didReceiveEditDragSnapshot.
+    
+    (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]):
+    (-[WKContentView _didConcludeEditDrag:]): Deleted.
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::willReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didConcludeDrop):
+    (WebKit::WebPageProxy::didConcludeEditDrag): Deleted.
+    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+    (WebKit::WebChromeClient::didFinishLoadingImageForElement):
+    * WebProcess/WebCoreSupport/WebChromeClient.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/WebPage.messages.in:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::didConcludeDrop):
+    
+    If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear
+    out the set here.
+    
+    (WebKit::WebPage::didConcludeEditDrag):
+    
+    After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI
+    process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not
+    including any selected content. The other snapshot is of the selected content only. However, when dropping
+    images (or a text selection containing images), these images may not yet have been loaded. If that is the case,
+    these images will appear to be missing from these snapshots.
+    
+    To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content
+    range have finished loading. We can tell that all dropped images have finished loading by using a new client
+    hook that is invoked when an image has finished loading.
+    
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    (WebKit::WebPage::computeAndSendEditDragSnapshot):
+    
+    Snapshot the selected content and send it to the UI process.
+    
+    Source/WebKitLegacy/mac:
+    
+    Add a new chrome client method. See other changelogs for more detail.
+    
+    * WebCoreSupport/WebChromeClient.h:
+    * WebCoreSupport/WebChromeClient.mm:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    
+    Source/WebKitLegacy/win:
+    
+    * WebCoreSupport/WebChromeClient.cpp:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    * WebCoreSupport/WebChromeClient.h:
+    
+    Tools:
+    
+    Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail.
+    
+    * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+    (TestWebKitAPI::isCompletelyWhite):
+    (TestWebKitAPI::TEST):
+    
+    Add a test that drags and drops an image into a contenteditable element, and then observes the resulting
+    UITargetedDragPreviews upon drop.
+    
+    * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+    * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+    (-[DragAndDropSimulator _resetSimulatedState]):
+    (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
+    (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]):
+    
+    Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction
+    delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer
+    the end of the simulated drag and drop until after drag previews have been received during an edit drag.
+    
+    (-[DragAndDropSimulator dropPreviews]):
+    (-[DragAndDropSimulator delayedDropPreviews]):
+    
+    Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which
+    previews were provided asynchronously.
+    
+    (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
+    * TestWebKitAPI/ios/UIKitSPI.h:
+    
+    Stage the new private drop interacton delegate method.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-05-26  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+            [iOS] Dropped text, attachments, and images should animate into place
+            https://bugs.webkit.org/show_bug.cgi?id=198243
+            <rdar://problem/35205373>
+
+            Reviewed by Tim Horton.
+
+            Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit
+            changelog for more detail.
+
+            Test: DragAndDropTests.DropPreviewForImageInEditableArea
+
+            * loader/EmptyClients.h:
+            * page/ChromeClient.h:
+            * page/Page.cpp:
+            (WebCore::Page::didFinishLoadingImageForElement):
+            * page/Page.h:
+            * rendering/RenderImage.cpp:
+            (WebCore::RenderImage::notifyFinished):
+
+2019-05-26  Babak Shafiei  <bshafiei@apple.com>
+
</ins><span class="cx">         Cherry-pick r245775. rdar://problem/35205373
</span><span class="cx"> 
</span><span class="cx">     [iOS] Respect -[NSItemProvider preferredPresentationSize] when dropping images
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebCoreloaderEmptyClientsh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebCore/loader/EmptyClients.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebCore/loader/EmptyClients.h  2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebCore/loader/EmptyClients.h     2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> 
</span><span class="cx"> class DiagnosticLoggingClient;
</span><span class="cx"> class EditorClient;
</span><ins>+class HTMLImageElement;
</ins><span class="cx"> class PageConfiguration;
</span><span class="cx"> 
</span><span class="cx"> class EmptyChromeClient : public ChromeClient {
</span><span class="lines">@@ -111,6 +112,8 @@
</span><span class="cx">     IntPoint accessibilityScreenToRootView(const IntPoint& p) const final { return p; };
</span><span class="cx">     IntRect rootViewToAccessibilityScreen(const IntRect& r) const final { return r; };
</span><span class="cx"> 
</span><ins>+    void didFinishLoadingImageForElement(HTMLImageElement&) final { }
+
</ins><span class="cx">     PlatformPageClient platformPageClient() const final { return 0; }
</span><span class="cx">     void contentsSizeChanged(Frame&, const IntSize&) const final { }
</span><span class="cx">     void intrinsicContentsSizeChanged(const IntSize&) const final { }
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebCorepageChromeClienth"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebCore/page/ChromeClient.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebCore/page/ChromeClient.h    2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebCore/page/ChromeClient.h       2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -85,6 +85,7 @@
</span><span class="cx"> class Geolocation;
</span><span class="cx"> class GraphicsLayer;
</span><span class="cx"> class GraphicsLayerFactory;
</span><ins>+class HTMLImageElement;
</ins><span class="cx"> class HTMLInputElement;
</span><span class="cx"> class HTMLMediaElement;
</span><span class="cx"> class HTMLVideoElement;
</span><span class="lines">@@ -180,6 +181,8 @@
</span><span class="cx">     virtual IntPoint accessibilityScreenToRootView(const IntPoint&) const = 0;
</span><span class="cx">     virtual IntRect rootViewToAccessibilityScreen(const IntRect&) const = 0;
</span><span class="cx"> 
</span><ins>+    virtual void didFinishLoadingImageForElement(HTMLImageElement&) = 0;
+
</ins><span class="cx">     virtual PlatformPageClient platformPageClient() const = 0;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CURSOR_SUPPORT)
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.cpp (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.cpp  2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.cpp     2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -2995,4 +2995,9 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Page::didFinishLoadingImageForElement(HTMLImageElement& element)
+{
+    chrome().client().didFinishLoadingImageForElement(element);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebCorepagePageh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.h    2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebCore/page/Page.h       2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -527,6 +527,8 @@
</span><span class="cx">     WEBCORE_EXPORT VisibilityState visibilityState() const;
</span><span class="cx">     WEBCORE_EXPORT void resumeAnimatingImages();
</span><span class="cx"> 
</span><ins>+    void didFinishLoadingImageForElement(HTMLImageElement&);
+
</ins><span class="cx">     WEBCORE_EXPORT void addLayoutMilestones(OptionSet<LayoutMilestone>);
</span><span class="cx">     WEBCORE_EXPORT void removeLayoutMilestones(OptionSet<LayoutMilestone>);
</span><span class="cx">     OptionSet<LayoutMilestone> requestedLayoutMilestones() const { return m_requestedLayoutMilestones; }
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebCorerenderingRenderImagecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebCore/rendering/RenderImage.cpp (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebCore/rendering/RenderImage.cpp      2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebCore/rendering/RenderImage.cpp 2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -378,6 +378,9 @@
</span><span class="cx">         // that the image is done and they can reference it directly.
</span><span class="cx">         contentChanged(ImageChanged);
</span><span class="cx">     }
</span><ins>+
+    if (is<HTMLImageElement>(element()))
+        page().didFinishLoadingImageForElement(downcast<HTMLImageElement>(*element()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RenderImage::isShowingMissingOrImageError() const
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/ChangeLog (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/ChangeLog       2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/ChangeLog  2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -1,3 +1,362 @@
</span><ins>+2019-05-26  Babak Shafiei  <bshafiei@apple.com>
+
+        Cherry-pick r245778. rdar://problem/35205373
+
+    [iOS] Dropped text, attachments, and images should animate into place
+    https://bugs.webkit.org/show_bug.cgi?id=198243
+    <rdar://problem/35205373>
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebCore:
+    
+    Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit
+    changelog for more detail.
+    
+    Test: DragAndDropTests.DropPreviewForImageInEditableArea
+    
+    * loader/EmptyClients.h:
+    * page/ChromeClient.h:
+    * page/Page.cpp:
+    (WebCore::Page::didFinishLoadingImageForElement):
+    * page/Page.h:
+    * rendering/RenderImage.cpp:
+    (WebCore::RenderImage::notifyFinished):
+    
+    Source/WebKit:
+    
+    Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in
+    <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor
+    and augment existing logic for taking snapshots after performing a drop in an editable content.
+    
+    Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web
+    view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of
+    the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade
+    from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop
+    preview to the drag caret rect. During this process, snapshot (2) is completely ignored.
+    
+    This was effectively a halfway implemention of the desired effect of animating the dropped content into place
+    and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation
+    was not possible in modern WebKit (without using synchronous IPC).
+    
+    Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot
+    (2) above and clean up some parts of the drop animation in editable content. See below for more details.
+    
+    * UIProcess/API/Cocoa/WKWebView.mm:
+    (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]):
+    
+    Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See
+    TestWebKitAPI changes for more detail.
+    
+    * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and
+    DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop,
+    until after the final edit drag snapshot has been received.
+    
+    * UIProcess/ios/DragDropInteractionState.h:
+    
+    Add some new methods to help manage the lifecycle of drop preview provider blocks.
+    
+    * UIProcess/ios/DragDropInteractionState.mm:
+    (WebKit::createTargetedDragPreview):
+    
+    Drive-by fix: make this return a RetainPtr.
+    
+    (WebKit::DragDropInteractionState::prepareForDelayedDropPreview):
+    
+    Stores a drop preview provider, given to us by UIKit.
+    
+    (WebKit::DragDropInteractionState::deliverDelayedDropPreview):
+    
+    Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are
+    taken following an edit drag (this is additionally after all images in the inserted fragment have finished
+    loading).
+    
+    (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders):
+    
+    Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session
+    cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers
+    are always invoked when cleaning up the drag session.
+    
+    (WebKit::DragDropInteractionState::previewForDragItem const):
+    (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):
+    
+    Call clearAllDelayedItemPreviewProviders.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::willReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didConcludeEditDrag): Deleted.
+    
+    More plumbing (see changes to DidConcludeEditDrag above).
+    
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView cleanupInteraction]):
+    (-[WKContentView cleanUpDragSourceSessionState]):
+    (-[WKContentView _willReceiveEditDragSnapshot]):
+    (-[WKContentView _didReceiveEditDragSnapshot:]):
+    
+    Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and
+    when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of
+    -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is
+    received.
+    
+    (-[WKContentView _deliverDelayedDropPreviewIfPossible:]):
+    (-[WKContentView _didPerformDragOperation:]):
+    (-[WKContentView textEffectsWindow]):
+    
+    Drive-by fix to remove a workaround for a deprecation warning.
+    
+    (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]):
+    (-[WKContentView dropInteraction:concludeDrop:]):
+    
+    Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are
+    guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives
+    after the drop is concluded.
+    
+    (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
+    (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]):
+    
+    Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time
+    to update the drop preview. We do this in _didReceiveEditDragSnapshot.
+    
+    (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]):
+    (-[WKContentView _didConcludeEditDrag:]): Deleted.
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::willReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didConcludeDrop):
+    (WebKit::WebPageProxy::didConcludeEditDrag): Deleted.
+    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+    (WebKit::WebChromeClient::didFinishLoadingImageForElement):
+    * WebProcess/WebCoreSupport/WebChromeClient.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/WebPage.messages.in:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::didConcludeDrop):
+    
+    If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear
+    out the set here.
+    
+    (WebKit::WebPage::didConcludeEditDrag):
+    
+    After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI
+    process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not
+    including any selected content. The other snapshot is of the selected content only. However, when dropping
+    images (or a text selection containing images), these images may not yet have been loaded. If that is the case,
+    these images will appear to be missing from these snapshots.
+    
+    To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content
+    range have finished loading. We can tell that all dropped images have finished loading by using a new client
+    hook that is invoked when an image has finished loading.
+    
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    (WebKit::WebPage::computeAndSendEditDragSnapshot):
+    
+    Snapshot the selected content and send it to the UI process.
+    
+    Source/WebKitLegacy/mac:
+    
+    Add a new chrome client method. See other changelogs for more detail.
+    
+    * WebCoreSupport/WebChromeClient.h:
+    * WebCoreSupport/WebChromeClient.mm:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    
+    Source/WebKitLegacy/win:
+    
+    * WebCoreSupport/WebChromeClient.cpp:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    * WebCoreSupport/WebChromeClient.h:
+    
+    Tools:
+    
+    Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail.
+    
+    * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+    (TestWebKitAPI::isCompletelyWhite):
+    (TestWebKitAPI::TEST):
+    
+    Add a test that drags and drops an image into a contenteditable element, and then observes the resulting
+    UITargetedDragPreviews upon drop.
+    
+    * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+    * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+    (-[DragAndDropSimulator _resetSimulatedState]):
+    (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
+    (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]):
+    
+    Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction
+    delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer
+    the end of the simulated drag and drop until after drag previews have been received during an edit drag.
+    
+    (-[DragAndDropSimulator dropPreviews]):
+    (-[DragAndDropSimulator delayedDropPreviews]):
+    
+    Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which
+    previews were provided asynchronously.
+    
+    (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
+    * TestWebKitAPI/ios/UIKitSPI.h:
+    
+    Stage the new private drop interacton delegate method.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-05-26  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+            [iOS] Dropped text, attachments, and images should animate into place
+            https://bugs.webkit.org/show_bug.cgi?id=198243
+            <rdar://problem/35205373>
+
+            Reviewed by Tim Horton.
+
+            Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in
+            <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor
+            and augment existing logic for taking snapshots after performing a drop in an editable content.
+
+            Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web
+            view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of
+            the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade
+            from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop
+            preview to the drag caret rect. During this process, snapshot (2) is completely ignored.
+
+            This was effectively a halfway implemention of the desired effect of animating the dropped content into place
+            and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation
+            was not possible in modern WebKit (without using synchronous IPC).
+
+            Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot
+            (2) above and clean up some parts of the drop animation in editable content. See below for more details.
+
+            * UIProcess/API/Cocoa/WKWebView.mm:
+            (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]):
+
+            Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See
+            TestWebKitAPI changes for more detail.
+
+            * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+            * UIProcess/PageClient.h:
+            * UIProcess/WebPageProxy.h:
+            * UIProcess/WebPageProxy.messages.in:
+
+            Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and
+            DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop,
+            until after the final edit drag snapshot has been received.
+
+            * UIProcess/ios/DragDropInteractionState.h:
+
+            Add some new methods to help manage the lifecycle of drop preview provider blocks.
+
+            * UIProcess/ios/DragDropInteractionState.mm:
+            (WebKit::createTargetedDragPreview):
+
+            Drive-by fix: make this return a RetainPtr.
+
+            (WebKit::DragDropInteractionState::prepareForDelayedDropPreview):
+
+            Stores a drop preview provider, given to us by UIKit.
+
+            (WebKit::DragDropInteractionState::deliverDelayedDropPreview):
+
+            Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are
+            taken following an edit drag (this is additionally after all images in the inserted fragment have finished
+            loading).
+
+            (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders):
+
+            Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session
+            cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers
+            are always invoked when cleaning up the drag session.
+
+            (WebKit::DragDropInteractionState::previewForDragItem const):
+            (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):
+
+            Call clearAllDelayedItemPreviewProviders.
+
+            * UIProcess/ios/PageClientImplIOS.h:
+            * UIProcess/ios/PageClientImplIOS.mm:
+            (WebKit::PageClientImpl::willReceiveEditDragSnapshot):
+            (WebKit::PageClientImpl::didReceiveEditDragSnapshot):
+            (WebKit::PageClientImpl::didConcludeEditDrag): Deleted.
+
+            More plumbing (see changes to DidConcludeEditDrag above).
+
+            * UIProcess/ios/WKContentViewInteraction.h:
+            * UIProcess/ios/WKContentViewInteraction.mm:
+            (-[WKContentView cleanupInteraction]):
+            (-[WKContentView cleanUpDragSourceSessionState]):
+            (-[WKContentView _willReceiveEditDragSnapshot]):
+            (-[WKContentView _didReceiveEditDragSnapshot:]):
+
+            Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and
+            when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of
+            -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is
+            received.
+
+            (-[WKContentView _deliverDelayedDropPreviewIfPossible:]):
+            (-[WKContentView _didPerformDragOperation:]):
+            (-[WKContentView textEffectsWindow]):
+
+            Drive-by fix to remove a workaround for a deprecation warning.
+
+            (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]):
+            (-[WKContentView dropInteraction:concludeDrop:]):
+
+            Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are
+            guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives
+            after the drop is concluded.
+
+            (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
+            (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]):
+
+            Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time
+            to update the drop preview. We do this in _didReceiveEditDragSnapshot.
+
+            (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]):
+            (-[WKContentView _didConcludeEditDrag:]): Deleted.
+            * UIProcess/ios/WebPageProxyIOS.mm:
+            (WebKit::WebPageProxy::willReceiveEditDragSnapshot):
+            (WebKit::WebPageProxy::didReceiveEditDragSnapshot):
+            (WebKit::WebPageProxy::didConcludeDrop):
+            (WebKit::WebPageProxy::didConcludeEditDrag): Deleted.
+            * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+            (WebKit::WebChromeClient::didFinishLoadingImageForElement):
+            * WebProcess/WebCoreSupport/WebChromeClient.h:
+            * WebProcess/WebPage/WebPage.cpp:
+            (WebKit::WebPage::didFinishLoadingImageForElement):
+            * WebProcess/WebPage/WebPage.h:
+            * WebProcess/WebPage/WebPage.messages.in:
+            * WebProcess/WebPage/ios/WebPageIOS.mm:
+            (WebKit::WebPage::didConcludeDrop):
+
+            If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear
+            out the set here.
+
+            (WebKit::WebPage::didConcludeEditDrag):
+
+            After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI
+            process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not
+            including any selected content. The other snapshot is of the selected content only. However, when dropping
+            images (or a text selection containing images), these images may not yet have been loaded. If that is the case,
+            these images will appear to be missing from these snapshots.
+
+            To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content
+            range have finished loading. We can tell that all dropped images have finished loading by using a new client
+            hook that is invoked when an image has finished loading.
+
+            (WebKit::WebPage::didFinishLoadingImageForElement):
+            (WebKit::WebPage::computeAndSendEditDragSnapshot):
+
+            Snapshot the selected content and send it to the UI process.
+
</ins><span class="cx"> 2019-05-23  Kocsen Chung  <kocsen_chung@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Cherry-pick r245661. rdar://problem/50613388
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm        2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm   2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -6889,6 +6889,11 @@
</span><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action
+{
+    [_contentView _doAfterReceivingEditDragSnapshotForTesting:action];
+}
+
</ins><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessAPICocoaWKWebViewPrivateh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h  2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h     2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -489,6 +489,8 @@
</span><span class="cx"> 
</span><span class="cx"> @property (nonatomic, readonly) CGRect _dragCaretRect WK_API_AVAILABLE(ios(11.0));
</span><span class="cx"> 
</span><ins>+- (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action WK_API_AVAILABLE(ios(WK_IOS_TBA));
+
</ins><span class="cx"> - (void)_requestActivatedElementAtPosition:(CGPoint)position completionBlock:(void (^)(_WKActivatedElementInfo *))block WK_API_AVAILABLE(ios(11.0));
</span><span class="cx"> - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text completionHandler:(void (^)(NSArray<NSValue *> *rects))completionHandler WK_API_AVAILABLE(ios(11.3));
</span><span class="cx"> - (void)_accessibilityStoreSelection WK_API_AVAILABLE(ios(11.3));
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/PageClient.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/PageClient.h  2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/PageClient.h     2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -479,7 +479,8 @@
</span><span class="cx"> #if ENABLE(DATA_INTERACTION)
</span><span class="cx">     virtual void didHandleDragStartRequest(bool started) = 0;
</span><span class="cx">     virtual void didHandleAdditionalDragItemsRequest(bool added) = 0;
</span><del>-    virtual void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>) = 0;
</del><ins>+    virtual void willReceiveEditDragSnapshot() = 0;
+    virtual void didReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData>) = 0;
</ins><span class="cx">     virtual void didChangeDragCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) = 0;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.h        2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.h   2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -724,12 +724,14 @@
</span><span class="cx">     void updateSelectionWithDelta(int64_t locationDelta, int64_t lengthDelta, CompletionHandler<void()>&&);
</span><span class="cx">     void requestDocumentEditingContext(WebKit::DocumentEditingContextRequest, CompletionHandler<void(WebKit::DocumentEditingContext)>&&);
</span><span class="cx">     void generateSyntheticEditingCommand(SyntheticEditingCommandType);
</span><del>-#if ENABLE(DATA_INTERACTION)
</del><ins>+#if ENABLE(DRAG_SUPPORT)
</ins><span class="cx">     void didHandleDragStartRequest(bool started);
</span><span class="cx">     void didHandleAdditionalDragItemsRequest(bool added);
</span><span class="cx">     void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions);
</span><span class="cx">     void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions);
</span><del>-    void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>);
</del><ins>+    void willReceiveEditDragSnapshot();
+    void didReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData>);
+    void didConcludeDrop();
</ins><span class="cx"> #endif
</span><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span><span class="cx"> #if ENABLE(DATA_DETECTION)
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in      2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/WebPageProxy.messages.in 2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -331,7 +331,8 @@
</span><span class="cx"> #if ENABLE(DATA_INTERACTION)
</span><span class="cx">     DidHandleDragStartRequest(bool started)
</span><span class="cx">     DidHandleAdditionalDragItemsRequest(bool added)
</span><del>-    DidConcludeEditDrag(Optional<WebCore::TextIndicatorData> textIndicator)
</del><ins>+    WillReceiveEditDragSnapshot()
+    DidReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData> textIndicator)
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessiosDragDropInteractionStateh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.h        2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.h   2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> struct DragItem;
</span><ins>+struct TextIndicatorData;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="lines">@@ -58,6 +59,11 @@
</span><span class="cx">     NSInteger itemIdentifier { 0 };
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct ItemAndPreviewProvider {
+    RetainPtr<UIDragItem> item;
+    BlockPtr<void(UITargetedDragPreview *)> provider;
+};
+
</ins><span class="cx"> class DragDropInteractionState {
</span><span class="cx"> public:
</span><span class="cx">     bool anyActiveDragSourceIs(WebCore::DragSourceAction) const;
</span><span class="lines">@@ -92,6 +98,10 @@
</span><span class="cx">     BlockPtr<void()> takeDragCancelSetDownBlock() { return WTFMove(m_dragCancelSetDownBlock); }
</span><span class="cx">     BlockPtr<void(NSArray<UIDragItem *> *)> takeAddDragItemCompletionBlock() { return WTFMove(m_addDragItemCompletionBlock); }
</span><span class="cx"> 
</span><ins>+    void prepareForDelayedDropPreview(UIDragItem *, void(^provider)(UITargetedDragPreview *preview));
+    void deliverDelayedDropPreview(UIView *contentView, UIView *previewContainer, const WebCore::TextIndicatorData&);
+    void clearAllDelayedItemPreviewProviders();
+
</ins><span class="cx"> private:
</span><span class="cx">     void updatePreviewsForActiveDragSources();
</span><span class="cx">     Optional<DragSourceState> activeDragSourceForItem(UIDragItem *) const;
</span><span class="lines">@@ -108,6 +118,7 @@
</span><span class="cx"> 
</span><span class="cx">     Optional<DragSourceState> m_stagedDragSource;
</span><span class="cx">     Vector<DragSourceState> m_activeDragSources;
</span><ins>+    Vector<ItemAndPreviewProvider> m_delayedItemPreviewProviders;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessiosDragDropInteractionStatemm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm       2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/DragDropInteractionState.mm  2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx">     return nil;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static UITargetedDragPreview *createTargetedDragPreview(UIImage *image, UIView *rootView, UIView *previewContainer, const FloatRect& frameInRootViewCoordinates, const Vector<FloatRect>& clippingRectsInFrameCoordinates, UIColor *backgroundColor, UIBezierPath *visiblePath)
</del><ins>+static RetainPtr<UITargetedDragPreview> createTargetedDragPreview(UIImage *image, UIView *rootView, UIView *previewContainer, const FloatRect& frameInRootViewCoordinates, const Vector<FloatRect>& clippingRectsInFrameCoordinates, UIColor *backgroundColor, UIBezierPath *visiblePath)
</ins><span class="cx"> {
</span><span class="cx">     if (frameInRootViewCoordinates.isEmpty() || !image)
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -78,8 +78,7 @@
</span><span class="cx"> 
</span><span class="cx">     CGPoint centerInContainerCoordinates = { CGRectGetMidX(frameInContainerCoordinates), CGRectGetMidY(frameInContainerCoordinates) };
</span><span class="cx">     auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:previewContainer center:centerInContainerCoordinates]);
</span><del>-    auto dragPreview = adoptNS([[UITargetedDragPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:target.get()]);
-    return dragPreview.autorelease();
</del><ins>+    return adoptNS([[UITargetedDragPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:target.get()]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static RetainPtr<UIImage> uiImageForImage(Image* image)
</span><span class="lines">@@ -186,6 +185,30 @@
</span><span class="cx">     updatePreviewsForActiveDragSources();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void DragDropInteractionState::prepareForDelayedDropPreview(UIDragItem *item, void(^provider)(UITargetedDragPreview *preview))
+{
+    m_delayedItemPreviewProviders.append({ item, provider });
+}
+
+void DragDropInteractionState::deliverDelayedDropPreview(UIView *contentView, UIView *previewContainer, const WebCore::TextIndicatorData& indicator)
+{
+    if (m_delayedItemPreviewProviders.isEmpty())
+        return;
+
+    auto textIndicatorImage = uiImageForImage(indicator.contentImage.get());
+    auto preview = createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)], nil);
+    for (auto& itemAndPreviewProvider : m_delayedItemPreviewProviders)
+        itemAndPreviewProvider.provider(preview.get());
+    m_delayedItemPreviewProviders.clear();
+}
+
+void DragDropInteractionState::clearAllDelayedItemPreviewProviders()
+{
+    for (auto& itemAndPreviewProvider : m_delayedItemPreviewProviders)
+        itemAndPreviewProvider.provider(nil);
+    m_delayedItemPreviewProviders.clear();
+}
+
</ins><span class="cx"> UITargetedDragPreview *DragDropInteractionState::previewForDragItem(UIDragItem *item, UIView *contentView, UIView *previewContainer) const
</span><span class="cx"> {
</span><span class="cx">     auto foundSource = activeDragSourceForItem(item);
</span><span class="lines">@@ -197,15 +220,15 @@
</span><span class="cx">         if (shouldUseVisiblePathToCreatePreviewForDragSource(source)) {
</span><span class="cx">             auto path = source.visiblePath.value();
</span><span class="cx">             UIBezierPath *visiblePath = [UIBezierPath bezierPathWithCGPath:path.ensurePlatformPath()];
</span><del>-            return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, visiblePath);
</del><ins>+            return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, visiblePath).autorelease();
</ins><span class="cx">         }
</span><del>-        return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, nil);
</del><ins>+        return createTargetedDragPreview(source.image.get(), contentView, previewContainer, source.dragPreviewFrameInRootViewCoordinates, { }, nil, nil).autorelease();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (shouldUseTextIndicatorToCreatePreviewForDragSource(source)) {
</span><span class="cx">         auto indicator = source.indicatorData.value();
</span><span class="cx">         auto textIndicatorImage = uiImageForImage(indicator.contentImage.get());
</span><del>-        return createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)], nil);
</del><ins>+        return createTargetedDragPreview(textIndicatorImage.get(), contentView, previewContainer, indicator.textBoundingRectInRootViewCoordinates, indicator.textRectsInBoundingRectCoordinates, [UIColor colorWithCGColor:cachedCGColor(indicator.estimatedBackgroundColor)], nil).autorelease();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return nil;
</span><span class="lines">@@ -266,6 +289,8 @@
</span><span class="cx"> 
</span><span class="cx"> void DragDropInteractionState::dragAndDropSessionsDidEnd()
</span><span class="cx"> {
</span><ins>+    clearAllDelayedItemPreviewProviders();
+
</ins><span class="cx">     // 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
</span><span class="cx">     // to prevent UIKit from getting into an inconsistent state.
</span><span class="cx">     if (auto completionBlock = takeDragCancelSetDownBlock())
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessiosPageClientImplIOSh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h       2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.h  2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -237,7 +237,8 @@
</span><span class="cx">     void didHandleDragStartRequest(bool started) override;
</span><span class="cx">     void didHandleAdditionalDragItemsRequest(bool added) override;
</span><span class="cx">     void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle& image) override;
</span><del>-    void didConcludeEditDrag(Optional<WebCore::TextIndicatorData>) override;
</del><ins>+    void willReceiveEditDragSnapshot() override;
+    void didReceiveEditDragSnapshot(Optional<WebCore::TextIndicatorData>) override;
</ins><span class="cx">     void didChangeDragCaretRect(const WebCore::IntRect& previousCaretRect, const WebCore::IntRect& caretRect) override;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessiosPageClientImplIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm      2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm 2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -819,11 +819,16 @@
</span><span class="cx">     [m_contentView _startDrag:ShareableBitmap::create(image)->makeCGImageCopy() item:item];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void PageClientImpl::didConcludeEditDrag(Optional<TextIndicatorData> data)
</del><ins>+void PageClientImpl::willReceiveEditDragSnapshot()
</ins><span class="cx"> {
</span><del>-    [m_contentView _didConcludeEditDrag:data];
</del><ins>+    [m_contentView _willReceiveEditDragSnapshot];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PageClientImpl::didReceiveEditDragSnapshot(Optional<TextIndicatorData> data)
+{
+    [m_contentView _didReceiveEditDragSnapshot:data];
+}
+
</ins><span class="cx"> void PageClientImpl::didChangeDragCaretRect(const IntRect& previousCaretRect, const IntRect& caretRect)
</span><span class="cx"> {
</span><span class="cx">     [m_contentView _didChangeDragCaretRect:previousCaretRect currentRect:caretRect];
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessiosWKContentViewInteractionh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h        2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h   2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -333,6 +333,7 @@
</span><span class="cx">     BOOL _isBlurringFocusedElement;
</span><span class="cx"> 
</span><span class="cx">     BOOL _focusRequiresStrongPasswordAssistance;
</span><ins>+    BOOL _waitingForEditDragSnapshot;
</ins><span class="cx"> 
</span><span class="cx">     BOOL _hasSetUpInteractions;
</span><span class="cx">     NSUInteger _ignoreSelectionCommandFadeCount;
</span><span class="lines">@@ -344,9 +345,10 @@
</span><span class="cx">     RetainPtr<UIDragInteraction> _dragInteraction;
</span><span class="cx">     RetainPtr<UIDropInteraction> _dropInteraction;
</span><span class="cx">     BOOL _shouldRestoreCalloutBarAfterDrop;
</span><del>-    BOOL _isAnimatingConcludeEditDrag;
</del><span class="cx">     RetainPtr<UIView> _visibleContentViewSnapshot;
</span><ins>+    RetainPtr<UIView> _unselectedContentSnapshot;
</ins><span class="cx">     RetainPtr<_UITextDragCaretView> _editDropCaretView;
</span><ins>+    BlockPtr<void()> _actionToPerformAfterReceivingEditDragSnapshot;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(WATCHOS)
</span><span class="lines">@@ -489,7 +491,8 @@
</span><span class="cx"> - (void)_didHandleDragStartRequest:(BOOL)started;
</span><span class="cx"> - (void)_didHandleAdditionalDragItemsRequest:(BOOL)added;
</span><span class="cx"> - (void)_startDrag:(RetainPtr<CGImageRef>)image item:(const WebCore::DragItem&)item;
</span><del>-- (void)_didConcludeEditDrag:(Optional<WebCore::TextIndicatorData>)data;
</del><ins>+- (void)_willReceiveEditDragSnapshot;
+- (void)_didReceiveEditDragSnapshot:(Optional<WebCore::TextIndicatorData>)data;
</ins><span class="cx"> - (void)_didChangeDragCaretRect:(CGRect)previousRect currentRect:(CGRect)rect;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -514,6 +517,7 @@
</span><span class="cx"> - (void)selectFormAccessoryPickerRow:(NSInteger)rowIndex;
</span><span class="cx"> - (void)setTimePickerValueToHour:(NSInteger)hour minute:(NSInteger)minute;
</span><span class="cx"> - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem;
</span><ins>+- (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action;
</ins><span class="cx"> 
</span><span class="cx"> @property (nonatomic, readonly) NSString *textContentTypeForTesting;
</span><span class="cx"> @property (nonatomic, readonly) NSString *selectFormPopoverTitle;
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm       2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm  2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -839,6 +839,7 @@
</span><span class="cx">     _outstandingPositionInformationRequest = WTF::nullopt;
</span><span class="cx"> 
</span><span class="cx">     _focusRequiresStrongPasswordAssistance = NO;
</span><ins>+    _waitingForEditDragSnapshot = NO;
</ins><span class="cx"> 
</span><span class="cx"> #if USE(UIKIT_KEYBOARD_ADDITIONS)
</span><span class="cx">     _candidateViewNeedsUpdate = NO;
</span><span class="lines">@@ -6243,6 +6244,9 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)cleanUpDragSourceSessionState
</span><span class="cx"> {
</span><ins>+    if (_waitingForEditDragSnapshot)
+        return;
+
</ins><span class="cx">     if (_dragDropInteractionState.dragSession() || _dragDropInteractionState.isPerformingDrop())
</span><span class="cx">         RELEASE_LOG(DragAndDrop, "Cleaning up dragging state (has pending operation: %d)", [[WebItemProviderPasteboard sharedInstance] hasPendingOperation]);
</span><span class="cx"> 
</span><span class="lines">@@ -6255,11 +6259,9 @@
</span><span class="cx">     [[WebItemProviderPasteboard sharedInstance] stageRegistrationList:nil];
</span><span class="cx">     [self _restoreCalloutBarIfNeeded];
</span><span class="cx"> 
</span><del>-    [_visibleContentViewSnapshot removeFromSuperview];
-    _visibleContentViewSnapshot = nil;
</del><ins>+    [std::exchange(_visibleContentViewSnapshot, nil) removeFromSuperview];
</ins><span class="cx">     [_editDropCaretView remove];
</span><span class="cx">     _editDropCaretView = nil;
</span><del>-    _isAnimatingConcludeEditDrag = NO;
</del><span class="cx">     _shouldRestoreCalloutBarAfterDrop = NO;
</span><span class="cx"> 
</span><span class="cx">     _dragDropInteractionState.dragAndDropSessionsDidEnd();
</span><span class="lines">@@ -6281,11 +6283,33 @@
</span><span class="cx">     return extractItemProvidersFromDragItems(session.items);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)_didConcludeEditDrag:(Optional<WebCore::TextIndicatorData>)data
</del><ins>+- (void)_willReceiveEditDragSnapshot
</ins><span class="cx"> {
</span><ins>+    _waitingForEditDragSnapshot = YES;
+}
+
+- (void)_didReceiveEditDragSnapshot:(Optional<WebCore::TextIndicatorData>)data
+{
+    _waitingForEditDragSnapshot = NO;
+
+    [self _deliverDelayedDropPreviewIfPossible:data];
+    [self cleanUpDragSourceSessionState];
+
+    if (auto action = WTFMove(_actionToPerformAfterReceivingEditDragSnapshot))
+        action();
+}
+
+- (void)_deliverDelayedDropPreviewIfPossible:(Optional<WebCore::TextIndicatorData>)data
+{
+    if (!_visibleContentViewSnapshot)
+        return;
+
</ins><span class="cx">     if (!data)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    if (!data->contentImage)
+        return;
+
</ins><span class="cx">     auto snapshotWithoutSelection = data->contentImageWithoutSelection;
</span><span class="cx">     if (!snapshotWithoutSelection)
</span><span class="cx">         return;
</span><span class="lines">@@ -6295,25 +6319,11 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     auto unselectedContentImageForEditDrag = adoptNS([[UIImage alloc] initWithCGImage:unselectedSnapshotImage.get() scale:_page->deviceScaleFactor() orientation:UIImageOrientationUp]);
</span><del>-    auto unselectedContentSnapshot = adoptNS([[UIImageView alloc] initWithImage:unselectedContentImageForEditDrag.get()]);
-    [unselectedContentSnapshot setFrame:data->contentImageWithoutSelectionRectInRootViewCoordinates];
</del><ins>+    _unselectedContentSnapshot = adoptNS([[UIImageView alloc] initWithImage:unselectedContentImageForEditDrag.get()]);
+    [_unselectedContentSnapshot setFrame:data->contentImageWithoutSelectionRectInRootViewCoordinates];
</ins><span class="cx"> 
</span><del>-    auto protectedSelf = retainPtr(self);
-    auto visibleContentViewSnapshot = adoptNS(_visibleContentViewSnapshot.leakRef());
-
-    _isAnimatingConcludeEditDrag = YES;
-    [self insertSubview:unselectedContentSnapshot.get() belowSubview:visibleContentViewSnapshot.get()];
-    [UIView animateWithDuration:0.25 animations:^() {
-        [visibleContentViewSnapshot setAlpha:0];
-    } completion:^(BOOL completed) {
-        [visibleContentViewSnapshot removeFromSuperview];
-        [UIView animateWithDuration:0.25 animations:^() {
-            [protectedSelf _stopSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning];
-            [unselectedContentSnapshot setAlpha:0];
-        } completion:^(BOOL completed) {
-            [unselectedContentSnapshot removeFromSuperview];
-        }];
-    }];
</del><ins>+    [self insertSubview:_unselectedContentSnapshot.get() belowSubview:_visibleContentViewSnapshot.get()];
+    _dragDropInteractionState.deliverDelayedDropPreview(self, self.unscaledView, data.value());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_didPerformDragOperation:(BOOL)handled
</span><span class="lines">@@ -6324,9 +6334,6 @@
</span><span class="cx">     if ([self.webViewUIDelegate respondsToSelector:@selector(_webView:dataInteractionOperationWasHandled:forSession:itemProviders:)])
</span><span class="cx">         [self.webViewUIDelegate _webView:_webView dataInteractionOperationWasHandled:handled forSession:dropSession itemProviders:[WebItemProviderPasteboard sharedInstance].itemProviders];
</span><span class="cx"> 
</span><del>-    if (!_isAnimatingConcludeEditDrag)
-        [self _stopSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning];
-
</del><span class="cx">     CGPoint global;
</span><span class="cx">     CGPoint client;
</span><span class="cx">     [self computeClientAndGlobalPointsForDropSession:dropSession outClientPoint:&client outGlobalPoint:&global];
</span><span class="lines">@@ -6483,6 +6490,15 @@
</span><span class="cx">     return dragItems;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (UIView *)textEffectsWindow
+{
+#if HAVE(UISCENE)
+    return [UITextEffectsWindow sharedTextEffectsWindowForWindowScene:self.window.windowScene];
+#else
+    return [UITextEffectsWindow sharedTextEffectsWindow];
+#endif
+}
+
</ins><span class="cx"> - (NSDictionary *)_autofillContext
</span><span class="cx"> {
</span><span class="cx">     BOOL provideStrongPasswordAssistance = _focusRequiresStrongPasswordAssistance && _focusedElementInformation.elementType == WebKit::InputType::Password;
</span><span class="lines">@@ -6864,6 +6880,22 @@
</span><span class="cx">     }];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)dropInteraction:(UIDropInteraction *)interaction item:(UIDragItem *)item willAnimateDropWithAnimator:(id <UIDragAnimating>)animator
+{
+    [animator addCompletion:[strongSelf = retainPtr(self)] (UIViewAnimatingPosition) {
+        [std::exchange(strongSelf->_unselectedContentSnapshot, nil) removeFromSuperview];
+    }];
+}
+
+- (void)dropInteraction:(UIDropInteraction *)interaction concludeDrop:(id <UIDropSession>)session
+{
+    [self _stopSuppressingSelectionAssistantForReason:WebKit::DropAnimationIsRunning];
+    [std::exchange(_visibleContentViewSnapshot, nil) removeFromSuperview];
+    [std::exchange(_unselectedContentSnapshot, nil) removeFromSuperview];
+    _dragDropInteractionState.clearAllDelayedItemPreviewProviders();
+    _page->didConcludeDrop();
+}
+
</ins><span class="cx"> - (UITargetedDragPreview *)dropInteraction:(UIDropInteraction *)interaction previewForDroppingItem:(UIDragItem *)item withDefault:(UITargetedDragPreview *)defaultPreview
</span><span class="cx"> {
</span><span class="cx">     CGRect caretRect = _page->currentDragCaretRect();
</span><span class="lines">@@ -6870,17 +6902,20 @@
</span><span class="cx">     if (CGRectIsEmpty(caretRect))
</span><span class="cx">         return nil;
</span><span class="cx"> 
</span><del>-ALLOW_DEPRECATED_DECLARATIONS_BEGIN
-    // FIXME: <rdar://problem/31074376> [WK2] Performing an edit drag should transition from the initial drag preview to the final drop preview
-    // This is blocked on UIKit support, since we aren't able to update the text clipping rects of a UITargetedDragPreview mid-flight. For now,
-    // just zoom to the center of the caret rect while shrinking the drop preview.
-    auto caretRectInWindowCoordinates = [self convertRect:caretRect toView:[UITextEffectsWindow sharedTextEffectsWindow]];
</del><ins>+    UIView *textEffectsWindow = self.textEffectsWindow;
+    auto caretRectInWindowCoordinates = [self convertRect:caretRect toView:textEffectsWindow];
</ins><span class="cx">     auto caretCenterInWindowCoordinates = CGPointMake(CGRectGetMidX(caretRectInWindowCoordinates), CGRectGetMidY(caretRectInWindowCoordinates));
</span><del>-    auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:[UITextEffectsWindow sharedTextEffectsWindow] center:caretCenterInWindowCoordinates transform:CGAffineTransformMakeScale(0, 0)]);
-ALLOW_DEPRECATED_DECLARATIONS_END
</del><ins>+    auto targetPreviewCenterInWindowCoordinates = CGPointMake(caretCenterInWindowCoordinates.x + defaultPreview.size.width / 2, caretCenterInWindowCoordinates.y + defaultPreview.size.height / 2);
+    auto target = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:textEffectsWindow center:targetPreviewCenterInWindowCoordinates transform:CGAffineTransformIdentity]);
</ins><span class="cx">     return [defaultPreview retargetedPreviewWithTarget:target.get()];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_dropInteraction:(UIDropInteraction *)interaction delayedPreviewProviderForDroppingItem:(UIDragItem *)item previewProvider:(void(^)(UITargetedDragPreview *preview))previewProvider
+{
+    // FIXME: This doesn't currently handle multiple items in a drop session.
+    _dragDropInteractionState.prepareForDelayedDropPreview(item, previewProvider);
+}
+
</ins><span class="cx"> - (void)dropInteraction:(UIDropInteraction *)interaction sessionDidEnd:(id <UIDropSession>)session
</span><span class="cx"> {
</span><span class="cx">     RELEASE_LOG(DragAndDrop, "Drop session ended: %p (performing operation: %d, began dragging: %d)", session, _dragDropInteractionState.isPerformingDrop(), _dragDropInteractionState.didBeginDragging());
</span><span class="lines">@@ -7140,6 +7175,18 @@
</span><span class="cx"> 
</span><span class="cx"> @implementation WKContentView (WKTesting)
</span><span class="cx"> 
</span><ins>+- (void)_doAfterReceivingEditDragSnapshotForTesting:(dispatch_block_t)action
+{
+#if ENABLE(DRAG_SUPPORT)
+    ASSERT(!_actionToPerformAfterReceivingEditDragSnapshot);
+    if (_waitingForEditDragSnapshot) {
+        _actionToPerformAfterReceivingEditDragSnapshot = action;
+        return;
+    }
+#endif
+    action();
+}
+
</ins><span class="cx"> - (WKFormInputControl *)formInputControl
</span><span class="cx"> {
</span><span class="cx">     if ([_inputPeripheral isKindOfClass:WKFormInputControl.class])
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitUIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm        2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm   2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -1219,11 +1219,21 @@
</span><span class="cx">         m_process->send(Messages::WebPage::RequestAdditionalItemsForDragSession(clientPosition, globalPosition, allowedActions), m_pageID);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::didConcludeEditDrag(Optional<TextIndicatorData> data)
</del><ins>+void WebPageProxy::willReceiveEditDragSnapshot()
</ins><span class="cx"> {
</span><del>-    pageClient().didConcludeEditDrag(data);
</del><ins>+    pageClient().willReceiveEditDragSnapshot();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::didReceiveEditDragSnapshot(Optional<TextIndicatorData> data)
+{
+    pageClient().didReceiveEditDragSnapshot(data);
+}
+
+void WebPageProxy::didConcludeDrop()
+{
+    m_process->send(Messages::WebPage::DidConcludeDrop(), m_pageID);
+}
+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if USE(QUICK_LOOK)
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitWebProcessWebCoreSupportWebChromeClientcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp   2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp      2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -583,6 +583,11 @@
</span><span class="cx">     return m_page.rootViewToAccessibilityScreen(rect);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebChromeClient::didFinishLoadingImageForElement(HTMLImageElement& element)
+{
+    m_page.didFinishLoadingImageForElement(element);
+}
+
</ins><span class="cx"> PlatformPageClient WebChromeClient::platformPageClient() const
</span><span class="cx"> {
</span><span class="cx">     notImplemented();
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitWebProcessWebCoreSupportWebChromeClienth"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h     2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h        2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -28,6 +28,11 @@
</span><span class="cx"> 
</span><span class="cx"> #include <WebCore/ChromeClient.h>
</span><span class="cx"> 
</span><ins>+<<<<<<< HEAD
+namespace WebCore {
+class HTMLImageElement;
+}
+
</ins><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><span class="cx"> class WebFrame;
</span><span class="lines">@@ -115,6 +120,8 @@
</span><span class="cx">     WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const final;
</span><span class="cx">     WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const final;
</span><span class="cx"> 
</span><ins>+    void didFinishLoadingImageForElement(WebCore::HTMLImageElement&) final;
+
</ins><span class="cx">     PlatformPageClient platformPageClient() const final;
</span><span class="cx">     void contentsSizeChanged(WebCore::Frame&, const WebCore::IntSize&) const final;
</span><span class="cx">     void intrinsicContentsSizeChanged(const WebCore::IntSize&) const final;
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitWebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp  2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp     2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -6706,6 +6706,14 @@
</span><span class="cx">     send(Messages::WebPageProxy::ConfigureLoggingChannel(channelName, state, level));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !PLATFORM(IOS_FAMILY) || !ENABLE(DRAG_SUPPORT)
+
+void WebPage::didFinishLoadingImageForElement(WebCore::HTMLImageElement&)
+{
+}
+
+#endif
+
</ins><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #undef RELEASE_LOG_IF_ALLOWED
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitWebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.h    2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.h       2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -154,6 +154,7 @@
</span><span class="cx"> class FrameSelection;
</span><span class="cx"> class FrameView;
</span><span class="cx"> class GraphicsContext;
</span><ins>+class HTMLImageElement;
</ins><span class="cx"> class HTMLMenuElement;
</span><span class="cx"> class HTMLMenuItemElement;
</span><span class="cx"> class HTMLPlugInElement;
</span><span class="lines">@@ -1109,10 +1110,13 @@
</span><span class="cx">     void didGetLoadDecisionForIcon(bool decision, CallbackID loadIdentifier, OptionalCallbackID);
</span><span class="cx">     void setUseIconLoadingClient(bool);
</span><span class="cx"> 
</span><del>-#if ENABLE(DATA_INTERACTION)
</del><ins>+#if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
</ins><span class="cx">     void didConcludeEditDrag();
</span><ins>+    void didConcludeDrop();
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    void didFinishLoadingImageForElement(WebCore::HTMLImageElement&);
+
</ins><span class="cx">     WebURLSchemeHandlerProxy* urlSchemeHandlerForScheme(const String&);
</span><span class="cx">     void stopAllURLSchemeTasks();
</span><span class="cx"> 
</span><span class="lines">@@ -1250,6 +1254,7 @@
</span><span class="cx"> #if PLATFORM(IOS_FAMILY) && ENABLE(DATA_INTERACTION)
</span><span class="cx">     void requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t allowedActions);
</span><span class="cx">     void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t allowedActions);
</span><ins>+    void computeAndSendEditDragSnapshot();
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(COCOA) && !PLATFORM(WPE)
</span><span class="lines">@@ -1759,6 +1764,10 @@
</span><span class="cx">     WebCore::DragSourceAction m_allowedDragSourceActions { WebCore::DragSourceActionAny };
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(DRAG_SUPPORT) && PLATFORM(IOS_FAMILY)
+    HashSet<RefPtr<WebCore::HTMLImageElement>> m_pendingImageElementsForDropSnapshot;
+#endif
+
</ins><span class="cx">     bool m_cachedMainFrameIsPinnedToLeftSide { true };
</span><span class="cx">     bool m_cachedMainFrameIsPinnedToRightSide { true };
</span><span class="cx">     bool m_cachedMainFrameIsPinnedToTopSide { true };
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitWebProcessWebPageWebPagemessagesin"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in  2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in     2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -302,9 +302,10 @@
</span><span class="cx">     DragCancelled()
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if ENABLE(DATA_INTERACTION)
</del><ins>+#if PLATFORM(IOS_FAMILY) && ENABLE(DRAG_SUPPORT)
</ins><span class="cx">     RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t allowedActions)
</span><span class="cx">     RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t allowedActions)
</span><ins>+    DidConcludeDrop()
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     # Popup menu.
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitWebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm    2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm       2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -822,19 +822,63 @@
</span><span class="cx">     send(Messages::WebPageProxy::DidHandleAdditionalDragItemsRequest(didHandleDrag));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPage::didConcludeDrop()
+{
+    m_pendingImageElementsForDropSnapshot.clear();
+}
+
</ins><span class="cx"> void WebPage::didConcludeEditDrag()
</span><span class="cx"> {
</span><ins>+    send(Messages::WebPageProxy::WillReceiveEditDragSnapshot());
+
+    layoutIfNeeded();
+
+    m_pendingImageElementsForDropSnapshot.clear();
+
+    bool waitingForAnyImageToLoad = false;
+    auto& frame = m_page->focusController().focusedOrMainFrame();
+    if (auto range = frame.selection().selection().toNormalizedRange()) {
+        for (TextIterator iterator(range.get()); !iterator.atEnd(); iterator.advance()) {
+            auto* node = iterator.node();
+            if (!is<HTMLImageElement>(node))
+                continue;
+
+            auto& imageElement = downcast<HTMLImageElement>(*node);
+            auto* cachedImage = imageElement.cachedImage();
+            if (cachedImage && cachedImage->image() && cachedImage->image()->isNull()) {
+                m_pendingImageElementsForDropSnapshot.add(&imageElement);
+                waitingForAnyImageToLoad = true;
+            }
+        }
+    }
+
+    if (!waitingForAnyImageToLoad)
+        computeAndSendEditDragSnapshot();
+}
+
+void WebPage::didFinishLoadingImageForElement(WebCore::HTMLImageElement& element)
+{
+    if (m_pendingImageElementsForDropSnapshot.isEmpty())
+        return;
+
+    m_pendingImageElementsForDropSnapshot.remove(&element);
+
+    if (m_pendingImageElementsForDropSnapshot.isEmpty())
+        computeAndSendEditDragSnapshot();
+}
+
+void WebPage::computeAndSendEditDragSnapshot()
+{
</ins><span class="cx">     Optional<TextIndicatorData> textIndicatorData;
</span><del>-
</del><span class="cx">     static auto defaultTextIndicatorOptionsForEditDrag = TextIndicatorOptionIncludeSnapshotOfAllVisibleContentWithoutSelection | TextIndicatorOptionExpandClipBeyondVisibleRect | TextIndicatorOptionPaintAllContent | TextIndicatorOptionIncludeMarginIfRangeMatchesSelection | TextIndicatorOptionPaintBackgrounds | TextIndicatorOptionComputeEstimatedBackgroundColor| TextIndicatorOptionUseSelectionRectForSizing | TextIndicatorOptionIncludeSnapshotWithSelectionHighlight;
</span><span class="cx">     auto& frame = m_page->focusController().focusedOrMainFrame();
</span><span class="cx">     if (auto range = frame.selection().selection().toNormalizedRange()) {
</span><del>-        if (auto textIndicator = TextIndicator::createWithRange(*range, defaultTextIndicatorOptionsForEditDrag, TextIndicatorPresentationTransition::None, FloatSize()))
</del><ins>+        if (auto textIndicator = TextIndicator::createWithRange(*range, defaultTextIndicatorOptionsForEditDrag, TextIndicatorPresentationTransition::None, { }))
</ins><span class="cx">             textIndicatorData = textIndicator->data();
</span><span class="cx">     }
</span><ins>+    send(Messages::WebPageProxy::DidReceiveEditDragSnapshot(WTFMove(textIndicatorData)));
+}
</ins><span class="cx"> 
</span><del>-    send(Messages::WebPageProxy::DidConcludeEditDrag(WTFMove(textIndicatorData)));
-}
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void WebPage::sendTapHighlightForNodeIfNecessary(uint64_t requestID, Node* node)
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitLegacymacChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/ChangeLog (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/ChangeLog     2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/ChangeLog        2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -1,3 +1,230 @@
</span><ins>+2019-05-26  Babak Shafiei  <bshafiei@apple.com>
+
+        Cherry-pick r245778. rdar://problem/35205373
+
+    [iOS] Dropped text, attachments, and images should animate into place
+    https://bugs.webkit.org/show_bug.cgi?id=198243
+    <rdar://problem/35205373>
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebCore:
+    
+    Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit
+    changelog for more detail.
+    
+    Test: DragAndDropTests.DropPreviewForImageInEditableArea
+    
+    * loader/EmptyClients.h:
+    * page/ChromeClient.h:
+    * page/Page.cpp:
+    (WebCore::Page::didFinishLoadingImageForElement):
+    * page/Page.h:
+    * rendering/RenderImage.cpp:
+    (WebCore::RenderImage::notifyFinished):
+    
+    Source/WebKit:
+    
+    Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in
+    <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor
+    and augment existing logic for taking snapshots after performing a drop in an editable content.
+    
+    Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web
+    view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of
+    the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade
+    from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop
+    preview to the drag caret rect. During this process, snapshot (2) is completely ignored.
+    
+    This was effectively a halfway implemention of the desired effect of animating the dropped content into place
+    and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation
+    was not possible in modern WebKit (without using synchronous IPC).
+    
+    Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot
+    (2) above and clean up some parts of the drop animation in editable content. See below for more details.
+    
+    * UIProcess/API/Cocoa/WKWebView.mm:
+    (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]):
+    
+    Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See
+    TestWebKitAPI changes for more detail.
+    
+    * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and
+    DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop,
+    until after the final edit drag snapshot has been received.
+    
+    * UIProcess/ios/DragDropInteractionState.h:
+    
+    Add some new methods to help manage the lifecycle of drop preview provider blocks.
+    
+    * UIProcess/ios/DragDropInteractionState.mm:
+    (WebKit::createTargetedDragPreview):
+    
+    Drive-by fix: make this return a RetainPtr.
+    
+    (WebKit::DragDropInteractionState::prepareForDelayedDropPreview):
+    
+    Stores a drop preview provider, given to us by UIKit.
+    
+    (WebKit::DragDropInteractionState::deliverDelayedDropPreview):
+    
+    Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are
+    taken following an edit drag (this is additionally after all images in the inserted fragment have finished
+    loading).
+    
+    (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders):
+    
+    Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session
+    cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers
+    are always invoked when cleaning up the drag session.
+    
+    (WebKit::DragDropInteractionState::previewForDragItem const):
+    (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):
+    
+    Call clearAllDelayedItemPreviewProviders.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::willReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didConcludeEditDrag): Deleted.
+    
+    More plumbing (see changes to DidConcludeEditDrag above).
+    
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView cleanupInteraction]):
+    (-[WKContentView cleanUpDragSourceSessionState]):
+    (-[WKContentView _willReceiveEditDragSnapshot]):
+    (-[WKContentView _didReceiveEditDragSnapshot:]):
+    
+    Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and
+    when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of
+    -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is
+    received.
+    
+    (-[WKContentView _deliverDelayedDropPreviewIfPossible:]):
+    (-[WKContentView _didPerformDragOperation:]):
+    (-[WKContentView textEffectsWindow]):
+    
+    Drive-by fix to remove a workaround for a deprecation warning.
+    
+    (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]):
+    (-[WKContentView dropInteraction:concludeDrop:]):
+    
+    Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are
+    guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives
+    after the drop is concluded.
+    
+    (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
+    (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]):
+    
+    Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time
+    to update the drop preview. We do this in _didReceiveEditDragSnapshot.
+    
+    (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]):
+    (-[WKContentView _didConcludeEditDrag:]): Deleted.
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::willReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didConcludeDrop):
+    (WebKit::WebPageProxy::didConcludeEditDrag): Deleted.
+    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+    (WebKit::WebChromeClient::didFinishLoadingImageForElement):
+    * WebProcess/WebCoreSupport/WebChromeClient.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/WebPage.messages.in:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::didConcludeDrop):
+    
+    If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear
+    out the set here.
+    
+    (WebKit::WebPage::didConcludeEditDrag):
+    
+    After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI
+    process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not
+    including any selected content. The other snapshot is of the selected content only. However, when dropping
+    images (or a text selection containing images), these images may not yet have been loaded. If that is the case,
+    these images will appear to be missing from these snapshots.
+    
+    To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content
+    range have finished loading. We can tell that all dropped images have finished loading by using a new client
+    hook that is invoked when an image has finished loading.
+    
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    (WebKit::WebPage::computeAndSendEditDragSnapshot):
+    
+    Snapshot the selected content and send it to the UI process.
+    
+    Source/WebKitLegacy/mac:
+    
+    Add a new chrome client method. See other changelogs for more detail.
+    
+    * WebCoreSupport/WebChromeClient.h:
+    * WebCoreSupport/WebChromeClient.mm:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    
+    Source/WebKitLegacy/win:
+    
+    * WebCoreSupport/WebChromeClient.cpp:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    * WebCoreSupport/WebChromeClient.h:
+    
+    Tools:
+    
+    Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail.
+    
+    * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+    (TestWebKitAPI::isCompletelyWhite):
+    (TestWebKitAPI::TEST):
+    
+    Add a test that drags and drops an image into a contenteditable element, and then observes the resulting
+    UITargetedDragPreviews upon drop.
+    
+    * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+    * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+    (-[DragAndDropSimulator _resetSimulatedState]):
+    (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
+    (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]):
+    
+    Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction
+    delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer
+    the end of the simulated drag and drop until after drag previews have been received during an edit drag.
+    
+    (-[DragAndDropSimulator dropPreviews]):
+    (-[DragAndDropSimulator delayedDropPreviews]):
+    
+    Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which
+    previews were provided asynchronously.
+    
+    (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
+    * TestWebKitAPI/ios/UIKitSPI.h:
+    
+    Stage the new private drop interacton delegate method.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-05-26  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+            [iOS] Dropped text, attachments, and images should animate into place
+            https://bugs.webkit.org/show_bug.cgi?id=198243
+            <rdar://problem/35205373>
+
+            Reviewed by Tim Horton.
+
+            Add a new chrome client method. See other changelogs for more detail.
+
+            * WebCoreSupport/WebChromeClient.h:
+            * WebCoreSupport/WebChromeClient.mm:
+            (WebChromeClient::didFinishLoadingImageForElement):
+
</ins><span class="cx"> 2019-05-08  Alex Christensen  <achristensen@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Don't crash when DOMNode.addEventListener:listener:useCapture: is called with a nil listener
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitLegacymacWebCoreSupportWebChromeClienth"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h      2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h 2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -31,6 +31,10 @@
</span><span class="cx"> #import <WebCore/FocusDirection.h>
</span><span class="cx"> #import <wtf/Forward.h>
</span><span class="cx"> 
</span><ins>+namespace WebCore {
+class HTMLImageElement;
+}
+
</ins><span class="cx"> @class WebView;
</span><span class="cx"> 
</span><span class="cx"> // FIXME: This class is used as a concrete class on Mac, but on iOS this is an abstract
</span><span class="lines">@@ -102,6 +106,8 @@
</span><span class="cx">     WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const final;
</span><span class="cx">     WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const final;
</span><span class="cx"> 
</span><ins>+    void didFinishLoadingImageForElement(WebCore::HTMLImageElement&) final;
+
</ins><span class="cx">     PlatformPageClient platformPageClient() const final;
</span><span class="cx">     void contentsSizeChanged(WebCore::Frame&, const WebCore::IntSize&) const final;
</span><span class="cx">     void intrinsicContentsSizeChanged(const WebCore::IntSize&) const final { }
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitLegacymacWebCoreSupportWebChromeClientmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm     2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm        2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -610,6 +610,10 @@
</span><span class="cx">     return rootViewToScreen(r);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebChromeClient::didFinishLoadingImageForElement(HTMLImageElement&)
+{
+}
+
</ins><span class="cx"> PlatformPageClient WebChromeClient::platformPageClient() const
</span><span class="cx"> {
</span><span class="cx">     return 0;
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitLegacywinChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/ChangeLog (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/ChangeLog     2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/ChangeLog        2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -1,3 +1,228 @@
</span><ins>+2019-05-26  Babak Shafiei  <bshafiei@apple.com>
+
+        Cherry-pick r245778. rdar://problem/35205373
+
+    [iOS] Dropped text, attachments, and images should animate into place
+    https://bugs.webkit.org/show_bug.cgi?id=198243
+    <rdar://problem/35205373>
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebCore:
+    
+    Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit
+    changelog for more detail.
+    
+    Test: DragAndDropTests.DropPreviewForImageInEditableArea
+    
+    * loader/EmptyClients.h:
+    * page/ChromeClient.h:
+    * page/Page.cpp:
+    (WebCore::Page::didFinishLoadingImageForElement):
+    * page/Page.h:
+    * rendering/RenderImage.cpp:
+    (WebCore::RenderImage::notifyFinished):
+    
+    Source/WebKit:
+    
+    Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in
+    <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor
+    and augment existing logic for taking snapshots after performing a drop in an editable content.
+    
+    Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web
+    view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of
+    the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade
+    from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop
+    preview to the drag caret rect. During this process, snapshot (2) is completely ignored.
+    
+    This was effectively a halfway implemention of the desired effect of animating the dropped content into place
+    and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation
+    was not possible in modern WebKit (without using synchronous IPC).
+    
+    Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot
+    (2) above and clean up some parts of the drop animation in editable content. See below for more details.
+    
+    * UIProcess/API/Cocoa/WKWebView.mm:
+    (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]):
+    
+    Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See
+    TestWebKitAPI changes for more detail.
+    
+    * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and
+    DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop,
+    until after the final edit drag snapshot has been received.
+    
+    * UIProcess/ios/DragDropInteractionState.h:
+    
+    Add some new methods to help manage the lifecycle of drop preview provider blocks.
+    
+    * UIProcess/ios/DragDropInteractionState.mm:
+    (WebKit::createTargetedDragPreview):
+    
+    Drive-by fix: make this return a RetainPtr.
+    
+    (WebKit::DragDropInteractionState::prepareForDelayedDropPreview):
+    
+    Stores a drop preview provider, given to us by UIKit.
+    
+    (WebKit::DragDropInteractionState::deliverDelayedDropPreview):
+    
+    Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are
+    taken following an edit drag (this is additionally after all images in the inserted fragment have finished
+    loading).
+    
+    (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders):
+    
+    Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session
+    cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers
+    are always invoked when cleaning up the drag session.
+    
+    (WebKit::DragDropInteractionState::previewForDragItem const):
+    (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):
+    
+    Call clearAllDelayedItemPreviewProviders.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::willReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didConcludeEditDrag): Deleted.
+    
+    More plumbing (see changes to DidConcludeEditDrag above).
+    
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView cleanupInteraction]):
+    (-[WKContentView cleanUpDragSourceSessionState]):
+    (-[WKContentView _willReceiveEditDragSnapshot]):
+    (-[WKContentView _didReceiveEditDragSnapshot:]):
+    
+    Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and
+    when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of
+    -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is
+    received.
+    
+    (-[WKContentView _deliverDelayedDropPreviewIfPossible:]):
+    (-[WKContentView _didPerformDragOperation:]):
+    (-[WKContentView textEffectsWindow]):
+    
+    Drive-by fix to remove a workaround for a deprecation warning.
+    
+    (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]):
+    (-[WKContentView dropInteraction:concludeDrop:]):
+    
+    Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are
+    guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives
+    after the drop is concluded.
+    
+    (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
+    (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]):
+    
+    Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time
+    to update the drop preview. We do this in _didReceiveEditDragSnapshot.
+    
+    (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]):
+    (-[WKContentView _didConcludeEditDrag:]): Deleted.
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::willReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didConcludeDrop):
+    (WebKit::WebPageProxy::didConcludeEditDrag): Deleted.
+    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+    (WebKit::WebChromeClient::didFinishLoadingImageForElement):
+    * WebProcess/WebCoreSupport/WebChromeClient.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/WebPage.messages.in:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::didConcludeDrop):
+    
+    If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear
+    out the set here.
+    
+    (WebKit::WebPage::didConcludeEditDrag):
+    
+    After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI
+    process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not
+    including any selected content. The other snapshot is of the selected content only. However, when dropping
+    images (or a text selection containing images), these images may not yet have been loaded. If that is the case,
+    these images will appear to be missing from these snapshots.
+    
+    To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content
+    range have finished loading. We can tell that all dropped images have finished loading by using a new client
+    hook that is invoked when an image has finished loading.
+    
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    (WebKit::WebPage::computeAndSendEditDragSnapshot):
+    
+    Snapshot the selected content and send it to the UI process.
+    
+    Source/WebKitLegacy/mac:
+    
+    Add a new chrome client method. See other changelogs for more detail.
+    
+    * WebCoreSupport/WebChromeClient.h:
+    * WebCoreSupport/WebChromeClient.mm:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    
+    Source/WebKitLegacy/win:
+    
+    * WebCoreSupport/WebChromeClient.cpp:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    * WebCoreSupport/WebChromeClient.h:
+    
+    Tools:
+    
+    Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail.
+    
+    * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+    (TestWebKitAPI::isCompletelyWhite):
+    (TestWebKitAPI::TEST):
+    
+    Add a test that drags and drops an image into a contenteditable element, and then observes the resulting
+    UITargetedDragPreviews upon drop.
+    
+    * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+    * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+    (-[DragAndDropSimulator _resetSimulatedState]):
+    (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
+    (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]):
+    
+    Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction
+    delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer
+    the end of the simulated drag and drop until after drag previews have been received during an edit drag.
+    
+    (-[DragAndDropSimulator dropPreviews]):
+    (-[DragAndDropSimulator delayedDropPreviews]):
+    
+    Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which
+    previews were provided asynchronously.
+    
+    (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
+    * TestWebKitAPI/ios/UIKitSPI.h:
+    
+    Stage the new private drop interacton delegate method.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-05-26  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+            [iOS] Dropped text, attachments, and images should animate into place
+            https://bugs.webkit.org/show_bug.cgi?id=198243
+            <rdar://problem/35205373>
+
+            Reviewed by Tim Horton.
+
+            * WebCoreSupport/WebChromeClient.cpp:
+            (WebChromeClient::didFinishLoadingImageForElement):
+            * WebCoreSupport/WebChromeClient.h:
+
</ins><span class="cx"> 2019-05-03  Daniel Bates  <dabates@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Pass KeyboardEvent by reference in more places
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitLegacywinWebCoreSupportWebChromeClientcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.cpp (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.cpp    2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.cpp       2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -703,6 +703,10 @@
</span><span class="cx">     return Icon::createIconForFiles(filenames);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebChromeClient::didFinishLoadingImageForElement(WebCore::HTMLImageElement&)
+{
+}
+
</ins><span class="cx"> void WebChromeClient::setCursor(const Cursor& cursor)
</span><span class="cx"> {
</span><span class="cx">     if (!cursor.platformCursor())
</span></span></pre></div>
<a id="branchessafari60812420branchSourceWebKitLegacywinWebCoreSupportWebChromeClienth"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.h      2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Source/WebKitLegacy/win/WebCoreSupport/WebChromeClient.h 2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -172,6 +172,8 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr<WebCore::Icon> createIconForFiles(const Vector<String>&) final;
</span><span class="cx"> 
</span><ins>+    void didFinishLoadingImageForElement(WebCore::HTMLImageElement&) final;
+
</ins><span class="cx"> private:
</span><span class="cx">     COMPtr<IWebUIDelegate> uiDelegate();
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari60812420branchToolsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Tools/ChangeLog (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Tools/ChangeLog       2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Tools/ChangeLog  2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -1,5 +1,256 @@
</span><span class="cx"> 2019-05-26  Babak Shafiei  <bshafiei@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r245778. rdar://problem/35205373
+
+    [iOS] Dropped text, attachments, and images should animate into place
+    https://bugs.webkit.org/show_bug.cgi?id=198243
+    <rdar://problem/35205373>
+    
+    Reviewed by Tim Horton.
+    
+    Source/WebCore:
+    
+    Add some hooks to notify the chrome client when an HTMLImageElement's image is finished loading. See WebKit
+    changelog for more detail.
+    
+    Test: DragAndDropTests.DropPreviewForImageInEditableArea
+    
+    * loader/EmptyClients.h:
+    * page/ChromeClient.h:
+    * page/Page.cpp:
+    (WebCore::Page::didFinishLoadingImageForElement):
+    * page/Page.h:
+    * rendering/RenderImage.cpp:
+    (WebCore::RenderImage::notifyFinished):
+    
+    Source/WebKit:
+    
+    Adds support for targeted drop animations on iOS in modern WebKit by adopting UIKit SPI introduced in
+    <rdar://problem/31075005> to allow updating the drop preview mid-flight. To get the animation right, we refactor
+    and augment existing logic for taking snapshots after performing a drop in an editable content.
+    
+    Currently, upon dropping in editable content, we first snapshot the web view and temporarily cover the real web
+    view with this snapshot. When the TextIndicator data arrives that contains (1) a snapshot of the visible part of
+    the web view ignoring the selection, and (2) a snapshot of just the selected contents after drop, we crossfade
+    from the web view snapshot to the snapshot in (1) using a hard-coded time delay (~500ms), and target the drop
+    preview to the drag caret rect. During this process, snapshot (2) is completely ignored.
+    
+    This was effectively a halfway implemention of the desired effect of animating the dropped content into place
+    and crossfading to the final content; before UIKit implemented updateable drag previews, the full implementation
+    was not possible in modern WebKit (without using synchronous IPC).
+    
+    Now that we're able to update the drag preview in the middle of the drop animation, we can now utilize snapshot
+    (2) above and clean up some parts of the drop animation in editable content. See below for more details.
+    
+    * UIProcess/API/Cocoa/WKWebView.mm:
+    (-[WKWebView _doAfterReceivingEditDragSnapshotForTesting:]):
+    
+    Add a testing hook to perform the given block after any pending edit drag snapshot has been received. See
+    TestWebKitAPI changes for more detail.
+    
+    * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+    * UIProcess/PageClient.h:
+    * UIProcess/WebPageProxy.h:
+    * UIProcess/WebPageProxy.messages.in:
+    
+    Split up the existing DidConcludeEditDrag IPC message into two messages: WillReceiveEditDragSnapshot and
+    DidReceiveEditDragSnapshot. This allows us to defer cleaning up the drag session state during an edit drop,
+    until after the final edit drag snapshot has been received.
+    
+    * UIProcess/ios/DragDropInteractionState.h:
+    
+    Add some new methods to help manage the lifecycle of drop preview provider blocks.
+    
+    * UIProcess/ios/DragDropInteractionState.mm:
+    (WebKit::createTargetedDragPreview):
+    
+    Drive-by fix: make this return a RetainPtr.
+    
+    (WebKit::DragDropInteractionState::prepareForDelayedDropPreview):
+    
+    Stores a drop preview provider, given to us by UIKit.
+    
+    (WebKit::DragDropInteractionState::deliverDelayedDropPreview):
+    
+    Invokes the stored drop preview providers with given text indicator data. This is invoked after snapshots are
+    taken following an edit drag (this is additionally after all images in the inserted fragment have finished
+    loading).
+    
+    (WebKit::DragDropInteractionState::clearAllDelayedItemPreviewProviders):
+    
+    Invokes all stored drop preview providers with a nil preview. This is invoked in any case where drag session
+    cleanup occurs earlier than normal (e.g., if the web process crashes during drop), and ensures that the handlers
+    are always invoked when cleaning up the drag session.
+    
+    (WebKit::DragDropInteractionState::previewForDragItem const):
+    (WebKit::DragDropInteractionState::dragAndDropSessionsDidEnd):
+    
+    Call clearAllDelayedItemPreviewProviders.
+    
+    * UIProcess/ios/PageClientImplIOS.h:
+    * UIProcess/ios/PageClientImplIOS.mm:
+    (WebKit::PageClientImpl::willReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didReceiveEditDragSnapshot):
+    (WebKit::PageClientImpl::didConcludeEditDrag): Deleted.
+    
+    More plumbing (see changes to DidConcludeEditDrag above).
+    
+    * UIProcess/ios/WKContentViewInteraction.h:
+    * UIProcess/ios/WKContentViewInteraction.mm:
+    (-[WKContentView cleanupInteraction]):
+    (-[WKContentView cleanUpDragSourceSessionState]):
+    (-[WKContentView _willReceiveEditDragSnapshot]):
+    (-[WKContentView _didReceiveEditDragSnapshot:]):
+    
+    Set _waitingForEditDragSnapshot to YES in the gap between when -_willReceiveEditDragSnapshot is invoked, and
+    when -_didReceiveEditDragSnapshot is invoked. If _waitingForEditDragSnapshot is YES, we bail out of
+    -cleanUpDragSourceSessionState, and instead clean up drag session state after the edit drag snapshot is
+    received.
+    
+    (-[WKContentView _deliverDelayedDropPreviewIfPossible:]):
+    (-[WKContentView _didPerformDragOperation:]):
+    (-[WKContentView textEffectsWindow]):
+    
+    Drive-by fix to remove a workaround for a deprecation warning.
+    
+    (-[WKContentView dropInteraction:item:willAnimateDropWithAnimator:]):
+    (-[WKContentView dropInteraction:concludeDrop:]):
+    
+    Implement this hook to ensure that the unselected content snapshot view and visible content snapshot view are
+    guaranteed to be removed from the view after a drop in editable content, even if the drag edit snapshot arrives
+    after the drop is concluded.
+    
+    (-[WKContentView dropInteraction:previewForDroppingItem:withDefault:]):
+    (-[WKContentView _dropInteraction:delayedPreviewProviderForDroppingItem:previewProvider:]):
+    
+    Implement the new UIKit SPI here. UIKit hands us a preview provider here, which we can invoke at a later time
+    to update the drop preview. We do this in _didReceiveEditDragSnapshot.
+    
+    (-[WKContentView _doAfterReceivingEditDragSnapshotForTesting:]):
+    (-[WKContentView _didConcludeEditDrag:]): Deleted.
+    * UIProcess/ios/WebPageProxyIOS.mm:
+    (WebKit::WebPageProxy::willReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didReceiveEditDragSnapshot):
+    (WebKit::WebPageProxy::didConcludeDrop):
+    (WebKit::WebPageProxy::didConcludeEditDrag): Deleted.
+    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+    (WebKit::WebChromeClient::didFinishLoadingImageForElement):
+    * WebProcess/WebCoreSupport/WebChromeClient.h:
+    * WebProcess/WebPage/WebPage.cpp:
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    * WebProcess/WebPage/WebPage.h:
+    * WebProcess/WebPage/WebPage.messages.in:
+    * WebProcess/WebPage/ios/WebPageIOS.mm:
+    (WebKit::WebPage::didConcludeDrop):
+    
+    If an edit drag has been concluded, there's no need to hang on to pending dropped image elements anymore; clear
+    out the set here.
+    
+    (WebKit::WebPage::didConcludeEditDrag):
+    
+    After concluding an edit drag, we try to deliver two web content snapshots to the UI process, so that the UI
+    process can assemble a targeted drop preview for UIKit. One snapshot is of the visible content area, not
+    including any selected content. The other snapshot is of the selected content only. However, when dropping
+    images (or a text selection containing images), these images may not yet have been loaded. If that is the case,
+    these images will appear to be missing from these snapshots.
+    
+    To ensure that we don't take this snapshot too early, defer it until all image elements in the dropped content
+    range have finished loading. We can tell that all dropped images have finished loading by using a new client
+    hook that is invoked when an image has finished loading.
+    
+    (WebKit::WebPage::didFinishLoadingImageForElement):
+    (WebKit::WebPage::computeAndSendEditDragSnapshot):
+    
+    Snapshot the selected content and send it to the UI process.
+    
+    Source/WebKitLegacy/mac:
+    
+    Add a new chrome client method. See other changelogs for more detail.
+    
+    * WebCoreSupport/WebChromeClient.h:
+    * WebCoreSupport/WebChromeClient.mm:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    
+    Source/WebKitLegacy/win:
+    
+    * WebCoreSupport/WebChromeClient.cpp:
+    (WebChromeClient::didFinishLoadingImageForElement):
+    * WebCoreSupport/WebChromeClient.h:
+    
+    Tools:
+    
+    Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail.
+    
+    * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+    (TestWebKitAPI::isCompletelyWhite):
+    (TestWebKitAPI::TEST):
+    
+    Add a test that drags and drops an image into a contenteditable element, and then observes the resulting
+    UITargetedDragPreviews upon drop.
+    
+    * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+    * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+    (-[DragAndDropSimulator _resetSimulatedState]):
+    (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
+    (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]):
+    
+    Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction
+    delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer
+    the end of the simulated drag and drop until after drag previews have been received during an edit drag.
+    
+    (-[DragAndDropSimulator dropPreviews]):
+    (-[DragAndDropSimulator delayedDropPreviews]):
+    
+    Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which
+    previews were provided asynchronously.
+    
+    (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
+    * TestWebKitAPI/ios/UIKitSPI.h:
+    
+    Stage the new private drop interacton delegate method.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-05-26  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+            [iOS] Dropped text, attachments, and images should animate into place
+            https://bugs.webkit.org/show_bug.cgi?id=198243
+            <rdar://problem/35205373>
+
+            Reviewed by Tim Horton.
+
+            Adjusts the iOS dragging simulator, and adds a new API test. See below for more detail.
+
+            * TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm:
+            (TestWebKitAPI::isCompletelyWhite):
+            (TestWebKitAPI::TEST):
+
+            Add a test that drags and drops an image into a contenteditable element, and then observes the resulting
+            UITargetedDragPreviews upon drop.
+
+            * TestWebKitAPI/cocoa/DragAndDropSimulator.h:
+            * TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm:
+            (-[DragAndDropSimulator _resetSimulatedState]):
+            (-[DragAndDropSimulator runFrom:to:additionalItemRequestLocations:]):
+            (-[DragAndDropSimulator _concludeDropAndPerformOperationIfNecessary]):
+
+            Teach the iOS version of DragAndDropSimulator to invoke -dropInteraction:concludeDrop: on the drop interaction
+            delegate when the drop finishes. This additionally uses _doAfterReceivingEditDragSnapshotForTesting: to defer
+            the end of the simulated drag and drop until after drag previews have been received during an edit drag.
+
+            (-[DragAndDropSimulator dropPreviews]):
+            (-[DragAndDropSimulator delayedDropPreviews]):
+
+            Have the drag and drop simulator remember which previews were returned by the delegate on drop, as well as which
+            previews were provided asynchronously.
+
+            (-[DragAndDropSimulator _webView:dataInteractionOperationWasHandled:forSession:itemProviders:]):
+            * TestWebKitAPI/ios/UIKitSPI.h:
+
+            Stage the new private drop interacton delegate method.
+
+2019-05-26  Babak Shafiei  <bshafiei@apple.com>
+
</ins><span class="cx">         Cherry-pick r245775. rdar://problem/35205373
</span><span class="cx"> 
</span><span class="cx">     [iOS] Respect -[NSItemProvider preferredPresentationSize] when dropping images
</span></span></pre></div>
<a id="branchessafari60812420branchToolsTestWebKitAPITestsiosDragAndDropTestsIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm  2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/Tests/ios/DragAndDropTestsIOS.mm     2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -2107,6 +2107,44 @@
</span><span class="cx">     TestWebKitAPI::Util::run(&done);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static BOOL isCompletelyWhite(UIImage *image)
+{
+    auto data = adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage)));
+    auto* dataPtr = CFDataGetBytePtr(data.get());
+    int imageWidth = image.size.width;
+    for (int row = 0; row < image.size.height; ++row) {
+        for (int column = 0; column < imageWidth; ++column) {
+            int pixelOffset = ((imageWidth * row) + column) * 4;
+            if (dataPtr[pixelOffset] != 0xFF || dataPtr[pixelOffset + 1] != 0xFF || dataPtr[pixelOffset + 2] != 0xFF)
+                return NO;
+        }
+    }
+    return YES;
+}
+
+TEST(DragAndDropTests, DropPreviewForImageInEditableArea)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    [webView synchronouslyLoadTestPageNamed:@"image-and-contenteditable"];
+
+    // Ensure that the resulting snapshot on drop contains only the dragged image.
+    [webView stringByEvaluatingJavaScript:@"editor.style.border = 'none'; editor.style.outline = 'none'"];
+
+    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
+    [simulator runFrom:CGPointMake(100, 50) to:CGPointMake(100, 300)];
+
+    NSArray *dropPreviews = [simulator dropPreviews];
+    NSArray *delayedDropPreviews = [simulator delayedDropPreviews];
+    EXPECT_EQ(1U, dropPreviews.count);
+    EXPECT_EQ(1U, delayedDropPreviews.count);
+    EXPECT_EQ(UITargetedDragPreview.class, [dropPreviews.firstObject class]);
+    EXPECT_EQ(UITargetedDragPreview.class, [delayedDropPreviews.firstObject class]);
+
+    UITargetedDragPreview *finalPreview = (UITargetedDragPreview *)delayedDropPreviews.firstObject;
+    EXPECT_EQ(UIImageView.class, finalPreview.view.class);
+    EXPECT_FALSE(isCompletelyWhite([(UIImageView *)finalPreview.view image]));
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(DRAG_SUPPORT) && PLATFORM(IOS_FAMILY)
</span></span></pre></div>
<a id="branchessafari60812420branchToolsTestWebKitAPIcocoaDragAndDropSimulatorh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h      2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/cocoa/DragAndDropSimulator.h 2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -111,6 +111,8 @@
</span><span class="cx"> @property (nonatomic, readonly) NSArray *finalSelectionRects;
</span><span class="cx"> @property (nonatomic, readonly) CGRect lastKnownDragCaretRect;
</span><span class="cx"> @property (nonatomic, readonly) NSArray<UITargetedDragPreview *> *liftPreviews;
</span><ins>+@property (nonatomic, readonly) NSArray *dropPreviews;
+@property (nonatomic, readonly) NSArray *delayedDropPreviews;
</ins><span class="cx"> @property (nonatomic, readonly) BOOL suppressedSelectionCommandsDuringDrop;
</span><span class="cx"> 
</span><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span></span></pre></div>
<a id="branchessafari60812420branchToolsTestWebKitAPIiosDragAndDropSimulatorIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm    2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/DragAndDropSimulatorIOS.mm       2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> 
</span><span class="cx"> #import <UIKit/UIDragInteraction.h>
</span><span class="cx"> #import <UIKit/UIDragItem.h>
</span><ins>+#import <UIKit/UIDropInteraction.h>
</ins><span class="cx"> #import <UIKit/UIInteraction.h>
</span><span class="cx"> #import <WebKit/WKWebViewPrivate.h>
</span><span class="cx"> #import <WebKit/_WKFocusedElementInfo.h>
</span><span class="lines">@@ -310,6 +311,8 @@
</span><span class="cx">     RetainPtr<NSMutableDictionary<NSNumber *, NSValue *>>_remainingAdditionalItemRequestLocationsByProgress;
</span><span class="cx">     RetainPtr<NSMutableArray<NSValue *>>_queuedAdditionalItemRequestLocations;
</span><span class="cx">     RetainPtr<NSMutableArray<UITargetedDragPreview *>> _liftPreviews;
</span><ins>+    RetainPtr<NSMutableArray> _dropPreviews;
+    RetainPtr<NSMutableArray> _delayedDropPreviews;
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr<NSMutableArray<_WKAttachment *>> _insertedAttachments;
</span><span class="cx">     RetainPtr<NSMutableArray<_WKAttachment *>> _removedAttachments;
</span><span class="lines">@@ -317,6 +320,7 @@
</span><span class="cx">     bool _hasStartedInputSession;
</span><span class="cx">     double _currentProgress;
</span><span class="cx">     bool _isDoneWithCurrentRun;
</span><ins>+    bool _isDoneWaitingForDelayedDropPreviews;
</ins><span class="cx">     DragAndDropPhase _phase;
</span><span class="cx"> 
</span><span class="cx">     BOOL _suppressedSelectionCommandsDuringDrop;
</span><span class="lines">@@ -373,6 +377,7 @@
</span><span class="cx">     _phase = DragAndDropPhaseBeginning;
</span><span class="cx">     _currentProgress = 0;
</span><span class="cx">     _isDoneWithCurrentRun = false;
</span><ins>+    _isDoneWaitingForDelayedDropPreviews = true;
</ins><span class="cx">     _observedEventNames = adoptNS([[NSMutableArray alloc] init]);
</span><span class="cx">     _insertedAttachments = adoptNS([[NSMutableArray alloc] init]);
</span><span class="cx">     _removedAttachments = adoptNS([[NSMutableArray alloc] init]);
</span><span class="lines">@@ -384,6 +389,8 @@
</span><span class="cx">     _remainingAdditionalItemRequestLocationsByProgress = nil;
</span><span class="cx">     _queuedAdditionalItemRequestLocations = adoptNS([[NSMutableArray alloc] init]);
</span><span class="cx">     _liftPreviews = adoptNS([[NSMutableArray alloc] init]);
</span><ins>+    _dropPreviews = adoptNS([[NSMutableArray alloc] init]);
+    _delayedDropPreviews = adoptNS([[NSMutableArray alloc] init]);
</ins><span class="cx">     _hasStartedInputSession = false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -454,6 +461,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Util::run(&_isDoneWithCurrentRun);
</span><ins>+    Util::run(&_isDoneWaitingForDelayedDropPreviews);
</ins><span class="cx">     [_webView clearMessageHandlers:dragAndDropEventNames()];
</span><span class="cx">     _finalSelectionRects = [_webView selectionRectsAfterPresentationUpdate];
</span><span class="cx"> 
</span><span class="lines">@@ -470,11 +478,30 @@
</span><span class="cx">     _lastKnownDragCaretRect = [_webView _dragCaretRect];
</span><span class="cx">     auto operation = [_lastKnownDropProposal operation];
</span><span class="cx">     if (operation != UIDropOperationCancel && operation != UIDropOperationForbidden) {
</span><ins>+        NSInteger dropPreviewIndex = 0;
+        __block NSUInteger numberOfPendingPreviews = [_dropSession items].count;
+        _isDoneWaitingForDelayedDropPreviews = !numberOfPendingPreviews;
+        for (UIDragItem *item in [_dropSession items]) {
+            auto defaultPreview = adoptNS([[UITargetedDragPreview alloc] initWithView:_webView.get()]);
+            id <UIDropInteractionDelegate_Staging_31075005> delegate = (id <UIDropInteractionDelegate_Staging_31075005>)[_webView dropInteractionDelegate];
+            UIDropInteraction *interaction = [_webView dropInteraction];
+            [_dropPreviews addObject:[delegate dropInteraction:interaction previewForDroppingItem:item withDefault:defaultPreview.get()] ?: NSNull.null];
+            [_delayedDropPreviews addObject:NSNull.null];
+            [delegate _dropInteraction:interaction delayedPreviewProviderForDroppingItem:item previewProvider:^(UITargetedDragPreview *preview) {
+                if (preview)
+                    [_delayedDropPreviews setObject:preview atIndexedSubscript:dropPreviewIndex];
+
+                if (!--numberOfPendingPreviews)
+                    _isDoneWaitingForDelayedDropPreviews = true;
+            }];
+            ++dropPreviewIndex;
+        }
</ins><span class="cx">         [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] performDrop:_dropSession.get()];
</span><span class="cx">         _phase = DragAndDropPhasePerformingDrop;
</span><span class="cx">     } else {
</span><del>-        _isDoneWithCurrentRun = YES;
</del><ins>+        _isDoneWithCurrentRun = true;
</ins><span class="cx">         _phase = DragAndDropPhaseCancelled;
</span><ins>+        [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] concludeDrop:_dropSession.get()];
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnd:_dropSession.get()];
</span><span class="lines">@@ -644,6 +671,16 @@
</span><span class="cx">     return _liftPreviews.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (NSArray<UITargetedDragPreview *> *)dropPreviews
+{
+    return _dropPreviews.get();
+}
+
+- (NSArray<UITargetedDragPreview *> *)delayedDropPreviews
+{
+    return _delayedDropPreviews.get();
+}
+
</ins><span class="cx"> - (CGRect)lastKnownDragCaretRect
</span><span class="cx"> {
</span><span class="cx">     return _lastKnownDragCaretRect;
</span><span class="lines">@@ -729,10 +766,14 @@
</span><span class="cx"> - (void)_webView:(WKWebView *)webView dataInteractionOperationWasHandled:(BOOL)handled forSession:(id)session itemProviders:(NSArray<NSItemProvider *> *)itemProviders
</span><span class="cx"> {
</span><span class="cx">     _suppressedSelectionCommandsDuringDrop = [_webView textInputContentView]._shouldSuppressSelectionCommands;
</span><del>-    _isDoneWithCurrentRun = true;
</del><span class="cx"> 
</span><span class="cx">     if (self.dropCompletionBlock)
</span><span class="cx">         self.dropCompletionBlock(handled, itemProviders);
</span><ins>+
+    [_webView _doAfterReceivingEditDragSnapshotForTesting:^{
+        [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] concludeDrop:_dropSession.get()];
+        _isDoneWithCurrentRun = true;
+    }];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (UIDropProposal *)_webView:(WKWebView *)webView willUpdateDropProposalToProposal:(UIDropProposal *)proposal forSession:(id <UIDropSession>)session
</span></span></pre></div>
<a id="branchessafari60812420branchToolsTestWebKitAPIiosUIKitSPIh"></a>
<div class="modfile"><h4>Modified: branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/UIKitSPI.h (245780 => 245781)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/UIKitSPI.h    2019-05-26 18:21:44 UTC (rev 245780)
+++ branches/safari-608.1.24.20-branch/Tools/TestWebKitAPI/ios/UIKitSPI.h       2019-05-26 18:21:55 UTC (rev 245781)
</span><span class="lines">@@ -183,4 +183,12 @@
</span><span class="cx"> - (void)setNextPreviousItemsVisible:(BOOL)visible;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+
+@protocol UIDropInteractionDelegate_Staging_31075005 <UIDropInteractionDelegate>
+- (void)_dropInteraction:(UIDropInteraction *)interaction delayedPreviewProviderForDroppingItem:(UIDragItem *)item previewProvider:(void(^)(UITargetedDragPreview *preview))previewProvider;
+@end
+
+#endif // PLATFORM(IOS)
+
</ins><span class="cx"> #endif // PLATFORM(IOS_FAMILY)
</span></span></pre>
</div>
</div>

</body>
</html>