/* 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; } }); });