feat(glossaire): polish sticky entry flow and aside navigation
All checks were successful
SMOKE / smoke (push) Successful in 18s
CI / build-and-anchors (push) Successful in 48s
CI / build-and-anchors (pull_request) Successful in 48s

This commit is contained in:
2026-03-24 00:29:39 +01:00
parent e39a0c547d
commit 87955adf5d
18 changed files with 3639 additions and 584 deletions

View File

@@ -1529,27 +1529,39 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
return headerH() + PAGE_GAP + localH + (followH || 0) + HYST;
}
function hasCrossed(el, lineY) {
function hasCrossedTop(el, lineY) {
return Boolean(el && el.getBoundingClientRect().top <= lineY);
}
function hasCrossedBottom(el, lineY) {
return Boolean(el && el.getBoundingClientRect().bottom <= lineY);
}
function getH2DisplayEl(item) {
return item?.h2 || item?.marker || item?.anchor || null;
}
function getH3DisplayEl(item) {
return item?.el || null;
}
function pickH2(lineY) {
if (!H2.length) return null;
let cand = null;
for (const t of H2) {
if (hasCrossed(t.marker, lineY)) cand = t;
const box = getH2DisplayEl(t);
if (hasCrossedBottom(box, lineY)) cand = t;
else break;
}
// Tant quaucun H2 na franchi la ligne de suivi,
// on ne montre rien.
if (!cand) return null;
const down = (window.scrollY || 0) >= lastY;
if (!down && cand && curH2 && cand.id !== curH2.id) {
const topNew = cand.marker.getBoundingClientRect().top;
if (topNew > lineY - (HYST * 2)) cand = curH2;
const box = getH2DisplayEl(cand);
const bottomNew = box ? box.getBoundingClientRect().bottom : Infinity;
if (bottomNew > lineY + (HYST * 2)) cand = curH2;
}
return cand;
@@ -1586,7 +1598,8 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
let cand = null;
for (const t of scoped) {
if (hasCrossed(t.el, lineY)) cand = t;
const box = getH3DisplayEl(t);
if (hasCrossedBottom(box, lineY)) cand = t;
else break;
}
@@ -1596,7 +1609,7 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
function maybeOpenActiveSection(activeH2, lineY) {
if (!activeH2 || !activeH2.id) return;
const pre = activeH2.marker.getBoundingClientRect().top <= (lineY + 140);
const pre = hasCrossedTop(activeH2.marker, lineY + 140);
if (!pre) return;
if (activeH2.id !== lastOpenedH2) {
@@ -1625,13 +1638,13 @@ const WHOAMI_FORCE_LOCALHOST = (import.meta.env.PUBLIC_WHOAMI_FORCE_LOCALHOST ??
curH3 = nextH3;
if (rfH2) {
const show = Boolean(curH2 && hasCrossed(curH2.marker, lineY));
const show = Boolean(curH2 && hasCrossedBottom(getH2DisplayEl(curH2), lineY));
rfH2.hidden = !show;
if (show) rfH2.textContent = curH2.title;
}
if (rfH3) {
const show = Boolean(curH3 && hasCrossed(curH3.el, lineY));
const show = Boolean(curH3 && hasCrossedBottom(getH3DisplayEl(curH3), lineY));
rfH3.hidden = !show;
if (show) rfH3.textContent = curH3.title;
}