diff --git a/extensions/image-preview/src/extension.ts b/extensions/image-preview/src/extension.ts index 5cdc665ab5f2a7e45fdc7a60b030c6f07b67648a..dc0d5c33956904c0a491e826a2a20f0c4918d55c 100644 --- a/extensions/image-preview/src/extension.ts +++ b/extensions/image-preview/src/extension.ts @@ -23,7 +23,7 @@ export function activate(context: vscode.ExtensionContext) { const previewManager = new PreviewManager(extensionRoot, sizeStatusBarEntry, binarySizeStatusBarEntry, zoomStatusBarEntry); - context.subscriptions.push(vscode.window.registerWebviewEditorProvider(PreviewManager.viewType, previewManager)); + context.subscriptions.push(vscode.window.registerWebviewCustomEditorProvider(PreviewManager.viewType, previewManager)); context.subscriptions.push(vscode.commands.registerCommand('imagePreview.zoomIn', () => { previewManager.activePreview?.zoomIn(); diff --git a/extensions/image-preview/src/preview.ts b/extensions/image-preview/src/preview.ts index 83fcaafaaaf48eeee754b609bc8d1c7cd9404290..dc2e6676245e98b4a5e5ebf0a4c93cf1984db82a 100644 --- a/extensions/image-preview/src/preview.ts +++ b/extensions/image-preview/src/preview.ts @@ -13,7 +13,7 @@ import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry'; const localize = nls.loadMessageBundle(); -export class PreviewManager implements vscode.WebviewEditorProvider { +export class PreviewManager implements vscode.WebviewCustomEditorProvider { public static readonly viewType = 'imagePreview.previewEditor'; @@ -28,10 +28,10 @@ export class PreviewManager implements vscode.WebviewEditorProvider { ) { } public async resolveWebviewEditor( - input: { readonly resource: vscode.Uri, }, + resource: vscode.Uri, webviewEditor: vscode.WebviewPanel, - ): Promise { - const preview = new Preview(this.extensionRoot, input.resource, webviewEditor, this.sizeStatusBarEntry, this.binarySizeStatusBarEntry, this.zoomStatusBarEntry); + ): Promise { + const preview = new Preview(this.extensionRoot, resource, webviewEditor, this.sizeStatusBarEntry, this.binarySizeStatusBarEntry, this.zoomStatusBarEntry); this._previews.add(preview); this.setActivePreview(preview); @@ -44,8 +44,6 @@ export class PreviewManager implements vscode.WebviewEditorProvider { this.setActivePreview(undefined); } }); - - return {}; } public get activePreview() { return this._activePreview; } diff --git a/extensions/markdown-language-features/src/features/previewManager.ts b/extensions/markdown-language-features/src/features/previewManager.ts index 95b21eba5001011be239cc748eb73e2a2a25d873..333a0651a448fd33bbfbbe8b6067c094af0ff171 100644 --- a/extensions/markdown-language-features/src/features/previewManager.ts +++ b/extensions/markdown-language-features/src/features/previewManager.ts @@ -52,7 +52,7 @@ class PreviewStore extends Disposable { } } -export class MarkdownPreviewManager extends Disposable implements vscode.WebviewPanelSerializer, vscode.WebviewEditorProvider { +export class MarkdownPreviewManager extends Disposable implements vscode.WebviewPanelSerializer, vscode.WebviewCustomEditorProvider { private static readonly markdownPreviewActiveContextKey = 'markdownPreviewFocus'; private readonly _topmostLineMonitor = new TopmostLineMonitor(); @@ -70,7 +70,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview ) { super(); this._register(vscode.window.registerWebviewPanelSerializer(DynamicMarkdownPreview.viewType, this)); - this._register(vscode.window.registerWebviewEditorProvider('vscode.markdown.preview.editor', this)); + this._register(vscode.window.registerWebviewCustomEditorProvider('vscode.markdown.preview.editor', this)); } public refresh() { @@ -149,11 +149,11 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview } public async resolveWebviewEditor( - input: { readonly resource: vscode.Uri; }, + resource: vscode.Uri, webview: vscode.WebviewPanel - ): Promise { + ): Promise { const preview = DynamicMarkdownPreview.revive( - { resource: input.resource, locked: false, resourceColumn: vscode.ViewColumn.One }, + { resource, locked: false, resourceColumn: vscode.ViewColumn.One }, webview, this._contentProvider, this._previewConfigurations, @@ -161,7 +161,6 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview this._topmostLineMonitor, this._contributions); this.registerStaticPreview(preview); - return {}; } private createNewDynamicPreview( diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 975f11aebd9da29d6bde2ac5e0e0117d64af0b50..b04aeb64807d3ebaebe57f65bc0f7849c8ef3d5b 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1180,101 +1180,87 @@ declare module 'vscode' { //#region Custom editors: https://github.com/microsoft/vscode/issues/77131 - /** - * Defines how a webview editor interacts with VS Code. - */ - interface WebviewEditorCapabilities { - /** - * Invoked when the resource has been renamed in VS Code. - * - * This is called when the resource's new name also matches the custom editor selector. - * - * If this is not implemented—or if the new resource name does not match the existing selector—then VS Code - * will close and reopen the editor on rename. - * - * @param newResource Full path to the resource. - * - * @return Thenable that signals the save is complete. - */ - // rename?(newResource: Uri): Thenable; - - /** - * Controls the editing functionality of a webview editor. This allows the webview editor to hook into standard - * editor events such as `undo` or `save`. - * - * WebviewEditors that do not have `editingCapability` are considered to be readonly. Users can still interact - * with readonly editors, but these editors will not integrate with VS Code's standard editor functionality. - */ - readonly editingCapability?: WebviewEditorEditingCapability; - } - /** * Defines the editing functionality of a webview editor. This allows the webview editor to hook into standard * editor events such as `undo` or `save`. + * + * @param EditType Type of edits. Edit objects must be json serializable. */ - interface WebviewEditorEditingCapability { + interface WebviewCustomEditorEditingDelegate { /** - * Persist the resource. + * Save a resource. * - * Extensions should persist the resource + * @param resource Resource being saved. * * @return Thenable signaling that the save has completed. */ - save(): Thenable; + save(resource: Uri): Thenable; /** + * Save an existing resource at a new path. * * @param resource Resource being saved. * @param targetResource Location to save to. + * + * @return Thenable signaling that the save has completed. */ saveAs(resource: Uri, targetResource: Uri): Thenable; /** * Event triggered by extensions to signal to VS Code that an edit has occurred. - * - * The edit must be a json serializable object. */ - readonly onEdit: Event; + readonly onEdit: Event<{ readonly resource: Uri, readonly edit: EditType }>; /** * Apply a set of edits. * - * This is triggered on redo and when restoring a custom editor after restart. Note that is not invoked - * when `onEdit` is called as `onEdit` implies also updating the view to reflect the edit. + * Note that is not invoked when `onEdit` is called as `onEdit` implies also updating the view to reflect the edit. * + * @param resource Resource being edited. * @param edit Array of edits. Sorted from oldest to most recent. + * + * @return Thenable signaling that the change has completed. */ - applyEdits(edits: readonly any[]): Thenable; + applyEdits(resource: Uri, edits: readonly EditType[]): Thenable; /** * Undo a set of edits. * * This is triggered when a user undoes an edit or when revert is called on a file. * + * @param resource Resource being edited. * @param edit Array of edits. Sorted from most recent to oldest. + * + * @return Thenable signaling that the change has completed. */ - undoEdits(edits: readonly any[]): Thenable; + undoEdits(resource: Uri, edits: readonly EditType[]): Thenable; } - export interface WebviewEditorProvider { + export interface WebviewCustomEditorProvider { /** * Resolve a webview editor for a given resource. * * To resolve a webview editor, a provider must fill in its initial html content and hook up all * the event listeners it is interested it. The provider should also take ownership of the passed in `WebviewPanel`. * - * @param input Information about the resource being resolved. + * @param resource Resource being resolved. * @param webview Webview being resolved. The provider should take ownership of this webview. * - * @return Thenable to a `WebviewEditorCapabilities` indicating that the webview editor has been resolved. - * The `WebviewEditorCapabilities` defines how the custom editor interacts with VS Code. + * @return Thenable indicating that the webview editor has been resolved. */ resolveWebviewEditor( - input: { - readonly resource: Uri - }, + resource: Uri, webview: WebviewPanel, - ): Thenable; + ): Thenable; + + /** + * Controls the editing functionality of a webview editor. This allows the webview editor to hook into standard + * editor events such as `undo` or `save`. + * + * WebviewEditors that do not have `editingCapability` are considered to be readonly. Users can still interact + * with readonly editors, but these editors will not integrate with VS Code's standard editor functionality. + */ + readonly editingDelegate?: WebviewCustomEditorEditingDelegate; } namespace window { @@ -1285,11 +1271,11 @@ declare module 'vscode' { * @param provider Resolves webview editors. * @param options Content settings for a webview panels the provider is given. * - * @return Disposable that unregisters the `WebviewEditorProvider`. + * @return Disposable that unregisters the `WebviewCustomEditorProvider`. */ - export function registerWebviewEditorProvider( + export function registerWebviewCustomEditorProvider( viewType: string, - provider: WebviewEditorProvider, + provider: WebviewCustomEditorProvider, options?: WebviewPanelOptions, ): Disposable; } diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 529d9e60f99016f8453b59f306b4cfde6921b034..c98600d897b62e0f01199fb61581fc065825183e 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -252,7 +252,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma this._revivers.delete(viewType); } - public $registerEditorProvider(extensionData: extHostProtocol.WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions): void { + public $registerEditorProvider(extensionData: extHostProtocol.WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, capabilities: readonly extHostProtocol.WebviewEditorCapabilities[]): void { if (this._editorProviders.has(viewType)) { throw new Error(`Provider for ${viewType} already registered`); } @@ -270,15 +270,17 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma webviewInput.webview.options = options; webviewInput.webview.extension = extension; + const resource = webviewInput.getResource(); - const model = await this.getModel(webviewInput); + const model = await this.loadOrCreateModel(webviewInput, resource, viewType, capabilities); webviewInput.onDisposeWebview(() => { + // TODO: This should be reference counted this._customEditorService.models.disposeModel(model); }); try { await this._proxy.$resolveWebviewEditor( - { resource: webviewInput.getResource(), edits: model.currentEdits }, + resource, handle, viewType, webviewInput.getTitle(), @@ -304,43 +306,45 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma this._editorProviders.delete(viewType); } - public async $registerCapabilities(handle: extHostProtocol.WebviewPanelHandle, capabilities: readonly extHostProtocol.WebviewEditorCapabilities[]): Promise { - const webviewInput = this.getWebviewInput(handle); - const model = await this.getModel(webviewInput); + private async loadOrCreateModel(webviewInput: WebviewInput, resource: URI, viewType: string, capabilities: readonly extHostProtocol.WebviewEditorCapabilities[]) { + const existingModel = this._customEditorService.models.get(webviewInput.getResource(), webviewInput.viewType); + if (existingModel) { + return existingModel; + } + + const newModel = await this._customEditorService.models.loadOrCreate(webviewInput.getResource(), webviewInput.viewType); const capabilitiesSet = new Set(capabilities); if (capabilitiesSet.has(extHostProtocol.WebviewEditorCapabilities.Editable)) { - model.onUndo(edits => { this._proxy.$undoEdits(handle, edits.map(x => x.data)); }); + newModel.onUndo(edits => { + this._proxy.$undoEdits(resource, viewType, edits.map(x => x.data)); + }); - model.onApplyEdit(edits => { - const editsToApply = edits.filter(x => x.source !== webviewInput).map(x => x.data); + newModel.onApplyEdit(edits => { + const editsToApply = edits.filter(x => x.source !== newModel).map(x => x.data); if (editsToApply.length) { - this._proxy.$applyEdits(handle, editsToApply); + this._proxy.$applyEdits(resource, viewType, editsToApply); } }); - model.onWillSave(e => { e.waitUntil(this._proxy.$onSave(handle)); }); + newModel.onWillSave(e => { + e.waitUntil(this._proxy.$onSave(resource.toJSON(), viewType)); + }); - model.onWillSaveAs(e => { e.waitUntil(this._proxy.$onSaveAs(handle, e.resource.toJSON(), e.targetResource.toJSON())); }); + newModel.onWillSaveAs(e => { + e.waitUntil(this._proxy.$onSaveAs(e.resource.toJSON(), viewType, e.targetResource.toJSON())); + }); } + return newModel; } - private getModel(webviewInput: WebviewInput) { - return this._customEditorService.models.loadOrCreate(webviewInput.getResource(), webviewInput.viewType); - } - - public $onEdit(handle: extHostProtocol.WebviewPanelHandle, editData: any): void { - const webview = this.getWebviewInput(handle); - if (!(webview instanceof CustomFileEditorInput)) { - throw new Error('Webview is not a webview editor'); - } - - const model = this._customEditorService.models.get(webview.getResource(), webview.viewType); + public $onEdit(resource: UriComponents, viewType: string, editData: any): void { + const model = this._customEditorService.models.get(URI.revive(resource), viewType); if (!model) { throw new Error('Could not find model for webview editor'); } - model.makeEdit({ source: webview, data: editData }); + model.pushEdit({ source: model, data: editData }); } private hookupWebviewEventDelegate(handle: extHostProtocol.WebviewPanelHandle, input: WebviewInput) { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 69fee57eaceba27f8f72b2439ac4eec4467189a5..815b1c913af59915ea0ed81c3ebf9280f3372170 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -532,9 +532,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => { return extHostWebviews.registerWebviewPanelSerializer(extension, viewType, serializer); }, - registerWebviewEditorProvider: (viewType: string, provider: vscode.WebviewEditorProvider, options?: vscode.WebviewPanelOptions) => { + registerWebviewCustomEditorProvider: (viewType: string, provider: vscode.WebviewCustomEditorProvider, options?: vscode.WebviewPanelOptions) => { checkProposedApiEnabled(extension); - return extHostWebviews.registerWebviewEditorProvider(extension, viewType, provider, options); + return extHostWebviews.registerWebviewCustomEditorProvider(extension, viewType, provider, options); }, registerDecorationProvider(provider: vscode.DecorationProvider) { checkProposedApiEnabled(extension); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 892bcaeb76347f2dcf26f28a6d4cc877a59751d3..3cfcbb4073782b0526388722acc7e21f54bb2938 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -572,11 +572,10 @@ export interface MainThreadWebviewsShape extends IDisposable { $registerSerializer(viewType: string): void; $unregisterSerializer(viewType: string): void; - $registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions): void; + $registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, capabilities: readonly WebviewEditorCapabilities[]): void; $unregisterEditorProvider(viewType: string): void; - $registerCapabilities(handle: WebviewPanelHandle, capabilities: readonly WebviewEditorCapabilities[]): void; - $onEdit(handle: WebviewPanelHandle, editJson: any): void; + $onEdit(resource: UriComponents, viewType: string, editJson: any): void; } export interface WebviewPanelViewStateData { @@ -594,13 +593,13 @@ export interface ExtHostWebviewsShape { $onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise; $deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise; - $resolveWebviewEditor(input: { resource: UriComponents, edits: readonly any[] }, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise; + $resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise; - $undoEdits(handle: WebviewPanelHandle, edits: readonly any[]): void; - $applyEdits(handle: WebviewPanelHandle, edits: readonly any[]): void; + $undoEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void; + $applyEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void; - $onSave(handle: WebviewPanelHandle): Promise; - $onSaveAs(handle: WebviewPanelHandle, resource: UriComponents, targetResource: UriComponents): Promise; + $onSave(resource: UriComponents, viewType: string): Promise; + $onSaveAs(resource: UriComponents, viewType: string, targetResource: UriComponents): Promise; } export interface MainThreadUrlsShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index ef8b03fcd93a1206d7c73510f71c9f182b33e36e..724b670d3400b17fd03a8ee238d8fde367fa5aa3 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -5,7 +5,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -import { assertIsDefined } from 'vs/base/common/types'; import { URI, UriComponents } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import * as modes from 'vs/editor/common/modes'; @@ -16,7 +15,7 @@ import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor'; import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview'; import * as vscode from 'vscode'; -import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewStateData, WebviewEditorCapabilities } from './extHost.protocol'; +import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewEditorCapabilities, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol'; import { Disposable as VSCodeDisposable } from './extHostTypes'; type IconPath = URI | { light: URI, dark: URI }; @@ -117,8 +116,6 @@ export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPa readonly _onDidChangeViewStateEmitter = this._register(new Emitter()); public readonly onDidChangeViewState: Event = this._onDidChangeViewStateEmitter.event; - public _capabilities?: vscode.WebviewEditorCapabilities; - constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, @@ -239,31 +236,6 @@ export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPa }); } - _setCapabilities(capabilities: vscode.WebviewEditorCapabilities) { - this._capabilities = capabilities; - if (capabilities.editingCapability) { - this._register(capabilities.editingCapability.onEdit(edit => { - this._proxy.$onEdit(this._handle, edit); - })); - } - } - - _undoEdits(edits: readonly any[]): void { - assertIsDefined(this._capabilities).editingCapability?.undoEdits(edits); - } - - _redoEdits(edits: readonly any[]): void { - assertIsDefined(this._capabilities).editingCapability?.applyEdits(edits); - } - - async _onSave(): Promise { - await assertIsDefined(this._capabilities?.editingCapability)?.save(); - } - - async _onSaveAs(resource: vscode.Uri, targetResource: vscode.Uri): Promise { - await assertIsDefined(this._capabilities?.editingCapability)?.saveAs(resource, targetResource); - } - private assertNotDisposed() { if (this._isDisposed) { throw new Error('Webview is disposed'); @@ -280,7 +252,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { private readonly _proxy: MainThreadWebviewsShape; private readonly _webviewPanels = new Map(); private readonly _serializers = new Map(); - private readonly _editorProviders = new Map(); + private readonly _editorProviders = new Map(); constructor( mainContext: IMainContext, @@ -331,10 +303,10 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { }); } - public registerWebviewEditorProvider( + public registerWebviewCustomEditorProvider( extension: IExtensionDescription, viewType: string, - provider: vscode.WebviewEditorProvider, + provider: vscode.WebviewCustomEditorProvider, options?: vscode.WebviewPanelOptions, ): vscode.Disposable { if (this._editorProviders.has(viewType)) { @@ -342,7 +314,10 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { } this._editorProviders.set(viewType, { extension, provider, }); - this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {}); + this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {}, this.getCapabilites(provider)); + provider?.editingDelegate?.onEdit(({ edit, resource }) => { + this._proxy.$onEdit(resource, viewType, edit); + }); return new VSCodeDisposable(() => { this._editorProviders.delete(viewType); @@ -431,7 +406,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { } async $resolveWebviewEditor( - input: { resource: UriComponents, edits: readonly any[] }, + resource: UriComponents, handle: WebviewPanelHandle, viewType: string, title: string, @@ -447,46 +422,44 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension, this._logService); const revivedPanel = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview); this._webviewPanels.set(handle, revivedPanel); - const capabilities = await provider.resolveWebviewEditor({ resource: URI.revive(input.resource) }, revivedPanel); - revivedPanel._setCapabilities(capabilities); - this.registerCapabilites(handle, capabilities); - - // TODO: the first set of edits should likely be passed when resolving - if (input.edits.length) { - revivedPanel._redoEdits(input.edits); - } + const revivedResource = URI.revive(resource); + await provider.resolveWebviewEditor(revivedResource, revivedPanel); } - $undoEdits(handle: WebviewPanelHandle, edits: readonly any[]): void { - const panel = this.getWebviewPanel(handle); - panel?._undoEdits(edits); + $undoEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void { + const provider = this.getEditorProvider(viewType); + provider?.editingDelegate?.undoEdits(URI.revive(resource), edits); } - $applyEdits(handle: WebviewPanelHandle, edits: readonly any[]): void { - const panel = this.getWebviewPanel(handle); - panel?._redoEdits(edits); + $applyEdits(resource: UriComponents, viewType: string, edits: readonly any[]): void { + const provider = this.getEditorProvider(viewType); + provider?.editingDelegate?.applyEdits(URI.revive(resource), edits); } - async $onSave(handle: WebviewPanelHandle): Promise { - const panel = this.getWebviewPanel(handle); - return panel?._onSave(); + async $onSave(resource: UriComponents, viewType: string): Promise { + const provider = this.getEditorProvider(viewType); + return provider?.editingDelegate?.save(URI.revive(resource)); } - async $onSaveAs(handle: WebviewPanelHandle, resource: UriComponents, targetResource: UriComponents): Promise { - const panel = this.getWebviewPanel(handle); - return panel?._onSaveAs(URI.revive(resource), URI.revive(targetResource)); + async $onSaveAs(resource: UriComponents, viewType: string, targetResource: UriComponents): Promise { + const provider = this.getEditorProvider(viewType); + return provider?.editingDelegate?.saveAs(URI.revive(resource), URI.revive(targetResource)); } private getWebviewPanel(handle: WebviewPanelHandle): ExtHostWebviewEditor | undefined { return this._webviewPanels.get(handle); } - private registerCapabilites(handle: WebviewPanelHandle, capabilities: vscode.WebviewEditorCapabilities) { + private getEditorProvider(viewType: string): vscode.WebviewCustomEditorProvider | undefined { + return this._editorProviders.get(viewType)?.provider; + } + + private getCapabilites(capabilities: vscode.WebviewCustomEditorProvider) { const declaredCapabilites: WebviewEditorCapabilities[] = []; - if (capabilities.editingCapability) { + if (capabilities.editingDelegate) { declaredCapabilites.push(WebviewEditorCapabilities.Editable); } - this._proxy.$registerCapabilities(handle, declaredCapabilites); + return declaredCapabilites; } } diff --git a/src/vs/workbench/contrib/customEditor/common/customEditor.ts b/src/vs/workbench/contrib/customEditor/common/customEditor.ts index 135ffc819b7eb5f2bc5d48635da546dae228b3db..8f37a7b6747e44061aee74e8aaafbbffbe50a393 100644 --- a/src/vs/workbench/contrib/customEditor/common/customEditor.ts +++ b/src/vs/workbench/contrib/customEditor/common/customEditor.ts @@ -77,7 +77,7 @@ export interface ICustomEditorModel extends IWorkingCopy { save(options?: ISaveOptions): Promise; saveAs(resource: URI, targetResource: URI, currentOptions?: ISaveOptions): Promise; - makeEdit(edit: CustomEditorEdit): void; + pushEdit(edit: CustomEditorEdit): void; } export const enum CustomEditorPriority { diff --git a/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts b/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts index 1443db0b0ce2627d239b76a49ef4bfabe3a4f22f..e4913f6962cee48ad64465dee17677a84ec49df3 100644 --- a/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts +++ b/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts @@ -57,7 +57,7 @@ export class CustomEditorModel extends Disposable implements ICustomEditorModel return this._edits.slice(0, Math.max(0, this._currentEditIndex + 1)); } - public makeEdit(edit: CustomEditorEdit): void { + public pushEdit(edit: CustomEditorEdit): void { this._edits.splice(this._currentEditIndex + 1, this._edits.length - this._currentEditIndex, edit.data); this._currentEditIndex = this._edits.length - 1; this.updateDirty();