1/* global Glide */
2
3
4document.addEventListener('DOMContentLoaded', function () {
5
6    let classSuffix = 'carrousel-cs';
7    let selector = `.${classSuffix}`;
8    const carrousels = [...document.querySelectorAll(selector)];
9
10    let carrouselGlideType = "glide";
11    let carrouselGridType = "grid";
12
13    carrousels.forEach(carrousel => {
14
15        let elementMinimalWidth = carrousel.dataset.elementWidth;
16        let carrouselType = carrouselGlideType;
17        let elementChildNodes = [...carrousel.childNodes].filter(child => {
18            if (child.nodeType === Node.ELEMENT_NODE) {
19                return child;
20            }
21        });
22        let childrenCount = elementChildNodes.length;
23        let elementsMin = carrousel.dataset.elementsMin;
24        let isGallery = false; // more than one element is visible
25        if (elementMinimalWidth !== undefined) {
26            if (childrenCount < elementsMin) {
27                carrouselType = carrouselGridType;
28            }
29        } else {
30            isGallery = true;
31        }
32        carrousel.classList.add(`carrousel-${carrouselType}-cs`);
33        switch (carrouselType) {
34            case carrouselGridType:
35                // we can't set the height of the container to have same height component
36                // because this is a grid and in small mobile screen, the height would be double
37                carrousel.classList.add("row", "row-cols-1", `row-cols-sm-${elementsMin}`, "justify-content-center");
38                elementChildNodes.forEach(element => {
39                    let gridColContainer = document.createElement("div");
40                    gridColContainer.classList.add("col");
41                    gridColContainer.appendChild(element);
42                    carrousel.appendChild(gridColContainer);
43                });
44                break;
45            case carrouselGlideType:
46
47                /**
48                 * Slides structure
49                 */
50                carrousel.classList.add("glide", "glide--ltr", "glide--carousel", "glide--swipeable");
51                let glideTrackContainer = document.createElement("div");
52                glideTrackContainer.classList.add("glide__track");
53                glideTrackContainer.dataset.glideEl = "track";
54                carrousel.appendChild(glideTrackContainer);
55                let glideSlidesContainer = document.createElement("div");
56                glideSlidesContainer.classList.add("glide__slides");
57                glideTrackContainer.appendChild(glideSlidesContainer);
58                elementChildNodes.forEach(element => {
59                    glideSlidesContainer.appendChild(element);
60                    element.classList.add("glide__slide");
61                    if (element.localName === "a") {
62                        // to center the image inside the link
63                        element.classList.add("justify-content-center", "align-items-center", "d-flex");
64                    }
65                });
66
67                /**
68                 * Control structure
69                 */
70                let control = carrousel.dataset.control;
71                if (control !== "none") {
72                    // move per view |< and |>
73                    // https://github.com/glidejs/glide/issues/346#issuecomment-1046137773
74                    let controlArrowContainer = document.createElement("div");
75                    controlArrowContainer.dataset.glideEl = "controls";
76                    if (!isGallery) {
77                        controlArrowContainer.classList.add("d-none", "d-sm-block");
78                    }
79                    carrousel.insertAdjacentElement('beforeend', controlArrowContainer);
80                    let controlArrows = `
81<button class="glide__arrow glide__arrow--left" data-glide-dir="|<">
82    <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M0 12l10.975 11 2.848-2.828-6.176-6.176H24v-3.992H7.646l6.176-6.176L10.975 1 0 12z"></path></svg>
83</button>
84<button class="glide__arrow glide__arrow--right" data-glide-dir="|>">
85    <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M13.025 1l-2.847 2.828 6.176 6.176h-16.354v3.992h16.354l-6.176 6.176 2.847 2.828 10.975-11z"></path></svg>
86</button>
87`;
88                    controlArrowContainer.insertAdjacentHTML('beforeend', controlArrows);
89
90
91                    let controlBulletContainer = document.createElement("div");
92                    carrousel.insertAdjacentElement('beforeend', controlBulletContainer);
93                    controlBulletContainer.classList.add("glide__bullets", "d-none", "d-sm-block");
94                    controlBulletContainer.dataset.glideEl = "controls[nav]";
95                    for (let i = 0; i < childrenCount; i++) {
96                        let controlBullet = document.createElement("button");
97                        controlBullet.classList.add("glide__bullet");
98                        controlBullet.dataset.glideDir = `=${i}`;
99                        if (i === 0) {
100                            controlBullet.classList.add("glide__bullet--activeClass");
101                        }
102                        controlBulletContainer.appendChild(controlBullet);
103                    }
104                }
105
106
107                let callGlide = function () {
108
109                    let perView = 1;
110                    if (typeof elementMinimalWidth !== 'undefined') {
111                        let offsetWidth = carrousel.offsetWidth;
112                        perView = Math.floor(offsetWidth / elementMinimalWidth);
113                        perView += 0.5; // mobile to show that there is further element on the right side
114                    }
115
116                    /**
117                     * https://www.jsdelivr.com/package/npm/@glidejs/glide
118                     * Dev:
119                     * "https://cdn.jsdelivr.net/npm/@glidejs/glide@3.5.2/dist/glide.js",
120                     * "sha256-zkYoJ1XwwGA4FbdmSdTz28y5PtHT8O/ZKzUAuQsmhKg="
121                     */
122                    combos.loader.loadExternalScript(
123                        "https://cdn.jsdelivr.net/npm/@glidejs/glide@3.5.2/dist/glide.min.js",
124                        "sha256-cXguqBvlUaDoW4nGjs4YamNC2mlLGJUOl64bhts/ztU=",
125                        `snippet-${classSuffix}`,
126                        function(){
127                            combos.loader.loadExternalStylesheet(
128                                "https://cdn.jsdelivr.net/npm/@glidejs/glide@3.5.2/dist/css/glide.core.min.css",
129                                "sha256-bmdlmBAVo1Q6XV2cHiyaBuBfe9KgYQhCrfQmoRq8+Sg=",
130                                `snippet-${classSuffix}`,
131                                function(){
132
133                                    let glide = new Glide(carrousel, {
134                                        type: 'carousel',
135                                        perView: perView
136                                    });
137                                    glide.mount();
138
139                                    /**
140                                     * To be able to set percentage height value on the child elements.
141                                     */
142                                    glideSlidesContainer.style.height = `${glideSlidesContainer.offsetHeight}px`;
143
144                                }
145                            );
146
147                        }
148                    );
149
150                };
151
152                if(navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom")){
153                    /**
154                     * In test, in jsdom, no request animation frame
155                     */
156                    callGlide()
157                } else {
158                    /**
159                     * To be sure that the first layout calculation has occurred
160                     */
161                    window.requestAnimationFrame(callGlide);
162                }
163                break;
164        }
165
166    });
167
168});
169