1/** 2 * theme.js â shared dark / light theme switch for all sites. 3 * Load in <head> (after brand.js.php) so the theme is applied before paint. 4 * Default: saved choice â brand.php 'theme' â the device's prefers-color-scheme. 5 * Adds a toggle button into any element marked [data-theme-mount], else floats 6 * one bottom-right. Colours themselves still come from brand.css.php. 7 */ 8(function () { 9 var KEY = 'pi-theme'; 10 var root = document.documentElement; 11 12 function preferred() { 13 try { var s = localStorage.getItem(KEY); if (s === 'light' || s === 'dark') return s; } catch (e) {} 14 var b = (window.BRAND && window.BRAND.theme) || 'auto'; 15 if (b === 'light' || b === 'dark') return b; 16 return (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; 17 } 18 function apply(t) { root.setAttribute('data-theme', t); } 19 20 apply(preferred()); // run immediately to avoid a flash of the wrong theme 21 22 function paint() { 23 var btn = document.getElementById('themeToggle'); if (!btn) return; 24 var dark = root.getAttribute('data-theme') === 'dark'; 25 btn.textContent = dark ? 'â' : 'â¾'; 26 var lbl = dark ? 'Switch to light theme' : 'Switch to dark theme'; 27 btn.setAttribute('aria-label', lbl); btn.title = lbl; 28 } 29 function toggle() { 30 var next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'; 31 apply(next); 32 try { localStorage.setItem(KEY, next); } catch (e) {} 33 paint(); 34 } 35 window.toggleTheme = toggle; 36 37 function mount() {
38 if (document.getElementById('themeToggle')) { paint(); return; } 39 var btn = document.createElement('button'); 40 btn.id = 'themeToggle'; btn.type = 'button'; 41 btn.addEventListener('click', toggle); 42 var host = document.querySelector('[data-theme-mount]'); 43 if (host) { btn.className = 'theme-toggle inline'; host.appendChild(btn); } 44 else { btn.className = 'theme-toggle float'; document.body.appendChild(btn); } 45 paint(); 46 } 47 if (document.readyState !== 'loading') mount(); 48 else document.addEventListener('DOMContentLoaded', mount); 49})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.