Skip to content

Commit a7f101c

Browse files
committed
(GH-422) Move from previewHTML to WebView API
Previously the Node Graph Feature use the previewHTML API within VSCode, however this being actively deprecated by the VSCode team. This commit wires up the static Node Graph Preview to call the Language Server and request the DOT text of the compiled manifest. A difference in the new API is the HTML must be a full HTML document. The older API expected a partial document.
1 parent 25239e4 commit a7f101c

File tree

1 file changed

+71
-7
lines changed

1 file changed

+71
-7
lines changed

src/feature/NodeGraphFeature.ts

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import * as path from 'path';
66
import { IFeature } from "../feature";
77
import { ILogger } from "../logging";
88
import { IConnectionManager } from '../connection';
9+
import { ConnectionStatus } from '../interfaces';
10+
import { CompileNodeGraphRequest } from '../messages';
11+
import { reporter } from '../telemetry/telemetry';
12+
import * as viz from 'viz.js';
913

1014
const PuppetNodeGraphToTheSideCommandId: string = 'extension.puppetShowNodeGraphToSide';
1115

@@ -14,6 +18,7 @@ class NodeGraphWebViewProvider implements vscode.Disposable {
1418
private docUri: vscode.Uri = undefined;
1519
private webPanel: vscode.WebviewPanel = undefined;
1620
private parentFeature: NodeGraphFeature = undefined;
21+
private shownLanguageServerNotAvailable = false;
1722

1823
constructor(
1924
documentUri:vscode.Uri,
@@ -35,22 +40,81 @@ class NodeGraphWebViewProvider implements vscode.Disposable {
3540
'nodeGraph', // Identifies the type of the webview. Used internally
3641
`Node Graph '${path.basename(this.docUri.fsPath)}'`, // Title of the panel displayed to the user
3742
vscode.ViewColumn.Beside, // Editor column to show the new webview panel in.
38-
{ }
43+
{ enableScripts: true }
3944
);
4045

4146
this.webPanel.onDidDispose( () => {
4247
this.parentFeature.onProviderWebPanelDisposed(this);
4348
});
4449

45-
this.update();
50+
this.updateAsync();
4651
}
4752

48-
public update(): void {
49-
this.webPanel.webview.html = this.getHTMLContent();
53+
public async updateAsync(): Promise<void> {
54+
this.webPanel.webview.html = await this.getHTMLContent();
5055
}
5156

52-
public getHTMLContent(): string {
53-
return '<html><body>Node Graph Preview - ' + (new Date().toUTCString()) + '</body></html>';
57+
public async getHTMLContent(): Promise<string> {
58+
if ((this.connectionManager.status !== ConnectionStatus.RunningLoaded) && (this.connectionManager.status !== ConnectionStatus.RunningLoading)) {
59+
if (this.shownLanguageServerNotAvailable) {
60+
vscode.window.showInformationMessage("The Puppet Node Graph Preview is not available as the Editor Service is not ready");
61+
this.shownLanguageServerNotAvailable = true;
62+
}
63+
return "The Puppet Node Graph Preview is not available as the Editor Service is not ready";
64+
}
65+
66+
// Use the language server to render the document
67+
const requestData = {
68+
external: this.docUri.toString()
69+
};
70+
return this.connectionManager.languageClient
71+
.sendRequest(CompileNodeGraphRequest.type, requestData)
72+
.then(
73+
(compileResult) => {
74+
75+
var svgContent = '';
76+
if (compileResult.dotContent !== null) {
77+
var styling = `
78+
bgcolor = "transparent"
79+
color = "white"
80+
rankdir = "TB"
81+
node [ shape="box" penwidth="2" color="#e0e0e0" style="rounded,filled" fontname="Courier New" fillcolor=black, fontcolor="white"]
82+
edge [ style="bold" color="#f0f0f0" penwith="2" ]
83+
84+
label = ""`;
85+
86+
var graphContent = compileResult.dotContent;
87+
if (graphContent === undefined) { graphContent = ''; }
88+
// vis.jz sees backslashes as escape characters, however they are not in the DOT language. Instead
89+
// we should escape any backslash coming from a valid DOT file in preparation to be rendered
90+
graphContent = graphContent.replace(/\\/g,"\\\\");
91+
graphContent = graphContent.replace(`label = "editorservices"`,styling);
92+
93+
svgContent = viz(graphContent,"svg");
94+
}
95+
96+
var errorContent = `<div style='font-size: 1.5em'>${compileResult.error}</div>`;
97+
if ((compileResult.error === undefined) || (compileResult.error === null)) { errorContent = ''; }
98+
99+
if (reporter) {
100+
reporter.sendTelemetryEvent(PuppetNodeGraphToTheSideCommandId);
101+
}
102+
103+
const html: string = `<!DOCTYPE html>
104+
<html lang="en">
105+
<head>
106+
<meta charset="UTF-8">
107+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
108+
</head>
109+
<body>
110+
${errorContent}
111+
<div id="graphviz_svg_div">
112+
${svgContent}
113+
</div>
114+
</body></html>`;
115+
116+
return html;
117+
});
54118
}
55119

56120
public dispose(): any {
@@ -100,7 +164,7 @@ export class NodeGraphFeature implements IFeature {
100164
// Subscribe to save events and fire updates
101165
context.subscriptions.push(vscode.workspace.onDidSaveTextDocument(document => {
102166
this.providers.forEach( (item) => {
103-
if (item.isSameUri(document.uri)) { item.update(); }
167+
if (item.isSameUri(document.uri)) { item.updateAsync(); }
104168
});
105169
}));
106170
logger.debug("Registered onDidSaveTextDocument for node graph event handler");

0 commit comments

Comments
 (0)