Automatic update from web-platform-tests Support dragging JS File objects to native drop targets When a web app places a JS File object (new File([bytes], 'photo.jpg')) into a dragstart handler, the blob bytes were previously discarded in DataObject::ToWebDragData(). This CL reads the blob bytes synchronously at drag-start time using SyncedFileReaderAccumulator::Load() and passes them as a BinaryDataItem through the IPC pipeline. Platform-specific delivery to native drop targets is handled by the existing PrepareDragForFileContents() path, which is already enabled for Linux, ChromeOS, and Windows via BUILDFLAG guards in web_contents_view_aura.cc. Currently, image file types are supported via the GetSafeFilenameForImageFileContents() gate. To enable this feature, launch Chrome with: --enable-blink-features=DragAndDropJSFileObjects Bug: 41120809 Change-Id: Ibe12d867f7d01a972b7aeb6ce55660adb7300b27 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7603160 Reviewed-by: Rohan Raja <roraja@microsoft.com> Reviewed-by: Kent Tamura <tkent@chromium.org> Commit-Queue: Joone Hur <joonehur@microsoft.com> Cr-Commit-Position: refs/heads/main@{#1627402} -- wpt-commits: 6fd907a40e68c632146df346deba6ba60299e2d5 wpt-pr: 59744
100 lines
3.1 KiB
HTML
100 lines
3.1 KiB
HTML
<!doctype html>
|
|
<meta charset="utf-8">
|
|
<title>Drag and Drop: JS File Object (fallback to text/plain when feature disabled)</title>
|
|
<link rel="author" title="Microsoft" href="http://www.microsoft.com">
|
|
<link rel="help" href="https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/resources/testdriver.js"></script>
|
|
<script src="/resources/testdriver-vendor.js"></script>
|
|
<script src="/resources/testdriver-actions.js"></script>
|
|
|
|
<style>
|
|
.box {
|
|
display: inline-block;
|
|
border: 2px solid black;
|
|
width: 100px;
|
|
height: 100px;
|
|
margin: 20px;
|
|
vertical-align: top;
|
|
line-height: 100px;
|
|
text-align: center;
|
|
}
|
|
#drag-src { background: lightblue; }
|
|
#drop-tgt { background: lightgrey; }
|
|
</style>
|
|
|
|
<div id="drag-src" class="box" draggable="true">Source</div>
|
|
<div id="drop-tgt" class="box">Target</div>
|
|
|
|
<script>
|
|
'use strict';
|
|
|
|
function makePngBytes() {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = 1; canvas.height = 1;
|
|
const ctx = canvas.getContext('2d');
|
|
ctx.fillStyle = 'red';
|
|
ctx.fillRect(0, 0, 1, 1);
|
|
const bin = atob(canvas.toDataURL('image/png').split(',')[1]);
|
|
return Uint8Array.from(bin, c => c.charCodeAt(0));
|
|
}
|
|
|
|
const PNG_BYTES = makePngBytes();
|
|
|
|
// This test verifies the fallback path when DragAndDropJSFileObjects is
|
|
// disabled: a JS-constructed File object should be transferred as text/plain
|
|
// containing only the filename, with no binary file content available.
|
|
promise_test(async t => {
|
|
const dragSrc = document.getElementById('drag-src');
|
|
const dropTgt = document.getElementById('drop-tgt');
|
|
|
|
const dropWatcher = new Promise((resolve, reject) => {
|
|
dragSrc.ondragstart = t.step_func(e => {
|
|
const file = new File([PNG_BYTES], 'test.png', {type: 'image/png'});
|
|
e.dataTransfer.items.add(file);
|
|
e.dataTransfer.effectAllowed = 'copy';
|
|
});
|
|
|
|
dropTgt.ondragenter = e => {
|
|
e.preventDefault();
|
|
e.dataTransfer.dropEffect = 'copy';
|
|
};
|
|
dropTgt.ondragover = e => {
|
|
e.preventDefault();
|
|
e.dataTransfer.dropEffect = 'copy';
|
|
};
|
|
|
|
dropTgt.ondrop = t.step_func(async e => {
|
|
e.preventDefault();
|
|
try {
|
|
// When the feature is disabled, no binary file content is transferred.
|
|
assert_equals(e.dataTransfer.files.length, 0,
|
|
'No files should be in .files when feature is disabled');
|
|
|
|
// The filename should be available as text/plain.
|
|
const text = e.dataTransfer.getData('text/plain');
|
|
assert_equals(text, 'test.png',
|
|
'Filename should be transferred as text/plain fallback');
|
|
resolve();
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
});
|
|
|
|
await new test_driver.Actions()
|
|
.pointerMove(0, 0, {origin: dragSrc})
|
|
.pointerDown()
|
|
.pause(100)
|
|
.pointerMove(15, 15, {origin: dragSrc})
|
|
.pause(100)
|
|
.pointerMove(0, 0, {origin: dropTgt})
|
|
.pause(100)
|
|
.pointerUp()
|
|
.send();
|
|
|
|
await dropWatcher;
|
|
}, 'JS File falls back to text/plain filename when DragAndDropJSFileObjects is disabled');
|
|
</script>
|