766e51af4c
Add packaging instructions; Add modules to handle Gemini file type (no Gemini server yet); Improve handling of configuration.
265 lines
9.8 KiB
JavaScript
265 lines
9.8 KiB
JavaScript
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);
|
|
})
|
|
}
|