/** * WP Modern Blog — İçindekiler (TOC) JavaScript * * - Scroll'a göre aktif başlık vurgulama (IntersectionObserver) * - TOC toggle (göster/gizle) * - Başlıklara smooth scroll */ ( function () { 'use strict'; function init() { const toc = document.getElementById( 'toc' ); const tocLinks = toc ? Array.from( toc.querySelectorAll( 'a[href^="#"]' ) ) : []; if ( ! toc || tocLinks.length === 0 ) return; // ─── TOC Toggle ────────────────────────────────────────────────────── const toggleBtn = document.getElementById( 'toc-toggle' ); const tocList = toc.querySelector( 'ol, ul' ); const tocArrow = toggleBtn ? toggleBtn.querySelector( '[data-toc-arrow]' ) : null; if ( toggleBtn && tocList ) { toggleBtn.addEventListener( 'click', function () { const isHidden = tocList.classList.toggle( 'hidden' ); toggleBtn.setAttribute( 'aria-expanded', isHidden ? 'false' : 'true' ); if ( tocArrow ) { tocArrow.classList.toggle( 'rotate-180', ! isHidden ); } // Tercihi kaydet try { localStorage.setItem( 'wpmb_toc_collapsed', isHidden ? '1' : '0' ); } catch ( _ ) {} } ); // Kaydedilmiş durumu uygula try { if ( localStorage.getItem( 'wpmb_toc_collapsed' ) === '1' ) { tocList.classList.add( 'hidden' ); toggleBtn.setAttribute( 'aria-expanded', 'false' ); if ( tocArrow ) tocArrow.classList.add( 'rotate-180' ); } } catch ( _ ) {} } // ─── Aktif Başlık Vurgulama (IntersectionObserver) ─────────────────── const headingIds = tocLinks.map( function ( a ) { return a.getAttribute( 'href' ).replace( '#', '' ); } ); const headings = headingIds.reduce( function ( acc, id ) { const el = document.getElementById( id ); if ( el ) acc.push( el ); return acc; }, [] ); if ( headings.length === 0 ) return; let activeId = null; function setActive( id ) { if ( id === activeId ) return; activeId = id; tocLinks.forEach( function ( link ) { const isActive = link.getAttribute( 'href' ) === '#' + id; link.classList.toggle( 'text-primary-700', isActive ); link.classList.toggle( 'font-semibold', isActive ); link.classList.toggle( 'text-gray-600', ! isActive ); } ); } // Görünür başlıkları takip et const visibleHeadings = new Set(); const observer = new IntersectionObserver( function ( entries ) { entries.forEach( function ( entry ) { if ( entry.isIntersecting ) { visibleHeadings.add( entry.target.id ); } else { visibleHeadings.delete( entry.target.id ); } } ); // En üstteki görünür başlığı bul let topId = null; for ( let i = 0; i < headings.length; i++ ) { if ( visibleHeadings.has( headings[ i ].id ) ) { topId = headings[ i ].id; break; } } if ( topId ) { setActive( topId ); } }, { rootMargin: '-64px 0px -60% 0px', // header yüksekliği kadar yukarı kaydır threshold: 0, } ); headings.forEach( function ( h ) { observer.observe( h ); } ); // ─── Smooth Scroll (href="#...") ────────────────────────────────────── toc.addEventListener( 'click', function ( e ) { const link = e.target.closest( 'a[href^="#"]' ); if ( ! link ) return; const targetId = link.getAttribute( 'href' ).replace( '#', '' ); const target = document.getElementById( targetId ); if ( ! target ) return; e.preventDefault(); const headerHeight = parseInt( getComputedStyle( document.documentElement ).getPropertyValue( '--header-height' ) || '64', 10 ); const top = target.getBoundingClientRect().top + window.pageYOffset - headerHeight - 8; window.scrollTo( { top, behavior: 'smooth' } ); history.replaceState( null, '', '#' + targetId ); } ); } if ( document.readyState !== 'loading' ) init(); else document.addEventListener( 'DOMContentLoaded', init ); } )();