Fix Reader footnotes opening in browser instead of scrolling#22733
Fix Reader footnotes opening in browser instead of scrolling#22733
Conversation
Footnote links in WordPress posts resolve to the post's own URL with a fragment identifier (e.g., "https://example.com/post/#fn-id"). The Reader was routing these to the browser because they passed the http URL check without being recognized as same-page anchors. - In ReaderPostDetailFragment.onUrlClick, detect when a clicked URL's base matches the current post URL and redirect to onPageJumpClick - Collapse the app bar on page jump so the target isn't obscured - In ReaderWebView, add first-line fragment detection in onTouchEvent and shouldOverrideUrlLoading for URLs matching the content base URL - Extract READER_CONTENT_BASE_URL constant in ReaderPostRenderer Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generated by 🚫 Danger |
The footnote fix works entirely in ReaderPostDetailFragment.onUrlClick by comparing against the post's own URL. The ReaderWebView interception (isSamePageFragmentUrl, loadDataWithBaseURL override, mLoadedBaseUrl) compared against the reader base URL which never matched real footnote URLs, so it was dead code. Also removes the now-unused READER_CONTENT_BASE_URL constant from ReaderPostRenderer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Flatten nested if in onUrlClick fragment detection - Remove redundant wasJsEnabled save/restore from onPageJumpClick and scrollToFragmentOrOpenUrl (JS is always enabled by ReaderPostRenderer) - Fall back to opening the full URL in the browser when the footnote element isn't found in the page Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rolling When tapping the ↩︎ back-reference in a footnote, the WebView reports it as an image inside an anchor (SRC_IMAGE_ANCHOR_TYPE). Previously this routed to the fullscreen image viewer. Now we check if the parent anchor's href contains a fragment identifier and route it through onUrlClick instead, where existing fragment detection handles scrolling back to the reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes detekt ComplexCondition and ReturnCount violations by extracting the 4-part fragment URL check into a dedicated method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Escape backslashes and single quotes in fragment identifiers passed to evaluateJavascript to prevent potential script injection from maliciously crafted post content. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract scrollToElement() with a fallback lambda to deduplicate the JS evaluation, sanitization, density conversion, and scroll logic that was repeated in onPageJumpClick and scrollToFragmentOrOpenUrl. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
There's a strange behaviour when tapping on the 1 back note. Sometimes it takes me to the correct position, but other times it takes me to the 2nd note position 🤔 Screen_recording_20260325_193257.mp4 |
The scroll target was computed from the element's DOM offset alone, ignoring the header and padding above the WebView. This caused the page to land too high—sometimes on the wrong footnote reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
I was unable to reproduce this, but I asked Claude to look into it and it found and fixed a bug. Can you give this another round? |
…-footnotes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Unfortunately, I am still able to reproduce it using my Pixel 6 physical device. Coulr you try these steps?
|
requestFocusNodeHref reads from a hit-test cache that is populated asynchronously. When the user taps quickly after scrolling, the cache can still hold the URL from the previous footnote tap, causing navigation to the wrong back-reference. Use evaluateJavascript with document.elementFromPoint instead: it resolves the anchor href from the actual tap coordinates at the moment of the click, eliminating the stale-data race. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous approach (elementFromPoint) failed because WebView viewport coordinates don't map reliably to touch coordinates when the WebView is inside a ScrollView. Instead, inject a capturing JS click listener after page load that intercepts taps on anchor elements with fragment hrefs and routes them through the existing wvHandler.postMessage bridge. This sees the actual DOM element that was clicked — no coordinate mapping and no stale hit-test cache. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove scrollToFragmentOrOpenUrl and getTopWithinAncestor (both had a single call site) by inlining their bodies. Also remove the extra blank line left behind by the StringUtils import removal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Thanks for the steps - I was able to reproduce this on a physical device. I believe it's fixed now. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## trunk #22733 +/- ##
==========================================
- Coverage 37.41% 37.41% -0.01%
==========================================
Files 2318 2318
Lines 123413 123418 +5
Branches 16754 16755 +1
==========================================
Hits 46180 46180
- Misses 73526 73531 +5
Partials 3707 3707 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…opagation - Only intercept clicks on anchors whose base URL matches the post URL (or bare #fragment hrefs), so external links with fragments are not caught unnecessarily. - Remove e.stopPropagation() to avoid suppressing other click listeners (text selection, analytics). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
adalpari
left a comment
There was a problem hiding this comment.
Works great, thank you for the fix!
🚢 it!





Description
Closes CMM-1098
Fixes footnote links in Reader posts opening in the external browser instead of scrolling to the footnote within the post.
WordPress footnote links resolve to the post's own URL with a fragment identifier (e.g.,
https://example.com/post/#fn-id). The Reader was treating these as external links because they passed theisValidClickedUrlhttp check without being recognized as same-page anchors.Testing instructions
Back-reference scrolling:
External links still work:
footnote.mp4