1 /*! 2 * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/) 3 * Copyright 2011-2024 The Bootstrap Authors 4 * Licensed under the Creative Commons Attribution 3.0 Unported License. 5 */ 6 7(() => { 8 'use strict' 9 10 // Site config surfaced by root.html as <html> data attributes: 11 // - data-color-mode-lock: "true" pins the configured mode; visitor 12 // preference and OS scheme are ignored and the toggles are inert 13 // (core/color-mode-init.html applies the same rules pre-paint). 14 // - data-color-mode-default: the site's configured starting mode. It 15 // must rank ABOVE the OS preference here â otherwise this script 16 // overrides the init script's choice on first visit and the page 17 // flips modes after load. 18 const rootEl = document.documentElement 19 const isLocked = rootEl.getAttribute('data-color-mode-lock') === 'true' 20 const configDefault = rootEl.getAttribute('data-color-mode-default') || 'auto' 21 22 const getStoredTheme = () => localStorage.getItem('theme') 23 const setStoredTheme = theme => localStorage.setItem('theme', theme) 24 25 const getPreferredTheme = () => { 26 if (isLocked) { 27 return configDefault === 'auto' ? 'dark' : configDefault 28 } 29 30 const storedTheme = getStoredTheme() 31 if (storedTheme) { 32 return storedTheme 33 } 34 35 if (configDefault !== 'auto') { 36 return configDefault 37 } 38 39 return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' 40 } 41 42 const setTheme = theme => { 43 if (theme === 'auto') { 44 document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) 45 } else { 46 document.documentElement.setAttribute('data-bs-theme', theme) 47 } 48 } 49 50 setTheme(getPreferredTheme()) 51 52 const showActiveTheme = (theme, focus = false) => { 53 const activeButtons = document.querySelectorAll(`[data-bs-theme-value="${theme}"]`) 54 if (!activeButtons.length) { 55 return 56 } 57 58 // The control can render more than once per page (settings offcanvas + 59 // theme-controls-bar), so sync active state across every instance. 60 document.querySelectorAll('[data-bs-theme-value]').forEach(element => { 61 element.classList.remove('active') 62 element.setAttribute('aria-pressed', 'false') 63 }) 64 activeButtons.forEach(element => { 65 element.classList.add('active') 66 element.setAttribute('aria-pressed', 'true') 67 }) 68 69 // Legacy dropdown affordances (#bd-theme toggle with a mirrored icon) â 70 // updated only when that markup is present. 71 const themeSwitcher = document.querySelector('#bd-theme') 72 const activeThemeIcon = document.querySelector('.theme-icon-active use') 73 const themeIconUse = activeButtons[0].querySelector('svg use') 74 if (activeThemeIcon && themeIconUse) { 75 activeThemeIcon.setAttribute('href', themeIconUse.getAttribute('href')) 76 } 77 if (themeSwitcher) { 78 const themeSwitcherText = document.querySelector('#bd-theme-text') 79 const baseLabel = themeSwitcherText?.textContent?.trim() || 'Toggle theme' 80 themeSwitcher.setAttribute('aria-label', `${baseLabel} (${theme})`) 81 if (focus) { 82 themeSwitcher.focus() 83 } 84 } 85 } 86 87 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { 88 if (isLocked) { 89 return 90 } 91 const storedTheme = getStoredTheme() 92 if (storedTheme !== 'light' && storedTheme !== 'dark') { 93 setTheme(getPreferredTheme()) 94 } 95 }) 96 97 window.addEventListener('DOMContentLoaded', () => { 98 showActiveTheme(getPreferredTheme()) 99 100 document.querySelectorAll('[data-bs-theme-value]') 101 .forEach(toggle => { 102 toggle.addEventListener('click', () => { 103 if (isLocked) { 104 return 105 } 106 const theme = toggle.getAttribute('data-bs-theme-value') 107 setStoredTheme(theme) 108 setTheme(theme) 109 showActiveTheme(theme, true) 110 }) 111 }) 112 }) 113})()
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.