diff options
Diffstat (limited to 'js/navigation.ts')
-rw-r--r-- | js/navigation.ts | 174 |
1 files changed, 63 insertions, 111 deletions
diff --git a/js/navigation.ts b/js/navigation.ts index 4a83be6..c1af99f 100644 --- a/js/navigation.ts +++ b/js/navigation.ts @@ -1,145 +1,97 @@ -async function loadPage(page_name: string, anchor?: string) { - console.log(`loading page \`${page_name}\``); +namespace Ach { + export async function loadPage(page_name: string, anchor?: string) { + console.log(`loading page \`${page_name}\``); - let url = `/html/${page_name}.html`; - console.log(`note: page is at "${url}"`); + window.scrollTo({ + top: 0.0, + left: undefined, + behavior: "smooth", + }); - window.history.pushState(page_name, "", url); + let url = `/html/${page_name}.html`; + console.log(`note: page is at "${url}"`); - let response = await fetch(url); + window.history.pushState(page_name, "", url); - if (!response.ok) { - throw new Error(`unable to load page: \"${response.status}\"`); - } + let response = await fetch(url); - let markup = await response.text(); + if (!response.ok) { + throw new Error(`unable to load page: \"${response.status}\"`); + } - let parser = new DOMParser(); - let dom = parser.parseFromString(markup, "text/html"); + let markup = await response.text(); - let titles = document.getElementsByTagName("title"); - let bodies = document.getElementsByTagName("body"); - let page = document.getElementById("page")!; + let parser = new DOMParser(); + let dom = parser.parseFromString(markup, "text/html"); - if (titles.length < 0x1) { - throw new Error("unable to find title"); - } + let body = Ach.getFirstElement(document, "body"); - if (bodies.length < 0x1) { - throw new Error("unable to find body"); - } + let title = Ach.getFirstElement(document, "title"); + let page = Ach.getOnlyElement(document, "page"); - if (!page) { - throw new Error("unable to find page element"); - } + let newTitle = Ach.getFirstElement(dom, "title"); + let newPage = Ach.getOnlyElement(dom, "page"); - let newTitles = dom.getElementsByTagName("title"); - let newPage = dom.getElementById("page"); + title.replaceWith(newTitle); + body.setAttribute("data-page", page_name); + page.replaceWith(newPage); - if (newTitles.length < 0x1) { - throw new Error("unable to find new title"); - } + initImages(); + initLinks(); - if (!newPage) { - throw new Error("unable to find new page element"); - } + if (anchor) { + console.log(`going to anchor \`${anchor}\``); - titles[0x0].replaceWith(newTitles[0x0]); - bodies[0x0].setAttribute("data-page", page_name); - page.replaceWith(newPage); + anchor = `anchor.${anchor}`; - initImages(); + console.log(`note: anchor has id "${anchor}"`); - if (anchor) { - console.log(`going to anchor \`${anchor}\``); + let anchor_element = document.getElementById(anchor); - anchor = `anchor.${anchor}`; + if (!anchor_element) { + throw new Error(`unable to find anchor "${anchor}"`); + } - console.log(`note: anchor has id "${anchor}"`); - - let anchor_element = document.getElementById(anchor); - - if (!anchor_element) { - throw new Error(`unable to find anchor "${anchor}"`); + anchor_element.scrollIntoView({ + behavior: "smooth", + }); } + } - anchor_element.scrollIntoView({ + export function toggleSideMenu() { + window.scrollTo({ + top: 0.0, + left: undefined, behavior: "smooth", }); - } -} - -function toggleSideMenu() { - scrollToTop(); - - let sideMenu = document.getElementById("sideMenu"); - let navBar = document.getElementById("navBar"); - let glyph = document.getElementById("glyph"); - - if (!sideMenu) { - throw new Error("unable to find sideMenu"); - } - - if (!navBar) { - throw new Error("unable to find navigation bar"); - } - - if (!glyph) { - throw new Error("unable to find glyph"); - } - sideMenu.classList.toggle("visible"); - glyph.classList.toggle("hidden"); + let sideMenu = Ach.getOnlyElement(document, "sideMenu"); + let navBar = Ach.getOnlyElement(document, "navBar"); + let glyph = Ach.getOnlyElement(document, "glyph"); - for (let link of navBar.getElementsByTagName("a")) { - link.classList.toggle("hidden"); - } -} - -async function scrollToTop() { - window.scroll({ - top: 0, - left: 0, - behavior: "smooth", - }); -} + sideMenu.classList.toggle("visible"); + glyph.classList.toggle("hidden"); -function initImages() { - let page = document.getElementById("page"); - - if (!page) { - throw new Error("unable to find page"); + for (let link of navBar.getElementsByTagName("a")) { + link.classList.toggle("hidden"); + } } - let imageList = Array.from(page.getElementsByTagName("x-image")); + export function parseInternalLink(address: string): [string, string | undefined] | undefined { + let regex = /\/html\/([A-Za-z0-9]+)\.html(?:#([A-Za-z0-9]+)){0,1}/; + let regex_result = regex.exec(address); - for (let image of imageList) { - let file = image.getAttribute("data-file"); - - if (!file) { - throw new Error("file not set for image element") + if (!regex_result) { + return; } - console.log("initialising image that links to \"" + file + "\""); - - let sourceUrl = "/image/source/" + file + ".webp"; - let thumbnailUrl = "/image/thumbnail/" + file + ".avif"; + let page = regex_result[0x1]; + let anchor = regex_result[0x2]; - let blurElement = document.createElement("img"); - blurElement.setAttribute("class", "blur"); - blurElement.setAttribute("src", thumbnailUrl); - - let hyperlinkElement = document.createElement("a"); - hyperlinkElement.setAttribute("href", sourceUrl); - hyperlinkElement.setAttribute("rel", "noopener noreferrer"); - hyperlinkElement.setAttribute("target", "_blank"); - - let image_element = document.createElement("img"); - image_element.setAttribute("src", thumbnailUrl); - - hyperlinkElement.appendChild(image_element); + if (!page) { + return; + } - image.appendChild(blurElement); - image.appendChild(hyperlinkElement); + return [page, anchor]; } } |