Skip to content

Commit

Permalink
Fixes to link discovery.
Browse files Browse the repository at this point in the history
  • Loading branch information
lwindolf committed Jun 17, 2024
1 parent c9f4279 commit 65477e7
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 116 deletions.
157 changes: 80 additions & 77 deletions tests/autodiscovery.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// vim: set ts=4 sw=4:

import { linkAutoDiscover, parserAutoDiscover } from "../www/assets/js/parsers/autodiscover";
import { linkAutoDiscover, parserAutoDiscover } from "../www/assets/js/parsers/autodiscover";

test("Atom 1.0 auto discover", () => {
let p = parserAutoDiscover(`<?xml version="1.0" encoding="utf-8"?>
Expand Down Expand Up @@ -76,7 +76,7 @@ test("RSS 1.1 auto discover", () => {
</items>
</Channel>`);

expect(p.id).toBe('rss');
expect(p.id).toBe('rss');
});

test("RSS 2.0 auto discover", () => {
Expand Down Expand Up @@ -255,85 +255,88 @@ test("no feed auto discover", () => {
expect(p).toBe(undefined);
});

test("Link auto discover: none", async () => {
global['fetch'] = jest.fn().mockImplementation(() =>
Promise.resolve({
text: () => Promise.resolve(`<!DOCTYPE html>
<html lang="en-us">
<head>
</head>
<body>
<p>content</p>
</body>
</html>
`),
})
);
let links = await linkAutoDiscover('https://example.com');
expect(links.length).toBe(0);
test("Link auto discover: none", () => {
const str = `<!DOCTYPE html>
<html lang="en-us">
<head>
</head>
<body>
<p>content</p>
</body>
</html>`;

let links = linkAutoDiscover(str, 'https://example.com');
expect(links.length).toBe(0);
})

test("Link auto discover: Atom", () => {
const str = `<!DOCTYPE html>
<html lang="en-us">
<head>
<link href="/feed/devops.xml" rel="alternate" title="LZone Blog" type="application/atom+xml" >
</head>
<body>
<p>content</p>
</body>
</html>`;

let links = linkAutoDiscover(str, 'https://lzone.de');
expect(links.length).toBe(1);
expect(links[0]).toBe("https://lzone.de/feed/devops.xml")
})

test("Link auto discover: Atom", async () => {
global['fetch'] = jest.fn().mockImplementation(() =>
Promise.resolve({
text: () => Promise.resolve(`<!DOCTYPE html>
<html lang="en-us">
<head>
<link href="/feed/devops.xml" rel="alternate" title="LZone Blog" type="application/atom+xml" >
</head>
<body>
<p>content</p>
</body>
</html>
`),
})
);

let links = await linkAutoDiscover('https://lzone.de');
expect(links.length).toBe(1);
expect(links[0]).toBe("https://lzone.de/feed/devops.xml")
test("Link auto discover: RSS", () => {
const str = `<!DOCTYPE html>
<html lang="en-us">
<head>
<link href="https://example.com/feed/devops.rss" rel="alternate" title="LZone Blog" type="application/rss+xml" >
</head>
<body>
<p>content</p>
</body>
</html>`;

let links = linkAutoDiscover(str, 'https://lzone.de');
expect(links.length).toBe(1);
expect(links[0]).toBe("https://example.com/feed/devops.rss")
})

test("Link auto discover: RSS", async () => {
global['fetch'] = jest.fn().mockImplementation(() =>
Promise.resolve({
text: () => Promise.resolve(`<!DOCTYPE html>
<html lang="en-us">
<head>
<link href="https://example.com/feed/devops.rss" rel="alternate" title="LZone Blog" type="application/rss+xml" >
</head>
<body>
<p>content</p>
</body>
</html>
`),
})
);

let links = await linkAutoDiscover('https://lzone.de');
expect(links.length).toBe(1);
expect(links[0]).toBe("https://example.com/feed/devops.rss")
test("Link auto discover: multiple links", () => {
const str =`<!DOCTYPE html>
<html lang="en-us">
<head>
<link href="feed/devops.rss" rel="alternate" title="LZone Blog" type="application/rss+xml" >
<link href="/feed/devops.atom" rel="alternate" title="LZone Blog" type="application/atom+xml" >
</head>
<body>
<p>content</p>
</body>
</html>`;

let links = linkAutoDiscover(str, 'https://lzone.de/blog');
expect(links.length).toBe(2);
expect(links[0]).toBe("https://lzone.de/blog/feed/devops.rss")
expect(links[1]).toBe("https://lzone.de/feed/devops.atom")
})

test("Link auto discover: multiple links", async () => {
global['fetch'] = jest.fn().mockImplementation(() =>
Promise.resolve({
text: () => Promise.resolve(`<!DOCTYPE html>
<html lang="en-us">
<head>
<link href="feed/devops.rss" rel="alternate" title="LZone Blog" type="application/rss+xml" >
<link href="/feed/devops.atom" rel="alternate" title="LZone Blog" type="application/atom+xml" >
</head>
<body>
<p>content</p>
</body>
</html>
`),
})
);

let links = await linkAutoDiscover('https://lzone.de/blog');
expect(links.length).toBe(2);
expect(links[0]).toBe("https://lzone.de/blog/feed/devops.rss")
expect(links[1]).toBe("https://lzone.de/feed/devops.atom")
test("Link auto discover: slashdot", () => {
const str = `<!-- html-header type=current begin -->
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Render IE9 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="top" title="News for nerds, stuff that matters" href="//slashdot.org/" >
<link rel="search" title="Search Slashdot" href="//slashdot.org/search.pl">
<link rel="alternate" title="Slashdot RSS" href="https://rss.slashdot.org/Slashdot/slashdotMain" type="application/rss+xml">
</head>
</html>`;

let links = linkAutoDiscover(str, 'https://slashdot.org');
expect(links.length).toBe(1);
expect(links[0]).toBe("https://rss.slashdot.org/Slashdot/slashdotMain")
})
4 changes: 2 additions & 2 deletions www/assets/js/dialogs/simpleSubscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ class SimpleSubscriptionDialog extends Dialog {
links.push(result.url);
} else {
// Alternatively we assume it is a HTML document and search for links
links = await linkAutoDiscover(result.url);
links = linkAutoDiscover(str, result.url);
}
console.log(links)

// FIXME: let user choose which feed to use
if(links.length > 0) {
FeedList.add(new Feed({
Expand Down
1 change: 0 additions & 1 deletion www/assets/js/feedupdater.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export class FeedUpdater {
})
.catch(() => {
// FIXME: provide HTTP status too
console.log("ERROR!")
return new Feed({ error: Feed.ERROR_NET });
});
return feed;
Expand Down
55 changes: 27 additions & 28 deletions www/assets/js/helpers/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import { template } from '../helpers/render.js';

class Dialog {
#modal;
#modalContent;
#callback;
#template;

Expand All @@ -22,61 +24,58 @@ class Dialog {

// Build a modal dialog from a Handlebars template
constructor(templateStr, data, callback) {
this.#modal = document.getElementById('modal');
this.#modalContent = document.getElementById('modalContent');
this.#template = template(templateStr);
this.#callback = callback;

document.getElementById('modal').style.display = 'block';
document.getElementById('modalContent').innerHTML = '<form>'+this.#template(data)+'</form>';
document.addEventListener('click', this.#onclickFunc = (e) => {
this.#onclick(e);
this.#modal.style.display = 'block';
this.#modalContent.innerHTML = this.#template(data);

this.#modal.addEventListener('click', this.#onclickFunc = (e) => {
if(e.target.id === 'modal') {
this.destroy();
e.preventDefault();
}
});
document.addEventListener('submit', this.#onsubmitFunc = (e) => {
this.#onsubmit(e);
this.#modal.addEventListener('submit', this.#onsubmitFunc = (e) => {
this.#onsubmit();
e.preventDefault();
});
document.addEventListener('keydown', this.#onkeydownFunc = (e) => {
if(e.code === "Escape")
this.#modal.addEventListener('keydown', this.#onkeydownFunc = (e) => {
if(e.code === "Escape") {
this.destroy();
e.preventDefault();
}
});
}

// handle close and submit clicks
#onclick(e) {
if(e.target.closest('.close') || e.target.id === 'modal') {
this.destroy();
e.preventDefault();
return;
}
}

#onsubmit(e) {
#onsubmit() {
var inputData = {};

[...document.querySelectorAll('#modalContent input, #modalContent select, #modalContent textarea')]
[...this.#modalContent.querySelectorAll('input, select, textarea')]
.forEach((e) => (inputData[e.name] = e.value));

this.#callback(inputData).then((done) => {
if(done)
this.destroy();
});

e.preventDefault();
return;
}

// Update the dialog with new data, along with a conditional
// template this allows changing the dialog and supplying new
// data & fields.
update(data) {
document.getElementById('modalContent').innerHTML = this.#template(data);
this.#modalContent.innerHTML = this.#template(data);
}

// "destructor"
destroy() {
document.getElementById('modal').style.display = 'none';
document.getElementById('modalContent').innerHTML = '';
document.removeEventListener('click', this.#onclickFunc);
document.removeEventListener('submit', this.#onsubmitFunc);
document.removeEventListener('keydown', this.#onkeydownFunc);
this.#modal.style.display = 'none';
this.#modalContent.innerHTML = '';
this.#modal.removeEventListener('click', this.#onclickFunc);
this.#modal.removeEventListener('submit', this.#onsubmitFunc);
this.#modal.removeEventListener('keydown', this.#onkeydownFunc);
}
}

Expand Down
14 changes: 8 additions & 6 deletions www/assets/js/parsers/autodiscover.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ function parserAutoDiscover(str) {
try {
if (XPath.lookup(doc.firstChild, parsers[i].autoDiscover[j]))
return parsers[i];
} catch (e) {
console.log(e);
} catch(e) {
// ignore
}
}
}
return undefined;
}

// for a given HTML document link return all feed links found
async function linkAutoDiscover(str) {
function linkAutoDiscover(str, baseURL) {
let doc;

// Try to parse as HTML
try {
doc = new DOMParser().parseFromString(str, 'text/html');
} catch (e) {
// ignore
} catch {
console.info("Link discovery: could not parse HTML!");
}

if (!doc)
Expand All @@ -56,7 +56,7 @@ async function linkAutoDiscover(str) {
(node) => {
let href = XPath.lookup(node, '@href');
if (!href.includes("://")) {
var u = new URL(url);
var u = new URL(baseURL);
if (href.startsWith('/'))
u.pathname = href;
else
Expand All @@ -66,6 +66,8 @@ async function linkAutoDiscover(str) {
results.push(href);
}
});

console.info("Link discovery found "+JSON.stringify(results));
return results;
}

Expand Down
6 changes: 4 additions & 2 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@

<!-- modal dialog -->
<div id="modal">
<div id="modalContent">
</div>
<form>
<div id="modalContent">
</div>
</form>
</div>
</div>

Expand Down

0 comments on commit 65477e7

Please sign in to comment.