diff options
author | Matt Bierner <matb@microsoft.com> | 2022-11-10 22:57:37 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-10 22:57:37 +0300 |
commit | 0308afcc5c3e3f0a03c6bd158a09712d7cb4d7b8 (patch) | |
tree | c67e2efc6521e08256a26752976cddf85ced673b | |
parent | aa37e17423137d2b27008bb83f8bccdf8a2a2728 (diff) |
Transform `text/uri-list` mime values in data transfers (#165768)
* Take different approach for transforming
* Remove unused param
-rw-r--r-- | src/vs/base/common/dataTransfer.ts | 15 | ||||
-rw-r--r-- | src/vs/editor/browser/dnd.ts | 13 | ||||
-rw-r--r-- | src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts | 4 | ||||
-rw-r--r-- | src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts | 4 | ||||
-rw-r--r-- | src/vs/workbench/api/common/extHost.protocol.ts | 1 | ||||
-rw-r--r-- | src/vs/workbench/api/common/extHostTypeConverters.ts | 69 | ||||
-rw-r--r-- | src/vs/workbench/browser/dnd.ts | 3 |
7 files changed, 77 insertions, 32 deletions
diff --git a/src/vs/base/common/dataTransfer.ts b/src/vs/base/common/dataTransfer.ts index c58d77cde53..7dd6d220b18 100644 --- a/src/vs/base/common/dataTransfer.ts +++ b/src/vs/base/common/dataTransfer.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { distinct } from 'vs/base/common/arrays'; import { URI } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; @@ -92,3 +93,17 @@ export class VSDataTransfer { return mimeType.toLowerCase(); } } + + +export const UriList = Object.freeze({ + // http://amundsen.com/hypermedia/urilist/ + create: (entries: ReadonlyArray<string | URI>): string => { + return distinct(entries.map(x => x.toString())).join('\r\n'); + }, + split: (str: string): string[] => { + return str.split('\r\n'); + }, + parse: (str: string): string[] => { + return UriList.split(str).filter(value => !value.startsWith('#')); + } +}); diff --git a/src/vs/editor/browser/dnd.ts b/src/vs/editor/browser/dnd.ts index 43b7b4914dd..c872a52e476 100644 --- a/src/vs/editor/browser/dnd.ts +++ b/src/vs/editor/browser/dnd.ts @@ -4,8 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { DataTransfers } from 'vs/base/browser/dnd'; -import { distinct } from 'vs/base/common/arrays'; -import { createFileDataTransferItem, createStringDataTransferItem, IDataTransferItem, VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { createFileDataTransferItem, createStringDataTransferItem, IDataTransferItem, UriList, VSDataTransfer } from 'vs/base/common/dataTransfer'; import { Mimes } from 'vs/base/common/mime'; import { URI } from 'vs/base/common/uri'; import { CodeDataTransfers, extractEditorsDropData, FileAdditionalNativeProperties } from 'vs/platform/dnd/browser/dnd'; @@ -64,13 +63,3 @@ export function addExternalEditorsDropData(dataTransfer: VSDataTransfer, dragEve dataTransfer.delete(internal); } } - -export const UriList = Object.freeze({ - // http://amundsen.com/hypermedia/urilist/ - create: (entries: ReadonlyArray<string | URI>): string => { - return distinct(entries.map(x => x.toString())).join('\r\n'); - }, - parse: (str: string): string[] => { - return str.split('\r\n').filter(value => !value.startsWith('#')); - } -}); diff --git a/src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts b/src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts index 02fa00393c6..22b431f4b57 100644 --- a/src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts +++ b/src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts @@ -7,11 +7,11 @@ import { DataTransfers } from 'vs/base/browser/dnd'; import { addDisposableListener } from 'vs/base/browser/dom'; import { CancelablePromise, createCancelablePromise, raceCancellation } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { createStringDataTransferItem, VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { createStringDataTransferItem, UriList, VSDataTransfer } from 'vs/base/common/dataTransfer'; import { Disposable } from 'vs/base/common/lifecycle'; import { Mimes } from 'vs/base/common/mime'; import { generateUuid } from 'vs/base/common/uuid'; -import { toVSDataTransfer, UriList } from 'vs/editor/browser/dnd'; +import { toVSDataTransfer } from 'vs/editor/browser/dnd'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IBulkEditService, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; diff --git a/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts b/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts index 1d72b9307f7..84632383d27 100644 --- a/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts +++ b/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts @@ -5,12 +5,12 @@ import { raceCancellation } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { UriList, VSDataTransfer } from 'vs/base/common/dataTransfer'; import { Disposable } from 'vs/base/common/lifecycle'; import { Mimes } from 'vs/base/common/mime'; import { relativePath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; -import { addExternalEditorsDropData, toVSDataTransfer, UriList } from 'vs/editor/browser/dnd'; +import { addExternalEditorsDropData, toVSDataTransfer } from 'vs/editor/browser/dnd'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { IBulkEditService, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index b1cb83364df..8ebcb32fb66 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1392,6 +1392,7 @@ export interface DataTransferItemDTO { readonly id: string; readonly asString: string; readonly fileData: IDataTransferFileDTO | undefined; + readonly uriListData?: ReadonlyArray<string | UriComponents>; } export interface DataTransferDTO { diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 8721bb81444..ff023d1fc3b 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -5,11 +5,14 @@ import { asArray, coalesce, isNonEmptyArray } from 'vs/base/common/arrays'; import { encodeBase64, VSBuffer } from 'vs/base/common/buffer'; +import { IDataTransferItem, UriList, VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { once } from 'vs/base/common/functional'; import * as htmlContent from 'vs/base/common/htmlContent'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ResourceSet } from 'vs/base/common/map'; import { marked } from 'vs/base/common/marked/marked'; import { parse } from 'vs/base/common/marshalling'; +import { Mimes } from 'vs/base/common/mime'; import { cloneAndChange } from 'vs/base/common/objects'; import { isEmptyObject, isNumber, isString, isUndefinedOrNull, withNullAsUndefined } from 'vs/base/common/types'; import { URI, UriComponents } from 'vs/base/common/uri'; @@ -19,8 +22,8 @@ import { IPosition } from 'vs/editor/common/core/position'; import * as editorRange from 'vs/editor/common/core/range'; import { ISelection } from 'vs/editor/common/core/selection'; import { IContentDecorationRenderOptions, IDecorationOptions, IDecorationRenderOptions, IThemeDecorationRenderOptions } from 'vs/editor/common/editorCommon'; -import * as languages from 'vs/editor/common/languages'; import * as encodedTokenAttributes from 'vs/editor/common/encodedTokenAttributes'; +import * as languages from 'vs/editor/common/languages'; import * as languageSelector from 'vs/editor/common/languageSelector'; import { EndOfLineSequence, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; @@ -39,8 +42,6 @@ import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGro import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import type * as vscode from 'vscode'; import * as types from './extHostTypes'; -import { once } from 'vs/base/common/functional'; -import { IDataTransferItem, VSDataTransfer } from 'vs/base/common/dataTransfer'; export namespace Command { @@ -1966,7 +1967,7 @@ export namespace ViewBadge { } export namespace DataTransferItem { - export function toDataTransferItem(item: extHostProtocol.DataTransferItemDTO, resolveFileData: () => Promise<Uint8Array>): types.DataTransferItem { + export function to(mime: string, item: extHostProtocol.DataTransferItemDTO, resolveFileData: () => Promise<Uint8Array>): types.DataTransferItem { const file = item.fileData; if (file) { return new class extends types.DataTransferItem { @@ -1978,16 +1979,62 @@ export namespace DataTransferItem { }; } }('', item.id); - } else { - return new types.DataTransferItem(item.asString); } + + if (mime === Mimes.uriList && item.uriListData) { + return new types.DataTransferItem(reviveUriList(item.uriListData)); + } + + return new types.DataTransferItem(item.asString); + } + + export async function from(mime: string, item: vscode.DataTransferItem | IDataTransferItem): Promise<extHostProtocol.DataTransferItemDTO> { + const stringValue = await item.asString(); + + if (mime === Mimes.uriList) { + return { + id: (item as IDataTransferItem | types.DataTransferItem).id, + asString: '', + fileData: undefined, + uriListData: serializeUriList(stringValue), + }; + } + + const fileValue = item.asFile(); + return { + id: (item as IDataTransferItem | types.DataTransferItem).id, + asString: stringValue, + fileData: fileValue ? { name: fileValue.name, uri: fileValue.uri } : undefined, + }; + } + + function serializeUriList(stringValue: string): ReadonlyArray<string | URI> { + return UriList.split(stringValue).map(part => { + if (part.startsWith('#')) { + return part; + } + + try { + return URI.parse(part); + } catch { + // noop + } + + return part; + }); + } + + function reviveUriList(parts: ReadonlyArray<string | UriComponents>): string { + return UriList.create(parts.map(part => { + return typeof part === 'string' ? part : URI.revive(part); + })); } } export namespace DataTransfer { export function toDataTransfer(value: extHostProtocol.DataTransferDTO, resolveFileData: (itemId: string) => Promise<Uint8Array>): types.DataTransfer { const init = value.items.map(([type, item]) => { - return [type, DataTransferItem.toDataTransferItem(item, () => resolveFileData(item.id))] as const; + return [type, DataTransferItem.to(type, item, () => resolveFileData(item.id))] as const; }); return new types.DataTransfer(init); } @@ -1999,13 +2046,7 @@ export namespace DataTransfer { value.forEach((value, key) => { promises.push((async () => { - const stringValue = await value.asString(); - const fileValue = value.asFile(); - newDTO.items.push([key, { - id: (value as IDataTransferItem | types.DataTransferItem).id, - asString: stringValue, - fileData: fileValue ? { name: fileValue.name, uri: fileValue.uri } : undefined, - }]); + newDTO.items.push([key, await DataTransferItem.from(key, value)]); })()); }); diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 1a73aa0b4c5..93d9de7b0f6 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -10,7 +10,7 @@ import { IListDragAndDrop } from 'vs/base/browser/ui/list/list'; import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView'; import { ITreeDragOverReaction } from 'vs/base/browser/ui/tree/tree'; import { coalesce } from 'vs/base/common/arrays'; -import { VSDataTransfer } from 'vs/base/common/dataTransfer'; +import { UriList, VSDataTransfer } from 'vs/base/common/dataTransfer'; import { Emitter } from 'vs/base/common/event'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { stringify } from 'vs/base/common/marshalling'; @@ -19,7 +19,6 @@ import { FileAccess, Schemas } from 'vs/base/common/network'; import { isWindows } from 'vs/base/common/platform'; import { basename, isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; -import { UriList } from 'vs/editor/browser/dnd'; import { CodeDataTransfers, createDraggedEditorInputFromRawResourcesData, Extensions, extractEditorsAndFilesDropData, IDragAndDropContributionRegistry, IDraggedResourceEditorInput, IResourceStat } from 'vs/platform/dnd/browser/dnd'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; |