1/** 2 * File navigation.js. 3 * 4 * Handles toggling the navigation menu for small screens and enables TAB key 5 * navigation support for dropdown menus. 6 */ 7(function () { 8 const siteNavigation = document.getElementById('site-navigation'); 9 10 // Return early if the navigation don't exist. 11 if (!siteNavigation) { 12 return; 13 } 14 15 const button = siteNavigation.getElementsByTagName('button')[0]; 16 17 // Return early if the button don't exist. 18 if ('undefined' === typeof button) { 19 return; 20 } 21 22 const menu = siteNavigation.getElementsByTagName('ul')[0]; 23 24 // Hide menu toggle button if menu is empty and return early. 25 if ('undefined' === typeof menu) { 26 button.style.display = 'none'; 27 return; 28 } 29 30 if (!menu.classList.contains('nav-menu')) { 31 menu.classList.add('nav-menu'); 32 } 33 34 // Toggle the .toggled class and the aria-expanded value each time the button is clicked. 35 button.addEventListener('click', function () { 36 siteNavigation.classList.toggle('toggled'); 37 38 if (button.getAttribute('aria-expanded') === 'true') { 39 button.setAttribute('aria-expanded', 'false'); 40 } else { 41 button.setAttribute('aria-expanded', 'true'); 42 } 43 }); 44 45 // Remove the .toggled class and set aria-expanded to false when the user clicks outside the navigation. 46 document.addEventListener('click', function (event) { 47 const isClickInside = siteNavigation.contains(event.target); 48 49 if (!isClickInside) { 50 siteNavigation.classList.remove('toggled'); 51 button.setAttribute('aria-expanded', 'false'); 52 } 53 }); 54 55 // Get all the link elements within the menu. 56 const links = menu.getElementsByTagName('a'); 57 58 // Get all the link elements with children within the menu. 59 const linksWithChildren = menu.querySelectorAll('.menu-item-has-children > a, .page_item_has_children > a'); 60 61 // Toggle focus each time a menu link is focused or blurred. 62 for (const link of links) { 63 link.addEventListener('focus', toggleFocus, true); 64 link.addEventListener('blur', toggleFocus, true); 65 } 66 67 // Toggle focus each time a menu link with children receive a touch event. 68 for (const link of linksWithChildren) { 69 link.addEventListener('touchstart', toggleFocus, false); 70 } 71 72 /** 73 * Sets or removes .focus class on an element. 74 */ 75 function toggleFocus() { 76 if (event.type === 'focus' || event.type === 'blur') { 77 let self = this; 78 // Move up through the ancestors of the current link until we hit .nav-menu. 79 while (!self.classList.contains('nav-menu')) { 80 // On li elements toggle the class .focus. 81 if ('li' === self.tagName.toLowerCase()) { 82 self.classList.toggle('focus'); 83 } 84 self = self.parentNode; 85 } 86 } 87 88 if (event.type === 'touchstart') { 89 const menuItem = this.parentNode; 90 event.preventDefault(); 91 for (const link of menuItem.parentNode.children) { 92 if (menuItem !== link) { 93 link.classList.remove('focus'); 94 } 95 } 96 menuItem.classList.toggle('focus'); 97 } 98 } 99}());
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.