parent
55cce0c433
commit
0e4f973553
Binary file not shown.
|
@ -24,7 +24,6 @@
|
||||||
"prepare": "grunt clean deploy"
|
"prepare": "grunt clean deploy"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hyperscript": "^2.0.2",
|
|
||||||
"milligram": "^1.4.1"
|
"milligram": "^1.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import h from "hyperscript";
|
|
||||||
import "../css/normalize.css";
|
import "../css/normalize.css";
|
||||||
import "milligram/dist/milligram.min.css";
|
import "milligram/dist/milligram.min.css";
|
||||||
import "../css/common.css";
|
import "../css/common.css";
|
||||||
|
@ -6,6 +5,17 @@ import "../css/nav.css";
|
||||||
import "../css/overrides.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`.
|
* 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
|
* @returns {HTMLElement} a base navigation element that will eventually be filled with contents
|
||||||
*/
|
*/
|
||||||
export const nav = function (highlightPath = "") {
|
export const nav = function (highlightPath = "") {
|
||||||
const base = h("ul",
|
const base = stringToHtml(`
|
||||||
h("li", h("a", {href: "https://fwdekker.com/"},
|
<ul>
|
||||||
h("div.logo", h("img.logo", {src: "https://fwdekker.com/favicon.png"})),
|
<li><a href="https://fwdekker.com/">
|
||||||
h("b", "FWDekker")
|
<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/")
|
fetch("https://fwdekker.com/api/nav/")
|
||||||
.then(it => it.json())
|
.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 => {
|
.catch(e => {
|
||||||
console.error("Failed to fetch navigation elements", e);
|
console.error("Failed to fetch navigation elements", e);
|
||||||
return [];
|
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
|
* @param [path] {number} the current path traversed, found by joining the names of the entries with `/`s; always starts
|
||||||
* and ends with a `/`
|
* and ends with a `/`
|
||||||
* @param [highlightPath] {String} the path to highlight together with its parents
|
* @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 unpackEntry = function (entry, path = "/", highlightPath = "") {
|
||||||
const shouldHighlight = highlightPath.startsWith(`${path + entry.name}/`);
|
const shouldHighlight = highlightPath.startsWith(`${path + entry.name}/`);
|
||||||
|
|
||||||
if (entry.entries.length === 0)
|
if (entry.entries.length === 0)
|
||||||
return h("li",
|
return `<li><a href="${entry.link}" class="${shouldHighlight ? "currentPage" : ""}">${entry.name}</a></li>`;
|
||||||
h("a", {href: entry.link, innerHTML: entry.name}),
|
|
||||||
{className: shouldHighlight ? "currentPage" : ""}
|
|
||||||
);
|
|
||||||
|
|
||||||
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 ? "▾" : "▸";
|
const arrow = depth === 0 ? "▾" : "▸";
|
||||||
|
|
||||||
return h("li",
|
return `
|
||||||
h("a", {href: entry.link, innerHTML: `${entry.name} ${arrow}`}),
|
<li class="${shouldHighlight ? "currentPage" : ""}">
|
||||||
h("ul", entry.entries.map(it => unpackEntry(it, `${path + entry.name}/`, highlightPath))),
|
<a href="${entry.link}">${entry.name} ${arrow}</a>
|
||||||
{className: shouldHighlight ? "currentPage" : ""}
|
<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}) {
|
export const header = function ({title, description}) {
|
||||||
if (title === undefined && description === undefined)
|
if (title === undefined && description === undefined)
|
||||||
return h("header.header");
|
return stringToHtml(`<header class="header"></header>`, "header");
|
||||||
|
|
||||||
return h("header.header",
|
return stringToHtml(`
|
||||||
h("section.container",
|
<header class="header">
|
||||||
title !== undefined ? h("h1", {innerHTML: title}) : undefined,
|
<section class="container">
|
||||||
description !== undefined ? h("p", h("em", {innerHTML: description})) : undefined
|
${(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,
|
author, authorURL, license, licenseURL, vcs, vcsURL, version,
|
||||||
privacyPolicyURL = undefined
|
privacyPolicyURL = undefined
|
||||||
}) {
|
}) {
|
||||||
return h("footer.footer",
|
return stringToHtml(`
|
||||||
h("section.container",
|
<footer class="footer">
|
||||||
footerLink("Made by ", author, authorURL, ". "),
|
<section class="container">
|
||||||
footerLink("Licensed under the ", license, licenseURL, ". "),
|
${footerLink("Made by ", author, authorURL, ". ")}
|
||||||
footerLink("Source code available on ", vcs, vcsURL, ". "),
|
${footerLink("Licensed under the ", license, licenseURL, ". ")}
|
||||||
footerLink(
|
${footerLink("Source code available on ", vcs, vcsURL, ". ")}
|
||||||
"Consider reading the ",
|
${footerLink(
|
||||||
privacyPolicyURL === null ? undefined : "privacy policy",
|
"Consider reading the ",
|
||||||
privacyPolicyURL === undefined ? "https://fwdekker.com/privacy/" : privacyPolicyURL,
|
privacyPolicyURL === null ? undefined : "privacy policy",
|
||||||
". "
|
privacyPolicyURL === undefined ? "https://fwdekker.com/privacy/" : privacyPolicyURL,
|
||||||
),
|
". "
|
||||||
h("div", version || "", {style: {"float": "right"}})
|
)}
|
||||||
)
|
<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 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 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
|
* @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) {
|
const footerLink = function (prefix, text, url, suffix) {
|
||||||
if (text === undefined) return h("span");
|
if (text === undefined) return "";
|
||||||
|
|
||||||
return h("span",
|
return `
|
||||||
h("span", prefix),
|
<span>
|
||||||
url !== undefined
|
${prefix}
|
||||||
? h("a", text, {href: url})
|
${url !== undefined ? `<a href="${url}">${text}</a>` : text}
|
||||||
: h("span", text),
|
${suffix}
|
||||||
h("span", suffix)
|
</span>
|
||||||
);
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue