1((function(global) { 2 const DATA = JSON.parse(document.documentElement.dataset.appearance || 'null'); 3 const matchMedia = window.matchMedia('(prefers-color-scheme: dark)'); 4 5 try { 6 // Chrome & Firefox 7 matchMedia.addEventListener('change', (event) => { 8 if (typhoonRetrieve().appearance === 'system') { 9 typhoonSetTheme(event.matches ? 'dark' : 'light', true); 10 } 11 }); 12 } catch (fallback) { 13 try { 14 // Safari 15 matchMedia.addListener((event) => { 16 if (typhoonRetrieve().appearance === 'system') { 17 typhoonSetTheme(event.matches ? 'dark' : 'light', true); 18 } 19 }); 20 } catch (error) { 21 console.error(error); 22 } 23 } 24 25 const typhoonStorage = { 26 set(value) { 27 const data = JSON.stringify(value); 28 29 if (DATA.type === 'cookie') { 30 Cookies.set('typhoon-appearance', data, { expires: 365 }); 31 } else { 32 const STORAGE = DATA.store ? 'localStorage' : 'sessionStorage'; 33 global[STORAGE].setItem('typhoon-appearance', data); 34 } 35 }, 36 get() { 37 if (DATA.type === 'cookie') { 38 return JSON.parse(Cookies.get('typhoon-appearance') || 'null'); 39 } else { 40 const STORAGE = DATA.store ? 'localStorage' : 'sessionStorage'; 41 return JSON.parse(global[STORAGE].getItem('typhoon-appearance') || 'null'); 42 } 43 }, 44 } 45 46 global.typhoonStore = function(data) { 47 const theme = data.appearance === 'system' ? typhoonGetTheme() : data.appearance; 48 const config = Object.assign({}, typhoonRetrieve(), data, { theme: theme }); 49 50 typhoonStorage.set(config); 51 typhoonSetTheme(theme, false); 52 } 53 54 global.typhoonRetrieve = function() { 55 const systemTheme = typhoonGetTheme(); 56 const storage = typhoonStorage.get(); 57 58 if (storage && storage.appearance === 'system') { 59 storage.theme = systemTheme; 60 } 61 62 return storage || { 63 theme: DATA.appearance === 'system' ? systemTheme : DATA.appearance, 64 appearance: DATA.appearance || 'system' 65 }; 66 } 67 68 global.typhoonSetTheme = function(theme, store) { 69 const event = new CustomEvent('typhoon-theme', { 70 detail: { 71 theme: theme, 72 appearance: typhoonRetrieve().appearance 73 } 74 }); 75 76 if (store) { 77 typhoonStore({ theme: theme || typhoonGetTheme() }); 78 } 79 80 if (DATA.type === 'cookie') { 81 window.dispatchEvent(event); 82 83 setTimeout(() => { 84 document.documentElement.classList.remove('light', 'dark'); 85 document.documentElement.classList.add(theme); 86 }, 0); 87 } else { 88 window.dispatchEvent(event); 89 } 90 } 91 92 global.typhoonGetTheme = function() { 93 return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; 94 } 95 96})(window));
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.