1function initializeWidgetAria() { 2 const translations = { 3 default: "Widget taalvertaling", 4 ar: "أداة ترج٠ة اÙÙØºØ©", 5 "zh-TW": "è¦çªèªè¨ç¿»è¯", 6 "zh-CN": "çªå£è¯è¨ç¿»è¯", 7 de: "Widget Sprachübersetzung", 8 en: "Widget Language Translate", 9 fr: "Widget de traduction de langue", 10 pl: "Widget tÅumaczenia jÄzyka", 11 es: "Widget de traducción de idiomas", 12 tr: "Dil çeviri widget'ı", 13 }; 14 15 const applyLabel = (element) => { 16 const currentLang = document.documentElement.lang; 17 const newLabel = translations[currentLang] || translations["default"]; 18 element.setAttribute("aria-label", newLabel); 19 }; 20 21 // 1. Check if it already exists 22 const existingSelect = document.querySelector(".goog-te-combo"); 23 if (existingSelect) { 24 applyLabel(existingSelect); 25 } 26 27 // 2. Watch the DOM for when the widget is injected 28 const observer = new MutationObserver((mutations, obs) => { 29 const select = document.querySelector(".goog-te-combo"); 30 if (select) { 31 applyLabel(select); 32 // Optional: Stop watching once we've found it and fixed it 33 // obs.disconnect(); 34 } 35 }); 36 37 observer.observe(document.body, { 38 childList: true, 39 subtree: true, 40 }); 41} 42 43initializeWidgetAria(); 44 45function initializeLocationToggles() { 46 var $locationsContainer = $("ul.locations"); 47 console.log("init"); 48 if ($locationsContainer.length > 0) { 49 $(".location > h4 button").on("click", function () { 50 console.log("click"); 51 if ($(window).width() <= 767) { 52 var $currentBtn = $(this); 53 var $parentLi = $currentBtn.parent().parent(".location"); 54 55 $(".location").not($parentLi).removeClass("active"); 56 $(".location > button").not($currentBtn).removeClass("active"); 57 58 $parentLi.toggleClass("active"); 59 $currentBtn.toggleClass("active"); 60 } 61 }); 62 } 63} 64 65initializeLocationToggles(); 66 67function initializeTranslateErrorMessages() { 68 if ( 69 document.documentElement.lang !== "nl" || 70 document.querySelector(".status-open")?.getAttribute("lang") === "en" 71 ) 72 return; 73 74 function updateErrorMessages() { 75 const errorMessages = document.querySelectorAll("p.error-message"); 76 77 errorMessages.forEach((msg) => { 78 const originalText = msg.textContent.trim(); 79 80 // Find the wrapper element to extract the field label name 81 const fieldWrapper = msg.closest(".freeform-column"); 82 if (!fieldWrapper) return; 83 const label = fieldWrapper.querySelector("label.freeform-label"); 84 if (!label) return; 85 86 let fieldName = label.textContent.trim(); 87 fieldName = fieldName.replace("*", "").trim(); 88 89 // Condition A: Required fields 90 if (originalText === "This field is required") { 91 msg.textContent = `Fout: het veld '${fieldName}' is verplicht`; 92 } 93 94 // Condition B: Date formatting fields 95 else if (originalText.includes("does not conform to")) { 96 msg.textContent = `Fout: het veld '${fieldName}' voldoet niet aan het formaat 'DD-MM-YYYY'`; 97 } 98 }); 99 } 100 101 const observer = new MutationObserver(() => { 102 updateErrorMessages(); 103 }); 104 105 observer.observe(document.body, { 106 childList: true, 107 subtree: true, 108 }); 109 110 updateErrorMessages(); 111} 112 113initializeTranslateErrorMessages(); 114 115function initializeTranslateErrorMessagesEN() { 116 if (document.querySelector(".status-open")?.getAttribute("lang") !== "en") 117 return; 118 119 function updateErrorMessages() { 120 const errorMessages = document.querySelectorAll("p.error-message"); 121 122 errorMessages.forEach((msg) => { 123 if (msg.textContent.trim() === "This field is required") { 124 const fieldWrapper = msg.closest(".freeform-column"); 125 if (!fieldWrapper) return; 126 const label = fieldWrapper.querySelector("label.freeform-label"); 127 if (!label) return; 128 let fieldName = label.textContent.trim(); 129 fieldName = fieldName.replace("*", "").trim(); 130 msg.textContent = `Error: the field '${fieldName}' is required`; 131 } 132 }); 133 } 134 135 const observer = new MutationObserver(() => { 136 updateErrorMessages(); 137 }); 138 139 observer.observe(document.body, { 140 childList: true, 141 subtree: true, 142 }); 143 144 updateErrorMessages(); 145} 146 147initializeTranslateErrorMessagesEN(); 148 149function initializeErrorAlertRoles() { 150 const addRoles = () => { 151 const errorMessages = document.querySelectorAll("p.error-message"); 152
153 errorMessages.forEach((msg) => { 154 if (!msg.hasAttribute("role")) { 155 msg.setAttribute("role", "alert"); 156 } 157 }); 158 }; 159 160 addRoles(); 161 162 const observer = new MutationObserver(addRoles); 163 164 observer.observe(document.body, { 165 childList: true, 166 subtree: true, 167 }); 168} 169 170initializeErrorAlertRoles(); 171 172function initializeFreeformRequiredFields() { 173 const requiredLabels = document.querySelectorAll("label.freeform-required"); 174 175 requiredLabels.forEach((label) => { 176 const column = label.closest(".freeform-column"); 177 178 if (column) { 179 const input = column.querySelector("input, textarea, select"); 180 181 if (input) { 182 input.required = true; 183 input.setAttribute("aria-required", "true"); 184 } 185 } 186 }); 187} 188 189function initializeApplyAutocompletetoForm() { 190 var targetForms = document.querySelectorAll("form"); 191 192 if (targetForms.length === 0) return; 193 194 var mapping = { 195 voornaam: "given-name", 196 voorletters: "given-name", 197 tussenvoegsel: "additional-name", 198 achternaam: "family-name", 199 last_name: "family-name", 200 geboortedatum: "bday", 201 "geboortedatum-day": "bday-day", 202 "geboortedatum-month": "bday-month", 203 "geboortedatum-year": "bday-year", 204 postcode: "postal-code", 205 huisnummer: "address-line2", 206 straatnaam: "address-line1", 207 adres: "address-line1", 208 stad: "address-level2", 209 emailadres: "email", 210 email: "email", 211 telefoonnummer: "tel", 212 }; 213 214 targetForms.forEach(function (targetForm) { 215 var inputs = targetForm.querySelectorAll("input[name], select[name]"); 216 217 inputs.forEach(function (input) { 218 var nameValue = input.getAttribute("name").toLowerCase(); 219 if (mapping[nameValue]) { 220 input.setAttribute("autocomplete", mapping[nameValue]); 221 } 222 }); 223 }); 224} 225 226initializeApplyAutocompletetoForm(); 227 228function initializeWhatsAppFocus() { 229 const container = document.querySelector(".c-messenger"); 230 const messengerBtn = document.querySelector("[js-messenger-toggle]"); 231 const messengerLink = document.querySelector(".messenger__link"); 232 233 if (!container || !messengerBtn || !messengerLink) return; 234 235 container.addEventListener("keydown", (e) => { 236 if (e.key !== "Tab") return; 237 238 const isOpen = container.classList.contains("is--visible"); 239 240 if (isOpen) { 241 if (document.activeElement === messengerBtn && !e.shiftKey) { 242 e.preventDefault(); 243 messengerLink.focus(); 244 } else if (document.activeElement === messengerLink && e.shiftKey) { 245 e.preventDefault(); 246 messengerBtn.focus(); 247 } 248 } 249 }); 250} 251 252initializeWhatsAppFocus(); 253 254function initializeNavigationFocus() { 255 const header = document.querySelector(".header"); 256 const toggle = header && header.querySelector(".navbar-toggle"); 257 258 if (!header || !toggle) return; 259 260 function isVisible(el) { 261 if (!el) return false; 262 return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); 263 } 264 265 function getLastTopLevelTab() { 266 const tabs = Array.from( 267 header.querySelectorAll(".navbar__tabs .navbar__tab") 268 ).filter(isVisible); 269 270 return tabs.length ? tabs[tabs.length - 1] : null; 271 } 272 273 function getActivePanel() { 274 const activePanel = 275 header.querySelector(".navbar__panel.is--active") || 276 header.querySelector('.navbar__panel[js-navbar-panel="active"]'); 277 278 return isVisible(activePanel) ? activePanel : null; 279 } 280 281 function getFocusableInPanel(panel) { 282 if (!panel) return []; 283 284 return Array.from( 285 panel.querySelectorAll( 286 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])' 287 ) 288 ).filter(isVisible); 289 } 290 291 function getActiveParentTab() { 292 // Prefer the active desktop tab in the left column 293 const activeDesktopTab = header.querySelector( 294 ".navbar__tabs .navbar__tab.is--active" 295 ); 296 if (isVisible(activeDesktopTab)) return activeDesktopTab; 297 298 // Fallback: active mobile tab in the panels column 299 const activeMobileTab = header.querySelector( 300 ".navbar__panels .navbar__tab--mobile.is--active" 301 ); 302 if (isVisible(activeMobileTab)) return activeMobileTab; 303 304 return null; 305 } 306 307 header.addEventListener( 308 "keydown", 309 function (e) { 310 if (e.key !== "Tab" || e.shiftKey) return; 311 312 const active = document.activeElement; 313 if (!active) return; 314 315 // CASE 1: 316 // From the final top-level .navbar__tab -> back to the toggle 317 const lastTopLevelTab = getLastTopLevelTab(); 318 if (lastTopLevelTab && active === lastTopLevelTab) { 319 e.preventDefault(); 320 toggle.focus(); 321 return; 322 } 323 324 // CASE 2: 325 // From the last focusable item in the active panel -> back to the parent tab 326 const activePanel = getActivePanel(); 327 if (!activePanel) return; 328 329 const focusables = getFocusableInPanel(activePanel); 330 if (!focusables.length) return; 331 332 const lastFocusable = focusables[focusables.length - 1]; 333 334 if (active === lastFocusable) {
335 const parentTab = getActiveParentTab(); 336 if (parentTab) { 337 e.preventDefault(); 338 parentTab.focus(); 339 } 340 } 341 }, 342 true 343 ); 344} 345 346initializeNavigationFocus(); 347 348function initializeNavigationFocusMobile() { 349 const navToggle = document.querySelector(".navbar-toggle"); 350 const navWrapper = document.querySelector(".nav-wrapper"); 351 352 if (!navToggle || !navWrapper) return; 353 354 navToggle.addEventListener("keydown", function (e) { 355 if (e.key === "Tab" && !e.shiftKey) { 356 const isExpanded = navToggle.getAttribute("aria-expanded") === "true"; 357 358 if (isExpanded) { 359 const firstMobileTab = navWrapper.querySelector(".navbar__tab--mobile"); 360 361 if (firstMobileTab) { 362 e.preventDefault(); 363 firstMobileTab.focus(); 364 } 365 } 366 } 367 }); 368 369 navWrapper.addEventListener("keydown", function (e) { 370 if (e.key !== "Tab") return; 371 372 const target = e.target; 373 374 const allMobileTabs = Array.from( 375 navWrapper.querySelectorAll(".navbar__tab--mobile, .navbar__tab--contact") 376 ); 377 378 // 1. Tab behavior on mobile tabs 379 if (target.classList.contains("navbar__tab--mobile")) { 380 const isPanelActive = target.classList.contains("is--active"); 381 382 const currentIndex = allMobileTabs.indexOf(target); 383 const isLastTab = currentIndex === allMobileTabs.length - 1; 384 385 if (!e.shiftKey) { 386 // If panel is closed â skip children 387 if (!isPanelActive) { 388 if (isLastTab) { 389 // ð LOOP BACK TO TOGGLE 390 e.preventDefault(); 391 navToggle.focus(); 392 } else { 393 const nextTab = allMobileTabs[currentIndex + 1]; 394 if (nextTab) { 395 e.preventDefault(); 396 nextTab.focus(); 397 } 398 } 399 } 400 } 401 } 402 403 // 2. Last link inside panel â back to its tab 404 if (!e.shiftKey && target.tagName === "A") { 405 const currentPanel = target.closest(".navbar__panel"); 406 if (!currentPanel) return; 407 408 const currentTab = navWrapper.querySelector( 409 `.navbar__tab--mobile[aria-controls="${currentPanel.id}"]` 410 ); 411 412 if (!currentTab) return; 413 414 const focusableLinks = Array.from( 415 currentPanel.querySelectorAll( 416 ".navbar__item-link, .navbar__child-link, .navbar__grandchild-link" 417 ) 418 ); 419 420 const lastLink = focusableLinks[focusableLinks.length - 1]; 421 422 if (target === lastLink) { 423 e.preventDefault(); 424 currentTab.focus(); 425 } 426 } 427 }); 428} 429 430initializeNavigationFocusMobile(); 431 432function initLocationButton() { 433 const locationButtons = document.querySelectorAll(".location h4 button"); 434 435 if (locationButtons.length === 0) { 436 return; 437 } 438 439 locationButtons.forEach(function (button) { 440 button.addEventListener("click", function () { 441 // 1. Check current state and flip it to the opposite 442 const isExpanded = this.getAttribute("aria-expanded") === "true"; 443 this.setAttribute("aria-expanded", !isExpanded); 444 445 // 2. Reset all OTHER location buttons to false 446 locationButtons.forEach(function (otherButton) { 447 if (otherButton !== button) { 448 otherButton.setAttribute("aria-expanded", "false"); 449 } 450 }); 451 }); 452 }); 453} 454 455initLocationButton();
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.