PageSourceSearch

https://sadv.co.za/wp-content/plugins/oxygen/subplugins/breakdance…/breakdance-swiper.js?bd_ver=6.1.3

js sadv.co.za collected 2026-10-01 15:54:27 UTC 13,043 bytes, 446 lines download raw bytes

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.