diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index a1c2cf45a13dd..067d0c11085c6 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 { @@ -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 85bb26a4ed085..bebfdbb889175 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4820,6 +4820,173 @@ 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; + + /** + * 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; + + /** + * Title of the panel shown in UI. + */ + title: string; + + /** + * Webview belonging to the panel. + */ + readonly webview: Webview; + + /** + * Content settings for the webview panel. + */ + readonly options: WebviewPanelOptions; + + /** + * Editor position of the panel. This property is only set if the webview is in + * one of the three editor view columns. + * + * @deprecated + */ + readonly viewColumn?: 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 +5469,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); }) diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index a841e09157495..7849ba9ea13fd 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -14,44 +14,25 @@ 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; - public readonly onMessageEmitter = new Emitter(); - public readonly onDidReceiveMessage: Event = this.onMessageEmitter.event; - - public readonly onDidChangeViewStateEmitter = new Emitter(); - public readonly onDidChangeViewState: Event = this.onDidChangeViewStateEmitter.event; + readonly _onMessageEmitter = new Emitter(); + public readonly onDidReceiveMessage: Event = this._onMessageEmitter.event; constructor( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, - title: string, options: vscode.WebviewOptions ) { this._handle = handle; this._proxy = proxy; - this._title = title; this._options = options; } dispose() { - 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); - } + this._onMessageEmitter.dispose(); } get html(): string { @@ -94,23 +75,26 @@ 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; 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( handle: WebviewPanelHandle, proxy: MainThreadWebviewsShape, viewType: string, + title: string, viewColumn: vscode.ViewColumn, editorOptions: vscode.WebviewPanelOptions, webview: ExtHostWebview @@ -120,6 +104,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { this._viewType = viewType; this._options = editorOptions; this._viewColumn = viewColumn; + this._title = title; this._webview = webview; } @@ -129,12 +114,14 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { } this._isDisposed = true; - this.onDisposeEmitter.fire(); + this._onDisposeEmitter.fire(); this._proxy.$disposeWebview(this._handle); - this.onDisposeEmitter.dispose(); - this.onDidChangeViewStateEmitter.dispose(); + this._webview.dispose(); + + this._onDisposeEmitter.dispose(); + this._onDidChangeViewStateEmitter.dispose(); } get webview() { @@ -147,16 +134,29 @@ 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; } - get position(): vscode.ViewColumn { + get viewColumn(): vscode.ViewColumn { this.assertNotDisposed(); return this._viewColumn; } - set position(value: vscode.ViewColumn) { + _setViewColumn(value: vscode.ViewColumn) { this.assertNotDisposed(); this._viewColumn = value; } @@ -166,7 +166,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { return this._visible; } - set visible(value: boolean) { + _setVisible(value: boolean) { this.assertNotDisposed(); this._visible = value; } @@ -212,8 +212,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; } @@ -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); } } @@ -246,10 +246,10 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { const panel = this.getWebviewPanel(handle); if (panel) { const viewColumn = typeConverters.toViewColumn(position); - if (panel.visible !== visible || panel.position !== viewColumn) { - panel.visible = visible; - panel.position = viewColumn; - panel.onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); + if (panel.visible !== visible || panel.viewColumn !== viewColumn) { + panel._setVisible(visible); + panel._setViewColumn(viewColumn); + panel._onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); } } } @@ -276,8 +276,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); }