1UAGBTabs = { 2 init( $selector ) { 3 const tabsWrap = document.querySelectorAll( $selector ); 4 if ( ! tabsWrap ) { 5 return; 6 } 7 8 for ( let i = 0; i < tabsWrap.length; i++ ) { 9 UAGBTabs.addEvents( tabsWrap[ i ], $selector ); 10 } 11 }, 12 addEvents( tabsWrap, $selector ) { 13 // Tabs wrap has two child elements, one is tabs list (.uagb-tabs__panel) and another is tabs body (.uagb-tabs__body-wrap). 14 const tabsWrapChildren = tabsWrap.children; 15 16 // Verify if tabsWrapChildren has two child elements. 17 if ( 2 !== tabsWrapChildren.length ) { 18 return; 19 } 20 21 const tabActive = tabsWrap.getAttribute( 'data-tab-active' ); 22 23 // Select tabs list (.uagb-tabs__panel) from tabsWrapChildren. 24 const tabLi = tabsWrapChildren[0].querySelectorAll( 'li.uagb-tab' ); 25 26 // Select tabs body (.uagb-tabs__body-wrap) from tabsWrapChildren and children will be tab body container (.uagb-tabs__body-container). 27 const tabBody = tabsWrapChildren[1].children; 28 29 for ( let i = 0; i < tabBody.length; i++ ) { 30 tabBody[ i ].setAttribute( 'tabindex', '0' ); 31 tabBody[ i ].setAttribute( 'role', 'tabpanel' ); 32 }; 33 34 // Set initial active class to Tabs body. 35 tabBody[ tabActive ].classList.add( 'uagb-tabs-body__active' ); 36 37 // Set initial active class to Tabs li. 38 tabLi[ tabActive ].classList.add( 'uagb-tabs__active' ); 39 40 for ( let i = 0; i < tabLi.length; i++ ) { 41 const tabsAnchor = tabLi[ i ].getElementsByTagName( 'a' )[ 0 ]; 42 43 // Set initial li ids. 44 tabLi[ i ].setAttribute( 'id', 'uagb-tabs__tab' + i ); 45 46 // Set initial aria attributes true for anchor tags. 47 tabsAnchor.setAttribute( 'aria-selected', true ); 48 // Selected tab gets tabindex="0". 49 tabsAnchor.setAttribute( 'tabindex', '0' ); 50 51 if ( ! tabLi[ i ].classList.contains( 'uagb-tabs__active' ) ) { 52 // Set aria attributes for anchor tags as false where needed. 53 tabsAnchor.setAttribute( 'aria-selected', false ); 54 // Other non selected tabs get tabindex="-1". 55 tabsAnchor.setAttribute( 'tabindex', '-1' ); 56 } 57 58 // Set initial data attribute for anchor tags. 59 tabsAnchor.setAttribute( 'data-tab', i ); 60 61 tabsAnchor.mainWrapClass = $selector; 62 // Add Click event listener 63 tabsAnchor.addEventListener( 'click', function ( e ) { 64 UAGBTabs.tabClickEvent( e, this, this.parentElement ); 65 } ); 66 } 67 68 // Enable arrow navigation between tabs in the tab list 69 const tabsRole = tabsWrapChildren[0].querySelectorAll( '.uagb-tab a[role="tab"]' ); 70 71 tabsRole.forEach( tab => { 72 tab.addEventListener( 'keydown', function ( e ) { 73 let newIndex; 74 const currentIndex = Array.prototype.indexOf.call( tabsRole, e.target ); 75 76 if ( e.key === 'ArrowRight' ) { 77 // Move to the next tab, loop back to the first if at the last 78 newIndex = ( currentIndex + 1 ) % tabsRole.length; 79 tabsRole[newIndex].focus(); 80 tabsRole[currentIndex].setAttribute( 'aria-selected', 'false' ); 81 tabsRole[newIndex].setAttribute( 'aria-selected', 'true' ); 82 UAGBTabs.tabClickEvent( e, tabsRole[newIndex], tabsRole[newIndex].parentElement ); 83 e.preventDefault(); 84 } else if ( e.key === 'ArrowLeft' ) { 85 // Move to the previous tab, loop to the last if at the first 86 newIndex = ( currentIndex - 1 + tabsRole.length ) % tabsRole.length; 87 tabsRole[newIndex].focus(); 88 tabsRole[currentIndex].setAttribute( 'aria-selected', 'false' ); 89 tabsRole[newIndex].setAttribute( 'aria-selected', 'true' ); 90 UAGBTabs.tabClickEvent( e, tabsRole[newIndex], tabsRole[newIndex].parentElement ); 91 e.preventDefault(); 92 } 93 } ); 94 } ); 95 }, 96 tabClickEvent( e, tabName, selectedLi ) { 97 e.preventDefault(); 98 99 const tabId = tabName.getAttribute( 'data-tab' ); 100 const tabPanel = selectedLi.closest( '.uagb-tabs__panel' ); 101 102 const tabContainer = tabName.closest( '.uagb-tabs__wrap' ); 103 104 const tabBodyWrap = tabContainer.querySelector( '.uagb-tabs__body-wrap' ); 105 106 const tabBodyChildren = tabBodyWrap.children; 107 const tabSelectedBody = UAGBTabs.getChildrenWithClass( tabBodyChildren, 'uagb-inner-tab-' + tabId ); 108 109 const allLi = tabPanel.querySelectorAll( 'a.uagb-tabs-list' ); 110 111 // Remove old li active class. 112 tabPanel.querySelector( '.uagb-tabs__active' )?.classList.remove( 'uagb-tabs__active' ); 113 114 //Remove old tab body active class. 115 UAGBTabs.getChildrenWithClass( tabBodyChildren, 'uagb-tabs-body__active' )?.classList.remove( 'uagb-tabs-body__active' ); 116 117 // Set aria-selected attribute as false for old active tab. 118 for ( let i = 0; i < allLi.length; i++ ) { 119 allLi[ i ].setAttribute( 'aria-selected', false ); 120 // Other non selected tabs get tabindex="-1". 121 allLi[i].setAttribute( 'tabindex', '-1' ); 122 } 123 124 // Set selected li active class. 125 selectedLi.classList.add( 'uagb-tabs__active' ); 126 127 // Set aria-selected attribute as true for new active tab. 128 tabName.setAttribute( 'aria-selected', true ); 129 130 // Selected tab gets tabindex="0". 131 tabName.setAttribute( 'tabindex', '0' ); 132 133 // Set selected tab body active class. 134 tabSelectedBody?.classList.add( 'uagb-tabs-body__active' ); 135 136 // Set aria-hidden attribute false for selected tab body. 137 tabSelectedBody?.setAttribute( 'aria-hidden', false ); 138 139 // Set aria-hidden attribute true for all unselected tab body. 140 for ( let i = 0; i < tabBodyChildren.length; i++ ) { 141 // If tabBodyChildren[i] has .uagb-inner-tab-' + tabId + ' then continue. 142 if ( tabBodyChildren[ i ].classList.contains( 'uagb-inner-tab-' + tabId ) ) { 143 continue; 144 } 145 146 tabBodyChildren[ i ].setAttribute( 'aria-hidden', true ); 147 } 148 }, 149 anchorTabId( $selector ) { 150 const tabsHash = window.location.hash; 151
152 if ( '' !== tabsHash && /^#uagb-tabs__tab\d$/.test( tabsHash ) ) { 153 const mainWrapClass = $selector; 154 const tabId = escape( tabsHash.substring( 1 ) ); 155 const selectedLi = document.querySelector( '#' + tabId ); 156 const topPos = selectedLi.getBoundingClientRect().top + window.pageYOffset; 157 window.scrollTo( { 158 top: topPos, 159 behavior: 'smooth', 160 } ); 161 const tabNum = selectedLi.querySelector( 'a.uagb-tabs-list' ).getAttribute( 'data-tab' ); 162 const listPanel = selectedLi.closest( '.uagb-tabs__panel' ); 163 const tabSelectedBody = document.querySelector( 164 mainWrapClass + ' > .uagb-tabs__body-wrap > .uagb-inner-tab-' + tabNum 165 ); 166 const tabUnselectedBody = document.querySelectorAll( 167 mainWrapClass + 168 ' > .uagb-tabs__body-wrap > .uagb-tabs__body-container:not(.uagb-inner-tab-' + 169 tabNum + 170 ')' 171 ); 172 const allLi = selectedLi.querySelectorAll( 'a.uagb-tabs-list' ); 173 const selectedAnchor = selectedLi.querySelector( 'a.uagb-tabs-list' ); 174 175 // Remove old li active class. 176 listPanel.querySelector( '.uagb-tabs__active' ).classList.remove( 'uagb-tabs__active' ); 177 178 // Remove old tab body active class. 179 document 180 .querySelector( mainWrapClass + ' > .uagb-tabs__body-wrap > .uagb-tabs-body__active' ) 181 .classList.remove( 'uagb-tabs-body__active' ); 182 183 // Set aria-selected attribute as false for old active tab. 184 for ( let i = 0; i < allLi.length; i++ ) { 185 allLi[ i ].setAttribute( 'tabindex', '-1' ); // Old active tab gets tabindex="-1". 186 allLi[ i ].setAttribute( 'aria-selected', false ); 187 } 188 189 // Set selected li active class. 190 selectedLi.classList.add( 'uagb-tabs__active' ); 191 192 // Set aria-selected attribute as true for new active tab. 193 selectedAnchor.setAttribute( 'aria-selected', true ); 194 195 selectedAnchor.setAttribute( 'tabindex', '0' ); // New active tab gets tabindex="0". 196 197 // Set selected tab body active class. 198 tabSelectedBody.classList.add( 'uagb-tabs-body__active' ); 199 200 // Set aria-hidden attribute false for selected tab body. 201 tabSelectedBody.setAttribute( 'aria-hidden', false ); 202 203 // Set aria-hidden attribute true for all unselected tab body. 204 for ( let i = 0; i < tabUnselectedBody.length; i++ ) { 205 tabUnselectedBody[ i ].setAttribute( 'aria-hidden', true ); 206 } 207 } 208 }, 209 getChildrenWithClass( children, className ) { 210 let child = null; 211 for ( let i = 0; i < children.length; i++ ) { 212 if ( children[ i ].classList.contains( className ) ) { 213 child = children[ i ]; 214 break; 215 } 216 } 217 return child; 218 } 219};
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.