(serverUrl)
| 233 | } |
| 234 | |
| 235 | function getWebviewHtml(serverUrl) { |
| 236 | const origin = getOrigin(serverUrl); |
| 237 | const escapedUrl = escapeHtml(serverUrl); |
| 238 | const escapedOrigin = escapeHtml(origin); |
| 239 | const nonce = createNonce(); |
| 240 | const serializedOrigin = JSON.stringify(origin); |
| 241 | |
| 242 | return `<!DOCTYPE html> |
| 243 | <html lang="en"> |
| 244 | <head> |
| 245 | <meta charset="UTF-8" /> |
| 246 | <meta |
| 247 | http-equiv="Content-Security-Policy" |
| 248 | content="default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${nonce}'; frame-src ${escapedOrigin};" |
| 249 | /> |
| 250 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 251 | <style> |
| 252 | html, |
| 253 | body { |
| 254 | margin: 0; |
| 255 | padding: 0; |
| 256 | width: 100%; |
| 257 | height: 100%; |
| 258 | overflow: hidden; |
| 259 | background: #000; |
| 260 | } |
| 261 | |
| 262 | iframe { |
| 263 | position: fixed; |
| 264 | inset: 0; |
| 265 | width: 100vw; |
| 266 | height: 100vh; |
| 267 | border: 0; |
| 268 | background: #000; |
| 269 | } |
| 270 | </style> |
| 271 | </head> |
| 272 | <body> |
| 273 | <iframe src="${escapedUrl}" title="SimDeck Simulator"></iframe> |
| 274 | <script nonce="${nonce}"> |
| 275 | const vscode = acquireVsCodeApi(); |
| 276 | const simdeckOrigin = ${serializedOrigin}; |
| 277 | window.addEventListener("message", (event) => { |
| 278 | if (event.origin !== simdeckOrigin) { |
| 279 | return; |
| 280 | } |
| 281 | if (event.data?.type === "simdeck.openSource") { |
| 282 | vscode.postMessage(event.data); |
| 283 | } |
| 284 | }); |
| 285 | </script> |
| 286 | </body> |
| 287 | </html>`; |
| 288 | } |
| 289 | |
| 290 | function createNonce() { |
| 291 | const alphabet = |
no test coverage detected