1(function () { 2 function BreakdanceSwiper() { 3 const { mergeObjects, matchMedia, getCurrentBreakpoint, is, isBuilder, prefersReducedMotion } = BreakdanceFrontend.utils; 4 5 const DEFAULT_SWIPER_OPTIONS = Object.freeze({ 6 settings: { 7 effect: "slide", 8 coverflow: { 9 rotate: { number: 50 }, 10 depth: { number: 100 }, 11 stretch: { number: 0 } 12 }, 13 speed: { number: 1000 }, 14 autoplay_settings: { 15 speed: { number: 3000 } 16 }, 17 advanced: { 18 between_slides: 0, 19 slides_per_view: 1, 20 slides_per_group: 1, 21 initial_slide: 0 22 }, 23 direction: "horizontal" 24 }, 25 pagination: { 26 type: "bullets" 27 } 28 }); 29 30 function isElementInDom(selector) { 31 return !!document.querySelector(selector); 32 } 33 34 /** 35 * Breakpoints support 36 */ 37 38 function setBreakpoint(swiper, settings) { 39 const { BASE_BREAKPOINT_ID } = window.BreakdanceFrontend.data; 40 const { realIndex, initialized, params } = swiper; 41 42 const hasLoop = swiper.params.loop && !isBuilder(); 43 const { advanced, effect } = settings; 44 const { slides_per_view, slides_per_group, between_slides, one_per_view_at } = advanced; 45 46 const alwaysOne = 47 effect === "fade" || 48 effect === "flip" || 49 one_per_view_at === BASE_BREAKPOINT_ID || 50 matchMedia(one_per_view_at); 51 52 if (alwaysOne) { 53 swiper.params.slidesPerView = 1; 54 swiper.params.slidesPerGroup = 1; 55 } else { 56 setBreakpointProperty(swiper, "slidesPerView", slides_per_view); 57 setBreakpointProperty(swiper, "slidesPerGroup", slides_per_group); 58 } 59 60 setBreakpointProperty(swiper, "spaceBetween", between_slides); 61 62 if (!initialized) { 63 return; 64 } 65 66 const breakpointSlidesPerView = getBreakpointValue(slides_per_view); 67 const needsReLoop = hasLoop && breakpointSlidesPerView !== params.slidesPerView; 68 69 // https://github.com/nolimits4web/swiper/blob/master/src/core/breakpoints/setBreakpoint.mjs#L105 70 if (initialized && needsReLoop) { 71 swiper.loopDestroy(); 72 swiper.loopCreate(realIndex); 73 } 74 75 swiper.updateSlides(); 76 swiper.slideReset(0); 77 } 78 79 function getBreakpointValue(value) { 80 if (Number.isFinite(value)) { 81 return value; 82 } 83 84 if (!is.obj(value)) { 85 return undefined; 86 } 87 88 const availableBreakpoints = Object.keys(value); 89 const current = getCurrentBreakpoint(availableBreakpoints); 90 91 if (!current) { 92 return undefined; 93 } 94 95 const resolvedValue = value[current.id]; 96 return isUnitValue(resolvedValue) ? resolvedValue.number : resolvedValue; 97 } 98 99 function setBreakpointProperty(swiper, key, value) { 100 if (Number.isFinite(value)) { 101 swiper.params[key] = value; 102 return; 103 } 104 105 if (!is.obj(value)) { 106 return; 107 } 108 109 const breakpointValue = getBreakpointValue(value); 110 111 if (Number.isFinite(breakpointValue)) { 112 swiper.params[key] = breakpointValue; 113 return; 114 } 115 116 if (isUnitValue(value) && !isResponsiveValue(value)) { 117 swiper.params[key] = value.number; 118 } 119 } 120 121 function isResponsiveValue(value) { 122 const { breakpoints } = window.BreakdanceFrontend.data; 123 const ids = breakpoints.map((bp) => bp.id); 124 return Object.keys(value).some((key) => ids.includes(key)); 125 } 126 127 function isUnitValue(value) { 128 return is.obj(value) && "number" in value; 129 } 130 131 function supportBreakpoints(swiper, settings) { 132 setBreakpoint(swiper, settings); 133 swiper.on("resize", () => { 134 setBreakpoint(swiper, settings); 135 }); 136 } 137 138 function syncSliders(sliderA, sliderB, syncMode = "thumbs") { 139 if (!sliderA || !sliderB) return; 140 141 if (syncMode === "controller") { 142 if (!sliderA.controller || !sliderB.controller) return; 143 sliderA.controller.control = sliderB; 144 sliderB.controller.control = sliderA;
145 sliderA.update(); 146 sliderB.update(); 147 return; 148 } 149 150 if (!sliderA.thumbs) return; 151 152 sliderB.params.freeMode = { enabled: true }; 153 sliderB.params.watchSlidesProgress = true; 154 sliderB.params.loop = false; 155 sliderB.params.slideToClickedSlide = true; 156 sliderB.update(); 157 158 sliderA.thumbs.swiper = sliderB; 159 sliderA.thumbs.init(); 160 sliderA.thumbs.update(true); 161 sliderA.update(); 162 } 163 164 function initSliderSync(sliderSelector, advancedSettings) { 165 const sliderA = document.querySelector(sliderSelector); 166 const sliderB = advancedSettings.sync_with_another_slider ? document.querySelector(`.${advancedSettings.slider_to_sync} .swiper`) : null; 167 const syncMode = advancedSettings.sync_mode; 168 169 if (!sliderB) return; 170 171 if (sliderB.swiper) { 172 syncSliders(sliderA.swiper, sliderB.swiper, syncMode); 173 } else { 174 sliderB.addEventListener("breakdance_swiper_init", () => { 175 syncSliders(sliderA.swiper, sliderB.swiper, syncMode); 176 }); 177 } 178 } 179 180 /** 181 * Animations support 182 */ 183 184 function resetSlideAnimations(slide) { 185 const customEvent = new Event("breakdance_reset_animations", { bubbles: true }); 186 slide.dispatchEvent(customEvent); 187 } 188 189 function playSlideAnimations(slide, delay) { 190 const customEvent = new CustomEvent("breakdance_play_animations", { 191 bubbles: true, 192 detail: { delay: delay / 1000 } 193 }); 194 slide.dispatchEvent(customEvent); 195 } 196 197 function supportEntranceAnimations(swiper, settings) { 198 let lastVisibleSlides = swiper.visibleSlides || []; 199 const playOn = settings.advanced.play_animations_on || "transition_end"; 200 201 const getNewestSlides = () => swiper.visibleSlides?.filter((slide) => !lastVisibleSlides.includes(slide)) || []; 202 const getHiddenSlides = () => swiper.slides?.filter((slide) => !swiper.visibleSlides.includes(slide)) || []; 203 204 swiper.on("sliderFirstMove", () => { 205 getHiddenSlides().forEach(resetSlideAnimations); 206 }); 207 208 swiper.on("slideChange", () => { 209 const delay = playOn === "transition_start" ? 0 : swiper.params.speed * 0.3; 210 const newSlides = getNewestSlides(); 211 212 newSlides.forEach((slide) => { 213 resetSlideAnimations(slide); 214 playSlideAnimations(slide, delay); 215 }); 216 217 lastVisibleSlides = swiper.visibleSlides; 218 }); 219 } 220 221 /** 222 * Instance management 223 */ 224 225 function destroy(id) { 226 if ( 227 window.swiperInstances && 228 window.swiperInstances[id] && 229 typeof window.swiperInstances[id].el === "object" 230 ) { 231 window.swiperInstances[id].destroy(true, true); 232 delete window.swiperInstances[id]; 233 } 234 } 235 236 function update({ id, selector, settings, paginationSettings, extras }) { 237 const swiperSelector = `${selector} > .breakdance-swiper-wrapper > .swiper`; 238 239 if (!isElementInDom(swiperSelector)) { 240 return; 241 } 242 243 destroy(id); 244 245 const mergedSettings = mergeObjects(DEFAULT_SWIPER_OPTIONS.settings, settings); 246 const mergedPagination = mergeObjects(DEFAULT_SWIPER_OPTIONS.pagination, paginationSettings); 247 const mergedExtras = extras || {}; 248 249 const isBuilderMode = Boolean(window?.BreakdanceFrontend.utils.isBuilder()); 250 const forceAutoplay = mergedExtras.autoplay === true; 251 252 const swiperInstance = new Swiper(swiperSelector, { 253 ...mergedExtras, 254 ...buildBaseConfig(mergedSettings, isBuilderMode), 255 ...buildAutoplayConfig(mergedSettings, isBuilderMode, forceAutoplay), 256 ...buildPaginationConfig(selector, mergedPagination), 257 ...buildNavigationConfig(selector), 258 ...buildEffectConfig(mergedSettings), 259 ...buildBuilderOverrides(isBuilderMode), 260 mousewheel: buildMouseWheelConfig(mergedSettings.advanced), 261 initialSlide: mergedSettings.advanced.initial_slide, 262 on: { 263 init: (event) => { 264 const customEvent = new Event("breakdance_swiper_init"); 265 event.el.dispatchEvent(customEvent); 266 } 267 } 268 }); 269
270 supportBreakpoints(swiperInstance, mergedSettings); 271 supportEntranceAnimations(swiperInstance, mergedSettings); 272 initSliderSync(swiperSelector, mergedSettings.advanced); 273 274 window.swiperInstances = { 275 ...window.swiperInstances, 276 [id]: swiperInstance 277 }; 278 } 279 280 /** 281 * Config builders 282 */ 283 284 function buildBaseConfig(settings, isBuilderMode) { 285 const { advanced, speed, infinite, direction, center_slides } = settings; 286 const isCoverflow = settings.effect === "coverflow"; 287 288 return { 289 speed: speed.number, 290 loop: infinite === "enabled" && !isBuilderMode, 291 keyboard: !advanced.disable_keyboard_control, 292 autoHeight: Boolean(advanced.auto_height), 293 loopPreventsSlide: false, 294 centeredSlides: isCoverflow ? true : center_slides, 295 watchSlidesProgress: advanced.slides_per_view !== 1, 296 parallax: true, 297 effect: settings.effect, 298 direction, 299 a11y: { 300 slideRole: "" 301 } 302 }; 303 } 304 305 function buildAutoplayConfig(settings, isBuilderMode, forceAutoplay) { 306 if (prefersReducedMotion()) return { autoplay: false }; 307 308 const autoplayEnabled = 309 settings.autoplay === "enabled" && (!isBuilderMode || forceAutoplay); 310 311 if (!autoplayEnabled) { 312 return { autoplay: false }; 313 } 314 315 const { autoplay_settings, infinite } = settings; 316 317 return { 318 autoplay: { 319 delay: autoplay_settings.speed.number, 320 pauseOnMouseEnter: Boolean(autoplay_settings.pause_on_hover), 321 disableOnInteraction: Boolean(autoplay_settings.stop_on_interaction), 322 stopOnLastSlide: infinite !== "enabled" 323 } 324 }; 325 } 326 327 function buildPaginationConfig(rootSelector, paginationSettings) { 328 return { 329 pagination: { 330 el: `${rootSelector} > .breakdance-swiper-wrapper > .swiper-pagination`, 331 type: paginationSettings.type, 332 clickable: true 333 } 334 }; 335 } 336 337 function buildNavigationConfig(rootSelector) { 338 return { 339 navigation: { 340 nextEl: `${rootSelector} > .breakdance-swiper-wrapper > .swiper-button-next`, 341 prevEl: `${rootSelector} > .breakdance-swiper-wrapper > .swiper-button-prev` 342 } 343 }; 344 } 345 346 function buildEffectConfig(settings) { 347 const configs = {}; 348 349 if (settings.effect === "coverflow") { 350 configs.coverflowEffect = { 351 rotate: settings.coverflow.rotate.number, 352 slideShadows: Boolean(settings.coverflow.shadow), 353 depth: settings.coverflow.depth.number, 354 stretch: settings.coverflow.stretch.number 355 }; 356 } 357 358 if (settings.effect === "fade") { 359 configs.fadeEffect = { crossFade: true }; 360 } 361 362 return configs; 363 } 364 365 function buildBuilderOverrides(isBuilderMode) { 366 if (!isBuilderMode) { 367 return {}; 368 } 369 370 return { 371 preventClicksPropagation: false, 372 preventClicks: false, 373 simulateTouch: false, 374 allowTouchMove: false 375 }; 376 } 377 378 function buildMouseWheelConfig(advancedSettings) { 379 if (!advancedSettings.swipe_on_scroll) { 380 return false; 381 } 382 383 return { 384 releaseOnEdges: true 385 }; 386 } 387 388 /** 389 * Builder utils 390 */ 391 392 function updateSliderFromChild(id) { 393 const sliderId = document 394 // select itself 395 .querySelector(`[data-node-id="${id}"]`) 396 // get parent (slider) node id 397 .parentElement.closest("[data-node-id]").dataset.nodeId; 398 399 const sliderIdNumber = sliderId && parseInt(sliderId); 400 401 if (window.swiperInstances && window.swiperInstances[sliderIdNumber]) { 402 window.swiperInstances[sliderIdNumber].update(); 403 } 404 } 405 406 function selectSlide(id) { 407 const slideElement = document 408 .querySelector(`[data-node-id="${id}"]`) 409 .closest(".swiper-slide"); 410 411 if (slideElement) { 412 const slideIndex = Array.from( 413 slideElement.parentElement.children 414 ).indexOf(slideElement); 415 416 const sliderElement = 417 slideElement.parentElement && 418 slideElement.parentElement.closest("[data-node-id]"); 419 420 const sliderId = sliderElement ? sliderElement.dataset.nodeId : null; 421 422 if ( 423 sliderId && 424 slideIndex !== null && 425 window.swiperInstances && 426 window.swiperInstances[sliderId] 427 ) { 428 if (window.swiperInstances[sliderId].visibleSlides.includes(slideElement)) { 429 return; 430 } 431 432 window.swiperInstances[sliderId].slideTo(slideIndex, 0); 433 } 434 } 435 } 436 437 return { 438 update, 439 destroy, 440 updateSliderFromChild, 441 selectSlide 442 }; 443 } 444 445 window.BreakdanceSwiper = BreakdanceSwiper; 446})();
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.