From 0b2c08472c3e401dc1f14054b903eeefad392314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Mon, 17 Aug 2026 17:05:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20UI=20=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E5=AD=97=E4=BD=93=E5=8A=A0=E8=BD=BD=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E8=B5=84=E6=BA=90=E6=B8=85=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在失败路径释放 URL.revokeObjectURL(url)。 - 若已注册字体面,也会从 document.fonts 移除。 --- .../src/features/ui-editor/useUiEditorFontFaces.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorFontFaces.ts b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorFontFaces.ts index c3b00de6c..0696ee745 100644 --- a/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorFontFaces.ts +++ b/apps/ai-game-creator-shell/src/features/ui-editor/useUiEditorFontFaces.ts @@ -69,6 +69,8 @@ export function useUiEditorFontFaces( for (const font of fontAssets) { void (async () => { const cssFamily = uiEditorPrivateFontFamily(font.asset_id); + let url: string | undefined; + let face: FontFace | undefined; try { if (typeof FontFace === 'undefined' || !document.fonts) { throw new Error('FontFace unavailable'); @@ -80,10 +82,10 @@ export function useUiEditorFontFaces( expectedSha256: font.content_sha256, }); if (cancelled) return; - const url = URL.createObjectURL( + url = URL.createObjectURL( new Blob([new Uint8Array(bytes)], { type: fontMimeType(font) }), ); - const face = new FontFace(cssFamily, `url(${JSON.stringify(url)})`, { + face = new FontFace(cssFamily, `url(${JSON.stringify(url)})`, { style: font.metadata.italic ? 'italic' : 'normal', weight: String(font.metadata.weight), }); @@ -99,6 +101,12 @@ export function useUiEditorFontFaces( [font.asset_id]: { cssFamily, status: 'loaded' }, })); } catch { + if (face) { + document.fonts?.delete(face); + } + if (url) { + URL.revokeObjectURL(url); + } if (!cancelled) { setStates((current) => ({ ...current,