mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Split out Webview
from WebviewEditor
in proposed API (#47370)
* Split out `Webview` from `WebviewEditor` in API **Problem** The current proposed `Webview` interface has a few methods and properties that are very editor specific, such as `.reveal` and `.onDidChangeViewState`. These properies will not make sense if we ever allow webview to be displayed in other locations, such as in widgets **Proposal** Split the concepts of a `Webview` and of a `WebveiwEditor`. A webview is the html content itself. A `WebviewEditor` is an editor that displays a `Webview` This would allow us to easily add other types of `Webview` owning objects in the future without having to document that some methods only apply when a webview is used as an editor vs as a widget
This commit is contained in:
parent
485a469b94
commit
8cb7e80544
|
@ -20,7 +20,7 @@ export class MarkdownPreview {
|
|||
|
||||
public static viewType = 'markdown.preview';
|
||||
|
||||
private readonly webview: vscode.Webview;
|
||||
private readonly editor: vscode.WebviewEditor;
|
||||
private throttleTimer: any;
|
||||
private line: number | undefined = undefined;
|
||||
private readonly disposables: vscode.Disposable[] = [];
|
||||
|
@ -32,7 +32,7 @@ export class MarkdownPreview {
|
|||
|
||||
|
||||
public static async revive(
|
||||
webview: vscode.Webview,
|
||||
webview: vscode.WebviewEditor,
|
||||
state: any,
|
||||
contentProvider: MarkdownContentProvider,
|
||||
previewConfigurations: MarkdownPreviewConfigurationManager,
|
||||
|
@ -69,7 +69,7 @@ export class MarkdownPreview {
|
|||
topmostLineMonitor: MarkdownFileTopmostLineMonitor,
|
||||
contributions: MarkdownContributions
|
||||
): MarkdownPreview {
|
||||
const webview = vscode.window.createWebview(
|
||||
const webview = vscode.window.createWebviewEditor(
|
||||
MarkdownPreview.viewType,
|
||||
MarkdownPreview.getPreviewTitle(resource, locked),
|
||||
previewColumn, {
|
||||
|
@ -90,7 +90,7 @@ export class MarkdownPreview {
|
|||
}
|
||||
|
||||
private constructor(
|
||||
webview: vscode.Webview,
|
||||
webview: vscode.WebviewEditor,
|
||||
private _resource: vscode.Uri,
|
||||
public locked: boolean,
|
||||
private readonly contentProvider: MarkdownContentProvider,
|
||||
|
@ -98,17 +98,17 @@ export class MarkdownPreview {
|
|||
private readonly logger: Logger,
|
||||
topmostLineMonitor: MarkdownFileTopmostLineMonitor
|
||||
) {
|
||||
this.webview = webview;
|
||||
this.editor = webview;
|
||||
|
||||
this.webview.onDidDispose(() => {
|
||||
this.editor.onDidDispose(() => {
|
||||
this.dispose();
|
||||
}, null, this.disposables);
|
||||
|
||||
this.webview.onDidChangeViewState(e => {
|
||||
this.editor.onDidChangeViewState(e => {
|
||||
this._onDidChangeViewStateEmitter.fire(e);
|
||||
}, null, this.disposables);
|
||||
|
||||
this.webview.onDidReceiveMessage(e => {
|
||||
this.editor.webview.onDidReceiveMessage(e => {
|
||||
if (e.source !== this._resource.toString()) {
|
||||
return;
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ export class MarkdownPreview {
|
|||
private readonly _onDisposeEmitter = new vscode.EventEmitter<void>();
|
||||
public readonly onDispose = this._onDisposeEmitter.event;
|
||||
|
||||
private readonly _onDidChangeViewStateEmitter = new vscode.EventEmitter<vscode.WebviewOnDidChangeViewStateEvent>();
|
||||
private readonly _onDidChangeViewStateEmitter = new vscode.EventEmitter<vscode.WebviewEditorOnDidChangeViewStateEvent>();
|
||||
public readonly onDidChangeViewState = this._onDidChangeViewStateEmitter.event;
|
||||
|
||||
public get resource(): vscode.Uri {
|
||||
|
@ -180,7 +180,7 @@ export class MarkdownPreview {
|
|||
|
||||
this._onDisposeEmitter.dispose();
|
||||
this._onDidChangeViewStateEmitter.dispose();
|
||||
this.webview.dispose();
|
||||
this.editor.dispose();
|
||||
|
||||
disposeAll(this.disposables);
|
||||
}
|
||||
|
@ -224,15 +224,15 @@ export class MarkdownPreview {
|
|||
}
|
||||
|
||||
public get viewColumn(): vscode.ViewColumn | undefined {
|
||||
return this.webview.viewColumn;
|
||||
return this.editor.viewColumn;
|
||||
}
|
||||
|
||||
public isPreviewOf(resource: vscode.Uri): boolean {
|
||||
return this._resource.fsPath === resource.fsPath;
|
||||
}
|
||||
|
||||
public isWebviewOf(webview: vscode.Webview): boolean {
|
||||
return this.webview === webview;
|
||||
public isWebviewOf(webview: vscode.WebviewEditor): boolean {
|
||||
return this.editor === webview;
|
||||
}
|
||||
|
||||
public matchesResource(
|
||||
|
@ -256,12 +256,12 @@ export class MarkdownPreview {
|
|||
}
|
||||
|
||||
public reveal(viewColumn: vscode.ViewColumn) {
|
||||
this.webview.reveal(viewColumn);
|
||||
this.editor.reveal(viewColumn);
|
||||
}
|
||||
|
||||
public toggleLock() {
|
||||
this.locked = !this.locked;
|
||||
this.webview.title = MarkdownPreview.getPreviewTitle(this._resource, this.locked);
|
||||
this.editor.webview.title = MarkdownPreview.getPreviewTitle(this._resource, this.locked);
|
||||
}
|
||||
|
||||
private static getPreviewTitle(resource: vscode.Uri, locked: boolean): string {
|
||||
|
@ -293,7 +293,7 @@ export class MarkdownPreview {
|
|||
|
||||
private postMessage(msg: any) {
|
||||
if (!this._disposed) {
|
||||
this.webview.postMessage(msg);
|
||||
this.editor.webview.postMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,8 +315,8 @@ 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.webview.title = MarkdownPreview.getPreviewTitle(this._resource, this.locked);
|
||||
this.webview.html = content;
|
||||
this.editor.webview.title = MarkdownPreview.getPreviewTitle(this._resource, this.locked);
|
||||
this.editor.webview.html = content;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import { isMarkdownFile } from '../util/file';
|
|||
import { MarkdownPreviewConfigurationManager } from './previewConfig';
|
||||
import { MarkdownContributions } from '../markdownExtensions';
|
||||
|
||||
export class MarkdownPreviewManager implements vscode.WebviewSerializer {
|
||||
export class MarkdownPreviewManager implements vscode.WebviewEditorSerializer {
|
||||
private static readonly markdownPreviewActiveContextKey = 'markdownPreviewFocus';
|
||||
|
||||
private readonly topmostLineMonitor = new MarkdownFileTopmostLineMonitor();
|
||||
|
@ -36,7 +36,7 @@ export class MarkdownPreviewManager implements vscode.WebviewSerializer {
|
|||
}
|
||||
}, null, this.disposables);
|
||||
|
||||
this.disposables.push(vscode.window.registerWebviewSerializer(MarkdownPreview.viewType, this));
|
||||
this.disposables.push(vscode.window.registerWebviewEditorSerializer(MarkdownPreview.viewType, this));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
@ -88,8 +88,8 @@ export class MarkdownPreviewManager implements vscode.WebviewSerializer {
|
|||
}
|
||||
}
|
||||
|
||||
public async deserializeWebview(
|
||||
webview: vscode.Webview,
|
||||
public async deserializeWebviewEditor(
|
||||
webview: vscode.WebviewEditor,
|
||||
state: any
|
||||
): Promise<void> {
|
||||
const preview = await MarkdownPreview.revive(
|
||||
|
@ -103,8 +103,8 @@ export class MarkdownPreviewManager implements vscode.WebviewSerializer {
|
|||
this.registerPreview(preview);
|
||||
}
|
||||
|
||||
public async serializeWebview(
|
||||
webview: vscode.Webview,
|
||||
public async serializeWebviewEditor(
|
||||
webview: vscode.WebviewEditor,
|
||||
): Promise<any> {
|
||||
const preview = this.previews.find(preview => preview.isWebviewOf(webview));
|
||||
return preview ? preview.state : undefined;
|
||||
|
|
162
src/vs/vscode.proposed.d.ts
vendored
162
src/vs/vscode.proposed.d.ts
vendored
|
@ -593,28 +593,6 @@ declare module 'vscode' {
|
|||
*/
|
||||
readonly enableCommandUris?: boolean;
|
||||
|
||||
/**
|
||||
* Should the find widget be enabled in the webview?
|
||||
*
|
||||
* Defaults to false.
|
||||
*/
|
||||
readonly enableFindWidget?: boolean;
|
||||
|
||||
/**
|
||||
* Should the webview's context be kept around even when the webview is no longer visible?
|
||||
*
|
||||
* Normally a webview's context is created when the webview becomes visible
|
||||
* and destroyed when the webview is hidden. Apps 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 webview 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 webview's context cannot be quickly saved and restored.
|
||||
*/
|
||||
readonly retainContextWhenHidden?: boolean;
|
||||
|
||||
/**
|
||||
* Root paths from which the webview can load local (filesystem) resources using the `vscode-resource:` scheme.
|
||||
*
|
||||
|
@ -625,20 +603,10 @@ declare module 'vscode' {
|
|||
readonly localResourceRoots?: Uri[];
|
||||
}
|
||||
|
||||
export interface WebviewOnDidChangeViewStateEvent {
|
||||
readonly viewColumn: ViewColumn;
|
||||
readonly active: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* A webview displays html content, like an iframe.
|
||||
*/
|
||||
export interface Webview {
|
||||
/**
|
||||
* The type of the webview, such as `'markdown.preview'`
|
||||
*/
|
||||
readonly viewType: string;
|
||||
|
||||
/**
|
||||
* Content settings for the webview.
|
||||
*/
|
||||
|
@ -656,26 +624,11 @@ declare module 'vscode' {
|
|||
*/
|
||||
html: string;
|
||||
|
||||
/**
|
||||
* The column in which the webview is showing.
|
||||
*/
|
||||
readonly viewColumn?: ViewColumn;
|
||||
|
||||
/**
|
||||
* Fired when the webview content posts a message.
|
||||
*/
|
||||
readonly onDidReceiveMessage: Event<any>;
|
||||
|
||||
/**
|
||||
* Fired when the webview is disposed.
|
||||
*/
|
||||
readonly onDidDispose: Event<void>;
|
||||
|
||||
/**
|
||||
* Fired when the webview's view state changes.
|
||||
*/
|
||||
readonly onDidChangeViewState: Event<WebviewOnDidChangeViewStateEvent>;
|
||||
|
||||
/**
|
||||
* Post a message to the webview content.
|
||||
*
|
||||
|
@ -684,9 +637,77 @@ declare module 'vscode' {
|
|||
* @param message Body of the message.
|
||||
*/
|
||||
postMessage(message: any): Thenable<boolean>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content settings for a webview editor.
|
||||
*/
|
||||
export interface WebviewEditorOptions {
|
||||
/**
|
||||
* Should the find widget be enabled in the editor?
|
||||
*
|
||||
* Defaults to false.
|
||||
*/
|
||||
readonly enableFindWidget?: boolean;
|
||||
|
||||
/**
|
||||
* Shows the webview in a given column.
|
||||
* Should the webview editor's content (iframe) be kept around even when the editor
|
||||
* is no longer visible?
|
||||
*
|
||||
* Normally the editor's html context is created when the editor becomes visible
|
||||
* and destroyed when it is is hidden. Apps 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 editor 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 editor's context cannot be quickly saved and restored.
|
||||
*/
|
||||
readonly retainContextWhenHidden?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* An editor that contains a webview.
|
||||
*/
|
||||
interface WebviewEditor {
|
||||
/**
|
||||
* The type of the webview editor, such as `'markdown.preview'`.
|
||||
*/
|
||||
readonly viewType: string;
|
||||
|
||||
/**
|
||||
* The webview belonging to the editor.
|
||||
*/
|
||||
readonly webview: Webview;
|
||||
|
||||
/**
|
||||
* Content settings for the webview editor.
|
||||
*/
|
||||
readonly options: WebviewEditorOptions;
|
||||
|
||||
/**
|
||||
* The column in which the editor is showing.
|
||||
*/
|
||||
readonly viewColumn?: ViewColumn;
|
||||
|
||||
/**
|
||||
* Fired when the editor's view state changes.
|
||||
*/
|
||||
readonly onDidChangeViewState: Event<WebviewEditorOnDidChangeViewStateEvent>;
|
||||
|
||||
/**
|
||||
* Fired when the editor is disposed.
|
||||
*
|
||||
* This may be because the user closed the editor or because `.dispose()` was
|
||||
* called on it.
|
||||
*
|
||||
* Trying to use the webview after it has been disposed throws an exception.
|
||||
*/
|
||||
readonly onDidDispose: Event<void>;
|
||||
|
||||
/**
|
||||
* Shows the webview editor in a given column.
|
||||
*
|
||||
* A webview may only be in a single column at a time. If it is already showing, this
|
||||
* command moves it to a new column.
|
||||
|
@ -694,64 +715,69 @@ declare module 'vscode' {
|
|||
reveal(viewColumn: ViewColumn): void;
|
||||
|
||||
/**
|
||||
* Dispose of the the webview.
|
||||
* Dispose of the webview editor.
|
||||
*
|
||||
* This closes the webview if it showing and disposes of the resources owned by the webview.
|
||||
* Webview are also disposed when the user closes the webview editor. Both cases fire `onDispose`
|
||||
* event. Trying to use the webview after it has been disposed throws an exception.
|
||||
* event.
|
||||
*/
|
||||
dispose(): any;
|
||||
}
|
||||
|
||||
export interface WebviewEditorOnDidChangeViewStateEvent {
|
||||
readonly viewColumn: ViewColumn;
|
||||
readonly active: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save and restore webviews that have been persisted when vscode shuts down.
|
||||
* Save and restore webview editors that have been persisted when vscode shuts down.
|
||||
*/
|
||||
interface WebviewSerializer {
|
||||
interface WebviewEditorSerializer {
|
||||
/**
|
||||
* Save a webview's `state`.
|
||||
* Save a webview editors's `state`.
|
||||
*
|
||||
* Called before shutdown. Webview may or may not be visible.
|
||||
* Called before shutdown. Webview editor may or may not be visible.
|
||||
*
|
||||
* @param webview Webview to serialize.
|
||||
* @param webviewEditor Webview editor to serialize.
|
||||
*
|
||||
* @returns JSON serializable state blob.
|
||||
*/
|
||||
serializeWebview(webview: Webview): Thenable<any>;
|
||||
serializeWebviewEditor(webviewEditor: WebviewEditor): Thenable<any>;
|
||||
|
||||
/**
|
||||
* Restore a webview from its `state`.
|
||||
* Restore a webview editor from its `state`.
|
||||
*
|
||||
* Called when a serialized webview first becomes active.
|
||||
*
|
||||
* @param webview Webview to restore. The serializer should take ownership of this webview.
|
||||
* @param webviewEditor Webview editor to restore. The serializer should take ownership of this editor.
|
||||
* @param state Persisted state.
|
||||
*/
|
||||
deserializeWebview(webview: Webview, state: any): Thenable<void>;
|
||||
deserializeWebviewEditor(webviewEditor: WebviewEditor, state: any): Thenable<void>;
|
||||
}
|
||||
|
||||
namespace window {
|
||||
/**
|
||||
* Create and show a new webview.
|
||||
* Create and show a new webview editor.
|
||||
*
|
||||
* @param viewType Identifies the type of the webview.
|
||||
* @param viewType Identifies the type of the webview editor.
|
||||
* @param title Title of the webview.
|
||||
* @param column Editor column to show the new webview in.
|
||||
* @param options Content settings for the webview.
|
||||
* @param column Editor column to show the new webview editor in.
|
||||
* @param editorOptions Settings for the webview editor.
|
||||
*/
|
||||
export function createWebview(viewType: string, title: string, column: ViewColumn, options: WebviewOptions): Webview;
|
||||
export function createWebviewEditor(viewType: string, title: string, column: ViewColumn, options: WebviewEditorOptions & WebviewOptions): WebviewEditor;
|
||||
|
||||
/**
|
||||
* Registers a webview serializer.
|
||||
* Registers a webview editor serializer.
|
||||
*
|
||||
* Extensions that support reviving should have an `"onView:viewType"` activation method and
|
||||
* make sure that `registerWebviewSerializer` is called during activation.
|
||||
* make sure that `registerWebviewEditorSerializer` is called during activation.
|
||||
*
|
||||
* Only a single serializer may be registered at a time for a given `viewType`.
|
||||
*
|
||||
* @param viewType Type of the webview that can be serialized.
|
||||
* @param viewType Type of the webview editor that can be serialized.
|
||||
* @param reviver Webview serializer.
|
||||
*/
|
||||
export function registerWebviewSerializer(viewType: string, reviver: WebviewSerializer): Disposable;
|
||||
export function registerWebviewEditorSerializer(viewType: string, reviver: WebviewEditorSerializer): Disposable;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
|
|
@ -129,7 +129,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
|
|||
this._webviews.set(handle, webview);
|
||||
webview._events = this.createWebviewEventDelegate(handle);
|
||||
|
||||
return this._proxy.$deserializeWebview(handle, webview.state.viewType, webview.state.state, webview.position, webview.options)
|
||||
return this._proxy.$deserializeWebview(handle, webview.state.viewType, webview.getTitle(), webview.state.state, webview.position, webview.options)
|
||||
.then(undefined, () => {
|
||||
webview.html = MainThreadWebviews.getDeserializationFailedContents(viewType);
|
||||
});
|
||||
|
|
|
@ -416,11 +416,11 @@ export function createApiFactory(
|
|||
registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => {
|
||||
return extHostDecorations.registerDecorationProvider(provider, extension.id);
|
||||
}),
|
||||
createWebview: proposedApiFunction(extension, (viewType: string, title: string, column: vscode.ViewColumn, options: vscode.WebviewOptions) => {
|
||||
createWebviewEditor: proposedApiFunction(extension, (viewType: string, title: string, column: vscode.ViewColumn, options: vscode.WebviewEditorOptions & vscode.WebviewOptions) => {
|
||||
return extHostWebviews.createWebview(viewType, title, column, options, extension.extensionFolderPath);
|
||||
}),
|
||||
registerWebviewSerializer: proposedApiFunction(extension, (viewType: string, serializer: vscode.WebviewSerializer) => {
|
||||
return extHostWebviews.registerWebviewSerializer(viewType, serializer);
|
||||
registerWebviewEditorSerializer: proposedApiFunction(extension, (viewType: string, serializer: vscode.WebviewEditorSerializer) => {
|
||||
return extHostWebviews.registerWebviewEditorSerializer(viewType, serializer);
|
||||
})
|
||||
};
|
||||
|
||||
|
|
|
@ -350,7 +350,7 @@ export interface MainThreadTelemetryShape extends IDisposable {
|
|||
export type WebviewHandle = string;
|
||||
|
||||
export interface MainThreadWebviewsShape extends IDisposable {
|
||||
$createWebview(handle: WebviewHandle, viewType: string, title: string, column: EditorPosition, options: vscode.WebviewOptions, extensionFolderPath: string): void;
|
||||
$createWebview(handle: WebviewHandle, viewType: string, title: string, column: EditorPosition, options: vscode.WebviewEditorOptions & vscode.WebviewOptions, extensionFolderPath: string): void;
|
||||
$disposeWebview(handle: WebviewHandle): void;
|
||||
$reveal(handle: WebviewHandle, column: EditorPosition): void;
|
||||
$setTitle(handle: WebviewHandle, value: string): void;
|
||||
|
@ -365,7 +365,7 @@ export interface ExtHostWebviewsShape {
|
|||
$onMessage(handle: WebviewHandle, message: any): void;
|
||||
$onDidChangeWeviewViewState(handle: WebviewHandle, active: boolean, position: EditorPosition): void;
|
||||
$onDidDisposeWeview(handle: WebviewHandle): Thenable<void>;
|
||||
$deserializeWebview(newWebviewHandle: WebviewHandle, viewType: string, state: any, position: EditorPosition, options: vscode.WebviewOptions): Thenable<void>;
|
||||
$deserializeWebview(newWebviewHandle: WebviewHandle, viewType: string, title: string, state: any, position: EditorPosition, options: vscode.WebviewOptions): Thenable<void>;
|
||||
$serializeWebview(webviewHandle: WebviewHandle): Thenable<any>;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,58 +12,35 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
|||
import { Disposable } from './extHostTypes';
|
||||
|
||||
export class ExtHostWebview implements vscode.Webview {
|
||||
|
||||
private readonly _handle: WebviewHandle;
|
||||
private readonly _viewType: string;
|
||||
private readonly _proxy: MainThreadWebviewsShape;
|
||||
private _title: string;
|
||||
private _html: string;
|
||||
private _options: vscode.WebviewOptions;
|
||||
private _isDisposed: boolean = false;
|
||||
private _viewColumn: vscode.ViewColumn;
|
||||
private _active: boolean;
|
||||
|
||||
public readonly onMessageEmitter = new Emitter<any>();
|
||||
public readonly onDidReceiveMessage: Event<any> = this.onMessageEmitter.event;
|
||||
|
||||
public readonly onDisposeEmitter = new Emitter<void>();
|
||||
public readonly onDidDispose: Event<void> = this.onDisposeEmitter.event;
|
||||
|
||||
public readonly onDidChangeViewStateEmitter = new Emitter<vscode.WebviewOnDidChangeViewStateEvent>();
|
||||
public readonly onDidChangeViewState: Event<vscode.WebviewOnDidChangeViewStateEvent> = this.onDidChangeViewStateEmitter.event;
|
||||
public readonly onDidChangeViewStateEmitter = new Emitter<vscode.WebviewEditorOnDidChangeViewStateEvent>();
|
||||
public readonly onDidChangeViewState: Event<vscode.WebviewEditorOnDidChangeViewStateEvent> = this.onDidChangeViewStateEmitter.event;
|
||||
|
||||
constructor(
|
||||
handle: WebviewHandle,
|
||||
proxy: MainThreadWebviewsShape,
|
||||
viewType: string,
|
||||
viewColumn: vscode.ViewColumn,
|
||||
title: string,
|
||||
options: vscode.WebviewOptions
|
||||
) {
|
||||
this._handle = handle;
|
||||
this._proxy = proxy;
|
||||
this._viewType = viewType;
|
||||
this._viewColumn = viewColumn;
|
||||
this._title = title;
|
||||
this._options = options;
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isDisposed = true;
|
||||
this._proxy.$disposeWebview(this._handle);
|
||||
|
||||
this.onDisposeEmitter.dispose();
|
||||
this.onMessageEmitter.dispose();
|
||||
dispose() {
|
||||
this.onDidChangeViewStateEmitter.dispose();
|
||||
}
|
||||
|
||||
get viewType(): string {
|
||||
this.assertNotDisposed();
|
||||
return this._viewType;
|
||||
}
|
||||
|
||||
get title(): string {
|
||||
this.assertNotDisposed();
|
||||
return this._title;
|
||||
|
@ -95,6 +72,84 @@ export class ExtHostWebview implements vscode.Webview {
|
|||
return this._options;
|
||||
}
|
||||
|
||||
public postMessage(message: any): Thenable<boolean> {
|
||||
this.assertNotDisposed();
|
||||
return this._proxy.$sendMessage(this._handle, message);
|
||||
}
|
||||
|
||||
public reveal(viewColumn: vscode.ViewColumn): void {
|
||||
this.assertNotDisposed();
|
||||
this._proxy.$reveal(this._handle, typeConverters.fromViewColumn(viewColumn));
|
||||
}
|
||||
|
||||
private assertNotDisposed() {
|
||||
if (this._isDisposed) {
|
||||
throw new Error('Webview is disposed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostWebviewEditor implements vscode.WebviewEditor {
|
||||
|
||||
private readonly _handle: WebviewHandle;
|
||||
private readonly _viewType: string;
|
||||
private readonly _options: vscode.WebviewEditorOptions;
|
||||
private readonly _proxy: MainThreadWebviewsShape;
|
||||
private _isDisposed: boolean = false;
|
||||
private _viewColumn: vscode.ViewColumn;
|
||||
private _active: boolean;
|
||||
|
||||
public readonly onDisposeEmitter = new Emitter<void>();
|
||||
public readonly onDidDispose: Event<void> = this.onDisposeEmitter.event;
|
||||
|
||||
public readonly onDidChangeViewStateEmitter = new Emitter<vscode.WebviewEditorOnDidChangeViewStateEvent>();
|
||||
public readonly onDidChangeViewState: Event<vscode.WebviewEditorOnDidChangeViewStateEvent> = this.onDidChangeViewStateEmitter.event;
|
||||
|
||||
private _webview: ExtHostWebview;
|
||||
|
||||
constructor(
|
||||
handle: WebviewHandle,
|
||||
proxy: MainThreadWebviewsShape,
|
||||
viewType: string,
|
||||
title: string,
|
||||
viewColumn: vscode.ViewColumn,
|
||||
editorOptions: vscode.WebviewEditorOptions,
|
||||
webviewOptions: vscode.WebviewOptions
|
||||
) {
|
||||
this._handle = handle;
|
||||
this._proxy = proxy;
|
||||
this._viewType = viewType;
|
||||
this._options = editorOptions;
|
||||
this._viewColumn = viewColumn;
|
||||
this._webview = new ExtHostWebview(handle, proxy, title, webviewOptions);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isDisposed = true;
|
||||
this._proxy.$disposeWebview(this._handle);
|
||||
|
||||
this.onDisposeEmitter.dispose();
|
||||
this.onDidChangeViewStateEmitter.dispose();
|
||||
}
|
||||
|
||||
get webview() {
|
||||
this.assertNotDisposed();
|
||||
return this._webview;
|
||||
}
|
||||
|
||||
get viewType(): string {
|
||||
this.assertNotDisposed();
|
||||
return this._viewType;
|
||||
}
|
||||
|
||||
get options() {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
get viewColumn(): vscode.ViewColumn {
|
||||
this.assertNotDisposed();
|
||||
return this._viewColumn;
|
||||
|
@ -137,8 +192,8 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
|||
|
||||
private readonly _proxy: MainThreadWebviewsShape;
|
||||
|
||||
private readonly _webviews = new Map<WebviewHandle, ExtHostWebview>();
|
||||
private readonly _serializers = new Map<string, vscode.WebviewSerializer>();
|
||||
private readonly _webviews = new Map<WebviewHandle, ExtHostWebviewEditor>();
|
||||
private readonly _serializers = new Map<string, vscode.WebviewEditorSerializer>();
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext
|
||||
|
@ -150,20 +205,20 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
|||
viewType: string,
|
||||
title: string,
|
||||
viewColumn: vscode.ViewColumn,
|
||||
options: vscode.WebviewOptions,
|
||||
options: vscode.WebviewEditorOptions & vscode.WebviewOptions,
|
||||
extensionFolderPath: string
|
||||
): vscode.Webview {
|
||||
): vscode.WebviewEditor {
|
||||
const handle = ExtHostWebviews.webviewHandlePool++ + '';
|
||||
this._proxy.$createWebview(handle, viewType, title, typeConverters.fromViewColumn(viewColumn), options, extensionFolderPath);
|
||||
|
||||
const webview = new ExtHostWebview(handle, this._proxy, viewType, viewColumn, options);
|
||||
const webview = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, viewColumn, options, options);
|
||||
this._webviews.set(handle, webview);
|
||||
return webview;
|
||||
}
|
||||
|
||||
registerWebviewSerializer(
|
||||
registerWebviewEditorSerializer(
|
||||
viewType: string,
|
||||
serializer: vscode.WebviewSerializer
|
||||
serializer: vscode.WebviewEditorSerializer
|
||||
): vscode.Disposable {
|
||||
if (this._serializers.has(viewType)) {
|
||||
throw new Error(`Serializer for '${viewType}' already registered`);
|
||||
|
@ -181,7 +236,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
|||
$onMessage(handle: WebviewHandle, message: any): void {
|
||||
const webview = this.getWebview(handle);
|
||||
if (webview) {
|
||||
webview.onMessageEmitter.fire(message);
|
||||
webview.webview.onMessageEmitter.fire(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,6 +264,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
|||
$deserializeWebview(
|
||||
webviewHandle: WebviewHandle,
|
||||
viewType: string,
|
||||
title: string,
|
||||
state: any,
|
||||
position: Position,
|
||||
options: vscode.WebviewOptions
|
||||
|
@ -218,9 +274,9 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
|||
return TPromise.wrapError(new Error(`No serializer found for '${viewType}'`));
|
||||
}
|
||||
|
||||
const revivedWebview = new ExtHostWebview(webviewHandle, this._proxy, viewType, typeConverters.toViewColumn(position), options);
|
||||
const revivedWebview = new ExtHostWebviewEditor(webviewHandle, this._proxy, viewType, title, typeConverters.toViewColumn(position), options as vscode.WebviewEditorOptions, options as vscode.WebviewOptions);
|
||||
this._webviews.set(webviewHandle, revivedWebview);
|
||||
return serializer.deserializeWebview(revivedWebview, state);
|
||||
return serializer.deserializeWebviewEditor(revivedWebview, state);
|
||||
}
|
||||
|
||||
$serializeWebview(
|
||||
|
@ -236,10 +292,10 @@ export class ExtHostWebviews implements ExtHostWebviewsShape {
|
|||
return TPromise.as(undefined);
|
||||
}
|
||||
|
||||
return serialzer.serializeWebview(webview);
|
||||
return serialzer.serializeWebviewEditor(webview);
|
||||
}
|
||||
|
||||
private getWebview(handle: WebviewHandle): ExtHostWebview | undefined {
|
||||
private getWebview(handle: WebviewHandle): ExtHostWebviewEditor | undefined {
|
||||
return this._webviews.get(handle);
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ export interface WebviewEvents {
|
|||
onDidClickLink?(link: URI, options: vscode.WebviewOptions): void;
|
||||
}
|
||||
|
||||
export interface WebviewInputOptions extends vscode.WebviewOptions {
|
||||
export interface WebviewInputOptions extends vscode.WebviewOptions, vscode.WebviewEditorOptions {
|
||||
tryRestoreScrollPosition?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ suite('ExtHostWebview', function () {
|
|||
const shape = createNoopMainThreadWebviews();
|
||||
const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape));
|
||||
|
||||
let lastInvokedDeserializer: vscode.WebviewSerializer | undefined = undefined;
|
||||
let lastInvokedDeserializer: vscode.WebviewEditorSerializer | undefined = undefined;
|
||||
|
||||
class NoopSerializer implements vscode.WebviewSerializer {
|
||||
async serializeWebview(webview: vscode.Webview): Promise<any> { /* noop */ }
|
||||
class NoopSerializer implements vscode.WebviewEditorSerializer {
|
||||
async serializeWebviewEditor(webview: vscode.WebviewEditor): Promise<any> { /* noop */ }
|
||||
|
||||
async deserializeWebview(webview: vscode.Webview, state: any): Promise<void> {
|
||||
async deserializeWebviewEditor(webview: vscode.WebviewEditor, state: any): Promise<void> {
|
||||
lastInvokedDeserializer = this;
|
||||
}
|
||||
}
|
||||
|
@ -34,20 +34,20 @@ suite('ExtHostWebview', function () {
|
|||
const serializerA = new NoopSerializer();
|
||||
const serializerB = new NoopSerializer();
|
||||
|
||||
const serializerARegistration = extHostWebviews.registerWebviewSerializer(viewType, serializerA);
|
||||
const serializerARegistration = extHostWebviews.registerWebviewEditorSerializer(viewType, serializerA);
|
||||
|
||||
await extHostWebviews.$deserializeWebview('x', viewType, {}, EditorPosition.ONE, {});
|
||||
await extHostWebviews.$deserializeWebview('x', viewType, 'title', {}, EditorPosition.ONE, {});
|
||||
assert.strictEqual(lastInvokedDeserializer, serializerA);
|
||||
|
||||
assert.throws(
|
||||
() => extHostWebviews.registerWebviewSerializer(viewType, serializerB),
|
||||
() => extHostWebviews.registerWebviewEditorSerializer(viewType, serializerB),
|
||||
'Should throw when registering two serializers for the same view');
|
||||
|
||||
serializerARegistration.dispose();
|
||||
|
||||
extHostWebviews.registerWebviewSerializer(viewType, serializerB);
|
||||
extHostWebviews.registerWebviewEditorSerializer(viewType, serializerB);
|
||||
|
||||
await extHostWebviews.$deserializeWebview('x', viewType, {}, EditorPosition.ONE, {});
|
||||
await extHostWebviews.$deserializeWebview('x', viewType, 'title', {}, EditorPosition.ONE, {});
|
||||
assert.strictEqual(lastInvokedDeserializer, serializerB);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue