summaryrefslogtreecommitdiff
path: root/app/src/main/java/org/terst/feedreader/readability
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/org/terst/feedreader/readability')
-rw-r--r--app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt64
1 files changed, 51 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 3cb4741..9a96e63 100644
--- a/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt
+++ b/app/src/main/java/org/terst/feedreader/readability/ReaderExtractor.kt
@@ -180,6 +180,17 @@ object ReaderExtractor {
}
}
+ // Some sites lazy-load the embed iframe itself, not just images --
+ // leaving `src` blank or a generic loader URL until their own script
+ // runs, which never happens here. Resolve iframe data-src first (same
+ // idea as the image lazy-load fix above) so the YouTube detection below
+ // has a real URL to work with instead of nothing.
+ var lazyFrames = document.querySelectorAll('iframe[data-src], iframe[data-lazy-src]');
+ for (var i = 0; i < lazyFrames.length; i++) {
+ var lazyFrameSrc = lazyFrames[i].getAttribute('data-src') || lazyFrames[i].getAttribute('data-lazy-src');
+ if (lazyFrameSrc) lazyFrames[i].setAttribute('src', lazyFrameSrc);
+ }
+
// 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
@@ -193,20 +204,47 @@ object ReaderExtractor {
);
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 frameSrc = frame.getAttribute('src') || '';
+ // A real video ID is always exactly 11 chars -- a playlist/live
+ // embed's path is literally ".../embed/videoseries?list=...", which
+ // (coincidentally exactly 11 characters itself) previously slipped
+ // past a length-only check and built a thumbnail URL for a video
+ // that doesn't exist (confirmed live: rendered as a broken-image
+ // glyph, not a still frame -- exactly what was reported).
+ var match = frameSrc.match(/embed\/([a-zA-Z0-9_-]{11})(?:[/?]|$)/);
+ if (match && match[1] === 'videoseries') match = null;
+ // Neither a class NOR an inline style survives here -- Readability
+ // strips both as part of its own cleanup. A bare <a><img></a> with
+ // no surrounding text didn't survive either, for a different reason:
+ // Readability's link-density cleanup treats a node that's almost
+ // entirely inside an <a> as a probable ad/share-button unit and
+ // discards it (confirmed live: the iframe was there, the transform
+ // ran, and the result still vanished from the final extracted
+ // content). A <figure>/<figcaption> pair -- the exact shape a normal
+ // captioned photo takes, which reliably survives elsewhere in this
+ // pipeline -- with the caption text OUTSIDE the link keeps the
+ // node's link-density low enough to read as real content.
+ var figure = document.createElement('figure');
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);
+ figure.appendChild(link);
+ if (match) {
+ var videoId = match[1];
+ 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';
+ link.appendChild(thumb);
+ var caption = document.createElement('figcaption');
+ caption.textContent = '▶ Watch on YouTube';
+ figure.appendChild(caption);
+ } else {
+ // No confident single video ID (a playlist, a live stream, or
+ // lazy-load resolution above still came up empty) -- a plain
+ // link beats a broken thumbnail or a dead iframe.
+ link.href = frameSrc || 'https://www.youtube.com/';
+ link.textContent = 'Watch on YouTube';
+ }
+ frame.parentNode.replaceChild(figure, frame);
}
// A news/blog article page's <header> conventionally holds everything