/** * -------------------------------------------------------------------- * docmd : the zero-config documentation engine. * * @package @docmd/core (and ecosystem) * @website https://docmd.io * @repository https://github.com/docmd-io/docmd * @license MIT * @copyright Copyright (c) 2025-present docmd.io * * [docmd-source] - Please do not remove this header. * -------------------------------------------------------------------- */ /** * -------------------------------------------------------------------- * docmd : Client-Side Application Logic (SPA Router & UI) * -------------------------------------------------------------------- */ /* global CSS */ (function () { // Idempotency guard. Some servers (e.g. `serve` with SPA fallback) can // request this same script twice — once at the page-relative URL, once // at the site root — and both copies execute. Without this guard, every // click handler (toggle, SPA nav, copy code, etc.) would bind twice and // every nav action would fire two times, silently breaking the sidebar. if (window.__docmdMainLoaded) return; window.__docmdMainLoaded = true; function findTargetElement(hash) { if (!hash) return null; const cleanHash = hash.substring(1); if (!cleanHash) return null; try { let target = document.getElementById(cleanHash) || document.querySelector(hash); if (target) return target; target = document.querySelector('[id$="-' + CSS.escape(cleanHash) + '"]'); if (target) return target; } catch (_e) { /* ignore */ } return null; } // 1. EVENT DELEGATION document.addEventListener('click', (e) => { // Collapsible Navigation // - Chevron (.collapse-icon-wrapper) click: always toggle, preventDefault. // - Dummy section divider: toggle, preventDefault. // - Real label click: navigate via SPA. The new // page's sidebar auto-expands the active group, so parents that are // pages themselves (e.g. "Syntax" with children) open as pages, // not as collapsed sections. const navTrigger = e.target.closest('.nav-group, .collapse-icon-wrapper'); if (navTrigger) { const item = navTrigger.closest('li.collapsible'); const isChevron = navTrigger.classList.contains('collapse-icon-wrapper'); const isDummySpan = navTrigger.tagName !== 'A'; // Offline-mode safety (issue #164): under file:// the SPA click handler // is not registered (initializeSPA short-circuits at line 581), so this // is the only click handler that runs. closest('.nav-group') can walk // past an empty-class nested and match the parent