Select Git revision
webviewBase.ts
webviewBase.ts 3.11 KiB
"use strict";
import {
commands,
Disposable,
ViewColumn,
Webview,
WebviewPanel,
WebviewPanelOnDidChangeViewStateEvent,
window,
} from "vscode";
import { Command } from "../theia/command";
const emptyCommands: Disposable[] = [
{
dispose: function () {
/* noop */
},
},
];
export abstract class WebviewBase implements Disposable {
protected disposable: Disposable;
private _disposablePanel: Disposable | undefined;
private _panel: WebviewPanel | undefined;
constructor(private id: string, private title:string, command: Command, private readonly _column?: ViewColumn) {
this.disposable = Disposable.from(
commands.registerCommand(command.cmd, this.onShowCommand, this)
);
this.load();
}
registerCommands(): Disposable[] {
return emptyCommands;
}
renderHead?(): string | Promise<string>;
renderBody?(): string | Promise<string>;
renderEndOfBody?(): string | Promise<string>;
dispose() {
this.disposable.dispose();
this._disposablePanel?.dispose();
}
protected onShowCommand() {
void this.show(this._column);
}
private onPanelDisposed() {
this._disposablePanel?.dispose();
this._panel = undefined;
}
private onViewStateChanged(e: WebviewPanelOnDidChangeViewStateEvent) {
console.log(
`Webview(${this.id}).onViewStateChanged`,
`active=${e.webviewPanel.active}, visible=${e.webviewPanel.visible}`
);
}
get visible() {
return this._panel?.visible ?? false;
}
hide() {
this._panel?.dispose();
}
setTitle(title: string) {
if (this._panel == null) return;
this._panel.title = title;
}
onMessageReceive(message) {
switch (message.command) {
case "alert":
window.showErrorMessage(message.text);
return;
}
}
async show(column: ViewColumn = ViewColumn.Beside): Promise<void> {
if (this._panel == null) {
this._panel = window.createWebviewPanel(
this.id,
this.title,
{ viewColumn: column, preserveFocus: false },
{
retainContextWhenHidden: true,
enableFindWidget: true,
enableCommandUris: true,
enableScripts: true,
}
);
this._disposablePanel = Disposable.from(
this._panel,
this._panel.onDidDispose(this.onPanelDisposed, this),
this._panel.onDidChangeViewState(this.onViewStateChanged, this),
this._panel.webview.onDidReceiveMessage(this.onMessageReceive, this),
...this.registerCommands()
);
this._panel.webview.html = await this.getHtml(this._panel.webview);
} else {
const html = await this.getHtml(this._panel.webview);
// Reset the html to get the webview to reload
this._panel.webview.html = "";
this._panel.webview.html = html;
this._panel.reveal(this._panel.viewColumn ?? ViewColumn.Active, false);
}
}
/**
* Must return the content displayed within the webViewPanel
*/
abstract render(): string;
/**
* Method called at the end of first render
*/
abstract load(): void;
private async getHtml(webview: Webview): Promise<string> {
return this.render();
}
}