Browse Source

Rewrite without hyperscript

Fixes #5. Reduces bundle by 6kB.
master v0.0.23
F.W. Dekker 9 months ago
parent
commit
0e4f973553
Signed by: FWDekker GPG Key ID: B1B567AF58D6EE0F
  1. 4523
      package-lock.json
  2. 1
      package.json
  3. 122
      src/main/js/Template.js

4523
package-lock.json

File diff suppressed because it is too large

1
package.json

@ -24,7 +24,6 @@
"prepare": "grunt clean deploy"
},
"dependencies": {
"hyperscript": "^2.0.2",
"milligram": "^1.4.1"
},
"devDependencies": {

122
src/main/js/Template.js

@ -1,4 +1,3 @@
import h from "hyperscript";
import "../css/normalize.css";
import "milligram/dist/milligram.min.css";
import "../css/common.css";
@ -6,6 +5,17 @@ import "../css/nav.css";
import "../css/overrides.css";
/**
* Converts the given string to an HTML element.
*
* @param string the string to convert to an HTML element
* @param query the type of element to return
* @returns {HTMLElement} the HTML element described by the given string
*/
const stringToHtml = function (string, query) {
return new DOMParser().parseFromString(string, "text/html").body.querySelector(query);
}
/**
* Alias for `document.querySelector`.
*
@ -41,22 +51,28 @@ export const doAfterLoad = function (fun) {
* @returns {HTMLElement} a base navigation element that will eventually be filled with contents
*/
export const nav = function (highlightPath = "") {
const base = h("ul",
h("li", h("a", {href: "https://fwdekker.com/"},
h("div.logo", h("img.logo", {src: "https://fwdekker.com/favicon.png"})),
h("b", "FWDekker")
))
);
const base = stringToHtml(`
<ul>
<li><a href="https://fwdekker.com/">
<div class="logo"><img class="logo" src="https://fwdekker.com/favicon.png" alt="FWDekker" /></div>
<b>FWDekker</b>
</a></li>
</ul>
`, "ul");
fetch("https://fwdekker.com/api/nav/")
.then(it => it.json())
.then(json => json.entries.forEach(entry => base.appendChild(unpackEntry(entry, "/", highlightPath))))
.then(json => {
json.entries.forEach(entry => base.appendChild(stringToHtml(unpackEntry(entry, "/", highlightPath), "li")))
})
.catch(e => {
console.error("Failed to fetch navigation elements", e);
return [];
});
return h("nav.nav", base);
const nav = stringToHtml(`<nav class="nav"></nav>`, "nav");
nav.appendChild(base);
return nav;
};
/**
@ -66,25 +82,23 @@ export const nav = function (highlightPath = "") {
* @param [path] {number} the current path traversed, found by joining the names of the entries with `/`s; always starts
* and ends with a `/`
* @param [highlightPath] {String} the path to highlight together with its parents
* @returns {HTMLElement} the navigation list entry as HTML, described by its children
* @returns {string} the navigation list entry as HTML, described by its children
*/
const unpackEntry = function (entry, path = "/", highlightPath = "") {
const shouldHighlight = highlightPath.startsWith(`${path + entry.name}/`);
if (entry.entries.length === 0)
return h("li",
h("a", {href: entry.link, innerHTML: entry.name}),
{className: shouldHighlight ? "currentPage" : ""}
);
return `<li><a href="${entry.link}" class="${shouldHighlight ? "currentPage" : ""}">${entry.name}</a></li>`;
const depth = path.split("/").length - 2; // -1 because count parts, then another -1 because of leading `/`
const depth = path.split("/").length - 2; // -1 because count parts, then another -1 because of leading `/`
const arrow = depth === 0 ? "&#9662;" : "&#9656;";
return h("li",
h("a", {href: entry.link, innerHTML: `${entry.name} ${arrow}`}),
h("ul", entry.entries.map(it => unpackEntry(it, `${path + entry.name}/`, highlightPath))),
{className: shouldHighlight ? "currentPage" : ""}
);
return `
<li class="${shouldHighlight ? "currentPage" : ""}">
<a href="${entry.link}">${entry.name} ${arrow}</a>
<ul>${entry.entries.map(it => unpackEntry(it, `${path + entry.name}/`, highlightPath)).join("")}</ul>
</li>
`;
};
@ -97,14 +111,16 @@ const unpackEntry = function (entry, path = "/", highlightPath = "") {
*/
export const header = function ({title, description}) {
if (title === undefined && description === undefined)
return h("header.header");
return h("header.header",
h("section.container",
title !== undefined ? h("h1", {innerHTML: title}) : undefined,
description !== undefined ? h("p", h("em", {innerHTML: description})) : undefined
)
);
return stringToHtml(`<header class="header"></header>`, "header");
return stringToHtml(`
<header class="header">
<section class="container">
${(title !== undefined ? `<h1>${title}</h1>` : "")}
${(description !== undefined ? `<p><em>${description}</em></p>` : "")}
</section>
</header>
`, "header");
};
@ -127,20 +143,22 @@ export const footer = function (
author, authorURL, license, licenseURL, vcs, vcsURL, version,
privacyPolicyURL = undefined
}) {
return h("footer.footer",
h("section.container",
footerLink("Made by ", author, authorURL, ". "),
footerLink("Licensed under the ", license, licenseURL, ". "),
footerLink("Source code available on ", vcs, vcsURL, ". "),
footerLink(
"Consider reading the ",
privacyPolicyURL === null ? undefined : "privacy policy",
privacyPolicyURL === undefined ? "https://fwdekker.com/privacy/" : privacyPolicyURL,
". "
),
h("div", version || "", {style: {"float": "right"}})
)
);
return stringToHtml(`
<footer class="footer">
<section class="container">
${footerLink("Made by ", author, authorURL, ". ")}
${footerLink("Licensed under the ", license, licenseURL, ". ")}
${footerLink("Source code available on ", vcs, vcsURL, ". ")}
${footerLink(
"Consider reading the ",
privacyPolicyURL === null ? undefined : "privacy policy",
privacyPolicyURL === undefined ? "https://fwdekker.com/privacy/" : privacyPolicyURL,
". "
)}
<div style="float: right;">${version || ""}</div>
</section>
</footer>
`, "footer");
};
/**
@ -150,18 +168,18 @@ export const footer = function (
* @param text {string|undefined} the text to display, or `undefined` if the returned element should be empty
* @param url {string|undefined} the URL to link the text to, or `undefined` if the text should not be a link
* @param suffix {string} the text to display after the text if the text is not undefined
* @returns {HTMLElement} a footer link element
* @returns {string} a footer link element
*/
const footerLink = function (prefix, text, url, suffix) {
if (text === undefined) return h("span");
return h("span",
h("span", prefix),
url !== undefined
? h("a", text, {href: url})
: h("span", text),
h("span", suffix)
);
if (text === undefined) return "";
return `
<span>
${prefix}
${url !== undefined ? `<a href="${url}">${text}</a>` : text}
${suffix}
</span>
`;
};

Loading…
Cancel
Save