summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-07-23 22:32:14 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-23 22:32:14 +0000
commitab392e2ab983a4c87e241b457c98244251b2206a (patch)
tree706d82f65760ba130a705283bc90a7a431ac9a10 /app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt
parentecdb45778e274126737aa87e27ed1b1c00cda01c (diff)
Strip <header> chrome before Readability parses; show full article title in reader content
- Confirmed live (Ars Technica): a section-kicker badge, the dek/subhead, and an orphaned duplicate hero-image caption were all leaking into extracted content because they live in a <header> Readability doesn't exclude by tag, only deprioritizes in scoring. Strip <header> from the DOM ourselves before handing off to Readability -- a pre-processing decision on our side, not a change to Readability's own algorithm, per instruction not to touch it. - Render the article's full title as a heading at the top of the reader content itself (wrapReaderHtml), not just the top bar, which truncates to one line. This also replaces whatever heading Readability happened to keep in-body, now that <header> (and any <h1> inside it) is stripped pre-parse. - Bump extraction timeout 15s -> 25s: confirmed live, several heavy real-world pages were timing out before onPageFinished ever fired, well short of a real parsing failure. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt')
-rw-r--r--app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt17
1 files changed, 15 insertions, 2 deletions
diff --git a/app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt b/app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt
index 503f71e..f95dfed 100644
--- a/app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt
+++ b/app/src/main/java/org/terst/feedreader/ui/ReaderWebView.kt
@@ -28,14 +28,27 @@ fun newReaderWebView(context: Context, onOpenLink: (String) -> Unit): WebView =
}
}
+private fun escapeHtml(text: String): String = text
+ .replace("&", "&amp;")
+ .replace("<", "&lt;")
+ .replace(">", "&gt;")
+ .replace("\"", "&quot;")
+ .replace("'", "&#39;")
+
// Hardcoded dark palette, not @media (prefers-color-scheme) -- the app itself always
// forces dark colorScheme() regardless of system setting (see MainActivity), so reader
// content should match rather than following a system light/dark the app itself ignores.
-fun wrapReaderHtml(bodyContent: String): String = """
+//
+// title is rendered here, as a real heading at the top of the content, rather than relying
+// on whatever heading Readability happened to keep in bodyContent (increasingly nothing --
+// see ReaderExtractor's <header> stripping) or on the top app bar's title, which truncates
+// to one line and was the only place a long title showed up before this.
+fun wrapReaderHtml(bodyContent: String, title: String? = null): String = """
<html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: sans-serif; font-size: 18px; line-height: 1.5; padding: 16px;
background-color: #121212; color: #e1e1e1; }
+ h1.article-title { font-size: 1.5em; line-height: 1.3; margin: 0 0 0.6em 0; }
a { color: #8ab4f8; }
img { max-width: 100%; height: auto; }
svg { max-width: 100%; }
@@ -49,5 +62,5 @@ fun wrapReaderHtml(bodyContent: String): String = """
those alone -- just cap the ones that would otherwise size themselves. */
svg:not([width]):not([height]) { max-width: 32px; max-height: 32px; }
</style></head>
- <body>$bodyContent</body></html>
+ <body>${if (!title.isNullOrBlank()) "<h1 class=\"article-title\">${escapeHtml(title)}</h1>" else ""}$bodyContent</body></html>
""".trimIndent()