1/* ADA WCAG 2.1 BWAT Accessibility - v1.5.5 */ 2(function() { 3 'use strict'; 4 5 // State 6 var settings = {}; 7 var defaults = { 8 textSize: 'normal', 9 lineHeight: 'normal', 10 spacing: 'normal', 11 contrast: 'normal', 12 brightness: 'normal', 13 grayscale: false, 14 links: false, 15 cursor: false, 16 animations: false, 17 line: false, 18 mask: false, 19 dyslexic: false 20 }; 21 22 // Load settings 23 function load() { 24 try { 25 var s = localStorage.getItem('bwat'); 26 settings = s ? JSON.parse(s) : {}; 27 } catch(e) { 28 settings = {}; 29 } 30 for (var k in defaults) { 31 if (!(k in settings)) settings[k] = defaults[k]; 32 } 33 } 34 35 // Save settings 36 function save() { 37 try { localStorage.setItem('bwat', JSON.stringify(settings)); } catch(e) {} 38 } 39 40 // Apply a setting 41 function apply(key, val) { 42 var html = document.documentElement; 43 44 // Button groups 45 if (key === 'textSize') { 46 html.classList.remove('bwat-text-large', 'bwat-text-larger', 'bwat-text-largest'); 47 if (val !== 'normal') html.classList.add('bwat-text-' + val); 48 } 49 else if (key === 'lineHeight') { 50 html.classList.remove('bwat-line-relaxed', 'bwat-line-loose', 'bwat-line-extra'); 51 if (val !== 'normal') html.classList.add('bwat-line-' + val); 52 } 53 else if (key === 'spacing') { 54 html.classList.remove('bwat-spacing-wide', 'bwat-spacing-wider', 'bwat-spacing-widest'); 55 if (val !== 'normal') html.classList.add('bwat-spacing-' + val); 56 } 57 else if (key === 'contrast') { 58 html.classList.remove('bwat-contrast-high', 'bwat-contrast-inverted'); 59 if (val !== 'normal') html.classList.add('bwat-contrast-' + val); 60 } 61 else if (key === 'brightness') { 62 html.classList.remove('bwat-brightness-bright', 'bwat-brightness-dim'); 63 if (val !== 'normal') html.classList.add('bwat-brightness-' + val); 64 } 65 // Toggles 66 else if (key === 'links') { 67 html.classList.toggle('bwat-links', val); 68 } 69 else if (key === 'cursor') { 70 html.classList.toggle('bwat-cursor-on', val); 71 } 72 else if (key === 'animations') { 73 html.classList.toggle('bwat-animations', val); 74 } 75 else if (key === 'line') { 76 html.classList.toggle('bwat-line-on', val); 77 } 78 else if (key === 'mask') { 79 html.classList.toggle('bwat-mask-on', val); 80 } 81 else if (key === 'dyslexic') { 82 html.classList.toggle('bwat-dyslexic', val); 83 } 84 else if (key === 'grayscale') { 85 html.classList.toggle('bwat-grayscale', val); 86 } 87 88 settings[key] = val; 89 save(); 90 } 91 92 // Apply all settings 93 function applyAll() { 94 for (var k in settings) { 95 apply(k, settings[k]); 96 } 97 } 98 99 // Update button states 100 function updateUI() { 101 // Button groups 102 document.querySelectorAll('[data-set]').forEach(function(btn) { 103 var key = btn.getAttribute('data-set'); 104 var val = btn.getAttribute('data-val'); 105 btn.classList.toggle('active', settings[key] === val); 106 }); 107 108 // Checkboxes 109 document.querySelectorAll('[data-toggle]').forEach(function(cb) { 110 var key = cb.getAttribute('data-toggle'); 111 cb.checked = settings[key] || false; 112 }); 113 } 114 115 // Reset all 116 function resetAll() { 117 localStorage.removeItem('bwat'); 118 settings = Object.assign({}, defaults); 119 120 var html = document.documentElement; 121 html.className = html.className.replace(/\bbwat-\S+/g, '').trim(); 122 123 updateUI(); 124 } 125 126 // Initialize 127 function init() { 128 load(); 129 applyAll(); 130 131 var panel = document.querySelector('.bwat-panel'); 132 var toggle = document.querySelector('.bwat-toggle'); 133 134 // Toggle panel 135 toggle.addEventListener('click', function() { 136 panel.classList.toggle('open'); 137 panel.setAttribute('aria-hidden', !panel.classList.contains('open')); 138 }); 139 140 // Close button 141 document.querySelector('.bwat-close').addEventListener('click', function() { 142 panel.classList.remove('open'); 143 panel.setAttribute('aria-hidden', 'true'); 144 }); 145 146 // Button groups 147 document.querySelectorAll('[data-set]').forEach(function(btn
147) { 148 btn.addEventListener('click', function() { 149 var key = this.getAttribute('data-set'); 150 var val = this.getAttribute('data-val'); 151 apply(key, val); 152 153 // Update active state 154 this.parentNode.querySelectorAll('button').forEach(function(b) { 155 b.classList.remove('active'); 156 }); 157 this.classList.add('active'); 158 }); 159 }); 160 161 // Checkboxes 162 document.querySelectorAll('[data-toggle]').forEach(function(cb) { 163 cb.addEventListener('change', function() { 164 var key = this.getAttribute('data-toggle'); 165 apply(key, this.checked); 166 }); 167 }); 168 169 // Reset 170 document.querySelector('.bwat-reset').addEventListener('click', resetAll); 171 172 // Close on outside click 173 document.addEventListener('click', function(e) { 174 if (!e.target.closest('.bwat-panel, .bwat-toggle')) { 175 panel.classList.remove('open'); 176 } 177 }); 178 179 // Escape key 180 document.addEventListener('keydown', function(e) { 181 if (e.key === 'Escape') panel.classList.remove('open'); 182 }); 183 184 // HIGH PERFORMANCE mouse tracking using requestAnimationFrame 185 var mouseX = -100, mouseY = -100; 186 var ticking = false; 187 188 document.addEventListener('mousemove', function(e) { 189 mouseX = e.clientX; 190 mouseY = e.clientY; 191 192 if (!ticking) { 193 requestAnimationFrame(function() { 194 document.documentElement.style.setProperty('--bwat-mouse-x', mouseX + 'px'); 195 document.documentElement.style.setProperty('--bwat-mouse-y', mouseY + 'px'); 196 ticking = false; 197 }); 198 ticking = true; 199 } 200 }); 201 202 updateUI(); 203 } 204 205 // Run when DOM ready 206 if (document.readyState === 'loading') { 207 document.addEventListener('DOMContentLoaded', init); 208 } else { 209 init(); 210 } 211})();
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.