/** * AKSRT Section Navs — legacy section_navs parity (posts-nav-lists + scrollspy). * * Builds TOC from [data-nav] h1–h4 into .posts-nav-box / .posts-nav-lists. * * @package AKSRT */ (function () { 'use strict'; var HEADING_SEL = 'h1, h2, h3, h4'; var MIN_HEADINGS = 3; var NAVBOX = '.posts-nav-box'; var NAV_CLASS = 'posts-nav-lists'; function isExcluded(el) { return el.classList.contains('item-heading') || !!el.closest('.no-nav'); } function ensureId(el, index) { if (!el.id) { el.id = 'wznav_' + index; } return el.id; } function buildLists(root) { var headings = root.querySelectorAll(HEADING_SEL); var html = ''; var count = 0; headings.forEach(function (h, i) { if (isExcluded(h)) return; var id = ensureId(h, i); var tag = h.tagName.toUpperCase(); var text = (h.textContent || '').trim(); if (!text) return; html += '
  • ' + text + '
  • '; count++; }); return count >= MIN_HEADINGS ? html : ''; } function fillBoxes(listsHtml) { document.querySelectorAll(NAVBOX).forEach(function (box) { var existing = box.querySelector('.' + NAV_CLASS); if (existing) { existing.innerHTML = listsHtml; return; } var title = box.getAttribute('data-title') || ''; var titleHtml = title ? '
    ' + title + '
    ' : ''; box.insertAdjacentHTML( 'beforeend', titleHtml + '
    ' ); }); } function smoothTo(hash) { var el = document.querySelector(hash); if (!el) return; var offset = 0; var header = document.querySelector('.header'); if (document.body.classList.contains('nav-fixed') && header) { offset = header.offsetHeight + 12; } var top = el.getBoundingClientRect().top + window.pageYOffset - offset; window.scrollTo({ top: top, behavior: 'smooth' }); } function bindClicks() { document.addEventListener('click', function (e) { var a = e.target && e.target.closest ? e.target.closest('.' + NAV_CLASS + ' a[href^="#"]') : null; if (!a) return; var href = a.getAttribute('href'); if (!href || href.length < 2) return; e.preventDefault(); history.replaceState(null, '', href); smoothTo(href); }); } function scrollspy() { var links = document.querySelectorAll('.' + NAV_CLASS + ' a[href^="#"]'); if (!links.length) return; var map = []; links.forEach(function (a) { var id = a.getAttribute('href').slice(1); var el = document.getElementById(id); if (el) map.push({ el: el, a: a, li: a.parentElement }); }); function update() { var y = window.scrollY + 110; var current = null; for (var i = 0; i < map.length; i++) { if (map[i].el.offsetTop <= y) current = map[i]; } map.forEach(function (m) { if (m.li) m.li.classList.toggle('active', m === current); }); } window.addEventListener('scroll', update, { passive: true }); update(); } function autoHash() { if (window.location.hash) { setTimeout(function () { smoothTo(window.location.hash); }, 40); } } function init() { if (document.documentElement.dataset.aksrtSectionNavInitialized === '1') return; document.documentElement.dataset.aksrtSectionNavInitialized = '1'; if (document.querySelector('.posts-nav-box .toc-list, .posts-nav-box.toc-widget .toc-list')) { return; } var root = document.querySelector('[data-nav], .article-content, .entry-content, main.article'); if (!root) return; var listsHtml = buildLists(root); if (!listsHtml) return; if (!document.querySelector(NAVBOX) && !document.querySelector('.' + NAV_CLASS)) { return; } fillBoxes(listsHtml); bindClicks(); scrollspy(); autoHash(); } jQuery(document).off('auto_fun.aksrt-section-navs').on('auto_fun.aksrt-section-navs', init); })();