From e8f697ade21738b6f3f6044b0aa96f1de028ff33 Mon Sep 17 00:00:00 2001 From: Jon Banafato Date: Sat, 26 Oct 2019 21:26:01 -0400 Subject: [PATCH] Add support for domain-specific feed detection Refactor the `findFeeds` function to allow easy addition of custom finder functions. This change does three things: 1. Breaks the iTunes and standard feed detection logic into their own respective functions 2. Adds a YouTube feed detection function 3. Creates a mapping to support custom feed detection functions for additional domains Fixes #34. --- rsspreview.js | 128 +++++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 58 deletions(-) diff --git a/rsspreview.js b/rsspreview.js index 97cdbbe..939fd19 100644 --- a/rsspreview.js +++ b/rsspreview.js @@ -336,29 +336,68 @@ getting.then(onOptions, onError); - function findFeeds() { - - let feeds = {}; - - function registerFeeds(feeds) { - - if (Object.keys(feeds).length > 0) { - - function handleResponse(message) { - } - - function handleError(error) { - //console.log(error); - } - - browser.runtime.sendMessage(feeds).then(handleResponse, handleError); + function registerFeeds(feeds) { + if (Object.keys(feeds).length > 0) { + function handleResponse(message) { } + + function handleError(error) { + //console.log(error); + } + + browser.runtime.sendMessage(feeds).then(handleResponse, handleError); } + } - var async_send = false; + function findiTunesPodcastsFeeds() { + let match = document.URL.match(/id(\d+)/) + if (match) { + let feeds = {}; + let itunesid = match[1]; + + var xhr = new XMLHttpRequest(); + xhr.open('GET', "https://itunes.apple.com/lookup?id="+itunesid+"&entity=podcast"); + + xhr.onload = function () { + if (xhr.readyState === xhr.DONE) { + if (xhr.status === 200) { + let res = JSON.parse(xhr.responseText); + + if ("results" in res) { + let pod = res["results"][0]; + let title = pod["collectionName"] || document.title; + let url = pod["feedUrl"]; + if (url) { + feeds[url] = title; + } + } + } + } + + registerFeeds(feeds); + }; + xhr.send(); + } + } + + function findYouTubeFeeds() { + let match = document.URL.match(/channel\/([a-zA-Z0-9]+)/); + if (match) { + let feeds = {}; + let channelId = match[1]; + let url = `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}`; + let title = document.title; + feeds[url] = title; + registerFeeds(feeds); + } + } + + // The default function used to find feeds if a domain-specific function doesn't exist. + // Parse the document's HTML looking for link tags pointing to the feed URL. + function defaultFindFeeds() { + let feeds = {}; document.querySelectorAll("link[rel='alternate']").forEach( (elem) => { - let type_attr = elem.getAttribute('type'); if (!type_attr) { return; @@ -366,55 +405,28 @@ let type = type_attr.toLowerCase(); if (type.includes('rss') || type.includes('atom') || type.includes('feed')) { - let title = elem.getAttribute('title'); let url = elem.href; if (url) { - feeds[url] = (title ? title : url); - } } }); - - if (document.domain == "itunes.apple.com" || document.domain == "podcasts.apple.com") { - - let match = document.URL.match(/id(\d+)/) - if (match) { - let itunesid = match[1]; - - var xhr = new XMLHttpRequest(); - xhr.open('GET', "https://itunes.apple.com/lookup?id="+itunesid+"&entity=podcast"); - - xhr.onload = function () { - if (xhr.readyState === xhr.DONE) { - if (xhr.status === 200) { - let res = JSON.parse(xhr.responseText); - - if ("results" in res) { - - let pod = res["results"][0]; - let title = pod["collectionName"] || document.title; - let url = pod["feedUrl"]; - if (url) { - feeds[url] = title; - } - } - } - } - - registerFeeds(feeds); - }; - async_send = true; - xhr.send(); - } - } - - if (!async_send) - registerFeeds(feeds); - + registerFeeds(feeds); } + const domainFeedFinders = new Map([ + ["itunes.apple.com", findiTunesPodcastsFeeds], + ["podcasts.apple.com", findiTunesPodcastsFeeds], + ["www.youtube.com", findYouTubeFeeds], + ]); + + function findFeeds() { + // Look up a feed detection function based on the domain. + // If a domain-specific function doesn't exist, fall back to a default. + let finder = domainFeedFinders.get(document.domain) || defaultFindFeeds; + finder(); + } })();