PageSourceSearch

https://sangrur.nic.in/wp-content/themes/district-theme-6/js/menu.js

js sangrur.nic.in collected 2026-10-02 10:12:51 UTC 28,013 bytes, 733 lines download raw bytes

1// Code for Acessible Main menu
2
3jQuery(document).ready(function ($) {
4
5    //adding outline on menu if meniitems focused
6    $('.menuWrapper nav')
7        .on('focusin', function () {
8            $(this).addClass('menu-focused');
9        })
10        .on('focusout', function () {
11            let $this = $(this);
12            setTimeout(function () {
13                if (!$this.find(':focus').length) {
14                    $this.removeClass('menu-focused');
15                }
16            }, 10);
17        });
18
19
20    $('.menuWrapper nav ul ul.sub-menu').each(function () {
21        const $submenu = $(this);
22        const $parentLi = $submenu.closest('li'); // parent <li> with sub-menu
23        const $parentLink = $parentLi.children('a').first();
24
25        if ($parentLink.length) {
26            const linkText = $.trim($parentLink.clone().children().remove().end().text());
27            if (linkText !== '') {
28                $submenu.attr('aria-label', linkText + ' submenu');
29            }
30        }
31    });
32
33    var top_level_links = jQuery(this).find('li  a');
34    jQuery(top_level_links).each(function () {
35        if (jQuery(this).next('ul').length > 0) {
36            jQuery(this).parent('li').attr('aria-haspopup', 'true');
37            jQuery(this).parent('li').addClass('has-sub');
38            jQuery(this).append('<span class="indicator1" aria-hidden="true"></span>')
39
40        }
41    });
42
43    function updateAriaExpanded($li, expanded) {
44        const $link = $li.children("a");
45        if ($li.children("ul.sub-menu").length) {
46            $link.attr("aria-expanded", expanded ? "true" : "false");
47        } else {
48            $link.removeAttr("aria-expanded");
49        }
50    }
51
52    function openMenu() {
53        if ($("body").hasClass("rtl")) {
54            $("#overflowMenu").animate({
55                left: "0px"
56            });
57        } else {
58            $("#overflowMenu").animate({
59                right: "0px"
60            });
61        }
62        $('#overflowMenu ul').find(' > li > a').attr('tabindex', 0);
63        $('#overflowMenu a.closeMenu').attr('tabindex', 0);
64    }
65
66
67    function applyAriaRoles() {
68        const $mainMenu = $(".menuWrapper nav > ul");
69
70        $mainMenu.attr({
71            "role": "menubar"
72        });
73
74        const $topLevelLinks = $mainMenu.find("> li > a");
75
76        $topLevelLinks.each(function (index) {
77            const $link = $(this);
78            $link.attr("role", "menuitem");
79            $link.attr("tabindex", index === 0 ? "0" : "-1");
80
81            const $parentLi = $link.closest("li");
82            $parentLi.attr("role", "none");
83
84            if ($parentLi.children("ul.sub-menu").length) {
85                $link.attr("aria-haspopup", "true");
86                updateAriaExpanded($parentLi, false);
87            } else {
88                $link.removeAttr("aria-haspopup aria-expanded");
89            }
90        });
91
92        $(".menuWrapper nav ul ul.sub-menu").attr("role", "menu").attr("tabindex", "0");
93        $(".menuWrapper nav ul ul.sub-menu > li").attr("role", "none");
94        $(".menuWrapper nav ul ul.sub-menu > li > a").attr("role", "menuitem").attr("tabindex", "-1"); // set all submenu items to -1 initially
95    }
96
97    applyAriaRoles();
98
99    function closeSubMenu($li) {
100        $li.find("> ul.sub-menu").slideUp().attr("aria-hidden", "true");
101        updateAriaExpanded($li, false);
102        $li.find("> ul.sub-menu > li > a").attr("tabIndex", -1);
103        $li.find("> ul.sub-menu > li > ul.sub-menu").slideUp().attr("aria-hidden", "true");
104        $li.find("> ul.sub-menu > li > a").each(function () {
105            updateAriaExpanded($(this).parent(), false);
106        });
107    }
108
109    function openSubMenu($li, focusLast = false, focusFirst = false) {
110        $li.find("> ul.sub-menu").slideDown().attr("aria-hidden", "false");
111        updateAriaExpanded($li, true);
112        $li.find("> ul.sub-menu > li > a").attr("tabIndex", 0);
113        if ($li.closest("ul.sub-menu").length > 0) {
114            $li.find("> ul.sub-menu").css({
115                display: "block",
116                right: "-250px"
117            });
118        }
119        if (focusLast) {
120            $li.find("> ul.sub-menu > li:last > a").focus();
121        } else if (focusFirst) {
122            $li.find("> ul.sub-menu > li:first > a").focus();
123        }
124    }
125
126    function onMenuItemClick(event) {
127        const $submenu = $(this).children("ul.sub-menu");
128        const $link = $(this).children("a");
129        if ($submenu.length) {
130            $(this).siblings("li").find("ul.sub-menu").slideUp().attr("aria-hidden", "true")
131                .siblings("a").each(function () {
132                    updateAriaExpanded($(this).parent(), false);
133                });
134
135            const isVisible = $submenu.is(":visible");
136            // $submenu.slideToggle();
137            $submenu.attr("aria-hidden", isVisible ? "true" : "false");
138            updateAriaExpanded($(this), !isVisible);
139            $submenu.find("> li > a").attr("tabIndex", isVisible ? -1 : 0);
140            if ($(this).hasClass("has-sub-child")) {
141                $submenu.css('left', '100%');
142            }
143            event.stopPropagation();
144        }
145    }
146
147    $(".menuWrapper nav ul li").each(function () {
148        if ($(this).children("ul.sub-menu").length) {
149            $(this).on("click", onMenuItemClick);
150        }
151    });
152
153
154    //Keyboard Navigation Handler for Main Menu, Overflow Menu and Submenus
155
156    $(document).on("keydown", function (event) {
157        const $currentElement = $(document.activeElement);
158
159        const $menuWrapper = $(".menuWrapper nav, .moreNav");
160        if ($menuWrapper.has($currentElement).length === 0) {
161            return;
162        }
163
164        const isMainMenuItem =
165            $currentElement.closest(".menuWrapper nav > ul > li").length > 0 ||
166            $currentElement.closest(".moreNav").length > 0;
167
168        const isInSubmenu = $currentElement.closest("ul.sub-menu").length > 0;
169
170        const $mainMenuItems = $(".menuWrapper nav > ul > li > a:visible, .moreNav > a:visible").filter(function () {
171            return $(this).closest("li").parents("ul").length === 1;
172        });
173
174        const currentIndex = $mainMenuItems.get().indexOf($currentElement[0]);
175
176        const $parentLi = $currentElement.closest("li");
177        const $submenuItems = isInSubmenu ? $currentElement.closest("ul.sub-menu").find("> li > a") : [];
178        const submenuIndex = isInSubmenu ? $submenuItems.index($currentElement) : -1;
179
180        // ENTER / SPACE
181        if (event.which === 13 || event.which === 32) {
182            event.preventDefault();
183            if ($parentLi.children("ul.sub-menu").length) {
184                openSubMenu($parentLi, false, true);
185                // $parentLi.children("a").attr("aria-expanded", "true");
186            } else {
187                window.location.href = $currentElement.attr("href");
188                // $parentLi.children("a").attr("aria-expanded", "false");
189            }
190        }
191
192
193        // LEFT / RIGHT / UP / DOWN / HOME / END / ALPHABETICAL KEYS
194        else if ([37, 38, 39, 40, 36, 35].includes(event.which) || (event.key.length === 1 && /[a-zA-Z0-9]/.test(event.key))) {
195            event.preventDefault();
196
197            if (event.which === 37) { // LEFT
198                if (!isInSubmenu && isMainMenuItem) {
199                    const prevIndex = currentIndex > 0 ? currentIndex - 1 : $mainMenuItems.length - 1;
200                    $mainMenuItems.eq(prevIndex).focus();
201                } else if (isInSubmenu) {
202                    const $parentMenuItem = $currentElement.closest("ul.sub-menu").parent("li");
203                    closeSubMenu($parentMenuItem);
204                    $parentMenuItem.find("> a").focus().attr("aria-expanded", "false");
205                }
206            } else if (event.which === 39) { // RIGHT
207                let $currentLi = $currentElement.closest("li");
208
209                // Case 1: On a submenu item that has its own nested submenu
210                if (isInSubmenu) {
211                    let $nestedSubmenu = $currentLi.children("ul.sub-menu");
212                    if ($nestedSubmenu.length > 0) {
213                        // Open nested submenu
214                        $nestedSubmenu.attr("aria-hidden", "false").slideDown().css({
215                            display: "block",
216                            right: "-250px"
217                        });
218                        $currentLi.children("a").attr("aria-expanded", "true");
219
220                        // Focus first item in nested submenu
221                        $nestedSubmenu.find('a[role="menuitem"]:visible').first().focus();
222                    } else {
223                        // If no nested submenu, jump to next top-level menu item
224                        let $topParentLi = $currentLi;
225                        while ($topParentLi.closest("ul.sub-menu").length) {
226                            $topParentLi = $topParentLi.closest("ul.sub-menu").parent("li");
227                        }
228
229                        // Close all open submenus of this top-level item
230                        $topParentLi.find("ul.sub-menu").slideUp().attr("aria-hidden", "true");
231                        $topParentLi.find("a[aria-expanded='true']").attr("aria-expanded", "false");
232
233                        const parentIndex = $mainMenuItems.index($topParentLi.find("> a"));
234                        const nextIndex = parentIndex < $mainMenuItems.length - 1 ? parentIndex + 1 : 0;
235                        $mainMenuItems.eq(nextIndex).focus();
236                    }
237                }
238
239                // Case 2: On a main menu item (not in submenu)
240                else if (!isInSubmenu && isMainMenuItem) {
241                    const nextIndex = currentIndex < $mainMenuItems.length - 1 ? currentIndex + 1 : 0;
242                    $mainMenuItems.eq(nextIndex).focus();
243                }
244            } else if (event.which === 38) { // UP
245
246                if (isInSubmenu) {
247                    const newIndex = submenuIndex > 0 ? submenuIndex - 1 : $submenuItems.length - 1;
248                    $submenuItems.eq(newIndex).focus();
249                    if ($parentLi.children("ul.sub-menu").length) {
250                        $parentLi.children("a").attr("aria-expanded", "true");
251                    }
252                } else if ($parentLi.children("ul.sub-menu").length) {
253                    openSubMenu($parentLi, true);
254                }
255
256            } else if (event.which === 40) { // DOWN
257
258                if (isInSubmenu) {
259                    const newIndex = submenuIndex < $submenuItems.length - 1 ? submenuIndex + 1 : 0;
260                    $submenuItems.eq(newIndex).focus();
261                    if ($parentLi.children("ul.sub-menu").length) {
262                        $parentLi.children("a").attr("aria-expanded", "true");
263                    }
264                } else if ($parentLi.children("ul.sub-menu").length) {
265                    openSubMenu($parentLi, false, true);
266                }
267
268            } else if (event.which === 36) { // HOME
269                if (isInSubmenu) {
270                    $submenuItems.eq(0).focus();
271                } else {
272                    $mainMenuItems.eq(0).focus();
273                }
274            } else if (event.which === 35) { // END
275                if (isInSubmenu) {
276                    $submenuItems.eq($submenuItems.length - 1).focus();
277                } else {
278                    $mainMenuItems.eq($mainMenuItems.length - 1).focus();
279                }
280            } else if (event.key.length === 1 && /[a-zA-Z0-9]/.test(event.key)) { // First-char nav
281                const searchChar = event.key.toLowerCase();
282                const items = isInSubmenu ? $submenuItems : $mainMenuItems;
283                let startIndex = isInSubmenu ? submenuIndex + 1 : currentIndex + 1;
284                if (startIndex >= items.length) startIndex = 0;
285                for (let i = 0; i < items.length; i++) {
286                    const index = (startIndex + i) % items.length;
287                    const itemText = items.eq(index).text().trim().toLowerCase();
288                    if (itemText.startsWith(searchChar)) {
289                        items.eq(index).focus();
290                        break;
291                    }
292                }
293            }
294        }
295
296
297    });
298
299
300    $('html').on('click', function (event) {
301        // If clicked outside both main menu and overflow menu
302        if (!$(event.target).closest('.menuWrapper, #overflowMenu').length) {
303            $(".menuWrapper nav ul li ul.sub-menu").each(function () {
304                $(this)
305                    .slideUp()
306                    .attr("aria-hidden", "true")
307                    .find("> li > a")
308                    .attr("tabindex", -1);
309            });
310            $(".menuWrapper nav ul li:has(ul.sub-menu) > a").attr("aria-expanded", "false");
311            $("#overflowMenu .ofMenu ul li ul.sub-menu").each(function () {
312                $(this)
313                    .slideUp()
314                    .attr("aria-hidden", "true")
315                    .find("> li > a")
316                    .attr("tabindex", -1);
317            });
318            $("#overflowMenu .ofMenu ul li:has(ul.sub-menu) > a").attr("aria-expanded", "false");
319        }
320    });
321
322
323    $('.menu').on('click', function (event) {
324        event.stopPropagation();
325    });
326
327    // $(".menuWrapper nav ul li").on("keyup", function(event) {
328    //     if (event.which === 9) {
329    //         $(this).siblings("li").find("ul.sub-menu").hide();
330    //         $(".menuWrapper nav ul li").each(menuEachLiKeyup);
331    //     }
332    // });
333
334    // $(".menuWrapper nav ul li").on("click", onMenuItemClick);
335
336    $(".menuWrapper nav ul li").each(function () {
337        if ($(this).children("ul.sub-menu").length) {
338            $(this).on("click", onMenuItemClick);
339        }
340    });
341
342    $("nav li li").mouseover(function () {
343        if ($(this).children("ul.sub-menu").length == 1) {
344            let parent = $(this);
345            let child_menu = $(this).children("ul.sub-menu");
346            if (
347                $(parent).offset().left + $(parent).width() + $(child_menu).width() >
348                $(window).width()
349            ) {
350                $(child_menu).css("left", "-" + $(parent).width() + "px");
351            } else {
352                $(child_menu).css("right", "-" + $(parent).width() + "px");
353            }
354        }
355    });
356
357    /***** Overflow Navigation Setup *****/
358
359    if ($(window).innerWidth() >= 640) {
360        let menuContanerWidth = $(".menuWrapper .container").width(),
361            itemsTotalWith = 0;
362        $(".menu > ul > li").each(function (s, a) {
363            let itemClone = $(this).clone();
364            itemClone.find('a').attr("tabindex", -1);
365            if (
366                ((itemsTotalWith += $(this).width()),
367                    itemsTotalWith > menuContanerWidth - 100 &&
368                    ($(this).hasClass("moreNav") ||
369                        ($(this).remove(),
370                            $("#overflowMenu .ofMenu > ul").append(itemClone)),
371                        !($(".menu ul .moreNav").length > 0)))
372            ) {
373                let n = $(
374                    '<li class="moreNav" role="none">' +
375                    '<a href="#" role="button" aria-label="More Menu" title="More Menu"><span class="icon-menu" aria-hidden="true"></span><span class="hide">' +
376                    $(".menuMoreText").html() +
377                    "</span></a></li>"
378                );
379                $(".menuMoreText").html("");
380                $(".menu>ul").append(n);
381                n.click(openMenu);
382            }
383        });
384    }
385
386    // // More Button
387    $(".moreNav a").on("click", function (event) {
388        event.preventDefault(), event.stopPropagation();
389        openMenu();
390    });
391
392
393    $('#overflowMenu').click(function (event) {
394        event.stopPropagation();
395    });
396
397
398    $(".ofMenu ul li").on("click", onMenuItemClick);
399
400    $('.ofMenu ul li').hover(function (e) {
401        $(this).siblings().children('ul.sub-menu').slideUp();
402        $(this).children('ul.sub-menu').slideDown();
403    }, function () {
404        $(this).parent().siblings().children('ul.sub-menu').slideUp();
405    });
406
407    /***** Responsive Navigation Setup *****/
408
409    $(".menuToggle").click(function (event) {
410        event.preventDefault();
411        $(".menuWrapper").stop().slideToggle();
412    });
413
414    if ($(window).width() <= 639) {
415        $(".menu ul li").each(function (index, element) {
416            $(this).off('click');
417            if ($(this).children("ul").length) {
418                $(".indicator").hide();
419                $("<a href='javascript:void(0)' aria-label='Click to expand submenu' class='menu-toggle'>&nbsp;</a>")
420                    .insertAfter($(element).find(" > a "));
421            }
422        });
423    }
424
425    $(".menu-toggle").click(function (event) {
426        event.preventDefault();
427        $(this).toggleClass("open").parents('li').siblings().children("ul.sub-menu").stop().slideUp('fast');
428        $(this).next("ul.sub-menu").slideToggle('fast');
429
430        $(this).parents('li').siblings().children("a").removeClass("open");
431        $(this).parents('li').siblings().children("a.menu-select").removeClass("menu-select");
432        $(this).prev().toggleClass("menu-select");
433
434        var menuTitle = $(this).closest("li").find("> a").text().trim();
435        var collapseText = S3WaaSAccessibilityParams.clickToCollapse;
436        var expandText = S3WaaSAccessibilityParams.clickToExpand;
437        var submenuWord = S3WaaSAccessibilityParams.submenu;
438
439        if ($(this).hasClass("open")) {
440            $(this).attr("aria-label", collapseText + " " + menuTitle + " " + submenuWord).removeAttr("aria-expanded").attr("aria-expanded", "true");
441        } else {
442            $(this).attr("aria-label", expandText + " " + menuTitle + " " + submenuWord).removeAttr("aria-expanded").attr("aria-expanded", "false");
443        }
444    });
445
446
447    jQuery(".menuWrapper nav ul li ul.sub-menu > li > a, #overflowMenu .ofMenu ul li ul.submenu > li > a").on("keydown", function (event) {
448        const $submenu = $(this).closest("ul.sub-menu");
449        const $submenuItems = $submenu.find("> li > a");
450        const currentIndex = $submenuItems.index(this);
451
452        // Trap focus within submenu
453        if (event.which === 9) { // Tab key
454            if (!event.shiftKey && currentIndex === $submenuItems.length - 1) {
455                event.preventDefault();
456                $submenuItems.eq(0).focus();
457            } else if (event.shiftKey && currentIndex === 0) {
458                event.preventDefault();
459                $submenuItems.eq($submenuItems.length - 1).focus();
460            }
461        }
462
463        if (event.which === 27) { // Escape key
464            const $parentLi = $submenu.parent("li");
465            closeSubMenu($parentLi);
466            $parentLi.find("> a").focus().attr('aria-expanded', 'false');
467            event.preventDefault();
468
469        }
470
471
472    });
473
474    //if no submenu is open and esc key pressed move focus to first focusable element in main
475    jQuery(".menuWrapper nav > ul > li > a").on("keydown", function (event) {
476        if (event.which === 27) {
477            const $levelFirstMenu = jQuery(this).closest("ul.sub-menu");
478
479            if ($levelFirstMenu.length === 0) {
480                const $firstMainLink = jQuery("main a:visible").first();
481                if ($firstMainLink.length) {
482                    $firstMainLink.focus();
483                }
484                event.preventDefault();
485            }
486        }
487    });
488
489
490});
491
492jQuery(document).ready(function ($) {
493    const $ov = $('#overflowMenu');
494    const ovWidth = $ov.width();
495
496    // Ensure menu is collapsed on load
497    $('.moreNav > a').attr('aria-expanded', 'false');
498    $ov.hide().css('right', -ovWidth);
499    $ov.find('.sub-menu').hide().attr('aria-hidden', 'true');
500    $ov.find('a').attr('tabindex', -1);
501
502    const $toggleButton = $('.moreNav > a');
503    $toggleButton.attr({
504        'aria-haspopup': 'true',
505        'aria-expanded': 'false',
506        'aria-controls': 'overflowMenu' // connects to the popup menu
507    });
508    $ov.attr({
509        'role': 'dialog',
510        'aria-modal': 'true'
511    });
512
513    function applyAttributes() {
514        $ov.find('.ofMenu > ul').attr('role', 'menu');
515        $ov.find('li').attr('role', 'none');
516        $ov.find('a').attr('role', 'menuitem');
517        $ov.find('li:has(ul.sub-menu) > a')
518            .attr('aria-haspopup', 'true')
519            .attr('aria-expanded', 'false')
520            .attr('tabindex', -1);
521        $ov.find('ul.sub-menu')
522            .attr('role', 'menu')
523            .attr('aria-hidden', 'true')
524            .hide();
525    }
526    applyAttributes();
527
528    function trapWithin($container) {
529        const $focusables = $container.find('a:visible, button:visible').filter('[tabindex!="-1"]');
530        const first = $focusables.first();
531        const last = $focusables.last();
532
533        $focusables.off('keydown.trap').on('keydown.trap', function (e) {
534            const $items = $focusables;
535            const currentIndex = $items.index(this);
536
537            if (e.key === 'Tab') {
538                if (e.shiftKey && this === first[0]) {
539                    e.preventDefault();
540                    last.focus();
541                } else if (!e.shiftKey && this === last[0]) {
542                    e.preventDefault();
543                    first.focus();
544                }
545            }
546
547            if (e.key === 'ArrowDown') {
548                e.preventDefault();
549                const nextIndex = (currentIndex + 1) % $items.length;
550                $items.eq(nextIndex).focus();
551            }
552
553            if (e.key === 'ArrowUp') {
554                e.preventDefault();
555                const prevIndex = (currentIndex - 1 + $items.length) % $items.length;
556                $items.eq(prevIndex).focus();
557            }
558        });
559    }
560
561    function openOverflow() {
562        if ($ov.is(':visible')) return;
563
564        $toggleButton.attr('aria-expanded', 'true');
565
566        $ov.css({
567            right: -ovWidth,
568            display: 'block'
569        }).animate({
570            right: 0
571        }, 400, function () {
572            $ov.find('a').attr('tabindex', 0);
573            // const $firstItem = $ov.find('.ofMenu > ul > li > a:visible').first();
574            // $firstItem.focus();
575            $ov.focus().css('outline', '2px solid black')
576            trapWithin($ov);
577
578            announceMenuStatus('More menu expanded');
579        });
580    }
581
582
583    function closeOverflow() {
584        $ov.animate({
585            right: -ovWidth
586        }, 400, function () {
587            $ov.css('display', 'none');
588            $ov.find('a').attr('tabindex', -1);
589            $ov.find('[aria-expanded="true"]').each(function () {
590                $(this)
591                    .attr('aria-expanded', 'false')
592                    .next('ul.sub-menu')
593                    .hide()
594                    .attr('aria-hidden', 'true');
595            });
596            $ov.find('*').off('keydown.trap');
597            $toggleButton.attr('aria-expanded', 'false').focus();
598
599            announceMenuStatus('More menu collapsed');
600        });
601    }
602
603    function toggleSubmenu($link, open) {
604        const $sub = $link.next('.sub-menu');
605        $link.attr('aria-expanded', open);
606        $sub.attr('aria-hidden', !open)[open ? 'slideDown' : 'slideUp']();
607        if (open) {
608            const $first = $sub.find('a:visible').first().focus();
609            trapWithin($sub);
610        } else {
611            $sub.find('*').off('keydown.trap');
612            $link.focus();
613        }
614    }
615
616    $('.moreNav > a').on('click keydown', function (e) {
617        if (e.type === 'click' || e.key === 'Enter' || e.key === ' ') {
618            e.preventDefault();
619            openOverflow();
620        }
621    });
622
623    $ov.find('.closeMenu').on('click keydown', function (e) {
624        if (e.type === 'click' || e.key === 'Enter' || e.key === ' ') {
625            e.preventDefault();
626            closeOverflow();
627        }
628    });
629
630    $ov.on('keydown', 'a', function (e) {
631        const key = e.which;
632        const $link = $(this);
633        const $li = $link.parent('li');
634        const isParent = $li.children('ul.sub-menu').length > 0;
635        let $all = $ov.find('a:visible');
636        let idx = $all.index(this);
637
638        if ([13, 32].includes(key)) {
639            e.preventDefault();
640            if (isParent) {
641                toggleSubmenu($link, $link.attr('aria-expanded') == 'false');
642            } else {
643                location.href = $link.attr('href');
644            }
645        } else if (key === 27) {
646            const $visibleSubmenus = $ov.find('ul.sub-menu:visible').filter(function () {
647                return $(this).css('display') !== 'none';
648            });
649
650            if ($visibleSubmenus.length > 0) {
651                const $deepestSubmenu = $visibleSubmenus.sort((a, b) => {
652                    return $(a).parents('ul.sub-menu').length - $(b).parents('ul.sub-menu').length;
653                }
653).last();
654
655                const $parentLi = $deepestSubmenu.parent('li');
656                const $parentLink = $parentLi.children('a');
657
658                $deepestSubmenu.slideUp().attr('aria-hidden', 'true');
659                $parentLink.attr('aria-expanded', 'false');
660                $deepestSubmenu.find('*').off('keydown.trap');
661                $parentLink.focus();
662            } else {
663                closeOverflow();
664            }
665            e.preventDefault();
666        } else if (key === 37) {
667            e.preventDefault();
668            const $submenu = $link.closest('ul.sub-menu');
669            const $allMain = $ov.find('.ofMenu > ul > li > a:visible');
670
671            if ($submenu.length > 0) {
672                const $parentLi = $submenu.parent('li');
673                const $parentLink = $parentLi.children('a');
674                $submenu.slideUp().attr('aria-hidden', 'true');
675                $parentLink.attr('aria-expanded', 'false');
676                $parentLink.focus();
677            } else {
678                const prev = (idx - 1 + $all.length) % $all.length;
679                $all.eq(prev).focus();
680            }
681        } else if (key === 39) {
682            e.preventDefault();
683            const $submenu = $link.closest('ul.sub-menu');
684            const $allMain = $ov.find('.ofMenu > ul > li > a:visible');
685
686            if ($submenu.length > 0) {
687                const $parentLi = $submenu.parent('li');
688                const $parentLink = $parentLi.children('a');
689                $submenu.slideUp().attr('aria-hidden', 'true');
690                $parentLink.attr('aria-expanded', 'false');
691                const mainIdx = $allMain.index($parentLink);
692                const nextIdx = (mainIdx + 1) % $allMain.length;
693                $allMain.eq(nextIdx).focus();
694            } else {
695                const next = (idx + 1) % $all.length;
696                $all.eq(next).focus();
697            }
698        } else if (key === 36) {
699            e.preventDefault();
700            $all.first().focus();
701        } else if (key === 35) {
702            e.preventDefault();
703            $all.last().focus();
704        }
705    });
706
707    $(document).on('click', function (e) {
708        if ($ov.is(':visible') && !$(e.target).closest('#overflowMenu, .moreNav').length) {
709            closeOverflow();
710        }
711    });
712
713    $(window).on('unload', function () {
714        $ov.hide().css('right', -ovWidth);
715        $ov.find('.sub-menu').hide().attr('aria-hidden', 'true');
716        $ov.find('a').attr('tabindex', -1);
717        $ov.find('[aria-expanded="true"]').attr('aria-expanded', 'false');
718    });
719
720    // Append HTML in body for screen reader purpose only 
721    if ($('#menu-status').length === 0) {
722        $('body').append('<div id="menu-status" role="status" aria-live="polite" style="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;"></div>');
723    }
724
725    // overflow menu expand/collapse message for screen reader
726    function announceMenuStatus(message) {
727        const $status = $('#menu-status');
728        $status.text(''); // Clear first to force re-announcement
729        setTimeout(() => $status.text(message), 10);
730    }
731
732
733});

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.