@@ -6,6 +6,10 @@ import * as path from 'path';
66import { IFeature } from "../feature" ;
77import { ILogger } from "../logging" ;
88import { 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
1014const 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