1
0
mirror of https://github.com/aureliendavid/rsspreview.git synced 2025-08-23 03:38:44 +00:00

Merge pull request #10 from glhrmv/master

General code format changes (+ readme update)
This commit is contained in:
A. David 2018-12-19 09:47:45 +01:00 committed by GitHub
commit 1e65cb4c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 168 additions and 221 deletions

View File

@ -1,6 +1,9 @@
# rsspreview
Firefox has removed support for RSS in versions 64+.
This includes the feed preview feature that was quite useful for some people.
This extension attempts to recreate it.
Download at: https://addons.mozilla.org/en-US/firefox/addon/rsspreview/

View File

@ -1,22 +1,21 @@
function detectFeed(event) {
// force application/rss+xml to text/xml so the browser displays it instead of downloading
let isfeed = false;
var isfeed = false;
for (var header of event.responseHeaders) {
if (header.name.toLowerCase() == "content-type") {
header.value = header.value.replace(/application\/(rss|atom)\+xml/,'text/xml');
for (let header of event.responseHeaders) {
if (header.name.toLowerCase() == 'content-type') {
header.value = header.value.replace(
/application\/(rss|atom)\+xml/,
'text/xml'
);
isfeed = true;
break;
}
}
if (isfeed) {
for (var i = 0; i < event.responseHeaders.length; i++) {
if (event.responseHeaders[i].name.toLowerCase() == "cache-control") {
for (let i = 0; i < event.responseHeaders.length; i++) {
if (event.responseHeaders[i].name.toLowerCase() == 'cache-control') {
event.responseHeaders.splice(i, 1);
break;
}
@ -24,20 +23,19 @@ function detectFeed(event) {
// don't cache requests we modified
// otherwise on reload the content-type won't be modified again
event.responseHeaders.push({ name : "Cache-Control", value : "no-cache, no-store, must-revalidate" });
event.responseHeaders.push({
name: 'Cache-Control',
value: 'no-cache, no-store, must-revalidate',
});
}
return {
responseHeaders: event.responseHeaders
};
return { responseHeaders: event.responseHeaders };
}
const browser = window.browser || window.chrome;
browser.webRequest.onHeadersReceived.addListener(
detectFeed,
{ urls: ["<all_urls>"], types: ["main_frame"] },
["blocking", "responseHeaders"]
)
{ urls: ['<all_urls>'], types: ['main_frame'] },
['blocking', 'responseHeaders']
);

View File

@ -1,5 +1,3 @@
html {
font: 3mm tahoma,arial,helvetica,sans-serif;
background-color: rgb(240, 240, 240);
@ -53,8 +51,6 @@ a[href] img {
margin-bottom: 0;
}
#feedTitleContainer {
margin-inline-start: 0;
margin-inline-end: .6em;

View File

@ -5,297 +5,253 @@
* it will do nothing next time.
*/
if (window.hasRun) {
console.log("already run");
console.log('already run');
return;
}
window.hasRun = true;
var xml_parser = new XMLSerializer();
var html_parser = new DOMParser();
let xml_parser = new XMLSerializer();
let html_parser = new DOMParser();
function xhrdoc(url, type, cb) {
var xhr = new XMLHttpRequest();
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'document';
xhr.overrideMimeType('text/' + type);
xhr.onload = function () {
xhr.onload = () => {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200) {
var resp = (type=="xml") ? xhr.responseXML : xhr.response;
let resp = type == 'xml' ? xhr.responseXML : xhr.response;
cb(resp);
}
}
};
xhr.send(null);
}
function applyxsl(xmlin, xsl, node, doc=document) {
var xsltProcessor = new XSLTProcessor();
function applyxsl(xmlin, xsl, node, doc = document) {
let xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
var fragment = xsltProcessor.transformToFragment(xmlin, doc);
let fragment = xsltProcessor.transformToFragment(xmlin, doc);
node.appendChild(fragment);
}
function getlang() {
if (navigator.languages && navigator.languages[0])
return navigator.languages[0];
else if (navigator.language)
return navigator.language;
else
return null;
else if (navigator.language) return navigator.language;
else return null;
}
function formatsubtitle() {
try {
var feed_desc = document.getElementById("feedSubtitleRaw");
let feed_desc = document.getElementById('feedSubtitleRaw');
var html_desc = html_parser.parseFromString('<h2 id="feedSubtitleText">'+feed_desc.innerText+'</h2>', "text/html");
var xml_desc = xml_parser.serializeToString(html_desc.body.firstChild);
let html_desc = html_parser.parseFromString(
'<h2 id="feedSubtitleText">' + feed_desc.innerText + '</h2>',
'text/html'
);
let xml_desc = xml_parser.serializeToString(html_desc.body.firstChild);
feed_desc.insertAdjacentHTML('afterend', xml_desc);
feed_desc.parentNode.removeChild(feed_desc);
}
catch (e) {
} catch (e) {
console.error(e);
console.log(feed_desc.innerText);
}
}
function formatdescriptions(el=document) {
function formatdescriptions(el = document) {
// unescapes descriptions to html then to xml
let tohtml = el.getElementsByClassName('feedRawContent');
var tohtml = el.getElementsByClassName("feedRawContent");
for (var i = 0; i<tohtml.length; i++) {
for (let i = 0; i < tohtml.length; i++) {
// in case of xhtml the content is already parsed
if (tohtml[i].getAttribute("desctype") != "xhtml") {
if (tohtml[i].getAttribute('desctype') != 'xhtml') {
try {
var html_desc = html_parser.parseFromString('<div class="feedEntryContent">'+tohtml[i].innerText+'</div>', "text/html");
var xml_desc = xml_parser.serializeToString(html_desc.body.firstChild);
let html_desc = html_parser.parseFromString(
'<div class="feedEntryContent">' + tohtml[i].innerText + '</div>',
'text/html'
);
let xml_desc = xml_parser.serializeToString(
html_desc.body.firstChild
);
tohtml[i].insertAdjacentHTML('afterend', xml_desc);
tohtml[i].setAttribute("todel", 1);
}
catch (e) {
tohtml[i].setAttribute('todel', 1);
} catch (e) {
console.error(e);
console.log(tohtml[i].innerHTML);
}
}
}
el.querySelectorAll('.feedRawContent').forEach(function(a){
if (a.getAttribute("todel") == "1") {
el.querySelectorAll('.feedRawContent').forEach(a => {
if (a.getAttribute('todel') == '1') {
a.remove();
} else if (a.getAttribute('desctype') == 'xhtml') {
a.classList.add('feedEntryContent');
a.classList.remove('feedRawContent');
}
else if (a.getAttribute("desctype") == "xhtml") {
a.classList.add("feedEntryContent");
a.classList.remove("feedRawContent");
}
})
});
}
function removeemptyenclosures(el = document) {
let encs = el.getElementsByClassName('enclosures');
function removeemptyenclosures(el=document) {
var encs = el.getElementsByClassName("enclosures");
for (var i = 0; i<encs.length; i++) {
if (!encs[i].firstChild)
encs[i].style.display = "none";
for (let i = 0; i < encs.length; i++)
if (!encs[i].firstChild) encs[i].style.display = 'none';
}
}
function formatfilenames(el = document) {
let encfn = el.getElementsByClassName('enclosureFilename');
function formatfilenames(el=document) {
for (let i = 0; i < encfn.length; i++) {
let url = new URL(encfn[i].innerText);
var encfn = el.getElementsByClassName("enclosureFilename");
for (var i = 0; i<encfn.length; i++) {
var url = new URL(encfn[i].innerText);
if (url) {
var fn = url.pathname.split("/").pop();
if (fn != "") {
encfn[i].innerText = fn;
let fn = url.pathname.split('/').pop();
if (fn != '') encfn[i].innerText = fn;
}
}
}
}
}
function formatfilesizes(el=document) {
function formatfilesizes(el = document) {
function humanfilesize(size) {
var i = 0;
if (size && size != "" && size > 0)
i = Math.floor( Math.log(size) / Math.log(1024) );
return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
};
let i = 0;
var encsz = el.getElementsByClassName("enclosureSize");
for (var i = 0; i<encsz.length; i++) {
var hsize = humanfilesize(encsz[i].innerText);
if (hsize) {
encsz[i].innerText = hsize;
if (size && size != '' && size > 0)
i = Math.floor(Math.log(size) / Math.log(1024));
return (
(size / Math.pow(1024, i)).toFixed(2) * 1 +
' ' +
['B', 'kB', 'MB', 'GB', 'TB'][i]
);
}
let encsz = el.getElementsByClassName('enclosureSize');
for (let i = 0; i < encsz.length; i++) {
let hsize = humanfilesize(encsz[i].innerText);
if (hsize) encsz[i].innerText = hsize;
}
}
function formattitles(el = document) {
let et = el.getElementsByClassName('entrytitle');
function formattitles(el=document) {
var et = el.getElementsByClassName("entrytitle");
for (var i = 0; i<et.length; i++) {
for (let i = 0; i < et.length; i++) {
//basically removes html content if there is some
//only do it if there's a tag to avoid doing it when text titles cointain a '&'
//(which can be caught but still displays an error in console, which is annoying)
if (et[i].innerText.indexOf('<') >= 0) {
var tmp = document.createElement("span");
let tmp = document.createElement('span');
try {
tmp.innerHTML = et[i].innerText;
et[i].innerText = tmp.textContent;
}
catch (e) {
} catch (e) {
console.error(e);
console.log(et[i].innerText);
}
}
}
}
}
function formatdates(el = document) {
let lang = getlang();
if (!lang) return;
}
let opts = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
};
let ed = el.getElementsByClassName('lastUpdated');
for (let i = 0; i < ed.length; i++) {
let d = new Date(ed[i].innerText);
if (isNaN(d)) continue;
let dstr =
d.toLocaleDateString(lang, opts) + ' ' + d.toLocaleTimeString(lang);
function formatdates(el=document) {
var lang = getlang();
if (!lang)
return;
var opts = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
var ed = el.getElementsByClassName("lastUpdated");
for (var i = 0; i<ed.length; i++) {
var d = new Date(ed[i].innerText);
if (isNaN(d))
continue;
var dstr = d.toLocaleDateString(lang, opts) + ' ' + d.toLocaleTimeString(lang);
ed[i].innerText = dstr;
}
}
}
function extensionimages(el=document) {
var extimgs = el.getElementsByClassName("extImg");
for (var i = 0; i<extimgs.length; i++) {
extimgs[i].src = chrome.extension.getURL(extimgs[i].attributes['data-src'].nodeValue);
}
function extensionimages(el = document) {
let extimgs = el.getElementsByClassName('extImg');
for (let i = 0; i < extimgs.length; i++)
extimgs[i].src = chrome.extension.getURL(
extimgs[i].attributes['data-src'].nodeValue
);
}
function makepreviewhtml() {
let doc = document.implementation.createHTMLDocument('');
var doc = document.implementation.createHTMLDocument("");
var feedBody = doc.createElement("div");
feedBody.id = "feedBody";
let feedBody = doc.createElement('div');
feedBody.id = 'feedBody';
doc.body.appendChild(feedBody);
var css = doc.createElement('link');
let css = doc.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute('href', chrome.extension.getURL("preview.css"));
css.setAttribute('href', chrome.extension.getURL('preview.css'));
doc.head.appendChild(css);
return doc;
}
function detect() {
var rootNode = document.getRootNode().documentElement;
let rootNode = document.getRootNode().documentElement;
// for chrome
var d = document.getElementById("webkit-xml-viewer-source-xml");
if (d && d.firstChild)
rootNode = d.firstChild;
let d = document.getElementById('webkit-xml-viewer-source-xml');
if (d && d.firstChild) rootNode = d.firstChild;
const rootName = rootNode.nodeName.toLowerCase();
let isRSS1 = false;
var isRSS1 = false;
if (rootName == "rdf" || rootName == "rdf:rdf") {
if (rootNode.attributes['xmlns']) {
isRSS1 = (rootNode.attributes['xmlns'].nodeValue.search('rss') > 0)
}
}
if ( rootName == "rss" || rootName == "channel" // rss2
|| rootName == "feed" // atom
|| isRSS1 ) {
if (rootName == 'rdf' || rootName == 'rdf:rdf')
if (rootNode.attributes['xmlns'])
isRSS1 = rootNode.attributes['xmlns'].nodeValue.search('rss') > 0;
if (
rootName == 'rss' ||
rootName == 'channel' || // rss2
rootName == 'feed' || // atom
isRSS1
)
return rootNode;
}
return null;
}
function main(feedNode) {
let feed_url = window.location.href;
let preview = makepreviewhtml();
var feed_url = window.location.href;
var preview = makepreviewhtml();
xhrdoc(chrome.extension.getURL("rss.xsl"), "xml", function(xsl_xml) {
applyxsl(feedNode, xsl_xml, preview.getElementById("feedBody"), preview);
xhrdoc(chrome.extension.getURL('rss.xsl'), 'xml', xsl_xml => {
applyxsl(feedNode, xsl_xml, preview.getElementById('feedBody'), preview);
// replace the content with the preview document
document.replaceChild(document.importNode(preview.documentElement, true), document.documentElement);
document.replaceChild(
document.importNode(preview.documentElement, true),
document.documentElement
);
var t0 = performance.now();
let t0 = performance.now();
formatsubtitle();
@ -307,20 +263,14 @@
formatdates();
extensionimages();
var t1 = performance.now();
let t1 = performance.now();
//console.log("exec in: " + (t1 - t0) + "ms");
document.title = document.getElementById("feedTitleText").innerText;
document.title = document.getElementById('feedTitleText').innerText;
});
}
var feedRoot = detect();
if (feedRoot)
main(feedRoot);
let feedRoot = detect();
if (feedRoot) main(feedRoot);
})();