1/** 2 * Resolves the colour scheme before first paint, and keeps AT's scheme and Bricks' in step. 3 * 4 * The two systems are independent: AT's colours live under html[data-theme="dark"], Bricks' under 5 * :root[data-brx-theme="dark"], with separate localStorage keys and separate default settings. 6 * 7 * AT only speaks for Bricks' attribute when it has a mandate to: 8 * - the visitor picked a scheme with either toggle, or 9 * - the site enforces one through AT's "Force default color scheme" setting. 10 * With AT set to "Auto" and nothing stored, AT resolves its own colours from the OS and leaves 11 * data-brx-theme alone, so Bricks' own "Default mode" (light / dark / auto) still decides. 12 */ 13(function () { 14 const html = document.documentElement; 15 16 function stored(key) { 17 try { return localStorage.getItem(key); } catch (e) { return null; } 18 } 19 20 function persist(key, value) { 21 try { localStorage.setItem(key, value); } catch (e) {} 22 } 23 24 // Applies a mode to both systems. `persistChoice` is for an actual choice by the visitor, never 25 // for a configured default: a stored value outranks the setting on the next load, so writing one 26 // from a setting would freeze it and ignore later changes to that setting. 27 window.brxcSetColorScheme = function (mode, options) { 28 if (mode !== 'dark' && mode !== 'light') return; 29 30 const settings = options || {}; 31 32 html.setAttribute('data-theme', mode); 33 if (settings.mirrorToBricks !== false) html.setAttribute('data-brx-theme', mode); 34 35 if (settings.persistChoice) { 36 persist('brxc-theme', mode); 37 persist('brx_mode', mode); 38 if (settings.acss) persist('acss-color-scheme', mode); 39 } 40 }; 41 42 const forced = typeof BRXC_FORCE_DEFAULT_SCHEME_COLOR !== 'undefined' ? BRXC_FORCE_DEFAULT_SCHEME_COLOR : false; 43 44 // Bricks' own key counts as a choice: its toggle is the only thing that writes it 45 const atChoice = stored('acss-color-scheme') || stored('brxc-theme'); 46 const bricksChoice = stored('brx_mode'); 47 const choice = (atChoice === 'dark' || atChoice === 'light') ? atChoice 48 : (bricksChoice === 'dark' || bricksChoice === 'light') ? bricksChoice 49 : null; 50 51 if (choice) { 52 // The visitor chose. Both systems follow it, and Bricks' key is brought in line so its own 53 // wp_head script â which runs after this one â reaches the same answer on this very load 54 // instead of painting its default first. 55 window.brxcSetColorScheme(choice); 56 if (bricksChoice !== choice) persist('brx_mode', choice); 57 if (atChoice !== choice) persist('brxc-theme', choice); 58 59 } else if (forced === 'dark' || forced === 'light') { 60 // The site enforces a scheme through AT, so AT speaks for both. Not persisted, so changing 61 // the setting still takes effect. 62 window.brxcSetColorScheme(forced); 63 64 // Bricks' script runs later and would reset its attribute to its own default 65 document.addEventListener('DOMContentLoaded', function () { 66 if (html.getAttribute('data-brx-theme') !== forced) html.setAttribute('data-brx-theme', forced); 67 }); 68 69 } else { 70 // No choice and nothing enforced: AT has no opinion about Bricks' colours. Resolve AT's own 71 // from the OS, exactly as before, and let Bricks' "Default mode" stand. 72 const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; 73 window.brxcSetColorScheme(prefersDark ? 'dark' : 'light', { mirrorToBricks: false }); 74 } 75 76 /** 77 * Bricks' toggle flips data-brx-theme and writes brx_mode, and dispatches no event, so listen 78 * for the click on its own element and mirror whatever it settled on. Delegated, so toggles 79 * added later by AJAX or a popup are covered, and read on the next frame because this handler 80 * runs after the element's own listener has already flipped the attribute. 81 */ 82 document.addEventListener('click', function (event) { 83 const toggle = event.target && event.target.closest ? event.target.closest('.brxe-toggle-mode') : null; 84 if (!toggle) return; 85 86 requestAnimationFrame(function () { 87 const target = html.getAttribute('data-brx-theme'); 88 89 // Bricks no longer drives this attribute: leave the page alone rather than guess 90 if (target !== 'dark' && target !== 'light') return; 91 92 // Already in step, so the click changed nothing we need to follow 93 if (target === html.getAttribute('data-theme')) return; 94
95 window.brxcSetColorScheme(target, { persistChoice: true, acss: typeof acss !== 'undefined' }); 96 document.dispatchEvent(new CustomEvent('brxc/color-scheme/changed', { detail: { mode: target, source: 'bricks' } })); 97 }); 98 }); 99})();
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.