PageSourceSearch

https://www.sms.com/wp-content/cache/min/1/wp-content/plugins/chil…/assets/js/accordion.js?ver=1788417922

js sms.com collected 2026-10-02 14:35:32 UTC 10,931 bytes, 46 lines download raw bytes

1(function($){'use strict';class AnimatedSideAccordion{constructor(element){this.widget=element;this.$widget=$(element);this.leftItems=this.$widget.find('.asa-left-item');this.rightPanels=this.$widget.find('.asa-right-panel');this.leftColumn=this.$widget.find('.asa-left-column');this.rightColumn=this.$widget.find('.asa-right-column');this.progressBar=this.$widget.find('.asa-progress-bar');this.progressFill=this.$widget.find('.asa-progress-fill');this.isMobile=window.innerWidth<=768;this.isStacked=this.$widget.hasClass('asa-mobile-stacked');this.currentIndex=0;this.isScrolling=!1;this.intersectionObserver=null;this.lastTouchY=null;this.scrollViewport=this.$widget.closest('.scroll-view-port').length?this.$widget.closest('.scroll-view-port'):$(window);this.init()}
2init(){this.bindEvents();this.setupIntersectionObserver();this.setupResizeHandler();this.activateFirstItem();this.updateProgressBar();requestAnimationFrame(()=>this.updateProgressBar());if(window.elementorFrontend){this.setupElementorEditor()}}
3updateProgressBar(){if(!this.progressFill.length||this.leftItems.length===0)return;const totalItems=this.leftItems.length;const currentIndex=this.currentIndex;const progressPercentage=((currentIndex+1)/totalItems)*100;this.progressFill.css('height',progressPercentage+'%')}
4updateProgressBarWithScroll(scrollProgress){if(!this.progressFill.length)return;this.progressFill.css('height',scrollProgress+'%')}
5bindEvents(){this.leftItems.on('click',(e)=>{const index=$(e.currentTarget).data('index');this.activateItem(index)});this.leftItems.on('keydown',(e)=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();const index=$(e.currentTarget).data('index');this.activateItem(index)}
6if(e.key==='ArrowDown'){e.preventDefault();this.navigateNext()}else if(e.key==='ArrowUp'){e.preventDefault();this.navigatePrevious()}});this.leftItems.attr('tabindex','0');this.scrollViewport.on('wheel',(e)=>{if(this.isMobile){return}
7if(!this.isWidgetInView()){return}
8if(this.isScrolling){e.preventDefault();return}
9const delta=e.originalEvent.deltaY;
9const lastIndex=this.leftItems.length-1;if(delta>0&&this.currentIndex<this.leftItems.length-1){e.preventDefault();this.navigateNext()}else if(delta<0&&this.currentIndex>0){e.preventDefault();this.navigatePrevious()}else{}});this.scrollViewport.on('touchstart',(e)=>{if(this.isMobile){return}
10if(!this.isWidgetInView())return;if(e.touches&&e.touches.length){this.lastTouchY=e.touches[0].clientY}});this.scrollViewport.on('touchmove',(e)=>{if(this.isMobile){return}
11if(!this.isWidgetInView())return;if(this.isScrolling){e.preventDefault();return}
12if(!e.touches||!e.touches.length)return;const currentY=e.touches[0].clientY;if(this.lastTouchY===null){this.lastTouchY=currentY;return}
13const deltaY=this.lastTouchY-currentY;this.lastTouchY=currentY;const lastIndex=this.leftItems.length-1;const threshold=5;if(deltaY>threshold&&this.currentIndex<lastIndex){e.preventDefault();this.navigateNext()}else if(deltaY<-threshold&&this.currentIndex>0){e.preventDefault();this.navigatePrevious()}else{}})}
14isWidgetInView(){const rect=this.widget.getBoundingClientRect();const viewportHeight=window.innerHeight||document.documentElement.clientHeight;return rect.top<viewportHeight&&rect.bottom>0}
15setupIntersectionObserver(){if(!window.IntersectionObserver){this.setupScrollListener();return}
16const root=this.scrollViewport[0]===window?null:this.scrollViewport[0];const options={root:root,rootMargin:'-40% 0px -40% 0px',threshold:[0,0.3,0.7,1]};this.intersectionObserver=new IntersectionObserver((entries)=>{entries.forEach(entry=>{if(this.isMobile){return}
17if(entry.isIntersecting&&entry.intersectionRatio>0.5){const index=$(entry.target).data('index');if(index!==this.currentIndex&&!this.isScrolling){this.syncLeftItem(index)}}
18this.updateProgressBarFromScroll()})},options);this.rightPanels.each((index,panel)=>{this.intersectionObserver.observe(panel)})}
19setupScrollListener(){let scrollTimeout;let lastScrollTop=0;this.scrollViewport.on('scroll',()=>{if(this.isMobile){return}
20const scrollTop=this.scrollViewport.scrollTop();const scrollDirection=scrollTop>lastScrollTop?'down':'up';lastScrollTop=scrollTop;clearTimeout(scrollTimeout);scrollTimeout=setTimeout(()=>{if(!this.isScrolling){this.detectVisiblePanelStep(scrollDirection)}},150)})}
21updateProgressBarFromScroll(){if(!this.progressFill.length||this.rightPanels.length===0)return;const viewportEl=(this.scrollViewport&&this.scrollViewport[0]&&this.scrollViewport[0]!==window)?this.scrollViewport[0]:null;const viewportRect=viewportEl?viewportEl.getBoundingClientRect():{top:0,bottom:window.innerHeight};let totalProgress=0;let visiblePanels=0;this.rightPanels.each((index,panel)=>{const $panel=$(panel);const rect=panel.getBoundingClientRect();const visibleHeight=Math.max(0,Math.min(rect.bottom,viewportRect.bottom)-Math.max(rect.top,viewportRect.top));const visibilityRatio=visibleHeight/$panel.outerHeight();if(visibilityRatio>0){totalProgress+=(index+1)*visibilityRatio;visiblePanels+=visibilityRatio}});if(visiblePanels>0){const weightedProgress=totalProgress/visiblePanels;const progressPercentage=(weightedProgress/this.rightPanels.length)*100}}
22detectVisiblePanelStep(scrollDirection){const scrollTop=this.scrollViewport.scrollTop();const viewportHeight=this.scrollViewport.height();const viewportTop=this.scrollViewport.offset().top;const viewportCenter=scrollTop+(viewportHeight/2);let bestIndex=this.currentIndex;let minDistance=Infinity;this.rightPanels.each((index,panel)=>{const $panel=$(panel);const panelTop=$panel.offset().top-viewportTop;const panelHeight=$panel.outerHeight();const panelBottom=panelTop+panelHeight;const panelCenter=(panelTop+panelBottom)/2;const distance=Math.abs(viewportCenter-panelCenter);if(scrollDirection==='down'&&index>this.currentIndex&&distance<minDistance){minDistance=distance;bestIndex=index}else if(scrollDirection==='up'&&index<this.currentIndex&&distance<minDistance){minDistance=distance;bestIndex=index}
23if(index===this.currentIndex&&distance<minDistance){minDistance=distance;bestIndex=index}});if(bestIndex!==this.currentIndex){this.syncLeftItem(bestIndex)}}
24setupResizeHandler(){let resizeTimeout;$(window).on('resize',()=>{clearTimeout(resizeTimeout);resizeTimeout=setTimeout(()=>{this.scrollViewport=this.$widget.closest('.scroll-view-port').length?this.$widget.closest('.scroll-view-port'):$(window);const wasMobile=this.isMobile;this.isMobile=window.innerWidth<=768;if(wasMobile!==this.isMobile){this.handleMobileChange()}
25this.updateScrollIndicator()},250)})}
26handleMobileChange(){if(this.isMobile&&this.isStacked){this.setupMobileStacked()}else{this.cleanupMobileStacked()}}
27setupMobileStacked(){this.rightColumn.addClass('expanded')}
28cleanupMobileStacked(){this.rightColumn.removeClass('expanded')}
29activateFirstItem(){if(this.leftItems.length>0){this.activateItem(0,!1);this.updateProgressBar()}}
30activateItem(index,animate=!0){if(index===this.currentIndex||index<0||index>=this.leftItems.length){return}
31const previousIndex=this.currentIndex;this.currentIndex=index;this.updateActiveStates(previousIndex,index,animate);this.updateProgressBar();if(this.isMobile&&this.isStacked){this.handleMobileStackedActivation(index)}
32if(!this.isMobile){this.scrollToPanelStep(index)}}
33updateActiveStates(previousIndex,currentIndex,animate=!0){const $previousLeft=this.leftItems.eq(previousIndex);const $currentLeft=this.leftItems.eq(currentIndex);const $previousPanel=this.rightPanels.eq(previousIndex);const $currentPanel=this.rightPanels.eq(currentIndex);$previousLeft.removeClass('active');$previousPanel.removeClass('active');$currentLeft.addClass('active');$currentPanel.addClass('active');if(animate){this.animatePanelTransition($previousPanel,$currentPanel)}
34this.updateAriaAttributes()}
35animatePanelTransition($previousPanel,$currentPanel){$previousPanel.css({transform:'translateX(-30px)',opacity:0}
35);setTimeout(()=>{$currentPanel.css({transform:'translateX(0)',opacity:1})},50)}
36handleMobileStackedActivation(index){const $currentPanel=this.rightPanels.eq(index);if(this.isMobile&&this.isStacked){const panelHeight=$currentPanel.outerHeight();this.rightColumn.css('max-height',panelHeight+'px')}}
37syncLeftItem(index){if(index===this.currentIndex||index<0||index>=this.leftItems.length){return}
38const $currentLeft=this.leftItems.eq(this.currentIndex);const $newLeft=this.leftItems.eq(index);$currentLeft.removeClass('active');$newLeft.addClass('active');this.currentIndex=index;this.updateProgressBar();this.rightPanels.removeClass('active');this.rightPanels.eq(index).addClass('active');this.updateAriaAttributes()}
39scrollToPanelStep(index){const $panel=this.rightPanels.eq(index);if($panel.length===0)return;this.isScrolling=!0;const panelTop=$panel.offset().top;const viewportTop=this.scrollViewport.offset().top;const viewportHeight=this.scrollViewport.height();const panelHeight=$panel.outerHeight();const offset=Math.max(100,(viewportHeight-panelHeight)/2);const targetScrollTop=panelTop-viewportTop-offset;this.scrollViewport.animate({scrollTop:targetScrollTop},800,'swing',()=>{setTimeout(()=>{this.isScrolling=!1},200)})}
40scrollToPanel(index){const $panel=this.rightPanels.eq(index);if($panel.length===0)return;this.isScrolling=!0;$('html, body').animate({scrollTop:$panel.offset().top-100},600,'swing',()=>{setTimeout(()=>{this.isScrolling=!1},100)})}
41navigateNext(){const nextIndex=Math.min(this.currentIndex+1,this.leftItems.length-1);this.activateItem(nextIndex);this.leftItems.eq(nextIndex).focus()}
42navigatePrevious(){const prevIndex=Math.max(this.currentIndex-1,0);this.activateItem(prevIndex);this.leftItems.eq(prevIndex).focus()}
43updateAriaAttributes(){this.leftItems.each((index,item)=>{const $item=$(item);$item.attr('aria-selected',index===this.currentIndex?'true':'false');$item.attr('aria-expanded',index===this.currentIndex?'true':'false')});this.rightPanels.each((index,panel)=>{const $panel=$(panel);$panel.attr('aria-hidden',index===this.currentIndex?'false':'true')})}
44setupElementorEditor(){if(window.elementorFrontend.isEditMode()){elementorFrontend.hooks.addAction('frontend/element_ready/animated-side-accordion.default',($widget)=>{const accordion=new AnimatedSideAccordion($widget[0])})}}
45destroy(){this.leftItems.off('click keydown');this.scrollViewport.off('scroll wheel');$(window).off('resize');if(this.intersectionObserver){this.intersectionObserver.disconnect()}}}
46$.fn.animatedSideAccordion=function(){return this.each(function(){if(!$.data(this,'animatedSideAccordion')){$.data(this,'animatedSideAccordion',new AnimatedSideAccordion(this))}})};$(document).ready(function(){$('.asa-widget').animatedSideAccordion()});$(window).on('elementor/frontend/init',function(){elementorFrontend.hooks.addAction('frontend/element_ready/animated-side-accordion.default',function($scope){$scope.find('.asa-widget').animatedSideAccordion()})});$(document).on('elementor/popup/show',function(){$('.asa-widget').animatedSideAccordion()})})(jQuery)

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.