fix: page down/up scrolls by viewport height, not line count#7479
fix: page down/up scrolls by viewport height, not line count#7479JohnMcLear wants to merge 4 commits intodevelopfrom
Conversation
Review Summary by QodoFix Page Down/Up scrolling with long wrapped lines
WalkthroughsDescription• Page Down/Up now scrolls by viewport height in pixels instead of line count • Fixes issue where long wrapped lines consumed entire viewport, making scrolling ineffective • Maintains 40px overlap for context preservation between page transitions • Cursor repositions to first/last visible line after scrolling Diagramflowchart LR
A["Page Down/Up keypress"] --> B["Calculate viewport height in pixels"]
B --> C["Scroll by viewport height minus 40px overlap"]
C --> D["Reposition cursor to new visible area"]
D --> E["Update selection and display"]
File Changes1. src/static/js/ace2_inner.ts
|
Code Review by Qodo
1.
|
Review Summary by QodoFix PageDown/PageUp scrolling with long wrapped lines
WalkthroughsDescription• Fix PageDown/PageUp to scroll by viewport pixel height instead of logical line count • Calculate lines-to-skip using actual rendered line heights for wrapped lines • Add regression test for consecutive long wrapped lines (#4562) • Simplify caret positioning logic and remove outdated comments Diagramflowchart LR
A["PageDown/PageUp Event"] --> B["Calculate viewport height in pixels"]
B --> C["Sum rendered line heights in viewport"]
C --> D["Compute lines-to-skip ratio"]
D --> E["Move cursor by calculated lines"]
E --> F["Scroll to caret position"]
G["Regression Test"] --> H["Create pad with long wrapped lines"]
H --> I["Verify PageDown advances cursor correctly"]
File Changes1. src/static/js/ace2_inner.ts
|
Code Review by Qodo
1. Off-by-one visible line count
|
|
|
||
| const oldVisibleLineRange = scroll.getVisibleLineRange(rep); | ||
| let topOffset = rep.selStart[0] - oldVisibleLineRange[0]; | ||
| if (topOffset < 0) topOffset = 0; |
There was a problem hiding this comment.
I like more brackets but I can understand both styles. Makes it more visible what is inside the if.
The previous implementation counted logical lines in the viewport, which failed when long wrapped lines consumed the entire viewport. Now scrolls by actual pixel height for correct behavior. Fixes #4562 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… PageDown/Up outerWin is an HTMLIFrameElement (returned by getElementsByName), not a Window object, so it has no .document property. The existing getInnerHeight() helper already uses outerDoc.documentElement.clientHeight correctly; align the PageDown/PageUp handler with that pattern. Adds a Playwright regression test that verifies PageDown scrolls the viewport when the pad contains long wrapping lines. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous approach tried to scroll the outerWin iframe element directly which didn't work. Reverted to the original cursor-movement approach but calculates lines-to-skip using viewport pixel height divided by actual rendered line heights. This correctly handles long wrapped lines that consume multiple visual rows. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
14d6a00 to
a0b5f7d
Compare
Recover the PageDown/Up fixes that got dropped when this branch was rebased onto develop: - Use getInnerHeight() instead of outerDoc.documentElement.clientHeight so hidden-iframe and Opera edge cases are handled the same as the rest of the editor. - scroll.getVisibleLineRange() returns an inclusive end index, so count (end - start + 1) logical lines to match the pixel-sum loop bounds. - Replace the flaky 'PageDown scrolls viewport' test with the robust #4562 regression that builds long wrapped lines via direct DOM and asserts the caret advances on successive PageDown presses. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Test plan
Fixes #4562
🤖 Generated with Claude Code