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