Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: cae8ae4bcecac04182955b33c075f88030233483
      
https://github.com/WebKit/WebKit/commit/cae8ae4bcecac04182955b33c075f88030233483
  Author: Ryosuke Niwa <[email protected]>
  Date:   2026-09-28 (Mon, 28 Sep 2026)

  Changed paths:
    M Source/WebCore/page/EventHandler.cpp
    M Source/WebCore/page/EventHandler.h
    M Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
    M Source/WebKit/UIProcess/WebPageProxy.cpp
    M Source/WebKit/UIProcess/WebPageProxy.h
    M Source/WebKit/UIProcess/ios/DragDropInteractionState.h
    M Source/WebKit/UIProcess/ios/DragDropInteractionState.mm
    M Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
    M Source/WebKit/WebProcess/WebPage/WebPage.cpp
    M Source/WebKit/WebProcess/WebPage/WebPage.h
    M Source/WebKit/WebProcess/WebPage/WebPage.messages.in
    M Source/cmake/WebKitSwiftFlags.cmake
    M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm
    M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ios/DragAndDropTestsIOS.mm

  Log Message:
  -----------
  [Site Isolation] Dragging from a cross-origin iframe to its parent frame 
twice hits an assertion in WebPage::willStartDrag()
https://bugs.webkit.org/show_bug.cgi?id=325315

Reviewed by Abrar Rahman Protyasha, Elliott Williams, and Wenson Hsieh.

When a drag started in a cross-origin iframe, WebDragClient::startDrag() set 
WebPage::m_isStartingDrag in
the iframe's process, but nothing ever reset it there. On iOS, 
PageClientImpl::startDrag() dropped the frame
identifier of the drag source, so WKContentView sent DidStartDrag and 
DragCancelled to the main frame's
process. DragEnded is routed by hit-testing the point where the drag ended, 
starting at the main frame, so
it never reached the iframe's process either when the drop landed in the parent 
frame. The next drag from
the iframe hit ASSERT(!m_isStartingDrag), and in release builds that process 
kept ignoring mouse events.
On both iOS and macOS the drag source also never received dragend.

Keep the drag source's frame identifier in DragSourceState on iOS, and use it 
to send DidStartDrag and
DragCancelled to the process of the frame that started the drag, as macOS 
already does for DidStartDrag.
WebPage::dragCancelled() now takes the frame identifier as well, since the 
iframe's process has no local
main frame.

To deliver dragend, WebPageProxy now remembers the drag source's frame when it 
receives StartDrag. After
DragEnded has been routed to the frame under the end point, if that frame's 
process is not the drag
source's, it sends the new DragSourceEnded message to the drag source's 
process. WebPage::dragSourceEnded()
maps the point from the main frame's root view into the local root with
convertFromRootViewAcrossIsolatedFrames(), resets the drag state, and calls the 
new
EventHandler::dragSourceEnded(), which is the part of dragSourceEndedAt() after 
the hit test. Skipping the
hit test there avoids forwarding the drag end to a remote frame under the point 
instead of dispatching
dragend.

Tests: TestWebKitAPI.DragAndDropTests.DragOutOfCrossOriginIframeTwice
       TestWebKitAPI.DragAndDropTests.DragOutOfSameSiteIframeTwice
       TestWebKitAPI.SiteIsolation.DragSourceEndedOutsideRemoteFrame
       Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm
       Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ios/DragAndDropTestsIOS.mm

* Source/WebCore/page/EventHandler.cpp:
(WebCore::EventHandler::dragSourceEndedAt):
(WebCore::EventHandler::dragSourceEnded):
* Source/WebCore/page/EventHandler.h:
* Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::startDrag):
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::dragEnded):
(WebKit::WebPageProxy::dragEndedInFrame):
(WebKit::WebPageProxy::dragCancelled):
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/ios/DragDropInteractionState.h:
* Source/WebKit/UIProcess/ios/DragDropInteractionState.mm:
(WebKit::DragDropInteractionState::initialDragSourceFrameID const):
(WebKit::DragDropInteractionState::dragSourceFrameIDForItem const):
(WebKit::DragDropInteractionState::stageDragItem):
* Source/WebKit/UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::startDrag):
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView _startDrag:item:nodeID:frameID:]):
(-[WKContentView _didHandleAdditionalDragItemsRequest:]):
(-[WKContentView dragInteraction:itemsForBeginningSession:]):
(-[WKContentView dragInteraction:sessionWillBegin:]):
(-[WKContentView dragInteraction:item:willAnimateCancelWithAnimator:]):
(-[WKContentView _startDrag:item:nodeID:]): Deleted.
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::dragSourceEnded):
(WebKit::WebPage::dragCancelled):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:
* Source/cmake/WebKitSwiftFlags.cmake:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(TestWebKitAPI::(SiteIsolation, DragSourceEndedOutsideRemoteFrame)):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ios/DragAndDropTestsIOS.mm:
(TestWebKitAPI::dragEventsForDraggingOutOfIframeTwice):
(TestWebKitAPI::TEST(DragAndDropTests, DragOutOfSameSiteIframeTwice)):
(TestWebKitAPI::TEST(DragAndDropTests, DragOutOfCrossOriginIframeTwice)):

Canonical link: https://commits.webkit.org/322103@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to