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());
}
}