PageSourceSearch

https://www.mms.edu.jo/themes/custom/born_ready_bs4_evolution/js/components/main-menu.js?v=10.6.4

js mms.edu.jo collected 2026-10-03 01:57:24 UTC 8,242 bytes, 279 lines download raw bytes

1(function (Drupal) {
2  'use strict';
3
4  Drupal.behaviors.mainMenuHover = {
5    attach(context) {
6      const containers = context.querySelectorAll(
7        '.header__secondary-menu-inner:not(.secondary-menu-initialized)'
8      );
9
10      containers.forEach((container) => {
11        container.classList.add('secondary-menu-initialized');
12
13        const menuItems = container.querySelectorAll(
14          '.menu-left .menu-item'
15        );
16
17        const desktopSubmenus = container.querySelectorAll(
18          '.menu-right > .submenu'
19        );
20
21        const desktopSubmenuItems = container.querySelectorAll(
22          '.menu-right .submenu-item'
23        );
24
25        const thirdLevelMenus = container.querySelectorAll(
26          '.menu-third .third-level-menu'
27        );
28
29        const isDesktop = () => window.innerWidth >= 1024;
30
31        const closeThirdLevelMenus = () => {
32          thirdLevelMenus.forEach((menu) => {
33            menu.classList.remove('is-active');
34          });
35
36          desktopSubmenuItems.forEach((item) => {
37            item.classList.remove('is-active');
38          });
39        };
40
41        const closeDesktopMenus = () => {
42          desktopSubmenus.forEach((submenu) => {
43            submenu.classList.remove('is-active');
44          });
45
46          menuItems.forEach((item) => {
47            item.classList.remove('is-active');
48          });
49
50          closeThirdLevelMenus();
51        };
52
53        /*
54         * First-level menu hover.
55         */
56        menuItems.forEach((menuItem) => {
57          menuItem.addEventListener('mouseenter', () => {
58            if (!isDesktop()) {
59              return;
60            }
61
62            const parentIndex = menuItem.dataset.index;
63
64            closeDesktopMenus();
65
66            const targetSubmenu = container.querySelector(
67              `.menu-right > .submenu[data-submenu-index="${parentIndex}"]`
68            );
69
70            if (targetSubmenu) {
71              targetSubmenu.classList.add('is-active');
72            }
73
74            menuItem.classList.add('is-active');
75          });
76        });
77
78        /*
79         * Second-level menu hover.
80         */
81        desktopSubmenuItems.forEach((submenuItem) => {
82          submenuItem.addEventListener('mouseenter', () => {
83            if (!isDesktop()) {
84              return;
85            }
86
87            const parentIndex = submenuItem.dataset.parentIndex;
88            const thirdLevelIndex =
89              submenuItem.dataset.thirdLevelIndex;
90
91            closeThirdLevelMenus();
92
93            submenuItem.classList.add('is-active');
94
95            const targetThirdLevelMenu = container.querySelector(
96              `.menu-third .third-level-menu` +
97              `[data-parent-index="${parentIndex}"]` +
98              `[data-third-level-index="${thirdLevelIndex}"]`
99            );
100
101            if (targetThirdLevelMenu) {
102              targetThirdLevelMenu.classList.add('is-active');
103            }
104          });
105        });
106
107        /*
108         * Keep the selected second-level item active while the mouse
109         * is over its corresponding third-level column.
110         */
111        thirdLevelMenus.forEach((thirdLevelMenu) => {
112          thirdLevelMenu.addEventListener('mouseenter', () => {
113            if (!isDesktop()) {
114              return;
115            }
116
117            const parentIndex = thirdLevelMenu.dataset.parentIndex;
118            const thirdLevelIndex =
119              thirdLevelMenu.dataset.thirdLevelIndex;
120
121            closeThirdLevelMenus();
122
123            thirdLevelMenu.classList.add('is-active');
124
125            const matchingSubmenuItem = container.querySelector(
126              `.menu-right .submenu-item` +
127              `[data-parent-index="${parentIndex}"]` +
128              `[data-third-level-index="${thirdLevelIndex}"]`
129            );
130
131            if (matchingSubmenuItem) {
132              matchingSubmenuItem.classList.add('is-active');
133            }
134          });
135        });
136
137        container.addEventListener('mouseleave', () => {
138          if (isDesktop()) {
139            closeDesktopMenus();
140          }
141        });
142        /*
143        * Mobile menu.
144        */
145        menuItems.forEach((menuItem) => {
146          const firstLevelToggle = menuItem.querySelector(
147            ':scope > .menu-item-text'
148          );
149
150          const mobileSubmenu = menuItem.querySelector(
151            ':scope > .submenu'
152          );
153
154          if (!firstLevelToggle || !mobileSubmenu) {
155            return;
156          }
157
158          /*
159          * First-level item opens the second-level menu.
160          */
161          firstLevelToggle.addEventListener('click', (event) => {
162            if (isDesktop()) {
163              return;
164            }
165
166            event.preventDefault();
167
168            const willOpen = !menuItem.classList.contains('is-active');
169
170            /*
171            * Close other first-level menus.
172            */
173            menuItems.forEach((otherMenuItem) => {
174              if (otherMenuItem === menuItem) {
175                return;
176              }
177
178              otherMenuItem.classList.remove('is-active');
179
180              const otherSubmenu = otherMenuItem.querySelector(
181                ':scope > .submenu'
182              );
183
184              otherSubmenu?.classList.remove('is-active');
185
186              /*
187              * Close third-level menus belonging to the other item.
188              */
189              otherMenuItem
190                .querySelectorAll('.submenu-item.is-active')
191                .forEach((submenuItem) => {
192                  submenuItem.classList.remove('is-active');
193                });
194
195              otherMenuItem
196                .querySelectorAll('.third-level-menu.is-active')
197                .forEach((thirdLevelMenu) => {
198                  thirdLevelMenu.classList.remove('is-active');
199                });
200            });
201
202            menuItem.classList.toggle('is-active', willOpen);
203            mobileSubmenu.classList.toggle('is-active', willOpen);
204
205            /*
206            * Close third-level menus when the first-level item closes.
207            */
208            if (!willOpen) {
209              mobileSubmenu
210                .querySelectorAll('.submenu-item.is-active')
211                .forEach((submenuItem) => {
212                  submenuItem.classList.remove('is-active');
213                });
214
215              mobileSubmenu
216                .querySelectorAll('.third-level-menu.is-active')
217                .forEach((thirdLevelMenu) => {
218                  thirdLevelMenu.classList.remove('is-active');
219                });
220            }
221          });
222
223          /*
224          * Second-level items that have a third-level menu.
225          */
226          const mobileSubmenuItems = mobileSubmenu.querySelectorAll(
227            ':scope > .submenu-item.has-third-level'
228          );
229
230          mobileSubmenuItems.forEach((submenuItem) => {
231            const secondLevelToggle = submenuItem.querySelector(
232              ':scope > .submenu-item-text'
233            );
234
235            const thirdLevelMenu = submenuItem.querySelector(
236              ':scope > .third-level-menu'
237            );
238
239            if (!secondLevelToggle || !thirdLevelMenu) {
240              return;
241            }
242
243            secondLevelToggle.addEventListener('click', (event) => {
244              if (isDesktop()) {
245                return;
246              }
247
248              event.preventDefault();
249              event.stopPropagation();
250
251              const willOpen = !submenuItem.classList.contains('is-active');
252
253              /*
254              * Close other third-level menus under the same second-level menu.
255              */
256              mobileSubmenuItems.forEach((otherSubmenuItem) => {
257                if (otherSubmenuItem === submenuItem) {
258                  return;
259                }
260
261                otherSubmenuItem.classList.remove('is-active');
262
263                const otherThirdLevelMenu =
264                  otherSubmenuItem.querySelector(
265                    ':scope > .third-level-menu'
266                  );
267
268                otherThirdLevelMenu?.classList.remove('is-active');
269              });
270
271              submenuItem.classList.toggle('is-active', willOpen);
272              thirdLevelMenu.classList.toggle('is-active', willOpen);
273            });
274          });
275        });
276      });
277    },
278  };
279})(Drupal);

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.