PageSourceSearch

https://heg-fr.ch/styleguide/common.js

js heg-fr.ch collected 2026-10-02 11:58:30 UTC 10,661 bytes, 341 lines download raw bytes

1// This is the webpack entry point
2// import exec from 'polyfills.exec.js'
3// import smoothscroll from 'smoothscroll-polyfill'
4// Import the main Sass file
5// import 'scss/common.scss'
6// // icons
7// import 'icons/logo-icon.svg'
8// import 'icons/logo-slogan.svg'
9// import 'icons/logo-place.svg'
10// import 'icons/logo-hes-so.svg'
11// images
12// import 'images/brochures/brochure-heg-1.png'
13// import 'images/brochures/brochure-heg-4.png'
14// import 'images/portraits-white-bg/portrait-1.png'
15// import 'images/hero/young-lady-listening-broad.jpg'
16// import 'images/hero/people-talking.jpg'
17
18// import 'images/square/portrait1.jpg'
19// import 'images/square/portrait2.jpg'
20// import 'images/square/portrait3.jpg'
21// import 'images/square/portrait4.jpg'
22// import 'images/square/portrait5.jpg'
23// import 'images/square/portrait6.jpg'
24// import 'images/square/portrait7.jpg'
25// import 'images/square/portrait8.jpg'
26// import 'images/square/portrait9.jpg'
27// import 'images/square/portrait10.jpg'
28
29// import svg4everybody from 'svg4everybody'
30
31/**
32 * Find direct children to node, replicating .querySelector(':scope > [...]')
33 */
34function find(node, selector) {
35  var removeId = false;
36
37  if (node.getAttribute("id") === null) {
38    node.setAttribute("id", "ID_" + new Date().getTime());
39    removeId = true;
40  }
41
42  let result = document.querySelector(
43    "#" + node.getAttribute("id") + " > " + selector
44  );
45
46  if (removeId) node.removeAttribute("id");
47
48  return result;
49}
50
51/**
52 * Find direct children to node, replicating .querySelectorAll(':scope > [...]')
53 */
54function findAll(node, selector) {
55  var removeId = false;
56
57  if (node.getAttribute("id") === null) {
58    node.setAttribute("id", "ID_" + new Date().getTime());
59    removeId = true;
60  }
61
62  let result = document.querySelectorAll(
63    "#" + node.getAttribute("id") + " > " + selector
64  );
65
66  if (removeId) node.removeAttribute("id");
67
68  return result;
69}
70
71function setHeights(navy) {
72  var minHeight = 0;
73  var level0 = navy.querySelector(".navy__level-0");
74
75  navy.querySelectorAll("ul").forEach(function (level) {
76    var childrenHeight = 0;
77    findAll(level, "li > *:first-child").forEach(function (child) {
78      childrenHeight += child.offsetHeight;
79    });
80    minHeight = childrenHeight > minHeight ? childrenHeight : minHeight;
81  });
82
83  var navySpacing = window
84    .getComputedStyle(level0, null)
85    .getPropertyValue("padding-top");
86  minHeight += 50 + parseInt(navySpacing);
87
88  navy.setAttribute("style", "min-height:" + minHeight + "px;");
89}
90
91// TOGGLE MAIN MENU
92document.addEventListener("DOMContentLoaded", function (event) {
93  window.addEventListener("resize", function () {
94    document.querySelectorAll(".navy").forEach(function (navy) {
95      setHeights(navy);
96    });
97  });
98
99  // hit escape to close the search menu or the main menu
100  window.addEventListener("keydown", function (e) {
101    let keyCode = e.keyCode;
102    if (keyCode === 27) {
103      if (
104        document.querySelector("html").classList.contains("mainmenu--is-open")
105      )
106        toggleMainMenu();
107      else if (
108        document.querySelector("html").classList.contains("searchmenu--is-open")
109      )
110        toggleSearchMenu();
111    }
112  });
113
114  // remove focus on links without a href
115  var emptyLinks = document.querySelectorAll("#mainmenu a:not([href])");
116  [].forEach.call(emptyLinks, function (emptyLink) {
117    emptyLink.tabIndex = -1;
118  });
119
120  function closeMainMenu() {
121    document.querySelector("html").classList.remove("mainmenu--is-open");
122    document.querySelector("html").classList.remove("searchmenu--is-open");
123    document.querySelector("html").classList.remove("header--is-condensed");
124    document.querySelector("html").classList.remove("negative-scroll");
125  }
126
127  function toggleMainMenu() {
128    document.querySelector("html").classList.toggle("mainmenu--is-open");
129    document.querySelector("html").classList.remove("searchmenu--is-open");
130    document.querySelector("html").classList.remove("header--is-condensed");
131    document.querySelector("html").classList.remove("negative-scroll");
132  }
133
134  function toggleSearchMenu() {
135    document.querySelector("html").classList.toggle("searchmenu--is-open");
136    document.querySelector("html").classList.remove("mainmenu--is-open");
137    document.querySelector("html").classList.remove("header--is-condensed");
138    document.querySelector("html").classList.remove("negative-scroll");
139
140    // set the focus into the search field when opening
141    if (
142      document.querySelector("html").classList.contains("searchmenu--is-open")
143    ) {
144      document.querySelector("#searchmenu .field").focus();
145    }
146  }
147
148  document
149    .querySelector("#menu-burger")?.addEventListener("click", toggleMainMenu);
150  document
151    .querySelector("#menu-search")?.addEventListener("click", toggleSearchMenu);
152  document
153    .querySelector("#skip-navigation")?.addEventListener("click", closeMainMenu);
154});
155
156// NAVY
157document.addEventListener("DOMContentLoaded", function (event) {
158  var navys = document.querySelectorAll(".navy");
159  var currentMenuLink = undefined;
160
161  function showNextLevel(navigation) {
162    navigation.classList.remove("show-level-0");
163    navigation.classList.add("show-level-1");
164  }
165
166  function showPrevLevel(navigation) {
167    navigation.classList.remove("show-level-1");
168    navigation.classList.add("show-level-0");
169
170    // set focus on the `parent` link after the transition
171    // 600ms is the duration of the sliding animation (find it in _navy.scss)
172    setTimeout(function () {
173      currentMenuLink.focus();
174    }, 610);
175  }
176
177  function displaySubmenu(target, submenus1) {
178    [].forEach.call(submenus1, function (submenu) {
179      if (!submenu.classList.contains("language-switcher")) {
180        submenu.classList.add("hidden");
181      }
182    });
183    target.classList.remove("hidden");
184
185    // set focus on the `.back` button after the transition
186    // 600ms is the duration of the sliding animation (find it in _navy.scss)
187    setTimeout(function () {
188      target.querySelector(".navy__back").focus();
189    }, 610);
190  }
191
192  function initializeEvents(nextButtons, backButtons, navy, level1, submenus1) {
193    [].forEach.call(nextButtons, function (btn) {
194      btn.relatedMenu = btn.nextElementSibling;
195
196      level1.appendChild(btn.relatedMenu);
197
198      btn.addEventListener("click", function () {
199        showNextLevel(navy);
200        displaySubmenu(btn.relatedMenu, submenus1);
201        currentMenuLink = btn.querySelector("a");
202      });
203    });
204
205    [].forEach.call(backButtons, function (btn) {
206      btn.addEventListener("click", function () {
207        showPrevLevel(navy);
208      });
209    });
210  }
211
212  navys.forEach(function (navy) {
213    setHeights(navy);
214
215    var nextButtons = navy.querySelectorAll(".navy__has-children");
216    var backButtons = navy.querySelectorAll(".navy__back");
217
218    var level1 = navy.querySelector(".navy__level-1");
219    var submenus1 = findAll(navy, "ul > li > ul");
220
221    var level2 = navy.querySelector(".navy__level-2");
222    var submenus2 = findAll(navy, "ul > li > ul > li > ul");
223
224    initializeEvents(nextButtons, backButtons, navy, level1, submenus1);
225
226    //remove focus on arrows
227    var arrows = navy.querySelectorAll(".navy__next");
228    [].forEach.call(arrows, function (arrow) {
229      arrow.tabIndex = -1;
230    });
231  });
232});
233
234// kick off the polyfill for smooth scrolling between anchors:
235// allow CSS like 'scroll-behavior: smooth' (used in helpers/anchor.scss)
236// https://github.com/iamdustan/smoothscroll
237
238// smoothscroll.polyfill()
239// svg4everybody()
240
241// listen to the scroll position and compress the header after 100vh scroll:
242// expand the menu if negative scroll is detected
243// scroll optimization found here: https://www.html5rocks.com/en/tutorials/speed/animations/
244
245var lastScrollPos = 0;
246var newScrollPos = 0;
247var ticking = false;
248var windowHeight = window.screen.height;
249var html = document.querySelector("html");
250
251function toggleHeaderAfterScroll(pos) {
252  // compress header if scroll > 100vh:
253  if (pos > window.innerHeight / 2) {
254    html.classList.add("header--is-condensed");
255
256    // expand header if negative scroll:
257    if (newScrollPos < lastScrollPos) {
258      html.classList.add("negative-scroll");
259    } else {
260      html.classList.remove("negative-scroll");
261    }
262    lastScrollPos = newScrollPos;
263  } else {
264    html.classList.remove("header--is-condensed");
265    html.classList.remove("negative-scroll");
266  }
267}
268
269window.addEventListener("scroll", function (e) {
270  newScrollPos = window.scrollY;
271
272  if (!ticking) {
273    window.requestAnimationFrame(function () {
274      toggleHeaderAfterScroll(newScrollPos);
275      ticking = false;
276    });
277    ticking = true;
278  }
279});
280
281//
282// Align Breadcrumb to the right when it is bigger than the screen width + break the left padding
283//
284document.addEventListener("DOMContentLoaded", function () {
285  const breadcrumbList = document.getElementById("breadcrumb")?.firstElementChild;
286  if (!breadcrumbList) return;
287
288  function setSrollLeft() {
289    breadcrumbList.scrollLeft = breadcrumbList.scrollWidth;
290  }
291
292  setSrollLeft();
293
294  window.addEventListener("resize", function () {
295    setSrollLeft();
296  });
297});
298
299//
300//remove homepage hero loader (blue background)
301//
302function iframeLoaded() {
303  setTimeout(function() {
304    var loader = document.querySelector(".hero__homepage__loader");
305    loader.classList.add("is-transparent");
306  }, 1000);
307}
308
309//
310//horizontal scroll button
311//
312
313const horizontalSlider = (sectionId) => {
314  const section = document.querySelector(sectionId);
315  const slider = section.querySelector('.list-inline--overflow');
316  const scrollLeftButton = section.querySelector('.scroll-button--left');
317  const scrollRightButton = section.querySelector('.scroll-button--right');
318  const scrollAmount = slider.querySelector('.event-list__item').offsetWidth;
319  const spacingUnitDefault = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--spacing-unit-default'));
320
321  scrollLeftButton.addEventListener('click', function() {
322    slider.scrollLeft -= scrollAmount + spacingUnitDefault;
323  });
324
325  scrollRightButton.addEventListener('click', function() {
326    slider.scrollLeft += scrollAmount + spacingUnitDefault;
327  });
328
329  const checkScroll = () => {
330    scrollLeftButton.classList.toggle('scroll-button--none', slider.scrollLeft <= spacingUnitDefault);
331    scrollRightButton.classList.toggle('scroll-button--none', Math.abs(slider.scrollLeft + slider.offsetWidth - slider.scrollWidth) < spacingUnitDefault);
332  };
333
334  slider.addEventListener('scroll', checkScroll, { passive: true });
335  checkScroll();
336}
337
338document.addEventListener('DOMContentLoaded', (event) => {
339  horizontalSlider('section#events');
340  horizontalSlider('section#news');
341});

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.