mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 05:19:39 +00:00
Add API proposal for reading files in data transfer (#148596)
* Add experimental support for reading files in data transfer
Adds a new `DataTransfer.asFile` method which lets you get file objects from a `DataTransfer`. This is currently only hooked up for drop into editors.
A few follow ups:
- Right now the file data is also read eagerly when it is transfered to the extension host. Before shipping this we would make this happen lazily instead
- The drop into editor api does not provide a nice way to do anything with the dropped files.
We should at least support returning a `WorkspaceEdit`. However `WorkspaceEdit` only supports text files, so we would also need to add an API that lets it deal with binary files
* Make `asFile` return a value instead of a promise
`asFile().data()` already returns a promise so `asFile` doesn't also need to be async
* Trying resolving data files transfer lazily
* Cleaning up code for lazy drop
* Remove testing code
* Remove unneeded buffer serialize
* 💄
This commit is contained in:
parent
6a93adb40d
commit
93fd393a0e
|
@ -25,14 +25,19 @@ const imageFileExtensions = new Set<string>([
|
|||
|
||||
export function registerDropIntoEditor(selector: vscode.DocumentSelector) {
|
||||
return vscode.languages.registerDocumentOnDropProvider(selector, new class implements vscode.DocumentOnDropProvider {
|
||||
async provideDocumentOnDropEdits(document: vscode.TextDocument, position: vscode.Position, dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<vscode.SnippetTextEdit | undefined> {
|
||||
async provideDocumentOnDropEdits(document: vscode.TextDocument, position: vscode.Position, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<vscode.SnippetTextEdit | undefined> {
|
||||
const enabled = vscode.workspace.getConfiguration('markdown', document).get('editor.drop.enabled', true);
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const replacementRange = new vscode.Range(position, position);
|
||||
return this.tryInsertUriList(document, replacementRange, dataTransfer, token);
|
||||
}
|
||||
|
||||
private async tryInsertUriList(document: vscode.TextDocument, replacementRange: vscode.Range, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<vscode.SnippetTextEdit | undefined> {
|
||||
const urlList = await dataTransfer.get('text/uri-list')?.asString();
|
||||
if (!urlList) {
|
||||
if (!urlList || token.isCancellationRequested) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
@ -65,7 +70,7 @@ export function registerDropIntoEditor(selector: vscode.DocumentSelector) {
|
|||
}
|
||||
});
|
||||
|
||||
return new vscode.SnippetTextEdit(new vscode.Range(position, position), snippet);
|
||||
return new vscode.SnippetTextEdit(replacementRange, snippet);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,5 +7,6 @@
|
|||
"src/**/*",
|
||||
"../../src/vscode-dts/vscode.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.textEditorDrop.d.ts",
|
||||
"../../src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -3,8 +3,17 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export interface IDataTransferFile {
|
||||
readonly name: string;
|
||||
readonly uri?: URI;
|
||||
data(): Promise<Uint8Array>;
|
||||
}
|
||||
|
||||
export interface IDataTransferItem {
|
||||
asString(): Thenable<string>;
|
||||
asFile(): IDataTransferFile | undefined;
|
||||
value: any;
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ import { IMarkerData } from 'vs/platform/markers/common/markers';
|
|||
import { Codicon, CSSIcon } from 'vs/base/common/codicons';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
|
||||
/**
|
||||
* Open ended enum at runtime
|
||||
|
@ -1984,18 +1985,6 @@ export enum ExternalUriOpenerPriority {
|
|||
Preferred = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IDataTransferItem {
|
||||
asString(): Thenable<string>;
|
||||
value: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type IDataTransfer = Map<string, IDataTransferItem>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { CancellationError } from 'vs/base/common/errors';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { Position as EditorPosition } from 'vs/editor/common/core/position';
|
||||
import { IPosition, Position as EditorPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range as EditorRange } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as languages from 'vs/editor/common/languages';
|
||||
|
@ -23,12 +23,14 @@ import { ITextModel } from 'vs/editor/common/model';
|
|||
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
|
||||
import { decodeSemanticTokensDto } from 'vs/editor/common/services/semanticTokensDto';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { DataTransferCache } from 'vs/workbench/api/common/shared/dataTransferCache';
|
||||
import { DataTransferConverter } from 'vs/workbench/api/common/shared/dataTransfer';
|
||||
import * as callh from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
|
||||
import * as search from 'vs/workbench/contrib/search/common/search';
|
||||
import * as typeh from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy';
|
||||
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
||||
import { ExtHostContext, ExtHostLanguageFeaturesShape, ICallHierarchyItemDto, ICodeActionDto, ICodeActionProviderMetadataDto, IdentifiableInlineCompletion, IdentifiableInlineCompletions, IDocumentFilterDto, IIndentationRuleDto, IInlayHintDto, ILanguageConfigurationDto, ILanguageWordDefinitionDto, ILinkDto, ILocationDto, ILocationLinkDto, IOnEnterRuleDto, IRegExpDto, ISignatureHelpProviderMetadataDto, ISuggestDataDto, ISuggestDataDtoField, ISuggestResultDtoField, ITypeHierarchyItemDto, IWorkspaceSymbolDto, MainContext, MainThreadLanguageFeaturesShape, reviveWorkspaceEditDto } from '../common/extHost.protocol';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
|
||||
export class MainThreadLanguageFeatures extends Disposable implements MainThreadLanguageFeaturesShape {
|
||||
|
@ -36,8 +38,6 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
|
|||
private readonly _proxy: ExtHostLanguageFeaturesShape;
|
||||
private readonly _registrations = new Map<number, IDisposable>();
|
||||
|
||||
private readonly _dropIntoEditorListeners = new Map<ICodeEditor, IDisposable>();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@ILanguageService private readonly _languageService: ILanguageService,
|
||||
|
@ -83,9 +83,6 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
|
|||
}
|
||||
this._registrations.clear();
|
||||
|
||||
dispose(this._dropIntoEditorListeners.values());
|
||||
this._dropIntoEditorListeners.clear();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -864,13 +861,47 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
|
|||
|
||||
// --- document drop Edits
|
||||
|
||||
private readonly _documentOnDropProviders = new Map<number, MainThreadDocumentOnDropProvider>();
|
||||
|
||||
$registerDocumentOnDropProvider(handle: number, selector: IDocumentFilterDto[]): void {
|
||||
this._registrations.set(handle, this._languageFeaturesService.documentOnDropEditProvider.register(selector, {
|
||||
provideDocumentOnDropEdits: async (model, position, dataTransfer, token) => {
|
||||
const dataTransferDto = await DataTransferConverter.toDataTransferDTO(dataTransfer);
|
||||
return this._proxy.$provideDocumentOnDropEdits(handle, model.uri, position, dataTransferDto, token);
|
||||
}
|
||||
}));
|
||||
const provider = new MainThreadDocumentOnDropProvider(handle, this._proxy);
|
||||
this._documentOnDropProviders.set(handle, provider);
|
||||
this._registrations.set(handle, combinedDisposable(
|
||||
this._languageFeaturesService.documentOnDropEditProvider.register(selector, provider),
|
||||
toDisposable(() => this._documentOnDropProviders.delete(handle)),
|
||||
));
|
||||
}
|
||||
|
||||
async $resolveDocumentOnDropFileData(handle: number, requestId: number, dataIndex: number): Promise<VSBuffer> {
|
||||
const provider = this._documentOnDropProviders.get(handle);
|
||||
if (!provider) {
|
||||
throw new Error('Could not find provider');
|
||||
}
|
||||
return provider.resolveDocumentOnDropFileData(requestId, dataIndex);
|
||||
}
|
||||
}
|
||||
|
||||
class MainThreadDocumentOnDropProvider implements languages.DocumentOnDropEditProvider {
|
||||
|
||||
private readonly dataTransfers = new DataTransferCache();
|
||||
|
||||
constructor(
|
||||
private readonly handle: number,
|
||||
private readonly _proxy: ExtHostLanguageFeaturesShape,
|
||||
) { }
|
||||
|
||||
async provideDocumentOnDropEdits(model: ITextModel, position: IPosition, dataTransfer: IDataTransfer, token: CancellationToken): Promise<languages.SnippetTextEdit | null | undefined> {
|
||||
const request = this.dataTransfers.add(dataTransfer);
|
||||
try {
|
||||
const dataTransferDto = await DataTransferConverter.toDataTransferDTO(dataTransfer);
|
||||
return await this._proxy.$provideDocumentOnDropEdits(this.handle, request.id, model.uri, position, dataTransferDto, token);
|
||||
} finally {
|
||||
request.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public resolveDocumentOnDropFileData(requestId: number, dataIndex: number): Promise<VSBuffer> {
|
||||
return this.dataTransfers.resolveDropFileData(requestId, dataIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,13 +15,16 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
|
|||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { DataTransferConverter } from 'vs/workbench/api/common/shared/dataTransfer';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IDataTransfer } from 'vs/workbench/common/dnd';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { DataTransferCache } from 'vs/workbench/api/common/shared/dataTransferCache';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadTreeViews)
|
||||
export class MainThreadTreeViews extends Disposable implements MainThreadTreeViewsShape {
|
||||
|
||||
private readonly _proxy: ExtHostTreeViewsShape;
|
||||
private readonly _dataProviders: Map<string, TreeViewDataProvider> = new Map<string, TreeViewDataProvider>();
|
||||
private readonly _dndControllers = new Map<string, TreeViewDragAndDropController>();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
|
@ -49,6 +52,9 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
|||
viewer.showCollapseAllAction = !!options.showCollapseAll;
|
||||
viewer.canSelectMany = !!options.canSelectMany;
|
||||
viewer.dragAndDropController = dndController;
|
||||
if (dndController) {
|
||||
this._dndControllers.set(treeViewId, dndController);
|
||||
}
|
||||
viewer.dataProvider = dataProvider;
|
||||
this.registerListeners(treeViewId, viewer);
|
||||
this._proxy.$setVisible(treeViewId, viewer.visible);
|
||||
|
@ -111,6 +117,14 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
|||
}
|
||||
}
|
||||
|
||||
$resolveDropFileData(destinationViewId: string, requestId: number, dataItemIndex: number): Promise<VSBuffer> {
|
||||
const controller = this._dndControllers.get(destinationViewId);
|
||||
if (!controller) {
|
||||
throw new Error('Unknown tree');
|
||||
}
|
||||
return controller.resolveDropFileData(requestId, dataItemIndex);
|
||||
}
|
||||
|
||||
private async reveal(treeView: ITreeView, dataProvider: TreeViewDataProvider, itemIn: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void> {
|
||||
options = options ? options : { select: false, focus: false };
|
||||
const select = isUndefinedOrNull(options.select) ? false : options.select;
|
||||
|
@ -170,6 +184,9 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
|
|||
}
|
||||
});
|
||||
this._dataProviders.clear();
|
||||
|
||||
this._dndControllers.clear();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +195,8 @@ type TreeItemHandle = string;
|
|||
|
||||
class TreeViewDragAndDropController implements ITreeViewDragAndDropController {
|
||||
|
||||
private readonly dataTransfersCache = new DataTransferCache();
|
||||
|
||||
constructor(private readonly treeViewId: string,
|
||||
readonly dropMimeTypes: string[],
|
||||
readonly dragMimeTypes: string[],
|
||||
|
@ -186,7 +205,12 @@ class TreeViewDragAndDropController implements ITreeViewDragAndDropController {
|
|||
|
||||
async handleDrop(dataTransfer: IDataTransfer, targetTreeItem: ITreeItem | undefined, token: CancellationToken,
|
||||
operationUuid?: string, sourceTreeId?: string, sourceTreeItemHandles?: string[]): Promise<void> {
|
||||
return this._proxy.$handleDrop(this.treeViewId, await DataTransferConverter.toDataTransferDTO(dataTransfer), targetTreeItem?.handle, token, operationUuid, sourceTreeId, sourceTreeItemHandles);
|
||||
const request = this.dataTransfersCache.add(dataTransfer);
|
||||
try {
|
||||
return await this._proxy.$handleDrop(this.treeViewId, request.id, await DataTransferConverter.toDataTransferDTO(dataTransfer), targetTreeItem?.handle, token, operationUuid, sourceTreeId, sourceTreeItemHandles);
|
||||
} finally {
|
||||
request.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
async handleDrag(sourceTreeItemHandles: string[], operationUuid: string, token: CancellationToken): Promise<IDataTransfer | undefined> {
|
||||
|
@ -197,7 +221,11 @@ class TreeViewDragAndDropController implements ITreeViewDragAndDropController {
|
|||
if (!additionalTransferItems) {
|
||||
return;
|
||||
}
|
||||
return DataTransferConverter.toDataTransfer(additionalTransferItems);
|
||||
return DataTransferConverter.toDataTransfer(additionalTransferItems, () => { throw new Error('not supported'); });
|
||||
}
|
||||
|
||||
public resolveDropFileData(requestId: number, dataItemIndex: number): Promise<VSBuffer> {
|
||||
return this.dataTransfersCache.resolveDropFileData(requestId, dataItemIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -263,6 +263,7 @@ export interface MainThreadTreeViewsShape extends IDisposable {
|
|||
$setMessage(treeViewId: string, message: string): void;
|
||||
$setTitle(treeViewId: string, title: string, description: string | undefined): void;
|
||||
$setBadge(treeViewId: string, badge: IViewBadge | undefined): void;
|
||||
$resolveDropFileData(destinationViewId: string, requestId: number, dataItemIndex: number): Promise<VSBuffer>;
|
||||
}
|
||||
|
||||
export interface MainThreadDownloadServiceShape extends IDisposable {
|
||||
|
@ -391,6 +392,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
|||
$registerCallHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerTypeHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerDocumentOnDropProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$resolveDocumentOnDropFileData(handle: number, requestId: number, dataIndex: number): Promise<VSBuffer>;
|
||||
$setLanguageConfiguration(handle: number, languageId: string, configuration: ILanguageConfigurationDto): void;
|
||||
}
|
||||
|
||||
|
@ -1368,7 +1370,7 @@ export interface ExtHostDocumentsAndEditorsShape {
|
|||
|
||||
export interface ExtHostTreeViewsShape {
|
||||
$getChildren(treeViewId: string, treeItemHandle?: string): Promise<ITreeItem[] | undefined>;
|
||||
$handleDrop(destinationViewId: string, treeDataTransfer: DataTransferDTO, targetHandle: string | undefined, token: CancellationToken, operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise<void>;
|
||||
$handleDrop(destinationViewId: string, requestId: number, treeDataTransfer: DataTransferDTO, targetHandle: string | undefined, token: CancellationToken, operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise<void>;
|
||||
$handleDrag(sourceViewId: string, sourceTreeItemHandles: string[], operationUuid: string, token: CancellationToken): Promise<DataTransferDTO | undefined>;
|
||||
$setExpanded(treeViewId: string, treeItemHandle: string, expanded: boolean): void;
|
||||
$setSelection(treeViewId: string, treeItemHandles: string[]): void;
|
||||
|
@ -1756,7 +1758,7 @@ export interface ExtHostLanguageFeaturesShape {
|
|||
$provideTypeHierarchySupertypes(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<ITypeHierarchyItemDto[] | undefined>;
|
||||
$provideTypeHierarchySubtypes(handle: number, sessionId: string, itemId: string, token: CancellationToken): Promise<ITypeHierarchyItemDto[] | undefined>;
|
||||
$releaseTypeHierarchy(handle: number, sessionId: string): void;
|
||||
$provideDocumentOnDropEdits(handle: number, resource: UriComponents, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<Dto<languages.SnippetTextEdit> | undefined>;
|
||||
$provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<Dto<languages.SnippetTextEdit> | undefined>;
|
||||
}
|
||||
|
||||
export interface ExtHostQuickOpenShape {
|
||||
|
|
|
@ -1750,14 +1750,18 @@ class TypeHierarchyAdapter {
|
|||
class DocumentOnDropAdapter {
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape,
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _provider: vscode.DocumentOnDropProvider
|
||||
private readonly _provider: vscode.DocumentOnDropProvider,
|
||||
private readonly _handle: number,
|
||||
) { }
|
||||
|
||||
async provideDocumentOnDropEdits(uri: URI, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<Dto<languages.SnippetTextEdit> | undefined> {
|
||||
async provideDocumentOnDropEdits(requestId: number, uri: URI, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<Dto<languages.SnippetTextEdit> | undefined> {
|
||||
const doc = this._documents.getDocument(uri);
|
||||
const pos = typeConvert.Position.to(position);
|
||||
const dataTransfer = DataTransferConverter.toDataTransfer(dataTransferDto);
|
||||
const dataTransfer = DataTransferConverter.toDataTransfer(dataTransferDto, async (index) => {
|
||||
return (await this._proxy.$resolveDocumentOnDropFileData(this._handle, requestId, index)).buffer;
|
||||
});
|
||||
|
||||
const edit = await this._provider.provideDocumentOnDropEdits(doc, pos, dataTransfer, token);
|
||||
if (!edit) {
|
||||
|
@ -2400,13 +2404,15 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
|||
// --- Document on drop
|
||||
|
||||
registerDocumentOnDropProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentOnDropProvider) {
|
||||
const handle = this._addNewAdapter(new DocumentOnDropAdapter(this._documents, provider), extension);
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new AdapterData(new DocumentOnDropAdapter(this._proxy, this._documents, provider, handle), extension));
|
||||
this._proxy.$registerDocumentOnDropProvider(handle, this._transformDocumentSelector(selector));
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideDocumentOnDropEdits(handle: number, resource: UriComponents, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<Dto<languages.SnippetTextEdit> | undefined> {
|
||||
return this._withAdapter(handle, DocumentOnDropAdapter, adapter => Promise.resolve(adapter.provideDocumentOnDropEdits(URI.revive(resource), position, dataTransferDto, token)), undefined, undefined);
|
||||
$provideDocumentOnDropEdits(handle: number, requestId: number, resource: UriComponents, position: IPosition, dataTransferDto: DataTransferDTO, token: CancellationToken): Promise<Dto<languages.SnippetTextEdit> | undefined> {
|
||||
return this._withAdapter(handle, DocumentOnDropAdapter, adapter =>
|
||||
Promise.resolve(adapter.provideDocumentOnDropEdits(requestId, URI.revive(resource), position, dataTransferDto, token)), undefined, undefined);
|
||||
}
|
||||
|
||||
// --- configuration
|
||||
|
|
|
@ -25,7 +25,7 @@ import { Command } from 'vs/editor/common/languages';
|
|||
import { DataTransferConverter, DataTransferDTO } from 'vs/workbench/api/common/shared/dataTransfer';
|
||||
import { ITreeViewsService, TreeviewsService } from 'vs/workbench/services/views/common/treeViewsService';
|
||||
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IDataTransfer } from 'vs/workbench/common/dnd';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
|
||||
type TreeItemHandle = string;
|
||||
|
||||
|
@ -144,14 +144,16 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
|||
return treeView.getChildren(treeItemHandle);
|
||||
}
|
||||
|
||||
async $handleDrop(destinationViewId: string, treeDataTransferDTO: DataTransferDTO, targetItemHandle: string | undefined, token: CancellationToken,
|
||||
async $handleDrop(destinationViewId: string, requestId: number, treeDataTransferDTO: DataTransferDTO, targetItemHandle: string | undefined, token: CancellationToken,
|
||||
operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise<void> {
|
||||
const treeView = this.treeViews.get(destinationViewId);
|
||||
if (!treeView) {
|
||||
return Promise.reject(new Error(localize('treeView.notRegistered', 'No tree view with id \'{0}\' registered.', destinationViewId)));
|
||||
}
|
||||
|
||||
const treeDataTransfer = DataTransferConverter.toDataTransfer(treeDataTransferDTO);
|
||||
const treeDataTransfer = DataTransferConverter.toDataTransfer(treeDataTransferDTO, async dataItemIndex => {
|
||||
return (await this._proxy.$resolveDropFileData(destinationViewId, requestId, dataItemIndex)).buffer;
|
||||
});
|
||||
if ((sourceViewId === destinationViewId) && sourceTreeItemHandles) {
|
||||
await this.addAdditionalTransferItems(treeDataTransfer, treeView, sourceTreeItemHandles, token, operationUuid);
|
||||
}
|
||||
|
@ -164,7 +166,21 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
|||
if (existingTransferOperation) {
|
||||
(await existingTransferOperation)?.forEach((value, key) => {
|
||||
if (value) {
|
||||
treeDataTransfer.set(key, value);
|
||||
const file = value.asFile();
|
||||
treeDataTransfer.set(key, {
|
||||
value: value.value,
|
||||
asString: value.asString,
|
||||
asFile() {
|
||||
if (!file) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
name: file.name,
|
||||
uri: file.uri,
|
||||
data: async () => await file.data()
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (operationUuid && treeView.handleDrag) {
|
||||
|
|
|
@ -2393,6 +2393,10 @@ export class DataTransferItem {
|
|||
return typeof this.value === 'string' ? this.value : JSON.stringify(this.value);
|
||||
}
|
||||
|
||||
asFile(): undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
constructor(public readonly value: any) { }
|
||||
}
|
||||
|
||||
|
|
|
@ -3,23 +3,42 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDataTransfer, IDataTransferItem } from 'vs/workbench/common/dnd';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IDataTransfer, IDataTransferItem } from 'vs/editor/common/dnd';
|
||||
|
||||
export interface IDataTransferFileDTO {
|
||||
readonly name: string;
|
||||
readonly uri?: UriComponents;
|
||||
}
|
||||
|
||||
interface DataTransferItemDTO {
|
||||
asString: string;
|
||||
readonly asString: string;
|
||||
readonly fileData: IDataTransferFileDTO | undefined;
|
||||
}
|
||||
|
||||
export interface DataTransferDTO {
|
||||
types: string[];
|
||||
items: DataTransferItemDTO[];
|
||||
readonly types: string[];
|
||||
readonly items: DataTransferItemDTO[];
|
||||
}
|
||||
|
||||
export namespace DataTransferConverter {
|
||||
export function toDataTransfer(value: DataTransferDTO): IDataTransfer {
|
||||
export function toDataTransfer(value: DataTransferDTO, resolveFileData: (dataItemIndex: number) => Promise<Uint8Array>): IDataTransfer {
|
||||
const newDataTransfer: IDataTransfer = new Map<string, IDataTransferItem>();
|
||||
value.types.forEach((type, index) => {
|
||||
newDataTransfer.set(type, {
|
||||
asString: async () => value.items[index].asString,
|
||||
asFile: () => {
|
||||
const file = value.items[index].fileData;
|
||||
if (!file) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
name: file.name,
|
||||
uri: URI.revive(file.uri),
|
||||
data: once(() => resolveFileData(index)),
|
||||
};
|
||||
},
|
||||
value: undefined
|
||||
});
|
||||
});
|
||||
|
@ -31,11 +50,15 @@ export namespace DataTransferConverter {
|
|||
types: [],
|
||||
items: []
|
||||
};
|
||||
|
||||
const entries = Array.from(value.entries());
|
||||
for (const entry of entries) {
|
||||
newDTO.types.push(entry[0]);
|
||||
const stringValue = await entry[1].asString();
|
||||
const fileValue = entry[1].asFile();
|
||||
newDTO.items.push({
|
||||
asString: await entry[1].asString()
|
||||
asString: stringValue,
|
||||
fileData: fileValue ? { name: fileValue.name, uri: fileValue.uri } : undefined,
|
||||
});
|
||||
}
|
||||
return newDTO;
|
||||
|
|
42
src/vs/workbench/api/common/shared/dataTransferCache.ts
Normal file
42
src/vs/workbench/api/common/shared/dataTransferCache.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IDataTransfer, IDataTransferItem } from 'vs/editor/common/dnd';
|
||||
|
||||
export class DataTransferCache {
|
||||
|
||||
private requestIdPool = 0;
|
||||
private readonly dataTransfers = new Map</* requestId */ number, ReadonlyArray<IDataTransferItem>>();
|
||||
|
||||
public add(dataTransfer: IDataTransfer): { id: number; dispose: () => void } {
|
||||
const requestId = this.requestIdPool++;
|
||||
this.dataTransfers.set(requestId, [...dataTransfer.values()]);
|
||||
return {
|
||||
id: requestId,
|
||||
dispose: () => {
|
||||
this.dataTransfers.delete(requestId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async resolveDropFileData(requestId: number, dataItemIndex: number): Promise<VSBuffer> {
|
||||
const entry = this.dataTransfers.get(requestId);
|
||||
if (!entry) {
|
||||
throw new Error('No data transfer found');
|
||||
}
|
||||
|
||||
const file = entry[dataItemIndex]?.asFile();
|
||||
if (!file) {
|
||||
throw new Error('No file item found in data transfer');
|
||||
}
|
||||
|
||||
return VSBuffer.wrap(await file.data());
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.dataTransfers.clear();
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ import { parse, stringify } from 'vs/base/common/marshalling';
|
|||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { hasWorkspaceFileExtension, isTemporaryWorkspace, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { IDataTransfer } from 'vs/workbench/common/dnd';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
import { extractSelection } from 'vs/platform/opener/common/opener';
|
||||
import { IListDragAndDrop } from 'vs/base/browser/ui/list/list';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
|
|
|
@ -3,69 +3,69 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { renderMarkdownAsPlaintext } from 'vs/base/browser/markdownRenderer';
|
||||
import { ActionBar, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { IHoverDelegate, IHoverDelegateOptions } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
|
||||
import { ITooltipMarkdownString } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
|
||||
import { IIdentityProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { IAsyncDataSource, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeDragOverReaction, ITreeNode, ITreeRenderer, TreeDragOverBubble } from 'vs/base/browser/ui/tree/tree';
|
||||
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
|
||||
import { ActionRunner, IAction } from 'vs/base/common/actions';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { isCancellationError } from 'vs/base/common/errors';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { createMatches, FuzzyScore } from 'vs/base/common/filters';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { basename, dirname } from 'vs/base/common/resources';
|
||||
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import 'vs/css!./media/views';
|
||||
import { toDisposable, IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
import { Command } from 'vs/editor/common/languages';
|
||||
import { localize } from 'vs/nls';
|
||||
import { createActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { Action2, IMenu, IMenuService, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { MenuId, IMenuService, registerAction2, Action2, IMenu } from 'vs/platform/actions/common/actions';
|
||||
import { IContextKeyService, ContextKeyExpr, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ITreeView, ITreeViewDescriptor, IViewsRegistry, Extensions, IViewDescriptorService, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeItemLabel, ViewContainer, ViewContainerLocation, ResolvableTreeItem, ITreeViewDragAndDropController, IViewBadge } from 'vs/workbench/common/views';
|
||||
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IThemeService, FileThemeIcon, FolderThemeIcon, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPane';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IAction, ActionRunner } from 'vs/base/common/actions';
|
||||
import { createAndFillInContextMenuActions, createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ActionBar, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { dirname, basename } from 'vs/base/common/resources';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
||||
import { localize } from 'vs/nls';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { textLinkForeground, textCodeBlockBackground, focusBorder, listFilterMatchHighlight, listFilterMatchHighlightBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeRenderer, ITreeNode, IAsyncDataSource, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeDragOverReaction, TreeDragOverBubble } from 'vs/base/browser/ui/tree/tree';
|
||||
import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
|
||||
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
|
||||
import { SIDE_BAR_BACKGROUND, PANEL_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { IHoverService } from 'vs/workbench/services/hover/browser/hover';
|
||||
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { ColorScheme } from 'vs/platform/theme/common/theme';
|
||||
import { IHoverDelegate, IHoverDelegateOptions } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { ITooltipMarkdownString } from 'vs/base/browser/ui/iconLabel/iconLabelHover';
|
||||
import { renderMarkdownAsPlaintext } from 'vs/base/browser/markdownRenderer';
|
||||
import { API_OPEN_DIFF_EDITOR_COMMAND_ID, API_OPEN_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { Command } from 'vs/editor/common/languages';
|
||||
import { isCancellationError } from 'vs/base/common/errors';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { CodeDataTransfers, convertResourceUrlsToUriList, DraggedTreeItemsIdentifier, fillEditorsDragData, LocalSelectionTransfer } from 'vs/workbench/browser/dnd';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ITreeViewsService } from 'vs/workbench/services/views/browser/treeViewsService';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { focusBorder, listFilterMatchHighlight, listFilterMatchHighlightBorder, textCodeBlockBackground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ColorScheme } from 'vs/platform/theme/common/theme';
|
||||
import { FileThemeIcon, FolderThemeIcon, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { CodeDataTransfers, convertResourceUrlsToUriList, DraggedTreeItemsIdentifier, fillEditorsDragData, LocalSelectionTransfer } from 'vs/workbench/browser/dnd';
|
||||
import { IResourceLabel, ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
import { API_OPEN_DIFF_EDITOR_COMMAND_ID, API_OPEN_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
|
||||
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPane';
|
||||
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { Extensions, ITreeItem, ITreeItemLabel, ITreeView, ITreeViewDataProvider, ITreeViewDescriptor, ITreeViewDragAndDropController, IViewBadge, IViewDescriptorService, IViewsRegistry, ResolvableTreeItem, TreeItemCollapsibleState, TreeViewItemHandleArg, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IDataTransfer } from 'vs/workbench/common/dnd';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IHoverService } from 'vs/workbench/services/hover/browser/hover';
|
||||
import { ThemeSettings } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { ITreeViewsService } from 'vs/workbench/services/views/browser/treeViewsService';
|
||||
|
||||
export class TreeViewPane extends ViewPane {
|
||||
|
||||
|
@ -1522,6 +1522,7 @@ export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
|
|||
if (uris.length) {
|
||||
treeDataTransfer.set(Mimes.uriList, {
|
||||
asString: () => Promise.resolve(uris.map(uri => uri.toString()).join('\n')),
|
||||
asFile: () => undefined,
|
||||
value: undefined
|
||||
});
|
||||
}
|
||||
|
@ -1547,6 +1548,7 @@ export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop<ITreeItem> {
|
|||
const converted = this.convertKnownMimes(type, kind, dataValue);
|
||||
treeDataTransfer.set(converted.type, {
|
||||
asString: () => Promise.resolve(converted.value!),
|
||||
asFile: () => undefined,
|
||||
value: undefined
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import { mixin } from 'vs/base/common/objects';
|
|||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IDataTransfer } from 'vs/workbench/common/dnd';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
|
||||
export const defaultViewIcon = registerIcon('default-view-icon', Codicon.window, localize('defaultViewIcon', 'Default view icon.'));
|
||||
|
||||
|
|
|
@ -13,14 +13,13 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
|||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IDataTransfer, IDataTransferItem } from 'vs/editor/common/dnd';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { IDataTransferItem } from 'vs/editor/common/languages';
|
||||
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
|
||||
import { performSnippetEdit } from 'vs/editor/contrib/snippet/browser/snippetController2';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { extractEditorsDropData } from 'vs/workbench/browser/dnd';
|
||||
import { IDataTransfer } from 'vs/workbench/common/dnd';
|
||||
|
||||
|
||||
export class DropIntoEditorController extends Disposable implements IEditorContribution {
|
||||
|
@ -48,13 +47,32 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
|
|||
|
||||
const textEditorDataTransfer: IDataTransfer = new Map<string, IDataTransferItem>();
|
||||
for (const item of dragEvent.dataTransfer.items) {
|
||||
const type = item.type;
|
||||
if (item.kind === 'string') {
|
||||
const type = item.type;
|
||||
const asStringValue = new Promise<string>(resolve => item.getAsString(resolve));
|
||||
textEditorDataTransfer.set(type, {
|
||||
asString: () => asStringValue,
|
||||
asFile: () => undefined,
|
||||
value: undefined
|
||||
});
|
||||
} else if (item.kind === 'file') {
|
||||
const file = item.getAsFile();
|
||||
if (file) {
|
||||
textEditorDataTransfer.set(type, {
|
||||
asString: () => Promise.resolve(''),
|
||||
asFile: () => {
|
||||
const uri = file.path ? URI.parse(file.path) : undefined;
|
||||
return {
|
||||
name: file.name,
|
||||
uri: uri,
|
||||
data: async () => {
|
||||
return new Uint8Array(await file.arrayBuffer());
|
||||
},
|
||||
};
|
||||
},
|
||||
value: undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +85,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
|
|||
const str = distinct(editorData).join('\n');
|
||||
textEditorDataTransfer.set(Mimes.uriList.toLowerCase(), {
|
||||
asString: () => Promise.resolve(str),
|
||||
asFile: () => undefined,
|
||||
value: undefined
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ export const allApiProposals = Object.freeze({
|
|||
contribViewsRemote: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts',
|
||||
contribViewsWelcome: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribViewsWelcome.d.ts',
|
||||
customEditorMove: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.customEditorMove.d.ts',
|
||||
dataTransferFiles: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts',
|
||||
diffCommand: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.diffCommand.d.ts',
|
||||
documentFiltersExclusive: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.documentFiltersExclusive.d.ts',
|
||||
editorInsets: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.editorInsets.d.ts',
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDataTransfer } from 'vs/workbench/common/dnd';
|
||||
import { IDataTransfer } from 'vs/editor/common/dnd';
|
||||
import { ITreeItem } from 'vs/workbench/common/views';
|
||||
import { ITreeViewsService as ITreeViewsServiceCommon, TreeviewsService } from 'vs/workbench/services/views/common/treeViewsService';
|
||||
|
||||
|
|
42
src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts
vendored
Normal file
42
src/vscode-dts/vscode.proposed.dataTransferFiles.d.ts
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/TODO
|
||||
|
||||
/**
|
||||
* A file associated with a {@linkcode DataTransferItem}.
|
||||
*/
|
||||
interface DataTransferFile {
|
||||
/**
|
||||
* The name of the file.
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* The full file path of the file.
|
||||
*
|
||||
* May be undefined on web.
|
||||
*/
|
||||
readonly uri?: Uri;
|
||||
|
||||
/**
|
||||
* The full file contents of the file.
|
||||
*/
|
||||
data(): Thenable<Uint8Array>;
|
||||
}
|
||||
|
||||
export interface DataTransferItem {
|
||||
/**
|
||||
* Try getting the file associated with this data transfer item.
|
||||
*
|
||||
* Note that the file object is only valid for the scope of the drag and drop operation.
|
||||
*
|
||||
* @returns The file for the data transfer or `undefined` if the item is not a file.
|
||||
*/
|
||||
asFile(): DataTransferFile | undefined;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue