// doc/page_utils.js // Small helpers shared by documentation demo pages (3rd column). (function () { function qs(sel) { return document.querySelector(sel); } function qsa(sel) { return Array.from(document.querySelectorAll(sel)); } function showToast(msg) { const el = document.getElementById('toast'); if (!el) return; el.textContent = msg; el.classList.add('show'); clearTimeout(el._t); el._t = setTimeout(() => el.classList.remove('show'), 900); } async function copyActiveCode() { const active = qs('.code-view.active, .html-view.active, .css-view.active'); const text = active ? active.innerText.trimEnd() : ''; if (!text) return; try { await navigator.clipboard.writeText(text); showToast('Copied'); } catch (e) { // Fallback const ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove(); showToast('Copied'); } } function switchTab(tab) { const tabs = qsa('.tabs .tab'); tabs.forEach(t => t.classList.remove('active')); qsa('.code-view, .html-view, .css-view').forEach(v => v.classList.remove('active')); const t = String(tab || 'js').toLowerCase(); const idx = (t === 'js') ? 0 : (t === 'html') ? 1 : 2; const tabEls = [tabs[0], tabs[1], tabs[2]]; const viewEls = [ document.getElementById('js-code'), document.getElementById('html-code'), document.getElementById('css-code') ]; tabEls.forEach((el, i) => { if (!el) return; const active = i === idx; el.classList.toggle('active', active); el.setAttribute('aria-selected', active ? 'true' : 'false'); el.tabIndex = active ? 0 : -1; }); const view = viewEls[idx]; if (view) view.classList.add('active'); } function enableTabKeyboardNav() { document.addEventListener('keydown', (e) => { const focused = document.activeElement; if (!focused || !focused.classList.contains('tab')) return; if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return; e.preventDefault(); const tabs = qsa('.tabs .tab'); const idx = Math.max(0, tabs.indexOf(focused)); const nextIdx = (e.key === 'ArrowRight') ? (idx + 1) % tabs.length : (idx - 1 + tabs.length) % tabs.length; const next = tabs[nextIdx]; const label = (next?.textContent || '').toLowerCase(); const lang = label.includes('html') ? 'html' : label.includes('css') ? 'css' : 'js'; switchTab(lang); qs('.tab.active')?.focus(); }); } function syncPrevNext(currentUrl) { try { const pn = window.parent?.docGetPrevNext?.(currentUrl); const prevEl = document.getElementById('prev-title'); const nextEl = document.getElementById('next-title'); const centerEl = document.getElementById('nav-center'); if (centerEl) centerEl.textContent = pn?.current?.group || centerEl.textContent || ''; if (prevEl) prevEl.textContent = pn?.prev?.title || '—'; if (nextEl) nextEl.textContent = pn?.next?.title || '—'; } catch {} } function syncMiddleActive(currentUrl) { try { window.parent?.setMiddleActive?.(currentUrl); } catch {} } // Expose window.DocPage = { showToast, copyActiveCode, switchTab, enableTabKeyboardNav, syncPrevNext, syncMiddleActive }; }());