1/* theme.js - light/dark theme control for MyFS Flights. 2 * 3 * Two responsibilities: 4 * 1. init() - run once from the shell <head> BEFORE first paint so the page 5 * renders in the right theme with no dark->light flash. Reads the 6 * per-device choice from localStorage, falling back to the OS 7 * preference. Does NOT write localStorage (an untouched device 8 * keeps following the OS until the user actually picks a theme). 9 * 2. set() - called from Blazor (interop) when the signed-in user's stored 10 * preference loads, and by the theme toggle. Applies + remembers 11 * the choice on this device. 12 * 13 * "Applying" a theme means: set <html data-theme="..."> (drives the css token 14 * layer in theme.css) AND swap the Syncfusion component stylesheet between its 15 * light (bootstrap5.css) and dark (bootstrap5-dark.css) builds. The Syncfusion 16 * <link> is found by id="sfTheme"; we rewrite only the file-name suffix so the 17 * CDN version in the href is never hard-coded here. 18 */ 19window.mfsfTheme = (function () { 20 var KEY = 'mfsf-theme'; 21 22 // Light is the product default (Aug 2026): anything that isn't an explicit 23 // 'dark' choice resolves to light. 24 function normalize(t) { return t === 'dark' ? 'dark' : 'light'; } 25 26 function apply(theme) { 27 theme = normalize(theme); 28 document.documentElement.setAttribute('data-theme', theme); 29 var link = document.getElementById('sfTheme'); 30 if (link) { 31 var href = link.getAttribute('href') || ''; 32 var next = href.replace(/bootstrap5(-dark)?\.css/, 33 'bootstrap5' + (theme === 'light' ? '' : '-dark') + '.css'); 34 if (next !== href) link.setAttribute('href', next); 35 } 36 return theme; 37 } 38 39 return { 40 // Current applied theme. 41 get: function () { 42 return normalize(document.documentElement.getAttribute('data-theme')); 43 }, 44 45 // No-flash boot: device choice, else light. The OS preference is no longer 46 // consulted - an untouched device always boots light so the default is the 47 // same for everyone, not whatever the OS happens to be set to. Never persists. 48 init: function () { 49 var t = null; 50 try { t = localStorage.getItem(KEY); } catch (e) { } 51 return apply(t); 52 }, 53 54 // Apply and remember on this device (user action or server preference). 55 set: function (theme) { 56 theme = apply(theme); 57 try { localStorage.setItem(KEY, theme); } catch (e) { } 58 return theme; 59 }, 60 61 // Flip and remember; returns the new theme. 62 toggle: function () { 63 return this.set(this.get() === 'light' ? 'dark' : 'light'); 64 } 65 }; 66})();
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.