fix: delay anchor line scrolling until layout settles#7544
fix: delay anchor line scrolling until layout settles#7544JohnMcLear wants to merge 2 commits intoether:developfrom
Conversation
Review Summary by QodoDelay anchor line scrolling until layout settles
WalkthroughsDescription• Refactor anchor line scrolling to reapply focus until layout settles • Extract line number parsing and focus logic into separate functions • Add 10-second settle window with 250ms polling intervals • Replace animation with direct scrollTop for better reliability • Add regression tests for delayed content expansion scenarios Diagramflowchart LR
A["Hash URL with #L anchor"] -->|getHashedLineNumber| B["Extract line number"]
B -->|focusOnLine| C["Start settle loop"]
C -->|250ms interval| D["getCurrentTargetOffset"]
D -->|focusOnHashedLine| E["Scroll and set selection"]
E -->|until 10s timeout| F["Layout stabilized"]
File Changes1. src/static/js/pad_editor.ts
|
Code Review by Qodo
1. Immediate focusUntilStable() scroll
|
| const focusUntilStable = () => { | ||
| if (Date.now() - startTime >= maxSettleDuration) { | ||
| window.clearInterval(intervalId); | ||
| return; | ||
| } | ||
| } | ||
| const currentOffsetTop = getCurrentTargetOffset(); | ||
| if (currentOffsetTop == null) return; | ||
|
|
||
| focusOnHashedLine(ace, lineNumberInt); | ||
| }; | ||
|
|
||
| focusUntilStable(); | ||
| intervalId = window.setInterval(focusUntilStable, settleInterval); |
There was a problem hiding this comment.
1. Immediate focusuntilstable() scroll 📎 Requirement gap ≡ Correctness
The new #L... behavior scrolls immediately on load via focusUntilStable() instead of deferring until the pad layout has fully settled. This can still cause an initial incorrect viewport position before late-loading content (for example images) finishes affecting layout.
Agent Prompt
## Issue description
The implementation scrolls immediately and then re-applies scrolling for a fixed settle window, but it does not actually *defer* scrolling until the layout has stabilized.
## Issue Context
Compliance requires that `#L...` navigation scroll occurs only after async content (e.g., images/plugins) has finished loading and the resulting layout is stable, to prevent landing on the wrong line/region.
## Fix Focus Areas
- src/static/js/pad_editor.ts[271-283]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if (lineNumber) { | ||
| if (lineNumber[0] === 'L') { | ||
| const $outerdoc = $('iframe[name="ace_outer"]').contents().find('#outerdocbody'); | ||
| const lineNumberInt = parseInt(lineNumber.substr(1)); |
There was a problem hiding this comment.
I must say this code is quite a mess. I like the new style with better function naming 😊.
| } | ||
| } | ||
| if (!lineNumber || lineNumber[0] !== 'L') return null; | ||
| const lineNumberInt = parseInt(lineNumber.substr(1)); |
There was a problem hiding this comment.
Just fyi. Substr should not be used as it is deprecated. You can use substring which should work in your case identically. You only need to pay attention because the second argument does not anymore mean length but end position. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr
| const hasMobileLayout = $('body').hasClass('mobile-layout'); | ||
| if (!hasMobileLayout) offsetTop += parseInt($inner.css('padding-top').replace('px', '')); | ||
| const $outerdocHTML = $aceOuter.contents().find('#outerdocbody').parent(); | ||
| $outerdoc.css({top: `${offsetTop}px`}); // Chrome |
There was a problem hiding this comment.
Is this only for chrome? Is it still relevant?
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Addresses Qodo review: the 10s reapply loop could fight the user when they tried to scroll or click away from the anchored line. Listen for wheel/touchmove/keydown/mousedown on both ace_outer and ace_inner documents in capture phase and tear down the interval on first signal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
de449b7 to
157cc5f
Compare
Summary
#L...line scrolling for a short settle window after pad loadCloses #5700