Merge pull request #3415 from deepseek-harness/worktree/3414-turn-rail-preview-layer

fix(web): keep turn previews above code banners
This commit is contained in:
Yichen Jiang 2026-09-01 21:05:36 +08:00 • committed by GitHub
commit 3efd4b51e0
5 changed files with 19 additions and 5 deletions

View file

@ -591,6 +591,18 @@ describe('web e2e: long Chat scroll contract', () => {
await expect.poll(() => tooltip.count(), { timeout: 15_000 }).toBe(1)
expect(await tooltip.textContent()).toContain(HISTORY_FIXTURE.markers.user(1))
expect(await tooltip.textContent()).toContain(HISTORY_FIXTURE.markers.assistant(1))
const transcriptLayers = await tooltip.evaluate((preview) => {
const railSlot = preview.closest('nav')?.parentElement
const codeBanner = document.querySelector<HTMLElement>('.md-code-block > :first-child')
if (!(railSlot instanceof HTMLElement) || codeBanner === null) {
throw new Error('turn preview or code-block banner stacking context is unavailable')
}
return {
codeBanner: Number(getComputedStyle(codeBanner).zIndex),
rail: Number(getComputedStyle(railSlot).zIndex),
}
})
expect(transcriptLayers.rail).toBeGreaterThan(transcriptLayers.codeBanner)
await world.page.keyboard.press('Enter')
// The jump pages history in and lands on turn 1: its mark flips to the

View file

@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/client/ui-chat/README.md
README.md: 19cfcf4d14f7e805d6113eeb4e34a586f7150574
README.zh.md: 18e20eeea15cf3eeb5e8e4a777fa534251232a81
README.md: 79214bf2feb8384cecbb152aa31af162dc6dfdde
README.zh.md: 674959e1974c74abba75f179eff50fe8488458fc

View file

@ -46,7 +46,7 @@ Settings → General exposes a persisted `Normal` / `Compact` conversation-displ
<a id="scroll-ownership"></a>
## Scroll ownership
Chat restores semantic anchors across history prepend and renderer remounts. While the reader is pinned to the floor, `ResizeObserver` follows the new floor and selects the latest loaded Turn without reading row geometry. Once the reader moves away, flow-height changes preserve the top position and the reading-line geometry selects the active Turn ([loaded-Turn navigation](../../../.agents/notes/implemented/feature/2026-08-25-loaded-turn-chat-navigation.md)).
Chat restores semantic anchors across history prepend and renderer remounts. While the reader is pinned to the floor, `ResizeObserver` follows the new floor and selects the latest loaded Turn without reading row geometry. Once the reader moves away, flow-height changes preserve the top position and the reading-line geometry selects the active Turn. Turn-rail previews paint above sticky Markdown code-block banners, while the rail frame remains inside the transcript band above the composer ([loaded-Turn navigation](../../../.agents/notes/implemented/feature/2026-08-25-loaded-turn-chat-navigation.md)).
-----

View file

@ -46,7 +46,7 @@ Chat 会为每个非空的初始或恢复请求、显式消息序列起点或真
<a id="scroll-ownership"></a>
## 滚动归属
Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点。读者跟随底部时,`ResizeObserver` 追随新的底部,并且无需读取行几何就选中最后一个已加载 Turn;读者离开底部后,高度变化会保持顶部位置,再由阅读线几何选择活跃 Turn([已加载 Turn 导航](../../../.agents/notes/implemented/feature/2026-08-25-loaded-turn-chat-navigation.zh.md))。
Chat 会在历史前插与 renderer 重新挂载时恢复语义锚点。读者跟随底部时,`ResizeObserver` 追随新的底部,并且无需读取行几何就选中最后一个已加载 Turn;读者离开底部后,高度变化会保持顶部位置,再由阅读线几何选择活跃 Turn。轮次导航预览位于 Markdown 代码块粘性头栏上方,而导航外框始终处于 composer 上方的 transcript 区域内([已加载 Turn 导航](../../../.agents/notes/implemented/feature/2026-08-25-loaded-turn-chat-navigation.zh.md))。
-----

View file

@ -3,7 +3,9 @@
.slot {
position: sticky;
top: 0;
z-index: 6;
/* Above transcript CodeBlock banners (z-index 6). The rail band excludes
the composer, so its preview never needs to cross the footer. */
z-index: 7;
height: 0;
pointer-events: none;
}