1( function( $ ) { 2 3 "use strict"; 4 5 var JetEngineRegisteredStores = window.JetEngineRegisteredStores || {}; 6 var JetEngineStores = window.JetEngineStores || {}; 7 8 var JetEngine = { 9 10 currentMonth: null, 11 currentRequest: {}, 12 activeCalendarDay: null, 13 lazyLoading: false, 14 addedScripts: [], 15 addedStyles: [], 16 addedPostCSS: [], 17 assetsPromises: [], 18 19 initDone: false, 20 21 commonInit: function() { 22 23 JetEngine.commonEvents(); 24 25 $( window ).on( 'jet-popup/render-content/ajax/success', JetEngine.initStores ); 26 27 window.JetPlugins.hooks.addFilter( 28 'jet-popup.show-popup.data', 29 'JetEngine.popupData', 30 ( popupData, $popup, $triggeredBy ) => { 31 32 if ( ! $triggeredBy ) { 33 return popupData; 34 } 35 36 if ( $triggeredBy.data( 'popupIsJetEngine' ) ) { 37 popupData = JetEngine.prepareJetPopup( popupData, { 'is-jet-engine': true }, $triggeredBy ); 38 } 39 40 return popupData; 41 } 42 ); 43 44 JetEngine.initStores(); 45 JetEngine.customUrlActions.init(); 46 47 }, 48 49 commonEvents: function( $scope ) { 50 $scope = $scope || $( document ); 51 52 $scope 53 .on( 'jet-filter-content-rendered', JetEngine.calendarCache.clear ) 54 .on( 'change.JetEngine', '.jet-calendar-caption__date-select', JetEngine.selectCalendarMonth ) 55 .on( 'click.JetEngine', '.jet-calendar-nav__link', JetEngine.switchCalendarMonth ) 56 .on( 'click.JetEngine', '.jet-calendar-week__day-mobile-overlay', JetEngine.showCalendarEvent ) 57 .on( 'click.JetEngine', '.jet-listing-dynamic-link__link[data-delete-link="1"]', JetEngine.showConfirmDeleteDialog ) 58 .on( 'jet-filter-content-rendered', JetEngine.maybeReinitSlider ) 59 .on( 'click.JetEngine', '.jet-add-to-store', JetEngine.addToStore ) 60 .on( 'click.JetEngine', '.jet-remove-from-store', JetEngine.removeFromStore ) 61 .on( 'click.JetEngine', '.jet-engine-listing-overlay-wrap:not([data-url*="event=hover"])', JetEngine.handleListingItemClick ) 62 .on( 'jet-filter-content-rendered', JetEngine.filtersCompatibility ) 63 .on( 'click.JetEngine', '.jet-container[data-url]', JetEngine.handleContainerURL ) 64 .on( 'change.JetEngine', '.jet-listing-dynamic-link .qty', JetEngine.handleProductQuantityChange ); 65 }, 66 67 handleProductQuantityChange: function ( event ) { 68 event.preventDefault(); 69 event.stopPropagation(); 70 71 const $this = $( this ); 72 73 $this.closest( ".jet-listing-dynamic-link" ).find( ".jet-woo-add-to-cart" ).data( "quantity", $this.val() ).attr( "data-quantity", $this.val() ); 74 }, 75 76 handleContainerURL: function() { 77 var $this = $( this ), 78 url = $this.data( 'url' ), 79 target = $this.data( 'target' ); 80 81 if ( ! target ) { 82 window.location = url; 83 } else { 84 window.open( url, '_blank' ).focus(); 85 } 86 87 }, 88 89 filtersCompatibility: function( event, $provider, filtersInstance, providerType ) { 90 91 if ( 'jet-engine' !== providerType ) { 92 return; 93 } 94 95 /* 96 No need anymore to manually re-init the block. 97 JetSmartFilters automatically re-init blocks. 98 99 var $blocksListing = $provider.closest( '.jet-listing-grid--blocks' ); 100 101 if ( $blocksListing.length ) { 102 JetEngine.widgetListingGrid( $blocksListing ); 103 } 104 */ 105 106 if ( window.JetPopupFrontend && window.JetPopupFrontend.initAttachedPopups ) { 107 window.JetPopupFrontend.initAttachedPopups( $provider ); 108 } 109 }, 110 111 init: function() { 112 113 var widgets = { 114 'jet-listing-dynamic-field.default' : JetEngine.widgetDynamicField, 115 'jet-listing-grid.default': JetEngine.widgetListingGrid, 116 }; 117 118 $.each( widgets, function( widget, callback ) { 119 window.elementorFrontend.hooks.addAction( 'frontend/element_ready/' + widget, callback ); 120 }); 121 122 // Re-init sliders in nested tabs 123 window.elementorFrontend.elements.$window.on( 124 'elementor/nested-tabs/activate', 125 ( event, content ) => { 126 const $content = $( content ); 127 128 setTimeout( () => { 129 JetEngine.maybeReinitSlider( event, $content ); 130 JetEngine.widgetDynamicField( $content ); 131 } ); 132 } 133 ); 134 135 window.elementorFrontend.hooks.addFilter( 136 'jet-popup/widget-extensions/popup-data', 137 JetEngine.prepareJetPopup 138 ); 139 140 window.JetPlugins.hooks.addFilter( 141 'jet-popup.show-popup.data', 142 'JetEngine.popupData', 143 ( popupData, $popup, $triggeredBy ) => { 144 145 if ( ! $triggeredBy ) { 146 return popupData; 147 } 148 149 if ( $triggeredBy.data( 'popupIsJetEngine' ) ) { 150 popupData = JetEngine.prepareJetPopup( popupData, { 'is-jet-engine': true }, $triggeredBy ); 151 } 152 153 return popupData; 154 } 155 ); 156 157 JetEngine.updateAddedStyles(); 158 }, 159 160 initBricks: function( $scope ) { 161 162 if ( window.bricksIsFrontend ) { 163 return; 164 } 165 166 $scope = $scope || $( 'body' ); 167 JetEngine.initBlocks( $scope ); 168 169 }, 170 171 initBlocks: function( $scope ) { 172 173 $scope = $scope || $( 'body' ); 174 175 window.JetPlugins.init( $scope, [ 176 { 177 block: 'jet-engine/listing-grid', 178 callback: JetEngine.widgetListingGrid 179 }, 180 { 181 block: 'jet-engine/dynamic-field', 182 callback: JetEngine.widgetDynamicField 183 } 184 ] ); 185 }, 186 187 initFrontStores: function( $scope ) { 188 189 $scope = $scope || $( 'body' ); 190 191 $( '.jet-add-to-store.is-front-store', $scope ).each( function() { 192 193 var $this = $( this ), 194 args = $this.data( 'args' ), 195 store = JetEngineStores[ args.store.type ], 196 count = 0; 197 198 args = JetEngine.ensureJSON( args ); 199 200 if ( ! store ) { 201 return; 202 } 203 204 if ( store.inStore( args.store.slug, '' + args.post_id ) ) { 205 JetEngine.switchDataStoreStatus( $this ); 206 } 207 208 } ); 209 210 $( '.jet-remove-from-store.is-front-store', $scope ).each( function() { 211 212 var $this = $( this ), 213 args = $this.data( 'args' ), 214 store = JetEngineStores[ args.store.type ], 215 count = 0; 216 217 args = JetEngine.ensureJSON( args ); 218 219 if ( ! store ) { 220 return; 221 } 222 223 if ( ! store.inStore( args.store.slug, '' + args.post_id ) ) { 224 $this.addClass( 'is-hidden' ); 225 } else { 226 $this.removeClass( 'is-hidden' ); 227 } 228 229 } ); 230 231 }, 232 233 initStores: function() { 234 235 JetEngine.initFrontStores(); 236 237 $.each( JetEngineRegisteredStores, function( storeSlug, storeType ) { 238 239 var store = JetEngineStores[ storeType ], 240 storeData = null, 241 count = 0; 242 243 if ( ! store ) { 244 return; 245 } 246 247 storeData = store.getStore( storeSlug ); 248 249 if ( storeData && storeData.length ) { 250 count = storeData.length; 251 } 252 253 $( 'span.jet-engine-data-store-count[data-store="' + storeSlug + '"]' ).text( count ); 254 255 } ); 256 257 JetEngine.loadFrontStoresItems(); 258 259 }, 260 261 loadFrontStoresItems: function( $scope ) { 262 263 $scope = $scope || $( 'body' ); 264 265 $( '.jet-listing-not-found.jet-listing-grid__items', $scope ).each( function() { 266 267 var $this = $( this ), 268 nav = $this.data( 'nav' ), 269 isStore = $this.data( 'is-store-listing' ), 270 query = nav.query || {}; 271 272 nav = JetEngine.ensureJSON( nav ); 273 274 if ( query && query.post__in && query.post__in.length && 0 >= query.post__in.indexOf( 'is-front' ) ) { 275 276 var storeType = query.post__in[1], 277 storeSlug = query.post__in[2], 278 store = JetEngineStores[ storeType ], 279 posts = [], 280 $container = $this.closest( '.elementor-widget-container' ); 281 282 if ( ! store ) { 283 return; 284 } 285 286 //Context Gutenberg 287 if ( ! $container.length ) { 288 $container = $this.closest( '.jet-listing-grid--blocks' ); 289 } 290 291 // Context Bricks 292 if ( ! $container.length ) { 293 $container = $this.closest( '.brxe-jet-engine-listing-grid' ) 294 } 295 296 posts = store.getStore( storeSlug ); 297 298 if ( ! posts.length ) { 299 return; 300 } 301 302 query.post__in = posts; 303 query.is_front_store = true; 304 305 JetEngine.ajaxGetListing( { 306 handler: 'get_listing', 307 container: $container, 308 masonry: false, 309 slider: false, 310 append: false, 311 query: query, 312 widgetSettings: nav.widget_settings, 313 }, function( response ) { 314 JetEngine.widgetListingGrid( $container ); 315 } ); 316 317 } else if ( isStore ) { 318 $( document ).trigger( 'jet-listing-grid-init-store', $this ); 319 } 320 321 } ); 322 }, 323 324 removeFromStore: function( event ) { 325 326 event.preventDefault(); 327 event.stopPropagation(); 328 329 var $this = $( this ), 330 args = $this.data( 'args' ), 331 isDataStoreBtn = $this.hasClass( 'jet-data-store-link' ); 332 333 args = JetEngine.ensureJSON( args ); 334 335 if ( args.store.is_front ) { 336 337 var store = JetEngineStores[ args.store.type ], 338 count = 0; 339 340 if ( ! store ) { 341 return; 342 } 343 344 if ( ! store.inStore( args.store.slug, '' + args.post_id ) ) { 345 var storePosts = store.getStore( args.store.slug ); 346 count = storePosts.length; 347 } else { 348 count = store.remove( args.store.slug, args.post_id ); 349 } 350 351 $( '.jet-add-to-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() { 352 JetEngine.switchDataStoreStatus( $( this ), true ); 353 } ); 354 355 $( '.jet-data-store-link.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() { 356 JetEngine.switchDataStoreStatus( $( this ), true ); 357 } ); 358 359 $( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( count ); 360 361 if ( args.remove_from_listing ) { 362 $this.closest( '.jet-listing-dynamic-post-' + args.post_id ).remove(); 363 } 364 365 JetEngine.dataStoreSyncListings( args ); 366 367 $( document ).trigger( 'jet-engine-data-stores-on-remove', args ); 368 369 return; 370 371 } 372 373 if ( $this.hasClass( 'jet-store-processing' ) ) { 374 return; 375 } 376 377 $this.css( 'opacity', 0.3 ); 378 $this.addClass( 'jet-store-processing' ); 379 380 $.ajax({ 381 url: JetEngineSettings.ajaxurl, 382 type: 'POST', 383 dataType: 'json', 384 data: { 385 action: 'jet_engine_remove_from_store_' + args.store.slug, 386 store: args.store.slug, 387 post_id: args.post_id, 388 }, 389 }).done( function( response ) { 390 391 $this.css( 'opacity', 1 ); 392 $this.removeClass( 'jet-store-processing' ); 393 394 if ( response.success ) { 395 396 if ( ! isDataStoreBtn ) { 397 $this.addClass( 'is-hidden' ); 398 } 399 400 $( '.jet-add-to-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() { 401 JetEngine.switchDataStoreStatus( $( this ), true ); 402 } ); 403 404 $( '.jet-data-store-link.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).each( function() { 405 JetEngine.switchDataStoreStatus( $( this ), true ); 406 } ); 407 408 JetEngine.dataStoreSyncListings( args ); 409 410 if ( args.remove_from_listing ) { 411 $this.closest( '.jet-listing-grid__item[data-post="' + args.post_id + '"]' ).remove(); 412 } 413 414 if ( response.data.fragments ) { 415 $.each( response.data.fragments, function( selector, value ) { 416 $( selector ).html( value ); 417 } ); 418 } 419 420 $( document ).trigger( 'jet-engine-data-stores-on-remove', args ); 421 422 } else { 423 alert( response.data.message ); 424 } 425 426 return response; 427 428 } ).done( function( response ) { 429 430 if ( args.remove_from_listing ) { 431 $this.closest( '.jet-listing-grid__item' ).remove(); 432 } 433 434 if ( response.success ) { 435 $( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( response.data.count ); 436 } 437 438 } ).fail( function( jqXHR, textStatus, errorThrown ) { 439 $this.css( 'opacity', 1 ); 440 $this.removeClass( 'jet-store-processing' ); 441 alert( errorThrown ); 442 } ); 443 444 }, 445 446 triggerPopup: function( popupID, isJetEngine, postID ) { 447 448 if ( ! popupID ) { 449 return; 450 } 451 452 var popupData = { 453 popupId: 'jet-popup-' + popupID, 454 }; 455 456 if ( isJetEngine ) { 457 popupData.isJetEngine = true; 458 popupData.postId = postID; 459 } 460 461 $( window ).trigger( { 462 type: 'jet-popup-open-trigger', 463 popupData: popupData 464 } ); 465 466 }, 467 468 dataStoreSyncListings: function( args ) { 469 if ( ! args.synch_id || typeof args.synch_id !== 'string' ) { 470 return; 471 } 472 473 const ids = args.synch_id.split( /[\s,]+/ ).map( ( id ) => id.replace( /\s/, '' ) ).filter( ( id ) => !! id ); 474 475 ids.forEach( function ( id ) { 476 let $container = $( '#' + id ), 477 $elemContainer = $container.find( '> .elementor-widget-container' ), 478 $items = $container.find( '.jet-listing-grid__items' ), 479 posts = [], 480 nav = $items.data( 'nav' ) || {}, 481 query = nav.query || {}, 482 postID = window.elementorFrontendConfig?.post?.id || 0; 483 484 nav = JetEngine.ensureJSON( nav ); 485 486 // Context Bricks 487 if ( $container.hasClass( 'brxe-jet-engine-listing-grid' ) ) { 488 postID = window.bricksData.postId; 489 } 490 491 // Context Gutenberg 492 if ( $container.hasClass( 'jet-listing-grid--blocks' )) { 493 postID = JetEngineSettings.post_id; 494 } 495 496 if ( args?.store?.is_front && Object.keys( query ).length ) { 497 let store = JetEngineStores[ args.store.type ]; 498 499 posts = store.getStore( args.store.slug ); 500 501 if ( ! posts.length ) { 502 posts = [ 'is-front', args.store.type, args.store.slug ]; 503 } 504 505 query.post__in = posts; 506 query.is_front_store = true; 507 } 508 509 let options = { 510 handler: 'get_listing', 511 container: $elemContainer.length ? $elemContainer : $container, 512 masonry: false, 513 slider: false, 514 append: false, 515 query: query, 516 widgetSettings: nav.widget_settings, 517 postID: postID, 518 elementID: $container.data( 'id' ),
519 }; 520 521 JetEngine.ajaxGetListing( options, function( response ) { 522 JetEngine.widgetListingGrid( $container ); 523 } ); 524 } ); 525 }, 526 527 addToStore: function( event ) { 528 529 event.preventDefault(); 530 event.stopPropagation(); 531 532 var $this = $( this ), 533 args = $this.data( 'args' ); 534 535 args = JetEngine.ensureJSON( args ); 536 537 if ( $this.hasClass( 'in-store' ) ) { 538 if ( args.popup ) { 539 JetEngine.triggerPopup( args.popup, args.isJetEngine, args.post_id ); 540 } else if ( '_blank' === $this.attr( 'target' ) ) { 541 window.open( $this.attr( 'href' ) ); 542 } else { 543 window.location = $this.attr( 'href' ); 544 } 545 return; 546 } 547 548 if ( args.store.is_front ) { 549 550 var store = JetEngineStores[ args.store.type ], 551 count = 0; 552 553 if ( ! store ) { 554 return; 555 } 556 557 if ( store.inStore( args.store.slug, '' + args.post_id ) ) { 558 var storePosts = store.getStore( args.store.slug ); 559 count = storePosts.length; 560 } else { 561 562 count = store.addToStore( args.store.slug, args.post_id, args.store.size ); 563 564 if ( false === count ) { 565 return; 566 } 567 568 } 569 570 if ( args.popup ) { 571 JetEngine.triggerPopup( args.popup, args.isJetEngine, args.post_id ); 572 } 573 574 JetEngine.switchDataStoreStatus( $this ); 575 $( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( count ); 576 $( '.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).removeClass( 'is-hidden' ); 577 578 JetEngine.dataStoreSyncListings( args ); 579 580 $( document ).trigger( 'jet-engine-data-stores-on-add', args ); 581 582 return; 583 } 584 585 if ( $this.hasClass( 'jet-store-processing' ) ) { 586 return; 587 } 588 589 $this.css( 'opacity', 0.3 ); 590 $this.addClass( 'jet-store-processing' ); 591 592 $( document ).trigger( 'jet-engine-on-add-to-store', [ $this, args ] ); 593 594 $.ajax({ 595 url: JetEngineSettings.ajaxurl, 596 type: 'POST', 597 dataType: 'json', 598 data: { 599 action: 'jet_engine_add_to_store_' + args.store.slug, 600 store: args.store.slug, 601 post_id: args.post_id, 602 }, 603 }).done( function( response ) { 604 605 $this.css( 'opacity', 1 ); 606 $this.removeClass( 'jet-store-processing' ); 607 608 if ( response.success ) { 609 610 JetEngine.switchDataStoreStatus( $this ); 611 $( '.jet-remove-from-store[data-store="' + args.store.slug + '"][data-post="' + args.post_id + '"]' ).removeClass( 'is-hidden' ); 612 613 if ( response.data.fragments ) { 614 $.each( response.data.fragments, function( selector, value ) { 615 $( selector ).html( value ); 616 } ); 617 } 618 619 JetEngine.dataStoreSyncListings( args ); 620 621 if ( args.popup ) { 622 JetEngine.triggerPopup( args.popup, args.isJetEngine, args.post_id ); 623 } 624 625 } else { 626 alert( response.data.message ); 627 } 628 629 $( document ).trigger( 'jet-engine-data-stores-on-add', args ); 630 631 return response; 632 633 } ).done( function( response ) { 634 635 if ( response.success ) { 636 $( 'span.jet-engine-data-store-count[data-store="' + args.store.slug + '"]' ).text( response.data.count ); 637 } 638 639 } ).fail( function( jqXHR, textStatus, errorThrown ) { 640 $this.css( 'opacity', 1 ); 641 $this.removeClass( 'jet-store-processing' ); 642 alert( errorThrown ); 643 } ); 644 645 }, 646 647 switchDataStoreStatus: function( $item, toInitial ) { 648 649 var isDataStoreLink = $item.hasClass( 'jet-data-store-link' ), 650 $label = $item.find( '.jet-listing-dynamic-link__label, .jet-data-store-link__label' ), 651 $icon = $item.find( '.jet-listing-dynamic-link__icon, .jet-data-store-link__icon' ), 652 args = $item.data( 'args' ), 653 replaceLabel, 654 replaceURL, 655 replaceIcon; 656 657 args = JetEngine.ensureJSON( args ); 658 659 toInitial = toInitial || false; 660 661 if ( isDataStoreLink ) { 662 663 switch ( args.action_after_added ) { 664 case 'remove_from_store': 665 666 if ( toInitial ) { 667 $item.addClass( 'jet-add-to-store' ); 668 $item.removeClass( 'jet-remove-from-store' ); 669 670 $item.removeClass( 'in-store' ); 671 } else { 672 $item.addClass( 'jet-remove-from-store' ); 673 $item.removeClass( 'jet-add-to-store' ); 674 675 $item.addClass( 'in-store' ); 676 677 } 678 679 break; 680 681 case 'hide': 682 683 if ( toInitial ) { 684 $item.removeClass( 'is-hidden' ); 685 } else { 686 $item.addClass( 'is-hidden' ); 687 } 688 689 return; 690 } 691 692 } 693 694 if ( toInitial ) { 695 replaceLabel = args.label; 696 replaceIcon = args.icon; 697 replaceURL = '#'; 698 } else { 699 replaceLabel = args.added_label; 700 replaceIcon = args.added_icon; 701 replaceURL = args.added_url; 702 } 703 704 if ( $label.length ) { 705 $label.replaceWith( replaceLabel ); 706 } else { 707 $item.append( replaceLabel ); 708 } 709 710 if ( $icon.length ) { 711 $icon.replaceWith( replaceIcon ); 712 } else { 713 $item.prepend( replaceIcon ); 714 } 715 716 if ( isDataStoreLink && 'remove_from_store' === args.action_after_added ) { 717 return; 718 } 719 720 $item.attr( 'href', replaceURL ); 721 722 if ( toInitial ) { 723 $item.removeClass( 'in-store' ); 724 } else if ( ! $item.hasClass( 'in-store' ) ) { 725 $item.addClass( 'in-store' ); 726 } 727 728 729 }, 730 731 showConfirmDeleteDialog: function( event ) { 732 event.preventDefault(); 733 event.stopPropagation(); 734 735 var $this = $( this ); 736 737 if ( window.confirm( $this.data( 'delete-message' ) ) ) { 738 window.location = $this.attr( 'href' ); 739 } 740 741 }, 742 743 handleListingItemClick: function( event ) { 744 745 var url = $( this ).data( 'url' ), 746 target = $( this ).data( 'target' ) || false; 747 748 if ( url ) { 749 750 event.preventDefault(); 751 752 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() ) { 753 return; 754 } 755 756 if ( -1 !== url.indexOf( '#jet-engine-action' ) ) { 757 758 JetEngine.customUrlActions.runAction( url ); 759 760 } else { 761 762 if ( '_blank' === target ) { 763 window.open( url ); 764 return; 765 } 766 767 window.location = url; 768 } 769 } 770 771 }, 772 773 customUrlActions: { 774 selectorOnClick: 'a[href^="#jet-engine-action"][href*="event=click"]', 775 selectorOnHover: 'a[href^="#jet-engine-action"][href*="event=hover"], [data-url^="#jet-engine-action"][data-url*="event=hover"]', 776 777 init: function() { 778 var timeout = null; 779 780 $( document ).on( 'click.JetEngine', this.selectorOnClick, function( event ) { 781 event.preventDefault(); 782 JetEngine.customUrlActions.actionHandler( event ) 783 } ); 784 785 $( document ).on( 'click.JetEngine', this.selectorOnHover, function( event ) { 786 if ( 'A' === event.currentTarget.nodeName ) { 787 event.preventDefault(); 788 } 789 } ); 790 791 $( document ).on( { 792 'mouseenter.JetEngine': function( event ) { 793 794 if ( timeout ) { 795 clearTimeout( timeout ); 796 } 797 798 timeout = setTimeout( function() { 799 JetEngine.customUrlActions.actionHandler( event ) 800 }, window.JetEngineSettings.hoverActionTimeout ); 801 }, 802 'mouseleave.JetEngine': function() { 803 if ( timeout ) { 804 clearTimeout( timeout ); 805 timeout = null; 806 } 807 }, 808 }, this.selectorOnHover ); 809 }, 810 811 actions: {}, 812 813 addAction: function( name, callback ) { 814 this.actions[ name ] = callback; 815 }, 816 817 actionHandler: function( event ) { 818 var url = $( event.currentTarget ).attr( 'href' ) || $( event.currentTarget ).attr( 'data-url' ); 819 820 this.runAction( url ); 821 }, 822 823 runAction: function( url ) { 824 var queryParts = url.split( '&' ), 825 settings = {}; 826
827 queryParts.forEach( function( item ) { 828 if ( -1 !== item.indexOf( '=' ) ) { 829 var pair = item.split( '=' ); 830 831 settings[ pair[0] ] = decodeURIComponent( pair[1] ); 832 } 833 } ); 834 835 if ( ! settings.action ) { 836 return; 837 } 838 839 var actionCb = this.actions[ settings.action ]; 840 841 if ( ! actionCb ) { 842 return; 843 } 844 845 actionCb( settings ); 846 } 847 }, 848 849 prepareJetPopup: function( popupData, widgetData, $scope ) { 850 851 var postId = null; 852 853 if ( widgetData['is-jet-engine'] ) { 854 popupData['isJetEngine'] = true; 855 856 var $gridItems = $scope.closest( '.jet-listing-grid__items' ), 857 $gridItem = $scope.closest( '.jet-listing-grid__item' ), 858 $calendarItem = $scope.closest( '.jet-calendar-week__day-event' ), 859 $itemObject = $scope.closest( '[data-item-object]' ), 860 filterProvider = false, 861 filterQueryId = 'default'; 862 863 if ( $gridItems.length ) { 864 popupData['listingSource'] = $gridItems.data( 'listing-source' ); 865 popupData['listingId'] = $gridItems.data( 'listing-id' ); 866 popupData['queryId'] = $gridItems.data( 'query-id' ); 867 } else { 868 869 var $queryItems = $scope.closest( '[data-query-id]' ), 870 $listingSource = $scope.closest( '[data-listing-source]' ); 871 872 if ( $queryItems.length ) { 873 popupData['queryId'] = $queryItems.data( 'query-id' ); 874 } 875 876 if ( $listingSource.length ) { 877 popupData['listingSource'] = $listingSource.data( 'listing-source' ); 878 } 879 } 880 881 if ( $gridItem.length ) { 882 popupData['postId'] = $gridItem.data( 'post-id' ); 883 filterProvider = 'jet-engine'; 884 } else if ( $calendarItem.length ) { 885 popupData['postId'] = $calendarItem.data( 'post-id' ); 886 filterProvider = 'jet-engine-calendar'; 887 } else if ( $itemObject ) { 888 popupData['postId'] = $itemObject.data( 'item-object' ); 889 } else if ( window.elementorFrontendConfig && window.elementorFrontendConfig.post ) { 890 popupData['postId'] = window.elementorFrontendConfig.post.id; 891 } 892 893 if ( window.JetEngineFormsEditor && window.JetEngineFormsEditor.hasEditor ) { 894 popupData['hasEditor'] = true; 895 } 896 897 // Add the filtered query to the popup data 898 if ( window.JetSmartFilters ) { 899 900 switch ( filterProvider ) { 901 case 'jet-engine': 902 var nav = $gridItems.data( 'nav' ); 903 904 if ( nav.widget_settings?._element_id ) { 905 filterQueryId = nav.widget_settings._element_id; 906 } 907 break; 908 909 case 'jet-engine-calendar': 910 var settings = $calendarItem.closest( '.jet-listing-calendar' ).data( 'settings' ); 911 912 if ( settings._element_id ) { 913 filterQueryId = settings._element_id; 914 } 915 break; 916 } 917 918 filterProvider = window.JetPlugins.hooks.applyFilters( 'jet-engine.prepareJetPopupData.filterProvider', filterProvider, $scope, widgetData ); 919 filterQueryId = window.JetPlugins.hooks.applyFilters( 'jet-engine.prepareJetPopupData.filterQueryId', filterQueryId, $scope, widgetData ); 920 921 if ( popupData.queryId && filterProvider 922 && window.JetSmartFilters?.filterGroups?.[ filterProvider + '/' + filterQueryId ]?.currentQuery 923 ) { 924 popupData['filtered_query'] = window.JetSmartFilters.filterGroups[ filterProvider + '/' + filterQueryId ].currentQuery; 925 } 926 } 927 928 } 929 930 return popupData; 931 932 }, 933 934 showCalendarEvent: function( event ) { 935 936 var $this = $( this ), 937 $day = $this.closest( '.jet-calendar-week__day' ), 938 $week = $day.closest( '.jet-calendar-week' ), 939 $events = $day.find( '.jet-calendar-week__day-content' ), 940 activeClass = 'calendar-event-active'; 941 942 if ( $day.hasClass( activeClass ) ) { 943 $day.removeClass( activeClass ); 944 JetEngine.activeCalendarDay.remove(); 945 JetEngine.activeCalendarDay = null; 946 return; 947 } 948 949 if ( JetEngine.activeCalendarDay ) { 950 JetEngine.activeCalendarDay.remove(); 951 $( '.' + activeClass ).removeClass( activeClass ); 952 JetEngine.activeCalendarDay = null; 953 } 954 955 $day.addClass( 'calendar-event-active' ); 956 957 JetEngine.activeCalendarDay = $( '<tr class="jet-calendar-week"><td colspan="7" class="jet-calendar-week__day jet-calendar-week__day-mobile"><div class="jet-calendar-week__day-mobile-event">' + $events.html() + '</div></td></tr>' ); 958 959 // Need for re-init popup events 960 JetEngine.activeCalendarDay.find( '.jet-popup-attach-event-inited' ).removeClass( 'jet-popup-attach-event-inited' ); 961 JetEngine.initElementsHandlers( JetEngine.activeCalendarDay ); 962 963 JetEngine.activeCalendarDay.insertAfter( $week ); 964 965 }, 966 967 widgetListingGrid: function( $scope ) { 968 969 var widgetID = $scope.closest( '.elementor-widget' ).data( 'id' ),
970 $wrapper = $scope.find( '.jet-listing-grid' ).first(), 971 hasLazyLoad = $wrapper.hasClass( 'jet-listing-grid--lazy-load' ), 972 $listing = $scope.find( '.jet-listing-grid__items' ).first(), 973 $slider = $listing.parent( '.jet-listing-grid__slider' ), 974 $masonry = $listing.hasClass( 'jet-listing-grid__masonry' ) ? $listing : false, 975 navSettings = $listing.data( 'nav' ), 976 masonryGrid = false, 977 listingType = 'elementor'; 978 979 navSettings = JetEngine.ensureJSON( navSettings ); 980 981 if ( hasLazyLoad ) { 982 983 var lazyLoadOptions = $wrapper.data( 'lazy-load' ), 984 widgetSettings = {}, 985 $container = $scope.find( '.elementor-widget-container' ); 986 987 // Get widget settings from `elementorFrontend` in Editor. 988 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() 989 && $wrapper.closest( '.elementor[data-elementor-type]' ).hasClass( 'elementor-edit-mode' ) 990 ) { 991 widgetSettings = JetEngine.getEditorElementSettings( $scope.closest( '.elementor-widget' ) ); 992 widgetID = false; // for avoid get widget settings from document in editor 993 } 994 995 if ( ! $container.length ) { 996 $container = $scope; 997 widgetSettings = $scope.data( 'widget-settings' ); 998 } 999 1000 if ( ! widgetID ) { 1001 widgetID = $scope.data( 'element-id' ); 1002 listingType = $scope.data( 'listing-type' ); 1003 } 1004 1005 JetEngine.lazyLoadListing( { 1006 container: $container, 1007 elementID: widgetID, 1008 postID: lazyLoadOptions.post_id, 1009 queriedID: lazyLoadOptions.queried_id || false, 1010 offset: lazyLoadOptions.offset || '0px', 1011 query: lazyLoadOptions.query || {}, 1012 listingType: listingType, 1013 widgetSettings: widgetSettings, 1014 extraProps: lazyLoadOptions.extra_props || false, 1015 } ); 1016 1017 return; 1018 } 1019 1020 if ( $slider.length ) { 1021 JetEngine.initSlider( $slider ); 1022 } 1023 1024 if ( $masonry && $masonry.length ) { 1025 1026 JetEngine.initMasonry( $masonry ); 1027 1028 /* Keep masonry re-init for Bricks */ 1029 if ( $scope.hasClass( 'brxe-jet-engine-listing-grid' ) ) { 1030 $( window ).on( 'load', function() { 1031 JetEngine.runMasonry( $masonry ); 1032 } ); 1033 } 1034 1035 } 1036 1037 if ( navSettings && navSettings.enabled ) { 1038 1039 JetEngine.loadMoreListing( { 1040 container: $listing, 1041 settings: navSettings, 1042 masonry: $masonry, 1043 slider: $slider, 1044 } ); 1045 1046 } 1047 1048 // Init elements handlers in editor. 1049 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() 1050 && $wrapper.closest( '.elementor-element-edit-mode' ).length 1051 ) { 1052 JetEngine.initElementsHandlers( $wrapper ); 1053 } 1054 1055 }, 1056 1057 initMasonry: function( $masonry, masonrySettings ) { 1058 imagesLoaded( $masonry, function() { 1059 JetEngine.runMasonry( $masonry, masonrySettings ); 1060 } ); 1061 }, 1062 1063 runMasonry: function( $masonry, masonrySettings ) { 1064 var defaultSettings = { 1065 itemSelector: '> .jet-listing-grid__item', 1066 columnsKey: 'columns', 1067 }; 1068 1069 masonrySettings = masonrySettings || {}; 1070 masonrySettings = $.extend( {}, defaultSettings, masonrySettings ); 1071 1072 var $eWidget = $masonry.closest( '.elementor-widget' ), 1073 $items = $( masonrySettings.itemSelector, $masonry ), 1074 options = $masonry.data( 'masonry-grid-options' ) || {}; 1075 1076 options = JetEngine.ensureJSON( options ); 1077 1078 // Reset masonry 1079 $items.css( { 1080 marginTop: '' 1081 } ); 1082 1083 // Bricks margin 1084 const { gap } = options; 1085 let margin = null; 1086 1087 if ( gap ) { 1088 margin = { 1089 x: +gap.horizontal, 1090 y: +gap.vertical, 1091 }; 1092 } 1093 1094 var args = { 1095 container: $masonry[0], 1096 margin: margin ? margin : 0, 1097 }; 1098 1099 if ( $eWidget.length ) { 1100 var settings = JetEngine.getElementorElementSettings( $eWidget ), 1101 breakpoints = {}, 1102 eBreakpoints = window.elementorFrontend.config.responsive.activeBreakpoints, 1103 columnsKey = masonrySettings.columnsKey; 1104 1105 args.columns = settings[columnsKey + '_widescreen'] ? +settings[columnsKey + '_widescreen'] : +settings[columnsKey]; 1106 1107 Object.keys( eBreakpoints ).reverse().forEach( function( breakpointName ) { 1108 1109 if ( settings[columnsKey + '_' + breakpointName] ) { 1110 if ( 'widescreen' === breakpointName ) { 1111 breakpoints[eBreakpoints[breakpointName].value - 1] = +settings[columnsKey]; 1112 } else { 1113 breakpoints[eBreakpoints[breakpointName].value] = +settings[columnsKey + '_' + breakpointName]; 1114 } 1115 } 1116 1117 } ); 1118 1119 args.breakAt = breakpoints; 1120 1121 } else { 1122 args.columns = options.columns.desktop; 1123 args.breakAt = { 1124 1025: options.columns.tablet, 1125 768: options.columns.mobile, 1126 }; 1127 } 1128 1129 var masonryInstance = Macy( args ); 1130 1131 masonryInstance.runOnImageLoad( function () { 1132 masonryInstance.recalculate( true ); 1133 }, true ); 1134 1135 // Event to recalculate current masonry listings. 1136 $masonry.on( 'jet-engine/listing/recalculate-masonry-listing', function() { 1137 masonryInstance.runOnImageLoad( function () { 1138 masonryInstance.recalculate( true ); 1139 }, true ); 1140 } ); 1141 1142 // Event to recalculate all masonry listings. 1143 $( document ).on( 'jet-engine/listing/recalculate-masonry', function() { 1144 masonryInstance.recalculate( true ); 1145 } ); 1146 1147 }, 1148
1149 ajaxGetListing: function( options, doneCallback, failCallback ) { 1150 1151 var container = options.container || false, 1152 handler = options.handler || false, 1153 masonry = options.masonry || false, 1154 slider = options.slider || false, 1155 append = options.append || false, 1156 query = options.query || {}, 1157 widgetSettings = options.widgetSettings || {}, 1158 postID = options.postID || false, 1159 queriedID = options.queriedID || false, 1160 elementID = options.elementID || false, 1161 page = options.page || 1, 1162 preventCSS = options.preventCSS || false, 1163 listingType = options.listingType || false, 1164 extraProps = options.extraProps || false, 1165 isEditMode = window.elementorFrontend && window.elementorFrontend.isEditMode(); 1166 1167 doneCallback = doneCallback || function( response ) {}; 1168 1169 if ( ! container|| ! handler ) { 1170 return; 1171 } 1172 1173 if ( ! preventCSS ) { 1174 container.css({ 1175 pointerEvents: 'none', 1176 opacity: '0.5', 1177 cursor: 'default', 1178 }); 1179 } 1180 1181 var requestData = { 1182 action: 'jet_engine_ajax', 1183 handler: handler, 1184 query: query, 1185 widget_settings: widgetSettings, 1186 page_settings: { 1187 post_id: postID, 1188 queried_id: queriedID, 1189 element_id: elementID, 1190 page: page, 1191 }, 1192 listing_type: listingType, 1193 isEditMode: isEditMode, 1194 addedPostCSS: JetEngine.addedPostCSS 1195 }; 1196 1197 if ( extraProps ) { 1198 Object.assign( requestData, extraProps ); 1199 } 1200 1201 $.ajax({ 1202 url: JetEngineSettings.ajaxlisting, 1203 type: 'POST', 1204 dataType: 'json', 1205 data: requestData, 1206 }).done( function( response ) { 1207 1208 // container.removeAttr( 'style' ); 1209 1210 // Manual reset container style to prevent removal of masonry styles. 1211 if ( !preventCSS ) { 1212 container.css( { 1213 pointerEvents: '', 1214 opacity: '', 1215 cursor: '', 1216 } ); 1217 } 1218 1219 if ( response.success ) { 1220 1221 JetEngine.enqueueAssetsFromResponse( response ); 1222 1223 container.data( 'page', page ); 1224 1225 var $html = $( response.data.html ); 1226 1227 JetEngine.initFrontStores( $html ); 1228 1229 if ( slider && slider.length ) { 1230 1231 var $slider = slider.find( '> .jet-listing-grid__items' ); 1232 1233 if ( ! $slider.hasClass( 'slick-initialized' ) ) { 1234 1235 if ( append ) { 1236 container.append( $html ); 1237 } else { 1238 container.html( $html ); 1239 } 1240 1241 var itemsCount = container.find( '> .jet-listing-grid__item' ).length; 1242 1243 slider.addClass( 'jet-listing-grid__slider' ); 1244 JetEngine.initSlider( slider, { itemsCount: itemsCount } ); 1245 1246 } else { 1247 $html.each( function( index, el ) { 1248 $slider.slick( 'slickAdd', el ); 1249 }); 1250 } 1251 1252 } else { 1253 1254 if ( append ) { 1255 container.append( $html ); 1256 } else { 1257 container.html( $html ); 1258 } 1259 1260 if ( masonry && masonry.length ) { 1261 //JetEngine.initMasonry( masonry ); 1262 masonry.trigger( 'jet-engine/listing/recalculate-masonry-listing' ); 1263 } 1264 1265 } 1266 1267 // Re-init Bricks scripts 1268 JetEngine.reinitBricksScripts(); 1269 1270 Promise.all( JetEngine.assetsPromises ).then( function() { 1271 JetEngine.initElementsHandlers( $html ); 1272 JetEngine.assetsPromises = []; 1273 } ); 1274 1275 if ( response.data.fragments ) { 1276 for ( var selector in response.data.fragments ) { 1277 var $selector = $( selector ); 1278 1279 if ( $selector.length ) { 1280 $selector.html( response.data.fragments[ selector ] ); 1281 } 1282 } 1283 } 1284 } 1285 1286 $( document ).trigger( 'jet-engine/listing/ajax-get-listing/done', [ $html, options ] ); 1287 1288 } ).done( doneCallback ).fail( function() { 1289 container.removeAttr( 'style' ); 1290 if ( failCallback ) { 1291 failCallback.call(); 1292 } 1293 1294 } ); 1295 1296 }, 1297 1298 loadMoreListing: function( args ) { 1299 1300 var instance = { 1301 1302 setup: function() { 1303 this.container = args.container; 1304 this.masonry = args.masonry; 1305 this.slider = args.slider; 1306 this.settings = args.settings; 1307 1308 this.wrapper = this.container.closest( '.jet-listing-grid' ); 1309 1310 this.type = this.settings.type || 'click'; 1311 this.page = parseInt( this.container.data( 'page' ), 10 ) || 0; 1312 this.pages = parseInt( this.container.data( 'pages' ), 10 ) || 0; 1313 this.queriedID = this.container.data( 'queried-id' ) || false; 1314 }, 1315 1316 init: function() { 1317 1318 this.setup(); 1319 1320 switch ( this.type ) { 1321 case 'click': 1322 1323 this.handleMore(); 1324 1325 break; 1326 1327 case 'scroll': 1328 1329 if ( ( ! window.elementorFrontend || ! window.elementorFrontend.isEditMode() ) && ! this.slider.length ) { 1330 this.handleInfiniteScroll(); 1331 } 1332 1333 break; 1334 } 1335 }, 1336 1337 handleMore: function() { 1338 1339 if ( ! this.settings.more_el ) { 1340 return; 1341 } 1342 1343 var self = this, 1344 $button = $( this.settings.more_el ); 1345 1346 if ( ! $button.length ) { 1347 return; 1348 } 1349 1350 if ( ! this.pages || this.page === this.pages && ! window.elementor ) { 1351 $button.css( 'display', 'none' ); 1352 } else { 1353 $button.removeAttr( 'style' ); 1354 } 1355 1356 $( document ) 1357 .off( 'click', this.settings.more_el ) 1358 .on( 'click', this.settings.more_el, function( event ) { 1359 event.preventDefault(); 1360 1361 if ( ! self.pages || self.page >= self.pages) { 1362 $button.css( 'display', 'none' ); 1363 return; 1364 } 1365 1366 $button.css( { 1367 pointerEvents: 'none', 1368 opacity: '0.5', 1369 cursor: 'default', 1370 } ); 1371 1372 self.ajaxGetItems( function( response ) { 1373 $button.removeAttr( 'style' ); 1374 1375 if ( response.success && self.page === self.pages ) { 1376 $button.css( 'display', 'none' ); 1377 } 1378 }, function() { 1379 $button.button.removeAttr( 'style' ); 1380 } 1381 ); 1382 } ); 1383 }, 1384 1385 handleInfiniteScroll: function() { 1386 1387 if ( this.container.hasClass( 'jet-listing-not-found' ) ) { 1388 return; 1389 } 1390 1391 if ( ! this.pages || this.page === this.pages ) { 1392 return; 1393 } 1394 1395 var self = this, 1396 $trigger = this.wrapper.find( '.jet-listing-grid__loader' ), 1397 offset = '0%'; 1398 1399 if ( ! $trigger.length ) { 1400 $trigger = $( '<div>', { 1401 class: 'jet-listing-grid__loading-trigger' 1402 } ); 1403 1404 this.wrapper.append( $trigger ); 1405 } 1406 1407 // Prepare offset value. 1408 if ( this.settings.widget_settings && this.settings.widget_settings.load_more_offset ) { 1409 var offsetValue = this.settings.widget_settings.load_more_offset; 1410 1411 switch ( typeof offsetValue ) { 1412 case 'object': 1413 var size = offsetValue.size ? offsetValue.size : '0', 1414 unit = offsetValue.unit ? offsetValue.unit : 'px'; 1415 1416 offset = size + unit; 1417 break; 1418 1419 case 'number': 1420 case 'string': 1421 offset = offsetValue + 'px'; 1422 break; 1423 } 1424 } 1425 1426 var observer = new IntersectionObserver( 1427 function( entries, observer ) { 1428 1429 if ( entries[0].isIntersecting ) { 1430 1431 self.ajaxGetItems( function() { 1432 1433 // Re-init observer if the last page is not loaded 1434 if ( self.page !== self.pages ) { 1435 setTimeout( function() { 1436 observer.observe( entries[0].target ); 1437 }, 250 ); 1438 } 1439 1440 } ); 1441 1442 // Detach observer 1443 observer.unobserve( entries[0].target ); 1444 } 1445 }, 1446 { 1447 rootMargin: '0% 0% ' + offset + ' 0%', 1448 } 1449 ); 1450 1451 observer.observe( $trigger[0] ); 1452 }, 1453 1454 ajaxGetItems: function( doneCallback, failCallback ) { 1455 var self = this; 1456 1457 this.page++; 1458 1459 this.wrapper.addClass( 'jet-listing-grid-loading' ); 1460 1461 JetEngine.ajaxGetListing( { 1462 handler: 'listing_load_more', 1463 container: this.container, 1464 masonry: this.masonry, 1465 slider: this.slider, 1466 append: true, 1467 query: this.settings.query, 1468 widgetSettings: this.settings.widget_settings, 1469 page: this.page, 1470 queriedID: this.queriedID, 1471 preventCSS: !! this.wrapper.find( '.jet-listing-grid__loader' ).length, // Prevent CSS if listing has the loader. 1472 }, function( response ) { 1473 1474 JetEngine.lazyLoading = false;
1475 self.wrapper.removeClass( 'jet-listing-grid-loading' ); 1476 1477 if ( doneCallback ) { 1478 doneCallback( response ); 1479 } 1480 1481 $( document ).trigger( 'jet-engine/listing-grid/after-load-more', [args, response] ); 1482 1483 }, function() { 1484 1485 JetEngine.lazyLoading = false; 1486 self.wrapper.removeClass( 'jet-listing-grid-loading' ); 1487 1488 if ( failCallback ) { 1489 failCallback(); 1490 } 1491 1492 } ); 1493 }, 1494 }; 1495 1496 instance.init(); 1497 }, 1498 1499 lazyLoadListing: function( args ) { 1500 1501 var $wrapper = args.container.find( '.jet-listing-grid' ), 1502 observer = new IntersectionObserver( 1503 function( entries, observer ) { 1504 1505 if ( entries[0].isIntersecting ) { 1506 1507 JetEngine.lazyLoading = true; 1508 1509 if ( ! $wrapper.length ) { 1510 $wrapper = args.container; 1511 } 1512 1513 $wrapper.addClass( 'jet-listing-grid-loading' ); 1514 1515 JetEngine.ajaxGetListing( { 1516 handler: 'get_listing', 1517 container: args.container, 1518 masonry: false, 1519 slider: false, 1520 append: false, 1521 elementID: args.elementID, 1522 postID: args.postID, 1523 queriedID: args.queriedID, 1524 query: args.query, 1525 widgetSettings: args.widgetSettings, 1526 listingType: args.listingType, 1527 preventCSS: true, 1528 extraProps: args.extraProps, 1529 }, function( response ) { 1530 1531 $wrapper.removeClass( 'jet-listing-grid-loading' ); 1532 1533 var $widget = args.container.closest( '.elementor-widget' ); 1534 1535 if ( ! $widget.length ) { 1536 $widget = args.container.closest( '.jet-listing-grid--blocks' ); 1537 } 1538 1539 if ( ! $widget.length ) { 1540 $widget = args.container; 1541 } 1542 1543 if ( $widget.length ) { 1544 $widget.find( '.jet-listing-grid' ).first().removeClass( 'jet-listing-grid--lazy-load' ); 1545 } 1546 1547 JetEngine.widgetListingGrid( $widget ); 1548 JetEngine.loadFrontStoresItems( $widget ); 1549 JetEngine.lazyLoading = false; 1550 1551 let needReInitFilters = false; 1552 let isFrontend = JetEngine.isFrontend(); 1553 1554 if ( isFrontend && window.JetSmartFilterSettings ) { 1555 1556 if ( response.data.filters_data ) { 1557 $.each( response.data.filters_data, function( param, data ) { 1558 if ( 'extra_props' === param ) { 1559 window.JetSmartFilterSettings[ param ] = $.extend( 1560 {}, 1561 window.JetSmartFilterSettings[ param ], 1562 data 1563 ); 1564 } else { 1565 if ( window.JetSmartFilterSettings[ param ]['jet-engine'] ) { 1566 window.JetSmartFilterSettings[ param ]['jet-engine'] = $.extend( 1567 {}, 1568 window.JetSmartFilterSettings[ param ]['jet-engine'], 1569 data 1570 ); 1571 } else { 1572 window.JetSmartFilterSettings[ param ]['jet-engine'] = data; 1573 } 1574 } 1575 }); 1576 1577 needReInitFilters = true; 1578 } 1579 1580 if ( response.data.indexer_data ) { 1581 const { 1582 provider = false, 1583 query = {} 1584 } = response.data.indexer_data; 1585 1586 window.JetSmartFilters.setIndexedData( provider, query ); 1587 } 1588 } 1589 1590 // ReInit filters 1591 if ( needReInitFilters && window.JetSmartFilters ) { 1592 window.JetSmartFilters.reinitFilters(); 1593 } 1594 1595 $( document ).trigger( 'jet-engine/listing-grid/after-lazy-load', [ args, response ] ); 1596 1597 }, function() { 1598 JetEngine.lazyLoading = false; 1599 1600 if ( ! $wrapper.length ) { 1601 $wrapper = args.container; 1602 } 1603 1604 $wrapper.removeClass( 'jet-listing-grid-loading' ); 1605 } ); 1606 1607 // Detach observer after the first load the listing 1608 observer.unobserve( entries[0].target ); 1609 } 1610 }, 1611 { 1612 rootMargin: '0% 0% ' + args.offset + ' 0%' 1613 } 1614 ); 1615 1616 observer.observe( args.container[0] ); 1617 }, 1618 1619 ensureJSON: function( maybeJSON ) { 1620 1621 if ( ! maybeJSON ) { 1622 return maybeJSON; 1623 } 1624 1625 if ( 'string' === typeof maybeJSON ) { 1626 console.log( maybeJSON ); 1627 //maybeJSON = JSON.parse( maybeJSON ); 1628 } 1629 1630 return maybeJSON; 1631 1632 }, 1633 1634 initSlider: function( $slider, customOptions ) { 1635 var $eWidget = $slider.closest( '.elementor-widget' ), 1636 options = $slider.data( 'slider_options' ), 1637 windowWidth = $( window ).width(), 1638 tabletBP = 1025, 1639 mobileBP = 768, 1640 tabletSlides, mobileSlides, defaultOptions, slickOptions; 1641 1642 options = JetEngine.ensureJSON( options ); 1643 1644 customOptions = customOptions || {}; 1645 1646 options = $.extend( {}, options, customOptions ); 1647 1648 if ( $eWidget.length ) { 1649 1650 var settings = JetEngine.getElementorElementSettings( $eWidget ), 1651 responsive = [], 1652 deviceMode = elementorFrontend.getCurrentDeviceMode(), 1653 eBreakpoints = window.elementorFrontend.config.responsive.activeBreakpoints; 1654 1655 options.slidesToShow = settings.columns_widescreen ? +settings.columns_widescreen : +settings.columns; 1656
1657 Object.keys( eBreakpoints ).reverse().forEach( function( breakpointName ) { 1658 1659 if ( settings['columns_' + breakpointName] ) { 1660 1661 if ( 'widescreen' === breakpointName ) { 1662 1663 responsive.push( { 1664 breakpoint: eBreakpoints[breakpointName].value, 1665 settings: { 1666 slidesToShow: +settings['columns'], 1667 } 1668 } ); 1669 1670 } else { 1671 var breakpointSettings = { 1672 breakpoint: eBreakpoints[breakpointName].value + 1, 1673 settings: { 1674 slidesToShow: +settings['columns_' + breakpointName], 1675 } 1676 }; 1677 1678 if ( options.slidesToScroll > breakpointSettings.settings.slidesToShow ) { 1679 breakpointSettings.settings.slidesToScroll = breakpointSettings.settings.slidesToShow; 1680 } 1681 1682 // if ( 'mobile' === breakpointName ) { 1683 // breakpointSettings.settings.slidesToScroll = 1; 1684 // } 1685 1686 responsive.push( breakpointSettings ); 1687 } 1688 } 1689 1690 } ); 1691 1692 options.responsive = responsive; 1693 1694 } else { 1695 1696 // Ensure we have at least some options to avoid errors 1697 if ( ! options.slidesToShow ) { 1698 options.slidesToShow = { 1699 desktop: 3, 1700 tablet: 1, 1701 mobile: 1, 1702 } 1703 } 1704 1705 if ( options.itemsCount <= options.slidesToShow.desktop && windowWidth >= tabletBP ) { // 1025 - ... 1706 $slider.removeClass( 'jet-listing-grid__slider' ); 1707 return; 1708 } else if ( options.itemsCount <= options.slidesToShow.tablet && tabletBP > windowWidth && windowWidth >= mobileBP ) { // 768 - 1024 1709 $slider.removeClass( 'jet-listing-grid__slider' ); 1710 return; 1711 } else if ( options.itemsCount <= options.slidesToShow.mobile && windowWidth < mobileBP ) { // 0 - 767 1712 $slider.removeClass( 'jet-listing-grid__slider' ); 1713 return; 1714 } 1715 1716 if ( options.slidesToShow.tablet ) { 1717 tabletSlides = options.slidesToShow.tablet; 1718 } else { 1719 tabletSlides = 1 === options.slidesToShow.desktop ? 1 : 2; 1720 } 1721 1722 if ( options.slidesToShow.mobile ) { 1723 mobileSlides = options.slidesToShow.mobile; 1724 } else { 1725 mobileSlides = 1; 1726 } 1727 1728 options.slidesToShow = options.slidesToShow.desktop; 1729 1730 options.responsive = [ 1731 { 1732 breakpoint: 1025, 1733 settings: { 1734 slidesToShow: tabletSlides, 1735 slidesToScroll: options.slidesToScroll > tabletSlides ? tabletSlides : options.slidesToScroll 1736 } 1737 }, 1738 { 1739 breakpoint: 768, 1740 settings: { 1741 slidesToShow: mobileSlides, 1742 slidesToScroll: 1 1743 } 1744 } 1745 ]; 1746 } 1747 1748 defaultOptions = { 1749 customPaging: function( slider, i ) { 1750 return $( '<span />' ).text( i + 1 ).attr( 'role', 'tab' ); 1751 }, 1752 slide: '.jet-listing-grid__item', 1753 dotsClass: 'jet-slick-dots', 1754 }; 1755 1756 slickOptions = $.extend( {}, defaultOptions, options ); 1757 1758 var $sliderItems = $slider.find( '> .jet-listing-grid__items' ); 1759 1760 if ( slickOptions.infinite ) { 1761 $sliderItems.on( 'init', function() { 1762 var $items = $( this ), 1763 $clonedSlides = $( '> .slick-list > .slick-track > .slick-cloned.jet-listing-grid__item', $items ); 1764 1765 if ( !$clonedSlides.length ) { 1766 return; 1767 } 1768 1769 JetEngine.initElementsHandlers( $clonedSlides ); 1770 1771 if ( $slider.find('.bricks-lazy-hidden').length ) { 1772 bricksLazyLoad(); 1773 } 1774 } ); 1775 } 1776 1777 // Temporary solution issue with Lazy Load images + RTL on Chrome. 1778 // Remove after fix in Chrome. 1779 // See: https://github.com/Crocoblock/issues-tracker/issues/7552 1780 if ( slickOptions.rtl ) { 1781 $sliderItems.on( 'init', function() { 1782 var $items = $( this ), 1783 $lazyImages = $( 'img[loading=lazy]', $items ), 1784 lazyImageObserver = new IntersectionObserver( 1785 function( entries, observer ) { 1786 entries.forEach( function( entry ) { 1787 if ( entry.isIntersecting ) { 1788 // If an image does not load, need to remove the `loading` attribute. 1789 if ( ! entry.target.complete ) { 1790 entry.target.removeAttribute( 'loading' ); 1791 } 1792 1793 // Detach observer 1794 observer.unobserve( entry.target ); 1795 } 1796 } ); 1797 } 1798 ); 1799 1800 $lazyImages.each( function() { 1801 const $img = $( this ); 1802 lazyImageObserver.observe( $img[0] ); 1803 } ); 1804 } ); 1805 } 1806 1807 if ( $sliderItems.hasClass( 'slick-initialized' ) ) { 1808 $sliderItems.slick( 'refresh', true ); 1809 return; 1810 } 1811 1812 if ( slickOptions.variableWidth ) { 1813 slickOptions.slidesToShow = 1; 1814 slickOptions.slidesToScroll = 1; 1815 slickOptions.responsive = null; 1816 } 1817 1818 $sliderItems.slick( slickOptions ); 1819 }, 1820 1821 maybeReinitSlider: function( event, $scope ) { 1822 var $slider = $scope.find( '.jet-listing-grid__slider' ); 1823 1824 if ( $slider.length ) { 1825 $slider.each( function() { 1826 JetEngine.initSlider( $( this ) ); 1827 } ); 1828 } 1829 }, 1830 1831 widgetDynamicField: function( $scope ) { 1832 1833 var $slider = $scope.find( '.jet-engine-gallery-slider' ); 1834 1835 if ( $slider.length ) { 1836 if ( $.isFunction( $.fn.imagesLoaded ) ) {
1837 $slider.imagesLoaded().always( function( instance ) { 1838 1839 var $eWidget = $slider.closest( '.elementor-widget' ); 1840 1841 if ( $slider.hasClass( 'slick-initialized' ) ) { 1842 $slider.slick( 'refresh', true ); 1843 } else { 1844 var atts = $slider.data( 'atts' ); 1845 1846 atts = JetEngine.ensureJSON( atts ); 1847 1848 if ( $eWidget.length ) { 1849 var settings = JetEngine.getElementorElementSettings( $scope ), 1850 eBreakpoints = window.elementorFrontend.config.responsive.activeBreakpoints, 1851 responsive = []; 1852 1853 if ( settings.img_slider_cols || settings.img_slider_cols_widescreen ) { 1854 atts.slidesToShow = settings.img_slider_cols_widescreen ? +settings.img_slider_cols_widescreen : +settings.img_slider_cols; 1855 } 1856 1857 Object.keys( eBreakpoints ).reverse().forEach( function( breakpointName ) { 1858 1859 if ( settings['img_slider_cols_' + breakpointName] ) { 1860 1861 if ( 'widescreen' === breakpointName ) { 1862 1863 responsive.push( { 1864 breakpoint: eBreakpoints[breakpointName].value, 1865 settings: { 1866 slidesToShow: +settings['img_slider_cols'], 1867 } 1868 } ); 1869 1870 } else { 1871 var breakpointSettings = { 1872 breakpoint: eBreakpoints[breakpointName].value + 1, 1873 settings: { 1874 slidesToShow: +settings['img_slider_cols_' + breakpointName], 1875 } 1876 }; 1877 1878 responsive.push( breakpointSettings ); 1879 } 1880 } 1881 1882 } ); 1883 1884 atts.responsive = responsive; 1885 } 1886 1887 $slider.slick( atts ); 1888 } 1889 } ); 1890 } 1891 } 1892 1893 $slider.on('init', function (event, slick) { 1894 1895 const slider = event.target; 1896 1897 if (!slider.classList.contains('jet-engine-gallery-lightbox')) { 1898 return; 1899 } 1900 1901 let lightbox = new PhotoSwipeLightbox({ 1902 mainClass: 'brx', 1903 gallery: slider, 1904 children: 'a', 1905 showHideAnimationType: 'none', 1906 zoomAnimationDuration: false, 1907 pswpModule: PhotoSwipe5, 1908 }); 1909 1910 lightbox.addFilter('numItems', numItems => slick.slideCount); 1911 1912 lightbox.addFilter('clickedIndex', function (clickedIndex, e) { 1913 const slide = e.target.closest('.slick-slide'); 1914 1915 if (!slide) { 1916 return clickedIndex; 1917 } 1918 1919 if (clickedIndex >= slick.slideCount) { 1920 return clickedIndex % slick.slideCount; 1921 } 1922 1923 return clickedIndex; 1924 }); 1925 1926 lightbox.addFilter('thumbEl', (thumbnail, itemData, index) => { 1927 return thumbnail; 1928 }); 1929 1930 lightbox.addFilter('thumbBounds', (thumbBounds, itemData, index) => { 1931 return thumbBounds; 1932 }); 1933 1934 lightbox.init(); 1935 }); 1936 1937 // Masonry init 1938 var $masonry = $scope.find( '.jet-engine-gallery-grid--masonry' ); 1939 1940 if ( $masonry.length ) { 1941 JetEngine.initMasonry( $masonry, { 1942 columnsKey: 'img_columns', 1943 itemSelector: '> .jet-engine-gallery-grid__item', 1944 } ); 1945 } 1946 1947 }, 1948 1949 calendarCache: { 1950 1951 entries: {}, 1952 1953 //introduced because Firefox does not have forEach method for iterators 1954 iterate: function( iterator, callback ) { 1955 if ( typeof iterator?.forEach === 'function' ) { 1956 iterator.forEach( callback ); 1957 } else if ( typeof iterator?.next === 'function' ) { 1958 let next; 1959 while ( next = iterator.next(), ! next.done ) { 1960 callback.call( this, next.value ); 1961 } 1962 } 1963 }, 1964 1965 get: function ( cacheId, month ) { 1966 return JetEngine.calendarCache.entries[ cacheId ]?.get( month ) || false; 1967 }, 1968 1969 set: function ( cacheId, month, content, settings = {}, timestamp = false ) { 1970 if ( ! JetEngine.calendarCache.entries[ cacheId ] ) { 1971 JetEngine.calendarCache.entries[ cacheId ] = new Map(); 1972 } 1973 1974 if ( ! JetEngine.calendarCache.entries[ cacheId ].has( month ) 1975 && JetEngine.calendarCache.entries[ cacheId ].size > ( settings['max_cache'] ?? 12 ) - 1 1976 ) { 1977 let deletedKey; 1978 1979 const mapKeys = JetEngine.calendarCache.entries[ cacheId ].keys(); 1980 1981 if ( settings['__switch_direction'] < 0 ) { 1982 let maxDate = false; 1983 1984 JetEngine.calendarCache.iterate( 1985 mapKeys, 1986 function ( key ) { 1987 const parsedDate = Date.parse( key ); 1988 1989 if ( ! maxDate || parsedDate > maxDate ) { 1990 maxDate = parsedDate; 1991 deletedKey = key; 1992 } 1993 } 1994 ); 1995 } else { 1996 let minDate = false;
1997 1998 JetEngine.calendarCache.iterate( 1999 mapKeys, 2000 function ( key ) { 2001 const parsedDate = Date.parse( key ); 2002 2003 if ( ! minDate || parsedDate < minDate ) { 2004 minDate = parsedDate; 2005 deletedKey = key; 2006 } 2007 } 2008 ); 2009 } 2010 2011 JetEngine.calendarCache.entries[ cacheId ].delete( deletedKey ); 2012 } 2013 2014 if ( ! timestamp ) { 2015 timestamp = Date.now(); 2016 } 2017 2018 JetEngine.calendarCache.entries[ cacheId ].set( month, [ content, timestamp ] ); 2019 }, 2020 2021 update: function ( cacheId, month, content, settings = {} ) { 2022 let cached = JetEngine.calendarCache.get( cacheId, month ); 2023 JetEngine.calendarCache.set( cacheId, month, content, settings, cached[1] ?? false ); 2024 }, 2025 2026 deleteExpiredEntries: function ( cacheId, cacheTimeout ) { 2027 //delete possible orphaned caches 2028 for ( const cacheId in JetEngine.calendarCache.entries ) { 2029 if ( ! document.querySelector( `.jet-calendar[data-cache-id="${cacheId}"]` ) ) { 2030 delete JetEngine.calendarCache.entries[ cacheId ]; 2031 } 2032 } 2033 2034 if ( ! JetEngine.calendarCache.entries[ cacheId ] ) { 2035 return; 2036 } 2037 2038 JetEngine.calendarCache.iterate( 2039 JetEngine.calendarCache.entries[ cacheId ].keys(), 2040 function ( month ) { 2041 if ( JetEngine.calendarCache.isExpired( cacheId, month, cacheTimeout ) ) { 2042 JetEngine.calendarCache.entries[ cacheId ].delete( month ); 2043 } 2044 } 2045 ); 2046 }, 2047 2048 isExpired: function ( cacheId, month, cacheTimeout ) { 2049 if ( cacheTimeout < 0 ) { 2050 return false; 2051 } 2052 2053 const cached = JetEngine.calendarCache.get( cacheId, month ); 2054 2055 if ( ! cached || ! Array.isArray( cached ) ) { 2056 return true; 2057 } 2058 2059 return ! cached[1] || cached[1] < Date.now() - cacheTimeout; 2060 }, 2061 2062 clear: function( e, $calendar ) { 2063 const cacheId = $calendar.data( 'cache-id' ) || false; 2064 2065 if ( ! cacheId ) { 2066 return; 2067 } 2068 2069 JetEngine.calendarCache.entries[ cacheId ] = new Map(); 2070 }, 2071 2072 modifyJetSmartFiltersSetiings: function( $widget, widgetType, monthData ) { 2073 if ( ! window.JetSmartFilterSettings || ! window.JetSmartFilterSettings.settings ) { 2074 return; 2075 } 2076 2077 if ( ! window.JetSmartFilterSettings.settings['jet-engine-calendar'] ) { 2078 return; 2079 } 2080 2081 monthData = monthData.split( ' ' ); 2082
2083 const month = monthData[0], 2084 year = monthData[1]; 2085 2086 let widgetId; 2087 2088 switch ( widgetType ) { 2089 case 'block': 2090 widgetId = $widget.closest( '.jet-listing-calendar-block' )[0].id; 2091 2092 if ( ! widgetId ) { 2093 widgetId = 'default'; 2094 } 2095 2096 if ( window.JetSmartFilterSettings.settings['jet-engine-calendar'][ widgetId ] ) { 2097 window.JetSmartFilterSettings.settings['jet-engine-calendar'][ widgetId ]['start_from_month'] = month; 2098 window.JetSmartFilterSettings.settings['jet-engine-calendar'][ widgetId ]['start_from_year'] = year; 2099 } 2100 2101 break; 2102 case 'bricks': 2103 widgetId = $widget.data( 'element-id' ); 2104 2105 if ( ! widgetId ) { 2106 break; 2107 } 2108 2109 for ( const id in window.JetSmartFilterSettings.settings['jet-engine-calendar'] ) { 2110 if ( window.JetSmartFilterSettings.settings['jet-engine-calendar'][ id ]?._id === widgetId ) { 2111 window.JetSmartFilterSettings.settings['jet-engine-calendar'][ id ]['start_from_month'] = month; 2112 window.JetSmartFilterSettings.settings['jet-engine-calendar'][ id ]['start_from_year'] = year; 2113 break; 2114 } 2115 } 2116 2117 break; 2118 case 'elementor': 2119 widgetId = $widget.closest( '.elementor-widget-jet-listing-calendar' )[0].id; 2120 2121 if ( ! widgetId ) { 2122 widgetId = 'default'; 2123 } 2124 2125 if ( window.JetSmartFilterSettings.settings['jet-engine-calendar']?.[ widgetId ] ) { 2126 window.JetSmartFilterSettings.settings['jet-engine-calendar'][ widgetId ]['start_from_month'] = month; 2127 window.JetSmartFilterSettings.settings['jet-engine-calendar'][ widgetId ]['start_from_year'] = year; 2128 } 2129 2130 break; 2131 } 2132 }, 2133 }, 2134 2135 selectCalendarMonth: function ( $event ) { 2136 let wrapper = this.closest( '.jet-calendar-caption__dates' ); 2137 2138 if ( ! JetEngine.updateDateSelectLabels( wrapper ) ) { 2139 return; 2140 } 2141 2142 JetEngine.switchCalendarMonth.bind( wrapper )() 2143 }, 2144 2145 updateDateSelectLabels: function( wrapper ) { 2146 let month = wrapper.querySelector( '.jet-calendar-caption__date-select.select-month' ), 2147 year = wrapper.querySelector( '.jet-calendar-caption__date-select.select-year' ); 2148 2149 if ( ! month || ! year ) { 2150 return false; 2151 } 2152 2153 let monthLabel = wrapper.querySelector( '.jet-calendar-caption__date-select-label.select-month' ), 2154 yearLabel = wrapper.querySelector( '.jet-calendar-caption__date-select-label.select-year' ); 2155 2156 wrapper.setAttribute( 'data-month', month.value + ' ' + year.value ); 2157 2158 const monthOption = month.querySelector( `option[value="${month.value}"]` ), 2159 yearOption = year.querySelector( `option[value="${year.value}"]` ); 2160 2161 monthLabel.innerHTML = monthOption.innerHTML; 2162 yearLabel.innerHTML = yearOption.innerHTML; 2163 2164 return true; 2165 }, 2166 2167 switchCalendarMonth: function( $event ) { 2168 2169 var $this = $( this ), 2170 $calendar = $this.closest( '.jet-calendar' ), 2171 $widget = $calendar.closest( '.elementor-widget-container' ), 2172 settings = $calendar.data( 'settings' ), 2173 post = $calendar.data( 'post' ), 2174 month = $this.data( 'month' ); 2175 2176 settings = JetEngine.ensureJSON( settings ); 2177 2178 if ( this.classList.contains( 'nav-link-prev' ) ) { 2179 settings['__switch_direction'] = -1; 2180 } else if ( this.classList.contains( 'nav-link-next' ) ) { 2181 settings['__switch_direction'] = 1; 2182 } else { 2183 settings['__switch_direction'] = 0; 2184 } 2185 2186 let widgetType = 'elementor'; 2187 2188 // Context Gutenberg 2189 if ( ! $widget.length ) { 2190 $widget = $calendar.closest( '.jet-listing-calendar-block' ); 2191 widgetType = 'block'; 2192 } 2193 2194 // Context Bricks 2195 if ( ! $widget.length ) { 2196 $widget = $calendar.closest( '.brxe-jet-listing-calendar' ) 2197 widgetType = 'bricks'; 2198 } 2199 2200 JetEngine.calendarCache.modifyJetSmartFiltersSetiings( $widget, widgetType, month ); 2201 2202 const cacheId = $calendar.data( 'cache-id' ) || false, 2203 cacheTimeout = ( settings['cache_timeout'] ?? 0 ) * 1000; 2204 2205 if ( cacheId && cacheTimeout ) { 2206 2207 JetEngine.calendarCache.deleteExpiredEntries( cacheId, cacheTimeout ); 2208 2209 // Remove the 'listening' and 'brx-open' classes from all matched elements to prevent 2210 // reinitialization issues in the accordion. 2211 if ( window.bricksIsFrontend ) { 2212 $calendar.find('.accordion-item.listening, .brxe-accordion-nested > .listening') 2213 .removeClass('listening brx-open'); 2214 } 2215 2216 JetEngine.calendarCache.update( cacheId, settings['prev_month'], $calendar.prop('outerHTML'), settings ); 2217 2218 const cached = JetEngine.calendarCache.get( cacheId, month ); 2219 2220 if ( cached?.length && cached[0] && ! JetEngine.calendarCache.isExpired( cacheId, month, cacheTimeout ) ) { 2221 let replacement = $( cached[0] ); 2222 replacement.removeClass( 'jet-calendar-loading' ); 2223 $calendar.replaceWith( replacement[0] ); 2224 JetEngine.initElementsHandlers( $widget ); 2225 JetEngine.updateDateSelectLabels( $widget[0] ); 2226 // Re-init Bricks scripts 2227 JetEngine.reinitBricksScripts(); 2228 2229 $( document ).trigger( 'jet-engine-request-calendar-cached', [ $widget ] ); 2230 2231 return; 2232 } 2233 } 2234 2235 $calendar.addClass( 'jet-calendar-loading' ); 2236 2237 JetEngine.currentRequest = { 2238 jet_engine_action: 'jet_engine_calendar_get_month', 2239 month: month, 2240 settings: settings, 2241 post: post, 2242 }; 2243 2244 $( document ).trigger( 'jet-engine-request-calendar' ); 2245 2246 $.ajax({ 2247 url: JetEngineSettings.ajaxlisting, 2248 type: 'POST', 2249 dataType: 'json', 2250 data: JetEngine.currentRequest, 2251 }).done( function( response ) { 2252 if ( response.success ) { 2253 $calendar.replaceWith( response.data.content ); 2254 2255 if ( cacheId && cacheTimeout ) { 2256 JetEngine.calendarCache.set( cacheId, month, response.data.content, settings ); 2257 } 2258 2259 JetEngine.initElementsHandlers( $widget ); 2260 // Re-init Bricks scripts 2261 JetEngine.reinitBricksScripts(); 2262 2263 $( document ).trigger( 'jet-engine-request-calendar-done', [ $widget ] ); 2264 } 2265 $calendar.removeClass( 'jet-calendar-loading' ); 2266 } ); 2267 }, 2268 2269 initElementsHandlers: function( $selector ) { 2270 2271 // Actual init 2272 window.JetPlugins.init( $selector ); 2273 2274 // Legacy Elementor-only init 2275 $selector.find( '[data-element_type]' ).each( function() { 2276 2277 var $this = $( this ), 2278 elementType = $this.data( 'element_type' ); 2279 2280 if ( !elementType ) { 2281 return; 2282 } 2283 2284 if ( ! window?.elementorFrontend?.hooks?.doAction ) { 2285 return; 2286 } 2287 2288 if ( 'widget' === elementType ) { 2289 elementType = $this.data( 'widget_type' ); 2290 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 2291 } 2292 2293 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 2294 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 2295 2296 } ); 2297 2298 if ( window.elementorFrontend ) { 2299 const elementorLazyLoad = new Event( "elementor/lazyload/observe" ); 2300 document.dispatchEvent( elementorLazyLoad ); 2301 } 2302 2303 if ( window.JetPopupFrontend && window.JetPopupFrontend.initAttachedPopups ) { 2304 window.JetPopupFrontend.initAttachedPopups( $selector ); 2305 } 2306 2307 }, 2308 2309 getElementorElementSettings: function( $scope ) { 2310 2311 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() && $scope.hasClass( 'elementor-element-edit-mode' ) ) { 2312 return JetEngine.getEditorElementSettings( $scope ); 2313 } 2314 2315 return $scope.data( 'settings' ) || {}; 2316 }, 2317 2318 getEditorElementSettings: function( $scope ) { 2319 var modelCID = $scope.data( 'model-cid' ), 2320 elementData; 2321 2322 if ( ! modelCID ) { 2323 return {}; 2324 } 2325 2326 if ( ! window.elementorFrontend.hasOwnProperty( 'config' ) ) { 2327 return {}; 2328 } 2329 2330 if ( ! window.elementorFrontend.config.hasOwnProperty( 'elements' ) ) { 2331 return {}; 2332 } 2333 2334 if ( ! window.elementorFrontend.config.elements.hasOwnProperty( 'data' ) ) { 2335 return {}; 2336 } 2337 2338 elementData = window.elementorFrontend.config.elements.data[ modelCID ]; 2339 2340 if ( ! elementData ) { 2341 return {}; 2342 } 2343 2344 return elementData.toJSON(); 2345 }, 2346 2347 debounce: function( threshold, callback ) { 2348 var timeout; 2349 2350 return function debounced( $event ) { 2351 function delayed() { 2352 callback.call( this, $event ); 2353 timeout = null; 2354 } 2355 2356 if ( timeout ) { 2357 clearTimeout( timeout ); 2358 } 2359 2360 timeout = setTimeout( delayed, threshold ); 2361 }; 2362 }, 2363 2364 updateAddedStyles: function() { 2365 if ( window.JetEngineSettings && window.JetEngineSettings.addedPostCSS ) { 2366 $.each( window.JetEngineSettings.addedPostCSS, function( ind, cssID ) {
2367 JetEngine.addedStyles.push( 'elementor-post-' + cssID ); 2368 JetEngine.addedPostCSS.push( cssID ); 2369 } ); 2370 } 2371 }, 2372 2373 enqueueAssetsFromResponse: function( response ) { 2374 if ( response.data.scripts ) { 2375 JetEngine.enqueueScripts( response.data.scripts ); 2376 } 2377 2378 if ( response.data.styles ) { 2379 JetEngine.enqueueStyles( response.data.styles ); 2380 } 2381 }, 2382 2383 enqueueScripts: function( scripts ) { 2384 $.each( scripts, function( handle, scriptHtml ) { 2385 JetEngine.enqueueScript( handle, scriptHtml ) 2386 } ); 2387 }, 2388 2389 enqueueStyles: function( styles ) { 2390 $.each( styles, function( handle, styleHtml ) { 2391 JetEngine.enqueueStyle( handle, styleHtml ) 2392 } ); 2393 }, 2394 2395 enqueueScript: function( handle, scriptHtml ) { 2396 2397 if ( -1 !== JetEngine.addedScripts.indexOf( handle ) ) { 2398 return; 2399 } 2400 2401 if ( ! scriptHtml ) { 2402 return; 2403 } 2404 2405 var selector = 'script[id="' + handle + '-js"]'; 2406 2407 if ( $( selector ).length ) { 2408 return; 2409 } 2410 2411 //$( 'body' ).append( scriptHtml ); 2412 2413 var scriptsTags = scriptHtml.match( /<script[\s\S]*?<\/script>/gm ); 2414 2415 if ( scriptsTags.length ) { 2416 2417 for ( var i = 0; i < scriptsTags.length; i++ ) { 2418 2419 JetEngine.assetsPromises.push( 2420 new Promise( function( resolve, reject ) { 2421 2422 var $tag = $( scriptsTags[i] ); 2423 2424 if ( $tag[0].src ) { 2425 2426 var tag = document.createElement( 'script' ); 2427 2428 tag.type = $tag[0].type; 2429 tag.src = $tag[0].src; 2430 tag.id = $tag[0].id; 2431 tag.async = false; 2432 tag.onload = function() { 2433 resolve(); 2434 }; 2435 2436 document.body.append( tag ); 2437 } else { 2438 $( 'body' ).append( scriptsTags[i] ); 2439 resolve(); 2440 } 2441 } ) 2442 ); 2443 } 2444 } 2445 2446 JetEngine.addedScripts.push( handle ); 2447 }, 2448 2449 enqueueStyle: function( handle, styleHtml ) { 2450 2451 if ( -1 !== handle.indexOf( 'google-fonts' ) ) { 2452 JetEngine.enqueueGoogleFonts( handle, styleHtml ); 2453 return; 2454 } 2455 2456 if ( -1 !== JetEngine.addedStyles.indexOf( handle ) ) { 2457 return; 2458 } 2459 2460 var selector = 'link[id="' + handle + '-css"],style[id="' + handle + '"]'; 2461 2462 if ( $( selector ).length ) { 2463 return; 2464 } 2465 2466 $( 'head' ).append( styleHtml ); 2467 2468 JetEngine.addedStyles.push( handle ); 2469 2470 if ( -1 !== handle.indexOf( 'elementor-post' ) ) { 2471 var postID = handle.replace( 'elementor-post-', '' ); 2472 JetEngine.addedPostCSS.push( postID ); 2473 } 2474 }, 2475 2476 enqueueGoogleFonts: function( handle, styleHtml ) { 2477 2478 var selector = 'link[id="' + handle + '-css"]'; 2479 2480 if ( $( selector ).length ) {} 2481 2482 $( 'head' ).append( styleHtml ); 2483 }, 2484 2485 isFrontend: function () { 2486 // Check the Elementor 2487 if (typeof window.elementorFrontend !== 'undefined') { 2488 return !window.elementorFrontend.isEditMode(); 2489 } 2490 2491 // Check the Bricks 2492 if (typeof window.bricksIsFrontend !== 'undefined') { 2493 return window.bricksIsFrontend; 2494 } 2495 2496 // If no builders are found, we assume it is frontend. 2497 return true; 2498 }, 2499 2500 reinitBricksScripts: function() { 2501 if ( window.bricksIsFrontend ) { 2502 document.dispatchEvent( 2503 new CustomEvent("bricks/ajax/query_result/displayed") 2504 ); 2505 } 2506 }, 2507 2508 filters: ( function() { 2509 2510 var callbacks = {}; 2511 2512 return { 2513 2514 addFilter: function( name, callback ) { 2515 2516 if ( ! callbacks.hasOwnProperty( name ) ) { 2517 callbacks[name] = []; 2518 } 2519 2520 callbacks[name].push(callback); 2521 2522 }, 2523 2524 applyFilters: function( name, value, args ) { 2525 2526 if ( ! callbacks.hasOwnProperty( name ) ) { 2527 return value; 2528 } 2529 2530 if ( args === undefined ) { 2531 args = []; 2532 } 2533 2534 var container = callbacks[ name ]; 2535 var cbLen = container.length; 2536 2537 for (var i = 0; i < cbLen; i++) { 2538 if (typeof container[i] === 'function') { 2539 value = container[i](value, args); 2540 } 2541 } 2542 2543 return value; 2544 } 2545 2546 }; 2547 2548 })() 2549 2550 }; 2551 2552 $( window ).on( 'elementor/frontend/init', JetEngine.init ); 2553 2554 window.JetEngine = JetEngine; 2555 2556 document.addEventListener( 'jet-smart-filters/inited', function() { 2557 window.JetSmartFilters.events.subscribe( 'ajaxFilters/updated', function( provider, queryId ) { 2558 window.JetEngine.initFrontStores( window.JetSmartFilters?.filterGroups?.[ provider + '/' + queryId ]?.$provider); 2559 } ); 2560 } ); 2561 2562 JetEngine.commonInit(); 2563 2564 window.addEventListener( 'DOMContentLoaded', function() { 2565 setTimeout( () => JetEngine.initBlocks() ); 2566 JetEngine.initDone = true; 2567 } ); 2568 2569 window.jetEngineBricks = function() { 2570 JetEngine.initBricks(); 2571 } 2572 2573 $( window ).trigger( 'jet-engine/frontend/loaded' ); 2574 2575}( 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.