Skip to content
Snippets Groups Projects
Select Git revision
  • 952c7dcc76c586a41b6de058732fb9a223ddeb5f
  • main default protected
  • wip-injection
3 results

Application.kt

Blame
  • webviewBase.ts 3.42 KiB
    'use strict';
    import {
    	commands,
    	Disposable,
    	Uri,
    	ViewColumn,
    	Webview,
    	WebviewPanel,
    	WebviewPanelOnDidChangeViewStateEvent,
    	window,
    } from 'vscode';
    import { Command } from '../theia/command';
    
    const emptyCommands: Disposable[] = [
    	{
    		dispose: function () {
    			/* noop */
    		},
    	},
    ];
    
    export function getUri(webview: Webview, extensionUri: Uri, pathList: string[]) {
    	return webview.asWebviewUri(Uri.joinPath(extensionUri, ...pathList));
    }
    
    export abstract class WebviewBase implements Disposable {
    	protected disposable: Disposable;
    	private _disposablePanel: Disposable | undefined;
    	protected _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();
    	}
    
    	getExternalRessourcePath(extensionUri: Uri, pathList: string[]) {
    		return getUri(this._panel!.webview, extensionUri, pathList);
    	}
    
    	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);
    		}
    	}
    
    	async reload() {
    		if (this._panel) {
    			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;
    		}
    	}
    
    	/**
    	 * 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();
    	}
    }