PageSourceSearch

https://visitrunavik.fo/views/main/js/Spliders.js?v=1790869110

js visitrunavik.fo collected 2026-10-02 22:54:57 UTC 9,880 bytes, 333 lines download raw bytes

1function Spliders(index, sliderType) {
2  let spliders = document.querySelectorAll(".queryAllSplide");
3  let primarySlider;
4  let secondarySlider;
5
6  spliders.forEach((e) => {
7    if (!sliderType) {
8      if (e.classList.contains(`splide-default-carousel`)) {
9        let slider = new Splide("#" + e.getAttribute("id"), {
10          rewind: true,
11          drag: true,
12          video: {
13            mute: true,
14            autoplay: true,
15            loop: true,
16            disableOverlayUI: true,
17            hideControls: true,
18            arrows: false,
19          },
20        });
21        slider.on("mounted", function (e) {
22          if (slider.length <= 1) {
23            slider.Components.Pagination.data.list.style = "display: none";
24            slider.Components.Arrows.arrows.prev.style = "display: none";
25            slider.Components.Arrows.arrows.next.style = "display: none";
26          }
27        });
28        slider.mount(window.splide.Extensions);
29      }
30      if (e.classList.contains("splide-slider-carousel")) {
31        let slider = new Splide("#" + e.getAttribute("id"), {
32          rewind: true,
33          drag: true,
34          gap: 0,
35
36          video: {
37            mute: true,
38            autoplay: true,
39            loop: true,
40            disableOverlayUI: true,
41            hideControls: true,
42            arrows: false,
43          },
44
45          breakpoints: {
46            1580: {
47              padding: {
48                left: "70px",
49                right: "70px",
50              },
51            },
52            1279: {
53              padding: {
54                left: "60px",
55                right: "60px",
56              },
57            },
58            660: {
59              padding: {
60                left: "25px",
61                right: "25px",
62              },
63            },
64          },
65        });
66
67        slider.on("click", function (e) {
68          slider.go(e.index);
69        });
70
71        slider.on("mounted", function (e) {
72          if (slider.length <= 1) {
73            slider.Components.Arrows.arrows.prev.style = "display: none";
74            slider.Components.Arrows.arrows.next.style = "display: none";
75            slider.root.style = "padding-top: 0px";
76          }
77        });
78
79        slider.mount(window.splide.Extensions);
80      }
81
82      if (e.classList.contains("splide-thumb-carousel")) {
83        if (e.classList.contains("splide-thumb-thumbs")) {
84          secondarySlider = new Splide("#" + e.getAttribute("id"), {
85            rewind: true,
86            fixedWidth: 150,
87            fixedHeight: 75,
88            isNavigation: true,
89            gap: 20,
90            focus: "center",
91            pagination: false,
92            cover: true,
93            arrows: true,
94            breakpoints: {
95              660: {
96                perPage: 2,
97                gap: 5,
98                padding: {
99                  left: 0,
100                  right: "6rem",
101                },
102              },
103            },
104          });
105
106          secondarySlider.on("mounted", function (e) {
107            if (secondarySlider.length <= 1) {
108              secondarySlider.root.style = "display: none";
109            }
110          });
111          secondarySlider.mount();
112        }
113        if (e.classList.contains("splide-thumb-main")) {
114          primarySlider = new Splide("#" + e.getAttribute("id"), {
115            rewind: true,
116            type: "fade",
117            pagination: false,
118            arrows: false,
119            cover: true,
120
121            video: {
122              mute: true,
123              autoplay: true,
124              loop: true,
125              disableOverlayUI: true,
126              hideControls: true,
127              arrows: false,
128            },
129          });
130        }
131        // Set the thumbnails slider as a sync target and then call mount.
132        primarySlider.sync(secondarySlider).mount(window.splide.Extensions);
133      }
134    }
135  });
136
137  let heroSpliders = document.querySelectorAll(".queryAllHeroSplide");
138  let main;
139  let thumbnails;
140  showIcons = true;
141
142  heroSpliders.forEach((e) => {
143    if (!sliderType) {
144      if (e.classList.contains("default-hero-type")) {
145        if (e.classList.contains(`slider-hero`)) {
146          var mainSplideID = "#" + e.getAttribute("id");
147
148          main = new Splide(mainSplideID, {
149            // rewind: true,
150            // type: 'fade',
151            // width: '100%',
152            // height: '1200px',
153            // pagination: false,
154            // arrows: false,
155            // cover: true,
156
157            // rewind: true,
158            // type: 'loop',
159            // pagination: false,
160            // arrows: false
161
162            type: "fade",
163            pagination: false,
164            arrows: true,
165            cover: true,
166            rewind: true,
167          });
168        }
169
170        if (e.classList.contains(`thumbnails-hero`)) {
171          var thumbnailsSplideID = "#" + e.getAttribute("id");
172
173          thumbnails = new Splide(thumbnailsSplideID, {
174            fixedWidth: 70,
175            fixedHeight: 70,
176            isNavigation: true,
177            focus: "center",
178            pagination: false,
179            arrows: false,
180            cover: true,
181            dragMinThreshold: {
182              mouse: 4,
183              touch: 10,
184            },
185          });
186          thumbnails.mount();
187        }
188
189        main.sync(thumbnails);
190        main.mount();
191      }
192    }
193  });
194}
195
196// Splide sizes the slides from the track width when it mounts. <body> is still
197// display: none on DOMContentLoaded (initApp() in tourism_main.js shows it in a
198// later listener), so the sliders measured a 0 px track: every slide kept its
199// content width, a hero photo its own aspect ratio, until Splide's window "load"
200// handler laid it out again. Showing the body first changes nothing on screen,
201// no frame is painted between two listeners.
202document.addEventListener("DOMContentLoaded", () => {
203  document.body.style.display = "unset";
204  Spliders();
205});
206
207// The tourism image lightbox (main/templates/partials/fullSizeImages.html).
208// window.openFullSizeImages is not it: that one feeds the What's On lightbox,
209// see utils/imageOverlay.js.
210function openTourismFullSizeImages(imageRef) {
211  // Only an image that opens the lightbox gets an imageRef (Page.php
212  // getLightboxGroup()); videos and the page's top image call this without one.
213  if (!Number.isInteger(imageRef)) return;
214
215  const imagesContainer = document.querySelector(".fullSizeImages");
216  const slide = imagesContainer.querySelector(
217    `.splide-expand-main .splide__slide[data-image-ref="${imageRef}"]`
218  );
219  // A page cached before the lightbox had groups has no data-image-ref.
220  if (!slide) return;
221
222  const mainContent = document.querySelector("html");
223  const foot = document.querySelector("footer");
224
225  imagesContainer.style.display = "grid";
226  mainContent.style.overflow = "hidden";
227  if (foot) foot.style.display = "none";
228  mountFullSizeImageSliders(slide);
229}
230
231// One pair of sliders per lightbox group, keyed by its .image-wrapper. Mounted
232// on the group's first open and reused after that: mounting on every open
233// stacked a new pair of sliders, and their click handlers, on the same slides.
234const fullSizeImageSliders = new Map();
235
236function mountFullSizeImageSliders(slide) {
237  const imagesContainer = document.querySelector(".fullSizeImages");
238  const imgIndex = imagesContainer.querySelector(".image-index");
239  const group = slide.closest(".image-wrapper");
240  const index = Array.prototype.indexOf.call(slide.parentElement.children, slide);
241
242  // Shown before mount or refresh, which measure the sliders.
243  imagesContainer.querySelectorAll(".image-wrapper").forEach((wrapper) => {
244    wrapper.hidden = wrapper !== group;
245  });
246
247  const mounted = fullSizeImageSliders.get(group);
248
249  if (mounted) {
250    // The sliders were measured while the lightbox was visible; it has been
251    // display: none since it was closed.
252    mounted.thumbnails.refresh();
253    mounted.main.refresh();
254    mounted.main.go(index);
255    imagesContainer.querySelector(".total-num-image").textContent = mounted.main.length;
256    imgIndex.textContent = index + 1;
257    return;
258  }
259
260  // Both sliders start at the image: sync only follows moves made after mount.
261  const thumbnails = new Splide(
262    group.querySelector(".splide-expand-thumbs"),
263    {
264      start: index,
265      rewind: true,
266      fixedWidth: 150,
267      fixedHeight: 75,
268      isNavigation: true,
269      gap: 20,
270      focus: "center",
271      pagination: false,
272      cover: true,
273      breakpoints: {
274        660: {
275          perPage: 2,
276          gap: 5,
277          padding: {
278            left: 0,
279            right: "6rem",
280          },
281        },
282      },
283    }
284  );
285
286  thumbnails.on("mounted", function () {
287    if (thumbnails.length <= 1) {
288      thumbnails.root.style = "display: none";
289    }
290  });
291  thumbnails.mount();
292
293  const main = new Splide(
294    group.querySelector(".splide-expand-main"),
295    {
296      start: index,
297      rewind: true,
298      type: "fade",
299      width: "100%",
300      height: "80vh",
301      pagination: false,
302      arrows: true,
303      cover: true,
304
305      video: {
306        mute: true,
307        autoplay: true,
308        loop: true,
309        disableOverlayUI: true,
310        hideControls: true,
311        arrows: false,
312      },
313      breakpoints: {
314        1279: {
315          height: "70vh",
316        },
317      },
318    }
319  );
320
321  main.on("move", function (newIndex) {
322    // Splide's arrow keys listen on the whole document, so the sliders of a
323    // hidden group move too; the counter belongs to the group on screen.
324    if (!group.hidden) imgIndex.textContent = newIndex + 1;
325  });
326  // Set the thumbnails slider as a sync target and then call mount.
327  main.sync(thumbnails).mount(window.splide.Extensions);
328
329  imagesContainer.querySelector(".total-num-image").textContent = main.length;
330  imgIndex.textContent = main.index + 1;
331
332  fullSizeImageSliders.set(group, { main, thumbnails });
333}

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.