未验证 提交 91191fb8 编写于 作者: M Matt Bierner 提交者: GitHub

Promote webview Api to stable (#47989)

* Promote webview Api to stable

Fixes #43713
Fixes #28263

* 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

* Move dispose methods onto webview itself

Also better hide a few 'internal' methods / properties on the panel / webview

* Revert "Move dispose methods onto webview itself"

This reverts commit 8fab6cc1a10b7c1c8c18f09df196240e93939881.

* Move title onto webview panel

* Use _ names for private setters

* Remove unused emitter and dispose onMessageEmitter

* Preview internal emitters with _
上级 d907469a
......@@ -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;
}
}
......
......@@ -4820,6 +4820,173 @@ declare module 'vscode' {
resolveTask(task: Task, token?: CancellationToken): ProviderResult<Task>;
}
/**
* 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<Uri>;
}
/**
* 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<any>;
/**
* 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<boolean>;
}
/**
* 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<WebviewPanelOnDidChangeViewStateEvent>;
/**
* 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<void>;
/**
* 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).
......
......@@ -474,171 +474,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<Uri>;
}
/**
* 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<any>;
/**
* 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<boolean>;
}
/**
* 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<WebviewPanelOnDidChangeViewStateEvent>;
/**
* 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<void>;
/**
* 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.
......@@ -670,18 +506,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.
*
......
......@@ -408,6 +408,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(<vscode.TerminalOptions>nameOrOptions);
......@@ -427,9 +430,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);
})
......
......@@ -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<any>();
public readonly onDidReceiveMessage: Event<any> = this.onMessageEmitter.event;
public readonly onDidChangeViewStateEmitter = new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>();
public readonly onDidChangeViewState: Event<vscode.WebviewPanelOnDidChangeViewStateEvent> = this.onDidChangeViewStateEmitter.event;
readonly _onMessageEmitter = new Emitter<any>();
public readonly onDidReceiveMessage: Event<any> = 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<void>();
public readonly onDidDispose: Event<void> = this.onDisposeEmitter.event;
readonly _onDisposeEmitter = new Emitter<void>();
public readonly onDidDispose: Event<void> = this._onDisposeEmitter.event;
public readonly onDidChangeViewStateEmitter = new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>();
public readonly onDidChangeViewState: Event<vscode.WebviewPanelOnDidChangeViewStateEvent> = this.onDidChangeViewStateEmitter.event;
readonly _onDidChangeViewStateEmitter = new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>();
public readonly onDidChangeViewState: Event<vscode.WebviewPanelOnDidChangeViewStateEvent> = 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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册