Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions e2e/theme-flash.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { test, expect } from "./fixtures";

// issue #1497:暗色系统下页面初次加载时,JS 设置 arco-theme 前 var(--color-bg-2) 无定义,出现白屏闪烁。
// 通过 CDP 禁用脚本执行来固定"首帧"(React 挂载前)状态,验证模板内联 CSS 的暗色兜底背景。
test.describe("暗色模式首屏闪烁 (issue #1497)", () => {
// options.html / popup.html / install.html 分别对应 options、popup、template 三个 HTML 模板
for (const pageName of ["options.html", "popup.html", "install.html"]) {
test(`系统暗色模式下 ${pageName} 首帧应为暗色背景`, async ({ context, extensionId }) => {
const page = await context.newPage();
await page.emulateMedia({ colorScheme: "dark" });
const cdp = await context.newCDPSession(page);
await cdp.send("Emulation.setScriptExecutionDisabled", { value: true });
await page.goto(`chrome-extension://${extensionId}/src/${pageName}`);
const bg = await page.evaluate(() => getComputedStyle(document.body).backgroundColor);
expect(bg).toBe("rgb(35, 35, 36)");
await page.close();
});
}

test("系统亮色模式下 options.html 首帧不应为暗色背景", async ({ context, extensionId }) => {
const page = await context.newPage();
await page.emulateMedia({ colorScheme: "light" });
const cdp = await context.newCDPSession(page);
await cdp.send("Emulation.setScriptExecutionDisabled", { value: true });
await page.goto(`chrome-extension://${extensionId}/src/options.html`);
const bg = await page.evaluate(() => getComputedStyle(document.body).backgroundColor);
expect(bg).not.toBe("rgb(35, 35, 36)");
await page.close();
});
});
6 changes: 6 additions & 0 deletions src/pages/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
background-color: var(--color-bg-2);
color: var(--color-text-1);
}
/* 暗色系统下,JS 设置 arco-theme 前的兜底背景,避免白屏闪烁 (issue #1497) */
@media (prefers-color-scheme: dark) {
body:not([arco-theme]) {
background-color: #232324;
}
}
</style>
</head>
<body>
Expand Down
6 changes: 6 additions & 0 deletions src/pages/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
min-height: 150px;
max-height: 500px;
}
/* 暗色系统下,JS 设置 arco-theme 前的兜底背景,避免白屏闪烁 (issue #1497) */
@media (prefers-color-scheme: dark) {
body:not([arco-theme]) {
background-color: #232324;
}
}
</style>
</head>

Expand Down
37 changes: 37 additions & 0 deletions src/pages/store/AppContext.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { describe, it, expect, beforeAll, afterEach } from "vitest";
import { render, setupGlobalMocks } from "@Tests/test-utils";

// AppProvider 挂载时根据 localStorage.lightMode 初始化主题。
// body 上的 arco-theme 属性必须始终被显式设置(light 也不例外),
// 模板内联 CSS 依赖 body:not([arco-theme]) 识别"主题未初始化"状态来做暗色兜底(issue #1497)。
describe("AppContext 颜色主题初始化", () => {
beforeAll(() => {
setupGlobalMocks();
});

afterEach(() => {
localStorage.removeItem("lightMode");
document.body.removeAttribute("arco-theme");
document.documentElement.classList.remove("dark");
});

it("dark 模式下应在 body 上设置 arco-theme=dark", () => {
localStorage.lightMode = "dark";
render(<div />);
expect(document.body.getAttribute("arco-theme")).toBe("dark");
expect(document.documentElement.classList.contains("dark")).toBe(true);
});

it("light 模式下应在 body 上显式设置 arco-theme=light,以区分主题未初始化状态", () => {
localStorage.lightMode = "light";
render(<div />);
expect(document.body.getAttribute("arco-theme")).toBe("light");
expect(document.documentElement.classList.contains("dark")).toBe(false);
});

it("auto 模式且系统为亮色时也应显式标记 arco-theme=light", () => {
localStorage.lightMode = "auto";
render(<div />);
expect(document.body.getAttribute("arco-theme")).toBe("light");
});
});
4 changes: 3 additions & 1 deletion src/pages/store/AppContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ const setAppColorTheme = (theme: "light" | "dark" | "auto") => {
break;
case "light":
document.documentElement.classList.remove("dark");
document.body.removeAttribute("arco-theme");
// 显式设置 light 而不是移除属性:模板内联 CSS 依赖 body:not([arco-theme])
// 识别"主题未初始化"状态来做暗色兜底,避免白屏闪烁 (issue #1497)
document.body.setAttribute("arco-theme", "light");
fnPlaceHolder.setEditorTheme?.("vs");
break;
}
Expand Down
6 changes: 6 additions & 0 deletions src/pages/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
background-color: var(--color-bg-2);
color: var(--color-text-1);
}
/* 暗色系统下,JS 设置 arco-theme 前的兜底背景,避免白屏闪烁 (issue #1497) */
@media (prefers-color-scheme: dark) {
body:not([arco-theme]) {
background-color: #232324;
}
}
</style>
</head>

Expand Down
Loading