Skip to content

Commit 93a4526

Browse files
jooneJoone Hur
andauthored
Propose the new drag type (DownloadURL-list) (#1235)
Co-authored-by: Joone Hur <joonehur@microsoft.com>
1 parent 9af0b92 commit 93a4526

File tree

1 file changed

+100
-62
lines changed

1 file changed

+100
-62
lines changed
Lines changed: 100 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Explainer: Drag Multiple Virtual Files Out of Browser
22

3-
Author: [Joone Hur](https://github.com/joone)
3+
Author: [Joone Hur](https://github.com/joone) (Microsoft)
44

55
# Participate
66

@@ -19,37 +19,41 @@ Author: [Joone Hur](https://github.com/joone)
1919
- [Using an array](#using-an-array)
2020
- [Using newline-delimiters](#using-newline-delimiters)
2121
- [UX perspective](#ux-perspective)
22-
- [Proposed Solution: Extending the `DownloadURL` Data Format](#proposed-solution-extending-the-downloadurl-data-format)
23-
- [New `DownloadURL` Data Format](#new-downloadurl-data-format)
22+
- [Proposed Solution: a new drag type `DownloadURL-list`](#proposed-solution-a-new-drag-type-downloadurl-list)
23+
- [`DownloadURL-list` data format](#downloadurl-list-data-format)
2424
- [Why JSON?](#why-json)
25-
- [Backward Compatibility](#backward-compatibility)
2625
- [Future Considerations](#future-considerations)
2726
- [Security & UX Considerations](#security--ux-considerations)
2827
- [Drag Bomb](#drag-bomb)
2928
- [Limit Download Requests](#limit-download-requests)
3029
- [Single-click button to delete all downloaded files](#single-click-button-to-delete-all-downloaded-files)
3130
- [Acknowledgements](#acknowledgements)
32-
- [Referenecs](#referenecs)
31+
- [References](#references)
3332

3433
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
3534

3635
# Introduction
3736

38-
Chromium has supported a non-standard drag type (`DownloadURL`) that allows Windows users to drag a virtual file out of the browser. However, the `DownloadURL` drag type is limited to supporting only a single file per drag-and-drop operation. To support more robust workflows, we propose extending the DownloadURL drag type to allow multiple files to be dragged simultaneously.
37+
The `DownloadURL` drag type is a Chromium‑specific drag‑and‑drop mechanism historically used to enable dragging a resource from a web page into the operating system as a file. However, it is limited to supporting only a single file per drag-and-drop operation. To support more robust workflows, we propose a new `DownloadURL-list` drag type to allow multiple files to be dragged simultaneously.
3938

4039
# Goals
4140

42-
Enable users to drag multiple files from Chromium to a desktop folder on Windows using an extended `DownloadURL` drag type.
41+
Enable users to drag multiple files from Chromium to a desktop folder on Windows using the `DownloadURL-list` drag type.
4342

4443
# Non-goals
45-
This proposal does not aim to:
46-
* Enable drag-and-drop of files into other browser contexts, whether between the same browser or different browsers.
47-
* Standardize this behavior across browsers via W3C. The proposal is specific to Chromium and Windows environments.
44+
45+
Support drag‑and‑drop of files that require authentication or session validation to download; such flows are out of scope for this proposal.
4846

4947
# Problem: The Single-File Limitation
50-
The current DownloadURL drag type in Chromium supports only a single file per drag-and-drop operation, which restricts more advanced workflows and user experiences.
48+
49+
The existing DownloadURL drag type encodes only a single file as:
50+
```
51+
<mimeType>:<filename>:<url>
52+
```
53+
This prevents multi‑file workflows and forces users to drag each item individually.
5154

5255
## Example of Current Behavior
56+
5357
Here's a typical example demonstrating the limitation:
5458

5559
```js
@@ -78,6 +82,7 @@ The `DownloadURL` format requires a string with three colon-separated components
7882
When [it was initially proposed](https://lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-August/022121.html), it was designed for single-file use. Although multi-file support was requested, it has never been implemented.
7983

8084
## Developer Workarounds and Limitations
85+
8186
Because `DownloadURL` is a Chromium-specific feature and not part of any web standard, documentation is limited. As a result, developers have attempted to pass multiple files using arrays or newline-delimited strings, but these formats are not supported by the current implementation:
8287

8388
### Using an array
@@ -107,72 +112,99 @@ This single-file constraint presents a significant inconvenience for users who f
107112

108113
The current implementation forces users to perform multiple drag-and-drop operations for each file, which is inefficient and cumbersome.
109114

110-
# Proposed Solution: Extending the `DownloadURL` Data Format
115+
# Proposed Solution: a new drag type `DownloadURL-list`
111116

112-
To enable multi-file drag-and-drop, we propose extending the format of the `DownloadURL` drag type within the HTML Drag and Drop API to carry information for multiple files.
117+
To support multi-file drag-and-drop, we propose a new `DownloadURL` drag type within the HTML Drag and Drop API to carry information for multiple files.
113118

114-
## New `DownloadURL` Data Format
115-
The `DownloadURL` data format will be extended to support an array of a file URL, serialized as a JSON string. Each object within this JSON array will represent a single file, containing its essential properties: `mimeType`, `filename`, and `url`.
119+
## `DownloadURL-list` data format
120+
The `DownloadURL-list` data format will support an array of a file URL, serialized as a JSON string. Each object within this JSON array will represent a single file, containing its essential properties: `mimeType`, `filename`, and `url`.
116121

117122
**Example JavaScript Implementation:**
118123
```js
119124
function dragstart(event) {
120-
// JSON object for multiple files drag-and-drop.
121-
const data = [
125+
// JSON array for multiple files drag-and-drop.
126+
const files = [
122127
{
123-
'type': 'image/png',
124-
'name': 'file2.png',
125-
'url': 'http://example.com/file2.png'
128+
mimeType: 'image/png',
129+
filename: 'file2.png',
130+
url: 'http://example.com/file2.png'
126131
},
127132
{
128-
'type': 'image/jpeg',
129-
'name': 'file1.jpg',
130-
'url': 'http://example.com/file1.jpg'
133+
mimeType: 'image/jpeg',
134+
filename: 'file1.jpg',
135+
url: 'http://example.com/file1.jpg'
131136
}
132137
];
133-
event.dataTransfer.setData('DownloadURL', JSON.stringify(data));
138+
// Set the new drag type with JSON data
139+
event.dataTransfer.setData('DownloadURL-list', JSON.stringify(files));
134140
}
135141
```
136142

137-
This new format allows a single `DownloadURL` data type to represent multiple files in a structured and extensible manner.
143+
This new format allows representing multiple files in a structured and extensible manner.
138144

139145
## Why JSON?
140146

141-
As seen in the examples of developer attempts, we could use a simple format to represent multiple files. However, the existing format requires its own parsing code, and there's always a risk of parsing errors due to user mistakes or security attacks. Therefore, JSON will be used for the new format because it is structured, extensible, widely supported, and robust.
142-
143-
# Backward Compatibility
147+
JSON is chosen for the new format because it is structured, extensible, widely supported, and robust. It reduces the risk of parsing errors and security issues compared to custom string formats. JSON also makes it easier to add future metadata (such as file size, description, or permissions) without breaking compatibility.
148+
149+
## Complete Example
150+
151+
Below is a full working example of a web page that lets users select multiple files and drag them all to a desktop folder in a single gesture:
152+
153+
```html
154+
<!DOCTYPE html>
155+
<html lang="en">
156+
<head>
157+
<meta charset="UTF-8">
158+
<title>DownloadURL-list Demo</title>
159+
</head>
160+
<body>
161+
<div id="drag-area" draggable="true">
162+
<p draggable="true">Drag this box to a folder.</p>
163+
<fieldset draggable="true">
164+
<legend>Files</legend>
165+
<ul draggable="true">
166+
<li draggable="true">report.pdf</li>
167+
<li draggable="true">photo.png</li>
168+
<li draggable="true">data.csv</li>
169+
</ul>
170+
</fieldset>
171+
</div>
172+
173+
<script>
174+
const availableFiles = [
175+
{ mimetype: 'application/pdf', fileame: 'report.pdf', url: 'report.pdf' },
176+
{ mimetype: 'image/png', filename: 'photo.png', url: 'photo.png' },
177+
{ mimetype: 'text/csv', filename: 'data.csv', url: 'data.csv' }
178+
];
179+
180+
document.getElementById('drag-area').addEventListener('dragstart', (e) => {
181+
const baseURL = new URL('.', window.location.href).href;
182+
const selected = availableFiles.map((file) => ({
183+
mimetype: file.mimetype,
184+
filename: file.filename,
185+
url: new URL(file.url, baseURL).href,
186+
}));
187+
188+
if (selected.length === 0) {
189+
e.preventDefault();
190+
return;
191+
}
192+
193+
e.dataTransfer.effectAllowed = 'copy';
194+
e.dataTransfer.setData('DownloadURL-list', JSON.stringify(selected));
195+
});
196+
</script>
197+
</body>
198+
</html>
199+
```
144200

145-
A crucial aspect of this proposal is to maintain backward compatibility with the existing `DownloadURL` single-file format. The `DownloadURL` drag type will continue to support the existing colon-delimited string format (e.g., `mime-type:file_name:URL`) alongside the new JSON array format.
201+
When the user drags the box onto a desktop folder, the browser downloads all selected files to that folder in one operation.
202+
A working demo is available [here](https://joone.github.io/web/dnd/downloadURL-list/explainer/index.html).
146203

147204
# Future Considerations
148205

149-
The `DownloadURL` drag type was originally implemented in WebKit([bug 31090](https://bugs.webkit.org/show_bug.cgi?id=31090)) and was later adopted by Chromium. However, it never standardized—primarily because it didn’t gain support in Gecko([bug 570164](https://bugzilla.mozilla.org/show_bug.cgi?id=570164)), where it was treated as a Chrome-specific mechanism
150-
151-
We can find a standard way to support dragging virtual files or file URLs out of browsers. While we could use `DataTransferItemList` to set multiple URL items, and the browser could download them when dragged to the desktop, the `text/uri-list` format used for this is an older standard that only carries URL information. This is insufficient for our needs, as it doesn't support additional details like the MIME type or desired filename. Therefore, to provide this richer download information, we would need to define a new drag format for downloading, potentially using the `application/json` MIME type.
152-
153-
```js
154-
function dragstart(event) {
155-
// Define the list of files to be dragged.
156-
const filesToDownload = [
157-
{
158-
"downloadUrl": "http://example.com/file1.jpg",
159-
"name": "image_one.jpg",
160-
"mimeType": "image/jpeg"
161-
},
162-
{
163-
"downloadUrl": "http://example.com/file2.png",
164-
"name": "image_two.png",
165-
"mimeType": "image/png"
166-
}
167-
];
168-
169-
// Add each file as a separate JSON item to the DataTransferItemList.
170-
for (const file of filesToDownload) {
171-
const jsonString = JSON.stringify(file);
172-
event.dataTransfer.items.add(jsonString, "application/json");
173-
}
174-
}
175-
```
206+
The `DownloadURL` drag type was originally introduced in WebKit ([bug 31090](https://bugs.webkit.org/show_bug.cgi?id=31090)) and later adopted by Chromium, but it was never standardized because Firefox chose not to implement it ([bug 570164](https://bugzilla.mozilla.org/show_bug.cgi?id=570164)), treating it as a Chrome‑specific feature. Despite the lack of standardization, it has been widely used in mail applications such as Outlook and GMail within Chromium‑based browsers, enabling users to drag mail attachments out of the browser for many years.
207+
Proposing a new `DownloadURL-list` drag type as a web standard provides a more extensible and interoperable solution. It also opens the door to additional scenarios, including drag‑and‑drop between browsers and native applications like WebView based applications, or file managers.
176208

177209
# Security & UX Considerations
178210

@@ -193,13 +225,19 @@ If the user does not consent to multiple downloads, the entire set of dragged fi
193225
A single-click option should be provided in the Chrome UI (download bubble and `chrome://downloads`) to allow users to easily remove all downloaded files from their device if they no longer want them or downloaded them by mistake.
194226

195227
# Acknowledgements
196-
Thank you to Daniel Cheng, Lily Chen, Lingling Becker, Mike Jackson, Min Qin for their valuable feedback and input.
197-
198-
# Referenecs
228+
Many thanks for valuable feedback and advice from:
229+
- Lingling Becker
230+
- Mike Jackson
231+
- Alex Russell
232+
- Daniel Cheng (Google)
233+
- Lily Chen (Google)
234+
- Min Qin (Google)
235+
236+
# References
199237
* [Design: Enabling Multi‑File Drag‑and‑Drop in Chromium on Windows](https://docs.google.com/document/d/1nHPDuEE876RMKwYBVzWgPvsek-9X1NhZuFyY5Q5Z6YU/edit?usp=sharing)
200238
* [Chromium Issue](https://issues.chromium.org/issues/40736398)
201239
* [[whatwg] Proposal to drag virtual file out of browser](https://lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-August/022121.html)
202-
* [HTML Drag and Drop API \- Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)
203-
* [Ryan Seddon | Drag out files like Gmail](https://ryanseddon.com/html5/gmail-dragout/)
240+
* [HTML Drag and Drop API - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)
241+
* [Ryan Seddon | Drag out files like Gmail](https://ryanseddon.com/html5/gmail-dragout/)
204242
* [HTML Standard: 6.11 Drag and drop](https://html.spec.whatwg.org/multipage/dnd.html)
205-
* [Case Study \- Drag and Drop Download in Chrome | web.dev](https://web.dev/case-studies/box-dnd-download)
243+
* [Case Study - Drag and Drop Download in Chrome | web.dev](https://web.dev/case-studies/box-dnd-download)

0 commit comments

Comments
 (0)