Skip to content

Commit

Permalink
Switch to ESM module loading.
Browse files Browse the repository at this point in the history
  • Loading branch information
lwindolf committed Jan 16, 2025
1 parent 0dfc348 commit 009c289
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 173 deletions.
108 changes: 0 additions & 108 deletions js/Readability-readerable.js

This file was deleted.

9 changes: 4 additions & 5 deletions js/gresource.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/liferea/readability">
<file compressed="true">Readability.js</file>
</gresource>
<gresource prefix="/org/gnome/liferea/js">
<file compressed="true">htmlview.js</file>
<file compressed="true">purify.min.js</file>
<file compressed="true">handlebars.min.js</file>
<file compressed="true">helpers/render.js</file>
<file compressed="true">vendor/Readability.js</file>
<file compressed="true">vendor/purify.min.js</file>
<file compressed="true">vendor/handlebars.min.js</file>
</gresource>
<gresource prefix="/org/gnome/liferea/templates">
<file compressed="true">item.xml</file>
Expand Down
29 changes: 0 additions & 29 deletions js/handlebars.min.js

This file was deleted.

89 changes: 89 additions & 0 deletions js/helpers/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// vim: set ts=4 sw=4:

import Handlebars from '../vendor/handlebars.min.js';

// Handlebars convenience helpers

if (Handlebars) {
// FIXME: register only once
Handlebars.registerHelper("eachSorted", function (obj, options) {
let data = Handlebars.createFrame(options, options.hash);
let result = '';

for (const key of Object.keys(obj).sort((a, b) => {
return a.toLowerCase().localeCompare(b.toLowerCase());
})) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
data.key = key;
result += options.fn(obj[key], { data: data });
}
}
return result;
});

Handlebars.registerHelper('ifTrue', function (v1, options) {
if (v1 == true) {
return options.fn(this);
}
return options.inverse(this);
});
Handlebars.registerHelper('ifFalse', function (v1, options) {
if (v1 == true) {
return options.fn(this);
}
return options.inverse(this);
});

Handlebars.registerHelper('contains', function (needle, haystack, options) {
needle = Handlebars.escapeExpression(needle);
haystack = Handlebars.escapeExpression(haystack);
return (haystack.indexOf(needle) > -1) ? options.fn(this) : options.inverse(this);
});

Handlebars.registerHelper('compare', function (v1, operator, v2, options) {
var operators = {
'==': v1 == v2 ? true : false,
'===': v1 === v2 ? true : false,
'!=': v1 != v2 ? true : false,
'!==': v1 !== v2 ? true : false,
'>': v1 > v2 ? true : false,
'>=': v1 >= v2 ? true : false,
'<': v1 < v2 ? true : false,
'<=': v1 <= v2 ? true : false,
'||': v1 || v2 ? true : false,
'&&': v1 && v2 ? true : false
}
if (Object.prototype.hasOwnProperty.call(operators, operator)) {
if (operators[operator]) {
return options.fn(this);
}
return options.inverse(this);
}
return console.error('Error: Expression "' + operator + '" not found');
});
}

function template(str) {
return Handlebars.compile(str);
}

function render(selector, template, params, append = false) {
let e = document.querySelector(selector);
let result;

if (!e)
return;

try {
result = template(params);
} catch (e) {
result = `Rendering exception: ${e}`;
}

if (append)
e.innerHTML += result;
else
e.innerHTML = result;
}

export { template, render };
18 changes: 6 additions & 12 deletions js/htmlview.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

var template;
import { render, template } from './helpers/render.js';
import DOMPurify from './vendor/purify.min.js';

function prepare(baseURL, title) {
if (title) {
Expand All @@ -31,8 +32,6 @@ function prepare(baseURL, title) {
base.setAttribute("href", baseURL);
document.head.appendChild(base);
}

template = Handlebars.compile(document.getElementById('template').innerHTML);
}

// returns first occurence of a given metadata type
Expand Down Expand Up @@ -61,17 +60,12 @@ function parseStatus(parsePhase, errorCode) {

async function load_node(data, baseURL, direction) {
let node = JSON.parse(decodeURIComponent(data));
let publisher = metadata_get(node, "publisher");
let author = metadata_get(node, "author");
let copyright = metadata_get(node, "copyright");
let description = metadata_get(node, "description");
let homepage = metadata_get(node, "homepage");

// FIXME
console.log(node);

prepare(baseURL, node.title);
document.body.innerHTML = template({
render("body", template(document.getElementById('template').innerHTML), {
node,
direction,
publisher : metadata_get(node, "publisher"),
Expand Down Expand Up @@ -155,8 +149,6 @@ async function load_item(data, baseURL, direction) {

article = new Readability(shadowDoc, {charThreshold: 100}).parse();
if (article) {
description = article.content;

// Use rich content from Readability if available and better!
if (article.content.length > item.description.length) {
item.description = article.content;
Expand All @@ -168,7 +160,7 @@ async function load_item(data, baseURL, direction) {
console.log(item);

prepare(baseURL, item.title);
document.body.innerHTML = template({
render("body", template (document.getElementById('template').innerHTML), {
item,
direction,

Expand Down Expand Up @@ -295,3 +287,5 @@ function youtube_embed(id) {

return false;
}

export { load_node, load_item };
11 changes: 5 additions & 6 deletions js/item.xml.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<script src='liferea:///readability/Readability.js'></script>
<script src='liferea:///js/purify.min.js'></script>
<script src='liferea:///js/handlebars.min.js'></script>
<script src='liferea:///js/htmlview.js'></script>

<script src='/js/vendor/Readability.js'></script>

<!-- FIXME: consider adding CSP meta tag here as e.g. Firefox reader mode page does -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Expand Down Expand Up @@ -74,7 +71,9 @@
</head>
<body>
</body>
<script>
<script type="module">
import { load_item } from '/js/htmlview.js';

REPLACE_MARKER
</script>
</html>
7 changes: 3 additions & 4 deletions js/node.xml.in
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<script src='liferea:///readability/Readability.js'></script>
<script src='liferea:///js/purify.min.js'></script>
<script src='liferea:///js/handlebars.min.js'></script>
<script src='liferea:///js/htmlview.js'></script>
<script src='/js/vendor/Readability.js'></script>

<!-- FIXME: consider adding CSP meta tag here as e.g. Firefox reader mode page does -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Expand Down Expand Up @@ -47,6 +44,8 @@
<body>
</body>
<script>
import { load_node } from '/js/htmlview.js';

REPLACE_MARKER
</script>
</html>
3 changes: 0 additions & 3 deletions js/purify.min.js

This file was deleted.

File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions js/vendor/handlebars.min.js

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions js/vendor/purify.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"installDeps": "ls node_modules"
},
"dependencies": {
"dompurify": "^3.0.6",
"dompurify": "^3.2.3",
"readability": "^0.1.0",
"handlebars": "^4.7.8"
},
Expand Down
7 changes: 4 additions & 3 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ js_files = $(js_in_files:.xml.in=.xml)

js_deps = $(top_srcdir)/js/gresource.xml \
$(top_srcdir)/js/htmlview.js \
$(top_srcdir)/js/Readability.js \
$(top_srcdir)/js/purify.min.js \
$(top_srcdir)/js/handlebars.min.js \
$(top_srcdir)/js/helpers/render.js \
$(top_srcdir)/js/vendor/Readability.js \
$(top_srcdir)/js/vendor/purify.min.js \
$(top_srcdir)/js/vendor/handlebars.min.js \
$(top_srcdir)/js/item.xml \
$(top_srcdir)/js/node.xml \
$(top_srcdir)/js/i18n-filter.xslt
Expand Down
16 changes: 14 additions & 2 deletions src/webkit/webkit.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,18 @@ liferea_webkit_handle_liferea_scheme (WebKitURISchemeRequest *request, gpointer
if (b) {
gsize length = 0;
const guchar *data = g_bytes_get_data (b, &length);
const gchar *mime;

// FIXME: what about freeing b?
g_autoptr(GInputStream) stream = g_memory_input_stream_new_from_data (data, length, NULL);
webkit_uri_scheme_request_finish (request, stream, length, "text/plain");

// For now we assume all resources are javascript, so MIME is hardcoded
if (g_str_has_suffix (path, ".js"))
mime = "text/javascript";
else
mime = "text/plain";

webkit_uri_scheme_request_finish (request, stream, length, mime);
} else {
debug (DEBUG_HTML, "Failed to load liferea:// request for path %s (%s)", path, rpath);
g_autoptr(GError) error = g_error_new (G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Resource not found");
Expand All @@ -404,7 +413,10 @@ liferea_webkit_init (LifereaWebKit *self)

security_manager = webkit_web_context_get_security_manager (webkit_web_context_get_default ());
website_data_manager = webkit_web_context_get_website_data_manager (webkit_web_context_get_default ());
webkit_security_manager_register_uri_scheme_as_local (security_manager, "liferea");
/* CORS is necessary to have ESM modules working. Security wise this should be ok as this scheme
is only used to fetch static resources. */
webkit_security_manager_register_uri_scheme_as_cors_enabled (security_manager, "liferea");


conf_signal_connect (
"changed::" ENABLE_ITP,
Expand Down

0 comments on commit 009c289

Please sign in to comment.