Remove legacy initNavOverflow from enhancements.js (core/nav.js owns zibll navFolding). Harden clearFolding against detached more nodes and skip counting existing .aksrt-nav-more during fold measurement.
145 lines
4.6 KiB
JavaScript
145 lines
4.6 KiB
JavaScript
/**
|
|
* AKSRT nav chrome — zibll contract (folding, chevron, language, drawer a11y).
|
|
* Drawer open/close via aksrt-runtime [data-toggle-class] → body.mobile-navbar-show.
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
var foldTimer = null;
|
|
|
|
function appendChevrons(root) {
|
|
(root || document).querySelectorAll(".navbar-top li.menu-item-has-children > a").forEach(function (a) {
|
|
if (a.querySelector(".fa-angle-down, .fas.fa-angle-down")) return;
|
|
var i = document.createElement("i");
|
|
i.className = "fa fa-angle-down ml6";
|
|
i.setAttribute("aria-hidden", "true");
|
|
a.appendChild(i);
|
|
});
|
|
}
|
|
|
|
function clearFolding() {
|
|
// Support both zibll-style more and any legacy .aksrt-nav-more nodes.
|
|
var mores = document.querySelectorAll(".navbar-nav > li.aksrt-nav-more");
|
|
Array.prototype.forEach.call(mores, function (more) {
|
|
var nav = more.parentNode;
|
|
if (!nav) {
|
|
more.remove();
|
|
return;
|
|
}
|
|
// Prefer direct child .sub-menu (zibll contract); fall back to first matching submenu.
|
|
var sub = null;
|
|
for (var i = 0; i < more.children.length; i++) {
|
|
var child = more.children[i];
|
|
if (
|
|
child.tagName === "UL" &&
|
|
(child.classList.contains("sub-menu") ||
|
|
child.classList.contains("aksrt-nav-more__dropdown"))
|
|
) {
|
|
sub = child;
|
|
break;
|
|
}
|
|
}
|
|
if (!sub) {
|
|
sub = more.querySelector(".sub-menu, .aksrt-nav-more__dropdown");
|
|
}
|
|
if (sub) {
|
|
while (sub.firstChild) {
|
|
// Guard: only insertBefore when more is still a child of nav.
|
|
if (more.parentNode === nav) {
|
|
nav.insertBefore(sub.firstChild, more);
|
|
} else {
|
|
nav.appendChild(sub.firstChild);
|
|
}
|
|
}
|
|
}
|
|
more.remove();
|
|
});
|
|
}
|
|
|
|
function navFolding() {
|
|
var collapse = document.querySelector(".navbar-collapse");
|
|
var nav = document.querySelector(".navbar-nav");
|
|
if (!collapse || !nav) return;
|
|
|
|
clearFolding();
|
|
|
|
if (window.innerWidth <= 996) return;
|
|
var header = document.querySelector(".header");
|
|
if (header && header.offsetHeight <= 81) return;
|
|
|
|
var surplus = collapse.clientWidth;
|
|
Array.prototype.forEach.call(collapse.children, function (child) {
|
|
if (!child.classList.contains("navbar-nav")) {
|
|
surplus -= child.offsetWidth || 0;
|
|
}
|
|
});
|
|
var headerEl = document.querySelector(".navbar-header");
|
|
surplus -= (headerEl ? headerEl.offsetWidth : 0) + 40;
|
|
|
|
var navsWidth = 66;
|
|
var foldItems = [];
|
|
Array.prototype.forEach.call(nav.children, function (li) {
|
|
if (li.classList.contains("aksrt-nav-more")) return;
|
|
navsWidth += li.offsetWidth || 0;
|
|
if (navsWidth > surplus) foldItems.push(li);
|
|
});
|
|
if (!foldItems.length) return;
|
|
|
|
var more = document.createElement("li");
|
|
more.className = "menu-item menu-item-has-children aksrt-nav-more";
|
|
more.innerHTML =
|
|
'<a href="javascript:void(0);"><i class="fas fa-bars" aria-hidden="true"></i></a><ul class="sub-menu"></ul>';
|
|
var sub = more.querySelector(".sub-menu");
|
|
foldItems.forEach(function (li) {
|
|
if (li && li.parentNode) sub.appendChild(li);
|
|
});
|
|
nav.appendChild(more);
|
|
appendChevrons(more);
|
|
}
|
|
|
|
function scheduleFold() {
|
|
if (foldTimer) clearTimeout(foldTimer);
|
|
foldTimer = setTimeout(function () {
|
|
try { navFolding(); } catch (e) {}
|
|
}, 80);
|
|
}
|
|
|
|
function bindLanguage() {
|
|
document.addEventListener("click", function (e) {
|
|
var btn = e.target && e.target.closest ? e.target.closest(".translate-button[data-language]") : null;
|
|
if (!btn) return;
|
|
e.preventDefault();
|
|
var lang = btn.getAttribute("data-language");
|
|
if (!lang) return;
|
|
try { localStorage.setItem("aksrt_lang", lang); } catch (err) {}
|
|
var url = new URL(window.location.href);
|
|
url.searchParams.set("lang", lang);
|
|
window.location.href = url.toString();
|
|
});
|
|
}
|
|
|
|
function bindDrawerA11y() {
|
|
document.addEventListener("keydown", function (e) {
|
|
if (e.key === "Escape" && document.body.classList.contains("mobile-navbar-show")) {
|
|
document.body.classList.remove("mobile-navbar-show");
|
|
}
|
|
});
|
|
}
|
|
|
|
function init() {
|
|
appendChevrons();
|
|
scheduleFold();
|
|
bindLanguage();
|
|
bindDrawerA11y();
|
|
window.addEventListener("resize", scheduleFold, { passive: true });
|
|
}
|
|
|
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {
|
|
window.AksrtFrontend.register("aksrt-nav-chrome", function () { init(); });
|
|
} else if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", init);
|
|
} else {
|
|
init();
|
|
}
|
|
})();
|