From bcc3ecccb6ce7902b53163ac0dd271dc1a0014ad Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 16 Apr 2018 11:48:38 -0700 Subject: [PATCH 1/8] Promote webview Api to stable Fixes #43713 Fixes #28263 --- src/vs/vscode.d.ts | 176 +++++++++++++++++ src/vs/vscode.proposed.d.ts | 178 +----------------- src/vs/workbench/api/node/extHost.api.impl.ts | 6 +- 3 files changed, 180 insertions(+), 180 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 85bb26a4ed085..547179daec612 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4820,6 +4820,170 @@ declare module 'vscode' { resolveTask(task: Task, token?: CancellationToken): ProviderResult; } + /** + * Content settings for a webview. + */ + export interface WebviewOptions { + /** + * Should scripts be enabled in the webview content? + * + * Defaults to false (scripts-disabled). + */ + readonly enableScripts?: boolean; + + /** + * Should command uris be enabled in webview content? + * + * Defaults to false. + */ + readonly enableCommandUris?: boolean; + + /** + * Root paths from which the webview can load local (filesystem) resources using the `vscode-resource:` scheme. + * + * Default to the root folders of the current workspace plus the extension's install directory. + * + * Pass in an empty array to disallow access to any local resources. + */ + readonly localResourceRoots?: ReadonlyArray; + } + + /** + * A webview displays html content, like an iframe. + */ + export interface Webview { + /** + * Content settings for the webview. + */ + readonly options: WebviewOptions; + + /** + * Title of the webview shown in UI. + */ + title: string; + + /** + * Contents of the webview. + * + * Should be a complete html document. + */ + html: string; + + /** + * Fired when the webview content posts a message. + */ + readonly onDidReceiveMessage: Event; + + /** + * Post a message to the webview content. + * + * Messages are only develivered if the webview is visible. + * + * @param message Body of the message. + */ + postMessage(message: any): Thenable; + } + + /** + * Content settings for a webview panel. + */ + export interface WebviewPanelOptions { + /** + * Should the find widget be enabled in the panel? + * + * Defaults to false. + */ + readonly enableFindWidget?: boolean; + + /** + * Should the webview panel's content (iframe) be kept around even when the panel + * is no longer visible? + * + * Normally the webview panel's html context is created when the panel becomes visible + * and destroyed when it is is hidden. Extensions that have complex state + * or UI can set the `retainContextWhenHidden` to make VS Code keep the webview + * context around, even when the webview moves to a background tab. When + * the panel becomes visible again, the context is automatically restored + * in the exact same state it was in originally. + * + * `retainContextWhenHidden` has a high memory overhead and should only be used if + * your panel's context cannot be quickly saved and restored. + */ + readonly retainContextWhenHidden?: boolean; + } + + /** + * A panel that contains a webview. + */ + interface WebviewPanel { + /** + * Type of the webview panel, such as `'markdown.preview'`. + */ + readonly viewType: string; + + /** + * Webview belonging to the panel. + */ + readonly webview: Webview; + + /** + * Content settings for the webview panel. + */ + readonly options: WebviewPanelOptions; + + /** + * Editor position of the panel. + */ + readonly position?: ViewColumn; + + /** + * Is the panel currently visible? + */ + readonly visible: boolean; + + /** + * Fired when the panel's view state changes. + */ + readonly onDidChangeViewState: Event; + + /** + * Fired when the panel is disposed. + * + * This may be because the user closed the panel or because `.dispose()` was + * called on it. + * + * Trying to use the panel after it has been disposed throws an exception. + */ + readonly onDidDispose: Event; + + /** + * Show the webview panel in a given column. + * + * A webview panel may only show in a single column at a time. If it is already showing, this + * method moves it to a new column. + */ + reveal(viewColumn: ViewColumn): void; + + /** + * Dispose of the webview panel. + * + * This closes the panel if it showing and disposes of the resources owned by the webview. + * Webview panels are also disposed when the user closes the webview panel. Both cases + * fire the `onDispose` event. + */ + dispose(): any; + } + + /** + * Event fired when a webview panel's view state changes. + */ + export interface WebviewPanelOnDidChangeViewStateEvent { + /** + * Webview panel whose view state changed. + */ + readonly webviewPanel: WebviewPanel; + } + /** * Namespace describing the environment the editor runs in. */ @@ -5302,6 +5466,18 @@ declare module 'vscode' { */ export function createOutputChannel(name: string): OutputChannel; + /** + * Create and show a new webview panel. + * + * @param viewType Identifies the type of the webview panel. + * @param title Title of the panel. + * @param position Editor column to show the new panel in. + * @param options Settings for the new panel. + * + * @return New webview panel. + */ + export function createWebviewPanel(viewType: string, title: string, position: ViewColumn, options: WebviewPanelOptions & WebviewOptions): WebviewPanel; + /** * Set a message to the status bar. This is a short hand for the more powerful * status bar [items](#window.createStatusBarItem). diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 7a55ba9b0e2e7..41bce3b26f5d7 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -469,171 +469,7 @@ declare module 'vscode' { //#endregion - //#region Matt: WebView - - /** - * Content settings for a webview. - */ - export interface WebviewOptions { - /** - * Should scripts be enabled in the webview content? - * - * Defaults to false (scripts-disabled). - */ - readonly enableScripts?: boolean; - - /** - * Should command uris be enabled in webview content? - * - * Defaults to false. - */ - readonly enableCommandUris?: boolean; - - /** - * Root paths from which the webview can load local (filesystem) resources using the `vscode-resource:` scheme. - * - * Default to the root folders of the current workspace plus the extension's install directory. - * - * Pass in an empty array to disallow access to any local resources. - */ - readonly localResourceRoots?: ReadonlyArray; - } - - /** - * A webview displays html content, like an iframe. - */ - export interface Webview { - /** - * Content settings for the webview. - */ - readonly options: WebviewOptions; - - /** - * Title of the webview shown in UI. - */ - title: string; - - /** - * Contents of the webview. - * - * Should be a complete html document. - */ - html: string; - - /** - * Fired when the webview content posts a message. - */ - readonly onDidReceiveMessage: Event; - - /** - * Post a message to the webview content. - * - * Messages are only develivered if the webview is visible. - * - * @param message Body of the message. - */ - postMessage(message: any): Thenable; - } - - /** - * Content settings for a webview panel. - */ - export interface WebviewPanelOptions { - /** - * Should the find widget be enabled in the panel? - * - * Defaults to false. - */ - readonly enableFindWidget?: boolean; - - /** - * Should the webview panel's content (iframe) be kept around even when the panel - * is no longer visible? - * - * Normally the webview panel's html context is created when the panel becomes visible - * and destroyed when it is is hidden. Extensions that have complex state - * or UI can set the `retainContextWhenHidden` to make VS Code keep the webview - * context around, even when the webview moves to a background tab. When - * the panel becomes visible again, the context is automatically restored - * in the exact same state it was in originally. - * - * `retainContextWhenHidden` has a high memory overhead and should only be used if - * your panel's context cannot be quickly saved and restored. - */ - readonly retainContextWhenHidden?: boolean; - } - - /** - * A panel that contains a webview. - */ - interface WebviewPanel { - /** - * Type of the webview panel, such as `'markdown.preview'`. - */ - readonly viewType: string; - - /** - * Webview belonging to the panel. - */ - readonly webview: Webview; - - /** - * Content settings for the webview panel. - */ - readonly options: WebviewPanelOptions; - - /** - * Editor position of the panel. - */ - readonly position?: ViewColumn; - - /** - * Is the panel current visible? - */ - readonly visible: boolean; - - /** - * Fired when the panel's view state changes. - */ - readonly onDidChangeViewState: Event; - - /** - * Fired when the panel is disposed. - * - * This may be because the user closed the panel or because `.dispose()` was - * called on it. - * - * Trying to use the panel after it has been disposed throws an exception. - */ - readonly onDidDispose: Event; - - /** - * Show the webview panel in a given column. - * - * A webview panel may only show in a single column at a time. If it is already showing, this - * method moves it to a new column. - */ - reveal(viewColumn: ViewColumn): void; - - /** - * Dispose of the webview panel. - * - * This closes the panel if it showing and disposes of the resources owned by the webview. - * Webview panels are also disposed when the user closes the webview panel. Both cases - * fire the `onDispose` event. - */ - dispose(): any; - } - - /** - * Event fired when a webview panel's view state changes. - */ - export interface WebviewPanelOnDidChangeViewStateEvent { - /** - * Webview panel whose view state changed. - */ - readonly webviewPanel: WebviewPanel; - } + //#region Matt: WebView Serializer /** * Save and restore webview panels that have been persisted when vscode shuts down. @@ -665,18 +501,6 @@ declare module 'vscode' { } namespace window { - /** - * Create and show a new webview panel. - * - * @param viewType Identifies the type of the webview panel. - * @param title Title of the panel. - * @param position Editor column to show the new panel in. - * @param options Settings for the new webview panel. - * - * @return New webview panel. - */ - export function createWebviewPanel(viewType: string, title: string, position: ViewColumn, options: WebviewPanelOptions & WebviewOptions): WebviewPanel; - /** * Registers a webview panel serializer. * diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 3de535519712c..b483818cea889 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -431,6 +431,9 @@ export function createApiFactory( createOutputChannel(name: string): vscode.OutputChannel { return extHostOutputService.createOutputChannel(name); }, + createWebviewPanel(viewType: string, title: string, column: vscode.ViewColumn, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { + return extHostWebviews.createWebview(viewType, title, column, options, extension.extensionFolderPath); + }, createTerminal(nameOrOptions: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[]): vscode.Terminal { if (typeof nameOrOptions === 'object') { return extHostTerminalService.createTerminalFromOptions(nameOrOptions); @@ -450,9 +453,6 @@ export function createApiFactory( registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => { return extHostDecorations.registerDecorationProvider(provider, extension.id); }), - createWebviewPanel: proposedApiFunction(extension, (viewType: string, title: string, column: vscode.ViewColumn, options: vscode.WebviewPanelOptions & vscode.WebviewOptions) => { - return extHostWebviews.createWebview(viewType, title, column, options, extension.extensionFolderPath); - }), registerWebviewPanelSerializer: proposedApiFunction(extension, (viewType: string, serializer: vscode.WebviewPanelSerializer) => { return extHostWebviews.registerWebviewPanelSerializer(viewType, serializer); }) From ee92f9abc358113a62371869ef4062aa4d1e25fd Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 17 Apr 2018 10:35:56 -0700 Subject: [PATCH 2/8] Rename position back to viewColumn and mark viewColumn as deprecated This allows us to more easily re-introduce a `position` property once we have gridlayout --- .../markdown-language-features/src/features/preview.ts | 2 +- src/vs/vscode.d.ts | 7 +++++-- src/vs/workbench/api/node/extHostWebview.ts | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index a1c2cf45a13dd..4e3b3c487ddd0 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -236,7 +236,7 @@ export class MarkdownPreview { } public get position(): vscode.ViewColumn | undefined { - return this.editor.position; + return this.editor.viewColumn; } public isWebviewOf(webview: vscode.WebviewPanel): boolean { diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 547179daec612..5bcb0473c3a04 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4932,9 +4932,12 @@ declare module 'vscode' { readonly options: WebviewPanelOptions; /** - * Editor position of the panel. + * Editor position of the panel. This property is only set if the webview is in + * one of the three editor view columns. + * + * @deprecated */ - readonly position?: ViewColumn; + readonly viewColumn?: ViewColumn; /** * Is the panel currently visible? diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index a841e09157495..25c43afa21bbb 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -151,12 +151,12 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { return this._options; } - get position(): vscode.ViewColumn { + get viewColumn(): vscode.ViewColumn { this.assertNotDisposed(); return this._viewColumn; } - set position(value: vscode.ViewColumn) { + set viewColumn(value: vscode.ViewColumn) { this.assertNotDisposed(); this._viewColumn = value; } @@ -246,9 +246,9 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { const panel = this.getWebviewPanel(handle); if (panel) { const viewColumn = typeConverters.toViewColumn(position); - if (panel.visible !== visible || panel.position !== viewColumn) { + if (panel.visible !== visible || panel.viewColumn !== viewColumn) { panel.visible = visible; - panel.position = viewColumn; + panel.viewColumn = viewColumn; panel.onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); } } From 8fab6cc1a10b7c1c8c18f09df196240e93939881 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 18 Apr 2018 16:17:43 -0700 Subject: [PATCH 3/8] Move dispose methods onto webview itself Also better hide a few 'internal' methods / properties on the panel / webview --- .../src/features/preview.ts | 4 +- src/vs/vscode.d.ts | 38 ++++++------ src/vs/workbench/api/node/extHostWebview.ts | 58 +++++++++---------- 3 files changed, 49 insertions(+), 51 deletions(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 4e3b3c487ddd0..8f91144439018 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -106,7 +106,7 @@ export class MarkdownPreview { this._locked = locked; this.editor = webview; - this.editor.onDidDispose(() => { + this.editor.webview.onDidDispose(() => { this.dispose(); }, null, this.disposables); @@ -192,7 +192,7 @@ export class MarkdownPreview { this._onDisposeEmitter.dispose(); this._onDidChangeViewStateEmitter.dispose(); - this.editor.dispose(); + this.editor.webview.dispose(); disposeAll(this.disposables); } diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 5bcb0473c3a04..ede448d9a84b6 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4874,6 +4874,16 @@ declare module 'vscode' { */ readonly onDidReceiveMessage: Event; + /** + * Fired when the webview is disposed. + * + * This may be because the user closed the panel that owns this webview + * or because `.dispose()` was called on the webview. + * + * Trying to use the webview after it has been disposed throws an exception. + */ + readonly onDidDispose: Event; + /** * Post a message to the webview content. * @@ -4882,6 +4892,15 @@ declare module 'vscode' { * @param message Body of the message. */ postMessage(message: any): Thenable; + + /** + * Dispose of the webview panel. + * + * This closes the panel that owns the webview if it showing and disposes of the + * resources owned by the webview. Webview are also disposed when the user closes + * the webview panel that owns the webview. Both cases fire the `onDispose` event. + */ + dispose(): any; } /** @@ -4949,16 +4968,6 @@ declare module 'vscode' { */ readonly onDidChangeViewState: Event; - /** - * Fired when the panel is disposed. - * - * This may be because the user closed the panel or because `.dispose()` was - * called on it. - * - * Trying to use the panel after it has been disposed throws an exception. - */ - readonly onDidDispose: Event; - /** * Show the webview panel in a given column. * @@ -4966,15 +4975,6 @@ declare module 'vscode' { * method moves it to a new column. */ reveal(viewColumn: ViewColumn): void; - - /** - * Dispose of the webview panel. - * - * This closes the panel if it showing and disposes of the resources owned by the webview. - * Webview panels are also disposed when the user closes the webview panel. Both cases - * fire the `onDispose` event. - */ - dispose(): any; } /** diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 25c43afa21bbb..176cb479c86fb 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -19,12 +19,12 @@ export class ExtHostWebview implements vscode.Webview { private _options: vscode.WebviewOptions; private _isDisposed: boolean = false; + public readonly onDisposeEmitter = new Emitter(); + public readonly onDidDispose: Event = this.onDisposeEmitter.event; + public readonly onMessageEmitter = new Emitter(); public readonly onDidReceiveMessage: Event = this.onMessageEmitter.event; - public readonly onDidChangeViewStateEmitter = new Emitter(); - public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; - constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, @@ -37,8 +37,17 @@ export class ExtHostWebview implements vscode.Webview { this._options = options; } - dispose() { - this.onDidChangeViewStateEmitter.dispose(); + public dispose() { + if (this._isDisposed) { + return; + } + + this._isDisposed = true; + this.onDisposeEmitter.fire(); + + this._proxy.$disposeWebview(this._handle); + + this.onDisposeEmitter.dispose(); } get title(): string { @@ -100,13 +109,9 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { private _viewColumn: vscode.ViewColumn; private _visible: boolean = true; - public readonly onDisposeEmitter = new Emitter(); - public readonly onDidDispose: Event = this.onDisposeEmitter.event; - public readonly onDidChangeViewStateEmitter = new Emitter(); public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; - constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, @@ -121,6 +126,8 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { this._options = editorOptions; this._viewColumn = viewColumn; this._webview = webview; + + webview.onDidDispose(this.dispose, this); } public dispose() { @@ -129,44 +136,35 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { } this._isDisposed = true; - this.onDisposeEmitter.fire(); - - this._proxy.$disposeWebview(this._handle); - - this.onDisposeEmitter.dispose(); this.onDidChangeViewStateEmitter.dispose(); } - get webview() { - this.assertNotDisposed(); + public get webview() { return this._webview; } - get viewType(): string { - this.assertNotDisposed(); + public get viewType(): string { return this._viewType; } - get options() { + public get options() { return this._options; } - get viewColumn(): vscode.ViewColumn { - this.assertNotDisposed(); - return this._viewColumn; + public get viewColumn(): vscode.ViewColumn | undefined { + return this._isDisposed ? undefined : this._viewColumn; } - set viewColumn(value: vscode.ViewColumn) { + _setViewColumn(value: vscode.ViewColumn) { this.assertNotDisposed(); this._viewColumn = value; } - get visible(): boolean { - this.assertNotDisposed(); - return this._visible; + public get visible(): boolean { + return !this._isDisposed && this._visible; } - set visible(value: boolean) { + _setVisible(value: boolean) { this.assertNotDisposed(); this._visible = value; } @@ -247,8 +245,8 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { if (panel) { const viewColumn = typeConverters.toViewColumn(position); if (panel.visible !== visible || panel.viewColumn !== viewColumn) { - panel.visible = visible; - panel.viewColumn = viewColumn; + panel._setVisible(visible); + panel._setViewColumn(viewColumn); panel.onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); } } @@ -257,7 +255,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { $onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Thenable { const panel = this.getWebviewPanel(handle); if (panel) { - panel.dispose(); + panel.webview.dispose(); this._webviewPanels.delete(handle); } return TPromise.as(void 0); From 4bfc732271fe58b92327bdfce6fa8610a9025b52 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 19 Apr 2018 10:27:17 -0700 Subject: [PATCH 4/8] Revert "Move dispose methods onto webview itself" This reverts commit 8fab6cc1a10b7c1c8c18f09df196240e93939881. --- .../src/features/preview.ts | 4 +- src/vs/vscode.d.ts | 38 ++++++------ src/vs/workbench/api/node/extHostWebview.ts | 58 ++++++++++--------- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 8f91144439018..4e3b3c487ddd0 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -106,7 +106,7 @@ export class MarkdownPreview { this._locked = locked; this.editor = webview; - this.editor.webview.onDidDispose(() => { + this.editor.onDidDispose(() => { this.dispose(); }, null, this.disposables); @@ -192,7 +192,7 @@ export class MarkdownPreview { this._onDisposeEmitter.dispose(); this._onDidChangeViewStateEmitter.dispose(); - this.editor.webview.dispose(); + this.editor.dispose(); disposeAll(this.disposables); } diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index ede448d9a84b6..5bcb0473c3a04 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4874,16 +4874,6 @@ declare module 'vscode' { */ readonly onDidReceiveMessage: Event; - /** - * Fired when the webview is disposed. - * - * This may be because the user closed the panel that owns this webview - * or because `.dispose()` was called on the webview. - * - * Trying to use the webview after it has been disposed throws an exception. - */ - readonly onDidDispose: Event; - /** * Post a message to the webview content. * @@ -4892,15 +4882,6 @@ declare module 'vscode' { * @param message Body of the message. */ postMessage(message: any): Thenable; - - /** - * Dispose of the webview panel. - * - * This closes the panel that owns the webview if it showing and disposes of the - * resources owned by the webview. Webview are also disposed when the user closes - * the webview panel that owns the webview. Both cases fire the `onDispose` event. - */ - dispose(): any; } /** @@ -4968,6 +4949,16 @@ declare module 'vscode' { */ readonly onDidChangeViewState: Event; + /** + * Fired when the panel is disposed. + * + * This may be because the user closed the panel or because `.dispose()` was + * called on it. + * + * Trying to use the panel after it has been disposed throws an exception. + */ + readonly onDidDispose: Event; + /** * Show the webview panel in a given column. * @@ -4975,6 +4966,15 @@ declare module 'vscode' { * method moves it to a new column. */ reveal(viewColumn: ViewColumn): void; + + /** + * Dispose of the webview panel. + * + * This closes the panel if it showing and disposes of the resources owned by the webview. + * Webview panels are also disposed when the user closes the webview panel. Both cases + * fire the `onDispose` event. + */ + dispose(): any; } /** diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 176cb479c86fb..25c43afa21bbb 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -19,12 +19,12 @@ export class ExtHostWebview implements vscode.Webview { private _options: vscode.WebviewOptions; private _isDisposed: boolean = false; - public readonly onDisposeEmitter = new Emitter(); - public readonly onDidDispose: Event = this.onDisposeEmitter.event; - public readonly onMessageEmitter = new Emitter(); public readonly onDidReceiveMessage: Event = this.onMessageEmitter.event; + public readonly onDidChangeViewStateEmitter = new Emitter(); + public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; + constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, @@ -37,17 +37,8 @@ export class ExtHostWebview implements vscode.Webview { this._options = options; } - public dispose() { - if (this._isDisposed) { - return; - } - - this._isDisposed = true; - this.onDisposeEmitter.fire(); - - this._proxy.$disposeWebview(this._handle); - - this.onDisposeEmitter.dispose(); + dispose() { + this.onDidChangeViewStateEmitter.dispose(); } get title(): string { @@ -109,9 +100,13 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { private _viewColumn: vscode.ViewColumn; private _visible: boolean = true; + public readonly onDisposeEmitter = new Emitter(); + public readonly onDidDispose: Event = this.onDisposeEmitter.event; + public readonly onDidChangeViewStateEmitter = new Emitter(); public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; + constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, @@ -126,8 +121,6 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { this._options = editorOptions; this._viewColumn = viewColumn; this._webview = webview; - - webview.onDidDispose(this.dispose, this); } public dispose() { @@ -136,35 +129,44 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { } this._isDisposed = true; + this.onDisposeEmitter.fire(); + + this._proxy.$disposeWebview(this._handle); + + this.onDisposeEmitter.dispose(); this.onDidChangeViewStateEmitter.dispose(); } - public get webview() { + get webview() { + this.assertNotDisposed(); return this._webview; } - public get viewType(): string { + get viewType(): string { + this.assertNotDisposed(); return this._viewType; } - public get options() { + get options() { return this._options; } - public get viewColumn(): vscode.ViewColumn | undefined { - return this._isDisposed ? undefined : this._viewColumn; + get viewColumn(): vscode.ViewColumn { + this.assertNotDisposed(); + return this._viewColumn; } - _setViewColumn(value: vscode.ViewColumn) { + set viewColumn(value: vscode.ViewColumn) { this.assertNotDisposed(); this._viewColumn = value; } - public get visible(): boolean { - return !this._isDisposed && this._visible; + get visible(): boolean { + this.assertNotDisposed(); + return this._visible; } - _setVisible(value: boolean) { + set visible(value: boolean) { this.assertNotDisposed(); this._visible = value; } @@ -245,8 +247,8 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { if (panel) { const viewColumn = typeConverters.toViewColumn(position); if (panel.visible !== visible || panel.viewColumn !== viewColumn) { - panel._setVisible(visible); - panel._setViewColumn(viewColumn); + panel.visible = visible; + panel.viewColumn = viewColumn; panel.onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); } } @@ -255,7 +257,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { $onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Thenable { const panel = this.getWebviewPanel(handle); if (panel) { - panel.webview.dispose(); + panel.dispose(); this._webviewPanels.delete(handle); } return TPromise.as(void 0); From 25f370f4437b2e642b2dbb2572d2c79354662a95 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 19 Apr 2018 10:29:28 -0700 Subject: [PATCH 5/8] Move title onto webview panel --- .../src/features/preview.ts | 4 +- src/vs/vscode.d.ts | 10 ++--- src/vs/workbench/api/node/extHostWebview.ts | 41 ++++++++++--------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 4e3b3c487ddd0..067d0c11085c6 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -269,7 +269,7 @@ export class MarkdownPreview { public toggleLock() { this._locked = !this._locked; - this.editor.webview.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked); + this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked); } private isPreviewOf(resource: vscode.Uri): boolean { @@ -327,7 +327,7 @@ export class MarkdownPreview { this.currentVersion = { resource, version: document.version }; const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line); if (this._resource === resource) { - this.editor.webview.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked); + this.editor.title = MarkdownPreview.getPreviewTitle(this._resource, this._locked); this.editor.webview.html = content; } } diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 5bcb0473c3a04..bebfdbb889175 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4857,11 +4857,6 @@ declare module 'vscode' { */ readonly options: WebviewOptions; - /** - * Title of the webview shown in UI. - */ - title: string; - /** * Contents of the webview. * @@ -4921,6 +4916,11 @@ declare module 'vscode' { */ readonly viewType: string; + /** + * Title of the panel shown in UI. + */ + title: string; + /** * Webview belonging to the panel. */ diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 25c43afa21bbb..3f53468c25d87 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -14,7 +14,6 @@ import { Disposable } from './extHostTypes'; export class ExtHostWebview implements vscode.Webview { private readonly _handle: WebviewPanelHandle; private readonly _proxy: MainThreadWebviewsShape; - private _title: string; private _html: string; private _options: vscode.WebviewOptions; private _isDisposed: boolean = false; @@ -28,12 +27,10 @@ export class ExtHostWebview implements vscode.Webview { constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, - title: string, options: vscode.WebviewOptions ) { this._handle = handle; this._proxy = proxy; - this._title = title; this._options = options; } @@ -41,19 +38,6 @@ export class ExtHostWebview implements vscode.Webview { this.onDidChangeViewStateEmitter.dispose(); } - get title(): string { - this.assertNotDisposed(); - return this._title; - } - - set title(value: string) { - this.assertNotDisposed(); - if (this._title !== value) { - this._title = value; - this._proxy.$setTitle(this._handle, value); - } - } - get html(): string { this.assertNotDisposed(); return this._html; @@ -94,6 +78,8 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { private readonly _handle: WebviewPanelHandle; private readonly _proxy: MainThreadWebviewsShape; private readonly _viewType: string; + private _title: string; + private readonly _options: vscode.WebviewPanelOptions; private readonly _webview: ExtHostWebview; private _isDisposed: boolean = false; @@ -111,6 +97,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, viewType: string, + title: string, viewColumn: vscode.ViewColumn, editorOptions: vscode.WebviewPanelOptions, webview: ExtHostWebview @@ -120,6 +107,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { this._viewType = viewType; this._options = editorOptions; this._viewColumn = viewColumn; + this._title = title; this._webview = webview; } @@ -147,6 +135,19 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { return this._viewType; } + get title(): string { + this.assertNotDisposed(); + return this._title; + } + + set title(value: string) { + this.assertNotDisposed(); + if (this._title !== value) { + this._title = value; + this._proxy.$setTitle(this._handle, value); + } + } + get options() { return this._options; } @@ -212,8 +213,8 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { const handle = ExtHostWebviews.webviewHandlePool++ + ''; this._proxy.$createWebviewPanel(handle, viewType, title, typeConverters.fromViewColumn(viewColumn), options, extensionFolderPath); - const webview = new ExtHostWebview(handle, this._proxy, title, options); - const panel = new ExtHostWebviewPanel(handle, this._proxy, viewType, viewColumn, options, webview); + const webview = new ExtHostWebview(handle, this._proxy, options); + const panel = new ExtHostWebviewPanel(handle, this._proxy, viewType, title, viewColumn, options, webview); this._webviewPanels.set(handle, panel); return panel; } @@ -276,8 +277,8 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { return TPromise.wrapError(new Error(`No serializer found for '${viewType}'`)); } - const webview = new ExtHostWebview(webviewHandle, this._proxy, title, options); - const revivedPanel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, typeConverters.toViewColumn(position), options, webview); + const webview = new ExtHostWebview(webviewHandle, this._proxy, options); + const revivedPanel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, title, typeConverters.toViewColumn(position), options, webview); this._webviewPanels.set(webviewHandle, revivedPanel); return serializer.deserializeWebviewPanel(revivedPanel, state); } From 256c4d669e447084570843bf7c00611b7214105b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 19 Apr 2018 10:31:54 -0700 Subject: [PATCH 6/8] Use _ names for private setters --- src/vs/workbench/api/node/extHostWebview.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 3f53468c25d87..9348207e171aa 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -157,7 +157,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { return this._viewColumn; } - set viewColumn(value: vscode.ViewColumn) { + _setViewColumn(value: vscode.ViewColumn) { this.assertNotDisposed(); this._viewColumn = value; } @@ -167,7 +167,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { return this._visible; } - set visible(value: boolean) { + _setVisible(value: boolean) { this.assertNotDisposed(); this._visible = value; } @@ -248,8 +248,8 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { if (panel) { const viewColumn = typeConverters.toViewColumn(position); if (panel.visible !== visible || panel.viewColumn !== viewColumn) { - panel.visible = visible; - panel.viewColumn = viewColumn; + panel._setVisible(visible); + panel._setViewColumn(viewColumn); panel.onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); } } From e23749bbca431efc4674131b16166956200ddc57 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 19 Apr 2018 10:33:39 -0700 Subject: [PATCH 7/8] Remove unused emitter and dispose onMessageEmitter --- src/vs/workbench/api/node/extHostWebview.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 9348207e171aa..69df8342fbbf9 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -21,9 +21,6 @@ export class ExtHostWebview implements vscode.Webview { public readonly onMessageEmitter = new Emitter(); public readonly onDidReceiveMessage: Event = this.onMessageEmitter.event; - public readonly onDidChangeViewStateEmitter = new Emitter(); - public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; - constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, @@ -35,7 +32,7 @@ export class ExtHostWebview implements vscode.Webview { } dispose() { - this.onDidChangeViewStateEmitter.dispose(); + this.onMessageEmitter.dispose(); } get html(): string { @@ -121,6 +118,8 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { this._proxy.$disposeWebview(this._handle); + this._webview.dispose(); + this.onDisposeEmitter.dispose(); this.onDidChangeViewStateEmitter.dispose(); } From 46d6f503f2927cf2db035979ea16dbb729b35b30 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 19 Apr 2018 10:34:39 -0700 Subject: [PATCH 8/8] Preview internal emitters with _ --- src/vs/workbench/api/node/extHostWebview.ts | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index 69df8342fbbf9..7849ba9ea13fd 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -18,8 +18,8 @@ export class ExtHostWebview implements vscode.Webview { private _options: vscode.WebviewOptions; private _isDisposed: boolean = false; - public readonly onMessageEmitter = new Emitter(); - public readonly onDidReceiveMessage: Event = this.onMessageEmitter.event; + readonly _onMessageEmitter = new Emitter(); + public readonly onDidReceiveMessage: Event = this._onMessageEmitter.event; constructor( handle: WebviewPanelHandle, @@ -32,7 +32,7 @@ export class ExtHostWebview implements vscode.Webview { } dispose() { - this.onMessageEmitter.dispose(); + this._onMessageEmitter.dispose(); } get html(): string { @@ -83,11 +83,11 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { private _viewColumn: vscode.ViewColumn; private _visible: boolean = true; - public readonly onDisposeEmitter = new Emitter(); - public readonly onDidDispose: Event = this.onDisposeEmitter.event; + readonly _onDisposeEmitter = new Emitter(); + public readonly onDidDispose: Event = this._onDisposeEmitter.event; - public readonly onDidChangeViewStateEmitter = new Emitter(); - public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; + readonly _onDidChangeViewStateEmitter = new Emitter(); + public readonly onDidChangeViewState: Event = this._onDidChangeViewStateEmitter.event; constructor( @@ -114,14 +114,14 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { } this._isDisposed = true; - this.onDisposeEmitter.fire(); + this._onDisposeEmitter.fire(); this._proxy.$disposeWebview(this._handle); this._webview.dispose(); - this.onDisposeEmitter.dispose(); - this.onDidChangeViewStateEmitter.dispose(); + this._onDisposeEmitter.dispose(); + this._onDidChangeViewStateEmitter.dispose(); } get webview() { @@ -238,7 +238,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { $onMessage(handle: WebviewPanelHandle, message: any): void { const panel = this.getWebviewPanel(handle); if (panel) { - panel.webview.onMessageEmitter.fire(message); + panel.webview._onMessageEmitter.fire(message); } } @@ -249,7 +249,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { if (panel.visible !== visible || panel.viewColumn !== viewColumn) { panel._setVisible(visible); panel._setViewColumn(viewColumn); - panel.onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); + panel._onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); } } }