1var bam = bam || {}; 2 3// polyfill forEach 4// https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Polyfill 5if ( window.NodeList && ! NodeList.prototype.forEach ) { 6 NodeList.prototype.forEach = function( callback, thisArg ) { 7 var i; 8 var len = this.length; 9 10 thisArg = thisArg || window; 11 12 for ( i = 0; i < len; i++ ) { 13 callback.call( thisArg, this[ i ], i, this ); 14 } 15 }; 16} 17 18/** 19 * Primary Menu keyboard navigation 20 */ 21 bam.primaryMenu = { 22 23 init: function() { 24 this.focusMenuWithChildren(); 25 }, 26 27 // The focusMenuWithChildren() function implements Keyboard Navigation in the Primary Menu 28 // by adding the '.focus' class to all 'li.menu-item-has-children' when the focus is on the 'a' element. 29 focusMenuWithChildren: function() { 30 // Get all the link elements within the primary menu. 31 var links, i, len, 32 menu = document.querySelector( '#site-navigation-inner' ); 33 34 if ( ! menu ) { 35 return false; 36 } 37 38 links = menu.getElementsByTagName( 'a' ); 39 40 // Each time a menu link is focused or blurred, toggle focus. 41 for ( i = 0, len = links.length; i < len; i++ ) { 42 links[i].addEventListener( 'focus', toggleFocus, true ); 43 links[i].addEventListener( 'blur', toggleFocus, true ); 44 } 45 46 //Sets or removes the .focus class on an element. 47 function toggleFocus() { 48 var self = this; 49 50 // Move up through the ancestors of the current link until we hit .main-navigation. 51 while ( -1 === self.className.indexOf( 'main-navigation' ) ) { 52 // On li elements toggle the class .focus. 53 if ( 'li' === self.tagName.toLowerCase() ) { 54 if ( -1 !== self.className.indexOf( 'focus' ) ) { 55 self.className = self.className.replace( ' focus', '' ); 56 } else { 57 self.className += ' focus'; 58 } 59 } 60 self = self.parentElement; 61 } 62 } 63 } 64}; 65 66/** 67 * Mobile Menu. 68 */ 69bam.mobileMenu = { 70 71 init: function() { 72 // Do the toggle. 73 this.toggle(); 74 }, 75 76 performToggle: function( element ) { 77 78 var target = element.dataset.toggleTarget, 79 activeClass = 'toggled-on'; 80 81 // Get the target element. 82 targetElement = document.querySelector(target); 83 84 // Change the icon of the menu toggle button. 85 if ( element.classList.contains('menu-toggle') ) { 86 this.toggleIcon(element); 87 } 88 89 element.classList.toggle(activeClass); 90 91 bamToggleAttribute(element, 'aria-expanded', 'true', 'false'); 92 93 targetElement.classList.toggle(activeClass); 94 95 }, 96 97 toggle: function() { 98 var self = this; 99 100 document.querySelectorAll('*[data-toggle-target]').forEach( function( element ) { 101 element.addEventListener( 'click', function( event ) { 102 event.preventDefault(); 103 self.performToggle( element ); 104 } ); 105 } ); 106 }, 107 108 toggleIcon: function(element) { 109 var icon = element.querySelector('i.fas'); 110 111 if ( ! icon ) { 112 return false; 113 } 114 115 if( icon.classList.contains('fa-bars') ) { 116 icon.classList.remove('fa-bars'); 117 icon.classList.add('fa-times'); 118 } else if ( icon.classList.contains('fa-times') ) { 119 icon.classList.remove('fa-times'); 120 icon.classList.add('fa-bars'); 121 } 122 } 123}; 124 125/** 126 * Search Toggle. 127 */ 128 bam.searchToggle = { 129 init: function() { 130 this.addListener(); 131 }, 132 133 toggle: function( element ) { 134 135 var navigationContainer = element.parentElement, 136 icon = navigationContainer.querySelector('i.fas'), 137 searchBoxContainer = navigationContainer.querySelector('.bam-search-box-container'), 138 inputField = navigationContainer.querySelector('input.search-field'); 139 140 // Toggle active class. 141 searchBoxContainer.classList.toggle('active'); 142 143 // Toggle search icon. 144 this.toggleIcon(icon); 145 146 // Focus the input field if the search box is displayed. 147 if( searchBoxContainer.classList.contains('active') ) { 148 inputField.focus(); 149 } 150 151 }, 152 153 addListener: function() { 154 155 var searchButton = document.querySelector('.bam-search-button-icon'); 156 157 if ( ! searchButton ) { 158 return false;
159 } 160 161 var self = this; 162 163 searchButton.addEventListener( 'click', function() { 164 self.toggle( this ); 165 } ); 166 167 }, 168 169 toggleIcon: function( icon ) { 170 if ( icon.classList.contains('fa-search') ) { 171 icon.classList.remove('fa-search'); 172 icon.classList.add('fa-times'); 173 } else if ( icon.classList.contains('fa-times') ) { 174 icon.classList.remove('fa-times'); 175 icon.classList.add('fa-search'); 176 } 177 } 178}; 179 180/** 181 * Intrinsic Ratio Embeds 182 * From TwentyTwenty WordPress theme. - Copyright (C) 2020 WordPress.org, GPLv2 or later 183 */ 184bam.intrinsicRatioVideos = { 185 186 init: function() { 187 this.makeFit(); 188 189 window.addEventListener( 'resize', function() { 190 this.makeFit(); 191 }.bind( this ) ); 192 }, 193 194 makeFit: function() { 195 document.querySelectorAll( 'iframe, object, video' ).forEach( function( video ) { 196 var ratio, iTargetWidth, 197 container = video.parentNode; 198 199 // Skip videos we want to ignore. 200 if ( video.classList.contains( 'intrinsic-ignore' ) || video.parentNode.classList.contains( 'intrinsic-ignore' ) ) { 201 return true; 202 } 203 204 if ( ! video.dataset.origwidth ) { 205 // Get the video element proportions. 206 video.setAttribute( 'data-origwidth', video.width ); 207 video.setAttribute( 'data-origheight', video.height ); 208 } 209 210 iTargetWidth = container.offsetWidth; 211 212 // Get ratio from proportions. 213 ratio = iTargetWidth / video.dataset.origwidth; 214 215 // Scale based on ratio, thus retaining proportions. 216 video.style.width = iTargetWidth + 'px'; 217 video.style.height = ( video.dataset.origheight * ratio ) + 'px'; 218 } ); 219 } 220 221}; 222 223/* Toggle an attribute */ 224function bamToggleAttribute( element, attribute, trueVal, falseVal ) { 225 if ( trueVal === undefined ) { 226 trueVal = true; 227 } 228 if ( falseVal === undefined ) { 229 falseVal = false; 230 } 231 if ( element.getAttribute( attribute ) !== trueVal ) { 232 element.setAttribute( attribute, trueVal ); 233 } else { 234 element.setAttribute( attribute, falseVal ); 235 } 236} 237 238/** 239 * Is the DOM ready? 240 * 241 * This implementation is coming from https://gomakethings.com/a-native-javascript-equivalent-of-jquerys-ready-method/ 242 * 243 * @param {Function} fn Callback function to run. 244 */ 245function bamDomReady( fn ) { 246 if ( typeof fn !== 'function' ) { 247 return; 248 } 249 250 if ( document.readyState === 'interactive' || document.readyState === 'complete' ) { 251 return fn(); 252 } 253 254 document.addEventListener( 'DOMContentLoaded', fn, false ); 255} 256 257bamDomReady( function() { 258 bam.mobileMenu.init(); 259 bam.searchToggle.init(); 260 bam.primaryMenu.init(); 261 bam.intrinsicRatioVideos.init(); 262} );
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.