From e6048e9914065ac0f943ffeaed5fe55db017ae64 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Tue, 15 Sep 2026 07:46:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(webui):=20=E5=80=99=E9=80=89=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E6=94=B9=E7=94=A8=E4=B8=8D=E9=80=8F=E6=98=8E=E5=BC=B9?= =?UTF-8?q?=E5=B1=82=E8=A1=A8=E9=9D=A2=20=E2=80=94=E2=80=94=20=E5=8D=8A?= =?UTF-8?q?=E9=80=8F=E6=98=8E+=E8=83=8C=E6=99=AF=E6=A8=A1=E7=B3=8A?= =?UTF-8?q?=E6=8A=8A=E8=83=8C=E5=90=8E=E7=9A=84=E8=A1=A8=E5=8D=95=E7=B3=8A?= =?UTF-8?q?=E8=BF=9B=E4=BA=86=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户(2026-09-15,看着抄送/转发两处的候选):「你在选择框的模糊逻辑上用力过猛, 导致只能显示一条信息」。 实测(生产构建 4c2bf26,浏览器里读计算样式,壁纸开): 菜单 background: rgba(255,255,255,0.5) + backdrop-filter: blur(8px) saturate(1.1) 而它浮在**表单自己**之上(主题输入框 y=294 正落在菜单 284-510 下面) ⇒ 背后的输入框/标签被糊一遍再从半透明列表底下透上来,只有顶行还读得清。 根因与 2026-09-14 那次「模糊叠模糊」同族:把**控件档**(0.5 透 + 8px 模糊)用在 **弹层**上。控件背后是面板自身,透一点好看;弹层背后是别的内容,透就是叠两份内容。 - 新增 .popup-surface(rgb(var(--c-white)),不取 backdrop-filter;壁纸开时单独压回不透明, 否则会撞上 html[data-bg='on'] .bg-white 那条接管规则) - .popup-surface 并入「滚动区不淡」豁免(原来只认 .glass-control,换类会漏掉 → 弹层又被洗白) - AddressInput 菜单 glass-control → popup-surface;旧断言 nav-merge.test.mjs:109 钉的正是 那个错的意图(『地址建议菜单』必须用控件档),已改钉新意图 判据:narrow-layout 新增 4 条(表面不透明/不取模糊/壁纸开时也压回/菜单穿的类)+ nav-merge 反向对照。两侧都验:变异①换回 glass-control → 红;变异②改回 0.5 → 红; 复原 → 71 通过 0 失败。生产实测:rgba(...,0.5)+blur → rgb(255,255,255)+无模糊。 --- .../electron/src/components/AddressInput.tsx | 2 +- client/electron/src/index.css | 34 ++++++++++++++++- .../test/manual/nav-restructure-verify.mjs | 10 +++-- client/electron/test/narrow-layout.test.mjs | 38 ++++++++++++++++++- client/electron/test/nav-merge.test.mjs | 13 ++++++- 5 files changed, 88 insertions(+), 9 deletions(-) diff --git a/client/electron/src/components/AddressInput.tsx b/client/electron/src/components/AddressInput.tsx index 6b46f16..acc535e 100644 --- a/client/electron/src/components/AddressInput.tsx +++ b/client/electron/src/components/AddressInput.tsx @@ -181,7 +181,7 @@ export default function AddressInput({ {open && items.length > 0 && (
= 0.99 && card !== null && menu > card, + `正文面 α=${card} 弹层 α=${menu}(弹层必须 ≥0.99)` ); } finally { await page.close(); diff --git a/client/electron/test/narrow-layout.test.mjs b/client/electron/test/narrow-layout.test.mjs index fa9dc5d..5c4030e 100644 --- a/client/electron/test/narrow-layout.test.mjs +++ b/client/electron/test/narrow-layout.test.mjs @@ -2,7 +2,7 @@ // // 不做视觉快照:那需要 headless 浏览器,且像素级比对在字体差异下极脆。 // 这里守住几条真正会坏掉的不变量。 -import { prose } from './lib/read.mjs'; +import { code, prose } from './lib/read.mjs'; import { check, finish } from './lib/checks.mjs'; const read = p => prose(new URL(p, import.meta.url)); @@ -205,9 +205,43 @@ check( ); check( '弹层(控件档滚动区)不做边缘淡出', - /\.overflow-y-auto\.glass-control\s*\{[\s\S]*?mask-image:\s*none/.test(css), + /\.overflow-y-auto\.(glass-control|popup-surface)\s*\{[\s\S]*?mask-image:\s*none/.test(css), '候选菜单这类弹层还在淡 —— 它高度只有几十像素,首尾项会被洗白' ); + +/* + * 候选/转发两个选择框的菜单必须是**不透明**表面(2026-09-15 用户: + * 「你在选择框的模糊逻辑上用力过猛,导致只能显示一条信息」)。 + * + * 判据钉的是**结构**而不是某个具体颜色值: + * ① 弹层类必须存在,且用 rgb(var(--c-white)) 而不是带 alpha 的 rgb(... / α); + * ② 弹层规则里不允许出现 backdrop-filter(背后的表单被模糊正是那份乱); + * ③ 壁纸开着时也得另有规则压回不透明(`html[data-bg='on'] .bg-white` 会抢); + * ④ AddressInput 的菜单必须穿这个类,不许再穿 .glass-control。 + */ +const popupRule = (css.match(/\.popup-surface\s*\{[\s\S]*?\n\}/) || [''])[0]; +const popupBgOn = (css.match(/html\[data-bg='on'\]\s*\.popup-surface\s*\{[\s\S]*?\n\}/) || [''])[0]; +const addrSrc = code('src/components/AddressInput.tsx'); // 判「代码里穿了哪个类」→ 用剥注释版 +check( + '弹层表面存在且不透明', + /\.popup-surface\s*\{/.test(css) && /background-color:\s*rgb\(var\(--c-white\)\)/.test(popupRule), + '弹层没有独立的不透明表面 —— 半透明列表叠在表单上,下面的行会被背后控件糊掉' +); +check( + '弹层不取背景模糊', + !/backdrop-filter:\s*blur/.test(popupRule), + '弹层又开了 background blur —— 背后的控件被糊住后和候选行叠在一起' +); +check( + '壁纸开时弹层也不透明', + /background-color:\s*rgb\(var\(--c-white\)\)/.test(popupBgOn) && !/backdrop-filter:\s*blur/.test(popupBgOn), + "`html[data-bg='on'] .bg-white` 会把弹层拉回半透明那档(0.88),必须单独压回去" +); +check( + '候选菜单穿的是弹层类', + /absolute[^`]*popup-surface/.test(addrSrc) && !/absolute[^`]*glass-control/.test(addrSrc), + 'AddressInput 的菜单还穿着控件档(.glass-control) —— 那档是给贴着面板的小控件用的' +); check( '淡出规则同时带 -webkit- 前缀(Electron 里以哪个为准不由我们定)', (maskRule.match(/-webkit-mask-image:/g) || []).length === 1 && diff --git a/client/electron/test/nav-merge.test.mjs b/client/electron/test/nav-merge.test.mjs index 31ae9c4..bd02ce2 100644 --- a/client/electron/test/nav-merge.test.mjs +++ b/client/electron/test/nav-merge.test.mjs @@ -106,7 +106,18 @@ test('③ 复选框与地址建议用"控件档"透度(比正文面更透)', assert.match(mailView, /import \{[^}]*ComposerChip[^}]*\} from '\.\/Composer'/, 'MailView 要用共用的胶囊组件'); assert.match(mailView, / 嵌套 > 控件)