From bca7206f59265525e6c40549ed7b96d6fbbb22dc Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 7 Nov 2019 14:53:13 -0800 Subject: [PATCH] Forward onEdit from webviewEditor to mainthread --- .../api/browser/mainThreadWebview.ts | 7 ++++ .../workbench/api/common/extHost.protocol.ts | 2 + src/vs/workbench/api/common/extHostWebview.ts | 40 +++++++++++++------ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 1ce660a06e8..907f258a0bc 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -296,6 +296,13 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma this._editorProviders.delete(viewType); } + public $onEdit(handle: extHostProtocol.WebviewPanelHandle, editJson: string): void { + const webview = this.getWebviewInput(handle); + if (!(webview instanceof CustomFileEditorInput)) { + throw new Error(`Webview is not a webview editor`); + } + } + private hookupWebviewEventDelegate(handle: extHostProtocol.WebviewPanelHandle, input: WebviewInput) { input.webview.onDidClickLink((uri: URI) => this.onDidClickLink(handle, uri)); input.webview.onMessage((message: any) => this._proxy.$onMessage(handle, message)); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 63da5a6a6b2..0d286d7cc52 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -570,6 +570,8 @@ export interface MainThreadWebviewsShape extends IDisposable { $registerEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions): void; $unregisterEditorProvider(viewType: string): void; + + $onEdit(handle: WebviewPanelHandle, editJson: string): void; } export interface WebviewPanelViewStateData { diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index 50fdaec003e..4d4a02ac726 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { URI, UriComponents } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import * as modes from 'vs/editor/common/modes'; @@ -14,7 +15,7 @@ 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 } from './extHost.protocol'; -import { Disposable } from './extHostTypes'; +import { Disposable as VSCodeDisposable } from './extHostTypes'; type IconPath = URI | { light: URI, dark: URI }; @@ -91,8 +92,7 @@ export class ExtHostWebview implements vscode.Webview { } } -export class ExtHostWebviewEditor implements vscode.WebviewPanel { - +export class ExtHostWebviewEditor extends Disposable implements vscode.WebviewPanel { private readonly _handle: WebviewPanelHandle; private readonly _proxy: MainThreadWebviewsShape; private readonly _viewType: string; @@ -107,10 +107,10 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel { _isDisposed: boolean = false; - readonly _onDisposeEmitter = new Emitter(); + readonly _onDisposeEmitter = this._register(new Emitter()); public readonly onDidDispose: Event = this._onDisposeEmitter.event; - readonly _onDidChangeViewStateEmitter = new Emitter(); + readonly _onDidChangeViewStateEmitter = this._register(new Emitter()); public readonly onDidChangeViewState: Event = this._onDidChangeViewStateEmitter.event; constructor( @@ -122,6 +122,7 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel { editorOptions: vscode.WebviewPanelOptions, webview: ExtHostWebview ) { + super(); this._handle = handle; this._proxy = proxy; this._viewType = viewType; @@ -135,16 +136,12 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel { if (this._isDisposed) { return; } - this._isDisposed = true; this._onDisposeEmitter.fire(); - this._proxy.$disposeWebview(this._handle); - this._webview.dispose(); - this._onDisposeEmitter.dispose(); - this._onDidChangeViewStateEmitter.dispose(); + super.dispose(); } get webview() { @@ -236,6 +233,10 @@ export class ExtHostWebviewEditor implements vscode.WebviewPanel { }); } + _addDisposable(disposable: IDisposable) { + this._register(disposable); + } + private assertNotDisposed() { if (this._isDisposed) { throw new Error('Webview is disposed'); @@ -296,7 +297,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { this._serializers.set(viewType, { serializer, extension }); this._proxy.$registerSerializer(viewType); - return new Disposable(() => { + return new VSCodeDisposable(() => { this._serializers.delete(viewType); this._proxy.$unregisterSerializer(viewType); }); @@ -315,7 +316,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { this._editorProviders.set(viewType, { extension, provider, }); this._proxy.$registerEditorProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, options || {}); - return new Disposable(() => { + return new VSCodeDisposable(() => { this._editorProviders.delete(viewType); this._proxy.$unregisterEditorProvider(viewType); }); @@ -418,11 +419,24 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { if (!entry) { return Promise.reject(new Error(`No provider found for '${viewType}'`)); } + const { provider, extension } = entry; const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, extension); 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); - await Promise.resolve(provider.resolveWebviewEditor({ resource: URI.revive(resource) }, revivedPanel)); + const capabilities = await provider.resolveWebviewEditor({ resource: URI.revive(resource) }, revivedPanel); + revivedPanel._addDisposable(this.hookupCapabilities(handle, capabilities)); + } + + private hookupCapabilities(handle: WebviewPanelHandle, capabilities: vscode.WebviewEditorCapabilities): IDisposable { + const disposables = new DisposableStore(); + if (capabilities.editingCapability) { + disposables.add(capabilities.editingCapability.onEdit(edit => { + this._proxy.$onEdit(handle, JSON.stringify(edit)); + })); + } + + return disposables; } }