@@ -20,7 +20,6 @@ export class DocumaticPreviewPanel {
20
20
private static readonly viewType = "isc-documatic-preview" ;
21
21
22
22
private readonly _panel : vscode . WebviewPanel ;
23
- private readonly _webviewFolderUri : vscode . Uri ;
24
23
private _disposables : vscode . Disposable [ ] = [ ] ;
25
24
26
25
/** The `TextEditor` of the class document that we're previewing documentation for. */
@@ -89,7 +88,6 @@ export class DocumaticPreviewPanel {
89
88
90
89
private constructor ( panel : vscode . WebviewPanel , webviewFolderUri : vscode . Uri , editor : vscode . TextEditor ) {
91
90
this . _panel = panel ;
92
- this . _webviewFolderUri = webviewFolderUri ;
93
91
this . _editor = editor ;
94
92
95
93
// Update the panel's icon
@@ -99,7 +97,7 @@ export class DocumaticPreviewPanel {
99
97
} ;
100
98
101
99
// Set the webview's initial content
102
- this . setWebviewHtml ( ) ;
100
+ this . setWebviewHtml ( webviewFolderUri ) ;
103
101
104
102
// Register handlers
105
103
this . registerEventHandlers ( ) ;
@@ -119,47 +117,92 @@ export class DocumaticPreviewPanel {
119
117
/**
120
118
* Set the static html for the webview.
121
119
*/
122
- private setWebviewHtml ( ) {
123
- const webview = this . _panel . webview ;
124
-
125
- // Local path to script and css for the webview
126
- const scriptUri = webview . asWebviewUri ( vscode . Uri . joinPath ( this . _webviewFolderUri , "documaticPreview.js" ) ) ;
127
- const styleUri = webview . asWebviewUri ( vscode . Uri . joinPath ( this . _webviewFolderUri , "documaticPreview.css" ) ) ;
128
-
129
- // Use a nonce to whitelist which scripts can be run
130
- const nonce = ( function ( ) {
131
- let text = "" ;
132
- const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ;
133
- for ( let i = 0 ; i < 32 ; i ++ ) {
134
- text += possible . charAt ( Math . floor ( Math . random ( ) * possible . length ) ) ;
135
- }
136
- return text ;
137
- } ) ( ) ;
120
+ private setWebviewHtml ( webviewFolderUri : vscode . Uri ) {
121
+ // Get the path to the @vscode /webview-ui-toolkit minimized js
122
+ const toolkitUri = this . _panel . webview . asWebviewUri ( vscode . Uri . joinPath ( webviewFolderUri , "toolkit-1.2.1.min.js" ) ) ;
138
123
139
124
// Set the webview's html
140
125
this . _panel . webview . html = `
141
126
<!DOCTYPE html>
142
127
<html lang="en-us">
143
128
<head>
144
129
<meta charset="UTF-8">
145
-
146
- <!--
147
- Use a content security policy to only allow loading images from https or from our extension directory,
148
- and only allow scripts that have a specific nonce.
149
- -->
150
- <meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src ${ webview . cspSource } ; style-src ${ webview . cspSource } ; script-src 'nonce-${ nonce } ';">
151
-
152
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
153
-
154
- <link href="${ styleUri } " rel="stylesheet">
130
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
131
+ <script type="module" src="${ toolkitUri } "></script>
155
132
</head>
156
133
<body>
157
- <br>
158
- <h2 id="header"></h2>
159
- <br>
134
+ <h1 id="header"></h1>
135
+ <vscode-divider></vscode-divider>
160
136
<div id="showText"></div>
161
-
162
- <script nonce="${ nonce } " src="${ scriptUri } "></script>
137
+ <script>
138
+ const vscode = acquireVsCodeApi();
139
+ const header = document.getElementById("header");
140
+ const showText = document.getElementById("showText");
141
+ const memberregex = new RegExp(
142
+ "(?:<method>([^<>/]*)</method>)|(?:<property>([^<>/]*)</property>)|(?:<query>([^<>/]*)</query>)",
143
+ "gi"
144
+ );
145
+ let classUri;
146
+
147
+ // Handle messages sent from the extension to the webview
148
+ window.addEventListener("message", (event) => {
149
+ const message = event.data; // The json data that the extension sent
150
+
151
+ // Update the header to reflect what we're previewing
152
+ header.innerText = message.element;
153
+
154
+ // Update the uri of the class that we're previewing
155
+ classUri = message.uri;
156
+
157
+ // Modify the Documatic HTML for previewing and show it
158
+ let modifiedDesc = message.desc;
159
+ let matcharr;
160
+ while ((matcharr = memberregex.exec(message.desc)) !== null) {
161
+ let commandArgs = [classUri];
162
+ if (matcharr[1] !== undefined) {
163
+ // This is a <METHOD> HTML tag
164
+ commandArgs[1] = "method";
165
+ commandArgs[2] = matcharr[1];
166
+ } else if (matcharr[2] !== undefined) {
167
+ // This is a <PROPERTY> HTML tag
168
+ commandArgs[1] = "property";
169
+ commandArgs[2] = matcharr[2];
170
+ } else {
171
+ // This is a <QUERY> HTML tag
172
+ commandArgs[1] = "query";
173
+ commandArgs[2] = matcharr[3];
174
+ }
175
+ const href = "command:intersystems.language-server.showSymbolInClass?" + encodeURIComponent(JSON.stringify(commandArgs));
176
+ const title = "Go to this " + commandArgs[1] + " definition";
177
+ modifiedDesc = modifiedDesc.replace(matcharr[0], '<a href="' + href + '" title="' + title + '">' + commandArgs[2] + '</a>');
178
+ }
179
+ showText.innerHTML = modifiedDesc
180
+ .replace(/<class>|<parameter>/gi, "<b><i>")
181
+ .replace(/<\\/class>|<\\/parameter>/gi, "</i></b>")
182
+ .replace(/<pre>/gi, "<code><pre>")
183
+ .replace(/<\\/pre>/gi, "</pre></code>")
184
+ .replace(/<example(?: +language *= *"?[a-z]+"?)? *>/gi, "<br/><code><pre>")
185
+ .replace(/<\\/example>/gi, "</pre></code>");
186
+
187
+ // Then persist state information.
188
+ // This state is returned in the call to vscode.getState below when a webview is reloaded.
189
+ vscode.setState({
190
+ header: header.innerText,
191
+ showText: showText.innerHTML,
192
+ uri: classUri,
193
+ });
194
+ });
195
+
196
+ // Webviews are normally torn down when not visible and re-created when they become visible again.
197
+ // State lets us save information across these re-loads
198
+ const state = vscode.getState();
199
+ if (state) {
200
+ // Fill in webview from the cache
201
+ header.innerText = state.header;
202
+ showText.innerHTML = state.showText;
203
+ classUri = state.uri;
204
+ }
205
+ </script>
163
206
</body>
164
207
</html>` ;
165
208
}
0 commit comments