Files
WRNexusJS/packages/viewer/src/renderers/html.ts
T

29 lines
1.2 KiB
TypeScript

import { sanitizeHtml } from "../parse/html.ts";
import { elementFactory, requireFile, setButtonLabel } from "./dom.ts";
import { sandboxFrame } from "./frame.ts";
import type { ViewerMount } from "../types.ts";
export const mountHtml: ViewerMount = async ({ parent, file, source, button, signal }) => {
const text = await requireFile(file).text();
if (signal.aborted) return;
const view = parent.ownerDocument.defaultView;
if (!view) throw new Error("HTML preview requires a document");
const frame = sandboxFrame(parent, {
title: source.name || "HTML preview",
policy:
"default-src 'none'; base-uri 'none'; form-action 'none'; style-src 'unsafe-inline'; img-src data:",
body: sanitizeHtml(text, view),
css: "body{padding:1rem;box-sizing:border-box;font:16px/1.5 system-ui}img{max-width:100%}",
});
const raw = elementFactory(parent.ownerDocument)("pre", text);
let sourceView = false;
const toggle = button("Source", () => {
sourceView = !sourceView;
setButtonLabel(toggle, sourceView ? "Preview" : "Source");
toggle.setAttribute("aria-pressed", String(sourceView));
parent.replaceChildren(sourceView ? raw : frame);
});
toggle.setAttribute("aria-pressed", "false");
parent.append(frame);
};