1export default function GDMSlideshow(selectors, height, arrows, mobileHeight, arrowsClass, dots, mobileBreakPoint, autoScrollOn, autoScrollInterval) { 2 3 4 const containers = document.querySelectorAll(selectors); 5 6 [...containers].forEach((container) => { 7 8 const slidesUl = container.querySelector(".slides"); 9 const slidesLis = container.querySelectorAll(".slides li"); 10 const slidesFigures = container.querySelectorAll(".slides li figure"); 11 const articleTextContainers = container.querySelectorAll('.article-text'); 12 13 // If it's a two column slideshow with text we set the height based on the height of the text 14 const setWidth = () => [...slidesLis].map(li => li.style.width = `${container.offsetWidth}px`); 15 16 setWidth(); 17 18 // Get the height of the tallest text container 19 const tallestTextContainer = Math.max(...[...articleTextContainers].map(container => [...container.children].reduce((acc, cur) => acc + cur.offsetHeight + 8, 0) - 8 + 40)); 20 21 22 // Set that as the height of the slideshow and figures 23 const slideshowHeight = () => { 24 25 if(height) { 26 container.style.height = `${height}px` 27 return height; 28 }; 29 30 if(mobileHeight && window.innerWidth < mobileBreakPoint) { 31 container.style.height = `${mobileHeight}px`; 32 return mobileHeight; 33 } 34 35 if(!mobileHeight && window.innerWidth < mobileBreakPoint) { 36 37 const calculatedMobileHeight = [...container.querySelectorAll('img')][0].offsetHeight + Math.max(...[...articleTextContainers].map(container => container.offsetHeight)) + 30; 38 container.style.height = `${calculatedMobileHeight}px`; 39 40 return calculatedMobileHeight; 41 } 42 43 // alert(`${[...container.querySelectorAll('img')][0].offsetHeight + Math.max(...[...articleTextContainers].map(container => container.offsetHeight)) + 30}px`); 44 45 if(!height && window.innerWidth > mobileBreakPoint) { 46 const calculatedLaptopHeight = Math.max(...[...articleTextContainers].map(container => container.offsetHeight)); 47 container.style.height = `${calculatedLaptopHeight}px`; 48 49 return calculatedLaptopHeight; 50 } 51 52 53 } 54 55 slideshowHeight(); 56 57 58 const createArrows = () => { 59 const arrowEls = document.createElement("ul"); 60 arrowsClass ? arrowEls.classList.add(arrowsClass) : arrowEls.classList.add("arrows"); 61 container.insertAdjacentElement("afterbegin", arrowEls); 62 63 const leftArrow = document.createElement("li"); 64 leftArrow.classList.add("left"); 65 leftArrow.textContent = "Left"; 66 arrowEls.insertAdjacentElement("afterbegin", leftArrow); 67 68 const rightArrow = document.createElement("li"); 69 rightArrow.classList.add("right"); 70 rightArrow.textContent = "Right"; 71 arrowEls.insertAdjacentElement("beforeend", rightArrow); 72 }; 73 74 if (arrows && !container.querySelector(".arrows") && !container.querySelector(`.${arrowsClass}`)) createArrows(); 75 76 // Set the slide position state to 0 77 let slidePosition = 0; 78 79 // Set the position of the slides using margin 80 const setSlidePosition = () => { 81 slidesUl.style.marginLeft = `${ 82 -Math.abs(slidePosition) * container.offsetWidth 83 }px`; 84 } 85 86 const dotsNav = () => { 87 88 const dotsOl = document.createElement('ol'); 89 dotsOl.classList.add('dots-nav'); 90 91 [...slidesLis].forEach((slide, i) => { 92 93 const dot = document.createElement('li'); 94 dot.textContent = i + 1; 95 dotsOl.insertAdjacentElement('beforeend', dot); 96 97 98 dot.addEventListener('click', (e) => { 99 slidePosition = -1 * i; 100
101 setActiveDotClass(); 102 103 // Set the margin on the slides ul based on the slidePosition state 104 setSlidePosition(); 105 106 // positionNavs(); 107 }); 108 }); 109 110 slidesUl.insertAdjacentElement('afterend', dotsOl); 111 } 112 // dotsNav 113 114 dots && !container.querySelector('.dots-nav') && dotsNav(); 115 116 // Position the navs under the text by calculating the text height per slide 117 // const positionNavs = () => { 118 119 // const totalTextHeight = [...articleTextContainers[Math.abs(slidePosition)].children].reduce((acc, cur) => acc + cur.offsetHeight + 8, 0) + 30; 120 121 // [container.querySelector('.dots-nav'), container.querySelector('.slideshow-nav')].forEach(nav => nav.style.marginTop = `${totalTextHeight}px`); 122 // } 123 124 // Make sure the dots nav is always below the text. even if the text overflows the slideshow 125 // window.innerWidth > mobileBreakPoint && positionNavs(); Not using this now -- made decision to position navs at bottom of slidehow 126 127 128 const arrowsNav = () => { 129 const arrowsUl = document.querySelector(arrowsClass ? `.${arrowsClass}` : "ul.arrows"); 130 131 arrowsUl.addEventListener("click", (e) => { 132 // If user clicks anything but the arrows, don't do anything 133 if ( 134 !e.target.classList.contains("left") && 135 !e.target.classList.contains("right") 136 ) 137 return; 138 139 // if the user clicks the left arrow and the first slide is displaying, go to the last slide 140 if (e.target.classList.contains("left") && slidePosition === 0) { 141 slidePosition = slidesLis.length -1; 142 } else if ( 143 // If the user clicks on thr right arrow when they're viewing the last slide, go to the first slide 144 e.target.classList.contains("right") && 145 Math.abs(slidePosition) === slidesLis.length -1 146 ) { 147 slidePosition = 0; 148 } else if 149 // Change the SlidePosition state 150 (e.target.classList.contains("left") && slidePosition !== 0) { 151 slidePosition -= 1 152 } else { 153 slidePosition -= 1; 154 } 155 156 // alert(slidePosition); 157 158 // Set the margin on the slides ul based on the slidePosition state 159 setSlidePosition(); 160 161 // Set the active dot 162 setActiveDotClass(); 163 164 // Position the navs under the text 165 // positionNavs(); 166 167 168 }); 169 }; 170 171 if (arrows) arrowsNav(); 172 173 174 const setActiveDotClass = () => { 175 [...document.querySelectorAll('.dots-nav li')].forEach((dot, i, arr) => { 176 dot.classList.contains('active') && dot.classList.remove('active'); 177 arr[Math.abs(slidePosition)].classList.add('active'); 178 }); 179 } 180 181 setActiveDotClass(); 182 183 // Make the arrows display to the left and right of the dots nav 184 if(container.querySelector(".slideshow-nav")) { 185 186 const dotsWidth = [...document.querySelectorAll('.dots-nav li')].reduce((acc, cur) => acc + cur.offsetWidth + 10, 0) + (document.querySelectorAll('.slideshow-nav li')[0].offsetWidth * 2); 187 188 container.querySelector(".slideshow-nav").style.width = `${dotsWidth}px`; 189 container.querySelector(".slideshow-nav").style.marginLeft = `${(-1 * (dotsWidth / 2))}px`; 190 } 191 192 193 const autoScroll = () => { 194 195 const scrollSlides = () => { 196 if (Math.abs(slidePosition) === slidesLis.length -1) { // last slide 197 slidePosition = 0; // go back to first slide 198 } else { 199 // alert(slidePosition) 200 201 slidePosition -= 1; 202 // alert(slidePosition) 203 } 204 205 // Set the margin on the slides ul based on the slidePosition state 206 setSlidePosition(); 207 208 // Set the active dot 209 setActiveDotClass(); 210 211 // Position the navs under the text 212 // positionNavs(); 213 } 214 215 216 217 let startSlideshow = setInterval(scrollSlides, autoScrollInterval); 218 219 container.addEventListener('mouseover', (e) => { 220 clearInterval(startSlideshow); 221 // alert('should not auto scroll') 222 }); 223 container.addEventListener('mouseout', () => startSlideshow = setInterval(scrollSlides, autoScrollInterval)); 224 225 } 226 // autoScroll 227 228 autoScrollOn && autoScroll() 229 230 window.addEventListener('resize', (e) => { 231 setWidth(); 232 233 slideshowHeight(); 234 setSlidePosition(); 235 236 }); 237 238 239 // Editor's pick margin top 240 const editorsPicks = document.querySelector('.editors-picks'); 241 242 const positionEditorsPicks = () => { 243 244 editorsPicks.style.marginTop = window.innerWidth > 990 ? `-${editorsPicks.offsetHeight}px` : 0; 245 document.querySelector('.features-with-editors-picks .large-9').style.minHeight = window.innerWidth > 990 ? `${slideshowHeight() + editorsPicks.offsetHeight + 10}px` : '0'; 246 247 } 248 249 if(editorsPicks) { 250 positionEditorsPicks(); 251 window.addEventListener('resize', (e) => positionEditorsPicks()); 252 } 253 254 }); 255 256}
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.