perf(webui): keep settings-only appearance defaults out of startup

This commit is contained in:
2026-09-08 01:41:04 +02:00
parent b75ca34295
commit 32c70a4657
6 changed files with 52 additions and 31 deletions
+16 -3
View File
@@ -12,6 +12,7 @@ const settings = readFileSync(resolve(webuiRoot, "src/features/settings/Settings
const paletteControl = readFileSync(resolve(webuiRoot, "src/components/AppearancePaletteControl.tsx"), "utf8");
const overridesEditor = readFileSync(resolve(webuiRoot, "src/components/AppearanceOverridesEditor.tsx"), "utf8");
const overridesRuntime = readFileSync(resolve(webuiRoot, "src/components/appearanceOverrides.ts"), "utf8");
const overridesDefaults = readFileSync(resolve(webuiRoot, "src/components/appearanceOverrideDefaults.ts"), "utf8");
assert.match(tokens, /:root\[data-theme="dark"\]/, "dark token overrides are required");
assert.match(tokens, /color-scheme:\s*dark/, "native controls must receive the dark color scheme");
@@ -30,14 +31,24 @@ assert.match(app, /applyAppearanceOverrides/, "the shell must apply validated ov
assert.match(app, /import \{ applyAppearanceOverrides \} from "\.\/components\/appearanceOverrides"/, "startup applies themes synchronously without importing settings editor controls");
assert.doesNotMatch(overridesRuntime, /import .*from ["']react["']|\.tsx|ColorPickerField|ContentGrid/, "the startup theme runtime must stay independent of editor UI");
assert.match(overridesEditor, /from "\.\/appearanceOverrides"/, "editor and runtime share the same validation implementation");
assert.match(overridesRuntime, /schema_version:\s*"1"/, "override exchange must use an explicit versioned schema");
assert.match(overridesEditor, /from "\.\/appearanceOverrideDefaults"/, "settings owns the unchanged default document");
assert.doesNotMatch(overridesRuntime, /appearanceOverrideDefaults|DEFAULT_APPEARANCE_OVERRIDES|cloneDefaultAppearanceOverrides/, "startup must not import settings-only default documents");
assert.match(overridesDefaults, /schema_version:\s*"1"/, "override exchange must use an explicit versioned schema");
assert.match(overridesRuntime, /contrastRatio[\s\S]*?<\s*4\.5/, "custom pairs must enforce WCAG AA contrast");
assert.match(overridesRuntime, /rgbDistance[\s\S]*?<\s*12/, "custom status colors must enforce differentiation");
const runtimeExports = {};
const defaultsExports = {};
vm.runInNewContext(ts.transpileModule(overridesRuntime, {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 }
}).outputText, { exports: runtimeExports });
const validOverrides = runtimeExports.cloneDefaultAppearanceOverrides();
vm.runInNewContext(ts.transpileModule(overridesDefaults, {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 }
}).outputText, { exports: defaultsExports });
const validOverrides = defaultsExports.cloneDefaultAppearanceOverrides();
assert.deepEqual(validOverrides, defaultsExports.DEFAULT_APPEARANCE_OVERRIDES);
assert.notEqual(validOverrides, defaultsExports.DEFAULT_APPEARANCE_OVERRIDES);
assert.notEqual(validOverrides.light, defaultsExports.DEFAULT_APPEARANCE_OVERRIDES.light);
assert.notEqual(validOverrides.dark, defaultsExports.DEFAULT_APPEARANCE_OVERRIDES.dark);
assert.equal(runtimeExports.validateAppearanceOverrides(validOverrides), validOverrides);
const colorProperties = new Map();
const root = { style: {
@@ -49,8 +60,10 @@ assert.equal(colorProperties.get("--accent"), validOverrides.dark.accent);
assert.equal(colorProperties.get("--danger-text"), validOverrides.dark.danger_foreground);
runtimeExports.applyAppearanceOverrides(root, validOverrides, "light");
assert.equal(colorProperties.get("--accent"), validOverrides.light.accent);
const invalidOverrides = runtimeExports.cloneDefaultAppearanceOverrides();
const invalidOverrides = defaultsExports.cloneDefaultAppearanceOverrides();
invalidOverrides.light.accent_foreground = invalidOverrides.light.accent;
assert.equal(defaultsExports.DEFAULT_APPEARANCE_OVERRIDES.light.accent_foreground, "#ffffff", "draft edits must not mutate shared defaults");
assert.equal(validOverrides.light.accent_foreground, "#ffffff", "independent override drafts must not share nested modes");
assert.throws(() => runtimeExports.validateAppearanceOverrides(invalidOverrides));
runtimeExports.applyAppearanceOverrides(root, invalidOverrides, "dark");
assert.equal(colorProperties.size, 0, "invalid documents clear previous custom tokens and never partially apply");