dsh-wisp 1.32.0 → 1.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -448,6 +448,80 @@ node tools/audit-log.mjs --confirm <manifest> # 生成后:并入代理登
448
448
 
449
449
  ## 变更
450
450
 
451
+ ### 1.33.1
452
+
453
+ **修「子菜单遮住主菜单」。** 上一版的定位是错的,而且错得不显眼 —— 面板确实"在旁边",
454
+ 只是**压进菜单十几个像素**。现在实测两矩形完全不重叠(右缘 1123 / 菜单左缘 1125)。
455
+
456
+ 根因有三层,都是"拿了不该拿的数字":
457
+
458
+ 1. **混用了两套坐标系**:菜单的 `left/top` 是**图层坐标**,而 `getBoundingClientRect()`
459
+ 给的是**视口坐标**。二者只在图层恰好从 (0,0) 开始时相等。
460
+ 2. **量了刚 append、还没布局的面板** ✗:那一刻它的宽度是 **0**,
461
+ 于是所有基于它的校正被守卫挡掉,位置就停在估算值上(实测就是这样一直没生效)。
462
+ 3. **宽度算错**:CSS 写 `width:184px` 但没写 `box-sizing` ✗ →
463
+ 默认 content-box 再加 `padding:6px` + `border:1px` → 实际 **198**,
464
+ 而翻转算式里用的常量是 178 —— 差了 20 像素,正好压住菜单。
465
+
466
+ **现在的做法**(不可能算错的那种):**只用量层坐标 + 宽度**。
467
+
468
+ - 面板宽度**固定**(`box-sizing:border-box; width:184px`)→ 常量就是真宽度,不用量;
469
+ - 横向:`x = 菜单left + 菜单宽度 + 2`,越界则 `x = 菜单left − 面板宽度 − 2`;
470
+ - 纵向:用"行矩形相对菜单矩形的**偏移**"→ `rr.top - mr.top` ——
471
+ 相对量与坐标系无关,而且自动带上头部/分隔线的高度(估算少了它,差了 28px);
472
+ - 入场动画从 `scale` 改成**纯淡入**:带 scale 的动画会让 `getBoundingClientRect()`
473
+ 量到缩放后的矩形,这是第 2 条坑的一部分。
474
+
475
+ **另外补了一道之前缺的防线**:冒烟里加了**真浏览器**的几何检查 ——
476
+ 「面板在菜单**旁边**(不是上面)」「在视口内」「与它所属那一行对齐」。
477
+ 假 DOM 没有布局,这三条**测不到**,而这个 bug 恰好只存在于布局里 ——
478
+ 所以它才会一路发布出去。
479
+
480
+ 预检 529 项沿用;冒烟 53 → **57 项**。
481
+
482
+ ### 1.33.0
483
+
484
+ ### 1.33.0
485
+
486
+ **子菜单改成在**旁边**弹出。** 上一版做成了"在行下面内联展开" —— 那是网页的手风琴,
487
+ 不是菜单栏。真正的 GUI 级联菜单(cascading menu / flyout)形状不一样:
488
+
489
+ ```
490
+ ┌──────────────────┐ ┌────────────────┐
491
+ │ 外观 深海女仆 ▸│──▶│ ✓ 深海女仆 │ ← 面板浮在行的**右侧**,
492
+ │ 行为 4/5 开 ▸│ │ 原版女仆 │ 与父行顶部对齐,
493
+ │ 位置 右下角 ▸│ │ 素绘女仆 │ 不把下面的内容推下去
494
+ └──────────────────┘ └────────────────┘
495
+ ```
496
+
497
+ 做对它的关键点,少一条都不算:
498
+
499
+ | 细节 | 为什么 |
500
+ |---|---|
501
+ | **面板是菜单的兄弟节点**(同一个 layer) | 才能探出菜单外面;内联展开永远做不到这一点。 |
502
+ | **右边放不下就翻到左侧**(▸ 变 ◂) | 否则子菜单被屏幕边缘切掉。 |
503
+ | **指针在「行」与「面板」之间算同一区域** | 两边都挂 enter/leave:任一边进入取消关闭,两边都离开才开始计宽限。 |
504
+ | **悬停是预览,点击是决定** | 悬停打开的随鼠标移开关闭;**点开的被钉住**,再点一次才收。 |
505
+ | **键盘 → / ←** | → 进子面板(焦点送进去),← 关面板并把焦点还给父行。 |
506
+ | **Esc 一次退一层** | 先关子面板,再关菜单。 |
507
+
508
+ **过程中修掉两个真 bug**(都是测试逼出来的):
509
+
510
+ 1. **子面板泄漏**:`closeMenu` 里那句收面板写成了 `if (menuEl) closeFlyout()` ——
511
+ 而那时 `menuEl` **已经被置空**,于是关菜单时子面板被**丢在屏幕上**。
512
+ 2. **Esc 永远退不到子面板**:`onKey` 的**第一句**就是"Escape → 关菜单",
513
+ 我那条"先关子面板"的分支排在后面,**永远轮不到**。诊断信息
514
+ `面板=还开着 菜单=被关了` 一眼看穿了它。
515
+
516
+ 另外把四个行构造器(动作行 / 开关行 / 滑块 / 罗盘)从 `openMenu` 内部提到了模块级 ——
517
+ 子面板要用同一批构造器,藏在 `openMenu` 里面就是一个 `ReferenceError`。
518
+
519
+ 预检 524 → **529 项**:面板是菜单的兄弟、有定位、不与菜单重叠、悬停延迟、宽限、
520
+ 指针移进面板算同一区域、路过不弹、触屏不弹、点击钉住、再点收起、手风琴、
521
+ → 进面板并聚焦、← 关闭并还焦点、Esc 逐层退出。
522
+
523
+ ### 1.32.0
524
+
451
525
  ### 1.32.0
452
526
 
453
527
  **分组改成悬停展开、移开收起**(点一下仍然是"钉住")。