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