From 6373c34525fdac3a298ab5e0299080383b72aaf6 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Thu, 30 Jul 2026 01:04:19 +0000 Subject: Merge Ars Technica's split .post-content blocks before Readability scores them Ars splits a longer article's body across multiple sibling .post-content.post-content-double divs (with a mid-content ad rail between them) instead of one continuous container. Readability scores each as an independent candidate and keeps only the highest-scoring one, silently dropping the rest -- confirmed live on "Reaction wheel failures leave Swift rescue mission spinning in orbit", which lost its first 7 paragraphs (lede through the reaction-wheel explainer). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_017Zwte3cyUJFUVycc3sDmjM --- .../feedreader/readability/ReaderExtractor.kt | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'app/src/main/java/org/terst/feedreader/readability') 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 9a96e63..1edef0e 100644 --- a/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt +++ b/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt @@ -247,6 +247,29 @@ object ReaderExtractor { frame.parentNode.replaceChild(figure, frame); } + // Ars Technica splits a longer article's body across MULTIPLE sibling + // ".post-content.post-content-double" divs -- each its own separate grid + // row, with a full mid-content ad rail sitting between them -- rather than + // keeping one continuous content container. Readability scores each as an + // independent candidate and keeps only the highest-scoring one, silently + // dropping the rest (confirmed live: "Reaction wheel failures leave Swift + // rescue mission spinning in orbit" lost its first .post-content entirely -- + // exactly its lede through the reaction-wheel explainer, 7 paragraphs -- + // while the second block, continuing the story, came through fine). Merge + // every such div's children into the first one before Readability ever sees + // the page, so it scores one complete candidate instead of splitting its + // vote across several partial ones. + var splitBlocks = document.querySelectorAll('.post-content.post-content-double'); + if (splitBlocks.length > 1) { + var mergeTarget = splitBlocks[0]; + for (var i = 1; i < splitBlocks.length; i++) { + while (splitBlocks[i].firstChild) { + mergeTarget.appendChild(splitBlocks[i].firstChild); + } + splitBlocks[i].parentNode.removeChild(splitBlocks[i]); + } + } + // A news/blog article page's
conventionally holds everything // BEFORE the real body: a section/category kicker, the dek/subhead, the // byline, and the hero image + its caption.