PageSourceSearch

https://zadna.org.za/media/mod_menu/js/menu.js?70e259

js zadna.org.za collected 2026-09-24 18:32:54 UTC 4,573 bytes, 136 lines download raw bytes

1/**
2 * @copyright  (C) 2019 Open Source Matters, Inc. <https://www.joomla.org>
3 * @license    GNU General Public License version 2 or later; see LICENSE.txt
4 */
5
6(() => {
7
8  function topLevelMouseOver(el, settings) {
9    const ulChild = el.querySelector('ul');
10    if (ulChild) {
11      ulChild.setAttribute('aria-hidden', 'false');
12      ulChild.classList.add(settings.menuHoverClass);
13    }
14  }
15  function topLevelMouseOut(el, settings) {
16    const ulChild = el.querySelector('ul');
17    if (ulChild) {
18      ulChild.setAttribute('aria-hidden', 'true');
19      ulChild.classList.remove(settings.menuHoverClass);
20    }
21  }
22  function setupNavigation(nav) {
23    const settings = {
24      menuHoverClass: 'show-menu'};
25
26    // Set tabIndex to -1 so that top_level_childs can't receive focus until menu is open
27    nav.querySelectorAll(':scope > li').forEach(topLevelEl => {
28      const linkEl = topLevelEl.querySelector('a');
29      if (linkEl) {
30        linkEl.tabIndex = '0';
31        linkEl.addEventListener('mouseover', topLevelMouseOver(topLevelEl, settings));
32        linkEl.addEventListener('mouseout', topLevelMouseOut(topLevelEl, settings));
33      }
34      const spanEl = topLevelEl.querySelector('span');
35      if (spanEl) {
36        if (spanEl.parentNode.nodeName !== 'A') {
37          spanEl.tabIndex = '0';
38        }
39        spanEl.addEventListener('mouseover', topLevelMouseOver(topLevelEl, settings));
40        spanEl.addEventListener('mouseout', topLevelMouseOut(topLevelEl, settings));
41      }
42      topLevelEl.addEventListener('mouseover', ({
43        currentTarget
44      }) => {
45        const ulChild = currentTarget.querySelector('ul');
46        if (ulChild) {
47          ulChild.setAttribute('aria-hidden', 'false');
48          ulChild.classList.add(settings.menuHoverClass);
49        }
50      });
51      topLevelEl.addEventListener('mouseout', ({
52        currentTarget
53      }) => {
54        const ulChild = currentTarget.querySelector('ul');
55        if (ulChild) {
56          ulChild.setAttribute('aria-hidden', 'true');
57          ulChild.classList.remove(settings.menuHoverClass);
58        }
59      });
60      topLevelEl.addEventListener('focus', ({
61        currentTarget
62      }) => {
63        const ulChild = currentTarget.querySelector('ul');
64        if (ulChild) {
65          ulChild.setAttribute('aria-hidden', 'true');
66          ulChild.classList.add(settings.menuHoverClass);
67        }
68      });
69      topLevelEl.addEventListener('blur', ({
70        currentTarget
71      }) => {
72        const ulChild = currentTarget.querySelector('ul');
73        if (ulChild) {
74          ulChild.setAttribute('aria-hidden', 'false');
75          ulChild.classList.remove(settings.menuHoverClass);
76        }
77      });
78      topLevelEl.addEventListener('keydown', event => {
79        const keyName = event.key;
80        const curEl = event.target;
81        const curLiEl = curEl.parentElement;
82        const curUlEl = curLiEl.parentElement;
83        let prevLiEl = curLiEl.previousElementSibling;
84        let nextLiEl = curLiEl.nextElementSibling;
85        if (!prevLiEl) {
86          prevLiEl = curUlEl.children[curUlEl.children.length - 1];
87        }
88        if (!nextLiEl) {
89          [nextLiEl] = curUlEl.children;
90        }
91        switch (keyName) {
92          case 'ArrowLeft':
93            event.preventDefault();
94            {
95              prevLiEl.children[0].focus();
96            }
97            break;
98          case 'ArrowRight':
99            event.preventDefault();
100            {
101              nextLiEl.children[0].focus();
102            }
103            break;
104          case 'ArrowUp':
105            {
106              event.preventDefault();
107              const parent = curLiEl.parentElement.parentElement;
108              if (parent.nodeName === 'LI') {
109                parent.children[0].focus();
110              } else {
111                prevLiEl.children[0].focus();
112              }
113              break;
114            }
115          case 'ArrowDown':
116            event.preventDefault();
117            if (curLiEl.classList.contains('parent')) {
118              const child = curLiEl.querySelector('ul');
119              if (child != null) {
120                const childLi = child.querySelector('li');
121                childLi.children[0].focus();
122              } else {
123                nextLiEl.children[0].focus();
124              }
125            } else {
126              nextLiEl.children[0].focus();
127            }
128            break;
129        }
130      });
131    });
132  }
133  document.addEventListener('DOMContentLoaded', () => {
134    document.querySelectorAll('.nav').forEach(nav => setupNavigation(nav));
135  });
136})();

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.