Modularize code;
Add packaging instructions; Add modules to handle Gemini file type (no Gemini server yet); Improve handling of configuration.
This commit is contained in:
parent
84e54085b5
commit
766e51af4c
46 changed files with 2359 additions and 663 deletions
8
assets/script/iso8601_to_utc.js
Normal file
8
assets/script/iso8601_to_utc.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Convert ISO8601 To UTC
|
||||
|
||||
window.onload = function(){
|
||||
for (element of document.querySelectorAll('#articles > ul > li > div > h4')) {
|
||||
timestamp = new Date(element.textContent);
|
||||
element.textContent = timestamp.toUTCString();
|
||||
}
|
||||
}
|
6
assets/script/marked.min.js
vendored
Normal file
6
assets/script/marked.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
assets/script/parse_markdown.js
Normal file
7
assets/script/parse_markdown.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
// Parse Markdown
|
||||
|
||||
window.onload = function(){
|
||||
for (element of document.querySelectorAll('#articles > ul > li > div > p')) {
|
||||
element.innerHTML = marked.parse(element.textContent);
|
||||
}
|
||||
}
|
265
assets/script/postprocess.js
Normal file
265
assets/script/postprocess.js
Normal file
|
@ -0,0 +1,265 @@
|
|||
window.onload = async function(){
|
||||
let locationHref = new URL(location.href);
|
||||
let node = locationHref.searchParams.get('node')
|
||||
let pubsub = locationHref.searchParams.get('pubsub')
|
||||
|
||||
// Set button follow
|
||||
let follow = document.querySelector('#follow');
|
||||
if (follow) {
|
||||
//let feedUrl = location.href.replace(/^https?:/, 'feed:');
|
||||
let feedUrl = `feed://${location.host}/atom?pubsub=${pubsub}&node=${node}`;
|
||||
follow.href = feedUrl;
|
||||
follow.type = `application/atom+xml`;
|
||||
follow.addEventListener ('click', function() {
|
||||
window.open(feedUrl, "_self");
|
||||
});
|
||||
// Fix button subtome
|
||||
document.querySelector('#subtome').href='https://www.subtome.com/#/subscribe?feeds=' + feedUrl;
|
||||
}
|
||||
|
||||
// Convert ISO8601 To UTC
|
||||
for (let element of document.querySelectorAll(
|
||||
'#articles > ul > li > div > h4.published,' +
|
||||
'#articles > ul > li > div > h4.updated, ' +
|
||||
'#feed > #header > h2#subtitle.date')) {
|
||||
let timeStamp = new Date(element.textContent);
|
||||
element.textContent = timeStamp.toUTCString();
|
||||
}
|
||||
|
||||
// Parse Markdown
|
||||
for (let element of document.querySelectorAll('#articles div[type="text"]')) {
|
||||
element.innerHTML = marked.parse(element.textContent);
|
||||
}
|
||||
|
||||
// NOTE Report this issue to Movim. See node "deltachat" of pubsub "news.movim.eu".
|
||||
for (let element of document.querySelectorAll('#articles div[type="html"]')) {
|
||||
if (!element.children.length) {
|
||||
element.innerHTML = marked.parse(element.textContent);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
NOTE
|
||||
|
||||
The reason for the following code to parse HTML inside an software which
|
||||
already parses HTML, is that some people who influence the so called Gecko
|
||||
HTML Engine product (mostly people from the advertisement industry with whom
|
||||
I shamefully used to work with) have intentions to eliminate standards and
|
||||
technologies such as Syndication (Atom/RDF/RSS), XSLT and many other
|
||||
technologies that actually empower people and their privacy.
|
||||
|
||||
Recently, some changes were made to the XSLT parser of Gecko which result in
|
||||
noncompliance with the XSLT standard.
|
||||
|
||||
The XSLT feature that was removed is "disable-output-escaping" which upon the
|
||||
value "yes" the XSLT engine should transform and treat a subject string into
|
||||
HTML, yet the Gecko HTML Engine ignores this XSLT direction.
|
||||
|
||||
This change was probably made in order to:
|
||||
* Frustrate new XSLT developers; or
|
||||
* Influence new XSLT developers to think that XSLT has a limited set of
|
||||
features and believing of some sort of inability to parse HTML from a
|
||||
retrieved HTML string; and
|
||||
* Consequently cause developers to abstain from using the XSLT technology.
|
||||
|
||||
Do not use HTML browsers or use Ladybird, Pale Moon or browsers that are
|
||||
powered by KHTML (WebKit) instead of anti-privacy software such as Chromium
|
||||
and Gecko.
|
||||
|
||||
*/
|
||||
|
||||
// Parse HTML
|
||||
//if (navigator.userAgent.includes(') Gecko/')) {
|
||||
// for (let element of document.querySelectorAll('#articles div[type="html"]')) {
|
||||
// element.innerHTML = element.textContent;
|
||||
// }
|
||||
//}
|
||||
for (let element of document.querySelectorAll('#articles div[type="html"]')) {
|
||||
if (!element.children.length) {
|
||||
element.innerHTML = element.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
// Build a journal list
|
||||
if (locationHref.pathname.startsWith('/atom') && pubsub && node && !node.includes('/')) {
|
||||
itemsList = await openJson(pubsub, node)
|
||||
if (itemsList && locationHref.searchParams.get('item')) {
|
||||
let elementDiv = document.createElement('div');
|
||||
elementDiv.id = 'journal';
|
||||
let elementH3 = document.createElement('h3');
|
||||
elementH3.textContent = 'Journal';
|
||||
elementDiv.appendChild(elementH3);
|
||||
let elementH4 = document.createElement('h4');
|
||||
elementH4.textContent = node;
|
||||
elementDiv.appendChild(elementH4);
|
||||
let elementUl = document.createElement('ol');
|
||||
elementDiv.appendChild(elementUl);
|
||||
for (let item of itemsList.reverse()) {
|
||||
let elementLi = document.createElement('li');
|
||||
let elementA = document.createElement('a');
|
||||
elementA.textContent = item.title;
|
||||
elementA.href = item.link;
|
||||
elementLi.appendChild(elementA);
|
||||
elementUl.appendChild(elementLi);
|
||||
console.log(elementLi.length)
|
||||
if (elementUl.children.length > 9) {break};
|
||||
}
|
||||
let elementB = document.createElement('b');
|
||||
elementB.textContent = 'Actions';
|
||||
elementDiv.appendChild(elementB);
|
||||
let elementUl2 = document.createElement('ul');
|
||||
elementDiv.appendChild(elementUl2);
|
||||
links = [
|
||||
{'text' : 'Subscribe from an XMPP client.',
|
||||
'href' : `xmpp:${pubsub}?pubsub;action=subscribe;node=${node}`,
|
||||
'type' : 'x-scheme-handler/xmpp'},
|
||||
{'text' : 'Subscribe with a News Reader.',
|
||||
'href' : `feed://${location.host}/atom?pubsub=${pubsub}&node=${node}`,
|
||||
'type' : 'application/atom+xml'},
|
||||
{'text' : 'Browse the journal.',
|
||||
'href' : `atom?pubsub=${pubsub}&node=${node}`,
|
||||
'type' : 'application/atom+xml'},
|
||||
{'text' : 'Browse the portal.',
|
||||
'href' : `opml?pubsub=${pubsub}`,
|
||||
'type' : 'text/x-opml'}
|
||||
]
|
||||
for (let link of links) {
|
||||
let elementLi = document.createElement('li');
|
||||
let elementA = document.createElement('a');
|
||||
elementA.textContent = link.text;
|
||||
elementA.href = link.href;
|
||||
elementA.type = link.type;
|
||||
elementLi.appendChild(elementA);
|
||||
elementUl2.appendChild(elementLi);
|
||||
}
|
||||
elementDiv.appendChild(elementUl2);
|
||||
// document.querySelector('#feed').appendChild(elementDiv); // This would result in a combination of Title, Article, and Journal
|
||||
document.querySelector('#articles').appendChild(elementDiv);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert URI xmpp: to URI http: links.
|
||||
for (let xmppLink of document.querySelectorAll(
|
||||
'#articles h3 > a[href^="xmpp:"][id^="rivista-"],' +
|
||||
'#articles h5.related > a[class^="rivista-"],' +
|
||||
'#journal > ol > li > a[href^="xmpp:"]')) {
|
||||
xmppUri = new URL(xmppLink);
|
||||
let parameters = xmppUri.search.split(';');
|
||||
try {
|
||||
try {
|
||||
let node = parameters.find(parameter => parameter.startsWith('node=')).split('=')[1];
|
||||
let item = parameters.find(parameter => parameter.startsWith('item=')).split('=')[1];
|
||||
let pubsub = xmppUri.pathname;
|
||||
xmppLink.href = `atom?pubsub=${pubsub}&node=${node}&item=${item}`
|
||||
} catch {
|
||||
let node = parameters.find(parameter => parameter.startsWith('node=')).split('=')[1];
|
||||
let pubsub = xmppUri.pathname;
|
||||
xmppLink.href = `atom?pubsub=${pubsub}&node=${node}`
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Display a selection of suggested software.
|
||||
const selection = {
|
||||
'akregator' : {
|
||||
'name' : 'Akregator',
|
||||
'image' : 'akregator.svg',
|
||||
'url' : 'https://apps.kde.org/akregator/'
|
||||
},
|
||||
'leechcraft' : {
|
||||
'name' : 'LeechCraft',
|
||||
'image' : 'leechcraft.png',
|
||||
'url' : 'https://leechcraft.org/'
|
||||
},
|
||||
'liferea' : {
|
||||
'name' : 'Liferea',
|
||||
'image' : 'liferea.svg',
|
||||
'url' : 'https://lzone.de/liferea/'
|
||||
},
|
||||
'raven' : {
|
||||
'name' : 'Raven Reader',
|
||||
'image' : 'raven.svg',
|
||||
'url' : 'https://ravenreader.app/'
|
||||
},
|
||||
'rssguard' : {
|
||||
'name' : 'RSS Guard',
|
||||
'image' : 'rssguard.png',
|
||||
'url' : 'https://github.com/martinrotter/rssguard'
|
||||
},
|
||||
'rssowl' : {
|
||||
'name' : 'RSSOwl',
|
||||
'image' : 'rssowl.svg',
|
||||
'url' : 'http://www.rssowl.org/'
|
||||
},
|
||||
'tickr' : {
|
||||
'name' : 'TICKR',
|
||||
'image' : 'tickr.png',
|
||||
'url' : 'https://www.open-tickr.net/'
|
||||
}
|
||||
}
|
||||
let selectionLink = document.querySelector('#selection-link');
|
||||
selectionLink.addEventListener ('click', function() {
|
||||
let elementDiv = document.createElement('div');
|
||||
elementDiv.id = 'selection-page';
|
||||
let elementH1 = document.createElement('h1');
|
||||
elementH1.textContent = 'Select A News Reader';
|
||||
elementDiv.appendChild(elementH1);
|
||||
let elementH2 = document.createElement('h2');
|
||||
elementH2.textContent = 'Install A Feed Reader For Desktop And Mobile';
|
||||
elementDiv.appendChild(elementH2);
|
||||
const brands = Object.keys(selection);
|
||||
let elementDivSel = document.createElement('div');
|
||||
elementDivSel.id = 'selection';
|
||||
for (let i = 0; i < brands.length; i++) {
|
||||
let brand = brands[i];
|
||||
let elementSpan = document.createElement('span');
|
||||
let elementA = document.createElement('a');
|
||||
elementA.href = selection[brand].url;
|
||||
elementA.textContent = selection[brand].name;
|
||||
let elementImg = document.createElement('img');
|
||||
elementImg.src = 'graphic/' + selection[brand].image;
|
||||
elementSpan.appendChild(elementImg);
|
||||
elementSpan.appendChild(elementA);
|
||||
elementDivSel.appendChild(elementSpan);
|
||||
elementDiv.appendChild(elementDivSel);
|
||||
}
|
||||
let elementP1 = document.createElement('p');
|
||||
elementP1.textContent = '' +
|
||||
'This is a selection of desktop, mobile and HTML (sometimes referred to ' +
|
||||
'as "online") News Readers for you to choose from.';
|
||||
elementDiv.appendChild(elementP1);
|
||||
let elementP2 = document.createElement('p');
|
||||
elementP2.textContent = '' +
|
||||
'This selection includes: Podcast Managers, Torrent ' +
|
||||
'Clients, Chat Bots, HTML Browsers and Plugins which support ' +
|
||||
'syndication feeds.';
|
||||
elementDiv.appendChild(elementP2);
|
||||
let elementSpan = document.createElement('span');
|
||||
elementSpan.id = 'return';
|
||||
elementSpan.textContent = 'Return';
|
||||
elementSpan.addEventListener ('click', function() {
|
||||
document.querySelector('#selection-page').remove();
|
||||
});
|
||||
elementDiv.appendChild(elementSpan);
|
||||
document.body.appendChild(elementDiv);
|
||||
});
|
||||
}
|
||||
|
||||
async function openJson(pubsubJid, nodeId) {
|
||||
return fetch(`/data/${pubsubJid}/${nodeId}.json`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('HTTP Error: ' + response.status);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(json => {
|
||||
return json;
|
||||
})
|
||||
.catch(err => {
|
||||
console.warn(err);
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue