140 lines
4.0 KiB
TypeScript
140 lines
4.0 KiB
TypeScript
import { window, ViewColumn, WebviewPanel } from "vscode";
|
|
import { WebviewServer } from "./WebviewServer";
|
|
import { Disposable } from "@hediet/std/disposable";
|
|
import { WindowWithWebviewData } from "../webviewContract";
|
|
import { Config } from "../Config";
|
|
|
|
export const debugVisualizer = "debugVisualizer";
|
|
|
|
export class InternalWebviewManager {
|
|
private readonly openedWebviews = new Map<
|
|
WebviewPanel,
|
|
DebugVisualizerWebview
|
|
>();
|
|
|
|
public readonly dispose = Disposable.fn();
|
|
|
|
constructor(
|
|
private readonly server: WebviewServer,
|
|
private readonly config: Config
|
|
) {
|
|
this.dispose.track(
|
|
window.registerWebviewPanelSerializer(debugVisualizer, {
|
|
deserializeWebviewPanel: async (panel, state) => {
|
|
this.restore(panel);
|
|
},
|
|
})
|
|
);
|
|
|
|
this.dispose.track({
|
|
dispose: () => {
|
|
for (const panel of this.openedWebviews.keys()) {
|
|
panel.dispose();
|
|
}
|
|
},
|
|
});
|
|
}
|
|
|
|
public createNew(expression: string | undefined = undefined) {
|
|
const webviewPanel = window.createWebviewPanel(
|
|
debugVisualizer,
|
|
"Debug Visualizer",
|
|
ViewColumn.Two,
|
|
{
|
|
enableScripts: true,
|
|
retainContextWhenHidden: true,
|
|
portMapping: [
|
|
{
|
|
webviewPort: this.server.port,
|
|
extensionHostPort: this.server.port,
|
|
},
|
|
],
|
|
}
|
|
);
|
|
|
|
this.initializeView(webviewPanel, expression);
|
|
}
|
|
|
|
private restore(webviewPanel: WebviewPanel) {
|
|
this.initializeView(webviewPanel);
|
|
}
|
|
|
|
private initializeView(
|
|
webviewPanel: WebviewPanel,
|
|
expression: string | undefined = undefined
|
|
) {
|
|
webviewPanel.webview.html = getDebugVisualizerWebviewHtml(
|
|
this.server,
|
|
expression,
|
|
this.config
|
|
);
|
|
const view = new DebugVisualizerWebview(webviewPanel);
|
|
this.openedWebviews.set(webviewPanel, view);
|
|
webviewPanel.onDidDispose(() => {
|
|
this.openedWebviews.delete(webviewPanel);
|
|
});
|
|
}
|
|
}
|
|
|
|
export class DebugVisualizerWebview {
|
|
constructor(private readonly webviewPanel: WebviewPanel) {}
|
|
}
|
|
|
|
function getDebugVisualizerWebviewHtml(
|
|
server: WebviewServer,
|
|
initialExpression: string | undefined = undefined,
|
|
config: Config
|
|
) {
|
|
const isDev = !!process.env.USE_DEV_UI;
|
|
return `
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval'; connect-src * 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src *; style-src * 'unsafe-inline'; worker-src * data: blob: data: 'unsafe-inline' 'unsafe-eval'; font-src * 'unsafe-inline' 'unsafe-eval' 'self' data: blob:;">
|
|
<style>
|
|
html { height: 100%; width: 100%; padding: 0; margin: 0; }
|
|
body { height: 100%; width: 100%; padding: 0; margin: 0; }
|
|
iframe { height: 100%; width: 100%; padding: 0; margin: 0; border: 0; display: block; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
Object.assign(window, ${JSON.stringify({
|
|
webviewData: {
|
|
serverSecret: server.secret,
|
|
serverPort: server.port,
|
|
publicPath: server.publicPath,
|
|
expression: initialExpression,
|
|
theme: config.theme,
|
|
},
|
|
} as WindowWithWebviewData)});
|
|
const api = window.VsCodeApi = acquireVsCodeApi();
|
|
window.addEventListener('message', event => {
|
|
if (event.source === window.frames[0]) {
|
|
if (event.data.command === "setState") {
|
|
// console.log("setState", event.data.state);
|
|
api.setState(event.data.state);
|
|
}
|
|
if (event.data.command === "getState") {
|
|
// console.log("getState, sent ", api.getState());
|
|
window.frames[0].postMessage({ command: "getStateResult", state: api.getState() }, "*");
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
|
|
${
|
|
isDev
|
|
? `<iframe sandbox="allow-top-navigation allow-scripts allow-same-origin allow-popups allow-pointer-lock allow-forms" src="${server.getWebviewPageUrl(
|
|
{
|
|
mode: "webviewIFrame",
|
|
expression: initialExpression,
|
|
}
|
|
)}"></iframe>`
|
|
: `<script type="text/javascript" src="${server.webviewBundleUrl}"></script>`
|
|
}
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|