RSSHub-Radar/src/js/content/utils.js

121 lines
4.4 KiB
JavaScript

import RSSParser from 'rss-parser';
const rssParser = new RSSParser();
let pageRSS = null;
const defaultTitle =
document.querySelector('title') &&
document.querySelector('title').innerHTML &&
document
.querySelector('title')
.innerHTML.replace(/<!\[CDATA\[(.*)]]>/, (match, p1) => p1)
.trim();
const image = (document.querySelector('link[rel~="icon"]') && handleUrl(document.querySelector('link[rel~="icon"]').getAttribute('href'))) || document.location.origin + '/favicon.ico';
function handleUrl(url) {
return new URL(url, document.location.href).toString();
}
export function getPageRSS() {
if (!pageRSS) {
pageRSS = [];
const unique = {
data: {},
save: function (url) {
this.data[url.replace(/^(https?:)?\/\//, '')] = 1;
},
check: function (url) {
return this.data[url.replace(/^(https?:)?\/\//, '')];
},
};
// links
const types = [
'application/rss+xml',
'application/atom+xml',
'application/rdf+xml',
'application/rss',
'application/atom',
'application/rdf',
'text/rss+xml',
'text/atom+xml',
'text/rdf+xml',
'text/rss',
'text/atom',
'text/rdf',
'application/feed+json',
];
const links = document.querySelectorAll('link[type]');
for (let i = 0; i < links.length; i++) {
if (links[i].hasAttribute('type') && types.indexOf(links[i].getAttribute('type')) !== -1) {
const feed_url = links[i].getAttribute('href');
if (feed_url) {
const feed = {
url: handleUrl(feed_url),
title: links[i].getAttribute('title') || defaultTitle,
image,
};
if (!unique.check(feed.url)) {
pageRSS.push(feed);
unique.save(feed.url);
}
}
}
}
// a
const aEles = document.querySelectorAll('a');
const check = /([^a-zA-Z]|^)rss([^a-zA-Z]|$)/i;
for (let i = 0; i < aEles.length; i++) {
if (aEles[i].hasAttribute('href')) {
const href = aEles[i].getAttribute('href');
if (
href.match(/\/(feed|rss|atom)(\.(xml|rss|atom))?\/?$/) ||
(aEles[i].hasAttribute('title') && aEles[i].getAttribute('title').match(check)) ||
(aEles[i].hasAttribute('class') && aEles[i].getAttribute('class').match(check)) ||
(aEles[i].innerText && aEles[i].innerText.match(check))
) {
const feed = {
url: handleUrl(href),
title: aEles[i].innerText || aEles[i].getAttribute('title') || defaultTitle,
image,
uncertain: 1,
};
if (!unique.check(feed.url)) {
pageRSS.push(feed);
unique.save(feed.url);
}
}
}
}
// whole page
if (!unique.check(document.location.href)) {
let html;
if (document.body && document.body.childNodes && document.body.childNodes.length === 1 && document.body.childNodes[0].tagName && document.body.childNodes[0].tagName.toLowerCase()) {
html = document.body.childNodes[0].innerText;
} else if (document.querySelector('#webkit-xml-viewer-source-xml')) {
html = document.querySelector('#webkit-xml-viewer-source-xml').innerHTML;
}
if (html) {
rssParser.parseString(html, (err, result) => {
if (!err) {
chrome.runtime.sendMessage(null, {
text: 'addPageRSS',
feed: {
url: document.location.href,
title: result.title,
image,
},
});
}
});
}
}
unique.save(document.location.href);
}
return pageRSS;
}