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 | 39 |
1 files changed, 26 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 28c762c..7e8e10c 100644 --- a/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt +++ b/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt @@ -69,16 +69,29 @@ object ReaderExtractor { val script = """ (function() { try { - // Some "soft" paywalls deliver the full article in the initial HTML - // response to every visitor, then hide it with CSS (inline or via a - // stylesheet rule) pending a client-side subscription check -- the - // content itself isn't withheld by the server, only its visibility is. - // Readability has a built-in heuristic that skips anything hidden this - // way (treating it as boilerplate to discard), which is exactly what - // was throwing away real, already-delivered article text and leaving - // only the visible teaser/subscribe prompt. Un-hide before extracting -- - // this must run on the live document (getComputedStyle needs a node - // attached to the render tree), so it happens before the clone below. + $readabilityJs + function plainLength(article) { + return (article && article.textContent) ? article.textContent.trim().length : 0; + } + + // Readability's default hidden-element skip (treating display:none / + // visibility:hidden nodes as boilerplate) is correct for the vast + // majority of sites -- it's what keeps collapsed nav/footer/sidebar + // chrome out of the result. Try it first, unmodified. + var normalArticle = new Readability(document.cloneNode(true)).parse(); + if (plainLength(normalArticle) >= 500) { + return JSON.stringify(normalArticle); + } + + // Only reached when the normal pass came back thin. Some "soft" + // paywalls deliver the full article in the initial HTML response to + // every visitor, then hide it with CSS (inline or via a stylesheet + // rule) pending a client-side subscription check -- the content isn't + // withheld by the server, only its visibility is, and Readability's + // hidden-element skip discards it the same as any other hidden chrome. + // Un-hide and retry; keep whichever pass actually found more text, + // since un-hiding everything indiscriminately can just as easily pull + // in an unrelated hidden footer/notice on a normal (non-paywalled) page. var all = document.querySelectorAll('*'); for (var i = 0; i < all.length; i++) { var el = all[i]; @@ -88,9 +101,9 @@ object ReaderExtractor { el.style.setProperty('visibility', 'visible', 'important'); } } - $readabilityJs - var article = new Readability(document.cloneNode(true)).parse(); - return JSON.stringify(article); + var unhiddenArticle = new Readability(document.cloneNode(true)).parse(); + var best = plainLength(unhiddenArticle) > plainLength(normalArticle) ? unhiddenArticle : normalArticle; + return JSON.stringify(best); } catch (e) { return JSON.stringify({error: e.toString()}); } |
