'use strict'; (() => { const timers = new WeakMap(); const status = document.getElementById('copy-status'); let statusTimer; document.querySelectorAll('[data-copy-target]').forEach(button => { button.addEventListener('click', async () => { const target = document.getElementById(button.dataset.copyTarget); if (!target || button.disabled) return; button.disabled = true; button.setAttribute('aria-busy', 'true'); const original = button.dataset.originalText || button.textContent; button.dataset.originalText = original; let success = false; try { await navigator.clipboard.writeText(target.textContent); success = true; } catch { const field = document.createElement('textarea'); field.value = target.textContent; field.setAttribute('readonly', ''); field.style.cssText = 'position:fixed;opacity:0;top:0;left:0;pointer-events:none'; document.body.appendChild(field); field.select(); try { success = document.execCommand('copy'); } catch { /* Keep the manual copy fallback visible. */ } field.remove(); button.focus({preventScroll:true}); } clearTimeout(timers.get(button)); clearTimeout(statusTimer); button.dataset.copyState = success ? 'success' : 'error'; button.textContent = success ? '已复制 ✓' : '请手动复制'; if (status) status.textContent = success ? '已复制到剪贴板' : '复制失败,请选中命令后手动复制'; timers.set(button, setTimeout(() => { button.textContent = original; delete button.dataset.copyState; }, 2200)); statusTimer = setTimeout(() => { if (status) status.textContent = ''; }, 2600); button.disabled = false; button.removeAttribute('aria-busy'); }); }); const themeButton = document.querySelector('.docs-theme'); const updateThemeButton = () => { const dark = document.documentElement.classList.contains('dark'); themeButton?.setAttribute('aria-pressed', String(dark)); themeButton?.setAttribute('aria-label', dark ? '切换为浅色主题' : '切换为深色主题'); themeButton?.setAttribute('title', dark ? '切换为浅色主题' : '切换为深色主题'); }; updateThemeButton(); themeButton?.addEventListener('click', () => { const dark = document.documentElement.classList.toggle('dark'); try { localStorage.setItem('newapi:theme:v1:mode', dark ? 'dark' : 'light'); } catch { /* Theme still works without storage. */ } updateThemeButton(); }); if (!('IntersectionObserver' in window)) return; const reduced = window.matchMedia('(prefers-reduced-motion: reduce)'); if (!reduced.matches) { const reveal = new IntersectionObserver(entries => { entries.forEach(entry => { if (!entry.isIntersecting) return; entry.target.classList.add('is-revealed'); reveal.unobserve(entry.target); }); }, {threshold: 0.06}); document.querySelectorAll('[data-docs-reveal]').forEach(panel => reveal.observe(panel)); } const links = [...document.querySelectorAll('.toc a[href^="#"]')]; const sections = links.map(link => document.getElementById(link.hash.slice(1))).filter(Boolean); if (!sections.length) return; let active = null; const visible = new Set(); const mark = id => { if (id === active) return; active = id; links.forEach(link => { if (link.hash === '#' + id) link.setAttribute('aria-current', 'location'); else link.removeAttribute('aria-current'); }); }; const initial = document.getElementById(location.hash.slice(1)); mark(initial && sections.includes(initial) ? initial.id : sections[0].id); const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) visible.add(entry.target); else visible.delete(entry.target); }); const candidates = sections.filter(section => visible.has(section)); if (candidates.length) mark(candidates[0].id); }, {rootMargin: '-16% 0px -58% 0px', threshold: 0}); sections.forEach(section => observer.observe(section)); links.forEach(link => link.addEventListener('click', () => mark(link.hash.slice(1)))); })();