1/** 2 * 2015-2024 Chronopost SAS 3 * 4 * NOTICE OF LICENSE 5 * 6 * This source file is subject to the Academic Free License 3.0 (AFL-3.0) 7 * that is bundled with this package in the file LICENSE.txt. 8 * It is also available through the world-wide-web at this URL: 9 * https://opensource.org/licenses/AFL-3.0 10 * If you did not receive a copy of the license and are unable to 11 * obtain it through the world-wide-web, please send an email 12 * to [email protected] so we can send you a copy immediately. 13 * 14 * @author Chronopost SAS <[email protected]> 15 * @copyright 2015-2024 Chronopost SAS 16 * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) 17 */ 18 19/* Check if jquery exist */ 20window.onload = function () { 21 if (!window.jQuery) { 22 (function () { 23 const script = document.createElement("script"); 24 script.src = '/modules/chronopost/views/js/jquery-1.11.0.min.js'; 25 script.type = 'text/javascript'; 26 document.head.appendChild(script); 27 })(); 28 } 29} 30 31var marker_group = null; 32var defaultPostCode = "75001"; 33var initRelaisMapTimeout = null; 34var userJustSelectedRelayPoint = false; 35var postcodeInputTimeout = null; 36var userIsEditingPostcode = false; 37var userIsInteractingWithMap = false; 38var lastMapInteractionTime = 0; 39 40function isDeliveryStepActive() { 41 var $deliveryStep = $("#checkout-delivery-step"); 42 if ($deliveryStep.length) { 43 // Support both PS 9.1/Hummingbird (step--current) and Classic theme (-current) 44 var hasCurrentClass = $deliveryStep.hasClass("-current") || $deliveryStep.hasClass("step--current"); 45 var hasJsClass = $deliveryStep.hasClass("js-current-step"); 46 return hasCurrentClass && hasJsClass; 47 } 48 49 // Fallback for one-page checkout or legacy flows without step markers 50 return $('body').hasClass('order-opc'); 51} 52 53function capitalize(string) { 54 return string.charAt(0).toUpperCase() + string.slice(1); 55} 56 57/** 58 * Submit postCode change and rebuild markers 59 */ 60function postcodeChangeEvent() { 61 initRelaisMap(null, $('#relais_postcode').val(), null, cust_country); 62} 63 64/** 65 * Toogle map when "Relais" carrier is selected 66 * 67 * @param address 68 * @param codePostal 69 * @param city 70 * @param e 71 * @returns {boolean} 72 */ 73function toggleRelaisMap(address, codePostal, city, e) { 74 var valueChecked = $("#js-delivery .form-check > input[type=radio]:checked, #js-delivery .custom-radio > input[type=radio]:checked").val(); 75 if (valueChecked !== undefined) { 76 valueChecked = valueChecked.replace(/,$/, ''); 77 } 78 79 var carrierChecked = $("input[name^='delivery_option']:checked, input[name=id_carrier]:checked").val(); 80 if (carrierChecked !== undefined) { 81 carrierChecked = carrierChecked.replace(/,$/, ''); 82 } 83 84 var postCodeControls = $('#chrono_postcode_controls'); 85 var chronorelaisContainer = $('#chronorelais_container'); 86 87 if (valueChecked === CHRONORELAIS_AMBIENT_ID || carrierChecked === CHRONORELAIS_AMBIENT_ID_INT || 88 valueChecked === CHRONORELAIS_ID || carrierChecked === CHRONORELAIS_ID_INT || 89 valueChecked === RELAISEUROPE_ID || carrierChecked === RELAISEUROPE_ID_INT || 90 valueChecked === RELAISDOM_ID || carrierChecked === RELAISDOM_ID_INT || 91 valueChecked === TOSHOPDIRECT_ID || carrierChecked === TOSHOPDIRECT_ID_INT || 92 valueChecked === TOSHOPDIRECT_EUROPE_ID || carrierChecked === TOSHOPDIRECT_EUROPE_ID_INT) { 93 if (typeof e !== "undefined") { 94 e.stopPropagation(); 95 } 96 97 // Show Chronorelais controls 98 chronorelaisContainer.show(); 99 postCodeControls.show(); 100 101 initRelaisMap(address, codePostal, city, cust_country); 102 103 // Force Leaflet to recalculate map size after container becomes visible 104 if (relais_map !== null && typeof relais_map.invalidateSize === 'function') { 105 setTimeout(function() { 106 relais_map.invalidateSize(); 107 }, 200); 108 } 109 110 return false; 111 } 112 113 // Hide Chronorelais controls 114 chronorelaisContainer.hide(); 115 postCodeControls.hide(); 116} 117 118/** 119 * Initialize layers and build markers 120 * 121 * @param address 122 * @param codePostal 123 * @param city 124 * @param country 125 */ 126function initRelaisMap(address, codePostal, city, country) { 127 if (typeof codePostal === 'undefined') { 128 return; 129 } 130 131 // Skip if user just manually selected a relay point 132 if (userJustSelectedRelayPoint) { 133 console.log('[Chronopost] initRelaisMap - skipping, user just selected point'); 134 return; 135 } 136 137 if (userIsEditingPostcode) { 138 return; 139 } 140 141 if (userIsInteractingWithMap) { 142 return; 143 } 144 145 var timeSinceLastInteraction = Date.now() - lastMapInteractionTime; 146 if (lastMapInteractionTime > 0 && timeSinceLastInteraction < 2000) { 147 return; 148 } 149 150 // Get Leaflet map. 151 if (relais_map === null) { 152 relais_map = mapInit(); 153 154 if (relais_map === null) { 155 return; 156 } 157 158 // Initialize imagery 159 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 160 attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' 161 }).addTo(relais_map); 162 163 // Add markers layer 164 marker_group = L.featureGroup(); 165 marker_group.addTo(relais_map); 166 167 relais_map.on('dragstart zoomstart click mousedown', function() { 168 userIsInteractingWithMap = true; 169 lastMapInteractionTime = Date.now(); 170 }); 171 172 relais_map.on('dragend zoomend moveend', function() { 173 lastMapInteractionTime = Date.now(); 174 setTimeout(function() { 175 userIsInteractingWithMap = false;
176 }, 1000); 177 }); 178 179 relais_map.on('click', function() { 180 lastMapInteractionTime = Date.now(); 181 setTimeout(function() { 182 userIsInteractingWithMap = false; 183 }, 1000); 184 }); 185 186 relais_map.on('popupopen', function() { 187 userIsInteractingWithMap = true; 188 lastMapInteractionTime = Date.now(); 189 }); 190 191 relais_map.on('popupclose', function() { 192 lastMapInteractionTime = Date.now(); 193 setTimeout(function() { 194 userIsInteractingWithMap = false; 195 }, 1000); 196 }); 197 } else { 198 // Clean old markers 199 marker_group.clearLayers(); 200 } 201 202 // Build all markers 203 initRelaisMarkers(address, codePostal, city, country); 204} 205 206/** 207 * Initialize Leaflet map 208 * 209 * @returns {*} 210 */ 211function mapInit() { 212 if ($('#chronorelais_map').length === 0) { 213 return null; 214 } 215 216 return L.map('chronorelais_map').setView([0, 0], 12); 217} 218 219/** 220 * Save customer "relais" 221 * 222 * @param relaisID 223 */ 224function associateRelais(relaisID) { 225 if (isDeliveryStepActive()) { 226 chrAjaxRequest({ 227 'action': 'storePointRelais', 228 'relaisID': relaisID, 229 'cartID': cartID, 230 'customerFirstname': encodeURIComponent(cust_firstname), 231 'customerLastname': encodeURIComponent(cust_lastname), 232 }, 'GET') 233 .catch((error) => { 234 console.log(error); 235 }); 236 } 237} 238 239/** 240 * Create all "relais" list 241 * 242 * @param json 243 */ 244function createAllPointRelais(json) { 245 var htmlForTxtSection = ''; 246 var data; 247 248 try { 249 data = JSON.parse(json); 250 } catch (e) { 251 console.error('[Chronopost] Invalid JSON response:', json); 252 console.error('[Chronopost] Parse error:', e); 253 alert('Erreur: la réponse du serveur n\'est pas valide. Vérifiez la console pour plus de détails.'); 254 return; 255 } 256 257 if (data.errorCode !== 0) { 258 alert('Code postal erroné, merci de modifier le code postal dans votre adresse de livraison.'); 259 260 // init with original zipcode 261 cust_address = defaultPostCode + ", France"; 262 $('#relais_postcode').val(defaultPostCode); 263 initRelaisMap(cust_address, defaultPostCode); 264 265 return; 266 } 267 268 if (data.hasOwnProperty("listePointRelais") && data.listePointRelais) { 269 var listePointsRelais = data.listePointRelais; 270 271 let associateRelaisId = listePointsRelais[0].identifiant; 272 if (listePointsRelais.length !== undefined) { 273 for (var i = 0; i < listePointsRelais.length; i++) { 274 // COMPAT WITH OLD RECHERCHEBT 275 var id = listePointsRelais[i].identifiant; 276 var nom = listePointsRelais[i].nom; 277 var adresse = listePointsRelais[i].adresse1; 278 var postalCode = listePointsRelais[i].codePostal; 279 var localite = listePointsRelais[i].localite; 280 281 // Create marker 282 createRelaisMarker(listePointsRelais[i]); 283 chronodata[id] = listePointsRelais[i]; 284 285 // Build corresponding "relais" input 286 htmlForTxtSection += '<div class="checkbox"><label><input type="radio" name="chronorelaisSelect" id="bt' + id + '" value="' + id + '"'; 287 if (i === 0 && data['lastPR'] === '' || data['lastPR'] === id) { 288 htmlForTxtSection += " checked"; 289 associateRelaisId = id; 290 } 291 htmlForTxtSection += '/> ' + nom + ' - ' + adresse + ' - ' + postalCode + ' ' + localite + '</label></div>'; 292 } 293 associateRelais(associateRelaisId); 294 } else { 295 // COMPAT WITH OLD RECHERCHEBT 296 var id = listePointsRelais.identifiant; 297 var nom = listePointsRelais.nom; 298 var adresse = listePointsRelais.adresse1; 299 var postalCode = listePointsRelais.codePostal; 300 var localite = listePointsRelais.localite; 301 302 // Create marker 303 createRelaisMarker(listePointsRelais); 304 chronodata[id] = listePointsRelais; 305 306 // Build corresponding "relais" input 307 htmlForTxtSection += '<div class="checkbox"><label><input type="radio" name="chronorelaisSelect" id="bt' + id + '" value="' + id + '"'; 308 htmlForTxtSection += " checked"; 309 htmlForTxtSection += '/> ' + nom + ' - ' + adresse + ' - ' + postalCode + ' ' + localite + '</label></div>'; 310 associateRelais(listePointsRelais.identifiant); 311 } 312 313 // Add all relais to list 314 $('#relais_txt').html(htmlForTxtSection); 315 316 // Listener for BT select in radio list 317 $('body').on('change', 'input[name="chronorelaisSelect"]', function () { 318 var relaisId = $('input[name="chronorelaisSelect"]:checked').val(); 319 320 // Flag that user just made a selection (prevent immediate reload) 321 userJustSelectedRelayPoint = true; 322 userIsInteractingWithMap = true; 323 lastMapInteractionTime = Date.now(); 324 325 setTimeout(function() { 326 userJustSelectedRelayPoint = false;
327 userIsInteractingWithMap = false; 328 }, 1000); 329 330 associateRelais(relaisId); 331 openMarker(relaisId); 332 }); 333 334 // Open closest marker 335 openMarker($('input[name="chronorelaisSelect"]:checked').val()); 336 337 // Fit map to markers with tighter zoom 338 var bounds = marker_group.getBounds(); 339 if (bounds.isValid()) { 340 relais_map.fitBounds(bounds, { 341 paddingTopLeft: [50, 50], 342 paddingBottomRight: [50, 50], 343 maxZoom: 14 // Limit zoom to avoid being too close 344 }); 345 } 346 } 347} 348 349/** 350 * Open marker corresponding to given "relais" ID 351 * 352 * @param relaisId 353 */ 354function openMarker(relaisId) { 355 if (typeof relaisId === 'undefined') { 356 return; 357 } 358 359 var marker = map_markers && map_markers[relaisId]; 360 if (!marker || typeof marker.openPopup !== 'function') { 361 return; 362 } 363 364 // Ensure popup opens after any DOM/radio updates finish 365 setTimeout(function() { 366 marker.openPopup(); 367 if (relais_map && typeof marker.getLatLng === 'function' && typeof relais_map.getBounds === 'function') { 368 var markerPosition = marker.getLatLng(); 369 var mapBounds = relais_map.getBounds(); 370 371 if (mapBounds && !mapBounds.contains(markerPosition)) { 372 relais_map.panTo(markerPosition); 373 } 374 } 375 }, 50); 376} 377 378/** 379 * Initialize all markers 380 * 381 * @param address 382 * @param cp 383 * @param city 384 * @param country 385 */ 386function initRelaisMarkers(address, cp, city, country) {
387 let currentCarrier = $('.delivery-options input:checked').val(); 388 389 function handleRelayPointsResponse(response) { 390 let data; 391 try { 392 data = JSON.parse(response); 393 } catch (e) { 394 console.error('[Chronopost] Invalid JSON response:', response); 395 createAllPointRelais(response); 396 return; 397 } 398 399 let hasNoResults = !data.listePointRelais || 400 data.listePointRelais === null || 401 (Array.isArray(data.listePointRelais) && data.listePointRelais.length === 0); 402 403 if (hasNoResults && city !== null && city !== 'unknown') { 404 chrAjaxRequest({ 405 'action': 'getPointRelais2', 406 'city': 'unknown', 407 'codePostal': cp, 408 'country': country, 409 'carrier': currentCarrier, 410 'cartID': cartID, 411 }, 'GET') 412 .then(createAllPointRelais) 413 .catch((error) => { 414 console.error('[Chronopost] Error loading relay points (retry):', error); 415 }); 416 } else { 417 createAllPointRelais(response); 418 } 419 } 420 421 if (city === null) { 422 chrAjaxRequest({ 423 'action': 'getPointRelais2', 424 'city': 'unknown', 425 'codePostal': cp, 426 'country': country, 427 'carrier': currentCarrier, 428 'cartID': cartID, 429 }, 'GET') 430 .then(createAllPointRelais) 431 .catch((error) => { 432 console.error('[Chronopost] Error loading relay points:', error); 433 }); 434 } else { 435 chrAjaxRequest({ 436 'action': 'getPointRelais2', 437 'codePostal': cp, 438 'address': encodeURIComponent(address), 439 'country': country, 440 'city': city, 441 'carrier': currentCarrier, 442 'cartID': cartID, 443 }, 'GET') 444 .then(handleRelayPointsResponse) 445 .catch((error) => { 446 console.error('[Chronopost] Error loading relay points:', error); 447 }); 448 } 449} 450 451/** 452 * Create Leaflet Marker for given "relais" 453 * 454 * @param relais 455 */ 456function createRelaisMarker(relais) { 457 var relaisIcon = L.icon({ 458 iconUrl: path + '/views/img/postal.png', 459 iconSize: [45, 30] 460 }); 461 462 var marker = L.marker([relais.coordGeolocalisationLatitude, relais.coordGeolocalisationLongitude], {icon: relaisIcon}); 463 464 marker.on('click', function (e) { 465 userIsInteractingWithMap = true; 466 lastMapInteractionTime = Date.now(); 467 setTimeout(function() { 468 userIsInteractingWithMap = false; 469 }, 1000); 470 471 $("#bt" + relais.identifiant).click(); 472 }); 473 474 map_markers[relais.identifiant] = marker; 475 marker.addTo(marker_group).bindPopup(buildMarkerPopup(relais)); 476} 477 478/** 479 * Build HTML Marker popup for given "relais" 480 * 481 * @param relais 482 * @returns {string} 483 */ 484function buildMarkerPopup(relais) { 485 var popup = '<div class="pointRelais"><h4>' 486 + relais.nom + '</h4><p>' + relais.adresse1 + '<br/ >' + relais.codePostal 487 + ' ' + relais.localite + '</p><h5>' + trad_horaire_ouverture + '</h5><table><tbody>'; 488 489 if (typeof relais.listeHoraireOuverture !== 'undefined' && relais.listeHoraireOuverture !== null) { 490 for (var i = 0; i < relais.listeHoraireOuverture.length; i++) { 491 var day = relais.listeHoraireOuverture[i]; 492 if (day.horairesAsString !== null) { 493 popup += '<tr class="first_item item"><td>' + capitalize(days[day.jour - 1]) + '</td><td>' 494 + day.horairesAsString + '</td></tr>'; 495 } 496 } 497 } 498 499 popup += '</tbody></table>' 500 + '<p class="text-right"><input type="hidden" name="btID" value="' + relais.identifiant 501 + '"/><a class="button_large btselect" href="javascript:;" class="pull-right">' + trad_selectionner + ' »</a></p>' 502 + '</div>'; 503 504 return popup; 505} 506 507// Triggered on BT select from popup 508function btSelect() { 509 // Prevent map reload when selecting from popup 510 userIsInteractingWithMap = true; 511 lastMapInteractionTime = Date.now(); 512 setTimeout(function() { 513 userIsInteractingWithMap = false;
514 }, 1000); 515 516 var btID = $(this).parent().children('input').val(); 517 var mObj = $('#relais_txt input[value=' + btID + ']'); 518 mObj.click(); 519 520 associateRelais(btID); 521 522 $("html, body").animate({scrollTop: $('#relais_txt').offset().top}, 500); 523 $("#" + btID).prop('checked', true); 524} 525 526function cleanContainers() { 527 var dummyContainer = $('#chronorelais_dummy_container'); 528 529 // move in DOM to prevent compatibility issues with Common Services' modules 530 if ($("#chronorelais_container").length > 0) { 531 dummyContainer.remove(); 532 } else { 533 dummyContainer.attr('id', 'chronorelais_container'); 534 } 535 536 let checkedDeliveryOption = $("input[name*='delivery_option[']:checked"); 537 if (checkedDeliveryOption.length === 0 || typeof checkedDeliveryOption === 'undefined') { 538 return; 539 } 540 541 let carrierVal = checkedDeliveryOption.val(); 542 let checkedCarrier = carrierVal.indexOf(',') !== -1 ? carrierVal.substring(0, carrierVal.indexOf(',')) : carrierVal; 543 if (checkedCarrier === CHRONORELAIS_AMBIENT_ID || checkedCarrier === CHRONORELAIS_ID || checkedCarrier === RELAISEUROPE_ID || 544 checkedCarrier === RELAISDOM_ID || checkedCarrier === TOSHOPDIRECT_ID || checkedCarrier === TOSHOPDIRECT_EUROPE_ID) { 545 let deliveryOptionItem = checkedDeliveryOption.closest('.delivery-option__item.js-delivery-option'); 546 547 if (deliveryOptionItem.length === 0) { 548 deliveryOptionItem = checkedDeliveryOption.closest('.delivery-option'); 549 } 550 551 if (deliveryOptionItem.length > 0) { 552 $('#chronorelais_container').detach().appendTo(deliveryOptionItem); 553 } else { 554 // Fallback ultime: avant la section commentaire (.order-options) 555 let orderOptions = $('#js-delivery .order-options'); 556 if (orderOptions.length > 0) { 557 $('#chronorelais_container').detach().insertBefore(orderOptions); 558 } else { 559 let container = $("[id^=delivery_option]:checked").parents('.delivery-option').children('label'); 560 if (container.length === 0) { 561 container = $('#extra_carrier'); 562 } 563 $('#chronorelais_container').detach().insertAfter(container); 564 } 565 } 566 } 567} 568 569$(function () { 570 // Return if variable are undefined 571 if (typeof CHRONORELAIS_AMBIENT_ID === 'undefined' && typeof CHRONORELAIS_ID === 'undefined' && 572 typeof RELAISEUROPE_ID === 'undefined' && typeof RELAISDOM_ID === 'undefined' && 573 typeof TOSHOPDIRECT_ID === 'undefined' && typeof TOSHOPDIRECT_EUROPE_ID === 'undefined') { 574 return false; 575 } 576 577 var body = $("body"); 578 579 body.on("click", ".gm-style img", function (event) { 580 event.preventDefault(); 581 582 var deliveryStep = $("#checkout-delivery-step"); 583 if (!deliveryStep.hasClass("-current")) { 584 deliveryStep.addClass("-current"); 585 } 586 587 if (!deliveryStep.hasClass("js-current-step")) { 588 deliveryStep.addClass("js-current-step"); 589 } 590 }); 591 592 // Function to initialize relay map if on delivery step 593 let $deliveryStep = $("#checkout-delivery-step"); 594 function initializeRelayMapIfOnDeliveryStep() { 595 if (userIsEditingPostcode) { 596 return; 597 } 598 599 if (userIsInteractingWithMap) { 600 return; 601 } 602 603 var timeSinceLastInteraction = Date.now() - lastMapInteractionTime; 604 if (lastMapInteractionTime > 0 && timeSinceLastInteraction < 2000) { 605 return; 606 } 607 608 if (isDeliveryStepActive()) { 609 cleanContainers(); 610 toggleRelaisMap(cust_address_clean, cust_codePostal, cust_city); 611 } 612 } 613 614 // Debounced version to prevent multiple rapid calls 615 function debouncedInitializeRelayMap() { 616 // Clear any pending timeout 617 if (initRelaisMapTimeout) { 618 clearTimeout(initRelaisMapTimeout); 619 } 620 // Set new timeout - will only execute after 150ms of no new calls 621 initRelaisMapTimeout = setTimeout(function() { 622 initializeRelayMapIfOnDeliveryStep(); 623 initRelaisMapTimeout = null; 624 }, 150); 625 } 626 627 // Initialize on page load 628 initializeRelayMapIfOnDeliveryStep(); 629 630 // Listen to PrestaShop's checkout step change event (triggered by AJAX updates)
631 let currentCheckoutStep = $('.checkout-step.-current.js-current-step, .checkout-step.step--current.js-current-step'); 632 prestashop.on('changedCheckoutStep', function(event) { 633 let checkoutStep = $('.checkout-step.-current.js-current-step, .checkout-step.step--current.js-current-step'); 634 635 if (!checkoutStep.is(currentCheckoutStep) && isDeliveryStepActive()) { 636 debouncedInitializeRelayMap(); 637 } 638 639 currentCheckoutStep = checkoutStep; 640 }); 641 642 prestashop.on('updatedDeliveryForm', function(event) { 643 if (isDeliveryStepActive()) { 644 // Give PrestaShop time to finish rendering the form 645 setTimeout(function() { 646 debouncedInitializeRelayMap(); 647 }, 100); 648 } 649 }); 650 651 // Clean container on load 652 //cleanContainers(); 653 //toggleRelaisMap(cust_address_clean, cust_codePostal, cust_city); 654 655 // Listener for selection of the ChronoRelais carrier radio button 656 body.on('click', '#js-delivery .form-check > input[type=radio], #js-delivery .custom-radio > input[type=radio], input[name^="delivery_option"], input[name=id_carrier]', function (e) { 657 cleanContainers(); 658 toggleRelaisMap(cust_address_clean, cust_codePostal, cust_city, e); 659 660 var value = parseInt($(this).val()); 661 if (value === parseInt(CHRONORELAIS_AMBIENT_ID) || value === parseInt(CHRONORELAIS_ID) || 662 value === parseInt(RELAISEUROPE_ID) || value === parseInt(RELAISDOM_ID) || 663 value === parseInt(TOSHOPDIRECT_ID) || value === parseInt(TOSHOPDIRECT_EUROPE_ID)) { 664 if ($('#chronorelais_container').length) { 665 $('html, body').animate({ 666 scrollTop: $('#chronorelais_container').offset().top 667 }, 500); 668 } 669 } 670 }); 671 672 body.on('mousedown', '#relais_postcode', function (e) { 673 userIsEditingPostcode = true; 674 }); 675 676 body.on('focus', '#relais_postcode', function (e) { 677 userIsEditingPostcode = true; 678 }); 679 680 body.on('blur', '#relais_postcode', function (e) { 681 if (!postcodeInputTimeout) { 682 userIsEditingPostcode = false; 683 } 684 }); 685 686 body.on('click', '#change_postcode', function(e) { 687 e.preventDefault(); 688 e.stopPropagation(); 689 690 if (postcodeInputTimeout) { 691 clearTimeout(postcodeInputTimeout); 692 postcodeInputTimeout = null; 693 } 694 695 userIsEditingPostcode = false; 696 postcodeChangeEvent(); 697 }); 698 699 body.on('input', '#relais_postcode', function (e) { 700 userIsEditingPostcode = true; 701 702 if (postcodeInputTimeout) { 703 clearTimeout(postcodeInputTimeout); 704 } 705 706 var inputValue = $(this).val(); 707 708 if (inputValue.length >= 3) { 709 postcodeInputTimeout = setTimeout(function() { 710 userIsEditingPostcode = false; 711 postcodeChangeEvent(); 712 postcodeInputTimeout = null; 713 }, 800); 714 } 715 }); 716 717 body.on('keydown', '#relais_postcode', function (e) { 718 if (e.which === 13) { 719 e.preventDefault(); 720 e.stopPropagation(); 721 722 if (postcodeInputTimeout) { 723 clearTimeout(postcodeInputTimeout); 724 postcodeInputTimeout = null; 725 } 726 727 userIsEditingPostcode = false; 728 postcodeChangeEvent(); 729 return false; 730 } 731 }); 732 733 body.on('mousedown click', '.leaflet-popup, .leaflet-popup-content-wrapper, .leaflet-popup-content', function(e) { 734 userIsInteractingWithMap = true; 735 lastMapInteractionTime = Date.now(); 736 console.log('[Chronopost] User clicked on popup element'); 737 setTimeout(function() { 738 userIsInteractingWithMap = false; 739 }, 1000); 740 }); 741 742 body.on('mousedown touchstart', '#chronorelais_map', function(e) { 743 userIsInteractingWithMap = true; 744 lastMapInteractionTime = Date.now(); 745 console.log('[Chronopost] User interacting with map container'); 746 }); 747 748 body.on('mouseup touchend', '#chronorelais_map', function(e) { 749 lastMapInteractionTime = Date.now(); 750 setTimeout(function() { 751 userIsInteractingWithMap = false;
752 console.log('[Chronopost] User finished interacting with map container'); 753 }, 1000); 754 }); 755 756 // Listener for BT select in popup 757 body.on("click", ".btselect", function (e) { 758 btSelect.call(e.target, e); 759 }); 760 761 // Listener for cart navigation to next step 762 body.on('click', 'input[name=processCarrier]', function () { 763 if ($('input[name=id_carrier]:checked').val() == carrierID && !$("input[name=chronorelaisSelect]:checked").val()) { 764 alert($("#errormessage").val()); 765 $("html, body").animate({scrollTop: $('#relais_txt_cont').offset().top}, 500); 766 return false; 767 } 768 }); 769});
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.