diff --git a/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts b/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts index 0947e16840e..79c2b2a9542 100644 --- a/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts +++ b/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts @@ -44,7 +44,7 @@ export async function tryGetUriListSnippet(document: vscode.TextDocument, dataTr } const uris: vscode.Uri[] = []; - for (const resource of urlList.split('\n')) { + for (const resource of urlList.split('\r\n')) { try { uris.push(vscode.Uri.parse(resource)); } catch { diff --git a/src/vs/editor/browser/dnd.ts b/src/vs/editor/browser/dnd.ts index b90bf922695..65d83ee29b8 100644 --- a/src/vs/editor/browser/dnd.ts +++ b/src/vs/editor/browser/dnd.ts @@ -56,8 +56,7 @@ export function addExternalEditorsDropData(dataTransfer: VSDataTransfer, dragEve } if (editorData.length) { - const str = distinct(editorData).join('\n'); - dataTransfer.replace(Mimes.uriList, createStringDataTransferItem(str)); + dataTransfer.replace(Mimes.uriList, createStringDataTransferItem(UriList.create(editorData))); } } @@ -65,3 +64,13 @@ export function addExternalEditorsDropData(dataTransfer: VSDataTransfer, dragEve dataTransfer.delete(internal); } } + +export const UriList = Object.freeze({ + // http://amundsen.com/hypermedia/urilist/ + create: (entries: ReadonlyArray): 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 b5d38905c78..6255f2daaec 100644 --- a/src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts +++ b/src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts @@ -10,7 +10,7 @@ import { createStringDataTransferItem, VSDataTransfer } from 'vs/base/common/dat import { Disposable } from 'vs/base/common/lifecycle'; import { Mimes } from 'vs/base/common/mime'; import { generateUuid } from 'vs/base/common/uuid'; -import { toVSDataTransfer } from 'vs/editor/browser/dnd'; +import { toVSDataTransfer, UriList } from 'vs/editor/browser/dnd'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IBulkEditService, ResourceEdit } from 'vs/editor/browser/services/bulkEditService'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; @@ -176,8 +176,7 @@ export class CopyPasteController extends Disposable implements IEditorContributi if (!dataTransfer.has(Mimes.uriList)) { const resources = await this._clipboardService.readResources(); if (resources.length) { - const value = resources.join('\n'); - dataTransfer.append(Mimes.uriList, createStringDataTransferItem(value)); + dataTransfer.append(Mimes.uriList, createStringDataTransferItem(UriList.create(resources))); } } diff --git a/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts b/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts index 0c050ea25f6..dbed8dd28ed 100644 --- a/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts +++ b/src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts @@ -9,7 +9,7 @@ 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 } from 'vs/editor/browser/dnd'; +import { addExternalEditorsDropData, toVSDataTransfer, UriList } from 'vs/editor/browser/dnd'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { IBulkEditService, ResourceEdit } from 'vs/editor/browser/services/bulkEditService'; @@ -137,9 +137,9 @@ class DefaultOnDropProvider implements DocumentOnDropEditProvider { return undefined; } - private getUriListInsertText(urlList: string): string | undefined { + private getUriListInsertText(strUriList: string): string | undefined { const uris: URI[] = []; - for (const resource of urlList.split('\n')) { + for (const resource of UriList.parse(strUriList)) { try { uris.push(URI.parse(resource)); } catch { diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index dc877136e37..f5061e30594 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -19,6 +19,7 @@ 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'; @@ -60,7 +61,7 @@ export async function extractTreeDropData(dataTransfer: VSDataTransfer): Promise if (dataTransfer.has(resourcesKey)) { try { const asString = await dataTransfer.get(resourcesKey)?.asString(); - const rawResourcesData = JSON.stringify(asString?.split('\n').filter(value => !value.startsWith('#'))); + const rawResourcesData = JSON.stringify(UriList.parse(asString ?? '')); editors.push(...createDraggedEditorInputFromRawResourcesData(rawResourcesData)); } catch (error) { // Invalid transfer @@ -70,11 +71,6 @@ export async function extractTreeDropData(dataTransfer: VSDataTransfer): Promise return editors; } -export function convertResourceUrlsToUriList(resourceUrls: string): string { - const asJson: URI[] = JSON.parse(resourceUrls); - return asJson.map(uri => uri.toString()).join('\n'); -} - export interface IResourcesDropHandlerOptions { /**