Files
q-edit/scripts/init-page-hash.mjs
2025-09-02 21:04:17 -04:00

74 lines
2.0 KiB
JavaScript

import { getState, setPage } from "../src/state/hash.js";
/**
* Delegate clicks on [data-page] within pagination containers to update the URL hash.
* Also reflects active page state using aria-current='page' and 'is-active' class.
*/
function bindContainer(container) {
if (!container || container.dataset.pageHashInitialized === "1") {
return;
}
container.dataset.pageHashInitialized = "1";
container.addEventListener("click", (e) => {
const el = /** @type {HTMLElement|null} */ (
e.target instanceof HTMLElement ? e.target.closest("[data-page]") : null
);
if (!el) {
return;
}
const v = el.getAttribute("data-page");
if (!v) {
return;
}
const n = Number(v);
if (!Number.isFinite(n) || n < 1) {
return;
}
e.preventDefault();
setPage(n);
});
}
function reflectActive() {
const { page } = getState();
const current = Number.isFinite(page) && page > 0 ? page : null;
const containers = [
document.getElementById("pagination-top"),
document.getElementById("pagination-bottom"),
].filter(Boolean);
for (const c of containers) {
const items = c.querySelectorAll("[data-page]");
items.forEach((el) => {
const n = Number(el.getAttribute("data-page"));
const isActive = current != null && n === current;
if (isActive) {
el.classList.add("is-active");
el.setAttribute("aria-current", "page");
} else {
el.classList.remove("is-active");
el.removeAttribute("aria-current");
}
});
}
}
export function initPageHash() {
const top = document.getElementById("pagination-top");
const bottom = document.getElementById("pagination-bottom");
bindContainer(top);
bindContainer(bottom);
reflectActive();
window.addEventListener("hashchange", reflectActive);
document.addEventListener("qedit:hash:updated", reflectActive);
}
// Auto-init on DOM ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => initPageHash(), { once: true });
} else {
initPageHash();
}