PageSourceSearch

https://www.lilyneige.com/themes/classic/assets/js/ln-nav.js?v=n7

js lilyneige.com collected 2026-10-09 21:31:45 UTC 7,398 bytes, 212 lines download raw bytes

1(function () {
2  var searchHome = null;
3  var mq = window.matchMedia("(min-width: 768px)");
4
5  function isDesktop() {
6    return mq.matches;
7  }
8
9  function getSearchWidget() {
10    var el = document.getElementById("search_widget") || document.getElementById("_desktop_search");
11    if (!el) return null;
12    if (el.id === "_mobile_search") return null;
13    return el;
14  }
15
16  function rememberHome(search) {
17    if (!search || searchHome) return;
18    var parent = search.parentNode;
19    if (!parent) return;
20    if (parent.id === "ln-topbar-search") return;
21    if (parent.classList && parent.classList.contains("ln-topbar__search")) return;
22    if (parent.closest && parent.closest("#ln-topbar-search")) return;
23    searchHome = parent;
24  }
25
26  function layoutTopbar() {
27    var lang = document.getElementById("_desktop_language_selector");
28    var slot = document.getElementById("ln-topbar-lang");
29    if (lang && slot && lang.parentNode !== slot) {
30      slot.appendChild(lang);
31    }
32    var currency = document.getElementById("_desktop_currency_selector");
33    var right = document.querySelector("#header .header-nav .ln-topbar__right");
34    if (currency && right && !right.contains(currency)) {
35      var user = document.getElementById("_desktop_user_info");
36      if (user && right.contains(user)) {
37        right.insertBefore(currency, user);
38      } else {
39        right.appendChild(currency);
40      }
41    }
42
43    var searchSlot = document.getElementById("ln-topbar-search");
44    var search = getSearchWidget();
45    if (search && search.closest && search.closest("#_mobile_search") && !isDesktop()) {
46      document.documentElement.classList.remove("ln-search-in-topbar");
47      return finishLangOnly();
48    }
49    if (search) rememberHome(search);
50
51    var desktop = isDesktop();
52    var headerTopRight = document.querySelector("#header .header-top-right");
53
54    if (search && searchSlot && desktop) {
55      if (search.parentNode !== searchSlot) {
56        searchSlot.appendChild(search);
57      }
58      var input = search.querySelector('input[name="s"]');
59      if (input) {
60        var ph = input.getAttribute("placeholder") || "";
61        if (ph.length > 9 || ph.toLowerCase() === "rechercher") {
62          input.setAttribute("placeholder", "Recherche");
63        }
64      }
65      document.documentElement.classList.add("ln-search-in-topbar");
66    } else if (search && !desktop) {
67      document.documentElement.classList.remove("ln-search-in-topbar");
68      var dest = searchHome || headerTopRight;
69      if (dest && (dest.id === "ln-topbar-search" || (dest.closest && dest.closest("#ln-topbar-search")))) {
70        dest = headerTopRight;
71      }
72      if (dest && dest.id !== "_mobile_search" && search.parentNode !== dest) {
73        dest.appendChild(search);
74      }
75    }
76    return;
77
78    function finishLangOnly() {}
79  }
80
81  function restoreMain() {
82    ["notifications", "wrapper", "footer"].forEach(function (id) {
83      var el = document.getElementById(id);
84      if (!el) return;
85      if (el.style.display === "none") el.style.display = "";
86    });
87    var main = document.querySelector("main");
88    if (main && main.style.display === "none") main.style.display = "";
89  }
90
91  function syncMenuAria() {
92    var icon = document.getElementById("menu-icon");
93    var wrap = document.getElementById("mobile_top_menu_wrapper");
94    if (!icon || !wrap) return;
95    var open = window.getComputedStyle(wrap).display !== "none";
96    icon.setAttribute("aria-expanded", open ? "true" : "false");
97  }
98
99  function setMenuOpen(open) {
100    var wrap = document.getElementById("mobile_top_menu_wrapper");
101    if (!wrap) return;
102    wrap.classList.toggle("is-open", !!open);
103    if (!open) wrap.style.display = "none";
104    else wrap.style.display = "block";
105    syncMenuAria();
106  }
107
108  function bindHamburger() {
109    var icon = document.getElementById("menu-icon");
110    if (!icon) return;
111    icon.setAttribute("role", "button");
112    icon.setAttribute("tabindex", "0");
113    if (!icon.getAttribute("aria-label")) icon.setAttribute("aria-label", "Menu");
114    icon.setAttribute("aria-controls", "mobile_top_menu_wrapper");
115    icon.addEventListener("keydown", function (e) {
116      if (e.key === "Enter" || e.key === " ") {
117        e.preventDefault();
118        icon.click();
119      }
120    });
121    icon.addEventListener("click", function () {
122      var wrap = document.getElementById("mobile_top_menu_wrapper");
123      var willOpen = wrap ? !wrap.classList.contains("is-open") : false;
124      setMenuOpen(willOpen);
125      setTimeout(function () {
126        restoreMain();
127        syncMenuAria();
128      }, 0);
129    });
130  }
131
132  function bindMobileDrops() {
133    document.addEventListener("click", function (e) {
134      if (isDesktop()) return;
135      var barLi = e.target.closest("#mobile_top_menu_wrapper .ln-nav__bar > li, #_mobile_top_menu .ln-nav__bar > li");
136      if (!barLi) return;
137      var drop = barLi.querySelector(":scope > .ln-nav__drop, :scope > ul");
138      if (!drop) return;
139      var link = e.target.closest("a");
140      if (link && link.parentNode === barLi && !barLi.classList.contains("is-open")) {
141        e.preventDefault();
142        var siblings = barLi.parentNode.children;
143        for (var i = 0; i < siblings.length; i++) {
144          if (siblings[i] !== barLi && siblings[i].classList) siblings[i].classList.remove("is-open");
145        }
146        barLi.classList.add("is-open");
147      }
148    });
149  }
150
151  function boot() {
152    layoutTopbar();
153    setMenuOpen(false);
154    bindHamburger();
155    bindMobileDrops();
156    restoreMain();
157    syncMenuAria();
158    syncHeaderCompact();
159  }
160
161  if (document.readyState === "loading") {
162    document.addEventListener("DOMContentLoaded", boot);
163  } else {
164    boot();
165  }
166
167  /* Compact sticky: hide topbar+logo while scrolled; keep 2 menu lines */
168  var COMPACT_ON = 100;
169  var COMPACT_OFF = 40;
170  var compactRaf = 0;
171  function syncHeaderCompact() {
172    var header = document.getElementById("header");
173    if (!header) return;
174    var y = window.scrollY || window.pageYOffset || 0;
175    var on = header.classList.contains("ln-header-compact");
176    if (!on && y >= COMPACT_ON) {
177      header.classList.add("ln-header-compact");
178      document.documentElement.classList.add("ln-header-compact");
179    } else if (on && y <= COMPACT_OFF) {
180      header.classList.remove("ln-header-compact");
181      document.documentElement.classList.remove("ln-header-compact");
182    }
183  }
184  function onScrollCompact() {
185    if (compactRaf) return;
186    compactRaf = window.requestAnimationFrame(function () {
187      compactRaf = 0;
188      syncHeaderCompact();
189    });
190  }
191  window.addEventListener("scroll", onScrollCompact, { passive: true });
192  syncHeaderCompact();
193
194  window.addEventListener("resize", layoutTopbar);
195  if (mq.addEventListener) mq.addEventListener("change", layoutTopbar);
196  else if (mq.addListener) mq.addListener(layoutTopbar);
197
198  var items = document.querySelectorAll("#header .ln-nav__bar > li");
199  items.forEach(function (li) {
200    var drop = li.querySelector(":scope > .ln-nav__drop, :scope > ul");
201    if (!drop) return;
202    li.addEventListener("mouseenter", function () {
203      if (!isDesktop()) return;
204      items.forEach(function (other) { other.classList.remove("is-open"); });
205      li.classList.add("is-open");
206    });
207    li.addEventListener("mouseleave", function () {
208      if (!isDesktop()) return;
209      li.classList.remove("is-open");
210    });
211  });
212})();

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.