From aac6d3e0f406ecdd7ffd412a51ba1117104ce73c Mon Sep 17 00:00:00 2001 From: laoyang Date: Tue, 29 Sep 2026 08:10:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=81=94=E6=83=B3=E8=AF=8D=E9=94=AE=E7=9B=98?= =?UTF-8?q?=E9=80=89=E8=AF=8D=E5=BD=BB=E5=BA=95=E4=BF=AE=E5=A4=8D=EF=BC=9A?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E9=94=AE=20/=20=E9=80=97=E5=8F=B7=E5=8F=A5?= =?UTF-8?q?=E5=8F=B7=20/=20=E8=BE=93=E5=85=A5=E6=B3=95=E7=BB=84=E5=90=88?= =?UTF-8?q?=E4=B8=8A=E5=B1=8F=E5=9B=9B=E6=9D=A1=E8=B7=AF=E5=BE=84=E5=85=A8?= =?UTF-8?q?=E9=80=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景:用户反馈「上下键和逗号句号都无法选择候选词,只能用鼠标」。逐条查下去 发现是**三个各自独立的原因**叠在一起,任何一个没修都会让人觉得「还是坏的」。 ① 单组按键模式让另一组键静默失效 线上 settings.suggest_keys 停在 'punct'(只认 , 和 .)—— 是该模式的正确 行为,但用户不知道那是设置项在起作用,只当坏了。 改法:默认值改为 'both'(↓/↑ 与 , . 都认)。'both' 是 'arrows' 与 'punct' 各自行为的**严格超集**,升级不会让任何人的习惯失效,只是多了一组。 老库用**一次性迁移**(哨兵键 mig_suggest_keys_both 把关)把已知单组值并成 'both'。⚠️ 迁移必须只跑一次:db_init() 每次请求都执行,无条件 UPDATE 会把 用户在后台特意选回的 'arrows' 于下一个请求改回去 —— 设置项直接失效。 同时同步三处默认值:index.php / admin/index.php / admin/actions.php。 ② 【元凶】beforeinput 只认 insertText,漏了 insertCompositionText 输入法把标点当**组合内容**提交时,beforeinput 的 inputType 是 insertCompositionText,旧代码直接 return → 这条路径完全失效。 修法:两种 inputType 都认。 ③ 【真机实测的硬限制】insertCompositionText 的 beforeinput cancelable = false Chromium 里这条事件**不允许** preventDefault(CDP 实测记录: beforeinput it:insertCompositionText comp:true data:"," pd:false cc:false), 所以「命中就拦」对这条路根本无效 —— 标点会被真的插进搜索框。 修法:加「事后收口」——beforeinput 记下快照与该移到的目标下标, 等这一帧事件洪峰过去(setTimeout 0)再把标点从输入框里撤掉、并补上选词移动。 目标下标必须**当场算好**:收口跑在宏任务里,那时 input 的 `active = -1` 已经把选中清掉了,再从 active 起算会每次都回到第一条(不累加)。 顺带把标点判定抽成共用函数 punctDir/keyPunctDir(e.key 与 e.code 互为兜底), 并修掉「方向键也无差别置去重闸门」——方向键不产生 beforeinput,置了纯属副作用, 反而会误挡紧随其后的真实标点。 测试与验证(全部实跑,非推断): - jsdom 交互测试 89 项全过,新增「真实浏览器形态」场景(cancelable=false + 组合上屏),并**纠正了旧版一条在断言 bug 本身的断言**(原写「组合上屏不该被拦」)。 - 反向验证 6 变体全部精确挂掉对应断言(含新增的「只认 insertText」与 「方向键置闸门」两个变体);旧变体引用的 isComma/isPeriod 已随重构更新。 - **真实浏览器**(Playwright + msedge + CDP IME)21/21:上下键 / 半角 / 全角 insertText / IME 组合上屏四条路径全部能选词。 - 真实浏览器反向验证:基准全绿,删掉「事后收口」或改回只认 insertText 都精确报红。 - 迁移语义测试 16 项全过(真实 db_init,含「用户改回 arrows 后不再被覆盖」)。 - 静态断言空跑 155 条全过;线上部署 0 FAIL,诊断页 57 条断言全过。 - 线上真机直连 n.yangyq.net 21/21。 --- admin/actions.php | 6 +- admin/index.php | 17 ++--- assets/js/app.js | 174 ++++++++++++++++++++++++++++++++++++---------- db.php | 25 ++++++- index.php | 8 +-- 5 files changed, 174 insertions(+), 56 deletions(-) diff --git a/admin/actions.php b/admin/actions.php index e393a79..21969c5 100644 --- a/admin/actions.php +++ b/admin/actions.php @@ -268,9 +268,9 @@ try { // 打开方式:'0' = 当前页面;其余(含字段缺失、被篡改成怪值)一律回到 '1'(新标签页) // ——默认必须等于改造前的旧行为,这样老库里已有的值上线后不会突然变样。 $open = (string)($_POST['open_blank'] ?? '1') === '0' ? '0' : '1'; - // 联想词按键:arrows(↓/↑)/ punct(, 和 .)/ both;非白名单一律回到 arrows - $keys = (string)($_POST['suggest_keys'] ?? 'arrows'); - if (!in_array($keys, ['arrows', 'punct', 'both'], true)) { $keys = 'arrows'; } + // 联想词按键:both(都认,默认)/ arrows(↓/↑)/ punct(, 和 .);非白名单一律回到 both + $keys = (string)($_POST['suggest_keys'] ?? 'both'); + if (!in_array($keys, ['arrows', 'punct', 'both'], true)) { $keys = 'both'; } $map = [ 'site_name' => trim((string)($_POST['site_name'] ?? '')), 'subtitle' => trim((string)($_POST['subtitle'] ?? '')), diff --git a/admin/index.php b/admin/index.php index b87578c..84e7b25 100644 --- a/admin/index.php +++ b/admin/index.php @@ -325,18 +325,19 @@ else: // settings ?> 各用各的(没恢复好的引擎会自动回退到百度的建议)。

- 决定用哪组键在联想下拉里选词:选中某条后回车才按该词搜索;不选就直接回车 = 用你输入的原文。 - 「, 和 .」跟输入法一样,手不用离开主键区,习惯中文输入法的话更顺手。 - ⚠️ 选它之后,联想下拉打开时逗号与句号会当作选词键,不再直接输入 —— - 想搜「python, pandas」这类带逗号的词,先按 Esc 关掉下拉再输。 + 决定用哪组键在联想下拉里选词:选中某条后回车才按该词搜索;不选就直接回车 = 用你输入的原文。
+ 推荐「两者都可以」——手不用离开主键区,习惯中文输入法的话按 , . 更顺手,同时也保留方向键。 + ⚠️ 只要联想下拉打开着,逗号与句号就会当作选词键、不再直接输入 —— + 想搜「python, pandas」这类带逗号的词,先按 Esc 关掉下拉再输。
+ 若只留一组键,另一组会完全没反应(不是坏了,是这里的选择),所以除非你明确只想用一组,建议保持默认。