squiggle/packages/vscode-ext/client/src/utils.ts
2022-06-22 01:00:43 +03:00

60 lines
1.6 KiB
TypeScript

import * as vscode from "vscode";
const getNonce = () => {
let text = "";
const possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < 32; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
export const getWebviewContent = ({
webview,
title,
script,
context,
}: {
webview: vscode.Webview;
title: string;
script: string;
context: vscode.ExtensionContext;
}) => {
const nonce = getNonce();
const styleUri = webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "media/vendor/components.css")
);
const scriptUris = [
// vendor files are copied over by `yarn run compile`
"media/vendor/react.js",
"media/vendor/react-dom.js",
"media/vendor/components.js",
script,
].map((script) =>
webview.asWebviewUri(vscode.Uri.joinPath(context.extensionUri, script))
);
return `
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- Use a content security policy to only allow scripts that have a specific nonce. -->
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-${nonce}' 'unsafe-eval';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleUri}" rel="stylesheet" />
<title>${title}</title>
</head>
<body style="background-color: white; color: black; padding: 8px 12px">
<div id="root"></div>
${scriptUris
.map((uri) => `<script nonce="${nonce}" src="${uri}"></script>`)
.join("")}
</body>
</html>
`;
};