108 lines
2.9 KiB
JavaScript
108 lines
2.9 KiB
JavaScript
|
//@ts-check
|
||
|
import { changeTitle } from "./changeTitle.mjs";
|
||
|
import { getCurrentHashUrl } from "./getCurrentHashUrl.mjs";
|
||
|
import { fetchMarkdown } from "./fetchMarkdown.mjs";
|
||
|
import { fetchText } from "./fetchText.mjs";
|
||
|
import { parseFileList } from "./parseFileList.mjs";
|
||
|
import { documentMode } from "./documentMode.mjs";
|
||
|
import { getElementById } from "./getElementById.mjs";
|
||
|
import { onDocumentKeyUp } from "./onDocumentKey.mjs";
|
||
|
|
||
|
/*****************************************************************
|
||
|
*
|
||
|
* Creating references to the important stuff
|
||
|
*
|
||
|
****************************************************************/
|
||
|
|
||
|
/**
|
||
|
* The elements we will need
|
||
|
*/
|
||
|
const [Menu, Body, Source, Burger] = ["Menu", "Body", "Source", "Burger"].map(
|
||
|
getElementById
|
||
|
);
|
||
|
|
||
|
const loadingMode = documentMode("loading");
|
||
|
const sourceEnableMode = documentMode("source-enabled");
|
||
|
const menuOpenMode = documentMode("menu-open");
|
||
|
|
||
|
/*****************************************************************
|
||
|
*
|
||
|
* Router
|
||
|
*
|
||
|
* Things related to main navigation and to loading pages
|
||
|
*
|
||
|
****************************************************************/
|
||
|
|
||
|
/**
|
||
|
* Listens to hashchange event, and attempts to read the url.
|
||
|
* @param {HashChangeEvent} [_evt]
|
||
|
*/
|
||
|
export const onHashChange = async (_evt) => {
|
||
|
const { path, params } = getCurrentHashUrl();
|
||
|
if (!path) {
|
||
|
return false;
|
||
|
}
|
||
|
loadingMode.on();
|
||
|
const { title, raw, content } = await fetchMarkdown(path);
|
||
|
changeTitle(title);
|
||
|
Body.innerHTML = "";
|
||
|
Source.innerHTML = raw;
|
||
|
Body.appendChild(content);
|
||
|
loadingMode.off();
|
||
|
};
|
||
|
|
||
|
const loadFileList = () => {
|
||
|
loadingMode.on();
|
||
|
|
||
|
fetchText("./files.txt").then(fillMenuFromFileList);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Called when the file list is obtained (presumably through loading)
|
||
|
* parses the file list, then fills the side navigation
|
||
|
* If there's no page loaded, it also loads the first page in the list
|
||
|
* (the list gets sorted by date, but the first line is the one that gets used)
|
||
|
* @param {string} lines
|
||
|
*/
|
||
|
export const fillMenuFromFileList = (lines) => {
|
||
|
const links = parseFileList(lines).sort(
|
||
|
({ date_unix: a }, { date_unix: b }) => a - b
|
||
|
);
|
||
|
if (links.length < 1) {
|
||
|
return;
|
||
|
}
|
||
|
Menu.innerHTML = links
|
||
|
.map(({ href, title }) => `<a data-link href="#${href}">${title}</a>`)
|
||
|
.join(`\n`);
|
||
|
if (!getCurrentHashUrl().path) {
|
||
|
// @ts-ignore
|
||
|
const href = links.find(({ index }) => index === 0).href;
|
||
|
window.location.hash = `#${href}`;
|
||
|
} else {
|
||
|
onHashChange();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/*****************************************************************
|
||
|
*
|
||
|
* Bootstrapping
|
||
|
*
|
||
|
* this is where things actually happen
|
||
|
*
|
||
|
****************************************************************/
|
||
|
|
||
|
/**
|
||
|
* Loads the article list, parses it, creates the menu items
|
||
|
*/
|
||
|
export const bootstrap = () => {
|
||
|
Burger.addEventListener("click", menuOpenMode.toggle);
|
||
|
|
||
|
window.addEventListener("hashchange", onHashChange);
|
||
|
|
||
|
loadFileList();
|
||
|
|
||
|
onDocumentKeyUp("?", sourceEnableMode.toggle);
|
||
|
};
|
||
|
|
||
|
export default bootstrap;
|