1// Wait for DigiAccess and add classes to the body tag so the page can adapt to the settings 2// Also, fire specific functions to re-layout parts like masonries or the header 3class CustomDigiAccessHandler { 4 // Range inputs 5 ranges = []; 6 daEvents = { 7 "da-font-size--range": { 8 'type': 'range', 9 'value': 0, 10 'events': [ 11 'da-click-range-fontsize', 12 'da-click-increase-fontsize', 13 'da-click-decrease-fontsize', 14 'da-click-clear-fontsize' 15 ], 16 'localStorage': 'da-fontSize' 17 }, 18 "da-line-spacing--range": { 19 'type': 'range', 20 'value': 0, 21 'events': [ 22 'da-click-range-line-spacing', 23 'da-click-increase-line-spacing', 24 'da-click-decrease-line-spacing', 25 'da-click-clear-line-spacing' 26 ], 27 'localStorage': 'da-lineHeight' 28 }, 29 "da-content-size--range": { 30 'type': 'range', 31 'value': 0, 32 'events': [ 33 'da-click-range-content-size', 34 'da-click-increase-content-size', 35 'da-click-decrease-content-size', 36 'da-click-clear-content-size' 37 ], 38 'localStorage': 'da-contentSize' 39 }, 40 "da-word-spacing--range": { 41 'type': 'range', 42 'value': 0, 43 'events': [ 44 'da-click-range-word-spacing', 45 'da-click-increase-word-spacing', 46 'da-click-decrease-word-spacing', 47 'da-click-clear-word-spacing' 48 ], 49 'localStorage': 'da-wordSpacing' 50 }, 51 "da-img": { 52 'type': 'toggle', 53 'value': false, 54 'events': [ 55 'da-click-hide-images' 56 ], 57 'localStorage': 'da-imageToggle' 58 }, 59 "da-einfacheschrift": { 60 'type': 'toggle', 61 'value': false, 62 'events': [ 63 'da-click-simple-font' 64 ], 65 'localStorage': 'da-simpleFont' 66 }, 67 "da-click-keyboard-navigation-profile": { 68 'type': 'toggle', 69 'value': false, 70 'events': [ 71 'da-click-keyboard-navigation-profile' 72 ], 73 'localStorage': 'da-keyboardNavigationProfile' 74 } 75 }; 76 77 constructor() { 78 // Read the localStorage values and update the daEvents object, update the body classes 79 this.digiAccessLocalStorage(); 80 81 // Add the event listener for DigiAccess and react to the events, update the body classes 82 this.digiAccessEventListener(); 83 84 // When the page is loaded or resized, check if the burger menu should be shown based on the range values 85 window.addEventListener('load', (event) => { 86 this.toggleBurgerMenu(); 87 }); 88 89 window.addEventListener('resize', (event) => { 90 this.toggleBurgerMenu(); 91 }); 92 } 93 94 /** 95 * Toggle the burger menu based on the range values 96 * 97 * @returns void 98 */ 99 toggleBurgerMenu() { 100 // Await animation frame 101 requestAnimationFrame(() => { 102 // Check if all daEvents of type range are below 25 103 let allRangesBelow25 = true; 104 105 for (const [key, value] of Object.entries(this.daEvents)) { 106 if (value.type === 'range') { 107 if (value.value >= 25) { 108 allRangesBelow25 = false; 109 } 110 } 111 } 112 113 // Add the burger class to the header if one of the range values is above 25, otherwise reevaluate the menu size 114 if (!allRangesBelow25) { 115 // Force the burger menu 116 document.querySelector('header').classList.add('burger'); 117 if (typeof updateNavigationTabindex === 'function') { 118 updateNavigationTabindex(); 119 } 120 } else { 121 // Reevaluate based on the default menu size logic in the header 122 document.querySelector('header').classList.remove('burger');
123 if (typeof checkMenuSizes === 'function') { 124 checkMenuSizes(); 125 } 126 } 127 }); 128 } 129 130 /** 131 * Read the localStorage values and update the daEvents object 132 * 133 * @returns void 134 */ 135 digiAccessLocalStorage() { 136 // Loop through all DigiAccess events 137 for (const [key, value] of Object.entries(this.daEvents)) { 138 // Check if the event has a localStorage key 139 if (value.localStorage) { 140 // Check if the localStorage key exists 141 if (localStorage.getItem(value.localStorage)) { 142 // Get the value from localStorage 143 let localStorageValue = localStorage.getItem(value.localStorage); 144 145 // Check if the value is a boolean 146 if (localStorageValue === 'true' || localStorageValue === 'false') { 147 // Convert the value to a boolean 148 localStorageValue = localStorageValue === 'true'; 149 value.value = localStorageValue; 150 this.handleToggle(key, localStorageValue); 151 } else { 152 // Multiply the value by 10 to get the correct range value 153 localStorageValue = parseFloat(localStorageValue) * 10; 154 value.value = localStorageValue; 155 this.handleRange(key, parseInt(localStorageValue)); 156 } 157 } 158 } 159 } 160 } 161 162 /** 163 * Add the event listener for DigiAccess and react to the events 164 * 165 * @returns void 166 */ 167 digiAccessEventListener() { 168 // Listen for DigiAccess events 169 document.addEventListener('da-general', (event) => { 170 // Loop through all DigiAccess events 171 for (const [key, value] of Object.entries(this.daEvents)) { 172 // Check for the event type 173 if (value.type === 'range') { 174 // Loop through all events of the range type 175 for (let i = 0; i < value.events.length; i++) { 176 // Check if the event matches the current event 177 if (value.events[i] === event.detail.action) { 178 // Update the value in the event object 179 value.value = event.detail.rangeValue; 180 181 // Handle the range 182 this.handleRange(key, event.detail.rangeValue); 183 184 // Recalculate the masonries 185 this.handleMasonries(); 186 187 // Handle the header placeholder 188 this.handleHeaderPlaceholder(); 189 190 // Recalculate the burger menu 191 this.toggleBurgerMenu(); 192 } 193 } 194 } else if (value.type === 'toggle') { 195 // Loop through all events of the toggle type 196 for (let i = 0; i < value.events.length; i++) { 197 // Check if the event matches the current event 198 if (value.events[i] === event.detail.action) { 199 // Handle the toggle 200 this.handleToggle(key, event.detail.enabled); 201 } 202 } 203 } 204 } 205 }); 206 207 // Listen for tab key and run the this.handleToggle function with the keyboard navigation profile value 208 document.addEventListener('keydown', (event) => { 209 if (event.key === 'Tab') { 210 // Get the keyboard navigation profile value from the daEvents object 211 const keyboardNavigationProfile = this.daEvents['da-click-keyboard-navigation-profile'].value; 212 213 // If the keyboard navigation profile is not enabled, enable it 214 if (!keyboardNavigationProfile) { 215 this.daEvents['da-click-keyboard-navigation-profile'].value = true; 216 this.handleToggle('da-click-keyboard-navigation-profile', true); 217 } 218 } 219 }); 220 } 221 222 /** 223 * Handle the range events and update the body classes 224 * 225 * @param {string} name 226 * @param {number} value 227 * 228 * @returns void 229 */ 230 handleRange(name, value) {
231 const id = name; 232 233 // Ranges with their corresponding CSS classes 234 // The slider can go to 100, but since we need a "smaller than" comparison, 235 // we need to add 1 to the upper bound of the biggest positive range, hence the 101 236 const sliderRanges = [ 237 { range: [-100, -75], className: 'ms-' + id + '-negative-75_100' }, 238 { range: [-75, -50], className: 'ms-' + id + '-negative-50_75' }, 239 { range: [-50, -25], className: 'ms-' + id + '-negative-25_50' }, 240 { range: [25, 50], className: 'ms-' + id + '-25_50' }, 241 { range: [50, 75], className: 'ms-' + id + '-50_75' }, 242 { range: [75, 101], className: 'ms-' + id + '-75_100' } 243 ]; 244 245 sliderRanges.forEach(sliderRange => { 246 if (value >= sliderRange.range[0] && value < sliderRange.range[1]) { 247 document.body.classList.add(sliderRange.className); 248 } else { 249 document.body.classList.remove(sliderRange.className); 250 } 251 }); 252 } 253 254 /** 255 * Handle the toggle events and update the body classes 256 * 257 * @param {string} name 258 * @param {boolean} pressed 259 * 260 * @returns void 261 */ 262 handleToggle(name, pressed) { 263 const id = name; 264 265 if (pressed) { 266 document.body.classList.add('ms-' + id + '-enabled'); 267 } else { 268 document.body.classList.remove('ms-' + id + '-enabled'); 269 } 270 } 271 272 /** 273 * Recalculate the masonries 274 * 275 * @returns void 276 */ 277 handleMasonries() { 278 // handle the news masonries 279 if (typeof newsMasonries != 'undefined') { 280 for (let i = 0; i < newsMasonries.length; i++) { 281 newsMasonries[i].layout(); 282 } 283 } 284 285 // handle the kna masonries 286 if (typeof knaMasonries != 'undefined') { 287 for (let i = 0; i < knaMasonries.length; i++) { 288 if (typeof knaMasonries[i] != 'undefined') { 289 knaMasonries[i].layout(); 290 } 291 } 292 } 293 } 294 295 296 /** 297 * Recalculate the header placeholder 298 * 299 * @returns void 300 */ 301 handleHeaderPlaceholder() { 302 // Wait for next animation frame 303 requestAnimationFrame(() => { 304 305 // Wait for the resize animation (300ms) to finish 306 setTimeout(() => { 307 resizeHeaderPlaceholder(); 308 }, 300); 309 }); 310 } 311} 312 313 314new CustomDigiAccessHandler();
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.