/* global Glide */
document.addEventListener('DOMContentLoaded', function () {
let classSuffix = 'carrousel-cs';
let selector = `.${classSuffix}`;
const carrousels = [...document.querySelectorAll(selector)];
let carrouselGlideType = "glide";
let carrouselGridType = "grid";
carrousels.forEach(carrousel => {
let elementMinimalWidth = carrousel.dataset.elementWidth;
let carrouselType = carrouselGlideType;
let elementChildNodes = [...carrousel.childNodes].filter(child => {
if (child.nodeType === Node.ELEMENT_NODE) {
return child;
}
});
let childrenCount = elementChildNodes.length;
let elementsMin = carrousel.dataset.elementsMin;
let isGallery = false; // more than one element is visible
if (elementMinimalWidth !== undefined) {
if (childrenCount < elementsMin) {
carrouselType = carrouselGridType;
}
} else {
isGallery = true;
}
carrousel.classList.add(`carrousel-${carrouselType}-cs`);
switch (carrouselType) {
case carrouselGridType:
// we can't set the height of the container to have same height component
// because this is a grid and in small mobile screen, the height would be double
carrousel.classList.add("row", "row-cols-1", `row-cols-sm-${elementsMin}`, "justify-content-center");
elementChildNodes.forEach(element => {
let gridColContainer = document.createElement("div");
gridColContainer.classList.add("col");
gridColContainer.appendChild(element);
carrousel.appendChild(gridColContainer);
});
break;
case carrouselGlideType:
/**
* Slides structure
*/
carrousel.classList.add("glide", "glide--ltr", "glide--carousel", "glide--swipeable");
let glideTrackContainer = document.createElement("div");
glideTrackContainer.classList.add("glide__track");
glideTrackContainer.dataset.glideEl = "track";
carrousel.appendChild(glideTrackContainer);
let glideSlidesContainer = document.createElement("div");
glideSlidesContainer.classList.add("glide__slides");
glideTrackContainer.appendChild(glideSlidesContainer);
elementChildNodes.forEach(element => {
glideSlidesContainer.appendChild(element);
element.classList.add("glide__slide");
if (element.localName === "a") {
// to center the image inside the link
element.classList.add("justify-content-center", "align-items-center", "d-flex");
}
});
/**
* Control structure
*/
let control = carrousel.dataset.control;
if (control !== "none") {
// move per view |< and |>
// https://github.com/glidejs/glide/issues/346#issuecomment-1046137773
let controlArrowContainer = document.createElement("div");
controlArrowContainer.dataset.glideEl = "controls";
if (!isGallery) {
controlArrowContainer.classList.add("d-none", "d-sm-block");
}
carrousel.insertAdjacentElement('beforeend', controlArrowContainer);
let controlArrows = `
`;
controlArrowContainer.insertAdjacentHTML('beforeend', controlArrows);
let controlBulletContainer = document.createElement("div");
carrousel.insertAdjacentElement('beforeend', controlBulletContainer);
controlBulletContainer.classList.add("glide__bullets", "d-none", "d-sm-block");
controlBulletContainer.dataset.glideEl = "controls[nav]";
for (let i = 0; i < childrenCount; i++) {
let controlBullet = document.createElement("button");
controlBullet.classList.add("glide__bullet");
controlBullet.dataset.glideDir = `=${i}`;
if (i === 0) {
controlBullet.classList.add("glide__bullet--activeClass");
}
controlBulletContainer.appendChild(controlBullet);
}
}
let callGlide = function () {
let perView = 1;
if (typeof elementMinimalWidth !== 'undefined') {
let offsetWidth = carrousel.offsetWidth;
perView = Math.floor(offsetWidth / elementMinimalWidth);
perView += 0.5; // mobile to show that there is further element on the right side
}
/**
* https://www.jsdelivr.com/package/npm/@glidejs/glide
* Dev:
* "https://cdn.jsdelivr.net/npm/@glidejs/glide@3.5.2/dist/glide.js",
* "sha256-zkYoJ1XwwGA4FbdmSdTz28y5PtHT8O/ZKzUAuQsmhKg="
*/
combos.loader.loadExternalScript(
"https://cdn.jsdelivr.net/npm/@glidejs/glide@3.5.2/dist/glide.min.js",
"sha256-cXguqBvlUaDoW4nGjs4YamNC2mlLGJUOl64bhts/ztU=",
`snippet-${classSuffix}`,
function(){
combos.loader.loadExternalStylesheet(
"https://cdn.jsdelivr.net/npm/@glidejs/glide@3.5.2/dist/css/glide.core.min.css",
"sha256-bmdlmBAVo1Q6XV2cHiyaBuBfe9KgYQhCrfQmoRq8+Sg=",
`snippet-${classSuffix}`,
function(){
let glide = new Glide(carrousel, {
type: 'carousel',
perView: perView
});
glide.mount();
/**
* To be able to set percentage height value on the child elements.
*/
glideSlidesContainer.style.height = `${glideSlidesContainer.offsetHeight}px`;
}
);
}
);
};
if(navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom")){
/**
* In test, in jsdom, no request animation frame
*/
callGlide()
} else {
/**
* To be sure that the first layout calculation has occurred
*/
window.requestAnimationFrame(callGlide);
}
break;
}
});
});