-
Notifications
You must be signed in to change notification settings - Fork 72
feat(webview): saveScrollPosition / restoreScrollPosition helpers (#626) #809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -172,6 +172,38 @@ public void refreshPageContents() { | |||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||
| * Issue #626: capture the current scroll position into a | ||||||||||||||||||||||||||||||||||||||||||
| * window-scoped variable so a follow-up content swap can restore it. | ||||||||||||||||||||||||||||||||||||||||||
| * Pair with {@link #restoreScrollPosition()} called once the new | ||||||||||||||||||||||||||||||||||||||||||
| * body HTML has been rendered. | ||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||
| public void saveScrollPosition() { | ||||||||||||||||||||||||||||||||||||||||||
| runJavascript("window.__awfulSavedScroll = window.scrollY;"); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||
| * Restore a previously captured scroll position. Safe to call before | ||||||||||||||||||||||||||||||||||||||||||
| * the DOM has finished settling, the JS uses requestAnimationFrame | ||||||||||||||||||||||||||||||||||||||||||
| * to retry until the document height covers the saved offset. | ||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||
| public void restoreScrollPosition() { | ||||||||||||||||||||||||||||||||||||||||||
| runJavascript( | ||||||||||||||||||||||||||||||||||||||||||
| "(function(){" + | ||||||||||||||||||||||||||||||||||||||||||
| "var target = window.__awfulSavedScroll;" + | ||||||||||||||||||||||||||||||||||||||||||
| "if (target == null) { return; }" + | ||||||||||||||||||||||||||||||||||||||||||
| "function tryScroll() {" + | ||||||||||||||||||||||||||||||||||||||||||
| "if (document.documentElement.scrollHeight >= target) {" + | ||||||||||||||||||||||||||||||||||||||||||
| "window.scrollTo({top: target});" + | ||||||||||||||||||||||||||||||||||||||||||
| "} else {" + | ||||||||||||||||||||||||||||||||||||||||||
| "window.requestAnimationFrame(tryScroll);" + | ||||||||||||||||||||||||||||||||||||||||||
| "}" + | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+195
to
+200
|
||||||||||||||||||||||||||||||||||||||||||
| "function tryScroll() {" + | |
| "if (document.documentElement.scrollHeight >= target) {" + | |
| "window.scrollTo({top: target});" + | |
| "} else {" + | |
| "window.requestAnimationFrame(tryScroll);" + | |
| "}" + | |
| "var attempts = 0;" + | |
| "var maxAttempts = 60;" + | |
| "function tryScroll() {" + | |
| "var doc = document.documentElement;" + | |
| "var maxScrollTop = Math.max(0, doc.scrollHeight - doc.clientHeight);" + | |
| "if (maxScrollTop >= target) {" + | |
| "window.scrollTo({top: target});" + | |
| "if (window.scrollY >= target || attempts >= maxAttempts) { return; }" + | |
| "} else if (attempts >= maxAttempts) {" + | |
| "window.scrollTo({top: maxScrollTop});" + | |
| "return;" + | |
| "}" + | |
| "attempts++;" + | |
| "window.requestAnimationFrame(tryScroll);" + |
Copilot
AI
Apr 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a successful restore, window.__awfulSavedScroll is left set. That makes subsequent restores (or other pages using the same WebView) potentially apply a stale offset unexpectedly. Clearing the saved value once it has been applied would make the helper safer to use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
window.scrollTo({top: target})uses the options-object overload, which isn’t supported on older Chromium-based Android WebViews (minSdk 24 can still be on an older WebView). If unsupported, this will throw and abort the restore. Prefer the legacy signature (scrollTo(0, target)) or feature-detect before using the options overload.