1// Light/Dark mode theme toggle with localStorage persistence 2// Default theme: dark mode (on first load and fallback) 3 4(function() { 5 // Safe localStorage wrapper with fallback 6 const storage = { 7 get: function(key, defaultValue) { 8 try { 9 return localStorage.getItem(key) || defaultValue; 10 } catch (e) { 11 // localStorage disabled or blocked (privacy mode, etc) 12 return defaultValue; 13 } 14 }, 15 set: function(key, value) { 16 try { 17 localStorage.setItem(key, value); 18 } catch (e) { 19 // Silently fail if localStorage unavailable 20 // Theme will reset on page reload but toggle still works 21 } 22 } 23 }; 24 25 // Check for saved theme preference or default to dark mode 26 const savedTheme = storage.get('theme', 'dark'); 27 28 // Apply theme on load 29 if (savedTheme === 'dark') { 30 document.documentElement.setAttribute('data-theme', 'dark'); 31 } else if (savedTheme === 'light') { 32 document.documentElement.setAttribute('data-theme', 'light'); 33 } else { 34 // Default to dark mode on first load 35 document.documentElement.setAttribute('data-theme', 'dark'); 36 storage.set('theme', 'dark'); 37 } 38 39 // Create toggle button 40 const toggleButton = document.createElement('button'); 41 toggleButton.id = 'theme-toggle'; 42 toggleButton.setAttribute('aria-label', 'Toggle theme'); 43 toggleButton.setAttribute('aria-pressed', savedTheme === 'dark' ? 'true' : 'false'); 44 toggleButton.title = savedTheme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'; 45 toggleButton.innerHTML = savedTheme === 'dark' ? 'âï¸' : 'ð'; 46 document.body.appendChild(toggleButton); 47 48 // Toggle theme on click 49 toggleButton.addEventListener('click', function() { 50 const currentTheme = document.documentElement.getAttribute('data-theme'); 51 const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; 52 53 // Update theme 54 if (newTheme === 'dark') { 55 document.documentElement.setAttribute('data-theme', 'dark'); 56 toggleButton.innerHTML = 'âï¸'; 57 toggleButton.title = 'Switch to light mode'; 58 toggleButton.setAttribute('aria-pressed', 'true'); 59 } else { 60 document.documentElement.setAttribute('data-theme', 'light'); 61 toggleButton.innerHTML = 'ð'; 62 toggleButton.title = 'Switch to dark mode'; 63 toggleButton.setAttribute('aria-pressed', 'false'); 64 } 65 66 // Save preference (gracefully fails if localStorage unavailable) 67 storage.set('theme', newTheme); 68 }); 69})();
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.