1( function( $ ) { 2 3 "use strict"; 4 5 var mapProvider = new window.JetEngineMapsProvider(); 6 7 var JetEngineMaps = { 8 9 markersData: {}, 10 clusterersData: {}, 11 mapProvider: mapProvider, 12 13 preventPanToMarker: false, 14 15 init: function() { 16 17 var widgets = { 18 'jet-engine-maps-listing.default' : JetEngineMaps.widgetMap, 19 }; 20 21 $.each( widgets, function( widget, callback ) { 22 window.elementorFrontend?.hooks?.addAction( 'frontend/element_ready/' + widget, callback ); 23 }); 24 25 }, 26 27 initBlocks: function( $scope ) { 28 29 $scope = $scope || $( 'body' ); 30 31 window.JetPlugins.init( $scope, [ 32 { 33 block: 'jet-engine/maps-listing', 34 callback: JetEngineMaps.widgetMap 35 } 36 ] ); 37 38 }, 39 40 initBricks: function( $scope ) { 41 42 $scope = $scope || $( 'body' ); 43 44 window.JetPlugins.init( $scope, [ 45 { 46 block: 'jet-engine/bricks-maps-listing', 47 callback: JetEngineMaps.bricksWidgetMap 48 } 49 ] ); 50 51 }, 52 53 commonInit: function() { 54 // Register URL Action. 55 if ( undefined === window.JetEngine ) { 56 $( window ).on( 'jet-engine/frontend/loaded', JetEngineMaps.registerUrlAction ); 57 } else { 58 JetEngineMaps.registerUrlAction(); 59 } 60 }, 61 62 bricksWidgetMap: function( $scope ) { 63 64 if (JetEngineMaps.isBricksHiddenWrap($scope)) { 65 JetEngineMaps.initMapAfterDisplayingWidgets($scope[0]); 66 return; 67 } 68 69 JetEngineMaps.widgetMap($scope); 70 }, 71 72 widgetMap: function( $scope ) { 73 74 var $container = $scope.find( '.jet-map-listing' ), 75 mapID = $scope.data( 'id' ), 76 map, 77 init, 78 markers, 79 bounds, 80 general, 81 gmMarkers = [], 82 activeInfoWindow, 83 width, 84 offset, 85 mapSettings, 86 autoCenter, 87 customCenter, 88 markerCluster; 89 90 if ( ! $container.length || $container.attr( 'id' ) ) { 91 return; 92 } 93 94 $container.attr( 'id', 'map_' + mapID + '_' + Math.floor( Math.random() * Math.floor( 999 ) ) ); 95 96 var initMarker = function( markerData ) { 97 var marker, 98 infowindow, 99 popup, 100 popupOpenOn = undefined !== general.popupOpenOn ? general.popupOpenOn : 'click', 101 pinData = { 102 position: { lat: markerData.latLang.lat, lng: markerData.latLang.lng }, 103 map: map, 104 shadow: false, 105 }; 106 107 if ( markerData.custom_marker ) { 108 pinData.content = markerData.custom_marker; 109 } else if ( general.marker && 'image' === general.marker.type ) { 110 pinData.content = '<img src="' + general.marker.url + '" class="jet-map-marker-image" alt="" style="cursor: pointer;">'; 111 } else if ( general.marker && 'text' === general.marker.type ) { 112 pinData.content = general.marker.html.replace( '_marker_label_', markerData.label ); 113 } else if ( general.marker && 'icon' === general.marker.type ) { 114 pinData.content = general.marker.html; 115 } 116 117 pinData.markerClustering = markerData.markerClustering; 118 119 marker = mapProvider.addMarker( pinData ); 120 121 gmMarkers.push( marker ); 122 123 JetEngineMaps.addMarkerData( markerData.id, marker, mapID ); 124 125 if ( bounds && marker ) { 126 bounds.extend( mapProvider.getMarkerPosition( marker ) ); 127 } 128 129 infowindow = mapProvider.addPopup( { 130 position: { lat: markerData.latLang.lat, lng: markerData.latLang.lng }, 131 width: width, 132 offset: offset, 133 map: map, 134 } ); 135 136 mapProvider.closePopup( infowindow, function() { 137 if ( activeInfoWindow?.map ) { 138 activeInfoWindow.map.isInternalInteraction = false; 139 } 140 141 activeInfoWindow = false; 142 }, map ); 143 144 mapProvider.openPopup( marker, function( event ) { 145 // Prevent clicking on a point of interest under listing marker 146 if ( event && event.stopPropagation ) { 147 event.stopPropagation(); 148 } 149 150 if ( infowindow.contentIsSet() ) { 151 152 if ( activeInfoWindow === infowindow ) { 153 return; 154 } 155 156 if ( activeInfoWindow ) { 157 activeInfoWindow.close(); 158 } 159 160 infowindow.setMap( map ); 161 infowindow.draw(); 162 infowindow.open( map, marker ); 163 164 JetEngineMaps.initHandlers( $container.find( '.jet-map-box' ) ); 165 166 activeInfoWindow = infowindow; 167 168 setCenterByMarker( marker ); 169 170 return; 171 172 } else if ( general.popupPreloader ) { 173 174 if ( activeInfoWindow ) { 175 activeInfoWindow.close(); 176 activeInfoWindow = false;
177 } 178 179 infowindow.setMap( map ); 180 infowindow.draw(); 181 182 infowindow.setContent( '<div class="jet-map-preloader is-active"><div class="jet-map-loader"></div></div>', false ); 183 184 infowindow.open( map, marker ); 185 186 } 187 188 var querySeparator = general.querySeparator || '?'; 189 var api = general.api + 190 querySeparator + 191 'listing_id=' + general.listingID + 192 '&post_id=' + 193 markerData.id + 194 '&source=' + general.source + 195 '&geo_query_distance=' + markerData.geo_query_distance; 196 var queriedID = $container.data( 'queried-id' ); 197 198 if ( queriedID ) { 199 api += '&queried_id=' + queriedID; 200 } 201 202 if ( mapID ) { 203 api += '&element_id=' + mapID; 204 } 205 206 if ( window.JetSmartFilters?.filterGroups ) { 207 const filterGroups = window.JetSmartFilters.filterGroups; 208 209 for ( const groupName in filterGroups ) { 210 if ( ! groupName.includes( 'jet-engine-maps/' ) ) { 211 continue; 212 } 213 214 if ( filterGroups[ groupName ]?.$provider?.[0] === $container[0] ) { 215 const filtersUrl = filterGroups[ groupName ].getUrl( true ); 216 217 if ( filtersUrl ) { 218 api += '&jsf=' + filtersUrl.replace( '?jsf=', '' ); 219 } 220 221 break; 222 } 223 } 224 } 225 226 jQuery.ajax({ 227 url: api, 228 type: 'GET', 229 dataType: 'json', 230 beforeSend: function( jqXHR ) { 231 var nonce = window.JetEngineSettings ? window.JetEngineSettings.restNonce : general.restNonce; 232 jqXHR.setRequestHeader( 'X-WP-Nonce', nonce ); 233 }, 234 }).done( function( response ) { 235 236 if ( activeInfoWindow ) { 237 activeInfoWindow.close(); 238 } 239 240 infowindow.setMap( map ); 241 infowindow.draw(); 242 243 infowindow.setContent( response.html, false ); 244 245 infowindow.open( map, marker ); 246 247 JetEngineMaps.initHandlers( $container.find( '.jet-map-box' ) ); 248 249 activeInfoWindow = infowindow; 250 251 // Re-init Bricks scripts 252 JetEngineMaps.reinitBricksScripts( mapID ); 253 254 }).fail( function( error ) { 255 256 if ( activeInfoWindow ) { 257 activeInfoWindow.close(); 258 } 259 260 infowindow.setContent( error, true ); 261 infowindow.open( map, marker ); 262 263 activeInfoWindow = infowindow; 264 265 }); 266 267 setCenterByMarker( marker ); 268 269 }, infowindow, map, popupOpenOn ); 270 271 }; 272 273 var setCenterByMarker = function( marker ) { 274 275 if ( JetEngineMaps.preventPanToMarker ) { 276 return; 277 } 278 279 if ( ! general.centeringOnOpen ) { 280 return; 281 } 282 283 mapProvider.panTo( { 284 map: map, 285 position: mapProvider.getMarkerPosition( marker ), 286 zoom: general.zoomOnOpen ? +general.zoomOnOpen : false, 287 } ); 288 289 map.isInternalInteraction = false; 290 }; 291 292 var setAutoCenter = function() { 293 294 if ( ! bounds ) { 295 return; 296 } 297 298 if ( bounds.isEmpty && bounds.isEmpty() ) { 299 return; 300 } 301 302 mapProvider.setAutoCenter( { 303 map: map, 304 settings: general, 305 bounds: bounds, 306 } ); 307 308 }; 309 310 init = $container.data( 'init' ); 311 markers = $container.data( 'markers' ); 312 general = $container.data( 'general' ); 313 autoCenter = general.autoCenter; 314 315 if ( ! autoCenter ) { 316 customCenter = general.customCenter; 317 } 318 319 mapSettings = { 320 zoomControl: true, 321 fullscreenControl: true, 322 streetViewControl: true, 323 mapTypeControl: true, 324 }; 325 326 mapSettings = $.extend( {}, mapSettings, init ); 327 328 if ( ! autoCenter && customCenter ) { 329 mapSettings.center = customCenter; 330 mapSettings.zoom = general.customZoom; 331 } 332 333 if ( general.maxZoom ) { 334 mapSettings.maxZoom = general.maxZoom; 335 } 336 337 if ( general.minZoom ) { 338 mapSettings.minZoom = general.minZoom; 339 } 340 341 if ( general.styles ) { 342 mapSettings.styles = general.styles; 343 } 344 345 if ( general.advanced ) { 346 347 if ( general.advanced.zoom_control ) { 348 mapSettings.gestureHandling = general.advanced.zoom_control; 349 } else { 350 mapSettings.scrollwheel = false; 351 } 352 353 if ( undefined !== general.advanced.scrollwheel ) { 354 mapSettings.scrollwheel = general.advanced.scrollwheel; 355 } 356 357 } 358 359 map = mapProvider.initMap( $container[0], mapSettings ); 360 361 bounds = mapProvider.initBounds(); 362 width = parseInt( general.width, 10 ); 363 offset = parseInt( general.offset, 10 ); 364 365 $container.data( 'mapInstance', map ); 366 367 if ( markers ) { 368 $.each( markers, function( index, markerData ) { 369 markerData.markerClustering = general.markerClustering; 370 initMarker( markerData ); 371 }); 372 } 373 374 if ( autoCenter || ! customCenter ) { 375 setAutoCenter(); 376 } 377 378 if ( general.markerClustering ) { 379 380 markerCluster = mapProvider.getMarkerCluster( { 381 map: map, 382 markers: gmMarkers, 383 clustererImg: general.clustererImg,
384 clusterMaxZoom: general.clusterMaxZoom, 385 clusterRadius: general.clusterRadius, 386 } ); 387 388 JetEngineMaps.clusterersData[ mapID ] = markerCluster; 389 } 390 391 $scope.on( 'jet-filter-custom-content-render', function( event, response ) { 392 393 if ( activeInfoWindow ) { 394 activeInfoWindow.close(); 395 } 396 397 if ( markerCluster ) { 398 mapProvider.removeMarkers( markerCluster, gmMarkers ); 399 } 400 401 gmMarkers.forEach( function( marker ) { 402 mapProvider.removeMarker( marker ); 403 } ); 404 405 gmMarkers.splice( 0, gmMarkers.length ); 406 JetEngineMaps.restoreMarkerData(); 407 408 bounds = mapProvider.initBounds(); 409 410 if ( response.markers.length ) { 411 412 for ( var i = 0; i < response.markers.length; i++ ) { 413 let marker = response.markers[ i ]; 414 marker.markerClustering = general.markerClustering; 415 initMarker( marker ); 416 } 417 418 if ( markerCluster ) { 419 mapProvider.addMarkers( markerCluster, gmMarkers ); 420 } 421 422 } 423 424 if ( ! map.jeFiltersAutoCenterBlock && ( autoCenter || ! customCenter ) ) { 425 setAutoCenter(); 426 } 427 428 } ); 429 430 }, 431 432 addMarkerData: function( id, marker, mapID ) { 433 434 if ( ! this.markersData[id] ) { 435 this.markersData[id] = []; 436 } 437 438 this.markersData[id].push( { 439 marker: marker, 440 clustererIndex: mapID 441 } ); 442 }, 443 restoreMarkerData: function() { 444 this.markersData = {}; 445 }, 446 447 registerUrlAction: function() { 448 window.JetEngine.customUrlActions.addAction( 449 'open_map_listing_popup', 450 JetEngineMaps.openMapListingPopup 451 ); 452 }, 453 454 openMapListingPopup: function( settings ) { 455 456 if ( ! settings.id ) { 457 return; 458 } 459 460 var popupID = settings.id, 461 zoom = settings.zoom ? +settings.zoom : false; 462 463 if ( undefined === JetEngineMaps.markersData[ popupID ] ) { 464 return; 465 } 466 467 if ( zoom ) { 468 JetEngineMaps.preventPanToMarker = true; 469 } 470 471 for ( var i = 0; i < JetEngineMaps.markersData[ popupID ].length; i++ ) { 472 473 var marker = JetEngineMaps.markersData[ popupID ][i].marker, 474 map = mapProvider.getMarkerMap( marker ); 475 476 if ( !map ) { 477 // A marker inside a cluster 478 var clustererIndex = JetEngineMaps.markersData[ popupID ][i].clustererIndex, 479 markersClusterer = JetEngineMaps.clusterersData[ clustererIndex ]; 480 481 mapProvider.fitMapToMarker( marker, markersClusterer, zoom ); 482 } else { 483 // Centering the map 484 mapProvider.panTo( { 485 map: map, 486 position: mapProvider.getMarkerPosition( marker ), 487 zoom: zoom, 488 } ); 489 } 490 491 mapProvider.triggerOpenPopup( marker ); 492 493 if ( settings.scroll_to_map ) { 494 const container = mapProvider.getContainer( map ); 495 const offset = $( container ).offset(); 496 497 $( 'html, body' ).animate( { scrollTop: ( offset.top - 30 ) } ); 498 } 499 } 500 501 JetEngineMaps.preventPanToMarker = false;
502 }, 503 504 customInitMapBySelector: function( $selector ) { 505 var $mapBlock = $selector.closest( '[data-is-block="jet-engine/maps-listing"]' ), 506 $mapBricks = $selector.closest( '[data-is-block="jet-engine/bricks-maps-listing"]' ), 507 $mapElWidget = $selector.closest( '.elementor-widget-jet-engine-maps-listing' ); 508 509 if ( $mapBlock.length ) { 510 JetEngineMaps.widgetMap( $mapBlock ); 511 } 512 513 if ( $mapBricks.length ) { 514 JetEngineMaps.bricksWidgetMap( $mapBricks ); 515 } 516 517 if ( $mapElWidget.length ) { 518 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $mapElWidget, $ ); 519 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $mapElWidget, $ ); 520 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + $mapElWidget.data( 'widget_type' ), $mapElWidget, $ ); 521 } 522 }, 523 524 initHandlers: function( $selector ) { 525 526 // Actual init 527 window.JetPlugins.init( $selector ); 528 529 // Legacy Elementor-only init 530 // 531 // added check for window.elementorFrontend.hooks to prevent JS error if Elementor Listing Item is used in Block editor Map Listing 532 // https://github.com/Crocoblock/issues-tracker/issues/13998 533 if ( window?.elementorFrontend?.hooks ) { 534 $selector.find( '[data-element_type]' ).each( function() { 535 var $this = $( this ), 536 elementType = $this.data( 'element_type' ); 537 538 if ( !elementType ) { 539 return; 540 } 541 542 if ( 'widget' === elementType ) { 543 elementType = $this.data( 'widget_type' ); 544 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 545 } 546 547 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 548 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 549 550 } ); 551 } 552 553 if ( window.JetPopupFrontend && window.JetPopupFrontend.initAttachedPopups ) { 554 window.JetPopupFrontend.initAttachedPopups( $selector ); 555 } 556 557 // Reinit the common events for a map popup. 558 // Only for Google provider as event propagation is disabled. 559 if ( window.JetEngine && mapProvider.getId && 'google' === mapProvider.getId() ) { 560 JetEngine.commonEvents( $selector ); 561 } 562 563 }, 564 565 // Restart the map when it is displayed 566 initMapAfterDisplayingWidgets: function( node ) { 567 const observer = new IntersectionObserver((entries, observer) => { 568 entries.forEach(entry => { 569 if (entry.isIntersecting) { 570 observer.unobserve(entry.target); 571 572 JetEngineMaps.widgetMap($(entry.target)); 573 } 574 }); 575 }); 576 577 observer.observe(node); 578 }, 579 580 // Check the Bricks parent node. Is it hidden or not? 581 // The problem was the accordion and tabs 582 isBricksHiddenWrap: function( $scope ) { 583 const generalWrapper = $scope[0].closest('.brxe-accordion-nested, .brxe-tabs-nested'); 584 const wrapHidden = $scope[0].closest('.listening, .tab-pane'); 585 586 if (generalWrapper && wrapHidden && !wrapHidden.classList.contains('brx-open')) { 587 return true; 588 } 589 590 return false; 591 }, 592 593 //map - map instance
594 //bounds - an object containing 'south', 'west', 'north', 'east' coordinates 595 dispatchMapSyncEvent: function( map, bounds ) { 596 597 const mapDiv = mapProvider.getContainer( map ); 598 //debounce event dispatch to prevent unnecessary filter requests on zoom/pan change 599 clearTimeout( mapDiv?.JetEngineMapDebounceTimer ); 600 601 let debounceTime = + ( JetEngineSettings?.mapSyncFilter?.debounceTime ?? 500 ); 602 603 if ( ! isFinite( debounceTime ) ) { 604 debounceTime = 1000; 605 } 606 607 mapDiv.JetEngineMapDebounceTimer = setTimeout( 608 JetEngineMaps.dispatchMapSyncEventImmediate, 609 debounceTime, 610 mapDiv, 611 bounds, 612 map 613 ); 614 }, 615 616 dispatchMapSyncEventImmediate: function( mapDiv, bounds, map ) { 617 if ( map.isInternalInteraction ) { 618 map.isInternalInteraction = false; 619 return; 620 } 621 622 const event = new CustomEvent( 623 "jet-engine/maps/update-sync-bounds", 624 { 625 detail: { 626 div: mapDiv, 627 bounds: bounds, 628 map: map, 629 mapProvider 630 }, 631 } 632 ); 633 634 document.dispatchEvent( event ); 635 }, 636 637 dispatchMapSyncInitEvent: function( map ) { 638 const event = new CustomEvent( 639 "jet-engine/maps/init-sync-bounds", 640 { 641 detail: { 642 map: map, 643 div: mapProvider.getContainer( map ), 644 mapProvider 645 }, 646 } 647 ); 648 649 document.dispatchEvent( event ); 650 }, 651 652 reinitBricksScripts: function (elementId) { 653 if (!window.bricksIsFrontend) { 654 return; 655 } 656 657 document.dispatchEvent( 658 new CustomEvent("bricks/ajax/query_result/displayed", { 659 detail: { 660 queryId: elementId || null 661 } 662 }) 663 ); 664 } 665 }; 666 667 $( window ).on( 'elementor/frontend/init', JetEngineMaps.init ); 668 669 window.addEventListener( 'DOMContentLoaded', function() { 670 JetEngineMaps.initBlocks(); 671 JetEngineMaps.initBricks(); 672 } ); 673 674 window.jetEngineMapsBricks = function() { 675 JetEngineMaps.initBricks(); 676 } 677 678 window.JetEngineMaps = JetEngineMaps; 679 680 JetEngineMaps.commonInit(); 681 682 $( window ).trigger( 'jet-engine/frontend-maps/loaded' ); 683 684}( jQuery ) );
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.