diff options
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/readability')
| -rw-r--r-- | app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt b/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt index f9adbb4..3cb4741 100644 --- a/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt +++ b/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt @@ -180,23 +180,70 @@ object ReaderExtractor { } } + // A YouTube iframe embed is dead weight here -- JS is off in the WebView + // that actually displays this content, so the real embedded player could + // never initialize anyway (just a blank/broken box). Swap it for a + // tap-to-open thumbnail (a real <img>, which Readability treats like any + // other content image) linking to the video -- newReaderWebView sends a + // YouTube watch link straight to the YouTube app/browser instead of our + // own article-extraction pipeline, since there's no article to extract + // from a video page. + var iframes = document.querySelectorAll( + 'iframe[src*="youtube.com/embed/"], iframe[src*="youtube-nocookie.com/embed/"]' + ); + for (var i = 0; i < iframes.length; i++) { + var frame = iframes[i]; + var match = frame.getAttribute('src').match(/embed\/([a-zA-Z0-9_-]+)/); + if (!match) continue; + var videoId = match[1]; + var link = document.createElement('a'); + link.className = 'yt-embed'; + link.href = 'https://www.youtube.com/watch?v=' + videoId; + var thumb = document.createElement('img'); + thumb.src = 'https://i.ytimg.com/vi/' + videoId + '/hqdefault.jpg'; + thumb.alt = 'YouTube video'; + var play = document.createElement('span'); + play.className = 'yt-play'; + link.appendChild(thumb); + link.appendChild(play); + frame.parentNode.replaceChild(link, frame); + } + // A news/blog article page's <header> conventionally holds everything // BEFORE the real body: a section/category kicker, the dek/subhead, the - // byline, and the hero image + its caption. Readability doesn't exclude - // <header> by tag outright (only deprioritizes it in scoring), so on - // some articles enough of it scores highly enough to get pulled in + // byline, and the hero image + its caption. <footer> (site nav/link + // menus) is the same story at the other end. Readability doesn't exclude + // either by tag outright (only deprioritizes them in scoring), so on + // some articles enough of one scores highly enough to get pulled in // alongside the real body -- confirmed live: a kicker icon, the dek // paragraph, AND an orphaned duplicate hero-image caption (a mobile-only - // copy with no adjacent <img> at all) all leaking in above the real - // lede on an Ars Technica article. This is a pre-processing decision on - // our side, not a change to Readability's own algorithm: treat <header> - // as page chrome, never article content, and remove it before Readability - // ever sees the page. (The article's actual title is shown separately -- - // see ReaderWebView.wrapReaderHtml -- so losing the in-body <h1> here is - // fine, it was never meant to double as the body text anyway.) - var headers = document.querySelectorAll('header'); - for (var i = 0; i < headers.length; i++) { - headers[i].parentNode.removeChild(headers[i]); + // copy with no adjacent <img> at all) all leaking in above the real lede + // on an Ars Technica article. This is a pre-processing decision on our + // side, not a change to Readability's own algorithm: treat <header>/ + // <footer> as page chrome, never article content, and remove them before + // Readability ever sees the page. (The article's actual title is shown + // separately -- see ReaderWebView.wrapReaderHtml -- so losing the in-body + // <h1> here is fine, it was never meant to double as the body text.) + var chrome = document.querySelectorAll('header, footer'); + for (var i = 0; i < chrome.length; i++) { + chrome[i].parentNode.removeChild(chrome[i]); + } + + // Two more sibling widgets confirmed live, same "not article content" + // story: an author bio card (photo + name + one-paragraph bio, after the + // real body -- its photo has the same Tailwind-dependent absolute-fill + // styling as the section-badge icon and hero image, so it'd render + // oversized for the same underlying reason even if kept) and a "Most + // Read"/trending-stories widget (a list of OTHER articles' thumbnails -- + // confirmed live: one showed up as a giant unrelated photo followed by an + // empty numbered list, since the widget's later items only populate their + // thumbnail on scroll-into-view, which never happens in this hidden, + // off-screen extraction WebView). + var sequels = document.querySelectorAll( + '[class*="author-mini-bio" i], [class*="author-bio" i], [class*="most-read" i]' + ); + for (var i = 0; i < sequels.length; i++) { + if (sequels[i].parentNode) sequels[i].parentNode.removeChild(sequels[i]); } // Readability's default hidden-element skip (treating display:none / |
