blob: aa99842a89ecce1f6aac2fcdae97035eb5fc0187 [file] [log] [blame]
{
"version": 3,
"sources": ["index.ts"],
"sourcesContent": ["/**\n * Left Navigation.\n */\nexport const initJumpLinks = async function () {\n const pagesWithJumpLinks = ['/about'];\n if (!pagesWithJumpLinks.includes(window.location.pathname)) {\n // stop the file from doing anything else if the page doesn't have jumplinks\n return;\n }\n\n // these might be generated or not so don't grab references to the elements until actually need them.\n const titles = 'h2, h3, h4';\n const nav = '.LeftNav a';\n // these are always in the dom so we can get them now and throw errors if they're not.\n const leftNav = document.querySelector('.LeftNav');\n const siteContent = document.querySelector('.go-Content');\n let isObserverDisabled = false;\n\n /**\n * El function\n * @example el('h1', {className: 'title'}, 'Welcome to the site');\n * @example el('ul', {className: 'list'}, el('li', {}, 'Item one'), el('li', {}, 'Item two'), el('li', {}, 'Item three'));\n * @example el('img', {src: '/url.svg'});\n */\n function el(\n type = '',\n props: { [key: string]: string } = {},\n ...children: (HTMLElement | HTMLElement[] | string | undefined)[]\n ) {\n // Error, no type declared.\n if (!type) {\n throw new Error('Provide `type` to create document element.');\n }\n\n // Create element with optional attribute props\n const docEl = Object.assign(document.createElement(type), props);\n\n // Children: array containing strings or elements\n children.forEach(child => {\n if (typeof child === 'string') {\n docEl.appendChild(document.createTextNode(child));\n } else if (Array.isArray(child)) {\n child.forEach(c => docEl.appendChild(c));\n } else if (child instanceof HTMLElement) {\n docEl.appendChild(child);\n }\n });\n\n return docEl;\n }\n /** Build Nav if data hydrate is present. */\n function buildNav() {\n return new Promise((resolve, reject) => {\n let navItems: { id: string; label: string; subnav?: { id: string; label: string }[] }[] = [];\n let elements: HTMLElement[] = [];\n\n if (!siteContent || !leftNav) {\n return reject('.SiteContent not found.');\n }\n if (leftNav instanceof HTMLElement && !leftNav?.dataset?.hydrate) {\n return resolve(true);\n }\n\n for (const title of siteContent.querySelectorAll(titles)) {\n if (title instanceof HTMLElement && !title?.dataset?.ignore) {\n switch (title.tagName) {\n case 'H2':\n navItems = [\n ...navItems,\n {\n id: title.id,\n label: title?.dataset?.title ? title.dataset.title : title.textContent ?? '',\n },\n ];\n break;\n\n case 'H3':\n case 'H4':\n if (!navItems[navItems.length - 1]?.subnav) {\n navItems[navItems.length - 1].subnav = [\n {\n id: title.id,\n label: title?.dataset?.title ? title.dataset.title : title.textContent ?? '',\n },\n ];\n } else if (navItems[navItems.length - 1].subnav) {\n navItems[navItems.length - 1].subnav?.push({\n id: title.id,\n label: title?.dataset?.title ? title.dataset.title : title.textContent ?? '',\n });\n }\n break;\n }\n }\n }\n\n for (const navItem of navItems) {\n const link = el('a', { href: '#' + navItem.id }, el('span', {}, navItem.label));\n elements = [...elements, link];\n if (navItem?.subnav) {\n let subLinks: HTMLElement[] = [];\n for (const subnavItem of navItem.subnav) {\n const subItem = el(\n 'li',\n {},\n el(\n 'a',\n { href: '#' + subnavItem.id },\n el('img', { src: '/static/frontend/about/dot.svg', width: '5', height: '5' }),\n el('span', {}, subnavItem.label)\n )\n );\n subLinks = [...subLinks, subItem];\n }\n const list = el('ul', { className: 'LeftSubnav' }, subLinks);\n elements = [...elements, list];\n }\n }\n\n elements.forEach(element => leftNav.appendChild(element));\n\n return resolve(true);\n });\n }\n /**\n * Set the correct active element.\n */\n function setNav() {\n return new Promise(resolve => {\n if (!document.querySelectorAll(nav)) return resolve(true);\n for (const a of document.querySelectorAll(nav)) {\n if (a instanceof HTMLAnchorElement && a.href === location.href) {\n setElementActive(a);\n break;\n }\n }\n resolve(true);\n });\n }\n /** resetNav: removes all .active from nav elements */\n function resetNav() {\n return new Promise(resolve => {\n if (!document.querySelectorAll(nav)) return resolve(true);\n for (const a of document.querySelectorAll(nav)) {\n a.classList.remove('active');\n }\n resolve(true);\n });\n }\n /** setElementActive: controls resetting nav and highlighting the appropriate nav items */\n function setElementActive(element: HTMLAnchorElement) {\n if (element instanceof HTMLAnchorElement) {\n resetNav().then(() => {\n element.classList.add('active');\n const parent = element?.parentNode?.parentNode;\n if (parent instanceof HTMLElement && parent?.classList?.contains('LeftSubnav')) {\n parent.previousElementSibling?.classList.add('active');\n }\n });\n }\n }\n /** setLinkManually: disables observer and selects the clicked nav item. */\n function setLinkManually() {\n delayObserver();\n const link = document.querySelector('[href=\"' + location.hash + '\"]');\n if (link instanceof HTMLAnchorElement) {\n setElementActive(link);\n }\n }\n /** delayObserver: Quick on off switch for intersection observer. */\n function delayObserver() {\n isObserverDisabled = true;\n setTimeout(() => {\n isObserverDisabled = false;\n }, 200);\n }\n /** observeSections: kicks off observation of titles as well as manual clicks with hashchange */\n function observeSections() {\n window.addEventListener('hashchange', setLinkManually);\n\n if (siteContent?.querySelectorAll(titles)) {\n const callback: IntersectionObserverCallback = entries => {\n if (!isObserverDisabled && Array.isArray(entries) && entries.length > 0) {\n for (const entry of entries) {\n if (entry.isIntersecting && entry.target instanceof HTMLElement) {\n const { id } = entry.target;\n const link = document.querySelector('[href=\"#' + id + '\"]');\n if (link instanceof HTMLAnchorElement) {\n setElementActive(link);\n }\n break;\n }\n }\n }\n };\n // rootMargin is important when multiple sections are in the observable area **on page load**.\n // they will still be highlighted on scroll because of the root margin.\n const ob = new IntersectionObserver(callback, {\n threshold: 0,\n rootMargin: '0px 0px -50% 0px',\n });\n for (const title of siteContent.querySelectorAll(titles)) {\n if (title instanceof HTMLElement && !title?.dataset?.ignore) {\n ob.observe(title);\n }\n }\n }\n }\n\n try {\n await buildNav();\n await setNav();\n if (location.hash) {\n delayObserver();\n }\n observeSections();\n } catch (e) {\n if (e instanceof Error) {\n console.error(e.message);\n } else {\n console.error(e);\n }\n }\n};\n"],
"mappings": "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",
"names": []
}