1/** 2 * BigWelt content sliders â scroll-snap carousels with prev/next arrows. 3 * Uses document-level delegation so arrows keep working after page reload / editor save 4 * (saved HTML must not rely on data-bw-slider-init alone). 5 */ 6(function (global) { 7 'use strict'; 8 9 function isEditorMode() { 10 if (global.BW_IS_CONTENTBOX_EDITOR || global.BW_IS_AIBOX_EDITOR) { 11 return true; 12 } 13 if (global.BwIsContentboxEditor) { 14 return global.BwIsContentboxEditor(); 15 } 16 if (global.BwContentboxClickfix && typeof global.BwContentboxClickfix.isEditorMode === 'function') { 17 return global.BwContentboxClickfix.isEditorMode(); 18 } 19 if (document.body && document.body.classList.contains('bw-page-editor')) { 20 return true; 21 } 22 return false; 23 } 24 25 function qsa(sel, root) { 26 return Array.prototype.slice.call((root || document).querySelectorAll(sel)); 27 } 28 29 function qs(sel, root) { 30 return (root || document).querySelector(sel); 31 } 32 33 function findTrack(wrap) { 34 if (!wrap) { 35 return null; 36 } 37 return qs('.bw-content-slider-track', wrap) 38 || qs('#imageSlider', wrap) 39 || qs('[data-bw-slider-track]', wrap) 40 || qsa('[style*="scroll-snap"]', wrap).filter(function (el) { 41 return el.children && el.children.length > 0; 42 })[0]; 43 } 44 45 function findWrap(el) { 46 if (!el || !el.closest) { 47 return null; 48 } 49 return el.closest('.bw-content-slider-wrap, #sliderContainer, [data-bw-slider]'); 50 } 51 52 function findWrapFromTrack(track) { 53 if (!track || !track.parentElement) { 54 return null; 55 } 56 var p = track.parentElement; 57 if (p.id === 'sliderContainer' || p.classList.contains('bw-content-slider-wrap') || p.getAttribute('data-bw-slider')) { 58 return p; 59 } 60 return findWrap(track); 61 } 62 63 function isInsideSlider(el) { 64 return !!(el && el.closest && el.closest('.bw-content-slider-wrap, #sliderContainer, [data-bw-slider]')); 65 } 66 67 function isPrevButton(btn) { 68 if (!btn || !isInsideSlider(btn)) { 69 return false; 70 } 71 if (btn.classList.contains('bw-slider-prev') || btn.getAttribute('data-bw-slider-prev') !== null) { 72 return true; 73 } 74 /* Only chevron/angle icons â fa-arrow-* is used on page CTAs and must not hijack clicks */ 75 return !!qs('.fa-chevron-left, .fa-angle-left', btn); 76 } 77 78 function isNextButton(btn) { 79 if (!btn || !isInsideSlider(btn)) { 80 return false; 81 } 82 if (btn.classList.contains('bw-slider-next') || btn.getAttribute('data-bw-slider-next') !== null) { 83 return true; 84 } 85 return !!qs('.fa-chevron-right, .fa-angle-right', btn); 86 } 87 88 function resolveArrowButton(target) { 89 if (!target || !target.closest) { 90 return null; 91 } 92 var wrap = findWrap(target); 93 if (!wrap) { 94 return null; 95 } 96 var btn = target.closest('.bw-slider-prev, .bw-slider-next, [data-bw-slider-prev], [data-bw-slider-next]'); 97 if (btn && wrap.contains(btn)) { 98 return btn; 99 } 100 var icon = target.closest('.fa-chevron-left, .fa-chevron-right, .fa-angle-left, .fa-angle-right'); 101 if (icon) { 102 btn = icon.closest('button, a, [role="button"]'); 103 if (btn && wrap.contains(btn)) { 104 return btn; 105 } 106 } 107 return null; 108 } 109 110 function clickIsOnArrowButton(target, btn) { 111 if (!target || !btn) { 112 return false; 113 } 114 return target === btn || (btn.contains && btn.contains(target)); 115 } 116 117 function labelArrowButtons(wrap) { 118 var prev = qs('.bw-slider-prev', wrap); 119 var next = qs('.bw-slider-next', wrap); 120 qsa('button, a, [role="button"]', wrap).forEach(function (btn) { 121 if (!prev && isPrevButton(btn)) { 122 prev = btn; 123 btn.classList.add('bw-slider-prev'); 124 } 125 if (!next && isNextButton(btn)) { 126 next = btn; 127 btn.classList.add('bw-slider-next'); 128 } 129 }); 130 return { prev: prev, next: next }; 131 } 132 133 function hideDots(wrap) { 134 wrap.classList.add('bw-slider-no-dots'); 135 qsa('.bw-slider-dots, .slick-dots, ul.slick-dots, .slider-dots, [class*="slider-
135dots"]', wrap).forEach(function (el) { 136 el.style.display = 'none'; 137 }); 138 } 139 140 function slideStep(track) { 141 if (!track) { 142 return 300; 143 } 144 var slide = track.querySelector(':scope > *') || track.children[0]; 145 if (!slide) { 146 return track.clientWidth || 300; 147 } 148 var w = slide.getBoundingClientRect().width; 149 if (w > 0) { 150 return w; 151 } 152 var style = window.getComputedStyle(slide); 153 var flex = style.flex || style.flexBasis || ''; 154 if (flex.indexOf('100%') !== -1 || (slide.style.flex && slide.style.flex.indexOf('100%') !== -1)) { 155 return track.clientWidth || 300; 156 } 157 return track.clientWidth || slide.offsetWidth || 300; 158 } 159 160 function scrollTrack(track, direction) { 161 if (!track) { 162 return; 163 } 164 var step = slideStep(track); 165 var delta = direction < 0 ? -step : step; 166 var target = track.scrollLeft + delta; 167 if (typeof track.scrollTo === 'function') { 168 try { 169 track.scrollTo({ left: target, behavior: 'smooth' }); 170 return; 171 } catch (err) { 172 /* fall through */ 173 } 174 } 175 track.scrollLeft = target; 176 } 177 178 function handleArrowActivate(e) { 179 if (isEditorMode()) { 180 return; 181 } 182 var btn = resolveArrowButton(e.target); 183 if (!btn || !clickIsOnArrowButton(e.target, btn)) { 184 return; 185 } 186 var wrap = findWrap(btn); 187 if (!wrap) { 188 return; 189 } 190 var track = findTrack(wrap); 191 if (!track) { 192 return; 193 } 194 var prev = isPrevButton(btn); 195 var next = isNextButton(btn); 196 if (!prev && !next) { 197 return; 198 } 199 200 e.preventDefault(); 201 e.stopPropagation(); 202 if (typeof e.stopImmediatePropagation === 'function') { 203 e.stopImmediatePropagation(); 204 } 205 206 scrollTrack(track, prev ? -1 : 1); 207 } 208 209 function collectWraps(root) { 210 root = root || document; 211 var seen = []; 212 var add = function (el) { 213 if (!el || seen.indexOf(el) !== -1) { 214 return; 215 } 216 // Tracks/slides must not be treated as wraps (LLM sometimes duplicates classes). 217 if (el.classList && (el.classList.contains('bw-content-slider-track') || el.classList.contains('bw-slide'))) { 218 return; 219 } 220 seen.push(el); 221 }; 222 223 qsa('#sliderContainer, .bw-content-slider-wrap, [data-bw-slider]', root).forEach(add); 224 qsa('#imageSlider, .bw-content-slider-track', root).forEach(function (track) { 225 add(findWrapFromTrack(track)); 226 }); 227 228 return seen; 229 } 230 231 function normalizeSlider(wrap) { 232 if (!wrap) { 233 return; 234 } 235 // Repair class pollution before wiring. 236 if (wrap.classList.contains('bw-content-slider-track')) { 237 wrap.classList.remove('bw-content-slider-track'); 238 } 239 wrap.removeAttribute('data-bw-slider-init'); 240 wrap.classList.add('bw-content-slider-wrap'); 241 242 var track = findTrack(wrap); 243 if (!track) { 244 return; 245 } 246 track.classList.add('bw-content-slider-track'); 247 track.classList.remove('bw-content-slider-wrap', 'bw-slider-no-dots', 'bw-slide'); 248 track.removeAttribute('data-bw-slider'); 249 track.removeAttribute('data-bw-hide-dots'); 250 251 if (!track.style.overflowX) { 252 track.style.overflowX = 'auto'; 253 } 254 if (!track.style.display) { 255 track.style.display = 'flex'; 256 } 257 if (!track.style.scrollSnapType) { 258 track.style.scrollSnapType = 'x mandatory'; 259 } 260 if (!track.style.scrollBehavior) { 261 track.style.scrollBehavior = 'smooth'; 262 } 263 264 Array.prototype.slice.call(track.children).forEach(function (slide) { 265 if (!slide || slide.nodeType !== 1) { 266 return; 267 } 268 if (slide.classList.contains('bw-slider-prev') || slide.classList.contains('bw-slider-next')) { 269 // Arrows must never live inside the flex track (they become full-width white bars). 270 wrap.appendChild(slide); 271 return; 272 } 273 slide.classList.remove('bw-content-slider-wrap', 'bw-content-slider-track', 'bw-slider-no-dots'); 274 slide.classList.add('bw-slide'); 275 slide.removeAttribute('data-bw-slider'); 276 if (!slide.style.flex) { 277 slide.style.flex = '0 0 100%'; 278 } 279 if (!slide.style.minWidth) { 280 slide.style.minWidth = '100%'; 281 } 282 if (!slide.style.scrollSnapAlign) { 283 slide.style.scrollSnapAlign = 'start'; 284 } 285 if (!slide.style.boxSizing) { 286 slide.style.boxSizing = 'border-box'; 287 } 288 }); 289 290 // Deduplicate arrows â keep one prev and one next (prefer styled). 291 var prevAll = qsa('.bw-slider-prev, [data-bw-slider-prev]', wrap); 292 var nextAll = qsa('.bw-slider-next, [data-bw-slider-next]', wrap);
293 qsa('button, a, [role="button"]', wrap).forEach(function (btn) { 294 if (isPrevButton(btn) && prevAll.indexOf(btn) === -1) { 295 prevAll.push(btn); 296 } 297 if (isNextButton(btn) && nextAll.indexOf(btn) === -1) { 298 nextAll.push(btn); 299 } 300 }); 301 function scoreArrow(btn) { 302 var s = (btn.getAttribute('style') || ''); 303 var n = 0; 304 if (/background/i.test(s)) n += 2; 305 if (/rgba|#/i.test(s)) n += 2; 306 if (/width/i.test(s)) n += 1; 307 return n; 308 } 309 function keepBest(list, cls) { 310 if (!list.length) return null; 311 list.sort(function (a, b) { return scoreArrow(b) - scoreArrow(a); }); 312 var keep = list[0]; 313 list.slice(1).forEach(function (el) { 314 if (el && el.parentNode) el.parentNode.removeChild(el); 315 }); 316 keep.classList.add(cls); 317 if (keep.parentNode !== wrap) { 318 wrap.appendChild(keep); 319 } 320 return keep; 321 } 322 var arrows = { 323 prev: keepBest(prevAll, 'bw-slider-prev'), 324 next: keepBest(nextAll, 'bw-slider-next') 325 }; 326 if (!arrows.prev || !arrows.next) { 327 var labeled = labelArrowButtons(wrap); 328 if (!arrows.prev) arrows.prev = labeled.prev; 329 if (!arrows.next) arrows.next = labeled.next; 330 } 331 if (arrows.prev) { 332 arrows.prev.setAttribute('type', 'button'); 333 arrows.prev.setAttribute('aria-label', 'Previous slide'); 334 arrows.prev.style.pointerEvents = 'auto'; 335 arrows.prev.style.setProperty('position', 'absolute', 'important'); 336 arrows.prev.style.setProperty('top', '50%', 'important'); 337 arrows.prev.style.setProperty('bottom', 'auto', 'important'); 338 arrows.prev.style.setProperty('left', '16px', 'important'); 339 arrows.prev.style.setProperty('right', 'auto', 'important'); 340 arrows.prev.style.setProperty('transform', 'translateY(-50%)', 'important'); 341 arrows.prev.style.setProperty('z-index', '30', 'important'); 342 arrows.prev.style.setProperty('float', 'none', 'important'); 343 arrows.prev.style.setProperty('margin', '0', 'important'); 344 arrows.prev.style.setProperty('flex', '0 0 auto', 'important'); 345 arrows.prev.style.setProperty('min-width', '44px', 'important'); 346 arrows.prev.style.setProperty('max-width', '64px', 'important'); 347 } 348 if (arrows.next) { 349 arrows.next.setAttribute('type', 'button'); 350 arrows.next.setAttribute('aria-label', 'Next slide'); 351 arrows.next.style.pointerEvents = 'auto'; 352 arrows.next.style.setProperty('position', 'absolute', 'important'); 353 arrows.next.style.setProperty('top', '50%', 'important'); 354 arrows.next.style.setProperty('bottom', 'auto', 'important'); 355 arrows.next.style.setProperty('right', '16px', 'important'); 356 arrows.next.style.setProperty('left', 'auto', 'important'); 357 arrows.next.style.setProperty('transform', 'translateY(-50%)', 'important'); 358 arrows.next.style.setProperty('z-index', '30', 'important'); 359 arrows.next.style.setProperty('float', 'none', 'important'); 360 arrows.next.style.setProperty('margin', '0', 'important'); 361 arrows.next.style.setProperty('flex', '0 0 auto', 'important'); 362 arrows.next.style.setProperty('min-width', '44px', 'important'); 363 arrows.next.style.setProperty('max-width', '64px', 'important'); 364 } 365 366 if (wrap.getAttribute('data-bw-hide-dots') === '1' || wrap.classList.contains('bw-slider-no-dots')) { 367 hideDots(wrap); 368 } 369 } 370 371 function scan(root) { 372 collectWraps(root).forEach(normalizeSlider); 373 } 374 375 var arrowDocs = typeof WeakSet !== 'undefined' ? new WeakSet() : null; 376 var arrowBoundLegacy = false; 377 378 function bindArrowDelegation(doc) { 379 doc = doc || document; 380 if (arrowDocs) { 381 if (arrowDocs.has(doc)) { 382 return; 383 } 384 arrowDocs.add(doc); 385 } else if (doc === document) { 386 if (arrowBoundLegacy) { 387 return; 388 } 389 arrowBoundLegacy = true; 390 } 391 doc.addEventListener('click', handleArrowActivate, true); 392 } 393 394 function boot(root) { 395 root = root || document; 396 var doc = (root.nodeType === 9) ? root : (root.ownerDocument || document); 397 var scope = (root.nodeType === 9) ? (root.body || root) : root; 398 bindArrowDelegation(doc); 399 scan(scope); 400 if (typeof MutationObserver === 'undefined' || !scope) { 401 return; 402 } 403 var t = null; 404 var obs = new MutationObserver(function () { 405 if (t) { 406 clearTimeout(t); 407 } 408 t = setTimeout(function () { 409 scan(scope); 410 }, 120); 411 }); 412 obs.observe(scope, { childList: true, subtree: true }); 413 } 414 415 bindArrowDelegation(document); 416 417 if (document.readyState === 'loading') { 418 document.addEventListener('DOMContentLoaded', function () { boot
418(document); }); 419 } else { 420 boot(document); 421 } 422 423 global.BwContentSlider = { 424 scan: scan, 425 init: normalizeSlider, 426 boot: boot, 427 scrollTrack: scrollTrack, 428 findTrack: findTrack 429 }; 430})(typeof window !== 'undefined' ? window : this);
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.