1/* WRX Library demo tools (27.1.6) 2 First tool: document-level Bootstrap light/dark toggle with localStorage override. 3*/ 4(function (global, document) { 5 "use strict"; 6 if (!document || global.__wrxLibraryDemoTools27) return; 7 global.__wrxLibraryDemoTools27 = true; 8 9 var STORAGE_KEY = "wrx.library.demo.theme"; 10 var TOOLS_OPEN_STORAGE_KEY = "wrx.library.demo.tools.open"; 11 var ROOT = document.documentElement; 12 13 function toBool(value, fallback) { 14 if (value === undefined || value === null || value === "") return !!fallback; 15 if (typeof value === "boolean") return value; 16 var text = String(value).trim().toLowerCase(); 17 if (["true", "1", "yes", "y", "on"].indexOf(text) >= 0) return true; 18 if (["false", "0", "no", "n", "off"].indexOf(text) >= 0) return false; 19 return !!fallback; 20 } 21 22 function contextNode() { 23 return document.getElementById("wrx-ui-context"); 24 } 25 26 function enabledByContext() { 27 var ctx = contextNode(); 28 if (!ctx) return false; 29 if (ctx.dataset && Object.prototype.hasOwnProperty.call(ctx.dataset, "uiLibrarySectionActive")) { 30 return toBool(ctx.dataset.uiLibrarySectionActive, false); 31 } 32 return false; 33 } 34 35 function pageDefaultTheme() { 36 return ROOT.getAttribute("data-bs-theme") || "light"; 37 } 38 39 var DEFAULT_THEME = pageDefaultTheme(); 40 41 function storedTheme() { 42 try { 43 var value = global.localStorage && global.localStorage.getItem(STORAGE_KEY); 44 return value === "dark" || value === "light" ? value : ""; 45 } catch (e) { 46 return ""; 47 } 48 } 49 50 function persistTheme(theme) { 51 try { 52 if (global.localStorage) global.localStorage.setItem(STORAGE_KEY, theme); 53 } catch (e) {} 54 } 55 56 function clearPersistedTheme() { 57 try { 58 if (global.localStorage) global.localStorage.removeItem(STORAGE_KEY); 59 } catch (e) {} 60 } 61 62 function storedToolsOpen() { 63 try { 64 return global.localStorage && global.localStorage.getItem(TOOLS_OPEN_STORAGE_KEY) === "true"; 65 } catch (e) { 66 return false; 67 } 68 } 69 70 function persistToolsOpen(open) { 71 try { 72 if (global.localStorage) global.localStorage.setItem(TOOLS_OPEN_STORAGE_KEY, open ? "true" : "false"); 73 } catch (e) {} 74 } 75 76 function dispatchTheme(theme, source) { 77 var detail = { theme: theme, source: source || "demo-tools" }; 78 try { 79 document.dispatchEvent(new CustomEvent("wrx:theme:changed", { detail: detail })); 80 } catch (e) {} 81 } 82 83 function applyTheme(theme, options) { 84 if (theme !== "dark" && theme !== "light") theme = "light"; 85 ROOT.setAttribute("data-bs-theme", theme); 86 ROOT.setAttribute("data-wrx-demo-theme", theme); 87 document.body && document.body.setAttribute("data-wrx-demo-theme", theme); 88 updateButtons(theme); 89 if (!options || options.persist !== false) persistTheme(theme); 90 dispatchTheme(theme, options && options.source); 91 } 92 93 function updateButtons(theme) { 94 var toolbar = document.querySelector(".wrx-demo-tools"); 95 if (!toolbar) return; 96 var btn = toolbar.querySelector(".wrx-demo-tools-theme"); 97 var reset = toolbar.querySelector(".wrx-demo-tools-reset"); 98 if (btn) { 99 btn.setAttribute("data-wrx-theme-state", theme); 100 btn.setAttribute("aria-label", "Switch to " + (theme === "dark" ? "light" : "dark") + " mode"); 101 btn.setAttribute("title", "Theme: " + theme + ". Toggle light/dark."); 102 } 103 if (reset) { 104 reset.hidden = !storedTheme(); 105 } 106 } 107 108 function setToolbarOpen(toolbar, open, persist) { 109 if (!toolbar) return; 110 open = !!open; 111 toolbar.classList.toggle("is-open", open); 112 toolbar.setAttribute("data-wrx-demo-tools-open", open ? "true" : "false"); 113 var main = toolbar.querySelector(".wrx-demo-tools-main"); 114 var tray = toolbar.querySelector(".wrx-demo-tools-tray"); 115 if (main) { 116 main.setAttribute("aria-expanded", open ? "true" : "false"); 117 main.setAttribute("title", open ? "Collapse WRX demo tools" : "Open WRX demo tools"); 118 } 119 if (tray) { 120 tray.setAttribute("aria-hidden", open ? "false" : "true"); 121 Array.prototype.forEach.call(tray.querySelectorAll("button"), function (button) { 122 button.tabIndex = open ? 0 : -1; 123 }); 124 } 125 if (!open && document.activeElement && tray && tray.contains(document.activeElement) && main) { 126 try { 127 main.focus({ preventScroll: true }); 128 } catch (e) { 129 main.focus(); 130 } 131 }
132 if (persist !== false) persistToolsOpen(open); 133 } 134 135 function renderToolbar() { 136 if (document.querySelector(".wrx-demo-tools")) return; 137 var toolbar = document.createElement("div"); 138 toolbar.className = "wrx-demo-tools"; 139 toolbar.setAttribute("role", "toolbar"); 140 toolbar.setAttribute("aria-label", "WRX library demo tools"); 141 toolbar.setAttribute("data-wrx-demo-tools-ready", "false"); 142 toolbar.innerHTML = [ 143 '<button type="button" class="wrx-demo-tools-main" aria-label="WRX demo tools" aria-expanded="false" title="Open WRX demo tools">', 144 '<i class="fas fa-flask" aria-hidden="true"></i>', 145 '</button>', 146 '<span class="wrx-demo-tools-tray">', 147 '<button type="button" class="wrx-demo-tools-theme" aria-label="Toggle theme" title="Toggle light/dark theme">', 148 '<i class="fas fa-sun wrx-demo-tools-icon-light" aria-hidden="true"></i>', 149 '<i class="fas fa-moon wrx-demo-tools-icon-dark" aria-hidden="true"></i>', 150 '</button>', 151 '<button type="button" class="wrx-demo-tools-reset" aria-label="Use page default theme" title="Use page default theme">', 152 '<i class="fas fa-undo" aria-hidden="true"></i>', 153 '</button>', 154 '</span>' 155 ].join(""); 156 document.body.appendChild(toolbar); 157 158 toolbar.querySelector(".wrx-demo-tools-main").addEventListener("click", function (event) { 159 event.preventDefault(); 160 setToolbarOpen(toolbar, !toolbar.classList.contains("is-open")); 161 }); 162 toolbar.querySelector(".wrx-demo-tools-theme").addEventListener("click", function () { 163 var current = ROOT.getAttribute("data-bs-theme") === "dark" ? "dark" : "light"; 164 applyTheme(current === "dark" ? "light" : "dark", { source: "demo-tools-toggle" }); 165 }); 166 toolbar.querySelector(".wrx-demo-tools-reset").addEventListener("click", function () { 167 clearPersistedTheme(); 168 applyTheme(DEFAULT_THEME, { persist: false, source: "demo-tools-reset" }); 169 updateButtons(ROOT.getAttribute("data-bs-theme") || DEFAULT_THEME); 170 }); 171 setToolbarOpen(toolbar, storedToolsOpen(), false); 172 updateButtons(ROOT.getAttribute("data-bs-theme") || DEFAULT_THEME); 173 requestAnimationFrame(function () { 174 toolbar.setAttribute("data-wrx-demo-tools-ready", "true"); 175 }); 176 } 177 178 function init() { 179 if (!enabledByContext()) return; 180 var override = storedTheme(); 181 if (override) applyTheme(override, { persist: false, source: "demo-tools-storage" }); 182 renderToolbar(); 183 if (global.$wrx) { 184 global.$wrx.library = global.$wrx.library || {}; 185 global.$wrx.library.demoTools = { 186 applyTheme: applyTheme, 187 resetTheme: function () { 188 clearPersistedTheme(); 189 applyTheme(DEFAULT_THEME, { persist: false, source: "demo-tools-api-reset" }); 190 }, 191 setOpen: function (open) { 192 setToolbarOpen(document.querySelector(".wrx-demo-tools"), !!open); 193 }, 194 toggleOpen: function () { 195 var toolbar = document.querySelector(".wrx-demo-tools"); 196 if (toolbar) setToolbarOpen(toolbar, !toolbar.classList.contains("is-open")); 197 }, 198 isOpen: function () { 199 var toolbar = document.querySelector(".wrx-demo-tools"); 200 return !!(toolbar && toolbar.classList.contains("is-open")); 201 }, 202 storageKey: STORAGE_KEY, 203 toolsOpenStorageKey: TOOLS_OPEN_STORAGE_KEY 204 }; 205 } 206 } 207 208 if (document.readyState === "loading") { 209 document.addEventListener("DOMContentLoaded", init); 210 } else { 211 init(); 212 } 213})(window, document);
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.