mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 10:08:49 +01:00
Allow multiple entries with the same mimetype in dataTransfer (#150425)
Currently our data transfer implementation only allows a single entry of each mimeType. There can only be a single `image/gif` file for example. However this doesn't match how the DOM apis work. If you drop multiple gifs into VS Code for example, the DataTransfer you get contains entries for each of the gifs. This change allows us to also support DataTransfers that have multiple entries with the same mime type. Just like with the DOM, we support constructing these duplicate mime data transfers internally, but do not allow extensions to create them As part of this change, I've also made a few clean ups: - Add helpers for creating dataTransfer items - Clarify when adding a data transfer item should `append` or `replace` - Adopt some helper functions in a few more places
This commit is contained in:
@@ -40,6 +40,7 @@ import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/ed
|
||||
import type * as vscode from 'vscode';
|
||||
import * as types from './extHostTypes';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { VSDataTransfer } from 'vs/base/common/dataTransfer';
|
||||
|
||||
export namespace Command {
|
||||
|
||||
@@ -1980,14 +1981,13 @@ export namespace DataTransferItem {
|
||||
|
||||
export namespace DataTransfer {
|
||||
export function toDataTransfer(value: extHostProtocol.DataTransferDTO, resolveFileData: (dataItemIndex: number) => Promise<Uint8Array>): types.DataTransfer {
|
||||
const newDataTransfer = new types.DataTransfer();
|
||||
value.items.forEach(([type, item], index) => {
|
||||
newDataTransfer.set(type, DataTransferItem.toDataTransferItem(item, () => resolveFileData(index)));
|
||||
const init = value.items.map(([type, item], index) => {
|
||||
return [type, DataTransferItem.toDataTransferItem(item, () => resolveFileData(index))] as const;
|
||||
});
|
||||
return newDataTransfer;
|
||||
return new types.DataTransfer(init);
|
||||
}
|
||||
|
||||
export async function toDataTransferDTO(value: vscode.DataTransfer): Promise<extHostProtocol.DataTransferDTO> {
|
||||
export async function toDataTransferDTO(value: vscode.DataTransfer | VSDataTransfer): Promise<extHostProtocol.DataTransferDTO> {
|
||||
const newDTO: extHostProtocol.DataTransferDTO = { items: [] };
|
||||
|
||||
const promises: Promise<any>[] = [];
|
||||
|
||||
@@ -2451,18 +2451,33 @@ export class DataTransferItem {
|
||||
|
||||
@es5ClassCompat
|
||||
export class DataTransfer {
|
||||
#items = new Map<string, DataTransferItem>();
|
||||
#items = new Map<string, DataTransferItem[]>();
|
||||
|
||||
constructor(init?: Iterable<readonly [string, DataTransferItem]>) {
|
||||
for (const [mime, item] of init ?? []) {
|
||||
const existing = this.#items.get(mime);
|
||||
if (existing) {
|
||||
existing.push(item);
|
||||
} else {
|
||||
this.#items.set(mime, [item]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get(mimeType: string): DataTransferItem | undefined {
|
||||
return this.#items.get(mimeType);
|
||||
return this.#items.get(mimeType)?.[0];
|
||||
}
|
||||
|
||||
set(mimeType: string, value: DataTransferItem): void {
|
||||
this.#items.set(mimeType, value);
|
||||
// This intentionally overwrites all entries for a given mimetype.
|
||||
// This is similar to how the DOM DataTransfer type works
|
||||
this.#items.set(mimeType, [value]);
|
||||
}
|
||||
|
||||
forEach(callbackfn: (value: DataTransferItem, key: string) => void): void {
|
||||
this.#items.forEach(callbackfn);
|
||||
for (const [mime, items] of this.#items) {
|
||||
items.forEach(item => callbackfn(item, mime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user