Current Path :
/
home
/
develito
/
.trash
/
v6
/
media
/
mod_menu
/
js
/
Or
Select Your Path :
Upload File :
New :
File
Dir
/home/develito/.trash/v6/media/mod_menu/js/menu.js
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } /** * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ (() => { /** * Navigation menu * * Example usage: * // Default behavior (uses menuHoverClass = 'show-menu', dir = 'ltr') * new Nav(document.querySelector('.nav')); * * // Override defaults (e.g. custom open-class and RTL support) * new Nav(document.querySelector('.nav'), { * menuHoverClass: 'my-open-class', * dir: 'rtl' * }); * * @param {HTMLElement} nav The root <ul class="nav"> element * @param {Object} [settings] Optional overrides for defaultSettings * @param {string} [settings.menuHoverClass='show-menu'] CSS class to toggle on open submenus * @param {string} [settings.dir='ltr'] Text direction for keyboard nav ('ltr'|'rtl') */ class Nav { constructor(nav, settings = {}) { var _settings$dir, _this$nav$id, _this$nav; this.nav = nav; // read the HTML dir attribute or computed style, or fall back to defaultSettings.dir const browserDir = document.documentElement.getAttribute('dir') || // <html dir="…"> getComputedStyle(document.documentElement).direction || // CSS direction Nav.defaultSettings.dir; this.settings = _extends({}, Nav.defaultSettings, settings); // merge defaults, browser‐detected dir, and any explicit overrides in `settings` this.settings = _extends({}, Nav.defaultSettings, { dir: (_settings$dir = settings.dir) != null ? _settings$dir : browserDir }, settings); // Unique prefix for this nav instance - needed for the id of submenus and aria-controls this.idPrefix = (_this$nav$id = (_this$nav = this.nav) == null ? void 0 : _this$nav.id) != null ? _this$nav$id : `nav-${Math.floor(Math.random() * 100000)}`; this.topLevelNodes = this.nav.querySelectorAll(':scope > li'); this.topLevelNodes.forEach(topLevelEl => { // get submenu ul elements within topLevelEl const levelChildUls = topLevelEl.querySelectorAll('ul'); const ariaControls = []; levelChildUls.forEach(childUl => { childUl.setAttribute('aria-hidden', 'true'); childUl.classList.remove(this.settings.menuHoverClass); childUl.id = `${this.idPrefix}-submenu${Nav.idCounter}`; Nav.idCounter += 1; ariaControls.push(childUl.id); }); if (levelChildUls.length > 0) { const togglebtn = topLevelEl.querySelector('[aria-expanded]'); togglebtn == null || togglebtn.setAttribute('aria-controls', ariaControls.join(' ')); } }); nav.addEventListener('keydown', this.onMenuKeyDown.bind(this)); nav.addEventListener('click', this.onClick.bind(this)); if (this.nav.classList.contains(this.settings.preventSubmenuOpenOnload)) { this.toggleAllForCurrentActive(); } } onMenuKeyDown(event) { const target = event.target.closest('li'); if (!target) { return; } const subLists = target.querySelectorAll('ul'); switch (event.key) { case 'ArrowUp': event.preventDefault(); this.tabPrev(); break; case 'ArrowLeft': event.preventDefault(); if (this.settings.dir === 'rtl') { this.tabNext(); } else { this.tabPrev(); } break; case 'ArrowDown': event.preventDefault(); this.tabNext(); break; case 'ArrowRight': event.preventDefault(); if (this.settings.dir === 'rtl') { this.tabPrev(); } else { this.tabNext(); } break; case 'Enter': if (event.target.nodeName === 'SPAN' && event.target.parentNode.nodeName !== 'A' && subLists.length > 0) { var _subLists$; event.preventDefault(); this.toggleSubMenu(target, subLists, ((_subLists$ = subLists[0]) == null ? void 0 : _subLists$.getAttribute('aria-hidden')) === 'true'); } break; case ' ': case 'Spacebar': if (subLists.length > 0) { var _subLists$2; event.preventDefault(); this.toggleSubMenu(target, subLists, ((_subLists$2 = subLists[0]) == null ? void 0 : _subLists$2.getAttribute('aria-hidden')) === 'true'); } break; case 'Escape': { event.preventDefault(); const currentTopLevelLi = this.getTopLevelParentLi(event.target); if (!currentTopLevelLi) { break; } const allChildListsFromTopLevelLi = currentTopLevelLi.querySelectorAll('ul'); if (allChildListsFromTopLevelLi.length > 0) { this.toggleSubMenu(currentTopLevelLi, allChildListsFromTopLevelLi, false); } // set focus on the top level li child with tabindex currentTopLevelLi.querySelectorAll(':scope > [tabindex]:not([tabindex="-1"]), a, button').forEach(tabElement => { if (tabElement.hasAttribute(['aria-expanded'])) { tabElement.focus(); } }); break; } case 'End': { var _target$closest; event.preventDefault(); const currentLiList = (_target$closest = target.closest('ul')) == null ? void 0 : _target$closest.querySelectorAll(':scope > li'); for (let index = currentLiList.length - 1; index >= 0; index -= 1) { const lastTabbable = currentLiList[index].querySelector(':scope > [tabindex]:not([tabindex="-1"]), a, button'); if (lastTabbable) { lastTabbable.focus(); return; } } break; } case 'Home': { var _target$closest2; event.preventDefault(); const firstLi = (_target$closest2 = target.closest('ul')) == null ? void 0 : _target$closest2.querySelector(':scope > li:first-child'); if (firstLi) { var _firstLi$querySelecto; // set focus on first li child with tabindex within current list (_firstLi$querySelecto = firstLi.querySelector(':scope > [tabindex]:not([tabindex="-1"]), a, button')) == null || _firstLi$querySelecto.focus(); } break; } } } onClick(event) { var _event$target, _event$target2, _event$target3, _event$target4; if (!((_event$target = event.target) != null && _event$target.hasAttribute('aria-expanded')) && !((_event$target2 = event.target) != null && _event$target2.closest('[aria-expanded'))) { return; } if (((_event$target3 = event.target) == null ? void 0 : _event$target3.nodeName) === 'A') { return; } if (((_event$target4 = event.target) == null ? void 0 : _event$target4.nodeName) === 'SPAN' && event.target.parentNode.nodeName === 'A') { return; } const target = event.target.closest('li'); const subLists = target == null ? void 0 : target.querySelectorAll('ul'); if (subLists && subLists.length > 0) { var _subLists$3; event.preventDefault(); this.toggleSubMenu(target, subLists, ((_subLists$3 = subLists[0]) == null ? void 0 : _subLists$3.getAttribute('aria-hidden')) === 'true'); } } toggleSubMenu(target, subLists, open = false) { var _target$querySelector; if (open) { // close all opened submenus before opening the new one const allSubMenus = this.nav.querySelectorAll('ul[aria-hidden="false"]'); allSubMenus.forEach(ulChild => { var _this$getTopLevelPare; ulChild.setAttribute('aria-hidden', 'true'); ulChild.classList.remove(this.settings.menuHoverClass); (_this$getTopLevelPare = this.getTopLevelParentLi(ulChild)) == null || (_this$getTopLevelPare = _this$getTopLevelPare.querySelector(':scope > [aria-expanded]')) == null || _this$getTopLevelPare.setAttribute('aria-expanded', 'false'); }); } subLists.forEach(ulChild => { ulChild.setAttribute('aria-hidden', open ? 'false' : 'true'); ulChild.classList.toggle(this.settings.menuHoverClass, open); }); (_target$querySelector = target.querySelector(':scope > [aria-expanded]')) == null || _target$querySelector.setAttribute('aria-expanded', open ? 'true' : 'false'); } focusTabbable(direction = 1) { const tabbables = Array.from(this.nav.querySelectorAll('[tabindex]:not([tabindex="-1"]), a, button')).filter(el => !el.disabled && el.tabIndex >= 0 && el.offsetParent !== null); const currentIndex = tabbables.indexOf(document.activeElement); if (tabbables.length === 0) return; const nextIndex = (currentIndex + direction + tabbables.length) % tabbables.length; tabbables[nextIndex].focus(); } tabNext() { this.focusTabbable(1); } tabPrev() { this.focusTabbable(-1); } getTopLevelParentLi(element) { let currentLi = element.closest('li'); // this.topLevelNodes is a NodeList of top-level li elements in this nav while (currentLi && !Array.from(this.topLevelNodes).includes(currentLi)) { const parentUl = currentLi.parentElement.closest('ul'); currentLi = parentUl ? parentUl.closest('li') : null; } return currentLi; // top-level li or null if not found, or the } toggleAllForCurrentActive() { const active = this.nav.querySelector('.current.active'); if (active) { this.getTopLevelParentLi(active); let currentLi = active; while (currentLi && !Array.from(this.topLevelNodes).includes(currentLi)) { const parentUl = currentLi.parentElement.closest('ul'); currentLi = parentUl ? parentUl.closest('li') : null; if (currentLi) { var _subLists$4; const subLists = currentLi.querySelectorAll('ul'); this.toggleSubMenu(currentLi, subLists, ((_subLists$4 = subLists[0]) == null ? void 0 : _subLists$4.getAttribute('aria-hidden')) === 'true'); } } } } } // static idCounter for unique id generation of submenus // Default settings for the Nav class Nav.defaultSettings = { menuHoverClass: 'show-menu', dir: 'ltr', preventSubmenuOpenOnload: 'nav-active-open' }; Nav.idCounter = 0; // Initialize Nav instances for all nav elements on the page document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.nav').forEach(nav => new Nav(nav)); }); })();