// @ts-check
///
///
{
const $ = typeof jQuery !== "undefined" ? jQuery : null;
/** @type {typeof import('swiper').default} */
// @ts-ignore
const Swiper = window.Swiper;
/** @type {Record boolean, convert: (value: string) => any, items: string[] }>} */ const swiperOptionsTypes = {
boolean: {
test: value => value === "true" || value === "false",
convert: value => value !== "false",
items: [ "centeredSlides", "pagination-clickable", "observer", "observeParents", "freeMode", "watchSlidesVisibility", "watchSlidesProgress", "loop", "centeredSlidesBounds", "autoplay-disableOnInteraction", "autoHeight", "fraction-zeros", "cssMode", "fadeEffect-crossFade", "mousewheel", "allowTouchMove", "grabCursor", "freeModeMomentum", "parallax", "pauseOnMouseEnter", "reverseDirection", "watchOverflow" ]
},
number: {
test: value => !isNaN(parseFloat(value)),
convert: value => parseFloat(value),
items: [ "spaceBetween", "autoplay-delay", "initialSlide", "slidesPerView", "speed", "touchRatio" ]
},
string: {
test: () => true,
convert: value => value,
items: []
},
function: {
test: value => {
try {
new Function(`(${value})(...arguments)`);
return true;
} catch (err) {
return false;
}
},
convert: value => new Function(`(${value})(...arguments)`),
items: [ "on-activeIndexChange", "on-afterInit", "on-beforeDestroy", "on-beforeInit", "on-beforeLoopFix", "on-beforeResize", "on-beforeSlideChangeStart", "on-beforeTransitionStart", "on-breakpoint", "on-changeDirection", "on-click", "on-destroy", "on-doubleClick", "on-doubleTap", "on-fromEdge", "on-init", "on-lock", "on-loopFix", "on-momentumBounce", "on-observerUpdate", "on-orientationchange", "on-progress", "on-reachBeginning", "on-reachEnd", "on-realIndexChange", "on-resize", "on-setTransition", "on-setTranslate", "on-slideChange", "on-slideChangeTransitionEnd", "on-slideChangeTransitionStart", "on-slideNextTransitionEnd", "on-slideNextTransitionStart", "on-slidePrevTransitionEnd", "on-slidePrevTransitionStart", "on-slideResetTransitionEnd", "on-slideResetTransitionStart", "on-sliderFirstMove", "on-sliderMove", "on-slidesGridLengthChange", "on-slidesLengthChange", "on-snapGridLengthChange", "on-snapIndexChange", "on-tap", "on-toEdge", "on-touchEnd", "on-touchMove", "on-touchMoveOpposite", "on-touchStart", "on-transitionEnd", "on-transitionStart", "on-unlock", "on-update" ]
}
};
/** @type {Record} */ const aliases = {
items: "slidesPerView",
sets: "slidesPerGroup",
center: "centeredSlides",
"center-bounds": "centeredSlidesBounds",
gap: "spaceBetween",
next: "navigation-nextEl",
prev: "navigation-prevEl",
"disable-class": "navigation-disabledClass",
active: "initialSlide",
connect: "thumbs-connect",
offset: "slidesOffsetAfter",
dots: "pagination-el",
"dots-type": "pagination-type",
"dots-click": "pagination-clickable",
"auto-height": "autoHeight",
autoplay: "autoplay-delay",
"autoplay-int": "autoplay-disableOnInteraction",
"pause-mouse": "pauseOnMouseEnter",
fade: "fadeEffect-crossFade",
free: "freeMode",
reverse: "reverseDirection",
"free-momentum": "freeModeMomentum",
"grab-cursor": "grabCursor",
"parallax-enabled": "parallax"
};
const defaultOptions = `\n gap: 48;\n next: .swiper-next;\n prev: .swiper-prev;\n disable-class: uk-opacity-40;\n dots: .swiper-dotnav;\n dots-click: true;\n fraction-zeros: true;\n observer: true;\n observeParents: true;\n watchSlidesVisibility: true;\n watchSlidesProgress: true;\n `
/**
* Parse data-uc-swiper options
*
* @param {string} attr - attribute value
* @param {HTMLElement} el - element that has data-uc-swiper
* @param {boolean} useDefaults - use default options
*/;
const parseOptions = (attr, el, useDefaults = false) => {
const options = {};
((useDefaults ? defaultOptions + ";" : "") + attr).split(/(? item.trim()).map(item => item.split(":").map(w => w.trim())).forEach(([key, value]) => {
value = value.replace(/\\;/g, ";");
if (aliases[key]) {
key = aliases[key];
}
changeType: {
for (const type in swiperOptionsTypes) {
if (swiperOptionsTypes[type].items.includes(key)) {
if (!swiperOptionsTypes[type].test || swiperOptionsTypes[type].test(value)) {
value = swiperOptionsTypes[type].convert(value);
break changeType;
}
}
}
// START_DEV_ONLY
if (typeof value === "string") {
if (/^(true|false)$/.test(value)) {
console.warn("swiper option", key, value, "maybe be boolean.");
}
if (/^(\d+(\.\d+)?)$/.test(value)) {
console.warn("swiper option", key, value, "maybe be number.");
}
}
// END_DEV_ONLY
}
const parts = key.split("-");
/** @type {any} */ let opts = options;
parts.forEach((part, i) => {
if (i < parts.length - 1) {
opts[part] = opts[part] || {};
opts = opts[part];
} else {
opts[part] = value;
}
});
});
{
let parent = el.closest(options.parent || ".swiper-parent");
if (!parent) parent = el;
if (options.navigation && typeof options.navigation === "object") {
if (options.navigation.nextEl && typeof options.navigation.nextEl === "string") {
// @ts-ignore
options.navigation.nextEl = [ ...parent.querySelectorAll(options.navigation.nextEl) ];
}
if (options.navigation.prevEl && typeof options.navigation.prevEl === "string") {
// @ts-ignore
options.navigation.prevEl = [ ...parent.querySelectorAll(options.navigation.prevEl) ];
}
}
if (options.pagination && typeof options.pagination === "object") {
if (options.pagination.el && typeof options.pagination.el === "string") {
// @ts-ignore
options.pagination.el = [ ...parent.querySelectorAll(options.pagination.el) ];
}
}
if (options.thumbs) {
if (options.thumbs.connect && typeof options.thumbs.connect === "string") {
options.thumbs.connect = [ ...parent.querySelectorAll(options.thumbs.connect) ];
}
}
if (options.progress) {
if (options.progress.bar && typeof options.progress.bar === "string") {
options.progress.bar = [ ...parent.querySelectorAll(options.progress.bar) ];
}
}
delete options.parent;
}
if (options.progress && options.progress.bar) {
// @ts-ignore
const bar = $(/** @type {string} */ options.progress.bar);
delete options.progress;
options.on = {
init() {
bar.removeClass("animate");
bar.removeClass("active");
bar.eq(0).addClass("animate");
bar.eq(0).addClass("active");
},
slideChangeTransitionStart() {
bar.removeClass("animate");
bar.removeClass("active");
bar.eq(0).addClass("active");
},
slideChangeTransitionEnd() {
bar.eq(0).addClass("animate");
}
};
}
if (options.fraction && options.fraction.zeros && options.pagination) {
const fractionPadding = 2;
const fractionFill = "0";
delete options.fraction;
Object.assign(options.pagination, {
/** @param {number} number */
formatFractionCurrent(number) {
return String(number).padStart(fractionPadding, fractionFill);
},
/** @param {number} number */
formatFractionTotal(number) {
return String(number).padStart(fractionPadding, fractionFill);
}
});
}
return options;
};
/** @type {Record} */ const breakpoints = {
xs: 480,
s: 640,
m: 960,
l: 1200,
xl: 1600
};
const initSwiper = (div, optionsAttr = "data-uc-swiper") => {
// @ts-ignore
/** @type {import('swiper').SwiperOptions & { thumbs?: { connect?: (HTMLElement & { swiper?: import('swiper').Swiper })[] } }} */
let options = {};
try {
// @ts-ignore
options = parseOptions(div.getAttribute(optionsAttr), div, true);
for (const bp in breakpoints) {
const attr = div.getAttribute("data-uc-swiper-" + bp);
if (attr) {
options.breakpoints = options.breakpoints || {};
const bpSize = breakpoints[bp];
options.breakpoints[bpSize] = parseOptions(attr, div);
}
}
} catch (err) {
console.warn(err);
}
if (!options.on) options.on = {};
options.on.init = function(swiper) {
// @ts-ignore
$(swiper.el).addClass("swiper-initialized");
};
const ready = () => {
const swiper = new Swiper(div, options);
swiper.update();
document.addEventListener("DOMContentLoaded", () => swiper.update(), {
once: true
});
window.addEventListener("load", () => swiper.update(), {
once: true
});
};
if (options.thumbs && options.thumbs.connect) {
const connect = options.thumbs.connect;
delete options.thumbs.connect;
setTimeout(() => {
const el = connect[0];
if (!el || !options.thumbs) {
console.warn(`thumbs connect with selector "${connect}" not exist!`);
return;
}
options.thumbs.swiper = el.swiper;
if (options.thumbs.swiper) {
ready();
} else {
console.warn(`thumbs connect with selector "${connect}" not setup!`);
}
});
} else {
ready();
}
};
const runDataAttr = el => {
initSwiper(el, "data-uc-swiper");
};
document.addEventListener("DOMContentLoaded", () => {
// Run all.
dataAttrHelpers.watchDataAttr("data-uc-swiper", runDataAttr);
});
Object.assign(window, {
initSwiper: initSwiper
});
}