mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-07-08 00:30:24 +00:00
e8a3412939
When transcript virtualization is disabled (the #4325 opt-out, _virtualizeTranscript===false), renderMessages() renders every row with no windowing and never runs the virtualized measure pass (_updateMessageVirtualMeasurements early-returns when !virtualized). Under @media (pointer: coarse), .msg-row[data-role="user"] carries content-visibility: auto; contain-intrinsic-size: auto 96px. Every rebuild does inner.innerHTML='' then recreates rows as fresh elements, so a fresh off-screen tall user row (a long paste measuring thousands of px) reserves only the flat estimate instead of its real height. scrollHeight shrinks by (realHeight - estimate), the browser force-clamps scrollTop, and the viewport jumps backward (a browser clamp, JS=none, so scrollTop-write compensation cannot catch it). #5638 fixed this for the virtualized wipe-and-rebuild path but left the non-virtualized full-rebuild path uncovered. Fix, three coordinated parts: - _estimateUserRowIntrinsicHeight weights CJK / full-width characters as ~2 columns (they wrap at ~24 chars/line, not 48), so a CJK paste reserves close to its real height even before it is ever measured. - _applyUserRowIntrinsicHeight reserves max(remembered, estimate): a remembered height can be a partial paint (a row taller than the viewport only paints its intersecting slice under content-visibility:auto), so the estimate floors it. - _rememberRenderedUserRowIntrinsicHeights, called pre-wipe inside renderMessages, reads the still-laid-out rows' real heights and persists them keyed by session-relative index, only for rows within the viewport (a fully off-screen never-painted row reports its collapsed reserve and must not poison the map), floored at the estimate. Desktop rests at content-visibility:visible so intrinsic-size is inert there; verified no behavior change with pointer:fine. Adds tests/test_issue5744_nonvirtual_userrow_collapse_jumpback.py (7 mutation-checked node-harness tests). Existing #5637/#5638 suites and the render/virtualization suites pass.