()
| 2673 | function _wifiFsClose(el) { |
| 2674 | el.classList.add('hidden'); |
| 2675 | el.setAttribute('aria-hidden', 'true'); |
| 2676 | document.body.classList.remove('wifi-fs-open'); |
| 2677 | _wifiState.fs.open = false; |
| 2678 | _wifiState.hoverBssid = null; |
| 2679 | document.removeEventListener('keydown', _wifiFsKey); |
| 2680 | if (document.fullscreenElement && _wifiState.fs.native) document.exitFullscreen().catch(() => {}); |
| 2681 | _wifiState.fs.native = false; |
| 2682 | if (_wifiState.view === 'waterfall') _wifiDrawWaterfall(); |
| 2683 | else if (_wifiState.data) _wifiDrawSpectrum(); |
| 2684 | } |
| 2685 | |
| 2686 | function _wifiFsWire() { |
| 2687 | if (_wifiState.fs.wired) return; |
| 2688 | _wifiState.fs.wired = true; |
| 2689 | document.querySelectorAll('#wifi-fs-band button').forEach(b => |
| 2690 | b.addEventListener('click', () => wifiSetBand(b.dataset.band))); |
| 2691 | document.querySelectorAll('#wifi-fs-view button').forEach(b => |
| 2692 | b.addEventListener('click', () => { if (!b.disabled) wifiSetView(b.dataset.view); })); |
| 2693 | // Overlay toggles mirror the in-page checkboxes, so the existing change |
| 2694 | // handlers stay the single implementation. |
| 2695 | [['wifi-auto', 'wifi-fs-auto'], ['wifi-bt', 'wifi-fs-bt'], ['wifi-zb', 'wifi-fs-zb']].forEach(([mainId, fsId]) => { |
| 2696 | const m = document.getElementById(mainId), f = document.getElementById(fsId); |
| 2697 | if (!m || !f) return; |
| 2698 | f.addEventListener('change', () => { |
| 2699 | if (f.disabled) { f.checked = false; return; } |
| 2700 | m.checked = f.checked; |
| 2701 | m.dispatchEvent(new Event('change')); |
| 2702 | }); |
| 2703 | m.addEventListener('change', () => { f.checked = m.checked; }); |
| 2704 | }); |
| 2705 | const canvas = document.getElementById('wifi-spectrum-fs'); |
| 2706 | _wifiWireCanvas(canvas, 'wifi-fs-tip', 'wifi-fs-readout'); |
| 2707 | if (canvas && window.ResizeObserver) { |
| 2708 | new ResizeObserver(() => { |
| 2709 | if (!_wifiState.fs.open) return; |
| 2710 | if (_wifiState.view === 'waterfall') _wifiDrawWaterfall(); |
| 2711 | else if (_wifiState.data) _wifiDrawSpectrum(); |
| 2712 | }).observe(canvas.parentElement || canvas); |
| 2713 | } |
| 2714 | // Leaving native fullscreen (browser Esc / F11) should close the overlay too. |
| 2715 | document.addEventListener('fullscreenchange', () => { |
| 2716 | if (_wifiState.fs.open && _wifiState.fs.native && !document.fullscreenElement) { |
| 2717 | _wifiState.fs.native = false; |
| 2718 | _wifiFsClose(document.getElementById('wifi-fs')); |
| 2719 | } |
| 2720 | }); |
| 2721 | } |
| 2722 | |
| 2723 | function _wifiFsKey(e) { |
| 2724 | if (!_wifiState.fs.open) return; |
| 2725 | const tag = (e.target && e.target.tagName || '').toLowerCase(); |
| 2726 | const typing = tag === 'input' || tag === 'select' || tag === 'textarea'; |
| 2727 | if (e.key === 'Escape') { e.preventDefault(); wifiToggleFullscreen(); return; } |
| 2728 | if (typing) return; |
no test coverage detected