import { Box } from "@mantine/core";
import { useMemo } from "react";
import { wrapHtmlWithCsp } from "./contentViewerUtils";
import { useObjectUrl } from "./useObjectUrl";
/**
* Render an HTML resource inside a hardened iframe. Defense is layered:
*
* - `sandbox=""` — explicitly empty: no `allow-scripts`, `allow-forms`, or
* `allow-same-origin`, so scripts can't run and the frame is origin-isolated.
* - A `Content-Security-Policy` `` is injected (see {@link wrapHtmlWithCsp})
* as defense-in-depth — correct even if the sandbox is later loosened.
* - The document is served from a `Blob` object URL (revoked on unmount) rather
* than `srcdoc`, keeping it off the parent's origin.
*/
export interface HtmlFrameProps {
/** The raw HTML document or fragment to preview. */
html: string;
}
export function HtmlFrame({ html }: HtmlFrameProps) {
const blob = useMemo(
() => new Blob([wrapHtmlWithCsp(html)], { type: "text/html" }),
[html],
);
const url = useObjectUrl(blob);
return (
);
}