1function loadMap() { 2 let apiKey = locationFinderData.apiKey; 3 if (!apiKey) return; 4 5 const script = document.createElement('script'); 6 7 // Set the source to the map script URL with the API key 8 script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=geometry`; 9 script.setAttribute('data-loaded', true); 10 script.onload = function () { 11 initMap() 12 } 13 // Append the script element to the document body or head 14 document.body.appendChild(script); 15} 16 17function initMap() { 18 19 const locations = JSON.parse(locationFinderData.locations); 20 const locationWithValue = JSON.parse(locationFinderData.locationWithValue); 21 22 const geocoder = new google.maps.Geocoder(); 23 const locationPromises = locations.map(location => geocodeAddress(geocoder, location)); 24 25 Promise.all(locationPromises).then(locationsLatLng => { 26 if (navigator.geolocation) { 27 navigator.geolocation.getCurrentPosition(position => { 28 const userLocation = { 29 lat: position.coords.latitude, 30 lng: position.coords.longitude 31 }; 32 33 let closestLocation = null; 34 let closestDistance = Number.MAX_VALUE; 35 36 console.log(locationsLatLng) 37 38 locationsLatLng.forEach(location => { 39 let currentLocation = location; 40 41 let find = locationWithValue.find( e=> e.name == location.name ); 42 if(find){ 43 currentLocation.lat = find.lat; 44 currentLocation.lng = find.lng; 45 } 46 47 console.log(currentLocation); 48 49 const distance = google.maps.geometry.spherical.computeDistanceBetween( 50 new google.maps.LatLng(userLocation.lat, userLocation.lng), 51 new google.maps.LatLng(currentLocation.lat, currentLocation.lng) 52 ); 53 54 if (distance < closestDistance) { 55 closestDistance = distance; 56 closestLocation = location; 57 } 58 }); 59 60 if (closestLocation) { 61 let value = null; 62 let filter = locationWithValue.filter(loc => loc.name == closestLocation.name); 63 if(filter.length > 0){ 64 value = filter[0].value 65 //setCookie(value); 66 } 67 68 //setCookie(closestLocation.name); 69 70 let location = document.querySelector("form#location-select"); 71 if (location) { 72 let select = location.querySelector('select.location-select'); 73 if (select && !select.value) { 74 for (let i = 0; i < select.options.length; i++) { 75 if (select.options[i].innerText == closestLocation.name) { 76 setLocation(select.options[i].value) 77 let url = new URL(window.location); 78 if(url.pathname.includes('menu')){ 79 window.location.href = `/menu/${select.options[i].value}${url.search}` 80 } 81 // location 82 } 83 } 84 } 85 } 86 87 if(locationFinderData.isBlog == 'yes' && value){ 88 updateBlogLinks(value) 89 } 90 91 // alert(`The closest location is ${closestLocation.name} at a distance of ${(closestDistance / 1000).toFixed(2)} km.`); 92 } 93 }, () => { 94 console.error('Error: The Geolocation service failed.'); 95 }); 96 } else { 97 console.error('Error: Your browser doesn\'t support geolocation.'); 98 } 99 }); 100 101 102} 103 104// function initMap() { 105 106// let location = document.querySelector("form#location-select"); 107// if (location) { 108// let select = location.querySelector('select.location-select'); 109// if (select && !select.value) { 110// const locations = JSON.parse(locationFinderData.locations); 111 112// const geocoder = new google.maps.Geocoder(); 113// const locationPromises = locations.map(location => geocodeAddress(geocoder, location)); 114 115// Promise.all(locationPromises).then(locationsLatLng => { 116// if (navigator.geolocation) { 117// navigator.geolocation.getCurrentPosition(position => { 118// const userLocation = { 119// lat: position.coords.latitude,
120// lng: position.coords.longitude 121// }; 122 123// let closestLocation = null; 124// let closestDistance = Number.MAX_VALUE; 125 126// console.log(locationsLatLng) 127 128// locationsLatLng.forEach(location => { 129// const distance = google.maps.geometry.spherical.computeDistanceBetween( 130// new google.maps.LatLng(userLocation.lat, userLocation.lng), 131// new google.maps.LatLng(location.lat, location.lng) 132// ); 133 134// if (distance < closestDistance) { 135// closestDistance = distance; 136// closestLocation = location; 137// } 138// }); 139 140// if (closestLocation) { 141 142// for (let i = 0; i < select.options.length; i++) { 143// if (select.options[i].innerText == closestLocation.name) { 144// setLocation(select.options[i].value) 145// let url = new URL(window.location); 146// if(url.pathname.includes('menu')){ 147// window.location.href = `/menu/${select.options[i].value}${url.search}` 148// } 149// // location 150// } 151// } 152// console.log(select, select.options.length); 153// // alert(`The closest location is ${closestLocation.name} at a distance of ${(closestDistance / 1000).toFixed(2)} km.`); 154// } 155// }, () => { 156// console.error('Error: The Geolocation service failed.'); 157// }); 158// } else { 159// console.error('Error: Your browser doesn\'t support geolocation.'); 160// } 161// }); 162// } 163// } 164// } 165 166function geocodeAddress(geocoder, address) { 167 return new Promise((resolve, reject) => { 168 geocoder.geocode({ 'address': address }, (results, status) => { 169 if (status === 'OK') { 170 resolve({ 171 name: address, 172 lat: results[0].geometry.location.lat(), 173 lng: results[0].geometry.location.lng() 174 }); 175 } else { 176 reject(`Geocode was not successful for the following reason: ${status}`); 177 } 178 }); 179 }); 180} 181 182function setLocation(name){ 183 let select = document.querySelectorAll('select.location-select'); 184 select.forEach(ele => ele.value = name); 185 186 let links = document.querySelectorAll('.product--categories a'); 187 let current_location = document.querySelector('select[name="location"]'); 188 189 if(links.length > 0 && current_location.value && current_location.value != ""){ 190 links.forEach(ele => { 191 let link = ele.href; 192 if(link.includes('/menu')){ 193 let currenturl = new URL(link); 194 let search = currenturl.search; 195 let updatedLink = `/menu/${current_location.value}`; 196 //link = link.replace('/menu', `/menu/${current_location.value}`); 197 ele.href = updatedLink + `${search}`; 198 } 199 }) 200 } 201 202 setCookie('selected_location', name, 168); 203 204} 205 206function setCookie(name, value, hours) { 207 const d = new Date(); 208 d.setTime(d.getTime() + (hours * 60 * 60 * 1000)); // Convert hours to milliseconds 209 const expires = "expires=" + d.toUTCString(); 210 document.cookie = name + "=" + value + ";" + expires + ";path=/"; 211} 212 213function getCookie(name) { 214 const decodedCookie = decodeURIComponent(document.cookie); 215 const cookieArray = decodedCookie.split(';'); 216 const cookieName = name + "="; 217 218 for(let i = 0; i < cookieArray.length; i++) { 219 let cookie = cookieArray[i].trim(); 220 if (cookie.indexOf(cookieName) === 0) { 221 return cookie.substring(cookieName.length, cookie.length); 222 } 223 } 224 return ""; 225} 226 227function attachEvent(){ 228 let url = new URL(window.location); 229 if(url.pathname != "/"){ 230 return ; 231 } 232 let locationsSelectors = document.querySelectorAll(".location-select"); 233 console.log(locationsSelectors) 234 locationsSelectors.forEach(ele => { 235 ele.addEventListener('change', (e)=>{ 236 let value = e.target.value; 237 let locations = document.querySelectorAll(".location-select"); 238 locations.forEach(loc => { 239 if(loc.value != value){ 240 loc.value = value 241 } 242 }) 243 setLocation(value); 244 }) 245 }) 246} 247 248 249window.addEventListener('DOMContentLoaded', ()=>{ 250 if(getCookie('selected_location')){ 251 setLocation(getCookie('selected_location')) 252 if(locationFinderData.isBlog == 'yes'){ 253 updateBlogLinks(getCookie('selected_location')) 254 } 255 } 256 attachEvent() 257 258 //alert(getCookie('selected_location')); 259 260 // ======== 261 if(!getCookie('selected_location')){ 262 let select = document.querySelectorAll('select.location-select'); 263 select.forEach(ele => ele.value = ''); 264 if(locationFinderData.autoDetect == 'yes'){ 265 // alert('yes'); 266 loadMap(); 267 } 268 } 269}) 270 271 272function updateBlogLinks(name){ 273 console.log('============== updating blog links =============') 274 let current_link = new URL(window.location); 275 let anchors = document.querySelectorAll('a'); 276
277 anchors.forEach(a => { 278 try{ 279 let url = new URL(a.href); 280 if(url.host == current_link.host && url.pathname.includes('/menu')){ 281 a.href = `${url.origin}/menu/${name}${url.search}`; 282 } 283 }catch(ex){ 284 // continue; 285 } 286 }) 287 288} 289 290// window.addEventListener('load', () => { 291// let location = document.querySelector("form#location-select"); 292// console.log(location); 293// if (location) { 294// let select = location.querySelector('select.location-select'); 295// console.log(select, select.value, 'init') 296// if (select && !select.value) { 297// if(getCookie('selected_location')){ 298// setLocation(getCookie('selected_location')) 299// }else{ 300// loadMap(select, location); 301// } 302// } 303// } 304// }) 305 306class CustomPopup extends HTMLElement { 307 constructor() { 308 super(); 309 this.redirect = null; 310 this.previousFocusedElement = null; // Store the element that was focused before the popup opened 311 if (!getCookie('selected_location')) { 312 this.init(); 313 } 314 this.form = this.querySelector('form'); 315 this.form?.addEventListener('submit', this.handleSubmit.bind(this)); 316 this.closeBtn = this.querySelector('.close__popup-btn'); 317 this.closeBtn?.addEventListener('click', this.handleClose.bind(this)); 318 this.handleKeyDown = this.handleKeyDown.bind(this); // Bind for event listener 319 } 320 321 init() { 322 if(locationFinderData.autoDetect == 'no'){ 323 this.attachEvent(); 324 return ; 325 } 326 327 if (navigator.geolocation) { 328 navigator.geolocation.getCurrentPosition(() => {}, this.handleLocationError.bind(this)); 329 } 330 } 331 332 handleLocationError(err) { 333 // console.log('in custom popup', err); 334 this.attachEvent(); 335 } 336 337 attachEvent() { 338 // For Home page 339 let links = document.querySelectorAll('.product--categories a'); 340 if (links.length > 0) { 341 links.forEach(ele => { 342 let link = ele.href; 343 if (link.includes('/menu')) { 344 ele.addEventListener('click', this.handleEvent.bind(this)); 345 } 346 }); 347 } 348 if (locationFinderData.isBlog == 'yes') { 349 let current_link = new URL(window.location); 350 let anchors = document.querySelectorAll('a'); 351 352 anchors.forEach(a => { 353 try { 354 let url = new URL(a.href); 355 if (url.host == current_link.host && url.pathname.includes('/menu')) { 356 a.addEventListener('click', this.handleEvent.bind(this)); 357 } 358 } catch (ex) { 359 // continue; 360 } 361 }); 362 } 363 } 364 365 handleEvent(e) { 366 e.preventDefault(); 367 this.redirect = e.currentTarget.href; 368 this.previousFocusedElement = document.activeElement; // Save the focused element before showing the modal 369 this.classList.add('active'); 370 this.focusPopup(); 371 document.addEventListener('keydown', this.handleKeyDown); // Add keydown event listener for focus trapping 372 } 373 374 handleSubmit(e) { 375 e.preventDefault(); 376 let location = this.querySelector('#location-popup'); 377 let current_link = new URL(window.location); 378 let a = document.createElement('a'); 379 try { 380 let url = new URL(this.redirect); 381 if (url.host == current_link.host && url.pathname.includes('/menu')) { 382 a.href = `${url.origin}/menu/${location.value}${url.search}`; 383 setCookie('selected_location', location.value, 168); 384 } else { 385 a.href = this.redirect; 386 } 387 } catch (ex) { 388 // continue; 389 } 390 a.click(); 391 this.handleClose(); 392 } 393 394 handleClose() { 395 this.classList.remove('active'); 396 this.redirect = null; 397 this.previousFocusedElement?.focus(); // Return focus to the previously focused element 398 document.removeEventListener('keydown', this.handleKeyDown); // Remove keydown event listener 399 } 400 401 focusPopup() { 402 // Focus on the first focusable element inside the modal after a short delay 403 setTimeout(() => { 404 console.log("run"); 405 const focusableElements = this.querySelectorAll( 406 'button, [href], input, select, textarea, [tabindex]:not
406([tabindex="-1"])' 407 ); 408 if (focusableElements.length > 0) { 409 focusableElements[0].focus(); 410 } 411 }, 300); // Delay of 10ms to ensure the element is ready for focus 412 } 413 414 handleKeyDown(e) { 415 if (e.key === 'Tab') { 416 this.trapFocus(e); 417 } else if (e.key === 'Escape') { 418 this.handleClose(); // Close the modal on Escape key press 419 } 420 } 421 422 trapFocus(e) { 423 const focusableElements = this.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'); 424 const firstElement = focusableElements[0]; 425 const lastElement = focusableElements[focusableElements.length - 1]; 426 427 if (e.shiftKey && document.activeElement === firstElement) { 428 // If Shift + Tab is pressed and focus is on the first element, move focus to the last element 429 e.preventDefault(); 430 lastElement.focus(); 431 } else if (!e.shiftKey && document.activeElement === lastElement) { 432 // If Tab is pressed and focus is on the last element, move focus to the first element 433 e.preventDefault(); 434 firstElement.focus(); 435 } 436 } 437} 438 439customElements.define('custom-popup', CustomPopup);
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.