mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Update drop metadata proposal (#179918)
- Makes `dropMimeTypes` required - Prefix the actual `id` used internally with the extension id - Allow wildcard mime types, such as `image/*`
This commit is contained in:
parent
830d534e27
commit
739b93cce8
|
@ -47,7 +47,7 @@ export function registerDropIntoEditorSupport(selector: vscode.DocumentSelector)
|
|||
return edit;
|
||||
}
|
||||
}, {
|
||||
id: 'vscode.markdown.insertLink',
|
||||
id: 'insertLink',
|
||||
dropMimeTypes: [
|
||||
'text/uri-list'
|
||||
]
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
|
||||
|
@ -46,10 +47,45 @@ export class VSDataTransfer {
|
|||
return this._entries.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this data transfer contains data for a given mime type.
|
||||
*
|
||||
* This uses exact matching and does support wildcards.
|
||||
*/
|
||||
public has(mimeType: string): boolean {
|
||||
return this._entries.has(this.toKey(mimeType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this data transfer contains data matching a given mime type glob.
|
||||
*
|
||||
* This allows matching for wildcards, such as `image/*`.
|
||||
*/
|
||||
public matches(mimeTypeGlob: string): boolean {
|
||||
// Exact match
|
||||
if (this.has(mimeTypeGlob)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Anything glob
|
||||
if (mimeTypeGlob === '*/*') {
|
||||
return this._entries.size > 0;
|
||||
}
|
||||
|
||||
// Wildcard, such as `image/*`
|
||||
const wildcard = this.toKey(mimeTypeGlob).match(/^([a-z]+)$\/([a-z]+|\*)/i);
|
||||
if (!wildcard) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const [_, type, subtype] = wildcard;
|
||||
if (subtype === '*') {
|
||||
return Iterable.some(this._entries.keys(), key => key.startsWith(type + '/'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public get(mimeType: string): IDataTransferItem | undefined {
|
||||
return this._entries.get(this.toKey(mimeType))?.[0];
|
||||
}
|
||||
|
|
|
@ -1932,7 +1932,7 @@ export interface DocumentOnDropEdit {
|
|||
* @internal
|
||||
*/
|
||||
export interface DocumentOnDropEditProvider {
|
||||
readonly id?: string;
|
||||
readonly id: string;
|
||||
readonly dropMimeTypes?: readonly string[];
|
||||
|
||||
provideDocumentOnDropEdits(model: model.ITextModel, position: IPosition, dataTransfer: VSDataTransfer, token: CancellationToken): ProviderResult<DocumentOnDropEdit>;
|
||||
|
|
|
@ -94,7 +94,7 @@ export class DropIntoEditorController extends Disposable implements IEditorContr
|
|||
// Keep all providers that don't specify mime types
|
||||
return true;
|
||||
}
|
||||
return provider.dropMimeTypes.some(mime => ourDataTransfer.has(mime));
|
||||
return provider.dropMimeTypes.some(mime => ourDataTransfer.matches(mime));
|
||||
});
|
||||
|
||||
const possibleDropEdits = await raceCancellation(Promise.all(providers.map(provider => {
|
||||
|
|
|
@ -907,8 +907,8 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
|
|||
|
||||
private readonly _documentOnDropEditProviders = new Map<number, MainThreadDocumentOnDropEditProvider>();
|
||||
|
||||
$registerDocumentOnDropEditProvider(handle: number, selector: IDocumentFilterDto[], metadata?: { id: string; dropMimeTypes?: string[] }): void {
|
||||
const provider = new MainThreadDocumentOnDropEditProvider(handle, metadata, this._proxy, this._uriIdentService);
|
||||
$registerDocumentOnDropEditProvider(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, metadata: { id: string; dropMimeTypes: string[] }): void {
|
||||
const provider = new MainThreadDocumentOnDropEditProvider(handle, extensionId, metadata, this._proxy, this._uriIdentService);
|
||||
this._documentOnDropEditProviders.set(handle, provider);
|
||||
this._registrations.set(handle, combinedDisposable(
|
||||
this._languageFeaturesService.documentOnDropEditProvider.register(selector, provider),
|
||||
|
@ -990,17 +990,18 @@ class MainThreadDocumentOnDropEditProvider implements languages.DocumentOnDropEd
|
|||
|
||||
private readonly dataTransfers = new DataTransferCache();
|
||||
|
||||
readonly id?: string;
|
||||
readonly id: string;
|
||||
readonly dropMimeTypes?: readonly string[];
|
||||
|
||||
constructor(
|
||||
private readonly handle: number,
|
||||
metadata: { id: string; dropMimeTypes?: readonly string[] } | undefined,
|
||||
extensionId: ExtensionIdentifier,
|
||||
metadata: { id: string; dropMimeTypes: readonly string[] } | undefined,
|
||||
private readonly _proxy: ExtHostLanguageFeaturesShape,
|
||||
@IUriIdentityService private readonly _uriIdentService: IUriIdentityService
|
||||
) {
|
||||
this.id = metadata?.id;
|
||||
this.dropMimeTypes = metadata?.dropMimeTypes;
|
||||
this.id = extensionId.value + (metadata ? '.' + metadata.id : '');
|
||||
this.dropMimeTypes = metadata?.dropMimeTypes ?? ['*/*'];
|
||||
}
|
||||
|
||||
async provideDocumentOnDropEdits(model: ITextModel, position: IPosition, dataTransfer: VSDataTransfer, token: CancellationToken): Promise<languages.DocumentOnDropEdit | null | undefined> {
|
||||
|
|
|
@ -407,7 +407,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
|||
$registerSelectionRangeProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerCallHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerTypeHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void;
|
||||
$registerDocumentOnDropEditProvider(handle: number, selector: IDocumentFilterDto[], metadata?: { id: string; dropMimeTypes?: readonly string[] }): void;
|
||||
$registerDocumentOnDropEditProvider(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, metadata?: { id: string; dropMimeTypes: readonly string[] }): void;
|
||||
$resolvePasteFileData(handle: number, requestId: number, dataId: string): Promise<VSBuffer>;
|
||||
$resolveDocumentOnDropFileData(handle: number, requestId: number, dataId: string): Promise<VSBuffer>;
|
||||
$setLanguageConfiguration(handle: number, languageId: string, configuration: ILanguageConfigurationDto): void;
|
||||
|
|
|
@ -2386,7 +2386,9 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
|||
registerDocumentOnDropEditProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentDropEditProvider, metadata?: vscode.DocumentDropEditProviderMetadata) {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new AdapterData(new DocumentOnDropEditAdapter(this._proxy, this._documents, provider, handle, extension), extension));
|
||||
this._proxy.$registerDocumentOnDropEditProvider(handle, this._transformDocumentSelector(selector), metadata);
|
||||
|
||||
this._proxy.$registerDocumentOnDropEditProvider(handle, this._transformDocumentSelector(selector), extension.identifier, isProposedApiEnabled(extension, 'dropMetadata') ? metadata : undefined);
|
||||
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,17 @@ declare module 'vscode' {
|
|||
export interface DocumentDropEditProviderMetadata {
|
||||
/**
|
||||
* Unique identifier for the provider.
|
||||
*
|
||||
* This id should be unique within the extension but does not need to be unique across extensions.
|
||||
*/
|
||||
readonly id: string;
|
||||
|
||||
/**
|
||||
* List of data transfer types that the provider supports.
|
||||
*
|
||||
* This can either be an exact mime type such as `image/png`, or a wildcard pattern such as `image/*`.
|
||||
*/
|
||||
readonly dropMimeTypes?: readonly string[];
|
||||
readonly dropMimeTypes: readonly string[];
|
||||
}
|
||||
|
||||
export namespace languages {
|
||||
|
|
Loading…
Reference in a new issue