1(function () { 2 3 function isSearchBot() { 4 var ua = (navigator.userAgent || "").toLowerCase(); 5 var bots = [ 6 "googlebot", "adsbot-google", "mediapartners-google", "google-read-aloud", 7 "google-inspectiontool", "googleother", "storebot-google", 8 "google-cloudvertexbot", "googleproducer", "apis-google", 9 "bingbot", "msnbot", "adidxbot", "bingpreview", 10 "microsoftpreview", "bingvideopreview" 11 ]; 12 return bots.some(function (bot) { return ua.indexOf(bot) !== -1; }); 13 } 14 15 if (isSearchBot()) { 16 return; 17 } 18 19 var popup = document.getElementById("location-popup"); 20 var title = document.getElementById("location-title"); 21 var changeLocationLink = document.getElementById("change-location"); 22 var closeButton = popup ? popup.querySelector(".popup-close") : null; 23 var popupTimeout; 24 25 var POPUP_SHOWN_KEY = "locationPopupShown"; 26 var COOKIE_NAME = "userGeoPreference"; 27 28 function getCookie(name) { 29 var nameEQ = name + "="; 30 var ca = document.cookie.split(";"); 31 32 for (var i = 0; i < ca.length; i++) { 33 var c = ca[i].trim(); 34 35 if (c.indexOf(nameEQ) === 0) { 36 return decodeURIComponent(c.substring(nameEQ.length)); 37 } 38 } 39 40 return null; 41 } 42 43 function setCookie(name, value, days) { 44 var expires = ""; 45 46 if (days) { 47 var date = new Date(); 48 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 49 expires = "; expires=" + date.toUTCString(); 50 } 51 52 document.cookie = name + "=" + encodeURIComponent(value) + expires + "; path=/; SameSite=Lax"; 53 } 54 55 function getStoredUserLocation() { 56 var value = getCookie(COOKIE_NAME); 57 58 if (!value) { 59 return null; 60 } 61 62 try { 63 return JSON.parse(value); 64 } catch (e) { 65 return null; 66 } 67 } 68 69 function getCurrentLanguage() { 70 if (Array.isArray(alternateLanguageLinks) && alternateLanguageLinks.length) { 71 var current = alternateLanguageLinks.find(function (item) { 72 return item.IsCurrent || item.isCurrent || item.Selected || item.selected; 73 }); 74 75 if (current) { 76 return (current.Lang || current.lang || current.Culture || current.culture || "").toLowerCase(); 77 } 78 } 79 80 return (document.documentElement.lang || "").toLowerCase(); 81 } 82 83 function getCurrentSiteIso() { 84 var lang = document.documentElement.lang || ""; 85 var parts = lang.split("-"); 86 87 if (parts.length === 2) { 88 return parts[1].toUpperCase(); 89 } 90 91 return parts[0].toUpperCase(); 92 } 93 94 function getDisplayIso(isoCode) { 95 if (isoCode === "GB") { 96 return "UK"; 97 } 98 99 return isoCode; 100 } 101 102 function updatePopupTitle(isoCode) { 103 if (!title || !isoCode) { 104 return; 105 } 106 107 title.textContent = "Youâre visiting our " + getDisplayIso(isoCode) + " site"; 108 } 109 110 function saveUserGeoData(locationData) { 111 var language = getCurrentLanguage(); 112 var value = null; 113 114 const allCountries = Array.isArray(window.geoMapping && window.geoMapping.AllCountries) 115 ? window.geoMapping.AllCountries 116 : []; 117 118 const countryInfo = allCountries.find(function (c) { 119 return (c.IsoCode || "").toUpperCase() === (locationData.IsoCode || "").toUpperCase(); 120 }); 121 122 let resolvedLang = countryInfo && countryInfo.ResolvedTargetSiteUrl 123 ? countryInfo.ResolvedTargetSiteUrl 124 : ""; 125 126 if (resolvedLang === "/") { 127 resolvedLang = "en-us"; 128 } else { 129 resolvedLang = resolvedLang.replace(/^\//, ""); 130 } 131 132 if (locationData) { 133 value = JSON.stringify({ 134 country: locationData.Country || "", 135 isoCode: (locationData.IsoCode || "").toUpperCase(), 136 city: locationData.City || "", 137 latitude: locationData.Latitude || null, 138 longitude: locationData.Longitude || null, 139 language: resolvedLang 140 }); 141
142 setCookie(COOKIE_NAME, value, 365); 143 } 144 145 return JSON.parse(value); 146 } 147 148 function hasPopupBeenHandled() { 149 return getCookie(POPUP_SHOWN_KEY) === "true"; 150 } 151 152 function markPopupHandled() { 153 setCookie(POPUP_SHOWN_KEY, "true", 365); 154 } 155 156 function startAutoHide() { 157 clearTimeout(popupTimeout); 158 popupTimeout = setTimeout(function () { 159 closePopup(false); 160 }, 10000); 161 } 162 163 function closePopup(isUserAction) { 164 clearTimeout(popupTimeout); 165 166 if (!popup) { 167 return; 168 } 169 170 popup.classList.remove("show"); 171 popup.setAttribute("aria-hidden", "true"); 172 173 if (isUserAction) { 174 markPopupHandled(); 175 } 176 } 177 178 function showPopup() { 179 if (!popup) { 180 return; 181 } 182 183 popup.classList.add("show"); 184 popup.setAttribute("aria-hidden", "false"); 185 startAutoHide(); 186 } 187 188 function shouldShowPopup(userIso, siteIso) { 189 if(userIso === "CN") userIso = "ZH"; 190 191 if (!userIso || !siteIso) { 192 return false; 193 } 194 195 return userIso !== siteIso; 196 } 197 198 function getAlternateLinkForLanguage(targetLanguage) { 199 if (!targetLanguage) return null; 200 201 var normalized = targetLanguage.toLowerCase(); 202 var links = document.querySelectorAll('link[rel="alternate"][hreflang][href]'); 203 204 for (var i = 0; i < links.length; i++) { 205 var hreflang = (links[i].getAttribute("hreflang") || "").toLowerCase(); 206 207 if(normalized === "en-us") normalized = "x-default"; 208 209 if (hreflang === normalized) { 210 return links[i].getAttribute("href"); 211 } 212 } 213 214 return null; 215 } 216 217 function getAlternateLinkForIso(targetIso) { 218 if (!targetIso) { 219 return null; 220 } 221 222 var normalizedIso = targetIso.toLowerCase(); 223 var links = document.querySelectorAll('link[rel="alternate"][hreflang][href]'); 224 225 var exactEnglishMatch = null; 226 var fallbackMatch = null; 227 228 for (var i = 0; i < links.length; i++) { 229 var link = links[i]; 230 var hreflang = (link.getAttribute("hreflang") || "").toLowerCase(); 231 var parts = hreflang.split("-"); 232 233 if (parts.length !== 2) { 234 continue; 235 } 236 237 var languagePart = parts[0]; 238 var countryPart = parts[1]; 239 240 if (countryPart !== normalizedIso) { 241 continue; 242 } 243 244 if (!fallbackMatch) { 245 fallbackMatch = link.getAttribute("href"); 246 } 247 248 if (languagePart === "en") { 249 exactEnglishMatch = link.getAttribute("href"); 250 break; 251 } 252 } 253 254 return exactEnglishMatch || fallbackMatch; 255 } 256 257 function isAllowedHost() { 258 var allowedHosts = [ 259 "www.delphiautoparts.com", 260 "delphiautoparts-stg.sitefinity.cloud", 261 "localhost" //add for testing purposes, can be removed later 262 ]; 263 264 var currentHost = window.location.hostname.toLowerCase(); 265 266 return allowedHosts.includes(currentHost); 267 } 268 269 function appendCurrentQueryParams(targetUrl) { 270 var currentSearch = window.location.search; 271 272 if (!currentSearch) { 273 return targetUrl; 274 } 275 276 console.log(targetUrl, currentSearch) 277 278 var url = new URL(targetUrl, window.location.origin); 279 var currentParams = new URLSearchParams(currentSearch); 280 281 console.log(url) 282 283 currentParams.forEach(function (value, key) { 284 if (!url.searchParams.has(key)) { 285 url.searchParams.set(key, value); 286 } 287 }); 288 289 return url.href; 290 } 291 292 function redirectToPreferredSiteIfNeeded() { 293 if (!isAllowedHost()) { 294 return; 295 } 296 297 var storedUserLocation = getStoredUserLocation(); 298 299 if (!storedUserLocation) { 300 return false; 301 } 302 303 var currentLanguage = (document.documentElement.lang || "").toLowerCase(); 304 var currentIso = getCurrentSiteIso().toLowerCase(); 305 var targetUrl = null; 306 307 var preferredLanguage = storedUserLocation.language.toLowerCase(); 308 309 if (preferredLanguage === currentLanguage) { 310 return false; 311 } 312 313 targetUrl = getAlternateLinkForLanguage(preferredLanguage); 314 315 if (!targetUrl) { 316 return false; 317 } 318 319 var currentPath = window.location.pathname.toLowerCase(); 320 var targetPath = new URL(targetUrl, window.location.origin).pathname.toLowerCase(); 321 322 323 if (currentPath === targetPath) { 324 return false; 325 } 326 327 328 window.location.href = appendCurrentQueryParams(targetUrl); 329 return true; 330 } 331 332 function fetchUserLocationByIp() { 333 return fetch("/locationapi/v1/findlocation", { 334 method: "GET", 335 headers: { 336 "Accept": "application/json" 337 }, 338 credentials: "same-origin" 339 }) 340 .then(function (response) { 341 if (!response.ok) { 342 throw new Error("Location request failed: " + response.status); 343 } 344 345 return response.json(); 346 }) 347 .then(function (data) { 348 if (!data || data.Status !== 200 || !data.location) { 349 throw new Error("Invalid IP location response"); 350 } 351 352 return data.location; 353 }); 354 } 355 356 function getBrowserCoordinates() { 357 return new Promise(function (resolve, reject) { 358 if (!navigator.geolocation) { 359 reject(new Error("Geolocation is not supported")); 360 return; 361 } 362 363 navigator.geolocation.getCurrentPosition( 364 function (position) { 365 resolve({ 366 latitude: position.coords.latitude, 367 longitude: position.coords.longitude 368 }); 369 }, 370 function (error) { 371 reject(error); 372 redirectToRegionSelector(); 373 }, 374 {
375 enableHighAccuracy: false, 376 maximumAge: 300000 377 } 378 ); 379 }); 380 } 381 382 function hasExistingUserGeoPreference() { 383 var stored = getStoredUserLocation(); 384 385 return !!(stored && stored.isoCode); 386 } 387 388 function tryBrowserLocationThenFallback() { 389 return getBrowserCoordinates() 390 .then(function (coords) { 391 return fetchUserLocationByIp(); 392 }) 393 .catch(function () { 394 if (!hasExistingUserGeoPreference()) { 395 setCookie(COOKIE_NAME, "null", 365); 396 } 397 398 throw new Error("Geolocation denied or unavailable"); 399 }); 400 } 401 402 function getResolvedLanguageFromIso(isoCode) { 403 if (!isoCode) { 404 return ""; 405 } 406 407 var allCountries = Array.isArray(window.geoMapping && window.geoMapping.AllCountries) 408 ? window.geoMapping.AllCountries 409 : []; 410 411 var countryInfo = allCountries.find(function (c) { 412 return (c.IsoCode || "").toUpperCase() === isoCode.toUpperCase(); 413 }); 414 415 var resolvedLang = countryInfo && countryInfo.ResolvedTargetSiteUrl 416 ? countryInfo.ResolvedTargetSiteUrl 417 : ""; 418 419 if (resolvedLang === "/") { 420 return "en-us"; 421 } 422 423 return resolvedLang.replace(/^\//, "").toLowerCase(); 424 } 425 426 function redirectToRegionSelector() { 427 if (!sessionStorage.getItem("geo_redirected")) { 428 sessionStorage.setItem("geo_redirected", "true"); 429 430 localStorage.setItem( 431 "lastVisitedPageLinks", 432 JSON.stringify(alternateLanguageLinks || []) 433 ); 434 435 window.location.href = "/regional-selector"; 436 } 437 } 438 439 function processLocation(location) { 440 var siteLanguage = getCurrentLanguage(); 441 var savedData = saveUserGeoData(location); 442 443 if (!savedData || !savedData.isoCode) { 444 return; 445 } 446 447 var desiredLanguage = getResolvedLanguageFromIso(savedData.isoCode); 448 449 // User is already on their served site 450 if (!desiredLanguage || desiredLanguage === siteLanguage) { 451 return; 452 } 453 454 // User allowed location, but is not on served site 455 redirectToRegionSelector(); 456 } 457 458 document.addEventListener("DOMContentLoaded", function () { 459 460 document.querySelectorAll(".language-name-wrapper").forEach(function (element) { 461 element.href = getCookie(COOKIE_NAME) ? "/region-change" : "/regional-selector"; 462 463 element.addEventListener("click", function () { 464 localStorage.setItem("lastVisitedPageLinks", JSON.stringify(alternateLanguageLinks || [])); 465 markPopupHandled(); 466 }); 467 }); 468 if (redirectToPreferredSiteIfNeeded()) { 469 return; 470 } 471 472 var siteIso = getCurrentSiteIso(); 473 var storedUserLocation = getStoredUserLocation(); 474 475 476 if (closeButton) { 477 closeButton.addEventListener("click", function () { 478 closePopup(true); 479 }); 480 } 481 482 if (changeLocationLink) { 483 changeLocationLink.addEventListener("click", function (e) { 484 e.preventDefault(); 485 486 localStorage.setItem("lastVisitedPageLinks", JSON.stringify(alternateLanguageLinks || [])); 487 markPopupHandled(); 488 489 window.location.href = e.currentTarget.href; 490 }); 491 } 492 493 if (popup) { 494 popup.addEventListener("mouseenter", function () { 495 clearTimeout(popupTimeout); 496 }); 497 498 popup.addEventListener("mouseleave", function () { 499 startAutoHide(); 500 }); 501 } 502 503 if (storedUserLocation && storedUserLocation.isoCode) { 504 var storedUserIso = (storedUserLocation.isoCode || "").toUpperCase(); 505 506 507 if (shouldShowPopup(storedUserIso, siteIso)) { 508 var lang = (storedUserLocation.language || "").toLowerCase(); 509 var matchedKey = alternateLanguageLinks && Object.keys(alternateLanguageLinks).find(function (k) { 510 return k.toLowerCase() === lang; 511 }); 512 var matchingLink = matchedKey ? alternateLanguageLinks[matchedKey] : null; 513 514 if (!matchingLink) { 515 updatePopupTitle(siteIso); 516 showPopup(); 517 } 518 } 519 520 return; 521 } 522 523 if(isAllowedHost()) { 524 tryBrowserLocationThenFallback() 525 .then(function (location) { 526 processLocation(location); 527 }) 528 .catch(function (error) { 529 redirectToRegionSelector(); 530 }); 531 } 532 });
533})();
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.