PageSourceSearch

https://svitla.com/wp-content/themes/dvwbwp/assets/js/header.js?ver=e8c9be4

js svitla.com collected 2026-09-24 19:42:26 UTC 18,712 bytes, 557 lines download raw bytes

1/******/ (() => { // webpackBootstrap
2/******/ 	var __webpack_modules__ = ({
3
4/***/ 2637:
5/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6
7"use strict";
8/* harmony export */ __webpack_require__.d(__webpack_exports__, {
9/* harmony export */   nF: () => (/* binding */ throttle),
10/* harmony export */   t3: () => (/* binding */ checkMediaQuery)
11/* harmony export */ });
12/* unused harmony exports debounce, generateElements, outerWidth, next, prev, uuid */
13const throttle = (func, ms) => {
14  let isThrottled = false;
15  let savedArgs;
16  let savedThis;
17
18  function wrapper() {
19    if (isThrottled) {
20      savedArgs = arguments;
21      savedThis = this;
22      return;
23    }
24
25    func.apply(this, arguments);
26
27    isThrottled = true;
28
29    setTimeout(function () {
30      isThrottled = false;
31      if (savedArgs) {
32        wrapper.apply(savedThis, savedArgs);
33        savedArgs = savedThis = null;
34      }
35    }, ms);
36  }
37
38  return wrapper;
39};
40
41const debounce = (func, ms = 500) => {
42  let timeout;
43  return function () {
44    const fnCall = () => {
45      func.apply(this, arguments);
46    };
47    if (timeout) clearTimeout(timeout);
48    timeout = setTimeout(fnCall, ms);
49  };
50};
51
52const checkMediaQuery = (mw = 1024, isMin) => {
53  const query = isMin ? `(min-width: ${mw}px)` : `(max-width: ${mw}px)`;
54  return window.matchMedia(query);
55};
56
57const generateElements = (html) => {
58  const template = document.createElement('template');
59  template.innerHTML = html.trim();
60  return template.content.children;
61};
62
63const outerWidth = (el) => {
64  if (!el) return 0;
65  const style = getComputedStyle(el);
66  return el.getBoundingClientRect().width + parseFloat(style.marginLeft) + parseFloat(style.marginRight);
67};
68
69const next = (el, selector) => {
70  const nextEl = el.nextElementSibling;
71  if (!selector || (nextEl && nextEl.matches(selector))) {
72    return nextEl;
73  }
74  return null;
75};
76
77const prev = (el, selector) => {
78  const prevEl = el.previousElementSibling;
79  if (!selector || (prevEl && prevEl.matches(selector))) {
80    return prevEl;
81  }
82  return null;
83};
84
85const uuid = () => {
86  var d = new Date().getTime();
87  var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
88    var r = (d + Math.random() * 16) % 16 | 0;
89    d = Math.floor(d / 16);
90    return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
91  });
92  return uuid;
93};
94
95
96/***/ }),
97
98/***/ 2459:
99/***/ (() => {
100
101(function () {
102  const UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
103  const INIT_DELAY = 1000;
104  const COOKIE_NAME = 'dvwbwp_utm';
105  const COOKIE_DAYS = 30;
106
107  function storeUtmCookie() {
108    let params;
109    try {
110      params = new URL(window.location.href).searchParams;
111    } catch (e) {
112      return;
113    }
114
115    const data = {};
116    UTM_KEYS.forEach((key) => {
117      const value = params.get(key);
118      if (value) data[key] = value.slice(0, 255);
119    });
120
121    if (Object.keys(data).length === 0) return;
122
123    const expires = new Date(Date.now() + COOKIE_DAYS * 864e5).toUTCString();
124    document.cookie =
125      COOKIE_NAME +
126      '=' +
127      encodeURIComponent(JSON.stringify(data)) +
128      '; expires=' + expires +
129      '; path=/; SameSite=Lax' +
130      (window.location.protocol === 'https:' ? '; Secure' : '');
131  }
132
133  storeUtmCookie();
134
135  function init() {
136    const pageUrl = new URL(window.location.href);
137
138    function updateLink(link) {
139      if (!link || !link.href) return;
140
141      const rawHref = link.getAttribute('href');
142      if (!rawHref) return;
143
144      if (
145        rawHref.startsWith('#') ||
146        rawHref.startsWith('mailto:') ||
147        rawHref.startsWith('tel:') ||
148        rawHref.startsWith('javascript:')
149      ) {
150        return;
151      }
152
153      let url;
154      try {
155        url = new URL(link.href, window.location.origin);
156      } catch (e) {
157        return;
158      }
159
160      if (url.origin !== window.location.origin) return;
161
162      let updated = false;
163
164      UTM_KEYS.forEach((key) => {
165        const pageValue = pageUrl.searchParams.get(key);
166
167        if (pageValue && !url.searchParams.has(key)) {
168          url.searchParams.set(key, pageValue);
169          updated = true;
170        }
171      });
172
173      if (updated) {
174        link.href = url.toString();
175      }
176    }
177
178    function updateLinks(root) {
179      if (!root) return;
180
181      if (root.nodeType === 1 && root.matches && root.matches('a[href]')) {
182        updateLink(root);
183      }
184
185      if (root.querySelectorAll) {
186        root.querySelectorAll('a[href]').forEach(updateLink);
187      }
188    }
189
190    updateLinks(document);
191
192    const observer = new MutationObserver((mutations) => {
193      mutations.forEach((mutation) => {
194        mutation.addedNodes.forEach((node) => {
195          if (node.nodeType === 1) {
196            updateLinks(node);
197          }
198        });
199      });
200    });
201
202    observer.observe(document.body, {
203      childList: true,
204      subtree: true,
205    });
206  }
207
208  if (document.readyState === 'complete') {
209    setTimeout(init, INIT_DELAY);
210  } else {
211    window.addEventListener('load', function () {
212      setTimeout(init, INIT_DELAY);
213    });
214  }
215})();
216
217
218/***/ })
219
220/******/ 	});
221/************************************************************************/
222/******/ 	// The module cache
223/******/ 	var __webpack_module_cache__ = {};
224/******/ 	
225/******/ 	// The require function
226/******/ 	function __webpack_require__(moduleId) {
227/******/ 		// Check if module is in cache
228/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
229/******/ 		if (cachedModule !== undefined) {
230/******/ 			return cachedModule.exports;
231/******/ 		}
232/******/ 		// Create a new module (and put it into the cache)
233/******/ 		var module = __webpack_module_cache__[moduleId] = {
234/******/ 			// no module.id needed
235/******/ 			// no module.loaded needed
236/******/ 			exports: {}
237/******/ 		};
238/******/ 	
239/******/ 		// Execute the module function
240/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
241/******/ 	
242/******/ 		// Return the exports of the module
243/******/ 		return module.exports;
244/******/ 	}
245/******/ 	
246/************************************************************************/
247/******/ 	/* webpack/runtime/compat get default export */
248/******/ 	(() => {
249/******/ 		// getDefaultExport function for compatibility with non-harmony modules
250/******/ 		__webpack_require__.n = (module) => {
251/******/ 			var getter = module && module.__esModule ?
252/******/ 				() => (module['default']) :
253/******/ 				() => (module);
254/******/ 			__webpack_require__.d(getter, { a: getter });
255/******/ 			return getter;
256/******/ 		};
257/******/ 	})();
258/******/ 	
259/******/ 	/* webpack/runtime/define property getters */
260/******/ 	(() => {
261/******/ 		// define getter functions for harmony exports
262/******/ 		__webpack_require__.d = (exports, definition) => {
263/******/ 			for(var key in definition) {
264/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
265/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
266/******/ 				}
267/******/ 			}
268/******/ 		};
269/******/ 	})();
270/******/ 	
271/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
272/******/ 	(() => {
273/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
274/******/ 	})();
275/******/ 	
276/************************************************************************/
277var __webpack_exports__ = {};
278// This entry need to be wrapped in an IIFE because it need to be in strict mode.
279(() => {
280"use strict";
281/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2637);
282/* harmony import */ var _scripts_utm_fix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2459);
283/* harmony import */ var _scripts_utm_fix__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_scripts_utm_fix__WEBPACK_IMPORTED_MODULE_0__);
284/** Header + navigation */
285
286
287
288
289
290const classNameHide = 'header--hidden';
291const classNameLight = 'header--is-light';
292const classNameHeaderMobile = 'header--is-mobile';
293const classNameActive = 'nav-is-active';
294const classNameRotate = 'header--cont-rotate';
295const classActiveLinkCollapse = 'header--start-collapse-active-nav-link';
296const classNameHover = 'hover-active-js';
297const classListItemOpen = 'main-menu-list__item--open-js';
298const classNameMobMenuToggleClose = 'header__menu-button--close';
299const classNameBodyMobileMenu = 'mobile-navigation';
300const classNameBodyPersprctive = 'page__body--perspective';
301const threshold = 5;
302const heightLimit = 100;
303
304/** handle header styles on scroll */
305(() => {
306  let prevScrollPos = window.scrollY ?? window.pageYOffSet;
307  let headerMouseleaveTimeout;
308  const header = document.getElementById('header');
309
310  window.addEventListener('scroll', (0,_utils__WEBPACK_IMPORTED_MODULE_1__/* .throttle */ .nF)((e) => {
311    const currentScrollPos = window.scrollY ?? window.pageYOffSet;
312    if (Math.abs(prevScrollPos - currentScrollPos) <= threshold) return;
313
314    if (currentScrollPos <= threshold) {
315      header.classList.remove(classNameLight);
316      removeListItemsHover();
317    }
318    if (
319      currentScrollPos > prevScrollPos &&
320      currentScrollPos > heightLimit &&
321      !header.classList.contains(classNameActive)
322    ) {
323      header.classList.add(classNameHide);
324      setTimeout(() => {
325        header.classList.add(classNameLight);
326      }, 500);
327    } else if (currentScrollPos + window.innerHeight < document.body.scrollHeight) {
328      header.classList.remove(classNameHide);
329    }
330    prevScrollPos = currentScrollPos;
331
332    closeTOCMobileNavigation();
333  }, 100)); // onscroll
334
335  /** avoid to hide navigation on scrolled page reloading + apply header light styles */
336  const onload = () => {
337    const isMobileNavMQL = (0,_utils__WEBPACK_IMPORTED_MODULE_1__/* .checkMediaQuery */ .t3)(1024);
338
339    const header = document.getElementById('header');
340    header.classList.remove(classNameActive, classNameRotate);
341    setTimeout(() => {
342      header.classList.remove(classActiveLinkCollapse);
343    }, 250);
344    const scrollPos = window.scrollY ?? window.pageYOffSet;
345    if (scrollPos > heightLimit) {
346      header.classList.add(classNameLight);
347    }
348
349    document.getElementById('header').addEventListener('mouseleave', (event) => {
350      const scrollPos = window.scrollY ?? window.pageYOffSet;
351      if (scrollPos < heightLimit) {
352        headerMouseleaveTimeout = setTimeout(() => {
353          header.classList.remove(classNameLight);
354        }, 350);
355      }
356    });
357
358    document.querySelector('#header nav.main-navigation').addEventListener('mouseleave', (event) => {
359      if (event.relatedTarget && event.relatedTarget.closest && event.relatedTarget.closest('.mega-menu-panel')) return;
360      setTimeout(() => {
361        removeListItemsHover();
362      }, 250);
363    });
364
365    document.querySelectorAll('.mega-menu-panel').forEach((panel) => {
366      panel.addEventListener('mouseenter', () => {
367        headerMouseleaveTimeout && clearTimeout(headerMouseleaveTimeout);
368        const header = document.getElementById('header');
369        if (!header.classList.contains(classNameLight)) header.classList.add(classNameLight);
370      });
371      panel.addEventListener('mouseleave', (event) => {
372        if (!event.relatedTarget || !event.relatedTarget.closest || !event.relatedTarget.closest('#header')) {
373          removeListItemsHover();
374          const scrollPos = window.scrollY ?? window.pageYOffSet;
375          if (scrollPos < heightLimit) {
376            headerMouseleaveTimeout = setTimeout(() => {
377              header.classList.remove(classNameLight);
378            }, 350);
379          }
380        }
381      });
382    });
383
384    document.addEventListener('click', (e) => {
385      if (!document.getElementById('header').contains(e.target)) {
386        removeListItemsHover();
387      }
388    });
389
390    const mobileMenuToggle = document.getElementById('mobileMenuToggle');
391    const mainSection = document.querySelector('.main-container');
392    mobileMenuToggle.addEventListener('click', (e) => {
393      if(!mobileMenuToggle.classList.contains(classNameMobMenuToggleClose)) {
394        document.body.classList.add(classNameBodyPersprctive);
395      } else {
396        mainSection.ontransitionend = () => {
397          if(!mobileMenuToggle.classList.contains(classNameMobMenuToggleClose)) {
398            document.body.classList.remove(classNameBodyPersprctive);
399          }
400        };
401      }
402      mobileMenuToggle.classList.toggle(classNameMobMenuToggleClose);
403      document.body.classList.toggle(classNameBodyMobileMenu);
404    });
405
406    /** check if mobile navigation processing required */
407    function handleDeviceChange(e) {
408      header.classList.add('no-transition');
409      setTimeout(() => {
410        header.classList.remove('no-transition');
411      }, 500);
412      mobileMenuMod(e.matches);
413      if (e.matches) {
414        /** mobile nav **/
415        header.classList.add(classNameHeaderMobile);
416        detachMenuHoverJs();
417        attachMobileMenuExpanding();
418      } else {
419        /** desktop nav **/
420        document.body.classList.remove(classNameBodyMobileMenu);
421        mobileMenuToggle.classList.remove(classNameMobMenuToggleClose);
422        header.classList.remove(classNameHeaderMobile);
423        attachMenuHoverJs();
424        detachMobileMenuExpanding();
425      }
426    }
427    isMobileNavMQL.addEventListener('change', handleDeviceChange);
428    handleDeviceChange(isMobileNavMQL);
429  }; // onload
430
431  window.addEventListener('load', onload);
432
433  function removeListItemsHover() {
434    document.querySelectorAll('#header nav.main-navigation ul.header__menu-list li').forEach((el) => {
435      el.classList.remove(classNameHover);
436    });
437  }
438
439  function closeTOCMobileNavigation() {
440    const isMobileNavMQL = (0,_utils__WEBPACK_IMPORTED_MODULE_1__/* .checkMediaQuery */ .t3)(1024);
441    if (isMobileNavMQL.matches) {
442      const tocMobileNavigation = document.querySelector('#tocMobileNavigation .menu-list-dropdown__header');
443      const tocMobileNavWrapper = document.getElementById('tocMobileNavigation');
444      if (tocMobileNavigation) tocMobileNavigation.removeAttribute('data-open');
445      if (tocMobileNavWrapper) tocMobileNavWrapper.removeAttribute('data-open');
446    }
447  }
448
449  function mobileMenuMod(isMob) {
450    if (isMob) {
451      document
452        .querySelectorAll('.header nav.main-navigation > ul.main-menu-list > li.main-menu-list__item ul:not(.modified):not(.mega-menu__sub-links)')
453        .forEach((ulEl) => {
454          const aEl = ulEl.closest('li.main-menu-list__item').querySelector('a');
455          if (aEl) {
456            const addLiEl = document.createElement('li');
457            addLiEl.classList.add('main-menu-list__item', 'cloned-menu-item');
458            addLiEl.appendChild(aEl.cloneNode(true));
459            ulEl.prepend(addLiEl);
460            ulEl.classList.add('modified');
461          }
462        });
463    } else {
464      // TODO: ?? could be useless to remove mod-added submenu list items. it should be better just to hide li.cloned-menu-item with CSS for non mobile-nav
465      document
466        .querySelectorAll(
467          '.header nav.main-navigation > ul.main-menu-list > li.main-menu-list__item ul.modified li.cloned-menu-item'
468        )
469        .forEach((el) => el.parentNode.removeChild(el));
470      document
471        .querySelectorAll('.header nav.main-navigation > ul.main-menu-list > li.main-menu-list__item ul.modified')
472        .forEach((el) => el.classList.remove('modified'));
473    }
474  }
475
476  function handleMouseEnterNavListItem(e) {
477    headerMouseleaveTimeout && clearTimeout(headerMouseleaveTimeout);
478    const header = document.getElementById('header');
479    removeListItemsHover();
480    if (!header.classList.contains(classNameLight)) header.classList.add(classNameLight);
481    e.target.classList.add(classNameHover);
482  }
483
484  function attachMenuHoverJs() {
485    document.querySelectorAll('#header nav.main-navigation ul.header__menu-list > li').forEach((el) => {
486      el.addEventListener('mouseenter', handleMouseEnterNavListItem, false);
487    });
488  }
489
490  function detachMenuHoverJs() {
491    document.querySelectorAll('#header nav.main-navigation ul.header__menu-list > li').forEach((el) => {
492      el.removeEventListener('mouseenter', handleMouseEnterNavListItem, false);
493    });
494  }
495
496  function handleMobileMenuExpandClick(event) {
497    const linkEl = event.currentTarget;
498    const rect = linkEl.getBoundingClientRect();
499    const clickX = event.clientX - rect.left;
500    const width = rect.width;
501
502    if (clickX > width * 0.85 || width - clickX < 44) {
503      event.preventDefault();
504      const listItem = event.target.closest('li.main-menu-list__item');
505      if (listItem) {
506        if (listItem.classList.contains(classListItemOpen)) {
507          listItem.querySelectorAll('.mega-menu__group--open-js').forEach((g) => g.classList.remove('mega-menu__group--open-js'));
508        }
509        listItem.classList.toggle(classListItemOpen);
510      }
511    }
512  }
513
514  function handleMobileGroupExpandClick(event) {
515    const linkEl = event.currentTarget;
516    const rect = linkEl.getBoundingClientRect();
517    const clickX = event.clientX - rect.left;
518    const width = rect.width;
519
520    if (clickX > width * 0.85 || width - clickX < 44) {
521      event.preventDefault();
522      const group = event.currentTarget.closest('.mega-menu__group');
523      if (group) group.classList.toggle('mega-menu__group--open-js');
524    }
525  }
526
527  function attachMobileMenuExpanding() {
528    document.querySelectorAll('#header nav.main-navigation > ul > li.has-dropdown > a').forEach((linkEl) => {
529      linkEl.addEventListener('click', handleMobileMenuExpandClick, false);
530    });
531    document.querySelectorAll('#header nav.main-navigation > ul > li:not(.has-dropdown):has(>ul) > a').forEach((linkEl) => {
532      linkEl.addEventListener('click', handleMobileMenuExpandClick, false);
533    });
534    document.querySelectorAll('#header .mega-menu-panel .mega-menu__group-title').forEach((titleEl) => {
535      titleEl.addEventListener('click', handleMobileGroupExpandClick, false);
536    });
537  }
538  function detachMobileMenuExpanding() {
539    document.querySelectorAll('#header nav.main-navigation > ul > li.has-dropdown > a').forEach((linkEl) => {
540      linkEl.removeEventListener('click', handleMobileMenuExpandClick, false);
541    });
542    document.querySelectorAll('#header nav.main-navigation > ul > li:not(.has-dropdown):has(>ul) > a').forEach((linkEl) => {
543      linkEl.removeEventListener('click', handleMobileMenuExpandClick, false);
544    });
545    document.querySelectorAll('#header .mega-menu-panel .mega-menu__group-title').forEach((titleEl) => {
546      titleEl.removeEventListener('click', handleMobileGroupExpandClick, false);
547    });
548  }
549})();
550
551/** Eof Header + navigation */
552
553})();
554
555/******/ })()
556;
557//# sourceMappingURL=header.js.map

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.