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