Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 6x 6x 121x 121x 3872x 121x 31x 31x 11x 10x 5x 3x | const NONCE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const NONCE_LENGTH = 32;
export function getNonce(): string {
let text = '';
for (let i = 0; i < NONCE_LENGTH; i++) {
text += NONCE_CHARS.charAt(Math.floor(Math.random() * NONCE_CHARS.length));
}
return text;
}
export interface HtmlTemplateParams {
cspSource: string;
nonce: string;
scriptUri: string;
cssUri: string;
}
export function buildPreviewHtml(params: HtmlTemplateParams): string {
const { cspSource, nonce, scriptUri, cssUri } = params;
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="
default-src 'none';
img-src ${cspSource} https: data: blob:;
media-src ${cspSource} https: blob:;
script-src ${cspSource} 'nonce-${nonce}' 'unsafe-eval';
style-src ${cspSource} 'unsafe-inline';
font-src ${cspSource} https: data:;
">
<link rel="stylesheet" href="${cssUri}">
<title>Markdown Preview</title>
</head>
<body>
<div id="root"></div>
<script nonce="${nonce}" type="module" src="${scriptUri}"></script>
</body>
</html>`;
}
export function resolveImageSrc(src: string, baseUri: string): string {
if (!src) return src;
if (src.startsWith('http') || src.startsWith('data:')) return src;
if (!baseUri) return src;
return `${baseUri}/${src}`;
}
|