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