Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: ddcd91a27bd801bebc876705a4d6e1e062f9ad2e
      
https://github.com/WebKit/WebKit/commit/ddcd91a27bd801bebc876705a4d6e1e062f9ad2e
  Author: Wenson Hsieh <[email protected]>
  Date:   2025-10-25 (Sat, 25 Oct 2025)

  Changed paths:
    M Source/WebCore/dom/DataTransferItem.cpp
    M Source/WebCore/dom/DataTransferItem.h
    M Source/WebCore/dom/DataTransferItemList.cpp
    M Source/WebCore/platform/DragData.h
    M Source/WebCore/platform/Pasteboard.h
    M Source/WebCore/platform/cocoa/DragDataCocoa.mm
    M Source/WebCore/platform/mac/PasteboardMac.mm
    M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
    M Source/WebKit/UIProcess/API/mac/WKWebViewMac.h
    M Source/WebKit/UIProcess/API/mac/WKWebViewMac.mm
    M Source/WebKit/UIProcess/mac/WebViewImpl.mm
    M Tools/TestWebKitAPI/Tests/WebKitCocoa/image-and-file-upload.html
    M Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm
    M Tools/TestWebKitAPI/mac/TestDraggingInfo.mm

  Log Message:
  -----------
  facebook.com: Unable to drag and drop images (from Photos, Finder) into new 
album
https://bugs.webkit.org/show_bug.cgi?id=301472
rdar://150848219

Reviewed by Abrar Rahman Protyasha.

When dragging an image from either Photos or Finder and dropping into the album 
creation UI on
facebook.com in Safari, the file drop is effectively ignored. This happens 
because Facebook's script
expects the `dragenter` event to contain a non-empty list of DataTransfer 
items, with:

1. `item.kind` equal to `"file"`
2. A non-empty `item.type` that's not `text/html`, `text/plain`, or 
`text/uri-list`.

WebKit currently exposes an empty list of items (due to restrictions on reading 
drag items before
the drop is being performed), which causes Facebook's script to avoid calling 
`preventDefault()` on
`dragenter`. Both Blink and Gecko expose a list of data transfer items in this 
case that contains
the dropped file(s) and their MIME types, but attempts to get the file 
(`getAsFile()`) before the
`drop` event has been fired will result in a null `File` object. This patch 
aligns WebKit's behavior
to the other engines (with some caveats — see below), which fixes this bug on 
Facebook.

Tests: added to DragAndDropTests.DragPromisedImageFileIntoFileUpload

Tests: Tools/TestWebKitAPI/Tests/WebKitCocoa/image-and-file-upload.html
       Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm
       Tools/TestWebKitAPI/mac/TestDraggingInfo.mm
* Source/WebCore/dom/DataTransferItem.cpp:
(WebCore::DataTransferItem::create):

Add a `Kind` argument to this creation method, to create a `DataTransferItem` 
with a given type,
representing either a `String` or a placeholder for a `File`. Use this when 
dispatching drag update
events to expose file data transfer items that only expose type information.

(WebCore::DataTransferItem::DataTransferItem):
(WebCore::DataTransferItem::isFile const):
(WebCore::DataTransferItem::kind const):
* Source/WebCore/dom/DataTransferItem.h:

Introduce an `m_kind` member variable, and use it for the `kind()` attribute 
instead of basing it
off of the presence of `m_file`. This is because `file` items may now have a 
null `m_file`, before
the `drop` event is dispatched.

(WebCore::DataTransferItem::isFile const): Deleted.
* Source/WebCore/dom/DataTransferItemList.cpp:
(WebCore::DataTransferItemList::add):
(WebCore::DataTransferItemList::ensureItems const):

Apply the main fix here — only expose `File`-backed `DataTransferItem`s when 
the `DataTransfer` can
read data; when the `DataTransfer` can only read types, we instead expose a 
list of items based on
the promised MIME types.

In order to reduce fingerprinting surface when the user drags over unintended 
drop targets, we
additionally only expose known image and media types.

(WebCore::DataTransferItemList::didSetStringData):
* Source/WebCore/platform/DragData.h:
(WebCore::DragData::DragData):
(WebCore::DragData::setPromisedFileMIMETypes):
(WebCore::DragData::promisedFileMIMETypes const):

Add a list of MIME types of promised files when dragging over drop targets.

* Source/WebCore/platform/Pasteboard.h:
(WebCore::Pasteboard::Pasteboard):
(WebCore::Pasteboard::promisedFileMIMETypes const):
* Source/WebCore/platform/cocoa/DragDataCocoa.mm:
(WebCore::DragData::DragData):
* Source/WebCore/platform/mac/PasteboardMac.mm:
(WebCore::Pasteboard::Pasteboard):
(WebCore::Pasteboard::create):

Plumb the list of promised file MIME types from `DragData` → `Pasteboard`.

* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/UIProcess/API/mac/WKWebViewMac.h:
* Source/WebKit/UIProcess/API/mac/WKWebViewMac.mm:
(-[WKWebView _promisedFileMIMETypes:]):

Add a helper method to extract a list of MIME types for promised files in the 
drag session, before
the drag operation (drop) is performed. We get this via 
`-[NSFilePromiseReceiver fileTypes]` on the
dragged items, and otherwise fall back to getting preferred MIME types from 
dragged file URLs.

* Source/WebKit/UIProcess/mac/WebViewImpl.mm:
(WebKit::applicationFlagsForDrag):
(WebKit::WebViewImpl::draggingEntered):
(WebKit::WebViewImpl::draggingUpdated):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/image-and-file-upload.html:
* Tools/TestWebKitAPI/Tests/mac/DragAndDropTestsMac.mm:
(TEST(DragAndDropTests, DragPromisedImageFileIntoFileUpload)):

Augment an existing API test to also exercise this scenario by dumping the 
contents of the
`e.dataTransfer.items` while dragging.

* Tools/TestWebKitAPI/mac/TestDraggingInfo.mm:
(-[TestDraggingInfo 
enumerateDraggingItemsWithOptions:forView:classes:searchOptions:usingBlock:]):

Adjust this testing helper class to lazily generate `NSFilePromiseReceiver`s 
when WebKit asks to
`-enumerateDraggingItemsWithOptions:forView:classes:searchOptions:usingBlock:` 
to ensure that we
don't end up with dozens of redundant file promise receivers when simulating a 
drop. This was
previously not necessary because we only called this once when performing a 
drop, but we now need to
call it continually while dragging over the view.

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



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

Reply via email to