1// Promise polyfill 2!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n():"function"==typeof define&&define.amd?define(n):n()}(0,function(){"use strict";function e(e){var n=this.constructor;return this.then(function(t){return n.resolve(e()).then(function(){return t})},function(t){return n.resolve(e()).then(function(){return n.reject(t)})})}function n(e){return!(!e||"undefined"==typeof e.length)}function t(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=undefined,this._deferreds=[],c(e,this)}function r(e,n){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn(function(){var t=1===e._state?n.onFulfilled:n.onRejected;if(null!==t){var o;try{o=t(e._value)}catch(r){return void f(n.promise,r)}i(n.promise,o)}else(1===e._state?i:f)(n.promise,e._value)})):e._deferreds.push(n)}function i(e,n){try{if(n===e)throw new TypeError("A promise cannot be resolved with itself.");if(n&&("object"==typeof n||"function"==typeof n)){var t=n.then;if(n instanceof o)return e._state=3,e._value=n,void u(e);if("function"==typeof t)return void c(function(e,n){return function(){e.apply(n,arguments)}}(t,n),e)}e._state=1,e._value=n,u(e)}catch(r){f(e,r)}}function f(e,n){e._state=2,e._value=n,u(e)}function u(e){2===e._state&&0===e._deferreds.length&&o._immediateFn(function(){e._handled||o._unhandledRejectionFn(e._value)});for(var n=0,t=e._deferreds.length;t>n;n++)r(e,e._deferreds[n]);e._deferreds=null}function c(e,n){var t=!1;try{e(function(e){t||(t=!0,i(n,e))},function(e){t||(t=!0,f(n,e))})}catch(o){if(t)return;t=!0,f(n,o)}}var a=setTimeout;o.prototype["catch"]=function(e){return this.then(null,e)},o.prototype.then=function(e,n){var o=new this.constructor(t);return r(this,new function(e,n,t){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof n?n:null,this.promise=t}(e,n,o)),o},o.prototype["finally"]=e,o.all=function(e){return new o(function(t,o){function r(e,n){try{if(n&&("object"==typeof n||"function"==typeof n)){var u=n.then;if("function"==typeof u)return void u.call(n,function(n){r(e,n)},o)}i[e]=n,0==--f&&t(i)}catch(c){o(c)}}if(!n(e))return o(new TypeError("Promise.all accepts an array"));var i=Array.prototype.slice.call(e);if(0===i.length)return t([]);for(var f=i.length,u=0;i.length>u;u++)r(u,i[u])})},o.resolve=function(e){return e&&"object"==typeof e&&e.constructor===o?e:new o(function(n){n(e)})},o.reject=function(e){return new o(function(n,t){t(e)})},o.race=function(e){return new o(function(t,r){if(!n(e))return r(new TypeError("Promise.race accepts an array"));for(var i=0,f=e.length;f>i;i++)o.resolve(e[i]).then(t,r)})},o._immediateFn="function"==typeof setImmediate&&function(e){setImmediate(e)}||function(e){a(e,0)},o._unhandledRejectionFn=function(e){void 0!==console&&console&&console.warn("Possible Unhandled Promise Rejection:",e)};var l=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if("undefined"!=typeof global)return global;throw Error("unable to locate global object")}();"Promise"in l?l.Promise.prototype["finally"]||(l.Promise.prototype["finally"]=e):l.Promise=o}); 3 4( function( $, elementor, settings ) { 5 6 'use strict'; 7 8 var JetTabs = { 9 10 addedScripts: {}, 11 12 addedStyles: {}, 13 14 addedAssetsPromises: [], 15 16 init: function() { 17 var widgets = { 18 'jet-tabs.default': JetTabs.tabsInit, 19 'jet-accordion.default': JetTabs.accordionInit, 20 'jet-image-accordion.default': JetTabs.imageAccordionInit, 21 'jet-switcher.default': JetTabs.switcherInit, 22 }; 23 24 $.each( widgets, function( widget, callback ) { 25 elementor.hooks.addAction( 'frontend/element_ready/' + widget, callback ); 26 }); 27 28 // Add an action when the Swiper Loop Carousel widget is ready on the frontend 29 elementorFrontend.hooks.addAction('frontend/element_ready/loop-carousel.post', function($scope, $) { 30 31 $(window).on('load', function() { 32 33 var loopCarousel = $scope.find('.swiper'), 34 swiperInstance = loopCarousel.data( 'swiper' ), 35 $toggle = $scope.find( '.jet-toggle__control'), 36 $switcher = $scope.find( '.jet-switcher__control-instance'); 37 38 if( swiperInstance && ($toggle || $switcher) ) { 39 40 swiperInstance.on('slideChange', function () { 41 $toggle.off('click.jetAccordion'); 42 $switcher.off('click.jetSwitcher'); 43 JetTabs.initLoopCarouselHandlers( $scope ); 44 }); 45 } 46 }); 47 }); 48 }, 49 50 initLoopCarouselHandlers: function( $selector ) { 51 $selector.find( '.elementor-widget-jet-accordion, .elementor-widget-jet-switcher' ).each( function() { 52 53 var $this = $( this ), 54 55 elementType = $this.data( 'element_type' ); 56 57 if ( !elementType ) { 58 return; 59 } 60 61 if ( 'widget' === elementType ) { 62 elementType = $this.data( 'widget_type' ); 63 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 64 } 65 66 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 67 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 68 69 70 } ); 71 }, 72 73 tabsInit: async function( $scope ) { 74 var $target = $( '.jet-tabs', $scope ).first(), 75 $widgetId = $target.data( 'id' ),
76 $window = $( window ), 77 $controlWrapper = $( '.jet-tabs__control-wrapper', $target ).first(), 78 $contentWrapper = $( '.jet-tabs__content-wrapper', $target ).first(), 79 $controlList = $( '.jet-tabs__control', $controlWrapper ), 80 $contentList = $( '> .jet-tabs__content', $contentWrapper ), 81 settings = $.extend( $target.data( 'settings' ) || {}, JetTabs.getElementorElementSettings( $scope ) ), 82 anchorSelectors = [], 83 toogleEvents = 'mouseenter mouseleave', 84 scrollOffset, 85 autoSwitchInterval = null, 86 resumeTimeout = null, 87 curentHash = window.location.hash || false, 88 tabsArray = curentHash ? curentHash.replace( '#', '' ).split( '&' ) : false, 89 $tabsPosition = settings['tabsPosition'], 90 $tabsPositionClassList = [], 91 $tabsPositionBreakpoints = [], 92 prevDevice, 93 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(), 94 activeBreakpoints = elementor.config.responsive.activeBreakpoints, 95 swiperSettings = $target.data( 'swiper-settings' ) || {}, 96 swiper; 97 98 JetTabs.prepareVideoIframes( $contentWrapper ); 99 JetTabs.observeVideoIframes( $contentWrapper ); 100 101 function syncSwiperToIndex( index, immediate = false ) { 102 if ( ! swiper ) return; 103 try { 104 swiper.slideToLoop( index, immediate ? 0 : swiperOptions.speed, true ); 105 } catch ( e ) { 106 } 107 } 108 109 prevDevice = 'desktop'; 110 111 $tabsPositionBreakpoints['desktop'] = '' != settings['tabs_position'] ? settings['tabs_position'] : 'top'; 112 $tabsPositionClassList['desktop'] = "jet-tabs-position-" + $tabsPositionBreakpoints['desktop']; 113 114 Object.keys( activeBreakpoints ).reverse().forEach( function( breakpointName ) { 115 116 if ( 'widescreen' === breakpointName ) { 117 $tabsPositionBreakpoints[breakpointName] = ( settings['tabs_position_' + breakpointName] && '' != settings['tabs_position_' + breakpointName] ) ? settings['tabs_position_' + breakpointName] : 'top'; 118 $tabsPositionClassList[breakpointName] = "jet-tabs-position-" + $tabsPositionBreakpoints[breakpointName]; 119 } else { 120 $tabsPositionBreakpoints[breakpointName] = ( settings['tabs_position_' + breakpointName] && '' != settings['tabs_position_' + breakpointName] ) ? settings['tabs_position_' + breakpointName] : $tabsPositionBreakpoints[prevDevice]; 121 $tabsPositionClassList[breakpointName] = "jet-tabs-position-" + $tabsPositionBreakpoints[breakpointName]; 122 123 prevDevice = breakpointName; 124 } 125 } ); 126 127 if ( !$target.hasClass( $tabsPositionClassList[currentDeviceMode] ) ) { 128 for ( const [key, value] of Object.entries( $tabsPositionClassList ) ) { 129 $target.removeClass( value ); 130 } 131 132 $target.addClass( $tabsPositionClassList[currentDeviceMode] ); 133 } 134 135 if ( 'click' === settings['event'] ) { 136 addClickEvent(); 137 } else { 138 addMouseEvent(); 139 } 140 141 $window.load(function() { 142 143 var currentActiveContent = $contentList.eq( [settings['activeIndex']] ), 144 currentActiveContentHeight = currentActiveContent.outerHeight( true ); 145 146 if ( 'yes' != settings['no_active_tabs'] ) { 147 currentActiveContentHeight += parseInt( $contentWrapper.css( 'border-top-width' ) ) + parseInt( $contentWrapper.css( 'border-bottom-width' ) ); 148 $contentWrapper.css( 'min-height', currentActiveContentHeight ); 149 } 150 151 }); 152 153 if ( 'left' !== $tabsPositionBreakpoints[currentDeviceMode] && 'right' !== $tabsPositionBreakpoints[currentDeviceMode] ) { 154 var observerConfig = {childList: true, subtree: true }, 155 observerTarget = $( ".jet-tabs__content.active-content", $scope ); 156 157 if ( observerTarget[0] ) { 158 var observerCallback = ( mutationList, observer ) => { 159 for ( var mutation of mutationList ) { 160 if ( mutation.type === 'childList' ) { 161 observerTarget.closest( '.jet-tabs__content-wrapper' ).css( 'min-height', 'auto' ); 162 163 var activeContentHeight = observerTarget.outerHeight( true ); 164 165 activeContentHeight += parseInt( observerTarget.css( 'border-top-width' ) ) + parseInt( observerTarget.css( 'border-bottom-width' ) ); 166 observerTarget.closest( '.jet-tabs__content-wrapper' ).css( 'min-height', activeContentHeight ); 167 } 168 } 169 }; 170 171 var observer = new MutationObserver( observerCallback ); 172 173 observer.observe( observerTarget[0], observerConfig ); 174 } 175 } 176 177 const swiperOptions = { 178 slidesPerView: 'auto', 179 centeredSlides: swiperSettings.centeredSlides || false, 180 loop: swiperSettings.loop || false, 181 loopFillGroupWithBlank: true, 182 speed: 300, 183 navigation: { 184 nextEl: $target.find('.swiper-button-next')[0], 185 prevEl: $target.find('.swiper-button-prev')[0], 186 }, 187 keyboard: true, 188 allowTouchMove: true, 189 slideToClickedSlide: false, 190 autoplay: settings['autoSwitch'] ? { 191 delay: settings['autoSwitchDelay'], 192 disableOnInteraction: false, 193 stopOnLastSlide: true, 194 } : false, 195 }; 196 197 const $swiper = $scope.find( '.jet-tabs-swiper' ), 198 adjustedDelay = settings['autoSwitchDelay'] ? +settings['autoSwitchDelay'] + ( $swiper.length ? swiperOptions.speed : 0 ) : 0; 199 200 function scheduleAutoSwitch( fromIndex ) { 201 if ( ! settings[ 'autoSwitch' ] ) return; 202
203 var controlListLength = $controlList.length; 204 205 clearInterval( autoSwitchInterval ); 206 if ( resumeTimeout ) clearTimeout( resumeTimeout ); 207 208 var nextIndex = ( typeof fromIndex === 'number' ) 209 ? fromIndex 210 : ( settings[ 'activeIndex' ] === -1 ? -1 : settings[ 'activeIndex' ] ); 211 212 autoSwitchInterval = setInterval( function() { 213 nextIndex = ( nextIndex + 1 + controlListLength ) % controlListLength; 214 215 if ( settings[ 'ajaxTemplate' ] ) { 216 ajaxLoadTemplate( nextIndex ); 217 } 218 switchTab( nextIndex ); 219 if ( $swiper.length ) { 220 syncSwiperToIndex( nextIndex ); 221 const $swiperContainer = $swiper.find( '.jet-tabs-swiper-container' ); 222 $swiperContainer.find( '.swiper-slide' ).removeClass( 'active-tab' ); 223 $swiperContainer.find( '.swiper-slide[data-swiper-slide-index="' + nextIndex + '"]' ).addClass( 'active-tab' ); 224 } 225 }, adjustedDelay ); 226 } 227 228 function resumeAutoSwitch( fromIndex ) { 229 if ( ! settings[ 'autoSwitch' ] ) return; 230 231 clearInterval( autoSwitchInterval ); 232 if ( resumeTimeout ) clearTimeout( resumeTimeout ); 233 234 resumeTimeout = setTimeout( function() { 235 scheduleAutoSwitch( fromIndex ); 236 }, adjustedDelay ); 237 } 238 239 function stopAutoplay() { 240 if ( swiper.autoplay && swiper.autoplay.running ) { 241 swiper.autoplay.stop(); 242 clearInterval( autoSwitchInterval ); 243 } 244 } 245 246 if ( $swiper.length ) { 247 const $swiperContainer = $swiper.find( '.jet-tabs-swiper-container' ); 248 249 if ( swiperSettings.slidesPerView === 'fixed' ) { 250 $swiperContainer.find( '.swiper-slide' ).css( 'width', swiperSettings.itemWidth ); 251 } 252 253 if ( $swiperContainer.length && $swiperContainer.hasClass( 'swiper' ) ) { 254 swiper = await new window.elementorFrontend.utils.swiper( $swiperContainer[0], swiperOptions ); 255 256 const formFieldSelector = [ 257 '.jet-tabs__content-wrapper input', 258 '.jet-tabs__content-wrapper textarea', 259 '.jet-tabs__content-wrapper select', 260 '.jet-tabs__content-wrapper [contenteditable="true"]', 261 ].join(', '); 262 263 $target.on('keydown.jetTabsSwiperFix', formFieldSelector, function( e ) { 264 var code = e.which || e.keyCode; 265 266 if ( code === 37 || code === 38 || code === 39 || code === 40 ) { 267 e.stopPropagation(); 268 } 269 }); 270 271 const initialIndex = settings['activeIndex'] === -1 ? 0 : settings['activeIndex']; 272 273 swiper.slideToLoop( initialIndex, 0, false ); 274 275 if ( settings['autoSwitch'] && settings['activeIndex'] === -1 ) { 276 swiper.autoplay.stop(); 277 setTimeout( () => swiper.autoplay.start(), adjustedDelay ); 278 } 279 280 swiper.on( 'reachEnd', function () { 281 282 if ( settings['autoSwitch'] && swiper.isEnd && ! swiperSettings.loop ) { 283 const lastSlide = $swiperContainer.find( '.swiper-slide' ).last()[0]; 284 285 const observer = new MutationObserver( ( mutationsList ) => { 286 287 for ( const mutation of mutationsList ) { 288 if ( mutation.type === 'attributes' && lastSlide.classList.contains('active-tab') ) { 289 observer.disconnect(); 290 291 setTimeout( () => { 292 swiper.slideTo( 0, swiperOptions.speed, true ); 293 swiper.autoplay.start(); 294 }, adjustedDelay ); 295 296 } 297 } 298 299 }); 300 301 observer.observe( lastSlide, { attributes: true, attributeFilter: ['class'] } ); 302 } 303 304 }); 305 306 function handleTabSwitch( eventSlide ) { 307 const realIndex = parseInt( eventSlide.getAttribute( 'data-swiper-slide-index' ), 10 ); 308 309 $swiperContainer.find('.swiper-slide.active-tab').removeClass('active-tab'); 310 $( eventSlide ).addClass('active-tab'); 311 312 switchTab( realIndex ); 313 stopAutoplay(); 314 clearInterval( autoSwitchInterval ); 315 } 316 317 function addHoverAndTouchEvents() { 318 const $allSlides = $swiperContainer.find( '.swiper-slide' ); 319 320 $allSlides.off( 'mouseenter touchend' ); 321 322 $allSlides.on( 'mouseenter', function () { 323 stopAutoplay(); 324 handleTabSwitch( this ); 325 }); 326 327 $allSlides.on( 'touchend', function () { 328 329 if ( scrollOffset !== $( window ).scrollTop() ) { 330 return false;
331 } 332 333 handleTabSwitch( this ); 334 }); 335 } 336 337 if ( swiperSettings.loop ) { 338 if ( settings['event'] === 'click' ) { 339 swiper.on( 'click', function () { 340 341 if ( swiper.clickedSlide ) { 342 handleTabSwitch( swiper.clickedSlide) ; 343 } 344 345 }); 346 } else if ( settings['event'] === 'hover' ) { 347 addHoverAndTouchEvents(); 348 349 swiper.on( 'transitionEnd', function () { 350 addHoverAndTouchEvents(); 351 }); 352 } 353 } 354 355 $swiperContainer.on( 'click', function() { 356 stopAutoplay(); 357 clearInterval( autoSwitchInterval ); 358 }); 359 360 if ( settings['event'] === 'hover' ) { 361 $swiperContainer.on('mouseenter', function () { 362 stopAutoplay(); 363 }); 364 } 365 366 swiper.on( 'autoplay', function () { 367 $swiperContainer.find('.swiper-slide').removeClass('active-tab'); 368 369 const currentIndex = swiper.realIndex; 370 $swiperContainer.find('.swiper-slide[data-swiper-slide-index="' + currentIndex + '"]').addClass('active-tab'); 371 }); 372 373 swiper.on( 'navigationPrev', stopAutoplay ); 374 swiper.on( 'navigationNext', stopAutoplay ); 375 swiper.on( 'touchStart', stopAutoplay ); 376 } 377 } 378 379 if ( settings[ 'autoSwitch' ] ) { 380 var currentIndex = -1; 381 autoSwitchInterval = setInterval( function() { 382 var $visibleControls = $controlWrapper.find( '.jet-tabs__control:visible' ); 383 var len = $visibleControls.length; 384 385 if ( ! len ) return; 386 387 currentIndex = ( currentIndex + 1 ) % len; 388 389 var $activeControl = $visibleControls.eq( currentIndex ); 390 var tabId = parseInt( $activeControl.data( 'tab' ), 10 ) - 1; 391 392 if ( settings[ 'ajaxTemplate' ] && $activeControl.data( 'template-id' ) ) { 393 ajaxLoadTemplate( tabId ); 394 } 395 396 switchTab( tabId ); 397 398 }, adjustedDelay ); 399 400 } 401 402 if ( settings['ajaxTemplate'] ) { 403 ajaxLoadTemplate( settings['activeIndex'] ); 404 } 405 406 $( window ).on( 'resize.jetTabs orientationchange.jetTabs', JetTabs.debounce( 50, function() { 407 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(); 408 409 for ( const [key, value] of Object.entries( $tabsPositionClassList ) ) { 410 $target.removeClass( value ); 411 } 412 413 $target.addClass( $tabsPositionClassList[currentDeviceMode] ); 414 } ) ); 415 416 /** 417 * [addClickEvent description] 418 */ 419 function addClickEvent() { 420 $controlList.on( 'click.jetTabs', function() { 421 var $this = $( this ), 422 tabId = +$this.data( 'tab' ) - 1, 423 templateId = $this.data( 'template-id' ); 424 425 clearInterval( autoSwitchInterval ); 426 427 if ( settings['ajaxTemplate'] && templateId ) { 428 ajaxLoadTemplate( tabId ); 429 } 430 431 switchTab( tabId ); 432 resumeAutoSwitch( tabId ); 433 }); 434 } 435 436 /** 437 * [addMouseEvent description] 438 */ 439 function addMouseEvent() { 440 if ( 'ontouchend' in window || 'ontouchstart' in window ) { 441 $controlList.on( 'touchstart', function( event ) { 442 scrollOffset = $( window ).scrollTop(); 443 } ); 444 445 $controlList.on( 'touchend', function( event ) { 446 var $this = $( this ), 447 tabId = +$this.data( 'tab' ) - 1, 448 templateId = $this.data( 'template-id' ); 449 450 if ( scrollOffset !== $( window ).scrollTop() ) { 451 return false; 452 } 453 454 clearInterval( autoSwitchInterval ); 455 456 if ( settings['ajaxTemplate'] && templateId ) { 457 ajaxLoadTemplate( tabId ); 458 } 459 460 switchTab( tabId ); 461 if ( $swiper.length ) syncSwiperToIndex( tabId ); 462 resumeAutoSwitch( tabId ); 463 } ); 464 465 } else { 466 $controlList.on( 'mouseenter', function( event ) { 467 var $this = $( this ), 468 tabId = +$this.data( 'tab' ) - 1, 469 templateId = $this.data( 'template-id' ); 470 471 clearInterval( autoSwitchInterval ); 472 473 if ( settings['ajaxTemplate'] && templateId ) { 474 ajaxLoadTemplate( tabId ); 475 } 476 477 switchTab( tabId ); 478 } ); 479 } 480 } 481 482 $( '.jet-tabs__control', $scope ).keydown( function( e ) { 483 var $this = $( this ), 484 $which = e.which || e.keyCode; 485 486 if ( $which == 13 || $which == 32 ) { 487 if ( !$this.hasClass( 'active-tab' ) ) { 488 $this.click(); 489 return false;
490 } 491 } 492 493 if ( $which == 37 ) { 494 var prevTabId = $this.prev().data('tab'), 495 templateId = $this.prev().data( 'template-id' ); 496 497 if ( undefined != prevTabId ) { 498 clearInterval( autoSwitchInterval ); 499 500 if ( settings['ajaxTemplate'] && templateId ) { 501 ajaxLoadTemplate( prevTabId - 1 ); 502 } 503 504 switchTab( prevTabId - 1); 505 $this.prev().focus(); 506 } else { 507 $this.focus(); 508 } 509 } 510 511 if ( $which == 39 ) { 512 var nextTabId = $this.next().data('tab'), 513 templateId = $this.next().data( 'template-id' ); 514 515 if ( undefined != nextTabId ) { 516 clearInterval( autoSwitchInterval ); 517 518 if ( settings['ajaxTemplate'] && templateId ) { 519 ajaxLoadTemplate( nextTabId - 1 ); 520 } 521 522 switchTab( nextTabId - 1 ); 523 $this.next().focus(); 524 } else { 525 $this.focus(); 526 } 527 } 528 } ); 529 530 /** 531 * [switchTab description] 532 * @param {[type]} curentIndex [description] 533 * @return {[type]} [description] 534 */ 535 function switchTab( curentIndex ) { 536 var activeContentHeight = 'auto', 537 timer, 538 $controlWrapperHeight = $controlWrapper.outerHeight( true ), 539 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(), 540 controlsHeight = 0; 541 542 $controlList = $controlWrapper.find( '.jet-tabs__control' ); 543 $contentList = $contentWrapper.children( '.jet-tabs__content' ); 544 545 var $prevActiveContent = $contentWrapper.children( '.jet-tabs__content.active-content' ); 546 JetTabs.pauseMediaInContainer( $prevActiveContent ); 547 548 var $activeControl = $controlList.filter( '[data-tab="' + ( curentIndex + 1 ) + '"]' ).first(); 549 550 if ( ! $activeControl.length ) { 551 $activeControl = $controlList.eq( curentIndex ); 552 } 553 554 var controlId = $activeControl.attr( 'id' ); 555 var $activeContent = controlId 556 ? $contentList.filter( '[aria-labelledby="' + controlId + '"]' ) 557 : $(); 558 559 if ( ! $activeContent.length ) { 560 $activeContent = $contentList.filter( '[data-tab="' + ( curentIndex + 1 ) + '"]' ); 561 } 562 if ( ! $activeContent.length ) { 563 $activeContent = $contentList.eq( curentIndex ); 564 } 565 566 $controlList.removeClass( 'active-tab' ).attr( 'aria-expanded', 'false' ); 567 $contentList.removeClass( 'active-content' ).attr( 'aria-hidden', 'true' ); 568 569 $activeControl.addClass( 'active-tab' ).attr( 'aria-expanded', 'true' ); 570 $activeContent.addClass( 'active-content' ).attr( 'aria-hidden', 'false' ); 571 JetTabs.restoreMediaInContainer( $activeContent ); 572 573 574 if ( $controlWrapper.css( 'align-self' ) === 'stretch' ) { 575 $( '.jet-tabs__control', $controlWrapper ).each( function() { 576 controlsHeight += $( this ).outerHeight( true ); 577 } ); 578 $controlWrapperHeight = controlsHeight; 579 } 580 581 activeContentHeight = $activeContent.outerHeight( true ); 582 activeContentHeight += parseInt( $contentWrapper.css( 'border-top-width' ) ) + parseInt( $contentWrapper.css( 'border-bottom-width' ) ); 583 584 if ( 'left' === $tabsPositionBreakpoints[ currentDeviceMode ] || 'right' === $tabsPositionBreakpoints[ currentDeviceMode ] ) { 585 if ( activeContentHeight < $controlWrapperHeight ) { 586 $target.css( { 'min-height': 'auto' } ); 587 $contentWrapper.css( { 'min-height': $controlWrapperHeight } ); 588 $target.css( { 'min-height': $controlWrapperHeight } ); 589 } else if ( activeContentHeight < $contentWrapper.outerHeight( true ) ) { 590 $contentWrapper.css( { 'min-height': activeContentHeight } ); 591 $target.css( { 'min-height': activeContentHeight } ); 592 } 593 } else { 594 $contentWrapper.css( { 'min-height': activeContentHeight } ); 595 596 var observerConfig = { childList: true, subtree: true }, 597 observerTarget = $contentWrapper; 598 599 if ( observerTarget[ 0 ] ) { 600 var observerCallback = ( mutationList, observer ) => { 601 for ( var mutation of mutationList ) { 602 if ( mutation.type === 'childList' ) { 603 activeContentHeight = $activeContent.outerHeight( true ); 604 activeContentHeight += parseInt( $contentWrapper.css( 'border-top-width' ) ) + parseInt( $contentWrapper.css( 'border-bottom-width' ) ); 605 $contentWrapper.css( { 'min-height': activeContentHeight } ); 606 } 607 } 608 }; 609 610 var observer = new MutationObserver( observerCallback ); 611 612 observer.observe( observerTarget[ 0 ], observerConfig ); 613 } 614 } 615 616 $window.trigger( 'jet-tabs/tabs/show-tab-event/before', { 617 target: $target, 618 tabIndex: curentIndex, 619 } ); 620 621 if ( timer ) { 622 clearTimeout( timer ); 623 } 624 625 timer = setTimeout( function() { 626 $window.trigger( 'jet-tabs/tabs/show-tab-event/after', { 627 target: $target, 628 tabIndex: curentIndex, 629 } ); 630 631 if ( true === settings['switchScrolling'] ) { 632 $( 'html, body' ).animate( { 633 scrollTop: $contentWrapper.offset().top - settings['switchScrollingOffset']['size'] 634 }, 300 ); 635 } 636 }, 500 ); 637 } 638 639 /** 640 * [ajaxLoadTemplate description] 641 * @param {[type]} $index [description] 642 * @return {[type]} [description] 643 */ 644 function ajaxLoadTemplate( $index ) { 645 var $contentHolder = $contentList.eq( $index ), 646 templateLoaded = $contentHolder.data( 'template-loaded' ) || false, 647 templateId = $contentHolder.data( 'template-id' ), 648 loader = $( '.jet-tabs-loader', $contentHolder ), 649 ajaxData = { 650 'id': templateId, 651 'dev': window.JetTabsSettings.devMode, 652 }; 653 654 if ( templateLoaded || false === templateId ) { 655 return false;
656 } 657 658 $window.trigger( 'jet-tabs/ajax-load-template/before', { 659 toggleIndex: $index, 660 target: $target, 661 contentHolder: $contentHolder 662 } ); 663 664 $contentHolder.data( 'template-loaded', true ); 665 666 if ( window.JetTabsSettings.isSelfRequest ) { 667 ajaxData['jet_tabs_self'] = 1; 668 ajaxData['no-cache'] = 'true'; 669 ajaxData['timeStamp'] = Date.now(); 670 } 671 672 $.ajax( { 673 type: 'GET', 674 url: window.JetTabsSettings.templateApiUrl, 675 dataType: 'json', 676 data: ajaxData, 677 success: function( response ) { 678 if ( ! response || 'undefined' === typeof response.template_content ) { 679 loader.remove(); 680 $contentHolder.data( 'template-loaded', false ); 681 return; 682 } 683 684 var templateContent = response.template_content, 685 templateScripts = response.template_scripts || {}, 686 templateStyles = response.template_styles || {}, 687 assetsPromises = []; 688 689 for ( var scriptHandler in templateScripts ) { 690 assetsPromises.push( 691 JetTabs.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) 692 ); 693 } 694 695 for ( var styleHandler in templateStyles ) { 696 assetsPromises.push( 697 JetTabs.loadStyle( styleHandler, templateStyles[ styleHandler ] ) 698 ); 699 } 700 701 Promise.allSettled( assetsPromises ).then( function( results ) { 702 loader.remove(); 703 704 $contentHolder.html( templateContent ); 705 706 JetTabs.prepareVideoIframes( $contentHolder ); 707 JetTabs.observeVideoIframes( $contentWrapper ); 708 JetTabs.elementorFrontendInit( $contentHolder ); 709 710 $window.trigger( 'jet-tabs/ajax-load-template/after', { 711 toggleIndex: $index, 712 target: $target, 713 contentHolder: $contentHolder, 714 responce: response, 715 response: response 716 } ); 717 }, ); 718 }, 719 error: function( jqXHR, textStatus, errorThrown ) { 720 loader.remove(); 721 $contentHolder.data( 'template-loaded', false ); 722 } 723 } );//end 724 } 725 726 // Hash Watch Handler 727 if ( tabsArray ) { 728 729 $controlList.each( function( index ) { 730 var $this = $( this ), 731 id = $this.attr( 'id' ), 732 templateId = $this.data( 'template-id' ), 733 tabIndex = index; 734 735 tabsArray.forEach( function( itemHash, i ) { 736 737 if ( itemHash === id ) { 738 739 if ( settings['ajaxTemplate'] && templateId ) { 740 ajaxLoadTemplate( tabIndex ); 741 } 742 743 switchTab( tabIndex ); 744 } 745 } ); 746 747 } ); 748 } 749 750 $controlList.each( function() { 751 anchorSelectors.push( 'a[href*="#' + $( this ).attr( 'id' ) + '"]' ); 752 } ); 753 754 $( document ).on( 'click.jetTabAnchor', anchorSelectors.join( ',' ), function( event ) { 755 var $hash = $( this.hash ); 756 757 if ( ! $hash.closest( $scope )[0] ) { 758 return; 759 } 760 761 var tabInx = $hash.data( 'tab' ) - 1; 762 763 if ( settings['ajaxTemplate'] ) { 764 ajaxLoadTemplate( tabInx ); 765 } 766 767 switchTab( tabInx ); 768 } ); 769 770 },// tabsInit end 771 772 switcherInit: function( $scope ) { 773 var $target = $( '.jet-switcher', $scope ).first(), 774 $widgetId = $target.data( 'id' ), 775 $window = $( window ), 776 $controlWrapper = $( '.jet-switcher__control-wrapper', $target ).first(), 777 $contentWrapper = $( '.jet-switcher__content-wrapper', $target ).first(), 778 $controlInstance = $( '> .jet-switcher__control-instance', $controlWrapper ), 779 $controlList = $( '> .jet-switcher__control-instance > .jet-switcher__control, > .jet-switcher__control', $controlWrapper ), 780 $contentList = $( '> .jet-switcher__content', $contentWrapper ), 781 $disableContent = $( '> .jet-switcher__content--disable', $contentWrapper ), 782 $enableContent = $( '> .jet-switcher__content--enable', $contentWrapper ), 783 state = $target.hasClass( 'jet-switcher--disable' ), 784 settings = $target.data( 'settings' ) || {}, 785 toogleEvents = 'mouseenter mouseleave', 786 scrollOffset; 787 788 var heightResetTimer = null; 789 $target.on('click.jetSwitcherAnchors', '.jet-listing a[href^="#"]', function(e) { 790 var href = this.getAttribute('href'); 791 if (!href || href === '#') return; 792 793 var targetID = href.slice(1); 794 var targetEl = document.getElementById(targetID); 795 if (!targetEl) return; 796 797 e.preventDefault(); 798 799 if (heightResetTimer) { 800 clearTimeout(heightResetTimer); 801 heightResetTimer = null; 802 } 803 804 $contentWrapper.css({ height: 'auto' }); 805 806 var $activeTab = $(targetEl).closest('.jet-switcher__content'); 807 var firstListing = $activeTab.length ? $activeTab[0].querySelector('.jet-listing') : null; 808 var offset = firstListing ? (firstListing.offsetHeight - firstListing.scrollHeight) : 0; 809 810 var adminBar = document.getElementById('wpadminbar'); 811 var adminOffset = adminBar ? adminBar.offsetHeight : 0; 812 813 var topPos = targetEl.getBoundingClientRect().top + window.scrollY + offset - adminOffset; 814 815 window.scrollTo({ top: topPos, behavior: 'smooth' }); 816 817 if (history && history.replaceState) { 818 history.replaceState(null, '', '#' + targetID); 819 } else { 820 window.location.hash = targetID; 821 } 822 }); 823 824 JetTabs.observeVideoIframes( $contentWrapper ); 825
826 if ( 'ontouchend' in window || 'ontouchstart' in window ) { 827 addTouchEvent(); 828 } else { 829 addClickEvent(); 830 } 831 832 $( window ).on( 'resize.jetSwitcher orientationchange.jetSwitcher', function() { 833 $contentWrapper.css( { 'height': 'auto' } ); 834 } ); 835 836 $( '.jet-switcher__control', $scope ).keydown( function( e ) { 837 var $this = $( this ), 838 $which = e.which || e.keyCode; 839 840 if ( $which == 13 || $which == 32 ) { 841 switchTab(); 842 $( '[aria-expanded="true"]', $scope ).focus(); 843 } 844 845 if ( $which == 37 ) { 846 if ( 0 != $this.prev().length && $this.prev().hasClass( 'jet-switcher__control' ) && $target.hasClass( 'jet-switcher--preset-1' ) ) { 847 $this.prev().focus(); 848 switchTab(); 849 } else if ( $target.hasClass( 'jet-switcher--preset-2' ) ) { 850 if ( $this.hasClass( 'jet-switcher__control--disable' ) ) { 851 return false; 852 } else if ( $this.hasClass( 'jet-switcher__control--enable' ) ) { 853 $( '.jet-switcher__control--disable', $scope ).focus(); 854 switchTab(); 855 } 856 } 857 } 858 859 if ( $which == 39 ) { 860 if ( 0 != $this.next().length && $this.next().hasClass( 'jet-switcher__control' ) && $target.hasClass( 'jet-switcher--preset-1' ) ) { 861 $this.next().focus(); 862 switchTab(); 863 } else if ( $target.hasClass( 'jet-switcher--preset-2' ) ) { 864 if ( $this.hasClass( 'jet-switcher__control--disable' ) ) { 865 $( '.jet-switcher__control--enable', $scope ).focus(); 866 switchTab(); 867 } else if ( $this.hasClass( 'jet-switcher__control--enable' ) ) { 868 return false; 869 } 870 } 871 } 872 } ); 873 874 function addClickEvent() { 875 $controlInstance.on( 'click.jetSwitcher', function() { 876 switchTab(); 877 }); 878 } 879 880 function addTouchEvent() { 881 882 $controlInstance.on( 'touchstart', function( event ) { 883 scrollOffset = $( window ).scrollTop(); 884 } ); 885 886 $controlInstance.on( 'touchend', function( event ) { 887 if ( scrollOffset !== $( window ).scrollTop() ) { 888 return false; 889 } 890 891 switchTab(); 892 893 } ); 894 } 895 896 function switchTab( curentIndex ) { 897 var $activeControl, $activeContent, 898 activeContentHeight = 'auto', 899 timer; 900 901 if (heightResetTimer) { 902 clearTimeout(heightResetTimer); 903 heightResetTimer = null; 904 } 905 906 $contentWrapper.css( { 'height': $contentWrapper.outerHeight( true ) } ); 907 908 $target.toggleClass( 'jet-switcher--disable jet-switcher--enable' ); 909 910 if ( $target.hasClass( 'jet-switcher--disable' ) ) { 911 state = false; 912 } else { 913 state = true; 914 } 915 916 $activeControl = ! state ? $controlList.eq(0) : $controlList.eq(1); 917 $activeContent = ! state ? $contentList.eq(0) : $contentList.eq(1); 918 919 $contentList.removeClass( 'active-content' ); 920 activeContentHeight = $activeContent.outerHeight( true ); 921 activeContentHeight += parseInt( $contentWrapper.css( 'border-top-width' ) ) + parseInt( $contentWrapper.css( 'border-bottom-width' ) ); 922 $activeContent.addClass( 'active-content' ); 923 924 $controlList.attr( 'aria-expanded', 'false' ); 925 $activeControl.attr( 'aria-expanded', 'true' ); 926 927 $contentList.attr( 'aria-hidden', 'true' ); 928 $activeContent.attr( 'aria-hidden', 'false' ); 929 930 $contentWrapper.css( { 'height': activeContentHeight } ); 931 932 heightResetTimer = setTimeout( function() { 933 $contentWrapper.css( { 'height': 'auto' } ); 934 heightResetTimer = null; 935 }, 500 ); 936 937 $window.trigger( 'jet-tabs/switcher/show-case-event/before', { 938 target: $target, 939 caseIndex: curentIndex, 940 } ); 941 942 if ( timer ) { 943 clearTimeout( timer ); 944 } 945 946 timer = setTimeout( function() { 947 $window.trigger( 'jet-tabs/switcher/show-case-event/after', { 948 target: $target, 949 caseIndex: curentIndex, 950 } ); 951 }, 500 ); 952 } 953 }, 954 955 recalcReadMoreBox: function($anyChild) { 956 var $box = $anyChild.closest('.jet-view-more-section.view-more-visible'); 957 if (!$box.length) { 958 $box = $anyChild.closest('.jet-view-more__content'); 959 } 960 if (!$box.length) { 961 $box = $anyChild.closest('[data-jet-view-more]'); 962 } 963 if (!$box.length) return; 964 965 var content = $box.find('.jet-view-more__content, .elementor-widget-container, .e-con-inner').first()[0] || $box[0]; 966 967 requestAnimationFrame(function(){ 968 $box[0].style.height = ''; 969 var h = content.scrollHeight; 970 $box.css('max-height', h + 'px'); 971 }); 972 }, 973 974 accordionInit: function( $scope ) { 975 var $target = $( '.jet-accordion', $scope ).first(), 976 $widgetId = $target.data( 'id' ),
977 $window = $( window ), 978 $controlsList = $( '> .jet-accordion__inner > .jet-toggle > .jet-toggle__control', $target ), 979 settings = $.extend( $target.data( 'settings' ) || {}, JetTabs.getElementorElementSettings( $scope ) ), 980 $toggleList = $( '> .jet-accordion__inner > .jet-toggle', $target ), 981 anchorSelectors = [], 982 timer, timer2, timerСlick, 983 curentHash = window.location.hash || false, 984 togglesArray = curentHash ? curentHash.replace( '#', '' ).split( '&' ) : false; 985 986 function getResponsiveAccordionSetting( baseKey ) { 987 var currentDeviceMode = elementorFrontend.getCurrentDeviceMode(); 988 989 if ( 'mobile' === currentDeviceMode && settings.hasOwnProperty( baseKey + 'Mobile' ) ) { 990 return settings[ baseKey + 'Mobile' ]; 991 } 992 993 if ( 'tablet' === currentDeviceMode && settings.hasOwnProperty( baseKey + 'Tablet' ) ) { 994 return settings[ baseKey + 'Tablet' ]; 995 } 996 997 return settings[ baseKey ]; 998 } 999 1000 function isResponsiveScrollEnabled() { 1001 var value = getResponsiveAccordionSetting( 'switchScrolling' ); 1002 1003 return true === value || 'yes' === value || 'true' === value; 1004 } 1005 1006 function getResponsiveScrollOffset() { 1007 var value = getResponsiveAccordionSetting( 'switchScrollingOffset' ); 1008 1009 if ( value && 'object' === typeof value && undefined !== value.size ) { 1010 return parseInt( value.size || 0, 10 ); 1011 } 1012 1013 return parseInt( value || 0, 10 ); 1014 } 1015 1016 function getResponsiveScrollDelay() { 1017 var value = getResponsiveAccordionSetting( 'switchScrollingDelay' ); 1018 value = parseInt( value, 10 ); 1019 1020 return isNaN( value ) ? 500 : value; 1021 } 1022 1023 $toggleList.each( function() { 1024 if ( $( this ).hasClass( 'active-toggle' ) && settings['ajaxTemplate'] ) { 1025 var activeIndex = $( this ).find( '.jet-toggle__control' ).data( 'toggle' ) - 1; 1026 ajaxLoadTemplate( activeIndex ); 1027 } 1028 } ); 1029 1030 1031 $( window ).on( 'resize.jetAccordion orientationchange.jetAccordion', function() { 1032 var activeToggle = $( '> .jet-accordion__inner > .active-toggle', $target ), 1033 activeToggleContent = $( '> .jet-toggle__content', activeToggle ); 1034 1035 activeToggleContent.css( { 'height': 'auto' } ); 1036 } ); 1037 1038 $( '.jet-toggle__control', $scope ).keydown( function( e ) { 1039 var $this = $( this ), 1040 $which = e.which || e.keyCode; 1041 1042 if ( $which == 13 || $which == 32 ) { 1043 $this.click(); 1044 return false; 1045 } 1046 1047 if ( $which == 37 ) { 1048 if ( 0 != $this.closest( '.jet-accordion__item' ).prev().length ) { 1049 $this.closest( '.jet-accordion__item' ).prev().find( '.jet-toggle__control' ).focus(); 1050 } 1051 } 1052 1053 if ( $which == 39 ) { 1054 if ( 0 != $this.closest( '.jet-accordion__item' ).next().length ) { 1055 $this.closest( '.jet-accordion__item' ).next().find( '.jet-toggle__control' ).focus(); 1056 } 1057 } 1058 } ); 1059 1060 function closeToggle( $toggle, $toggleContent, $toggleControl, callback ) { 1061 var transitionDuration = 500; 1062 1063 $toggleContent.css( { 'height': $toggleContent.outerHeight() } ); 1064 1065 $toggleControl.attr( 'aria-expanded', 'false' ); 1066 1067 requestAnimationFrame( function() { 1068 requestAnimationFrame( function() { 1069 $toggleContent.css( { 'height': 0 } ); 1070 } ); 1071 } ); 1072 1073 setTimeout( function() { 1074 $toggle.removeClass( 'active-toggle' ); 1075 1076 if ( 'function' === typeof callback ) { 1077 callback(); 1078 } 1079 }, transitionDuration ); 1080 } 1081 1082 $controlsList.on( 'click.jetAccordion', function() { 1083 var $this = $( this ), 1084 $toggle = $this.closest( '.jet-toggle' ), 1085 toggleIndex = +$this.data( 'toggle' ) - 1, 1086 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(); 1087 1088 if ( typeof timer !== 'undefined' && timer ) clearTimeout( timer ); 1089 if ( typeof timer2 !== 'undefined' && timer2 ) clearTimeout( timer2 ); 1090 if ( typeof timerСlick !== 'undefined' && timerСlick ) clearTimeout( timerСlick ); 1091 1092 if ( $toggle.data('animating') ) return; 1093 $toggle.data('animating', true); 1094 setTimeout(function(){ $toggle.removeData('animating'); }, 100); 1095 1096 if ( settings['collapsible'] ) { 1097 var $toggleControl = $( '> .jet-toggle__control', $toggle ), 1098 $toggleContent = $( '> .jet-toggle__content', $toggle ); 1099 1100 if ( ! $toggleControl.length || ! $toggleContent.length ) { 1101 return; 1102 } 1103 const classIsOpen = 'active-toggle'; 1104 const isOpened = $toggle.hasClass( classIsOpen ); 1105 1106 // Capture scroll start position. 1107 const togglerInitialY = $toggleControl[0].getBoundingClientRect().top + window.scrollY; 1108 1109 // Find currently open item (if any).
1110 let currentlyOpenItem = null; 1111 let currentlyOpenControl = null; 1112 let currentlyOpenContent = null; 1113 $toggleList.each( function() { 1114 if ( 1115 this !== $toggle[0] && 1116 this.classList.contains( classIsOpen ) 1117 ) { 1118 currentlyOpenItem = this; 1119 currentlyOpenControl = this.querySelector( '.jet-toggle__control' ); 1120 currentlyOpenContent = this.querySelector( '.jet-toggle__content' ); 1121 } 1122 } ); 1123 1124 // Measure content shift (closing content). 1125 const closingHeight = currentlyOpenContent?.scrollHeight || 0; 1126 1127 if ( !isOpened && currentlyOpenControl && currentlyOpenContent ) { 1128 currentlyOpenItem.classList.remove( classIsOpen ); 1129 currentlyOpenContent.style.height = '0'; 1130 currentlyOpenControl.setAttribute( 'aria-expanded', 'false' ); 1131 1132 // Calculate the predicted scroll position after layout shift. 1133 if ( closingHeight ) { 1134 const currentTogglerY = 1135 currentlyOpenControl.getBoundingClientRect().top + 1136 window.scrollY; 1137 1138 // Only scroll if clicked toggler is below the currently open one. 1139 if ( togglerInitialY > currentTogglerY ) { 1140 const predictedY = togglerInitialY - closingHeight; 1141 1142 if ( window.scrollY > predictedY) { 1143 requestAnimationFrame( () => { 1144 let offset = 0; 1145 1146 if ( true === isResponsiveScrollEnabled() ) { 1147 offset = getResponsiveScrollOffset(); 1148 } 1149 window.scrollTo( { 1150 top: predictedY - offset, 1151 behavior: 'auto', 1152 } ); 1153 } ); 1154 } 1155 } 1156 } 1157 } 1158 1159 $toggleList.each( function( index ) { 1160 var $this = $( this ), 1161 $toggleControl = $( '> .jet-toggle__control', $this ), 1162 $toggleContent = $( '> .jet-toggle__content', $this ), 1163 $toggleContentHeight = $( '> .jet-toggle__content > .jet-toggle__content-inner', $this ).outerHeight(); 1164 1165 $toggleContentHeight += parseInt( $toggleContent.css( 'border-top-width' ) ) + parseInt( $toggleContent.css( 'border-bottom-width' ) ); 1166 1167 if ( index === toggleIndex && ! $toggle.hasClass( 'active-toggle' ) ) { 1168 $this.addClass( 'active-toggle' ); 1169 $toggleContent.css( { 'height': $toggleContentHeight } ); 1170 1171 $toggleControl.attr( 'aria-expanded', 'true' ); 1172 1173 if ( settings['ajaxTemplate'] ) { 1174 ajaxLoadTemplate( toggleIndex ); 1175 } 1176 1177 $window.trigger( 'jet-tabs/accordion/show-toggle-event/before', { 1178 target: $target, 1179 toggleIndex: toggleIndex, 1180 } ); 1181 1182 if ( timer ) { 1183 clearTimeout( timer ); 1184 } 1185 1186 timer = setTimeout( function() { 1187 1188 $window.trigger( 'jet-tabs/accordion/show-toggle-event/after', { 1189 target: $target, 1190 toggleIndex: toggleIndex, 1191 } ); 1192 1193 $toggleContent.css( { 'height': 'auto' } ); 1194 JetTabs.recalcReadMoreBox($target); 1195 1196 if ( isResponsiveScrollEnabled() ) { 1197 $( 'html, body' ).animate( { 1198 scrollTop: $this.offset().top - getResponsiveScrollOffset() 1199 }, getResponsiveScrollDelay() ); 1200 } 1201 }, 500 ); 1202 1203 } else { 1204 if ( $this.hasClass( 'active-toggle' ) ) { 1205 if ( timer2 ) { 1206 clearTimeout( timer2 ); 1207 } 1208 1209 closeToggle( $this, $toggleContent, $toggleControl ); 1210 } 1211 } 1212 } ); 1213 1214 } else { 1215 1216 var $toggleContent = $( '> .jet-toggle__content', $toggle ), 1217 $toggleContentHeight = $( '> .jet-toggle__content > .jet-toggle__content-inner', $toggle ).outerHeight(); 1218 1219 $toggleContentHeight += parseInt( $toggleContent.css( 'border-top-width' ) ) + parseInt( $toggleContent.css( 'border-bottom-width' ) ); 1220 1221 if ( timerСlick ) { 1222 clearTimeout( timerСlick ); 1223 } 1224 1225 timerСlick = setTimeout( function() { 1226 1227 if ( ! $toggle.hasClass( 'active-toggle') ) { 1228 1229 $toggle.addClass( 'active-toggle' ); 1230 1231 $toggleContent.css( { 'height': $toggleContentHeight } ); 1232 1233 $this.attr( 'aria-expanded', 'true' ); 1234 1235 if ( settings['ajaxTemplate'] ) { 1236 ajaxLoadTemplate( toggleIndex ); 1237 } 1238 1239 $window.trigger( 'jet-tabs/accordion/show-toggle-event/before', { 1240 target: $target, 1241 toggleIndex: toggleIndex, 1242 } ); 1243 1244 if ( timer ) { 1245 clearTimeout( timer ); 1246 } 1247 1248 timer = setTimeout( function() { 1249 $window.trigger( 'jet-tabs/accordion/show-toggle-event/after', { 1250 target: $target, 1251 toggleIndex: toggleIndex, 1252 } ); 1253 1254 $toggleContent.css( { 'height': 'auto' } ); 1255 JetTabs.recalcReadMoreBox($target); 1256 1257 if ( isResponsiveScrollEnabled() && settings['collapsible'] !== true ) { 1258 $( 'html, body' ).animate( { 1259 scrollTop: $this.offset().top - getResponsiveScrollOffset() 1260 }, getResponsiveScrollDelay() ); 1261 } 1262 }, 200 ); 1263 1264 } else { 1265 if ( timer2 ) { 1266 clearTimeout( timer2 ); 1267 } 1268 1269 closeToggle( $toggle, $toggleContent, $this, function() { 1270 var $box = $target.closest( '.jet-view-more-section.view-more-visible' ); 1271 1272 if ( $box.length ) { 1273 requestAnimationFrame( function() { 1274 $box.css( 'max-height', $box[0].scrollHeight + 'px' ); 1275 } ); 1276 } 1277 } ); 1278 } 1279 1280 }, 200 ); 1281 } 1282 1283 }); 1284 1285 /** 1286 * [ajaxLoadTemplate description] 1287 * @param {[type]} $index [description] 1288 * @return {[type]} [description] 1289 */ 1290 function ajaxLoadTemplate( $index ) { 1291 var $toggle = $toggleList.eq( $index ), 1292 $contentHolder = $( '> .jet-toggle__content', $toggle ), 1293 $contentHolderInner = $( '> .jet-toggle__content > .jet-toggle__content-inner', $toggle ), 1294 templateLoaded = $contentHolder.data( 'template-loaded' ) || false, 1295 templateId = $contentHolder.data( 'template-id' ), 1296 loader = $( '.jet-tabs-loader', $contentHolderInner ); 1297 1298 if ( templateLoaded || false === templateId ) { 1299 return false;
1300 } 1301 1302 $window.trigger( 'jet-tabs/ajax-load-template/before', { 1303 toggleIndex: $index, 1304 target: $target, 1305 contentHolder: $contentHolder 1306 } ); 1307 1308 $contentHolder.data( 'template-loaded', true ); 1309 1310 var ajaxData = { 1311 id: templateId, 1312 dev: window.JetTabsSettings.devMode 1313 }; 1314 1315 if ( window.JetTabsSettings && window.JetTabsSettings.isSelfRequest ) { 1316 ajaxData.jet_tabs_self = 1; 1317 ajaxData._ = Date.now(); 1318 } 1319 1320 $.ajax( { 1321 type: 'GET', 1322 url: window.JetTabsSettings.templateApiUrl, 1323 dataType: 'json', 1324 data: ajaxData, 1325 success: function( responce ) { 1326 if ( !responce || typeof responce.template_content === 'undefined' ) { 1327 loader.remove(); 1328 $contentHolder.data( 'template-loaded', false ); 1329 return; 1330 } 1331 var templateContent = responce.template_content, 1332 templateScripts = responce.template_scripts || {}, 1333 templateStyles = responce.template_styles || {}; 1334 1335 for ( var scriptHandler in templateScripts ) { 1336 JetTabs.addedAssetsPromises.push( JetTabs.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 1337 } 1338 1339 for ( var styleHandler in templateStyles ) { 1340 JetTabs.addedAssetsPromises.push( JetTabs.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 1341 } 1342 1343 Promise.all( JetTabs.addedAssetsPromises ).then( function( value ) { 1344 loader.remove(); 1345 1346 $contentHolderInner.html( templateContent ); 1347 1348 JetTabs.elementorFrontendInit( $contentHolderInner ); 1349 1350 $window.trigger( 'jet-tabs/ajax-load-template/after', { 1351 toggleIndex: $index, 1352 target: $target, 1353 contentHolder: $contentHolder, 1354 responce: response, 1355 response: response 1356 } ); 1357 }, function( reason ) { 1358 console.log( 'Script Loaded Error' ); 1359 }); 1360 } 1361 } );//end 1362 } 1363 1364 // Hash Watch Handler 1365 if ( togglesArray ) { 1366 1367 $controlsList.each( function( index ) { 1368 var $this = $( this ), 1369 id = $this.attr( 'id' ), 1370 toggleIndex = index; 1371 1372 togglesArray.forEach( function( itemHash, i ) { 1373 if ( itemHash === id ) { 1374 $this.trigger('click.jetAccordion'); 1375 } 1376 } ); 1377 1378 } ); 1379 } 1380 1381 $controlsList.each( function() { 1382 anchorSelectors.push( 'a[href*="#' + $( this ).attr( 'id' ) + '"]' ); 1383 } ); 1384 1385 $( document ).on( 'click.jetAccordionAnchor', anchorSelectors.join( ',' ), function( event ) { 1386 var $hash = $( this.hash ); 1387 1388 if ( ! $hash.closest( $scope )[0] ) { 1389 return; 1390 } 1391 1392 $hash.trigger( 'click.jetAccordion' ); 1393 } ); 1394 1395 },// accordionInit end 1396 1397 imageAccordionInit: function( $scope) { 1398 var $target = $( '.jet-image-accordion', $scope ), 1399 instance = null, 1400 settings = {}; 1401 1402 if ( ! $target.length ) { 1403 return; 1404 } 1405 1406 settings = $target.data( 'settings' ); 1407 1408 instance = new jetImageAccordion( $target, settings ); 1409 instance.init(); 1410 },// imageAccordionInit end 1411 1412 loadScriptAsync: function( script, uri ) { 1413 1414 if ( ! uri ) { 1415 return Promise.resolve( script ); 1416 } 1417 1418 if ( JetTabs.addedScripts.hasOwnProperty( script ) ) { 1419 return JetTabs.addedScripts[ script ]; 1420 } 1421 1422 JetTabs.addedScripts[ script ] = new Promise( function( resolve, reject ) { 1423 var existingTag = document.querySelector( 'script[src="' + uri + '"]' ); 1424 1425 if ( existingTag ) { 1426 resolve( script ); 1427 return; 1428 } 1429 1430 var tag = document.createElement( 'script' ); 1431 1432 tag.src = uri; 1433 tag.async = true; 1434 1435 tag.onload = function() { 1436 resolve( script ); 1437 }; 1438 1439 tag.onerror = function() { 1440 reject( { 1441 type: 'script', 1442 handler: script, 1443 uri: uri 1444 } ); 1445 }; 1446 1447 document.head.appendChild( tag ); 1448 }); 1449 }, 1450 1451 loadStyle: function( style, uri ) { 1452 1453 if ( !uri ) { 1454 return Promise.resolve( style ); 1455 } 1456 1457 if ( JetTabs.addedStyles.hasOwnProperty( style ) ) { 1458 return JetTabs.addedStyles[ style ]; 1459 } 1460 1461 JetTabs.addedStyles[ style ] = new Promise( function( resolve, reject ) { 1462 var existingTag = document.querySelector( 'link[href="' + uri + '"]' ); 1463 1464 if ( existingTag ) { 1465 resolve( style ); 1466 return; 1467 } 1468 1469 var tag = document.createElement( 'link' ); 1470 1471 tag.id = style; 1472 tag.rel = 'stylesheet'; 1473 tag.href = uri; 1474 tag.type = 'text/css'; 1475 tag.media = 'all'; 1476 1477 tag.onload = function() { 1478 resolve( style ); 1479 }; 1480 1481 tag.onerror = function() { 1482 reject( { 1483 type: 'style', 1484 handler: style, 1485 uri: uri 1486 } ); 1487 }; 1488 1489 document.head.appendChild( tag ); 1490 } ); 1491 1492 return JetTabs.addedStyles[ style ]; 1493 }, 1494 1495 elementorFrontendInit: function( $container ) { 1496 1497 $container.find( '[data-element_type]' ).each( function() { 1498 var $this = $( this ), 1499 elementType = $this.data( 'element_type' ); 1500 1501 if ( ! elementType ) { 1502 return; 1503 } 1504 1505 try { 1506 if ( 'widget' === elementType ) { 1507 elementType = $this.data( 'widget_type' ); 1508 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 1509 } 1510 1511 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 1512 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 1513 1514 } catch ( err ) { 1515 console.log(err); 1516 1517 $this.remove(); 1518 1519 return false;
1520 } 1521 } ); 1522 1523 }, 1524 1525 getElementorElementSettings: function( $scope ) { 1526 1527 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() && $scope.hasClass( 'elementor-element-edit-mode' ) ) { 1528 return JetTabs.getEditorElementSettings( $scope ); 1529 } 1530 1531 return $scope.data( 'settings' ) || {}; 1532 }, 1533 1534 getEditorElementSettings: function( $scope ) { 1535 var modelCID = $scope.data( 'model-cid' ), 1536 elementData; 1537 1538 if ( ! modelCID ) { 1539 return {}; 1540 } 1541 1542 if ( ! elementor.hasOwnProperty( 'config' ) ) { 1543 return {}; 1544 } 1545 1546 if ( ! elementor.config.hasOwnProperty( 'elements' ) ) { 1547 return {}; 1548 } 1549 1550 if ( ! elementor.config.elements.hasOwnProperty( 'data' ) ) { 1551 return {}; 1552 } 1553 1554 elementData = elementor.config.elements.data[ modelCID ]; 1555 1556 if ( ! elementData ) { 1557 return {}; 1558 } 1559 1560 return elementData.toJSON(); 1561 }, 1562 1563 prepareVideoIframes: function( $container ) { 1564 if ( ! $container || ! $container.length ) return; 1565 1566 $container.find( 'iframe' ).each( function() { 1567 var $iframe = $( this ); 1568 1569 var srcAttr = $iframe.attr( 'src' ) ? 'src' 1570 : ( $iframe.attr( 'data-src' ) ? 'data-src' 1571 : ( $iframe.attr( 'data-lazy-src' ) ? 'data-lazy-src' 1572 : ( $iframe.attr( 'data-lazy-load' ) ? 'data-lazy-load' : null ) ) ); 1573 1574 if ( ! srcAttr ) return; 1575 1576 var src = $iframe.attr( srcAttr ); 1577 if ( ! src ) return; 1578 1579 var isYouTube = /youtube\.com|youtube-nocookie\.com|youtu\.be/i.test( src ); 1580 var isVimeo = /vimeo\.com/i.test( src ); 1581 1582 if ( ! isYouTube && ! isVimeo ) return; 1583 1584 try { 1585 var fixedSrc = src.indexOf( '//' ) === 0 ? window.location.protocol + src : src; 1586 var url = new URL( fixedSrc ); 1587 1588 if ( isYouTube ) { 1589 if ( ! url.searchParams.has( 'enablejsapi' ) ) url.searchParams.set( 'enablejsapi', '1' ); 1590 if ( ! url.searchParams.has( 'origin' ) ) url.searchParams.set( 'origin', window.location.origin ); 1591 } 1592 1593 if ( isVimeo ) { 1594 if ( ! url.searchParams.has( 'api' ) ) url.searchParams.set( 'api', '1' ); 1595 } 1596 1597 var newSrc = url.toString(); 1598 1599 if ( src.indexOf( '//' ) === 0 ) { 1600 newSrc = newSrc.replace( window.location.protocol, '' ); 1601 } 1602 1603 if ( newSrc !== src ) { 1604 $iframe.attr( srcAttr, newSrc ); 1605 } 1606 } catch ( e ) { 1607 } 1608 } ); 1609 }, 1610 1611 pauseMediaInContainer: function( $container ) { 1612 if ( ! $container || ! $container.length ) return; 1613 1614 $container.find( 'video, audio' ).each( function() { 1615 try { 1616 this.pause(); 1617 } catch ( e ) { 1618 } 1619 } ); 1620 1621 function getUrlAndAttr( $iframe ) { 1622 if ( $iframe.attr( 'src' ) ) return { attr: 'src', url: $iframe.attr( 'src' ) }; 1623 if ( $iframe.attr( 'data-src' ) ) return { attr: 'data-src', url: $iframe.attr( 'data-src' ) }; 1624 if ( $iframe.attr( 'data-lazy-src' ) ) return { 1625 attr: 'data-lazy-src', 1626 url: $iframe.attr( 'data-lazy-src' ) 1627 }; 1628 if ( $iframe.attr( 'data-lazy-load' ) ) return { 1629 attr: 'data-lazy-load', 1630 url: $iframe.attr( 'data-lazy-load' ) 1631 }; 1632 return { attr: null, url: '' }; 1633 } 1634 1635 $container.find( 'iframe' ).each( function() { 1636 var iframe = this; 1637 var $iframe = jQuery( iframe ); 1638 1639 var info = getUrlAndAttr( $iframe ); 1640 var url = info.url || ''; 1641 if ( ! url ) return; 1642 1643 var isYouTube = /youtube\.com|youtube-nocookie\.com|youtu\.be/i.test( url ); 1644 var isVimeo = /vimeo\.com/i.test( url ); 1645 if ( ! isYouTube && ! isVimeo ) return; 1646 1647 var hasYTApi = isYouTube && /enablejsapi=1/i.test( url ); 1648 var hasVmApi = isVimeo && /api=1/i.test( url ); 1649 1650 if ( ( hasYTApi || hasVmApi ) && iframe.contentWindow ) { 1651 try { 1652 if ( hasYTApi ) { 1653 iframe.contentWindow.postMessage( JSON.stringify( { 1654 event: 'command', 1655 func: 'pauseVideo', 1656 args: '' 1657 } ), '*' ); 1658 return; 1659 } 1660 1661 if ( hasVmApi ) { 1662 iframe.contentWindow.postMessage( JSON.stringify( { 1663 method: 'pause' 1664 } ), '*' ); 1665 return; 1666 } 1667 } catch ( e ) { 1668 } 1669 } 1670 1671 try { 1672 if ( ! $iframe.attr( 'data-jet-tabs-restore-src' ) ) { 1673 $iframe.attr( 'data-jet-tabs-restore-src', url ); 1674 } 1675 1676 $iframe.attr( 'src', 'about:blank' ); 1677 $iframe.removeAttr( 'srcdoc' ); 1678 } catch ( e ) { 1679 } 1680 } ); 1681 }, 1682 1683 observeVideoIframes: function( $root ) { 1684 if ( ! $root || ! $root.length ) return; 1685 1686 if ( $root.data( 'jetTabsVideoObserver' ) ) return; 1687 1688 var observer = new MutationObserver( function( mutations ) { 1689 mutations.forEach( function( m ) { 1690 1691 if ( m.type === 'attributes' ) { 1692 var el = m.target; 1693 1694 if ( el && el.nodeType === 1 && el.tagName === 'IFRAME' ) { 1695 JetTabs.prepareVideoIframes( jQuery( el ).parent() ); 1696 } 1697 1698 return; 1699 } 1700 1701 if ( m.type === 'childList' ) { 1702 if ( ! m.addedNodes || ! m.addedNodes.length ) return; 1703
1704 m.addedNodes.forEach( function( node ) { 1705 if ( node.nodeType !== 1 ) return; 1706 1707 var $node = jQuery( node ); 1708 1709 if ( $node.is( 'iframe' ) ) { 1710 JetTabs.prepareVideoIframes( $node.parent() ); 1711 return; 1712 } 1713 1714 var $iframes = $node.find ? $node.find( 'iframe' ) : jQuery(); 1715 if ( $iframes.length ) { 1716 JetTabs.prepareVideoIframes( $node ); 1717 } 1718 } ); 1719 } 1720 1721 } ); 1722 } ); 1723 1724 observer.observe( $root[ 0 ], { 1725 childList: true, 1726 subtree: true, 1727 attributes: true, 1728 attributeFilter: [ 'src', 'data-src', 'data-lazy-src', 'data-lazy-load' ], 1729 } ); 1730 $root.data( 'jetTabsVideoObserver', observer ); 1731 }, 1732 1733 restoreMediaInContainer: function( $container ) { 1734 if ( ! $container || ! $container.length ) return; 1735 1736 $container.find( 'iframe[data-jet-tabs-restore-src]' ).each( function() { 1737 var $iframe = jQuery( this ); 1738 var restoreUrl = $iframe.attr( 'data-jet-tabs-restore-src' ); 1739 if ( ! restoreUrl ) return; 1740 1741 $iframe.attr( 'src', restoreUrl ); 1742 $iframe.removeAttr( 'data-jet-tabs-restore-src' ); 1743 1744 JetTabs.prepareVideoIframes( $iframe.parent() ); 1745 } ); 1746 }, 1747 1748 debounce: function( threshold, callback ) { 1749 var timeout; 1750 1751 return function debounced( $event ) { 1752 function delayed() { 1753 callback.call( this, $event ); 1754 timeout = null; 1755 } 1756 1757 if ( timeout ) { 1758 clearTimeout( timeout ); 1759 } 1760 1761 timeout = setTimeout( delayed, threshold ); 1762 }; 1763 } 1764 1765 }; 1766 1767 /** 1768 * jetImageAccordion Class 1769 * 1770 * @return {void} 1771 */ 1772 window.jetImageAccordion = function( $selector, settings ) { 1773 var self = this, 1774 $instance = $selector, 1775 $itemsList = $( '.jet-image-accordion__item', $instance ), 1776 itemslength = $itemsList.length, 1777 defaultSettings = { 1778 orientation: 'vertical', 1779 activeSize: { 1780 size: 50, 1781 unit: '%' 1782 }, 1783 duration: 500, 1784 activeItem: -1 1785 }, 1786 settings = settings || {}, 1787 activeItem = -1; 1788 1789 /** 1790 * Checking options, settings and options merging 1791 */ 1792 settings = $.extend( defaultSettings, settings ); 1793 1794 activeItem = settings['activeItem']; 1795 1796 /** 1797 * Layout Build 1798 */ 1799 this.layoutBuild = function( ) { 1800 1801 $itemsList.css( { 1802 'transition-duration': settings.duration + 'ms' 1803 } ); 1804 1805 $itemsList.each( function( index ) { 1806 if ( index === activeItem ) { 1807 $( this ).addClass( 'active-accordion' ); 1808 self.layoutRender(); 1809 } 1810 } ); 1811 1812 $( '.jet-image-accordion__image-instance', $itemsList ).imagesLoaded().progress( function( instance, image ) { 1813 var $image = $( image.img ), 1814 $parentItem = $image.closest( '.jet-image-accordion__item' ), 1815 $loader = $( '.jet-image-accordion__item-loader', $parentItem ); 1816 1817 $image.addClass( 'loaded' ); 1818 1819 $loader.fadeTo( 250, 0, function() { 1820 $( this ).remove(); 1821 } ); 1822 }); 1823 1824 self.layoutRender(); 1825 self.addEvents(); 1826 } 1827 1828 /** 1829 * Layout Render 1830 */ 1831 this.layoutRender = function( $accordionItem ) { 1832 var $accordionItem = $accordionItem || false, 1833 activeSize = settings.activeSize.size, 1834 basis = ( 100 / itemslength ).toFixed(2), 1835 grow = activeSize / ( ( 100 - activeSize ) / ( itemslength - 1 ) ); 1836 1837 $( '.jet-image-accordion__item:not(.active-accordion)', $instance ).css( { 1838 'flex-grow': 1 1839 } ); 1840 1841 $( '.active-accordion', $instance ).css( { 1842 'flex-grow': grow 1843 } ); 1844 } 1845 1846 this.addEvents = function() { 1847 var toogleEvents = 'mouseenter', 1848 scrollOffset = $( window ).scrollTop(); 1849 1850 if ( 'ontouchend' in window || 'ontouchstart' in window ) { 1851 $itemsList.on( 'touchstart.jetImageAccordion', function( event ) { 1852 scrollOffset = $( window ).scrollTop(); 1853 } ); 1854 1855 $itemsList.on( 'touchend.jetImageAccordion', function( event ) { 1856 event.stopPropagation(); 1857 1858 var $this = $( this ); 1859 1860 if ( scrollOffset !== $( window ).scrollTop() ) { 1861 return false; 1862 } 1863 1864 if ( ! $this.hasClass( 'active-accordion' ) ) { 1865 $itemsList.removeClass( 'active-accordion' ); 1866 $this.addClass( 'active-accordion' ); 1867 } else { 1868 $itemsList.removeClass( 'active-accordion' ); 1869 } 1870 1871 self.layoutRender(); 1872 } ); 1873 } else { 1874 $itemsList.on( 'mouseenter', function( event ) { 1875 var $this = $( this ); 1876 1877 if ( ! $this.hasClass( 'active-accordion' ) ) { 1878 $itemsList.removeClass( 'active-accordion' ); 1879 $this.addClass( 'active-accordion' ); 1880 } 1881 1882 self.layoutRender(); 1883 } ); 1884 1885 $( '.jet-image-accordion__item', $instance ).keydown( function( e ) { 1886 var $this = $( this ), 1887 $which = e.which || e.keyCode; 1888 1889 if ( $which == 13 || $which == 32 ) { 1890 if ( ! $this.hasClass( 'active-accordion' ) ) { 1891 $itemsList.removeClass( 'active-accordion' ); 1892 $this.addClass( 'active-accordion' ); 1893 } else { 1894 $itemsList.removeClass( 'active-accordion' ); 1895 1896 if ( -1 !== activeItem ) { 1897 $itemsList.eq( activeItem ).addClass( 'active-accordion' ); 1898 } 1899 1900 self.layoutRender(); 1901 } 1902 1903 self.layoutRender(); 1904 } 1905 1906 if ( $which == 37 ) { 1907 if ( 0 != $this.prev().length ) { 1908 $itemsList.removeClass( 'active-accordion' ); 1909 $this.prev().focus(); 1910 $this.prev().addClass( 'active-accordion' ); 1911 self.layoutRender(); 1912 } 1913 } 1914 1915 if ( $which == 39 ) { 1916 if ( 0 != $this.next().length ) { 1917 $itemsList.removeClass( 'active-accordion' ); 1918 $this.next().focus(); 1919 $this.next().addClass( 'active-accordion' ); 1920 self.layoutRender(); 1921 } 1922 } 1923 } ); 1924 } 1925 1926 $instance.on( 'mouseleave.jetImageAccordion', function( event ) { 1927 $itemsList.removeClass( 'active-accordion' ); 1928 1929 if ( -1 !== activeItem ) { 1930 $itemsList.eq( activeItem ).addClass( 'active-accordion' ); 1931 } 1932 1933 self.layoutRender(); 1934 } ); 1935 1936 /*$( document ).on( 'touchend.jetImageAccordion', function( event ) { 1937 $itemsList.removeClass( 'active-accordion' ); 1938 self.layoutRender(); 1939 } );*/ 1940 } 1941 1942 /** 1943 * Init 1944 */ 1945 this.init = function() { 1946 self.layoutBuild(); 1947 } 1948 } 1949 1950 $( window ).on( 'elementor/frontend/init', JetTabs.init ); 1951 1952 window.JetTabs = JetTabs; 1953 1954}( jQuery, window.elementorFrontend, window.JetTabsSettings ) );
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.