Fix abnormal preview of HTML files (#1986)

* Fix HTML artifact preview rendering

* Add after screenshot for HTML preview fix

* Add before screenshot for HTML preview fix

* Update before screenshot for HTML preview fix

* Update after screenshot for HTML preview fix

* Update before screenshot to Tsinghua homepage repro

* Update after screenshot to Tsinghua homepage preview

* Address PR review on HTML artifact preview

* Harden HTML artifact preview isolation
This commit is contained in:
Admire 2026-04-09 16:32:01 +08:00 committed by GitHub
parent 52718b0f23
commit 140907ce1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 10 deletions

View File

@ -83,7 +83,7 @@ export function ArtifactFileDetail({
const isSupportPreview = useMemo(() => {
return language === "html" || language === "markdown";
}, [language]);
const { content, url } = useArtifactContent({
const { content } = useArtifactContent({
threadId,
filepath: filepathFromProps,
enabled: isCodeFile && !isWriteFile,
@ -194,7 +194,7 @@ export function ArtifactFileDetail({
tooltip={t.common.openInNewWindow}
onClick={() => {
const w = window.open(
urlOfArtifact({ filepath, threadId }),
urlOfArtifact({ filepath, threadId, isMock }),
"_blank",
"noopener,noreferrer",
);
@ -226,7 +226,12 @@ export function ArtifactFileDetail({
tooltip={t.common.download}
onClick={() => {
const w = window.open(
urlOfArtifact({ filepath, threadId, download: true }),
urlOfArtifact({
filepath,
threadId,
download: true,
isMock,
}),
"_blank",
"noopener,noreferrer",
);
@ -249,9 +254,7 @@ export function ArtifactFileDetail({
(language === "markdown" || language === "html") && (
<ArtifactFilePreview
content={displayContent}
isWriteFile={isWriteFile}
language={language ?? "text"}
url={url}
/>
)}
{isCodeFile && viewMode === "code" && (
@ -274,15 +277,28 @@ export function ArtifactFileDetail({
export function ArtifactFilePreview({
content,
isWriteFile,
language,
url,
}: {
content: string;
isWriteFile: boolean;
language: string;
url?: string;
}) {
const [htmlPreviewUrl, setHtmlPreviewUrl] = useState<string>();
useEffect(() => {
if (language !== "html") {
setHtmlPreviewUrl(undefined);
return;
}
const blob = new Blob([content ?? ""], { type: "text/html" });
const url = URL.createObjectURL(blob);
setHtmlPreviewUrl(url);
return () => {
URL.revokeObjectURL(url);
};
}, [content, language]);
if (language === "markdown") {
return (
<div className="size-full px-4">
@ -302,7 +318,7 @@ export function ArtifactFilePreview({
className="size-full"
title="Artifact preview"
sandbox="allow-scripts allow-forms"
{...(isWriteFile ? { srcDoc: content } : url ? { src: url } : {})}
src={htmlPreviewUrl}
/>
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 KiB