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