1/** 2 * Image Accordion â expand items by hover, click, or touch. 3 */ 4( function () { 5 'use strict'; 6 7 /** 8 * @return {boolean} 9 */ 10 function prefersHoverInteraction() { 11 if ( ! window.matchMedia ) { 12 return true; 13 } 14 15 return window.matchMedia( '(hover: hover) and (pointer: fine)' ).matches; 16 } 17 18 /** 19 * @param {HTMLElement} accordion 20 * @return {() => void} 21 */ 22 function bindAccordion( accordion ) { 23 if ( accordion.dataset.dsmImageAccordionBound === '1' ) { 24 return function () {}; 25 } 26 27 const wrapper = accordion.querySelector( 28 '.dsm_image_accordion_wrapper' 29 ); 30 const children = Array.from( 31 accordion.querySelectorAll( '.dsm_image_accordion_child' ) 32 ); 33 34 if ( ! wrapper || ! children.length ) { 35 return function () {}; 36 } 37 38 accordion.dataset.dsmImageAccordionBound = '1'; 39 40 const defaultActive = new Set( 41 children.filter( function ( child ) { 42 return child.classList.contains( 43 'dsm_image_accordion_active_item' 44 ); 45 } ) 46 ); 47 48 const cleanups = []; 49 50 const clearActive = function () { 51 children.forEach( function ( child ) { 52 child.classList.remove( 'dsm_image_accordion_active_item' ); 53 } ); 54 }; 55 56 const restoreDefaultActive = function () { 57 clearActive(); 58 defaultActive.forEach( function ( child ) { 59 child.classList.add( 'dsm_image_accordion_active_item' ); 60 } ); 61 }; 62 63 const setActiveChild = function ( child ) { 64 clearActive(); 65 child.classList.add( 'dsm_image_accordion_active_item' ); 66 }; 67 68 const isHoverMode = wrapper.classList.contains( 69 'dsm_image_accordion_trigger_on_hover' 70 ); 71 const isClickMode = wrapper.classList.contains( 72 'dsm_image_accordion_trigger_on_click' 73 ); 74 const prefersHover = prefersHoverInteraction(); 75 76 children.forEach( function ( child ) { 77 if ( ! child.hasAttribute( 'tabindex' ) ) { 78 child.setAttribute( 'tabindex', '0' ); 79 } 80 if ( ! child.hasAttribute( 'role' ) ) { 81 child.setAttribute( 'role', 'button' ); 82 } 83 84 const onKeyDown = function ( event ) { 85 if ( event.key !== 'Enter' && event.key !== ' ' ) { 86 return; 87 } 88 event.preventDefault(); 89 setActiveChild( child ); 90 }; 91 92 child.addEventListener( 'keydown', onKeyDown ); 93 cleanups.push( function () { 94 child.removeEventListener( 'keydown', onKeyDown ); 95 } ); 96 } ); 97 98 if ( isHoverMode && prefersHover ) { 99 children.forEach( function ( child ) { 100 const onEnter = function () { 101 setActiveChild( child ); 102 }; 103 const onLeave = function () { 104 restoreDefaultActive(); 105 }; 106 107 child.addEventListener( 'mouseenter', onEnter ); 108 child.addEventListener( 'mouseleave', onLeave ); 109 cleanups.push( function () { 110 child.removeEventListener( 'mouseenter', onEnter ); 111 child.removeEventListener( 'mouseleave', onLeave ); 112 } ); 113 } ); 114 } else if ( isHoverMode ) { 115 children.forEach( function ( child ) { 116 const onTap = function ( event ) { 117 if ( 118 child.classList.contains( 119 'dsm_image_accordion_active_item' 120 ) && 121 ! defaultActive.has( child ) 122 ) { 123 event.preventDefault(); 124 restoreDefaultActive(); 125 return; 126 } 127 128 if ( 129 child.classList.contains( 130 'dsm_image_accordion_active_item' 131 ) 132 ) { 133 return; 134 } 135 136 event.preventDefault(); 137 setActiveChild( child ); 138 }; 139 140 child.addEventListener( 'click', onTap ); 141 cleanups.push( function () { 142 child.removeEventListener( 'click', onTap ); 143 } ); 144 } ); 145 } 146 147 if ( isClickMode ) { 148 accordion.classList.add( 'dsm_image_accordion_click_item' ); 149 children.forEach( function ( child ) { 150 const onClick = function () { 151 if ( 152 child.classList.contains( 153 'dsm_image_accordion_active_item' 154 ) 155 ) { 156 return; 157 } 158 setActiveChild( child ); 159 }; 160 161 child.addEventListener( 'click', onClick ); 162 cleanups.push( function () { 163 child.removeEventListener( 'click', onClick ); 164 } ); 165 } ); 166 } 167 168 return function () { 169 delete accordion.dataset.dsmImageAccordionBound; 170 cleanups.forEach( function ( fn ) { 171 fn(); 172 } ); 173 }; 174 } 175 176 function boot( root ) { 177 var scope = root && root.querySelectorAll ? root : document; 178 scope.querySelectorAll( '.dsm_image_accordion' ).forEach( bindAccordion ); 179 } 180
181 function dsmReinitImageAccordionInRoot( root ) { 182 if ( ! root || ! root.querySelectorAll ) { 183 return; 184 } 185 186 root.querySelectorAll( '.dsm_image_accordion' ).forEach( function ( accordion ) { 187 delete accordion.dataset.dsmImageAccordionBound; 188 } ); 189 190 boot( root ); 191 } 192 193 window.dsmReinitImageAccordionInRoot = dsmReinitImageAccordionInRoot; 194 195 [ 'dsm:reinit-library-modules-in-root', 'dsm:reinit-carousels-in-root' ].forEach( 196 function ( eventName ) { 197 window.addEventListener( eventName, function ( event ) { 198 var eventRoot = event && event.detail ? event.detail.root : null; 199 if ( eventRoot ) { 200 dsmReinitImageAccordionInRoot( eventRoot ); 201 } 202 } ); 203 } 204 ); 205 206 if ( document.readyState === 'loading' ) { 207 document.addEventListener( 'DOMContentLoaded', function () { 208 boot( document ); 209 } ); 210 } else { 211 boot( document ); 212 } 213} )();
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.