1(function () { 2 "use strict"; 3 4 var header = document.getElementById("site-header"); 5 if (!header) { 6 return; 7 } 8 9 var initFrenchLinkGuard = function () { 10 var path = window.location.pathname || "/"; 11 var isFrenchPath = path === "/fr" || path === "/fr/" || path.indexOf("/fr/") === 0; 12 if (!isFrenchPath) { 13 return; 14 } 15 16 var blockedPrefixes = ["/wp-admin/", "/wp-content/", "/wp-includes/", "/wp-json/", "/xmlrpc.php"]; 17 var frenchPathMap = { 18 "/": "/fr/", 19 "/shop/": "/fr/shop/", 20 "/mein-konto/": "/fr/mon-compte/", 21 "/my-account/": "/fr/mon-compte/", 22 "/warenkorb/": "/fr/panier-dachat/", 23 "/cart/": "/fr/panier-dachat/", 24 "/kasse/": "/fr/caisse/", 25 "/checkout/": "/fr/caisse/", 26 "/ueber-uns/": "/fr/a-propos/", 27 "/kontakt/": "/fr/contact/", 28 "/faq/": "/fr/faq/", 29 "/impressum/": "/fr/mentions-legales/", 30 "/agb/": "/fr/conditions-generales/", 31 "/versand/": "/fr/expedition/", 32 "/datenschutzerklaerung/": "/fr/declaration-de-confidentialite/", 33 "/all-one-blog/": "/fr/all-one-blog/", 34 "/store-locator/": "/fr/store-locator/", 35 "/fairtrade-projekte/": "/fr/fairtrade-projekte/" 36 }; 37 38 var normalizePath = function (value) { 39 if (!value) { 40 return "/"; 41 } 42 var result = value.charAt(0) === "/" ? value : "/" + value; 43 if (result !== "/" && result.charAt(result.length - 1) !== "/") { 44 result += "/"; 45 } 46 return result.toLowerCase(); 47 }; 48 49 var localizeUrl = function (href) { 50 if (!href) { 51 return href; 52 } 53 54 if (/^(?:#|mailto:|tel:|javascript:|\?)/i.test(href)) { 55 return href; 56 } 57 58 var parsed; 59 try { 60 parsed = new URL(href, window.location.href); 61 } catch (error) { 62 return href; 63 } 64 65 if (parsed.host !== window.location.host) { 66 return href; 67 } 68 69 var normalized = normalizePath(parsed.pathname); 70 if (normalized === "/fr/" || normalized.indexOf("/fr/") === 0) { 71 return parsed.toString(); 72 } 73 74 for (var i = 0; i < blockedPrefixes.length; i += 1) { 75 if (normalized.indexOf(blockedPrefixes[i]) === 0) { 76 return href; 77 } 78 } 79 80 var targetPath = frenchPathMap[normalized] || "/fr" + normalized; 81 parsed.pathname = targetPath; 82 return parsed.toString(); 83 }; 84 85 var shouldSkipAnchor = function (anchor) { 86 if (!anchor) { 87 return true; 88 } 89 90 var href = anchor.getAttribute("href") || ""; 91 if ("" === href || "#" === href) { 92 return true; 93 } 94 95 var text = ((anchor.textContent || "") + " " + (anchor.getAttribute("aria-label") || "")).trim().toUpperCase(); 96 if ("DE" === text) { 97 return true; 98 } 99 100 return false; 101 }; 102 103 var localizeAnchor = function (anchor) { 104 if (shouldSkipAnchor(anchor)) { 105 return; 106 } 107 108 var original = anchor.getAttribute("href") || ""; 109 var localized = localizeUrl(original); 110 if (localized && localized !== original) { 111 anchor.setAttribute("href", localized); 112 } 113 }; 114 115 var localizeAllAnchors = function (root) { 116 var scope = root || document; 117 var anchors = scope.querySelectorAll ? scope.querySelectorAll("a[href]") : []; 118 anchors.forEach(localizeAnchor); 119 if (scope.matches && scope.matches("a[href]")) { 120 localizeAnchor(scope); 121 } 122 }; 123 124 localizeAllAnchors(document); 125 126 var observer = new MutationObserver(function (mutations) { 127 mutations.forEach(function (mutation) { 128 mutation.addedNodes.forEach(function (node) { 129 if (!node || node.nodeType !== 1) { 130 return; 131 } 132 localizeAllAnchors(node); 133 }); 134 }); 135 }); 136 137 observer.observe(document.body, { childList: true, subtree: true }); 138 }; 139 140 initFrenchLinkGuard(); 141 142 var initTouchDesktopDropdowns = function () { 143 var desktopNav = header.querySelector(".site-nav-desktop .site-navigation"); 144 if (!desktopNav || !window.matchMedia) { 145 return; 146 } 147 148 var dropdownItems = Array.prototype.slice.call( 149 desktopNav.querySelectorAll(".site-nav__item.site-nav--has-dropdown, .site-nav__item.site-nav--language") 150 ); 151 if (!dropdownItems.length) { 152 return; 153 } 154 155 var touchQuery = window.matchMedia("(hover: none), (pointer: coarse)"); 156 157 var isTouchContext = function (event) { 158 if (touchQuery.matches) { 159 return true; 160 } 161 162 if (!event || typeof event !== "object") { 163 return false;
164 } 165 166 if (event.pointerType && event.pointerType.toLowerCase() === "touch") { 167 return true; 168 } 169 170 return false; 171 }; 172 173 var closeAll = function (exceptItem) { 174 dropdownItems.forEach(function (item) { 175 var trigger = item.querySelector(":scope > .site-nav__link--has-dropdown"); 176 var shouldStayOpen = !!exceptItem && item === exceptItem; 177 item.classList.toggle("is-touch-open", shouldStayOpen); 178 if (trigger) { 179 trigger.setAttribute("aria-expanded", shouldStayOpen ? "true" : "false"); 180 } 181 }); 182 }; 183 184 dropdownItems.forEach(function (item) { 185 var trigger = item.querySelector(":scope > .site-nav__link--has-dropdown"); 186 if (!trigger) { 187 return; 188 } 189 190 trigger.setAttribute("aria-haspopup", "true"); 191 trigger.setAttribute("aria-expanded", "false"); 192 193 trigger.addEventListener("click", function (event) { 194 if (!isTouchContext(event)) { 195 return; 196 } 197 198 event.preventDefault(); 199 event.stopPropagation(); 200 201 var isOpen = item.classList.contains("is-touch-open"); 202 closeAll(isOpen ? null : item); 203 }); 204 205 var dropdownLinks = item.querySelectorAll(".site-nav__dropdown a"); 206 dropdownLinks.forEach(function (link) { 207 link.addEventListener("click", function () { 208 closeAll(); 209 }); 210 }); 211 }); 212 213 document.addEventListener("pointerdown", function (event) { 214 if (!isTouchContext(event)) { 215 return; 216 } 217 218 var clickedInside = dropdownItems.some(function (item) { 219 return item.contains(event.target); 220 }); 221 222 if (!clickedInside) { 223 closeAll(); 224 } 225 }); 226 227 document.addEventListener("keydown", function (event) { 228 if (event.key === "Escape") { 229 closeAll(); 230 } 231 }); 232 233 var handleContextChange = function () { 234 closeAll(); 235 }; 236 237 if (typeof touchQuery.addEventListener === "function") { 238 touchQuery.addEventListener("change", handleContextChange); 239 } else if (typeof touchQuery.addListener === "function") { 240 touchQuery.addListener(handleContextChange); 241 } 242 }; 243 244 initTouchDesktopDropdowns(); 245 246 var initAnnouncementBar = function () { 247 var bars = document.querySelectorAll(".js-announcement-bar"); 248 if (!bars.length) { 249 return; 250 } 251 252 var resizeTimer = null; 253 var FONT_LOAD_TIMEOUT = 1500; 254 var mobileQuery = window.matchMedia("(max-width: 767px)"); 255 256 var getViewportNode = function (bar) { 257 return bar.querySelector(".announcement__link") || bar.querySelector(".announcement") || bar; 258 }; 259 260 var getBarGap = function (bar) { 261 var styles = window.getComputedStyle(bar); 262 var parsed = Number.parseFloat(styles.getPropertyValue("--announcement-gap")); 263 return Number.isFinite(parsed) && parsed >= 0 ? parsed : 80; 264 }; 265 266 var clearGeneratedCopies = function (track) { 267 var generated = track.querySelectorAll("[data-announcement-generated='1']"); 268 if (!generated.length) { 269 return; 270 } 271 272 generated.forEach(function (node) { 273 if (node && node.parentNode) { 274 node.parentNode.removeChild(node); 275 } 276 }); 277 }; 278 279 var updateBar = function (bar) { 280 var track = bar.querySelector(".js-announcement-track"); 281 var copy = bar.querySelector(".js-announcement-copy"); 282 var viewport = getViewportNode(bar); 283 var availableWidth; 284 var contentWidth; 285 var gap; 286 var distance; 287 var itemSpan; 288 var minTrackWidth; 289 var requiredCopies; 290 var currentCopies; 291 var speed; 292 var duration; 293 var clone; 294 295 if (!track || !copy) { 296 return; 297 } 298 299 clearGeneratedCopies(track); 300 bar.classList.remove("is-marquee"); 301 302 if (!mobileQuery.matches) { 303 return; 304 } 305 306 availableWidth = Math.max(0, Math.ceil(viewport.getBoundingClientRect().width)); 307 contentWidth = Math.max(0, Math.ceil(copy.getBoundingClientRect().width)); 308 if (availableWidth < 1 || contentWidth < 1) { 309 return; 310 } 311 312 gap = getBarGap(bar); 313 itemSpan = contentWidth + gap; 314 minTrackWidth = availableWidth + itemSpan * 2; 315 requiredCopies = Math.max(2, Math.ceil(minTrackWidth / Math.max(1, itemSpan))); 316 currentCopies = 1; 317 318 while (currentCopies < requiredCopies) { 319 clone = copy.cloneNode(true); 320 clone.classList.add("announcement__copy--clone"); 321 clone.setAttribute("aria-hidden", "true"); 322 clone.setAttribute("data-announcement-generated", "1"); 323 track.appendChild(clone); 324 currentCopies += 1; 325 } 326 327 distance = itemSpan; 328 speed = Number(bar.getAttribute("data-speed")) || Number.parseFloat(window.getComputedStyle(bar).getPropertyValue("--announcement-speed")) || 45; 329 duration = Math.max(8, distance / Math.max(20, speed)); 330 bar.style.setProperty("--announcement-duration", duration.toFixed(2) + "s"); 331 bar.style.setProperty("--announcement-shift", "-" + String(Math.round(distance)) + "px"); 332 bar.classList.add("is-marquee"); 333 }; 334 335 var updateAllBars = function () {
336 bars.forEach(updateBar); 337 }; 338 339 window.addEventListener( 340 "resize", 341 function () { 342 if (resizeTimer) { 343 window.clearTimeout(resizeTimer); 344 } 345 resizeTimer = window.setTimeout(updateAllBars, 140); 346 }, 347 { passive: true } 348 ); 349 350 if (typeof mobileQuery.addEventListener === "function") { 351 mobileQuery.addEventListener("change", updateAllBars); 352 } else if (typeof mobileQuery.addListener === "function") { 353 mobileQuery.addListener(updateAllBars); 354 } 355 356 window.addEventListener( 357 "load", 358 function () { 359 updateAllBars(); 360 }, 361 { once: true, passive: true } 362 ); 363 364 if (document.fonts && document.fonts.ready && typeof document.fonts.ready.then === "function") { 365 Promise.race([ 366 document.fonts.ready, 367 new Promise(function (resolve) { 368 window.setTimeout(resolve, FONT_LOAD_TIMEOUT); 369 }) 370 ]) 371 .then(function () { 372 updateAllBars(); 373 }) 374 .catch(function () { 375 updateAllBars(); 376 }); 377 } 378 379 updateAllBars(); 380 }; 381 382 initAnnouncementBar(); 383 384 var searchPanel = header.querySelector("[data-header-search]"); 385 var searchToggles = header.querySelectorAll("[data-header-search-toggle]"); 386 387 if (!searchPanel || !searchToggles.length) { 388 return; 389 } 390 391 var searchCloseTimer = null; 392 var scrollTicking = false; 393 var barVisible = true; 394 var lastY = 0; 395 396 var setSearchToggleState = function (isOpen) { 397 searchToggles.forEach(function (toggle) { 398 toggle.setAttribute("aria-expanded", String(isOpen)); 399 }); 400 }; 401 402 var isSearchOpen = function () { 403 return !searchPanel.hidden && searchPanel.classList.contains("is-open"); 404 }; 405 406 var openSearch = function () { 407 if (searchCloseTimer) { 408 window.clearTimeout(searchCloseTimer); 409 searchCloseTimer = null; 410 } 411 412 searchPanel.hidden = false; 413 window.requestAnimationFrame(function () { 414 searchPanel.classList.add("is-open"); 415 }); 416 setSearchToggleState(true); 417 418 var input = searchPanel.querySelector('input[type="search"]'); 419 if (input) { 420 input.focus(); 421 } 422 }; 423 424 var closeSearch = function () { 425 if (searchPanel.hidden && !searchPanel.classList.contains("is-open")) { 426 return; 427 } 428 429 searchPanel.classList.remove("is-open"); 430 setSearchToggleState(false); 431 432 if (searchCloseTimer) { 433 window.clearTimeout(searchCloseTimer); 434 } 435 436 searchCloseTimer = window.setTimeout(function () { 437 searchPanel.hidden = true; 438 searchCloseTimer = null; 439 }, 220); 440 }; 441 442 var syncScrollState = function () { 443 var y = Math.max(0, Math.round(window.scrollY || 0)); 444 445 if (barVisible && y > 56 && y > lastY) { 446 barVisible = false; 447 header.classList.add("is-scrolled"); 448 } else if (!barVisible && y <= 0) { 449 barVisible = true; 450 header.classList.remove("is-scrolled"); 451 } 452 453 lastY = y; 454 scrollTicking = false; 455 }; 456 457 searchToggles.forEach(function (toggle) { 458 toggle.addEventListener("click", function (event) { 459 event.preventDefault(); 460 event.stopPropagation(); 461 462 if (isSearchOpen()) { 463 closeSearch(); 464 return; 465 } 466 467 openSearch(); 468 }); 469 }); 470 471 document.addEventListener("click", function (event) { 472 if (!isSearchOpen()) { 473 return; 474 } 475 476 if (searchPanel.contains(event.target)) { 477 return; 478 } 479 480 var clickedToggle = Array.prototype.some.call(searchToggles, function (toggle) { 481 return toggle.contains(event.target); 482 }); 483 484 if (clickedToggle) { 485 return; 486 } 487 488 closeSearch(); 489 }); 490 491 document.addEventListener("keydown", function (event) { 492 if (event.key === "Escape") { 493 closeSearch(); 494 } 495 }); 496 497 window.addEventListener( 498 "scroll", 499 function () { 500 if (scrollTicking) { 501 return; 502 } 503 504 scrollTicking = true; 505 window.requestAnimationFrame(syncScrollState); 506 }, 507 { passive: true } 508 ); 509 510 barVisible = (window.scrollY || 0) <= 0; 511 lastY = Math.max(0, Math.round(window.scrollY || 0)); 512 header.classList.toggle("is-scrolled", !barVisible); 513 syncScrollState(); 514})();
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.