Files
MailUI4Agents/client/electron/scripts/gen-background-takeover.mjs
JianFeeeee 51522dd8c2 fix(webui): 导航令牌迁移收尾 + 生成 CSS 的头注释提前闭合(会丢规则)+ 两条过期判据重写 + 判据进 npm test
## 改法

- **`Sidebar.tsx` 底部两个按钮还是旧的深色导航假设**(`text-chrome-400
  hover:text-white hover:bg-chrome-800`、外层 `border-chrome-700`):导航改成白玻璃
  (`--nav-bg: 255 255 255 / 0.72`)之后,`chrome-400` 落在白底上约 2.6:1(图标要
  3:1),hover 还会在白导航上闪出一块近黑。账号头像那个按钮当时换成了 `.nav-item`,
  这两个漏了 —— 就是"导航令牌迁移做了一半"。已换成 `.nav-item` + `border-gray-200`。
  没加"Sidebar 里不许有 chrome-*"的判据:另有一处 `bg-chrome-600 text-chrome-100`
  是实心小色块(正常用法),一刀切会误红。

- **`background-takeover.generated.css` 的头注释提前闭合**:生成器在注释里写了
  「src」加「/」加两颗星加「/」加「.tsx」,其中那对「星号 + 斜杠」把 CSS 注释就地
  结束 —— 尾巴变成 CSS 正文,并与第一条规则的选择器连在一起成为非法选择器 ⇒
  **`.bg-amber-100` 那条接管规则被浏览器整条丢掉**(壁纸模式下不再变半透明)。
  构建只给一条 `[WARNING] Unexpected "14" [css-syntax-error]`,不报错、不影响构建,
  正是这套判据存在的理由。改在生成器(注释里只描述、不写 glob 字面量)并重新生成:
  压缩输出现在以 `html[data-bg=on] .bg-amber-100{` 起头、14 条规则全在、无告警。
  另加两条判据("头注释没提前闭合" + 自检)。

- **`background.test.mjs` 第 18 组三条重写**:原先断言「浅色/深色两套 `--nav-bg` 都
  定义」与「壁纸模式下 `.nav-rail` 里有 `backdrop-filter`」,两条编码的都是**已被
  有意撤掉的设计**(`faacd3c` 撤深色导航、`9aa702b` 撤导航自叠模糊),于是 `npm test`
  在 HEAD 上恒红。判据红成常态就不再是判据 —— 该改的是判据本身,而不是把缺陷写回代码。
  改成方向相反的两条:`.dark` 不许单独给导航换色 / 模糊只由壁纸层负责。

- **`cross-client-theme.test.mjs` 从来不在 `npm test` 链里**(vitest 只收
  `test/components` 与 `test/stores`)—— 那条"防漂移判据"从没在默认套件里跑过。
  已加进 `npm test`。

## 验证

- 变异测试:往 `.dark { }` 塞一行 `--nav-bg: 15 23 42 / 0.72;` → 红;往
  `html[data-bg='on'] .nav-rail` 塞 `backdrop-filter: blur(18px);` → 红;撤回 → 绿。
- `npm test` 退出码 0:窄屏布局全通过、主题 30、背景 34、cross-client 8、packaging 3、
  vitest 258/258;`npm run typecheck` 通过。
- packaging 第 3 条此前是红的,但**不是判据过期**:安装包真的落后于 dist,而 `npm test`
  的 `&&` 链一直在 background 那条就中断,`packaging` 从没跑到过。已 `npm run build`
  + `npx electron-builder --linux -c.electronDownload.isVerifyChecksum=false` 重打包。
  ⚠️ deb 目标在本机打不出来(fpm 的 portable ruby 在 `Dir.chdir` 处退出),
  AppImage 与 `linux-unpacked` 正常。
2026-09-14 13:29:57 +08:00

84 lines
3.8 KiB
JavaScript
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.

/**
* 生成"背景开启时哪些浅色表面类要变半透明"的 CSS。
*
* # 为什么要生成而不是手写
*
* 手写清单必然烂2026-09-13 用户报「很多界面是不透明的,导致壁纸露不出来」,
* 一查代码里在用的浅色表面类有 gray-100(24 处)、blue-50(17)、red-50(13)、
* gray-200(8)、green-50(8)… 而当时的接管清单只有 white / gray-50 / slate-100 ——
* 漏掉的那些全是实心的,正好盖住壁纸。
*
* 所以清单从**源码里实际出现的类**推导:出现什么就接管什么。新增一个
* `bg-purple-50` 而忘了同步,`test/background.test.mjs` 里那条判据会红。
*
* 只接管"表面段"50/100/200它们是面板底、提示条、卡片这类大面积浅色。
* 600/700 那一段是按钮与徽标(小控件、要读得清),**故意保持不透明** —— 见
* index.css 里 chrome-600/700 那段注释(实测可读性从 4.46:1 掉到 AA 以下)。
*/
import { readdir, readFile, writeFile } from 'node:fs/promises';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const HERE = dirname(fileURLToPath(import.meta.url));
const SRC = join(HERE, '..', 'src');
const OUT = join(SRC, 'background-takeover.generated.css');
/** 表面段:浅色大类 + 50/100/200 三档。 */
const SURFACE = /^bg-([a-z]+)-(50|100|200)$/;
/**
* 页面底:**必须完全透明**(背景开启时),不能进这份"半透明"清单。
*
* 它们铺满整屏,给它们 0.3 的不透明度等于在壁纸上盖一层白纱;而 index.css 里
* 已经把它们设成 transparent —— 谁后加载谁生效,生成物在 index.css 之后引入,
* 所以漏了这条排除就会把"完全透明"悄悄改回"半透明"。
*/
const PAGE_BASE = new Set(['bg-gray-50', 'bg-slate-100']);
async function walk(dir) {
const out = [];
for (const e of await readdir(dir, { withFileTypes: true })) {
const p = join(dir, e.name);
if (e.isDirectory()) out.push(...(await walk(p)));
else if (/\.(tsx?|jsx?)$/.test(e.name)) out.push(p);
}
return out;
}
const found = new Set();
for (const file of await walk(SRC)) {
const text = await readFile(file, 'utf8');
for (const m of text.matchAll(/bg-[a-z]+-\d{2,3}/g)) {
if (SURFACE.test(m[0]) && !PAGE_BASE.has(m[0])) found.add(m[0]);
}
}
const classes = [...found].sort();
const body = classes
.map(
(cls) =>
`html[data-bg='on'] .${cls} {\n` +
` background-color: rgb(var(--c-${cls.slice(3)}) / var(--bg-glass-inner));\n` +
` backdrop-filter: none; /* 外层已经模糊过,嵌套层再糊一次会把图案糊成灰块 */\n` +
` -webkit-backdrop-filter: none;\n}`,
)
.join('\n\n');
await writeFile(
OUT,
/*
* ★ 头注释里**不许写出「星号紧接斜杠」的 glob 字面量**2026-09-14 修)。
*
* 这里原先写的是「src」加「/」加两颗星加「/」加「.tsx」而中间那对
* 「星号 + 斜杠」会把 CSS 注释**提前闭合**:剩下的尾巴(`.tsx 的实际用法)。`
* 变成 CSS 正文,跟后面第一条规则的**选择器连在一起** —— 非法选择器 ⇒
* **那条规则被浏览器整条丢掉**`.bg-amber-100` 在壁纸模式下不再变半透明),
* 而构建只在日志里给一条 `[WARNING] Unexpected "14"`,不报错、不影响构建。
* 所以这里只描述、不写 glob 字面量。
*/
`/* 由 scripts/gen-background-takeover.mjs 生成 —— 不要手改。\n` +
` * 背景开启时把源码里在用的浅色表面类改成半透明(清单来自 src 目录下全部 .tsx 的实际用法)。\n` +
` * 共 ${classes.length} 个类:${classes.join(', ')}\n */\n\n${body}\n`,
);
console.log(` 生成 ${classes.length} 个类 → ${OUT}`);