Files
ttstd-infinite-canvas/web/test/app-icon-neutral-bootstrap.test.ts
AetherNo2332 c09304d905 fix(web): 首屏 favicon - 不再先闪内置品牌图标 (#570)
Original-Commit: d049f7014d49e93ab0e6aa8b7e715d5155b94dc0
fix(web): 首屏 favicon - 不再先闪内置品牌图标

index.html 静态声明 /logo.svg 作 icon,而 favicon 由 use-appearance-store 在解析出外观后写入
(link[rel~="icon"] + appearanceLogoURL)。自定义品牌部署于是会先闪一下内置 logo。

换成空占位 <link rel="icon" href="data:," />:外观系统照旧覆盖它,占位只是为了不让浏览器去
请求 /favicon.ico(那是一条 404)。代价是外观接口不可用时标签页没有图标,这是有意的取舍。

新增源码级守卫用例(上游原态 1 pass/1 fail,改后 2 pass)。
2026-09-21 09:37:20 +08:00

23 lines
1.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, test } from "bun:test";
import { readFileSync } from "node:fs";
const readProjectFile = (relative: string) => readFileSync(new URL(`../${relative}`, import.meta.url), "utf8");
// 首屏必须品牌中性:静态的 /logo.svg 会让自定义品牌部署在标签页上先闪一下内置 logo,
// 而 favicon 本来就由 use-appearance-store 在解析出外观后写入。空 data URL 只是占位,
// 避免浏览器去请求 /favicon.ico(那是一条 404)。
describe("app icon bootstrap", () => {
const indexHtml = readProjectFile("index.html");
const appearanceStore = readProjectFile("src/stores/use-appearance-store.ts");
test("index.html declares a neutral placeholder icon instead of the built-in brand", () => {
expect(indexHtml).toContain('<link rel="icon" href="data:," />');
expect(indexHtml).not.toContain('<link rel="icon" href="/logo.svg"');
});
test("the appearance store remains the single writer of the favicon", () => {
expect(appearanceStore).toContain('link[rel~="icon"]');
expect(appearanceStore).toContain("favicon.href = appearanceLogoURL(");
});
});