1( function( $, elementor ) { 2 3 'use strict'; 4 5 var JetTricks = { 6 7 init: function() { 8 var frontend = window.elementorFrontend || elementor; 9 10 if ( ! frontend || ! frontend.hooks ) { 11 return; 12 } 13 14 frontend.hooks.addAction( 'frontend/element_ready/section', JetTricks.elementorSection ); 15 frontend.hooks.addAction( 'frontend/element_ready/section', JetTricks.elementorColumn ); 16 frontend.hooks.addAction( 'frontend/element_ready/section', JetTricks.elementorWidget ); 17 frontend.hooks.addAction( 'frontend/element_ready/container', JetTricks.elementorSection ); 18 frontend.hooks.addAction( 'frontend/element_ready/container', JetTricks.elementorColumn ); 19 frontend.hooks.addAction( 'frontend/element_ready/column', JetTricks.elementorColumn ); 20 frontend.hooks.addAction( 'frontend/element_ready/column', JetTricks.elementorWidget ); 21 frontend.hooks.addAction( 'frontend/element_ready/widget', JetTricks.elementorWidget ); 22 frontend.hooks.addAction( 'frontend/element_ready/container', JetTricks.elementorWidget ); 23 24 var widgets = { 25 'jet-view-more.default' : JetTricks.widgetViewMore, 26 'jet-unfold.default' : JetTricks.widgetUnfold, 27 'jet-hotspots.default' : JetTricks.widgetHotspots 28 }; 29 30 $.each( widgets, function( widget, callback ) { 31 frontend.hooks.addAction( 'frontend/element_ready/' + widget, callback ); 32 }); 33 34 // Re-init widgets in nested tabs 35 if ( frontend.elements && frontend.elements.$window ) { 36 frontend.elements.$window.on( 37 'elementor/nested-tabs/activate', 38 ( event, content ) => { 39 40 const $content = $( content ); 41 42 var $button = $content.find( '.jet-unfold__button' ); 43 44 $button.off( 'click.jetUnfold' ); 45 46 JetTricks.initWidgetsHandlers( $content ); 47 JetTricks.elementorSection( $content ); 48 49 } 50 ); 51 } 52 53 // Add an action when the Swiper Loop Carousel widget is ready on the frontend 54 var loopCarouselTypes = [ 55 'loop-carousel.post', 56 'loop-carousel.product', 57 'loop-carousel.post_taxonomy', 58 'loop-carousel.product_taxonomy' 59 ]; 60 61 loopCarouselTypes.forEach( function( carouselType ) { 62 frontend.hooks.addAction( 'frontend/element_ready/' + carouselType, function( $scope, $ ) { 63 64 $( window ).on( 'load', function() { 65 var loopCarousel = $scope.find( '.swiper' ), 66 swiperInstance = loopCarousel.data( 'swiper' ), 67 $button = $scope.find( '.jet-unfold__button' ); 68 69 if ( swiperInstance && $button ) { 70 71 $button.off( 'click.jetUnfold' ); 72 JetTricks.initLoopCarouselHandlers( $scope ); 73 74 swiperInstance.on( 'slideChange', function() { 75 $button.off( 'click.jetUnfold' ); 76 JetTricks.initLoopCarouselHandlers( $scope ); 77 }); 78 } 79 }); 80 }); 81 }); 82 }, 83 84 getDeviceMode: function() { 85 if ( window.elementorFrontend && typeof window.elementorFrontend.getCurrentDeviceMode === 'function' ) { 86 return window.elementorFrontend.getCurrentDeviceMode(); 87 } 88 var w = window.innerWidth || document.documentElement.clientWidth || 0; 89 if ( w < 768 ) { 90 return 'mobile'; 91 } 92 if ( w < 1025 ) { 93 return 'tablet'; 94 } 95 return 'desktop'; 96 console.log( 'JetTricks.getDeviceMode', w ); 97 }, 98 99 initLoopCarouselHandlers: function( $selector ) { 100 $selector.find( '.elementor-widget-jet-unfold' ).each( function() { 101 102 var $this = $( this ), 103 104 elementType = $this.data( 'element_type' ); 105 106 if ( !elementType ) { 107 return; 108 } 109 110 if ( 'widget' === elementType ) { 111 elementType = $this.data( 'widget_type' ); 112 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 113 } 114 115 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 116 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 117 118 119 } ); 120 }, 121 122 initWidgetsHandlers: function( $selector ) { 123 124 $selector.find( '[data-element_type]' ).each( function() { 125 126 var excludeWidgets = [ 127 'jet-woo-product-gallery-slider.default', 128 'accordion.default', 129 'jet-form-builder-form.default', 130 'nav-menu.default' 131 ]; 132 133 var $this = $( this ), 134 135 elementType = $this.data( 'element_type' ); 136 137 if ( !elementType ) { 138 return; 139 } 140 141 if ( 'widget' === elementType ) { 142 143 elementType = $this.data( 'widget_type' ); 144 145 if ( excludeWidgets.includes( elementType ) ) { 146 return; 147 } 148 149 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 150 } 151 152 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 153 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 154 155 156 } ); 157 }, 158 159 loadParticles: function( $scope, instanceId, jsonConfig ) { 160 $scope.prepend( '<div id="' + instanceId + '" class="jet-tricks-particles-section__instance"></div>' ); 161 162 if ( typeof tsParticles !== 'undefined' && tsParticles.load ) { 163 if ( tsParticles.version && tsParticles.version.startsWith( '3.' ) ) { 164 tsParticles.load( { id: instanceId, options: jsonConfig } ); 165 } else { 166 tsParticles.load( instanceId, jsonConfig ); 167 } 168 } 169 }, 170 171 elementorSection: function( $scope ) { 172 var $target = $scope, 173 sectionId = $scope.data( 'id' ),
174 editMode = Boolean( elementor && elementor.isEditMode() ), 175 jetListing = $target.parents( '.elementor-widget-jet-listing-grid' ).data( 'id' ), 176 settings = {}; 177 178 if ( window.JetTricksSettings && window.JetTricksSettings.elements_data.sections.hasOwnProperty( sectionId ) ) { 179 settings = window.JetTricksSettings.elements_data.sections[ sectionId ]; 180 } 181 182 if ( editMode ) { 183 settings = JetTricks.sectionEditorSettings( $scope ); 184 } 185 186 if ( ! settings ) { 187 return false; 188 } 189 190 if ( jQuery.isEmptyObject( settings ) ) { 191 return false; 192 } 193 194 if ( 'false' === settings.particles || '' === settings.particles_json ) { 195 return false; 196 } 197 198 // Compatibility jet tricks particles with jet listing 199 200 if ( jetListing && $target.parent().data( 'elementor-type' ) === 'jet-listing-items' ){ 201 sectionId += jetListing + $target.parents( '.jet-listing-grid__item' ).data( 'post-id' ); 202 } 203 204 JetTricks.loadParticles( $scope, 'jet-tricks-particles-instance-' + sectionId, JSON.parse( settings.particles_json ) ); 205 206 }, 207 208 elementorColumn: function( $scope ) { 209 var $target = $scope, 210 $parentSection = $scope.closest( '.elementor-section' ), 211 isLegacyModeActive = !!$target.find( '> .elementor-column-wrap' ).length, 212 $window = $( window ), 213 columnId = $target.data( 'id' ), 214 editMode = Boolean( elementor && elementor.isEditMode() ), 215 settings = {}, 216 stickyInstance = null, 217 stickyInstanceOptions = { 218 topSpacing: 50, 219 bottomSpacing: 50, 220 containerSelector: isLegacyModeActive ? '.elementor-row' : '.elementor-container, .e-con-inner', 221 innerWrapperSelector: isLegacyModeActive ? '.elementor-column-wrap' : '.elementor-widget-wrap', 222 }, 223 $observerTarget = $target.find('.elementor-element'); 224 225 if ( ! editMode ) { 226 settings = $target.data( 'jet-settings' ); 227 228 if ( $target.hasClass( 'jet-sticky-column' ) ) { 229 if ( -1 !== settings['stickyOn'].indexOf( JetTricks.getDeviceMode() ) ) { 230 $target.each( function() { 231 var $this = $( this ), 232 elementType = $this.data( 'element_type' ); 233 234 if ( settings['behavior'] === 'fixed' ) { 235 initFixedSticky( $this, settings ); 236 } else if ( elementType !== 'container' && elementType !== 'section' ) { 237 initSidebarSticky( $this, settings, stickyInstanceOptions ); 238 } else if ( settings['behavior'] === 'scroll_until_end' ) { 239 initScrollUntilEndSticky( $this, settings ); 240 } else { 241 initDefaultSticky( $this, settings ); 242 } 243 }); 244 } 245 } 246 } 247 248 function initFixedSticky($element, settings) { 249 var offsetTop = parseInt(settings['topSpacing']) || 0; 250 var bottomSpacing = parseInt(settings['bottomSpacing']) || 0; 251 var $window = $(window); 252 var elementId = $element.data('id'); 253 var originalOffsetTop = $element.offset().top; 254 var originalHeight = $element.outerHeight(); 255 var scrollVisibility = settings['scrollVisibility'] || 'both'; 256 var scrollOffset = parseInt( settings['scrollOffset'], 10 ); 257 var lastScrollTop = $window.scrollTop(); 258 var lastDirection = null; 259 260 if ( isNaN( scrollOffset ) || scrollOffset < 0 ) { 261 scrollOffset = 12; 262 } 263 264 var $allStickyElements = $('.jet-sticky-column').filter(function() { 265 var $this = $(this); 266 var elementSettings = $this.data('jet-settings'); 267 268 return elementSettings && elementSettings.stickyOn.indexOf( JetTricks.getDeviceMode() ) !== -1; 269 }); 270 271 var currentIndex = $allStickyElements.index($element); 272 var $nextSticky = currentIndex + 1 < $allStickyElements.length ? $allStickyElements.eq(currentIndex + 1) : null; 273 var $stopper = null; 274 if ($nextSticky) { 275 $stopper = $nextSticky.closest('.elementor-top-section, .e-parent'); 276 if (!$stopper.length) { 277 $stopper = $nextSticky; 278 } 279 } 280 281 const $placeholder = $('<div></div>') 282 .addClass('jet-sticky-placeholder') 283 .css({ 284 display: 'none', 285 height: originalHeight, 286 width: $element.outerWidth(), 287 visibility: 'hidden' 288 }); 289 290 $element.before($placeholder); 291 292 $element.css({ 293 '--jet-tricks-sticky-offset': offsetTop + 'px', 294 }); 295 296 function withTransitionDisabled( callback ) { 297 $element.addClass( 'jet-sticky-container--no-transition' ); 298 callback(); 299 300 requestAnimationFrame( function() { 301 requestAnimationFrame( function() { 302 $element.removeClass( 'jet-sticky-container--no-transition' ); 303 } ); 304 } ); 305 } 306 307 function enableSticky() { 308 $placeholder.show(); 309 $element.addClass('jet-sticky-container--stuck'); 310 311 var stopperTop = $stopper?.offset()?.top; 312 var stopPoint = stopperTop ? (stopperTop - $element.outerHeight() - offsetTop - bottomSpacing) : null; 313 var diff = 0; 314 315 if (stopPoint && stopPoint < $window.scrollTop()) { 316 diff = (stopPoint - $window.scrollTop()); 317 } 318 319 $element.css({ 320 position: 'fixed', 321 top: diff + 'px', 322 left: $placeholder.offset().left + 'px', 323 width: $placeholder.outerWidth() + 'px', 324 zIndex: settings['zIndex'] || '' 325 }); 326 } 327 328 function disableSticky() { 329 $placeholder.hide(); 330 $element.removeClass('jet-sticky-container--stuck jet-sticky-container--hidden jet-sticky-container--scrolled'); 331 332 $element.css({ 333 position: '', 334 top: '', 335 left: '', 336 width: '', 337 zIndex: '' 338 }); 339 } 340 341 function updateStickyState( direction, isScrolled ) { 342 var shouldHide = false;
343 344 if ( ! isScrolled ) { 345 withTransitionDisabled( function() { 346 $element.removeClass( 'jet-sticky-container--hidden jet-sticky-container--scrolled' ); 347 } ); 348 return; 349 } 350 351 if ( ! direction ) { 352 $element.removeClass( 'jet-sticky-container--hidden' ); 353 $element.toggleClass( 'jet-sticky-container--scrolled', !! isScrolled ); 354 return; 355 } 356 357 if ( scrollVisibility === 'up' ) { 358 shouldHide = direction === 'down'; 359 } else if ( scrollVisibility === 'down' ) { 360 shouldHide = direction === 'up'; 361 } 362 363 $element.toggleClass( 'jet-sticky-container--hidden', shouldHide ); 364 $element.toggleClass( 'jet-sticky-container--scrolled', !! isScrolled ); 365 } 366 367 function onScroll() { 368 var scrollTop = $window.scrollTop(); 369 var isScrolled = scrollTop > scrollOffset; 370 371 if ( Math.abs( scrollTop - lastScrollTop ) >= scrollOffset ) { 372 lastDirection = scrollTop > lastScrollTop ? 'down' : 'up'; 373 lastScrollTop = scrollTop; 374 } 375 376 if (scrollTop >= originalOffsetTop) { 377 enableSticky(); 378 updateStickyState( lastDirection, isScrolled ); 379 } else { 380 disableSticky(); 381 lastScrollTop = scrollTop; 382 } 383 } 384 385 function onResize() { 386 originalOffsetTop = $placeholder.offset().top; 387 originalHeight = $element.outerHeight(); 388 389 $placeholder.css({ 390 height: originalHeight, 391 width: $element.outerWidth() 392 }); 393 394 onScroll(); 395 } 396 397 let ticking = false; 398 $window.on('scroll.jetStickyHeader-' + elementId, function() { 399 if (!ticking) { 400 requestAnimationFrame(function() { 401 onScroll(); 402 ticking = false; 403 }); 404 ticking = true; 405 } 406 }); 407 408 $window.on('resize.jetStickyHeader-' + elementId, JetTricksTools.debounce(100, onResize)); 409 onScroll(); 410 411 $window.on('resize.jetStickyHeader-' + elementId, JetTricksTools.debounce(100, function() { 412 if (-1 === settings['stickyOn'].indexOf( JetTricks.getDeviceMode() )) { 413 cleanupSticky($element, $placeholder, elementId); 414 } 415 })); 416 } 417 418 function cleanupSticky( $element, $placeholder, elementId ) { 419 $placeholder.remove(); 420 $element.css({ 421 position: '', 422 top: '', 423 left: '', 424 width: '', 425 zIndex: '', 426 transition: '', 427 willChange: '', 428 '--jet-tricks-sticky-offset': '' 429 }); 430 $element.removeClass('jet-sticky-container--stuck jet-sticky-container--hidden jet-sticky-container--scrolled'); 431 $window.off('scroll.jetStickyHeader-' + elementId); 432 $window.off('resize.jetStickyHeader-' + elementId); 433 } 434 435 function initSidebarSticky( $element, settings, options ) { 436 options.topSpacing = settings['topSpacing']; 437 options.bottomSpacing = settings['bottomSpacing']; 438 439 imagesLoaded( $parentSection, function() { 440 $target.data( 'stickyColumnInit', true ); 441 stickyInstance = new StickySidebar( $target[0], options ); 442 }); 443 444 var targetMutation = $target[0], 445 config = { attributes: true, childList: true, subtree: true }; 446 447 var observer = new MutationObserver( function( mutations ) { 448 for( var mutation of mutations ) { 449 if ( 'attributes' === mutation.type && mutation.attributeName !== 'style' ) { 450 $target[0].style.height = 'auto'; 451 } 452 } 453 }); 454 455 observer.observe( targetMutation, config ); 456 457 $window.on( 'resize.JetTricksStickyColumn orientationchange.JetTricksStickyColumn', 458 JetTricksTools.debounce( 50, resizeDebounce ) ); 459 460 var observer = new MutationObserver( function( mutations ) { 461 if ( stickyInstance ) { 462 mutations.forEach( function(mutation){ 463 if (mutation.attributeName === 'class') { 464 setTimeout( function() { 465 stickyInstance.destroy(); 466 stickyInstance = new StickySidebar( $target[0], options ); 467 }, 100 ); 468 } 469 }); 470 } 471 }); 472 473 $observerTarget.each( function(){ 474 observer.observe( $( this )[0], { 475 attributes: true 476 }); 477 }); 478 } 479 480 function initScrollUntilEndSticky( $element, settings ) { 481 const stickyHeight = $element.outerHeight(); 482 const stickyContentBottom = $element.offset().top + stickyHeight; 483 const stickyViewportOffset = $window.height() - stickyHeight - settings['bottomSpacing']; 484 485 $('body').addClass('jet-sticky-container'); 486 487 $window.on( 'scroll.jetSticky', function () { 488 const scrollPosition = $window.scrollTop(); 489 490 if ( scrollPosition + $window.height() >= stickyContentBottom ) { 491 $element.css({ 492 position: 'sticky', 493 top: stickyViewportOffset + 'px', 494 bottom: 'auto', 495 left: 'auto', 496 zIndex: settings['zIndex'], 497 }); 498 } 499 }); 500 501 $observerTarget.on( 'destroy.jetSticky', function () { 502 $window.off( 'scroll.jetSticky' ); 503 $('body').removeClass('jet-sticky-container'); 504 }); 505 } 506 507 function initDefaultSticky( $element, settings ) { 508 $('body').addClass('jet-sticky-container'); 509 $element.addClass( 'jet-sticky-container-sticky' ); 510 $element.css({ 511 'top': settings['topSpacing'], 512 'bottom': settings['bottomSpacing'] 513 }); 514 } 515 516 function resizeDebounce() { 517 var currentDeviceMode = JetTricks.getDeviceMode(), 518 availableDevices = settings['stickyOn'] || [], 519 isInit = $target.data( 'stickyColumnInit' ); 520 521 if ( -1 !== availableDevices.indexOf( currentDeviceMode ) ) { 522 if ( ! isInit ) { 523 $target.data( 'stickyColumnInit', true ); 524 stickyInstance = new StickySidebar( $target[0], stickyInstanceOptions ); 525 stickyInstance.updateSticky(); 526 } 527 } else { 528 $target.data( 'stickyColumnInit', false ); 529 stickyInstance.destroy(); 530 } 531 } 532 }, 533 534 elementorWidget: function( $scope ) { 535 var parallaxInstance = null, 536 satelliteInstance = null, 537 tooltipInstance = null, 538 scrollRevealInstance = null; 539 540 parallaxInstance = new jetWidgetParallax( $scope ); 541 parallaxInstance.init(); 542 543 satelliteInstance = new jetWidgetSatellite( $scope ); 544 satelliteInstance.init(); 545 546 tooltipInstance = new jetWidgetTooltip( $scope ); 547 tooltipInstance.init(); 548 549 scrollRevealInstance = new jetWidgetScrollReveal( $scope ); 550 scrollRevealInstance.init(); 551 552 }, 553 554 getElementorElementSettings: function( $scope ) { 555 556 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() && $scope.hasClass( 'elementor-element-edit-mode' ) ) { 557 return JetTricks.getEditorElementSettings( $scope ); 558 } 559 560 return $scope.data( 'settings' ) || {}; 561 }, 562 563 getEditorElementSettings: function( $scope ) { 564 var modelCID = $scope.data( 'model-cid' ), 565 elementData; 566 567 if ( ! modelCID ) { 568 return {}; 569 } 570 571 if ( ! elementor.hasOwnProperty( 'config' ) ) { 572 return {}; 573 } 574 575 if ( ! elementor.config.hasOwnProperty( 'elements' ) ) { 576 return {}; 577 } 578 579 if ( ! elementor.config.elements.hasOwnProperty( 'data' ) ) { 580 return {}; 581 } 582 583 elementData = elementor.config.elements.data[ modelCID ]; 584 585 if ( ! elementData ) { 586 return {}; 587 } 588 589 return elementData.toJSON(); 590 }, 591 592 widgetViewMore: function( $scope ) { 593 var $target = $scope.find( '.jet-view-more' ), 594 instance = null, 595 settings = $target.data( 'settings' ); 596 597 instance = new jetViewMore( $target, settings ); 598 instance.init(); 599 }, 600 601 widgetUnfold: function( $scope ) { 602 var $target = $scope.find( '.jet-unfold' ), 603 $button = $( '.jet-unfold__button', $target ), 604 $mask = $( '.jet-unfold__mask', $target ), 605 $content = $( '.jet-unfold__content', $target ), 606 $contentInner = $( '.jet-unfold__content-inner', $target), 607 $trigger = $( '.jet-unfold__trigger', $target), 608 $separator = $( '.jet-unfold__separator', $target ), 609 baseSettings = $target.data( 'settings' ) || {}, 610 elemSettings = ( typeof elementor !== 'undefined' && JetTricks.getElementorElementSettings ) ? ( JetTricks.getElementorElementSettings( $scope ) || {} ) : {}, 611 settings = $.extend( {}, baseSettings, elemSettings ), 612 maskBreakpointsHeights = [], 613 prevBreakpoint = '', 614 unfoldDuration = settings['unfoldDuration'] || settings['unfold_duration'], 615 foldDuration = settings['foldDuration'] || settings['fold_duration'], 616 unfoldEasing = settings['unfoldEasing'] || settings['unfold_easing'], 617 foldEasing = settings['foldEasing'] || settings['fold_easing'], 618 maskHeightAdv = 20, 619 heightCalc = '', 620 autoHide = settings['autoHide'] || false, 621 autoHideTime = settings['autoHideTime'] && 0 != settings['autoHideTime']['size'] ? settings['autoHideTime']['size'] : 5, 622 hideOutsideClick = settings['hideOutsideClick'] || false,
623 heightControlType = settings['heightControlType'] || 'height', 624 wordCount = settings['wordCount'] || 20, 625 autoHideTrigger, 626 activeBreakpoints = ( window.elementor && window.elementor.config && window.elementor.config.responsive && window.elementor.config.responsive.activeBreakpoints ) ? window.elementor.config.responsive.activeBreakpoints : {}, 627 initialLoaded = false, 628 isTrue = function( v ) { return v === true || v === 'true'; }; 629 630 function updateMaskGradientClass() { 631 if (settings.separatorType === 'gradient') { 632 if ($target.hasClass('jet-unfold-state') || $trigger.is(':hidden')) { 633 $mask.removeClass('jet-unfold__mask-gradient'); 634 } else { 635 $mask.addClass('jet-unfold__mask-gradient'); 636 } 637 } 638 } 639 640 function calculateHeightByWordCount() { 641 var text = $contentInner.text().trim(); 642 if (!text) { 643 return 0; 644 } 645 646 var words = text.split(/\s+/); 647 var wordsToShow = Math.min(getDeviceWordCount(), words.length); 648 if (wordsToShow >= words.length) { 649 return $contentInner.outerHeight(); 650 } 651 652 var visibleText = words.slice(0, wordsToShow).join(' '); 653 var range = document.createRange(); 654 var walker = document.createTreeWalker($contentInner[0], NodeFilter.SHOW_TEXT, null, false); 655 var endNode = null; 656 var endOffset = 0; 657 var wordsCounted = 0; 658 659 while (walker.nextNode()) { 660 var node = walker.currentNode; 661 var nodeText = node.textContent; 662 var match; 663 var wordPattern = /\S+/g; 664 665 while ((match = wordPattern.exec(nodeText)) !== null) { 666 wordsCounted++; 667 668 if (wordsCounted === wordsToShow) { 669 endOffset = match.index + match[0].length; 670 endNode = node; 671 break; 672 } 673 } 674 675 if (endNode) { 676 break; 677 } 678 } 679 680 if (!endNode) { 681 return $contentInner.outerHeight(); 682 } 683 684 try { 685 range.selectNodeContents($contentInner[0]); 686 range.setEnd(endNode, endOffset); 687 var rect = range.getBoundingClientRect(); 688 var containerRect = $contentInner[0].getBoundingClientRect(); 689 return Math.ceil(rect.bottom - containerRect.top); 690 } catch (e) { 691 var $temp = $contentInner.clone().empty().css({ position: 'absolute', visibility: 'hidden', width: $contentInner.outerWidth() }).html('<p>' + visibleText + '</p>'); 692 $contentInner.after($temp); 693 var h = $temp.outerHeight(); 694 $temp.remove(); 695 return h; 696 } 697 } 698 699 maskBreakpointsHeights['desktop'] = []; 700 maskBreakpointsHeights['widescreen'] = []; 701 702 maskBreakpointsHeights['desktop']['maskHeight'] = (settings['mask_height'] && settings['mask_height']['size'] && '' != settings['mask_height']['size']) ? settings['mask_height']['size'] : 50; 703 704 prevBreakpoint = 'desktop'; 705 706 Object.keys( activeBreakpoints ).reverse().forEach( function( breakpointName ) { 707 708 if ( 'widescreen' === breakpointName ) { 709 maskBreakpointsHeights['widescreen']['maskHeight'] = (settings['mask_height_widescreen'] && settings['mask_height_widescreen']['size'] && '' != settings['mask_height_widescreen']['size']) ? settings['mask_height_widescreen']['size'] : maskBreakpointsHeights['desktop']['maskHeight']; 710 } else { 711 maskBreakpointsHeights[breakpointName] = []; 712 713 var breakpointSetting = settings['mask_height_' + breakpointName]; 714 maskBreakpointsHeights[breakpointName]['maskHeight'] = (breakpointSetting && breakpointSetting['size'] && '' != breakpointSetting['size']) ? breakpointSetting['size'] : maskBreakpointsHeights[prevBreakpoint]['maskHeight']; 715 716 prevBreakpoint = breakpointName; 717 } 718 } ); 719 720 onLoaded(); 721 722 if ( typeof ResizeObserver !== 'undefined' ) { 723 new ResizeObserver( function( entries ) { 724 if ( $target.hasClass( 'jet-unfold-state' ) ) { 725 $mask.css( { 726 'height': $contentInner.outerHeight() 727 } ); 728 } 729 } ).observe( $contentInner[0] ); 730 } 731 732 if ( isTrue( hideOutsideClick ) ) { 733 $( window ).on( 'mouseup.jetUnfold', function( event ) { 734 let container = $target; 735 if ( !container.is( event.target ) && 0 === container.has( event.target ).length && $target.hasClass( 'jet-unfold-state' ) ) { 736 $button.trigger( 'click', { 737 scrollOnFold: false 738 } ); 739 } 740 } ) 741 } 742 743 $target.one('transitionend webkitTransitionEnd oTransitionEnd', function() { 744 if ( !initialLoaded ) { 745 onLoaded(); 746 initialLoaded = true; 747 } 748 }); 749 750 function onLoaded() { 751 initialLoaded = true; 752 753 var deviceHeight = getDeviceHeight(); 754 755 heightCalc = +deviceHeight + maskHeightAdv; 756
757 if ( heightCalc < $contentInner.height() ) { 758 759 if ( ! $target.hasClass( 'jet-unfold-state' ) ) { 760 $separator.css( { 761 'opacity': '1' 762 } ); 763 } 764 765 if ( ! $target.hasClass( 'jet-unfold-state' ) ) { 766 $mask.css( { 767 'height': deviceHeight 768 } ); 769 } else { 770 $mask.css( { 771 'height': $contentInner.outerHeight() 772 } ); 773 } 774 $trigger.css( 'display', 'flex' ); 775 updateMaskGradientClass(); 776 } else { 777 $trigger.hide(); 778 $mask.css( { 779 'height': '100%' 780 } ); 781 $content.css( { 782 'max-height': 'none' 783 } ); 784 $separator.css( { 785 'opacity': '0' 786 } ); 787 updateMaskGradientClass(); 788 } 789 } 790 791 $( window ).on( 'resize.jetWidgetUnfold orientationchange.jetWidgetUnfold', JetTricksTools.debounce( 50, function(){ 792 initialLoaded = false; 793 onLoaded(); 794 } ) ); 795 796 $button.keypress( function( e ) { 797 if ( e.which == 13 ) { 798 $button.click(); 799 return false; 800 } 801 } ); 802 803 $button.on( 'click.jetUnfold', function( e, options ) { 804 var $this = $( this ), 805 $buttonText = $( '.jet-unfold__button-text', $this ), 806 unfoldText = settings['unfoldText'] || '', 807 foldText = settings['foldText'] || '', 808 $buttonIcon = $( '.jet-unfold__button-icon', $this ), 809 unfoldIcon = settings['unfoldIcon'] || '', 810 foldIcon = settings['foldIcon'] || '', 811 contentHeight = $contentInner.outerHeight(), 812 deviceHeight = getDeviceHeight(), 813 shouldScrollOnFold = ! options || false !== options.scrollOnFold; 814 815 e.preventDefault(); 816 817 if ( typeof anime !== 'undefined' ) { 818 anime.remove( $mask[0] ); 819 } 820 821 if ( ! $target.hasClass( 'jet-unfold-state' ) ) { 822 $target.addClass( 'jet-unfold-state' ); 823 824 $separator.css( { 825 'opacity': '0' 826 } ); 827 828 $buttonIcon.html( foldIcon ); 829 $buttonText.text( foldText ); 830 831 // Force recalculation of content height after state change 832 setTimeout(function() { 833 contentHeight = $contentInner.outerHeight(); 834 var duration = ( unfoldDuration && unfoldDuration.size != null ? unfoldDuration.size : 300 ); 835 if ( typeof anime !== 'undefined' ) { 836 anime( { 837 targets: $mask[0], 838 height: contentHeight, 839 duration: duration, 840 easing: unfoldEasing || 'ease', 841 complete: function( anim ) { 842 $( document ).trigger( 'jet-engine/listing/recalculate-masonry' ); 843 } 844 } ); 845 } else { 846 $mask.css( 'height', contentHeight ); 847 $( document ).trigger( 'jet-engine/listing/recalculate-masonry' ); 848 } 849 }, 0); 850 851 if ( isTrue( autoHide ) ) { 852 autoHideTrigger = setTimeout( function() { 853 $button.trigger( 'click', { 854 scrollOnFold: false 855 } ); 856 }, autoHideTime * 1000 ); 857 } 858 } else { 859 clearTimeout( autoHideTrigger ); 860 861 $target.removeClass( 'jet-unfold-state' ); 862 863 $separator.css( { 864 'opacity': '1' 865 } ); 866 867 $buttonIcon.html( unfoldIcon ); 868 $buttonText.text( unfoldText ); 869 870 var foldDurationVal = ( foldDuration && foldDuration.size != null ? foldDuration.size : 300 ); 871 var onFoldComplete = function() { 872 if ( shouldScrollOnFold && isTrue( settings['foldScrolling'] ) && settings['foldScrollOffset'] ) { 873 $( 'html, body' ).animate( { 874 scrollTop: $target.offset().top - ( settings['foldScrollOffset']['size'] || 0 ) 875 }, 'slow' ); 876 } 877 $( document ).trigger( 'jet-engine/listing/recalculate-masonry' ); 878 }; 879 if ( typeof anime !== 'undefined' ) { 880 anime( { 881 targets: $mask[0], 882 height: deviceHeight, 883 duration: foldDurationVal, 884 easing: foldEasing || 'ease', 885 complete: onFoldComplete 886 } ); 887 } else { 888 $mask.css( 'height', deviceHeight ); 889 onFoldComplete(); 890 } 891 } 892 893 updateMaskGradientClass(); 894 } ); 895 896 function getDeviceMode() { 897 return ( typeof elementorFrontend !== 'undefined' && elementorFrontend.getCurrentDeviceMode ) ? elementorFrontend.getCurrentDeviceMode() : 'desktop'; 898 } 899 900 function getDeviceHeight() { 901 if (heightControlType === 'word_count') { 902 return calculateHeightByWordCount(); 903 } 904 905 var device = getDeviceMode(); 906 var heightSettings; 907 908 switch ( device ) { 909 910 case 'mobile': 911 heightSettings = settings.mask_height_mobile; 912 break; 913 914 case 'tablet': 915 heightSettings = settings.mask_height_tablet; 916 break; 917 918 default: 919 heightSettings = settings.mask_height || settings.height; 920 921 } 922 923 if ( ! heightSettings || ( heightSettings.size == null || heightSettings.size === '' ) ) { 924 heightSettings = settings.mask_height || settings.height || { size: 50, unit: 'px' }; 925 } 926 927 var unit = heightSettings.unit || 'px'; 928 var size = heightSettings.size != null ? heightSettings.size : 50; 929 930 switch ( unit ) { 931 932 case 'vh': 933 return ( window.innerHeight * size ) / 100; 934 935 case '%': 936 var parentHeight = $contentInner.parent().height(); 937 return ( parentHeight * size ) / 100; 938 939 default: 940 return size; 941 } 942 } 943 944 function getDeviceWordCount() { 945 var device = getDeviceMode(); 946 var value; 947 948 switch ( device ) { 949 case 'mobile': 950 value = settings.word_count_mobile || settings.wordCount; 951 break; 952 case 'tablet': 953 value = settings.word_count_tablet || settings.wordCount; 954 break; 955 default: 956 value = settings.word_count || settings.wordCount; 957 } 958 959 return ( value !== null && value !== undefined ) ? parseInt( value, 10 ) : 20; 960 } 961 }, 962 963 widgetHotspots: function( $scope ) { 964 var $target = $scope.find( '.jet-hotspots' ), 965 $hotspots = $( '.jet-hotspots__item', $target), 966 settings = $target.data( 'settings' ), 967 editMode = Boolean( elementor && elementor.isEditMode() ), 968 itemActiveClass = 'jet-hotspots__item--active'; 969 970 $target.imagesLoaded().progress( function() { 971 $target.addClass( 'image-loaded' ); 972 } ); 973 974 $hotspots.each( function( index ) { 975 var $this = $( this ), 976 horizontal = $this.data( 'horizontal-position' ), 977 vertical = $this.data( 'vertical-position' ), 978 tooltipWidth = $this.data( 'tooltip-width' ) || null, 979 showOnInit = $this.data( 'show-on-init' ), 980 itemSelector = $this[0], 981 options = {}; 982 983 $this.css( { 984 'left': horizontal + '%', 985 'top': vertical + '%' 986 } ); 987 988 if ( itemSelector._tippy ) { 989 itemSelector._tippy.destroy(); 990 } 991 992 options = { 993 content: ( $this.data( 'jet-tooltip-content' ) || {} ).content || '', 994 arrow: settings['tooltipArrow'] ? true : false, 995 placement: settings['tooltipPlacement'], 996 trigger: settings['tooltipTrigger'], 997 appendTo: editMode ? document.body : $target[0], 998 hideOnClick: 'manual' !== settings['tooltipTrigger'], 999 maxWidth: 'none', 1000 offset: [0, settings['tooltipDistance']['size']], 1001 allowHTML: true, 1002 interactive: settings['tooltipInteractive'] ? true : false, 1003 onShow( instance ) { 1004 $( itemSelector ).addClass( itemActiveClass ); 1005 1006 if ( tooltipWidth ) { 1007 instance.popper.querySelector( '.tippy-box' ).style.width = tooltipWidth; 1008 } 1009 1010 }, 1011 onHidden( instance ) { 1012 $( itemSelector ).removeClass( itemActiveClass ); 1013 } 1014 } 1015 1016 if ( 'manual' != settings['tooltipTrigger'] ) { 1017 options['duration'] = [ settings['tooltipShowDuration']['size'], settings['tooltipHideDuration']['size'] ]; 1018 options['animation'] = settings['tooltipAnimation']; 1019 options['delay'] = settings['tooltipDelay']; 1020 } 1021 1022 tippy( [ itemSelector ], options ); 1023 1024 if ( 'manual' === settings['tooltipTrigger'] && itemSelector._tippy ) { 1025 itemSelector._tippy.show(); 1026 } 1027 1028 if ( ( showOnInit === 'yes' || settings['tooltipShowOnInit'] ) && itemSelector._tippy ) { 1029 itemSelector._tippy.show(); 1030 } 1031 1032 } ); 1033 }, 1034 1035 columnEditorSettings: function( columnId ) { 1036 var editorElements = null, 1037 columnData = {}; 1038 1039 if ( ! window.elementor.hasOwnProperty( 'elements' ) ) { 1040 return false;
1041 } 1042 1043 editorElements = window.elementor.elements; 1044 1045 if ( ! editorElements.models ) { 1046 return false; 1047 } 1048 1049 $.each( editorElements.models, function( index, obj ) { 1050 1051 $.each( obj.attributes.elements.models, function( index, obj ) { 1052 if ( columnId == obj.id ) { 1053 columnData = obj.attributes.settings.attributes; 1054 } 1055 } ); 1056 1057 } ); 1058 1059 return { 1060 'sticky': columnData['jet_tricks_column_sticky'] || false, 1061 'topSpacing': columnData['jet_tricks_top_spacing'] || 50, 1062 'bottomSpacing': columnData['jet_tricks_bottom_spacing'] || 50, 1063 'stickyOn': columnData['jet_tricks_column_sticky_on'] || [ 'desktop', 'tablet', 'mobile'] 1064 } 1065 1066 }, 1067 1068 sectionEditorSettings: function( $scope ) { 1069 var editorElements = null, 1070 sectionData = {}; 1071 1072 if ( ! window.elementor.hasOwnProperty( 'elements' ) ) { 1073 return false; 1074 } 1075 1076 sectionData = JetTricks.getElementorElementSettings( $scope ); 1077 1078 return { 1079 'particles': sectionData['section_jet_tricks_particles'] || 'false', 1080 'particles_json': sectionData['section_jet_tricks_particles_json'] || '', 1081 } 1082 1083 } 1084 1085 }; 1086 1087 $( window ).on( 'elementor/frontend/init', JetTricks.init ); 1088 1089 JetTricks.initBlocks = function() { 1090 if ( window.JetPlugins ) { 1091 window.JetPlugins.bulkBlocksInit( [ 1092 { block: 'jet-tricks/view-more', callback: JetTricks.widgetViewMore }, 1093 { block: 'jet-tricks/unfold', callback: JetTricks.widgetUnfold }, 1094 { block: 'jet-tricks/hotspots', callback: JetTricks.widgetHotspots }, 1095 ] ); 1096 } 1097 }; 1098 1099 var JetTricksTools = { 1100 debounce: function( threshold, callback ) { 1101 var timeout; 1102 1103 return function debounced( $event ) { 1104 function delayed() { 1105 callback.call( this, $event ); 1106 timeout = null; 1107 } 1108 1109 if ( timeout ) { 1110 clearTimeout( timeout ); 1111 } 1112 1113 timeout = setTimeout( delayed, threshold ); 1114 }; 1115 }, 1116 1117 widgetEditorSettings: function( widgetId ) { 1118 var editorElements = null, 1119 widgetData = {}; 1120 1121 if ( !window.elementor.hasOwnProperty( 'elements' ) || !window.elementor.elements.models ) { 1122 return false; 1123 } 1124 1125 editorElements = window.elementor.elements; 1126 1127 function findWidgetById( models, widgetId ) { 1128 let foundData = null; 1129 1130 $.each( models, function( index, obj ) { 1131 if ( obj.id === widgetId ) { 1132 foundData = obj.attributes.settings.attributes; 1133 return false; 1134 } 1135 if ( obj.attributes.elements && obj.attributes.elements.models ) { 1136 foundData = findWidgetById( obj.attributes.elements.models, widgetId ); 1137 if ( foundData ) { 1138 return false; 1139 } 1140 } 1141 }); 1142 1143 return foundData; 1144 } 1145 1146 widgetData = findWidgetById( editorElements.models, widgetId ) || {}; 1147 1148 return { 1149 'speed': widgetData['jet_tricks_widget_parallax_speed'] || { 'size': 50, 'unit': '%'}, 1150 'parallax': widgetData['jet_tricks_widget_parallax'] || 'false', 1151 'invert': widgetData['jet_tricks_widget_parallax_invert'] || 'false', 1152 'stickyOn': widgetData['jet_tricks_widget_parallax_on'] || [ 'desktop', 'tablet', 'mobile'], 1153 'satellite': widgetData['jet_tricks_widget_satellite'] || 'false', 1154 'satelliteType': widgetData['jet_tricks_widget_satellite_type'] || 'text', 1155 'satellitePosition': widgetData['jet_tricks_widget_satellite_position'] || 'top-center', 1156 'satelliteText': widgetData['jet_tricks_widget_satellite_text'] || 'Lorem Ipsum', 1157 'satelliteIcon': widgetData['selected_jet_tricks_widget_satellite_icon'] || '', 1158 'satelliteImage': widgetData['jet_tricks_widget_satellite_image'] || '', 1159 'satelliteLink': widgetData['jet_tricks_widget_satellite_link'] || '', 1160 'tooltip': widgetData['jet_tricks_widget_tooltip'] || 'false', 1161 'tooltipDescription': widgetData['jet_tricks_widget_tooltip_description'] || 'Lorem Ipsum', 1162 'tooltipPlacement': widgetData['jet_tricks_widget_tooltip_placement'] || 'top', 1163 'tooltipArrow': 'true' === widgetData['jet_tricks_widget_tooltip_arrow'] ? true : false, 1164 'xOffset': widgetData['jet_tricks_widget_tooltip_x_offset'] || 0, 1165 'yOffset': widgetData['jet_tricks_widget_tooltip_y_offset'] || 0, 1166 'tooltipAnimation': widgetData['jet_tricks_widget_tooltip_animation'] || 'shift-toward', 1167 'tooltipTrigger': widgetData['jet_tricks_widget_tooltip_trigger'] || 'mouseenter', 1168 'customSelector': widgetData['jet_tricks_widget_tooltip_custom_selector'] || '', 1169 'zIndex': widgetData['jet_tricks_widget_tooltip_z_index'] || '999', 1170 'appendTo': widgetData['jet_tricks_widget_tooltip_append_to'] || 'widget', 1171 'delay': widgetData['jet_tricks_widget_tooltip_delay'] || '0', 1172 'followCursor': widgetData['jet_tricks_widget_tooltip_follow_cursor'] || 'false', 1173 'tooltipDevices': Array.isArray( widgetData['jet_tricks_widget_tooltip_devices'] ) 1174 ? widgetData['jet_tricks_widget_tooltip_devices'] 1175 : [], 1176 'scrollReveal': widgetData['jet_tricks_widget_scroll_reveal'] || 'false', 1177 'scrollRevealEffect': widgetData['jet_tricks_widget_scroll_reveal_effect'] || 'fade-up', 1178 'scrollRevealMaskDirection': widgetData['jet_tricks_widget_scroll_reveal_mask_direction'] || 'up', 1179 'scrollRevealDuration': widgetData['jet_tricks_widget_scroll_reveal_duration'] || { 'size': 0.6, 'unit': 's' }, 1180 'scrollRevealDelay': widgetData['jet_tricks_widget_scroll_reveal_delay'] || { 'size': 0, 'unit': 's' }, 1181 'scrollRevealOnce': widgetData['jet_tricks_widget_scroll_reveal_once'] || 'true', 1182 'scrollRevealRootMargin': widgetData['jet_tricks_widget_scroll_reveal_root_margin'] !== undefined && widgetData['jet_tricks_widget_scroll_reveal_root_margin'] !== null ? parseInt( widgetData['jet_tricks_widget_scroll_reveal_root_margin'], 10 ) : 0, 1183 'scrollRevealOn': widgetData['jet_tricks_widget_scroll_reveal_on'] || [ 'desktop', 'tablet', 'mobile' ] 1184 } 1185 } 1186 } 1187
1188 /** 1189 * Jet jetViewMore Class 1190 * 1191 * @return {void} 1192 */ 1193 window.jetViewMore = function( $selector, settings ) { 1194 var self = this, 1195 $window = $( window ), 1196 $button = $( '.jet-view-more__button', $selector ), 1197 defaultSettings = { 1198 sections: {}, 1199 effect: 'move-up', 1200 showall: false 1201 }, 1202 settings = $.extend( {}, defaultSettings, settings ), 1203 sections = settings['sections'], 1204 sectionsData = {}, 1205 editMode = Boolean( elementor && elementor.isEditMode() ), 1206 readLess = settings['read_less'] || false, 1207 readMoreLabel = settings['read_more_label'], 1208 readLessLabel = settings['read_less_label'], 1209 readMoreIconHtml = settings['read_more_icon_html'] || '', 1210 readLessIconHtml = settings['read_less_icon_html'] || '', 1211 hideAll = settings['hide_all'] || false, 1212 isOpened = false; 1213 1214 /** 1215 * Init 1216 */ 1217 self.init = function() { 1218 self.setSectionsData(); 1219 1220 if ( editMode ) { 1221 return false; 1222 } 1223 1224 function hideSection($section) { 1225 // Apply hide effect if available 1226 if (settings['hide_effect'] && settings['hide_effect'] !== 'none') { 1227 $section.addClass('view-more-hiding'); 1228 $section.addClass('jet-tricks-' + settings['hide_effect'] + '-hide-effect'); 1229 1230 // Remove classes after animation completes 1231 (function($currentSection) { 1232 $currentSection.on('animationend', function animationEndHandler() { 1233 $currentSection.off('animationend', animationEndHandler); 1234 $currentSection.removeClass('view-more-hiding'); 1235 $currentSection.removeClass('jet-tricks-' + settings['hide_effect'] + '-hide-effect'); 1236 $currentSection.css('height', ''); 1237 $currentSection.removeClass('view-more-visible'); 1238 $currentSection.removeClass('jet-tricks-' + settings['effect'] + '-effect'); 1239 }); 1240 })($section); 1241 } else { 1242 $section.css('height', ''); 1243 $section.removeClass('view-more-visible'); 1244 $section.removeClass('jet-tricks-' + settings['effect'] + '-effect'); 1245 } 1246 } 1247 1248 function showAllSections() { 1249 for ( var section in sectionsData ) { 1250 var $section = sectionsData[ section ]['selector']; 1251 sectionsData[ section ]['visible'] = true; 1252 $section.addClass( 'view-more-visible' ); 1253 $section.addClass( 'jet-tricks-' + settings['effect'] + '-effect' ); 1254 } 1255 } 1256 1257 function hideAllSections() { 1258 for ( var section in sectionsData ) { 1259 var $section = sectionsData[ section ]['selector']; 1260 sectionsData[ section ]['visible'] = false; 1261 hideSection($section); 1262 } 1263 } 1264 1265 function showNextSection() { 1266 for ( var section in sectionsData ) { 1267 var $section = sectionsData[ section ]['selector']; 1268 if ( !sectionsData[ section ]['visible'] ) { 1269 sectionsData[ section ]['visible'] = true; 1270 $section.addClass( 'view-more-visible' ); 1271 $section.addClass( 'jet-tricks-' + settings['effect'] + '-effect' ); 1272 break; 1273 } 1274 } 1275 } 1276 1277 function hideNextSection() { 1278 var sectionKeys = Object.keys(sectionsData).reverse(); 1279 for (var i = 0; i < sectionKeys.length; i++) { 1280 var sectionKey = sectionKeys[i]; 1281 var $section = sectionsData[sectionKey]['selector']; 1282 if (sectionsData[sectionKey]['visible']) { 1283 sectionsData[sectionKey]['visible'] = false; 1284 hideSection($section); 1285 break; 1286 } 1287 } 1288 } 1289 1290 $button.on('click', function() { 1291 if (readLess) { 1292 if (!isOpened) { 1293 if (!settings.showall) { 1294 showNextSection(); 1295 var allVisible = true; 1296 for (var section in sectionsData) { 1297 if (!sectionsData[section]['visible']) { 1298 allVisible = false; 1299 break; 1300 } 1301 } 1302 if (allVisible) { 1303 $button.find('.jet-view-more__label').text(readLessLabel); 1304 var lessIconHtml = readLessIconHtml; 1305 if ( lessIconHtml ) { 1306 $button.find('.jet-view-more__icon').html( lessIconHtml ); 1307 } 1308 $button.addClass('jet-view-more__button--read-less'); 1309 isOpened = true; 1310 } 1311 } else { 1312 showAllSections(); 1313 $button.find('.jet-view-more__label').text(readLessLabel); 1314 var lessIconHtml2 = readLessIconHtml; 1315 if ( lessIconHtml2 ) { 1316 $button.find('.jet-view-more__icon').html( lessIconHtml2 ); 1317 } 1318 $button.addClass('jet-view-more__button--read-less'); 1319 isOpened = true; 1320 } 1321 } else { 1322 if (hideAll) { 1323 hideAllSections(); 1324 $button.find('.jet-view-more__label').text(readMoreLabel); 1325 var moreIconHtml = readMoreIconHtml; 1326 if ( moreIconHtml ) { 1327 $button.find('.jet-view-more__icon').html( moreIconHtml ); 1328 } 1329 $button.removeClass('jet-view-more__button--read-less'); 1330 isOpened = false;
1331 } else { 1332 hideNextSection(); 1333 var allHidden = true; 1334 for (var section in sectionsData) { 1335 if (sectionsData[section]['visible']) { 1336 allHidden = false; 1337 break; 1338 } 1339 } 1340 if (allHidden) { 1341 $button.find('.jet-view-more__label').text(readMoreLabel); 1342 var moreIconHtml2 = readMoreIconHtml; 1343 if ( moreIconHtml2 ) { 1344 $button.find('.jet-view-more__icon').html( moreIconHtml2 ); 1345 } 1346 $button.removeClass('jet-view-more__button--read-less'); 1347 isOpened = false; 1348 } 1349 } 1350 } 1351 } else { 1352 if (!settings.showall) { 1353 showNextSection(); 1354 } else { 1355 showAllSections(); 1356 } 1357 var allVisible = true; 1358 for (var section in sectionsData) { 1359 if (!sectionsData[section]['visible']) { 1360 allVisible = false; 1361 break; 1362 } 1363 } 1364 if (allVisible) { 1365 $button.css({ 'display': 'none' }); 1366 } 1367 } 1368 }); 1369 1370 $button.keydown(function(e) { 1371 var $which = e.which || e.keyCode; 1372 if ($which == 13 || $which == 32) { 1373 e.preventDefault(); 1374 if (readLess) { 1375 $button.trigger('click'); 1376 } else { 1377 if (!settings.showall) { 1378 showNextSection(); 1379 } else { 1380 showAllSections(); 1381 } 1382 var allVisible = true; 1383 for (var section in sectionsData) { 1384 if (!sectionsData[section]['visible']) { 1385 allVisible = false; 1386 break; 1387 } 1388 } 1389 if (allVisible) { 1390 $button.css({ 'display': 'none' }); 1391 } 1392 } 1393 } 1394 }); 1395 }; 1396 1397 self.setSectionsData = function() { 1398 1399 for ( var section in sections ) { 1400 var $selector = $( '#' + sections[ section ] ); 1401 1402 if ( ! editMode ) { 1403 $selector.addClass( 'jet-view-more-section' ); 1404 } else { 1405 $selector.addClass( 'jet-view-more-section-edit-mode' ); 1406 } 1407 1408 sectionsData[ section ] = { 1409 'section_id': sections[ section ], 1410 'selector': $selector, 1411 'visible': false, 1412 } 1413 } 1414 }; 1415 }; 1416 1417 /** 1418 * [jetWidgetParallax description] 1419 * @param {[type]} $scope [description] 1420 * @return {[type]} [description] 1421 */ 1422 window.jetWidgetParallax = function( $scope ) { 1423 var self = this, 1424 $target = $scope, 1425 $section = $scope.closest( '.elementor-top-section' ), 1426 widgetId = $scope.data('id'), 1427 settings = {}, 1428 editMode = Boolean( elementor && elementor.isEditMode() ), 1429 $window = $( window ), 1430 isSafari = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/), 1431 platform = navigator.platform, 1432 safariClass = isSafari ? 'is-safari' : '', 1433 macClass = 'MacIntel' == platform ? ' is-mac' : ''; 1434 1435 /** 1436 * Init 1437 */ 1438 self.init = function() { 1439 1440 $scope.addClass( macClass ); 1441 1442 if ( ! editMode ) { 1443 settings = $scope.data( 'jet-tricks-settings' ); 1444 } else { 1445 settings = JetTricksTools.widgetEditorSettings( widgetId ); 1446 } 1447 1448 if ( ! settings ) { 1449 return false; 1450 } 1451 1452 if ( 'undefined' === typeof settings ) { 1453 return false; 1454 } 1455 1456 if ( 'false' === settings['parallax'] || 'undefined' === typeof settings['parallax'] ) { 1457 return false; 1458 } 1459 1460 $window.on( 'scroll.jetWidgetParallax resize.jetWidgetParallax', self.scrollHandler ).trigger( 'resize.jetWidgetParallax' ); 1461 }; 1462 1463 self.scrollHandler = function( event ) { 1464 var speed = +settings['speed']['size'] * 0.01, 1465 invert = 'true' == settings['invert'] ? -1 : 1, 1466 winHeight = $window.height(), 1467 winScrollTop = $window.scrollTop(), 1468 offsetTop = $scope.offset().top, 1469 thisHeight = $scope.outerHeight(), 1470 sectionHeight = $section.length ? $section.outerHeight() : 0, 1471 positionDelta = winScrollTop - offsetTop + ( winHeight / 2 ), 1472 abs = positionDelta > 0 ? 1 : -1, 1473 posY = abs * Math.pow( Math.abs( positionDelta ), 0.85 ), 1474 availableDevices = settings['stickyOn'] || [], 1475 currentDeviceMode = JetTricks.getDeviceMode(); 1476 1477 posY = invert * Math.ceil( speed * posY ); 1478 1479 if ( ! availableDevices.length || -1 !== availableDevices.indexOf( currentDeviceMode ) ) { 1480 $target.css( { 1481 'transform': 'translateY(' + posY + 'px)' 1482 } ); 1483 } else { 1484 $target.css( { 1485 'transform': 'translateY(0)' 1486 } ); 1487 } 1488 }; 1489 }; 1490 1491 /** 1492 * Scroll reveal on viewport entry (Elementor widgets). 1493 * 1494 * @param {jQuery} $scope Widget root. 1495 */ 1496 window.jetWidgetScrollReveal = function( $scope ) { 1497 var self = this, 1498 settings = {}, 1499 io = null, 1500 el = $scope[ 0 ]; 1501 1502 self.init = function() { 1503 1504 if ( ! el || $scope.data( 'jetScrollRevealInit' ) ) { 1505 return false;
1506 } 1507 1508 settings = $scope.data( 'jet-tricks-settings' ); 1509 1510 if ( ! settings || typeof settings !== 'object' ) { 1511 return false; 1512 } 1513 1514 if ( settings.scrollReveal !== 'true' && settings.scrollReveal !== true ) { 1515 return false; 1516 } 1517 1518 var availableDevices = settings.scrollRevealOn || [], 1519 currentDeviceMode = JetTricks.getDeviceMode(), 1520 deviceOk = ! availableDevices.length || -1 !== availableDevices.indexOf( currentDeviceMode ); 1521 1522 if ( ! deviceOk ) { 1523 $scope 1524 .addClass( 'jet-scroll-reveal--instant-exit jet-scroll-reveal--in-view' ) 1525 .removeClass( 'jet-scroll-reveal--pending' ); 1526 return false; 1527 } 1528 1529 if ( window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches ) { 1530 $scope 1531 .addClass( 'jet-scroll-reveal--instant-exit jet-scroll-reveal--in-view' ) 1532 .removeClass( 'jet-scroll-reveal--pending' ); 1533 return false; 1534 } 1535 1536 if ( typeof IntersectionObserver === 'undefined' ) { 1537 $scope 1538 .addClass( 'jet-scroll-reveal--instant-exit jet-scroll-reveal--in-view' ) 1539 .removeClass( 'jet-scroll-reveal--pending' ); 1540 return false; 1541 } 1542 1543 $scope.data( 'jetScrollRevealInit', true ); 1544 1545 var dur = settings.scrollRevealDuration && typeof settings.scrollRevealDuration.size !== 'undefined' 1546 ? parseFloat( settings.scrollRevealDuration.size, 10 ) 1547 : 0.6; 1548 var del = settings.scrollRevealDelay && typeof settings.scrollRevealDelay.size !== 'undefined' 1549 ? parseFloat( settings.scrollRevealDelay.size, 10 ) 1550 : 0; 1551 var rm = typeof settings.scrollRevealRootMargin === 'number' 1552 ? settings.scrollRevealRootMargin 1553 : parseInt( settings.scrollRevealRootMargin || 0, 10 ); 1554 var once = settings.scrollRevealOnce === 'true' || settings.scrollRevealOnce === true; 1555 1556 el.style.setProperty( '--jet-sr-duration', dur + 's' ); 1557 el.style.setProperty( '--jet-sr-delay', del + 's' ); 1558 1559 var rootMargin = '0px 0px ' + rm + 'px 0px'; 1560 1561 io = new IntersectionObserver( function( entries ) { 1562 entries.forEach( function( entry ) { 1563 if ( entry.isIntersecting ) { 1564 entry.target.classList.remove( 'jet-scroll-reveal--instant-exit' ); 1565 entry.target.classList.add( 'jet-scroll-reveal--in-view' ); 1566 entry.target.classList.remove( 'jet-scroll-reveal--pending' ); 1567 if ( once && io ) { 1568 io.unobserve( entry.target ); 1569 } 1570 } else if ( ! once ) { 1571 entry.target.classList.add( 'jet-scroll-reveal--instant-exit' ); 1572 entry.target.classList.remove( 'jet-scroll-reveal--in-view' ); 1573 entry.target.classList.add( 'jet-scroll-reveal--pending' ); 1574 } 1575 } ); 1576 }, { 1577 root: null, 1578 rootMargin: rootMargin, 1579 threshold: 0 1580 } ); 1581 1582 io.observe( el ); 1583 }; 1584 }; 1585 1586 /** 1587 * [jetWidgetSatellite description] 1588 * @param {[type]} $scope [description] 1589 * @return {[type]} [description] 1590 */ 1591 window.jetWidgetSatellite = function( $scope ) { 1592 var self = this, 1593 widgetId = $scope.data('id'), 1594 settings = {}, 1595 editMode = Boolean( elementor && elementor.isEditMode() ); 1596 1597 self.getClampedNumber = function( value, fallback, min, max ) { 1598 var parsed = parseFloat( value ); 1599 1600 if ( isNaN( parsed ) ) { 1601 parsed = fallback; 1602 } 1603 1604 if ( parsed < min ) { 1605 parsed = min; 1606 } 1607 1608 if ( parsed > max ) { 1609 parsed = max; 1610 } 1611 1612 return parsed; 1613 }; 1614 1615 self.getSatelliteLayoutStyleAttr = function() { 1616 var x = self.getClampedNumber( settings['satelliteOffsetX'], 0, -500, 500 ); 1617 var y = self.getClampedNumber( settings['satelliteOffsetY'], 0, -500, 500 ); 1618 var rotate = self.getClampedNumber( settings['satelliteRotate'], 0, -180, 180 ); 1619 var zIndex = self.getClampedNumber( settings['satelliteZIndex'], 2, -10, 999 ); 1620 var styleParts = [ 1621 '--jet-satellite-offset-x:' + x + 'px', 1622 '--jet-satellite-offset-y:' + y + 'px', 1623 '--jet-satellite-rotate:' + rotate + 'deg', 1624 '--jet-satellite-z:' + zIndex 1625 ]; 1626 1627 return ' style="' + styleParts.join( ';' ) + '"'; 1628 }; 1629 1630 /** 1631 * Init 1632 */ 1633 self.init = function() { 1634 1635 if ( ! editMode ) { 1636 settings = $scope.data( 'jet-tricks-settings' ); 1637 } else { 1638 settings = JetTricksTools.widgetEditorSettings( widgetId ); 1639 } 1640 1641 if ( ! settings || typeof settings !== 'object' ) { 1642 return false;
1643 } 1644 1645 if ( 'false' === settings['satellite'] || 'undefined' === typeof settings['satellite'] ) { 1646 return false; 1647 } 1648 1649 $scope.addClass( 'jet-satellite-widget' ); 1650 1651 $( '.jet-tricks-satellite', $scope ).addClass( 'jet-tricks-satellite--' + settings['satellitePosition'] ); 1652 1653 //satellite display in edit mode 1654 if ( editMode && $scope.find( '.jet-tricks-satellite' ).length === 0 ) { 1655 var html = ''; 1656 var layoutStyle = self.getSatelliteLayoutStyleAttr(); 1657 var pos = settings['satellitePosition'] || 'top-center'; 1658 var rootTag = ( $scope[0] && $scope[0].tagName ) ? $scope[0].tagName.toLowerCase() : ''; 1659 var wrapperTag = [ 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ].indexOf( rootTag ) !== -1 ? 'span' : 'div'; 1660 var instanceTag = 'span' === wrapperTag ? 'span' : 'div'; 1661 1662 var link = settings['satelliteLink'] || {}; 1663 var linkStart = '', linkEnd = ''; 1664 if ( link.url ) { 1665 linkStart = '<a class="jet-tricks-satellite__link">'; 1666 linkEnd = '</a>'; 1667 } 1668 1669 if ( settings['satelliteType'] === 'text' && settings['satelliteText'] ) { 1670 html = '<' + wrapperTag + ' class="jet-tricks-satellite jet-tricks-satellite--' + pos + '"' + layoutStyle + '><' + wrapperTag + ' class="jet-tricks-satellite__inner"><' + wrapperTag + ' class="jet-tricks-satellite__text">' + linkStart + '<span>' + settings['satelliteText'] + '</span>' + linkEnd + '</' + wrapperTag + '></' + wrapperTag + '></' + wrapperTag + '>'; 1671 } else if ( settings['satelliteType'] === 'icon' && settings['satelliteIcon'] && settings['satelliteIcon'].value ) { 1672 html = '<' + wrapperTag + ' class="jet-tricks-satellite jet-tricks-satellite--' + pos + '"' + layoutStyle + '><' + wrapperTag + ' class="jet-tricks-satellite__inner"><' + wrapperTag + ' class="jet-tricks-satellite__icon">' + linkStart + '<' + instanceTag + ' class="jet-tricks-satellite__icon-instance jet-tricks-icon"><i class="' + settings['satelliteIcon'].value + '"></i></' + instanceTag + '>' + linkEnd + '</' + wrapperTag + '></' + wrapperTag + '></' + wrapperTag + '>'; 1673 } else if ( settings['satelliteType'] === 'image' && settings['satelliteImage'] && settings['satelliteImage'].url ) { 1674 html = '<' + wrapperTag + ' class="jet-tricks-satellite jet-tricks-satellite--' + pos + '"' + layoutStyle + '><' + wrapperTag + ' class="jet-tricks-satellite__inner"><' + wrapperTag + ' class="jet-tricks-satellite__image">' + linkStart + '<img class="jet-tricks-satellite__image-instance" src="' + settings['satelliteImage'].url + '" alt="">' + linkEnd + '</' + wrapperTag + '></' + wrapperTag + '></' + wrapperTag + '>'; 1675 } 1676 1677 if ( html ) { 1678 $scope.prepend(html); 1679 } 1680 } 1681 }; 1682 }; 1683 1684 /** 1685 * [jetWidgetTooltip description] 1686 * @param {[type]} $scope [description] 1687 * @return {[type]} [description] 1688 */ 1689 window.jetWidgetTooltip = function( $scope ) { 1690 var self = this, 1691 widgetId = $scope.data('id'), 1692 widgetSelector = $scope[0], 1693 tooltipSelector = widgetSelector, 1694 settings = {}, 1695 editMode = Boolean( elementor && elementor.isEditMode() ), 1696 $window = $( window ), 1697 resizeTimer; 1698 1699 self.removeTooltipContent = function() { 1700 $scope.find( '> .jet-tooltip-widget__content' ).remove(); 1701 }; 1702 1703 self.destroyTooltipInstance = function() { 1704 if ( tooltipSelector && tooltipSelector._tippy ) { 1705 tooltipSelector._tippy.destroy(); 1706 } 1707 if ( widgetSelector && widgetSelector._tippy ) { 1708 widgetSelector._tippy.destroy(); 1709 } 1710 }; 1711 1712 self.isTooltipDeviceAllowed = function() { 1713 var devices = settings['tooltipDevices']; 1714 if ( typeof devices === 'undefined' || devices === null ) { 1715 return true; 1716 } 1717 if ( ! devices.length ) { 1718 return true; 1719 } 1720 return -1 !== devices.indexOf( JetTricks.getDeviceMode() ); 1721 }; 1722 1723 self.getTooltipDelayMs = function() { 1724 var d = settings['delay']; 1725 if ( d && typeof d === 'object' && d.hasOwnProperty( 'size' ) ) { 1726 return d.size ? d.size : 0; 1727 } 1728 if ( typeof d === 'number' ) { 1729 return d; 1730 } 1731 return 0; 1732 }; 1733 1734 self.mountTippy = function() { 1735 if ( ! tooltipSelector ) { 1736 return; 1737 } 1738 1739 var contentEl = $scope.find( '.jet-tooltip-widget__content' )[0]; 1740 if ( ! contentEl ) { 1741 return; 1742 } 1743 1744 var appendToBody = editMode || ( settings['appendTo'] === 'body' ); 1745 1746 tippy( 1747 [ tooltipSelector ], 1748 { 1749 content: contentEl.innerHTML, 1750 allowHTML: true, 1751 appendTo: appendToBody ? document.body : widgetSelector, 1752 arrow: settings['tooltipArrow'] ? true : false, 1753 placement: settings['tooltipPlacement'], 1754 offset: [ settings['xOffset'], settings['yOffset'] ], 1755 animation: settings['tooltipAnimation'], 1756 trigger: settings['tooltipTrigger'], 1757 interactive: settings['followCursor'] === 'false' || settings['followCursor'] === '
1757initial', 1758 zIndex: settings['zIndex'], 1759 maxWidth: 'none', 1760 delay: self.getTooltipDelayMs(), 1761 followCursor: settings['followCursor'] === 'false' ? false : (settings['followCursor'] === 'true' ? true : settings['followCursor']), 1762 onCreate: function (instance) { 1763 if ( appendToBody ) { 1764 var tippyId = editMode ? ( tooltipSelector.getAttribute('data-id') || widgetId ) : widgetId; 1765 if ( tippyId ) { 1766 instance.popper.classList.add( 'tippy-' + tippyId ); 1767 } 1768 if ( settings['wrapperClass'] ) { 1769 instance.popper.classList.add( settings['wrapperClass'] ); 1770 } 1771 } 1772 }, 1773 onShow: function (instance) { 1774 // JetFormBuilder Formless Actions Endpoints compatibility 1775 var addButtonListeners = window.crocoblock && window.crocoblock.frontComponents && window.crocoblock.frontComponents.addButtonListeners; 1776 if ( addButtonListeners && instance.popper ) { 1777 var buttons = instance.popper.querySelectorAll( '[data-jfb-submit-endpoint]' ); 1778 buttons.forEach( function (el) { addButtonListeners( el ); } ); 1779 } 1780 } 1781 } 1782 ); 1783 1784 if ( editMode && tooltipSelector && tooltipSelector._tippy ) { 1785 tooltipSelector._tippy.show(); 1786 } 1787 }; 1788 1789 self.refreshTooltipForDevice = function() { 1790 self.destroyTooltipInstance(); 1791 1792 if ( ! self.isTooltipDeviceAllowed() ) { 1793 return; 1794 } 1795 1796 self.mountTippy(); 1797 }; 1798 1799 /** 1800 * Init 1801 */ 1802 self.init = function() { 1803 1804 if ( ! editMode ) { 1805 settings = $scope.data( 'jet-tricks-settings' ); 1806 } else { 1807 settings = JetTricksTools.widgetEditorSettings( widgetId ); 1808 } 1809 1810 if ( ! settings ) { 1811 return false; 1812 } 1813 1814 if ( 'undefined' === typeof settings ) { 1815 return false; 1816 } 1817 1818 if ( 'false' === settings['tooltip'] || 'undefined' === typeof settings['tooltip'] || '' === settings['tooltipDescription'] ) { 1819 self.destroyTooltipInstance(); 1820 self.removeTooltipContent(); 1821 return false; 1822 } 1823 1824 $scope.addClass( 'jet-tooltip-widget' ); 1825 1826 tooltipSelector = widgetSelector; 1827 if ( settings['customSelector'] ) { 1828 var customEl = $( '.' + settings['customSelector'], $scope )[0]; 1829 if ( customEl ) { 1830 tooltipSelector = customEl; 1831 } 1832 } 1833 1834 if ( editMode && ! $( '#jet-tricks-tooltip-content-' + widgetId )[0] ) { 1835 var rootTag = ( $scope[0] && $scope[0].tagName ) ? $scope[0].tagName.toLowerCase() : ''; 1836 var wrapperTag = [ 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ].indexOf( rootTag ) !== -1 ? 'span' : 'div'; 1837 var template = $( '<' + wrapperTag + '>', { 1838 id: 'jet-tricks-tooltip-content-' + widgetId, 1839 class: 'jet-tooltip-widget__content' 1840 } ); 1841 1842 template.html( settings['tooltipDescription'] ); 1843 $scope.append( template ); 1844 } 1845 1846 $window.off( 'resize.jetTooltip' + widgetId ); 1847 $window.on( 'resize.jetTooltip' + widgetId, function() { 1848 clearTimeout( resizeTimer ); 1849 resizeTimer = setTimeout( function() { 1850 self.refreshTooltipForDevice(); 1851 }, 200 ); 1852 } ); 1853 1854 if ( editMode && document.body ) { 1855 var editorBindingsCleanupKey = 'jetTooltipEditorBindingsCleanup'; 1856 var prevEditorCleanup = $scope.data( editorBindingsCleanupKey ); 1857 if ( typeof prevEditorCleanup === 'function' ) { 1858 prevEditorCleanup(); 1859 } 1860 $scope.removeData( editorBindingsCleanupKey ); 1861 1862 var onEditorDeviceModeChange = function() { 1863 clearTimeout( resizeTimer ); 1864 resizeTimer = setTimeout( function() { 1865 self.refreshTooltipForDevice(); 1866 }, 50 ); 1867 }; 1868 window.addEventListener( 'elementor/device-mode/change', onEditorDeviceModeChange ); 1869 var deviceModeObserver = new MutationObserver( function( mutations ) { 1870 var i; 1871 for ( i = 0; i < mutations.length; i++ ) { 1872 if ( mutations[ i ].attributeName === 'data-elementor-device-mode' ) { 1873 onEditorDeviceModeChange(); 1874 break; 1875 } 1876 } 1877 } ); 1878 deviceModeObserver.observe( document.body, { 1879 attributes: true, 1880 attributeFilter: [ 'data-elementor-device-mode' ] 1881 } ); 1882 1883 $scope.data( editorBindingsCleanupKey, function jetTooltipEditorBindingsCleanup() { 1884 window.removeEventListener( 'elementor/device-mode/change', onEditorDeviceModeChange ); 1885 deviceModeObserver.disconnect(); 1886 } ); 1887 } 1888 1889 self.refreshTooltipForDevice(); 1890 1891 }; 1892 }; 1893 1894 JetTricks.initBlocksExtensions = function() { 1895 var isBlockEditorContext = !! ( 1896 document.body && ( 1897 document.body.classList.contains( 'block-editor-page' ) || 1898 document.body.classList.contains( 'block-editor-iframe__body' ) || 1899 document.body.classList.contains( 'editor-styles-wrapper' ) 1900 ) 1901 ) || !! document.querySelector( '.block-editor-block-list__layout, .edit-post-visual-editor' ); 1902 1903 $( '[data-jet-tricks-settings]' ).each( function() { 1904 var $scope = $( this ), 1905 settings = $scope.data( 'jet-tricks-settings' ); 1906 1907 if ( ! settings ) { 1908 return; 1909 } 1910 1911 if ( settings['parallax'] === 'true' ) { 1912 new jetWidgetParallax( $scope ).init(); 1913 } 1914 1915 if ( settings['satellite'] === 'true' && ! isBlockEditorContext ) { 1916 new jetWidgetSatellite( $scope ).init(); 1917 } 1918 1919 if ( settings['tooltip'] === 'true' && typeof tippy !== 'undefined' && ! isBlockEditorContext ) { 1920 new jetWidgetTooltip( $scope ).init(); 1921 } 1922 1923 if ( settings['scrollReveal'] === 'true' || settings['scrollReveal'] === true ) { 1924 new jetWidgetScrollReveal( $scope ).init(); 1925 } 1926 } ); 1927 1928 JetTricks.initBlocksParticles(); 1929 }; 1930 1931 JetTricks.initBlocksParticles = function() { 1932 $( '.jet-tricks-particles-section[data-jet-tricks-particles="true"]' ).each( function() { 1933 var $scope = $( this ), 1934 blockId = $scope.attr( 'data-jet-tricks-particles-id' ), 1935 jsonStr = $scope.attr( 'data-jet-tricks-particles-json' ); 1936 1937 if ( ! blockId || ! jsonStr ) { 1938 return; 1939 } 1940 1941 try { 1942 var particlesJson = JSON.parse( jsonStr ); 1943 } catch ( e ) { 1944 return; 1945 } 1946 1947 JetTricks.loadParticles( $scope, 'jet-tricks-particles-instance-' + blockId, particlesJson ); 1948 } ); 1949 }; 1950 1951 JetTricks.destroyBlockStickyColumn = function( $target ) { 1952 $target.css( { 1953 position: '', 1954 top: '', 1955 bottom: '', 1956 alignSelf: '', 1957 zIndex: '', 1958 } ); 1959 1960 }; 1961 1962 JetTricks.getBlockStickyAlign = function( settings ) { 1963 var align = settings && settings.stickyAlign ? String( settings.stickyAlign ) : 'top'; 1964 1965 if ( -1 === [ 'top', 'center', 'bottom' ].indexOf( align ) ) { 1966 align = 'top'; 1967 } 1968 1969 return align; 1970 }; 1971 1972 JetTricks.applyBlockStickyColumn = function( $target, settings, topSpacing, bottomSpacing ) { 1973 var align = JetTricks.getBlockStickyAlign( settings ); 1974 var alignSelf = 'flex-start'; 1975 1976 if ( 'bottom' === align ) { 1977 alignSelf = 'flex-end'; 1978 } else if ( 'center' === align ) { 1979 alignSelf = 'center'; 1980 } 1981 1982 $target.css( { 1983 position: 'sticky', 1984 top: topSpacing, 1985 bottom: bottomSpacing, 1986 alignSelf: alignSelf, 1987 zIndex: settings.zIndex !== undefined && settings.zIndex !== null && settings.zIndex !== '' ? settings.zIndex : '', 1988 } ); 1989 }; 1990 1991 JetTricks.initBlockStickyColumn = function( $target ) { 1992 var raw = $target.attr( 'data-jet-settings' ); 1993 var settings = raw; 1994 if ( typeof settings === 'string' ) { 1995 try { 1996 settings = JSON.parse( settings ); 1997 } catch ( e ) { 1998 return; 1999 } 2000 } 2001 if ( ! settings || typeof settings !== 'object' || ! settings.stickyOn || ! settings.stickyOn.length ) { 2002 return; 2003 } 2004 2005 var topS = parseInt( settings.topSpacing, 10 ); 2006 if ( settings.topSpacing === undefined || settings.topSpacing === null || settings.topSpacing === '' || window.isNaN( topS ) ) { 2007 topS = 50; 2008 } 2009 var bottomS = parseInt( settings.bottomSpacing, 10 ); 2010 if ( settings.bottomSpacing === undefined || settings.bottomSpacing === null || settings.bottomSpacing === '' || window.isNaN( bottomS ) ) { 2011 bottomS = 50; 2012 } 2013 2014 var allowed = -1 !== settings.stickyOn.indexOf( JetTricks.getDeviceMode() ); 2015 2016 if ( ! allowed ) { 2017 JetTricks.destroyBlockStickyColumn( $target ); 2018 return; 2019 } 2020 2021 var $row = $target.closest( '.wp-block-columns' ); 2022 if ( ! $row.length ) { 2023 JetTricks.destroyBlockStickyColumn( $target ); 2024 return; 2025 } 2026 2027 JetTricks.applyBlockStickyColumn( $target, settings, topS, bottomS ); 2028 }; 2029 2030 JetTricks.initBlocksStickyColumns = function() { 2031 $( '.wp-block-column.jet-sticky-column' ).each( function() { 2032 JetTricks.initBlockStickyColumn( $( this ) ); 2033 } ); 2034 2035 if ( ! JetTricks._blockStickyResizeBound ) { 2036 JetTricks._blockStickyResizeBound = true; 2037 $( window ).on( 2038 'resize.jetTricksBlockSticky orientationchange.jetTricksBlockSticky', 2039 JetTricksTools.debounce( 150, function() { 2040 $( '.wp-block-column.jet-sticky-column' ).each( function() { 2041 JetTricks.initBlockStickyColumn( $( this ) ); 2042 } ); 2043 } ) 2044 ); 2045 } 2046 }; 2047 2048 window.JetTricks = JetTricks; 2049 2050 if ( window.JetPlugins ) { 2051 JetTricks.initBlocks(); 2052 $( function() { JetPlugins.init() } ); 2053 } 2054 2055 $( function() { 2056 JetTricks.initBlocksExtensions(); 2057 JetTricks.initBlocksStickyColumns(); 2058 } ); 2059 2060}( jQuery, window.elementorFrontend ) );
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.