-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathWebViewProvider.ts
91 lines (80 loc) · 2.63 KB
/
WebViewProvider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import * as vscode from 'vscode'
import { getNonce } from './utils/utils'
import { getUIStorage } from './lib'
import { handleMessage } from './utils/handleMessage'
export class WebViewProvider implements vscode.WebviewViewProvider {
_doc?: vscode.TextDocument
constructor(
private readonly _route: string,
private readonly _context: vscode.ExtensionContext,
public view?: vscode.WebviewView,
) { }
public resolveWebviewView(webviewView: vscode.WebviewView) {
this.view = webviewView
webviewView.webview.options = {
// Allow scripts in the webview
enableScripts: true,
localResourceRoots: [this._context.extensionUri],
}
// todo: connection between webviews
webviewView.webview.onDidReceiveMessage(
handleMessage,
undefined,
this._context.subscriptions,
)
webviewView.webview.html = this._getHtmlForWebview(webviewView.webview)
}
public revive(panel: vscode.WebviewView) {
this.view = panel
}
private _getHtmlForWebview(webview: vscode.Webview) {
const styleUri = webview.asWebviewUri(
vscode.Uri.joinPath(
this._context.extensionUri,
'dist',
'webviews',
'style.css',
),
)
const scriptUri = webview.asWebviewUri(
vscode.Uri.joinPath(
this._context.extensionUri,
'dist',
'webviews',
'index.mjs',
),
)
const viewRoute = this._route
const uiStorage = getUIStorage()
// Use a nonce to only allow a specific script to be run.
const nonce = getNonce()
const contentSecurity = [
`img-src ${webview.cspSource} 'self' data:`,
`style-src ${webview.cspSource} 'self' 'unsafe-inline'`,
`script-src 'self' 'nonce-${nonce}'`,
'default-src * self blob:',
'font-src self data:',
'worker-src self blob: vscode-webview:',
]
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="${styleUri}" rel="stylesheet"/>
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="${contentSecurity.join(';')}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script nonce="${nonce}">
window.ri=${JSON.stringify(uiStorage)};
</script>
</head>
<body>
<div id="root" data-route="${viewRoute}"></div>
<script nonce="${nonce}" src="${scriptUri}" type="module"></script>
</body>
</html>`
}
}