testing moving the functionality into small modules #5

Open
xananax wants to merge 10 commits from split-into-modules into main
7 changed files with 189 additions and 111 deletions
Showing only changes of commit 8e7ce406ff - Show all commits

View File

@ -196,9 +196,6 @@
<div id="Loading">
<p></p>
</div>
<script type="module">
import blog from "./modules/templateBlog.mjs";
blog();
</script>
<script type="module" src="./modules/templateBlog.mjs"></script>
</body>
</html>

View File

@ -1,5 +1,12 @@
//@ts-check
/**
* Changes the document's title
* Changes the document's title. Instead of passing the main title, you can also
* change the functions `title` member:
* ```js
* changeTitle.title = "My Site"
* changeTitle("Home") // produces "Home | My Site"
* ```
* @param {string} title
* @param {string} mainTitle
* @returns

View File

@ -22,3 +22,5 @@ export const fetchMarkdown = (path) =>
: path.replace(/\.\w{2, 4}$/, "");
return { title, raw, content };
});
export default fetchMarkdown;

View File

@ -1,7 +1,20 @@
//@ts-check
import { changeTitle } from "./changeTitle.mjs";
import { documentMode } from "./documentMode.mjs";
import { fetchMarkdown } from "./fetchMarkdown.mjs";
import { fetchText } from "./fetchText.mjs";
import { generateDomFromString } from "./generateDomFromString.mjs";
import { getCurrentHashUrl } from "./getCurrentHashUrl.mjs";
import { getElementById } from "./getElementById.mjs";
import { isExternalUrl } from "./isExternalUrl.mjs";
import { isLocalHost } from "./isLocalHost.mjs";
import { isNotNull } from "./isNotNull.mjs";
import {
onDocumentKeyUp,
onDocumentKeyDown,
onDocumentKey,
} from "./onDocumentKey.mjs";
import { parseFileList } from "./parseFileList.mjs";
import {
querySelectorDoc,
@ -9,7 +22,30 @@ import {
querySelectorAll,
} from "./querySelectorAll.mjs";
import { rewriteLocalUrls } from "./rewriteLocalUrls.mjs";
import * as templateBlog from "./templateBlogUtils.mjs";
import { wait } from "./wait.mjs";
import { waitIfLocalHost } from "./waitIfLocalHost.mjs";
export { isExternalUrl, isLocalHost, rewriteLocalUrls, wait, waitIfLocalHost };
export {
changeTitle,
documentMode,
fetchMarkdown,
fetchText,
generateDomFromString,
getCurrentHashUrl,
getElementById,
isExternalUrl,
isLocalHost,
isNotNull,
onDocumentKeyUp,
onDocumentKeyDown,
onDocumentKey,
parseFileList,
querySelectorDoc,
querySelectorParent,
querySelectorAll,
rewriteLocalUrls,
templateBlog,
wait,
waitIfLocalHost,
};

View File

@ -1,3 +1,5 @@
//@ts-check
/**
*
* @param {string} keyToListen
@ -9,3 +11,33 @@ export const onDocumentKeyUp = (keyToListen, callback) => {
({ key }) => key === keyToListen && callback()
);
};
/**
*
* @param {string} keyToListen
* @param {()=>void} callback
*/
export const onDocumentKeyDown = (keyToListen, callback) => {
document.addEventListener(
"keydown",
({ key }) => key === keyToListen && callback()
);
};
/**
*
* @param {string} keyToListen
* @param {(down:boolean)=>void} callback
*/
export const onDocumentKey = (keyToListen, callback) => {
document.addEventListener(
"keyup",
({ key }) => key === keyToListen && callback(false)
);
document.addEventListener(
"keydown",
({ key }) => key === keyToListen && callback(true)
);
};
export default onDocumentKey;

View File

@ -1,107 +1,4 @@
//@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;
import blog from "./templateBlogUtils.mjs";
blog();

View File

@ -0,0 +1,107 @@
//@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();
};
export 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;