presentation/widgets/citation.widget.ts

presentation/widgets/citation.widget.ts is a file in Bane's Lab Site. 28 lines of code and 7 definitions.

import { CITED_PANEL_CLASS, CITE_CLASS } from "#configuration/constants/chapter.constants";
import { HREF_ATTRIBUTE, NONE } from "#configuration/constants/element.constants";
import { ANCHOR_PREFIX } from "#configuration/constants/document.constants";
import type { Disposer } from "#types/base.types";

const CITE_LINK_SELECTOR = `a.${CITE_CLASS}`;

const citedPanelOf = function citedPanelOf(node: EventTarget | null): HTMLElement | null {
    const link = node instanceof Element ? node.closest(CITE_LINK_SELECTOR) : null;
    const href = link?.getAttribute(HREF_ATTRIBUTE) ?? NONE;
    return href.startsWith(ANCHOR_PREFIX) ? document.getElementById(href.slice(ANCHOR_PREFIX.length)) : null;
};

export const mountCite = function mountCite(): Disposer {
    const onEnter = function onEnter(event: Event): void {
        citedPanelOf(event.target)?.classList.add(CITED_PANEL_CLASS);
    };
    const onLeave = function onLeave(event: Event): void {
        citedPanelOf(event.target)?.classList.remove(CITED_PANEL_CLASS);
    };
    document.addEventListener("mouseover", onEnter);
    document.addEventListener("mouseout", onLeave);
    document.addEventListener("focusin", onEnter);
    document.addEventListener("focusout", onLeave);
    return () => {
        document.removeEventListener("mouseover", onEnter);
        document.removeEventListener("mouseout", onLeave);
        document.removeEventListener("focusin", onEnter);
        document.removeEventListener("focusout", onLeave);
    };
};