fix: 批注高亮与编号不再压住会话顶栏 (#62) - #63
Merged
Merged
Conversation
This was referenced Sep 30, 2026
Merged
Collaborator
|
感谢 @PerryLink ——两个关键贡献都在这次合入中落了地:
情况说明:本 PR 基于 #65 之前的 main,而 #65 重写了同一片 renderMarkers 区域,无法直接合并;维护者接手后把你的两个核心洞见组合进了 #65 的编号图层架构(编号下限抬到会话列上沿 + 4px,仅当原文起于其下;原文已滚入顶栏之下时仍走「滚出可视区即消失」),你的原始提交 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修复 #62。
根因
标记层是 body 级的
position: fixed图层(client.js:912,z-index: 900,编号胶囊940)。改动前renderMarkers()只在这个图层上挖了一个 evenodd 洞 —— 输入框那个(#50 的修法)—— 所以输入框以外的一切,包括会话顶栏横带,都仍然可绘制。顶栏是文档流里的普通元素,渲染在会话滚动体之上
(
ConversationMainPanel.tsx:45先渲染conversation.session.header槽位,再渲染内容),因此被批注的原文一旦滚到顶栏之下,高亮矩形与编号胶囊仍按视口坐标绘制,直接压在顶栏上。
修法
沿用挖洞方案,再为顶栏横带挖第二个洞,位置由宿主钩子
[data-conversation-scroll]推导(滚动体,渲染于packages/client/ui-conversation/src/client/skeleton/ConversationContent.tsx:189):chipTop的下限从「视口上沿 4px」抬到「滚动体上沿以下 4px」,使本会落进洞里的胶囊被推到洞以下,而不是被整块裁掉。
这个洞有意只取
scrollBody.left..scrollBody.right,而不是 #62 建议的整幅宽度:#57 的侧边栏文件预览(
ui-sidebar-documentpreview,[data-document-markdown]与[data-code-preview]所在处)在会话列之外,整幅宽度的洞会把它们的标记一并裁掉。
其余不变。若
[data-conversation-scroll]不存在或宽度为 0,markerViewport()返回 null,裁剪路径完全退回原先只有输入框的多边形。
宿主钩子的稳定性
[data-conversation-scroll]不是新钩子:它由 2026-07-29 的a4602b959e("feat: optimize chat pagescroll area")引入,是
dsh-v0.1.0-rc.7直到dsh-v0.1.6-alpha.2的祖先,即本插件支持的整个区间内都存在。宿主自己的客户端测试就在用它 ——
ui-conversation/tests/skeleton.client.spec.tsx:484、ui-chat/tests/chat-view.client.spec.tsx:2688、ui-conversation/tests/assembly-surfaces.client.spec.tsx:145。对我自己在 #62 里那条评论的更正:我在那里把引入提交写成了
e62587c163,不对。git grep -c在a4602b959e^上匹配 0 个文件、在a4602b959e上匹配 13 个;而e62587c163(2026-09-17)只是改了该属性的一处既有用法,甚至不在
dsh-v0.1.0-rc.7的区间里。那条评论的结论(钩子存在、稳定、早于支持区间)不受影响,错的只是归属。
回归重点与取舍
① 顶栏下沿是结构上精确的,不是近似。
.root是flex-direction: column,顶栏槽位是它的首个子节点,紧跟着
.body > .scrollBody;.header是flex: none且没有任何 margin,.body是flex: 1且没有上外边距/上内边距,
.scrollBody只有margin-right: 2px(水平)。⇒[data-conversation-scroll]的getBoundingClientRect().top就是顶栏下沿,直接可用。② 为什么从滚动体推算,而不是用
[data-conversation-header-corner]。 那个属性确实存在(
packages/client/ui-conversation/src/client/skeleton/ConversationSession.tsx:137,一个headerCorner容器),但它标的是顶栏内部的角落容器,不是顶栏根节点;顶栏根节点只有 CSS Modules 哈希类名,宿主对外
给的是槽位名(
conversation.session.header等)而非 DOM 属性。所以从滚动体推算更稳。③
#50的输入框洞不会被覆盖。 新clipPath是把两个洞拼进同一个polygon(evenodd, …),不是替换;test/layout-overlay.test.mjs里有一条专门的回归用例断言输入框洞与顶栏洞同时存在(
输入框挖洞(issue #50)保持原样,两个洞互不影响)。侧栏文档预览不被误裁同理有专门断言。本 PR 不做的事:不改动标记层的挂载位置(把它挂进会话滚动容器会牵动滚动、裁剪与坐标语义,评审面过大,
应另开一条)。
验证
node --test test/*.test.mjs—— 25 passed, 0 failed(Windows 11 / Node v22.22.3)。test/layout-overlay.test.mjs新增 4 个用例,沿用placeAbove那个用例既有的「抽取源码再 eval」写法。它们用桩 DOM 驱动真实的
renderMarkers(),断言的是插件实际安装的clipPath,而不是某个辅助函数是否存在。
反证 —— 把新断言对着未打补丁的
client.js跑:打印出来的那个多边形就是缺陷本身:只有一个洞(输入框),顶栏横带整条可绘制。
本机验证(真实浏览器)
上一版这一段写的是「这台机器没有浏览器」——那是我写错了。 本机装了
Chrome 153.0.8010.52 / Edge 148 / Firefox 156;
test/overlay-browser.mjs也不是「只断言
CSS.supports(...)」,它已经用document.elementFromPoint()验过输入框洞真的挡得住命中。真正的原因是下面第 3 条:那个脚本在 Windows 上跑不起来。现在三条都补跑了。
1. 插件自带的浏览器 E2E —— 本机通过
test/overlay-browser.mjs,Chrome 153.0.8010.52(Windows 11,channel: 'chrome')+ Playwright 1.62.1:client.js上同样 PASS —— 它只覆盖 #50 的输入框洞。它是「没有弄坏」的证据,不是「修好了」的证据。
2. 顶栏横带的裁剪,用真实浏览器引擎单独验(本 PR 缺的就是这一半)
真实布局夹具(顶栏 /
[data-conversation-scroll]/[data-composer-card]/ 会话列之外的侧边栏),把插件实际安装的
clipPath交给引擎,再用document.elementFromPoint()逐点验证裁剪是否真的生效:先断言该引擎确实在命中测试里遵守
clip-path(零面积裁剪的元素不可命中),否则整张表没有意义 —— 这条自检通过。3. 顺带发现:
test/overlay-browser.mjs在 Windows 上跑不起来(与本 PR 无关,本 PR 没有改它)它用
new URL('../client.js', import.meta.url).pathname定位client.js;Windows 上这得到/D:/...,Playwright 于是去开D:\D:\...并报ENOENT。改成fileURLToPath(new URL('../client.js', import.meta.url))之后,上面第 1、2 条才跑得起来。要的话我另开一条一行 PR 修它 —— 按你们的分工,我不把无关改动塞进这条。
仍未做的
没有对着真实 DSH Desktop 做端到端确认(本机没装 Desktop 2.0.13)。上面验的是裁剪语义与几何,
外加插件自身浏览器 E2E 的回归通过;宿主里的实际观感仍建议在 2.0.13 / 内核 0.1.5-rc.2 的环境上复验一遍。
另外,如果你更希望由宿主在顶栏根节点上直接暴露一个
data-conversation-header属性,说一声,我改成消费它,而不是从滚动体反推这条横带。