parent
55cce0c433
commit
0e4f973553
Binary file not shown.
|
@ -24,7 +24,6 @@
|
|||
"prepare": "grunt clean deploy"
|
||||
},
|
||||
"dependencies": {
|
||||
"hyperscript": "^2.0.2",
|
||||
"milligram": "^1.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -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 ? "▾" : "▸";
|
||||
|
||||
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 stringToHtml(`<header class="header"></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">
|
||||
<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");
|
||||
if (text === undefined) return "";
|
||||
|
||||
return h("span",
|
||||
h("span", prefix),
|
||||
url !== undefined
|
||||
? h("a", text, {href: url})
|
||||
: h("span", text),
|
||||
h("span", suffix)
|
||||
);
|
||||
return `
|
||||
<span>
|
||||
${prefix}
|
||||
${url !== undefined ? `<a href="${url}">${text}</a>` : text}
|
||||
${suffix}
|
||||
</span>
|
||||
`;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue