import * as vscode from 'vscode'; import * as path from 'path'; const importsScript : string = " \n\ \n\ \n\ "; const htmlScript : string = " \n\ \n\ " export interface IEditorWebApp { onMessage: vscode.Event; SendMessage(message : EditorMessage): Promise; } export class EditorMessage { constructor( readonly type: string, readonly subType: string | undefined, readonly value: any | undefined ) {} public serialize() : any { return { type: this.type, sub_type: this.subType, value: this.value } } static deserialize(m : any) : EditorMessage { return new EditorMessage(m.type, m.sub_type, m.value); } } export class EditorWebApp implements IEditorWebApp{ private static panels: [string, vscode.WebviewPanel][] = []; private panel : vscode.WebviewPanel; public readonly onDidChangeEmitter = new vscode.EventEmitter(); public get onMessage(): vscode.Event { return this.onDidChangeEmitter.event; } constructor(extensionFolder: vscode.Uri ,appFolder: vscode.Uri, indexHtml: string, name: string, displayName: string){ const columnToShowIn : vscode.ViewColumn = vscode.window.activeTextEditor?.viewColumn || 0; let currentPanel : [string, vscode.WebviewPanel] | undefined = EditorWebApp.panels.find( (e : [string, vscode.WebviewPanel]) => e[0]==name ); if (currentPanel) { // # Already exist panel with web app currentPanel[1].reveal(columnToShowIn); } else { // # Doesn't exist panel with web app currentPanel = [ name, vscode.window.createWebviewPanel(name, displayName, columnToShowIn, { retainContextWhenHidden: true, enableScripts: true, localResourceRoots: [ extensionFolder,appFolder ] }) ]; const referencedIndexHtml = indexHtml .replace(/{context}/g, currentPanel[1].webview.asWebviewUri(appFolder).toString()) .replace(//g,""+importsScript) .replace(/{toolkit}/g, currentPanel[1].webview.asWebviewUri(vscode.Uri.joinPath(extensionFolder, ...["node_modules", "@vscode", "webview-ui-toolkit", "dist", "toolkit.js"])).toString()) .replace(/{codicons}/g, currentPanel[1].webview.asWebviewUri(vscode.Uri.joinPath(extensionFolder, ...["node_modules", "@vscode", "codicons", "dist", "codicon.css"])).toString()) .replace(//g,""+htmlScript); currentPanel[1].webview.html = referencedIndexHtml; EditorWebApp.panels.push(currentPanel); // # Reset when the current panel is closed currentPanel[1].onDidDispose(() => EditorWebApp.panels = EditorWebApp.panels.filter((e : [string, vscode.WebviewPanel]) => e[0]!=name)); currentPanel[1].webview.onDidReceiveMessage((m: any) => this.onDidChangeEmitter.fire(EditorMessage.deserialize(m))); } this.panel = currentPanel[1]; } public async SendMessage(message: EditorMessage): Promise { await this.panel.webview.postMessage(message.serialize()); } }