package org.terst.feedreader.ui import android.content.Context import android.view.View import android.webkit.WebResourceRequest import android.webkit.WebView import android.webkit.WebViewClient /** * Shared factory for the read-only, dark-themed article WebView used by both the * per-article ReaderScreen and LinkReaderScreen (for links tapped inside an article). * JS is always off -- extracted/feed HTML never needs it, and this keeps articles * from running arbitrary scripts. Link taps are intercepted rather than left to * WebView's default behavior (handing off to the system browser) so following a * link stays inside the app's own reader/extraction pipeline. */ fun newReaderWebView(context: Context, onOpenLink: (String) -> Unit): WebView = WebView(context).apply { settings.javaScriptEnabled = false overScrollMode = View.OVER_SCROLL_NEVER isVerticalScrollBarEnabled = false isHorizontalScrollBarEnabled = false webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { onOpenLink(request.url.toString()) return true } } } private fun escapeHtml(text: String): String = text .replace("&", "&") .replace("<", "<") .replace(">", ">") .replace("\"", """) .replace("'", "'") // 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. // // 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
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 = """ ${if (!title.isNullOrBlank()) "

${escapeHtml(title)}

" else ""}$bodyContent """.trimIndent()