1var mq = matchMedia("(min-width: 750px)"); 2 3document.addEventListener("DOMContentLoaded", () => { 4 5 6 // I. Accessible dropdowns - Add button elements to T1 menu items with children 7 document.querySelectorAll( '#mainnav>ul>li' ).forEach( el => { 8 if ( !el.querySelector( 'ul' ) ) { 9 return; 10 } 11 12 el.classList.add( 'menu-item-has-children' ); 13 let link = el.querySelector( 'a' ); 14 let btn = '<button><span class="sr-only">show submenu for “' + link.text + '”</span></button>'; 15 link.insertAdjacentHTML( 'afterend', btn ); 16 }); 17 18 // II. Accessible dropdowns - Helper class to set aria-expanded attribute 19 function ws_set_aria_expanded( el, value ) { 20 el.setAttribute( 'aria-expanded', value ); 21 } 22 23 24 if (window.mq.matches) { 25 // do desktop stuff // 26 27 28 // Add class to header when page scrolled to toggle alternate styles 29 window.addEventListener( 'scroll', () => { 30 if(window.pageYOffset > 0) { 31 document.body.classList.add('scrolled'); 32 } else { 33 document.body.classList.remove('scrolled'); 34 } 35 }); 36 37 38 function is_touch_device() { 39 var prefixes = ' -webkit- -moz- -o- -ms- '.split(' '); 40 var mq = function (query) { 41 return window.matchMedia(query).matches; 42 } 43 if(('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints > 0) || window.DocumentTouch && document instanceof DocumentTouch) { 44 return true; 45 } 46 var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''); 47 return mq(query); 48 } 49 50 51 // III. Accessible dropdowns - Event listener for buttons 52 document.querySelectorAll( '#mainnav>ul>li>button' ).forEach( el => { 53 el.addEventListener( 'click', (e) => { 54 e.preventDefault(); 55 let parent = el.parentNode; 56 parent.classList.toggle( 'expand' ); 57 let flag = parent.classList.contains( 'expand' ) ? true : false; 58 ws_set_aria_expanded( parent.querySelector( 'a' ), flag ); 59 ws_set_aria_expanded( parent.querySelector('button'), flag ); 60 }); 61 }); 62 63 64 // IV. Accessible dropdowns - Focus event listeners for megamenus 65 document.querySelectorAll( '#mainnav>ul>li.has-megamenu' ).forEach( el => { 66 let megamenu = el.querySelector( '.megamenu' ); 67 68 el.querySelector( 'a' ).addEventListener( 'focus', e => { 69 ws_close_element( el ); 70 }); 71 72 megamenu.addEventListener( 'focusout', e => { 73 if ( !megamenu.contains( e.relatedTarget ) ) { 74 ws_close_element( el ); 75 } 76 }); 77 }); 78 79 80 /// V. Accessible dropdowns - Focus event listeners for normal dropdowns 81 document.querySelectorAll( '#mainnav>ul>li.menu-item-has-children' ).forEach( el => { 82 el.querySelector( 'a' ).addEventListener( 'focus', e => { 83 ws_close_element( el ); 84 }); 85 86 el.querySelector( 'ul' ).addEventListener( 'focusout', function (e) { 87 if ( !this.contains( e.relatedTarget ) ) { 88 ws_close_element( el ); 89 } 90 }); 91 }); 92 93 94 // VI. Accessible dropdowns - Helper class to close expanded elements 95 function ws_close_element( el ) { 96 el.classList.remove( 'expand' ); 97 ws_set_aria_expanded( el.querySelector( 'a' ), false ); 98 ws_set_aria_expanded( el.querySelector( 'button' ), false ); 99 } 100 101 102 // On touch devices, expand dropdowns on first tap 103 if( is_touch_device() ) { 104 document.querySelectorAll( "#mainnav>ul>li>a" ).forEach( elem => { 105 elem.addEventListener('touchstart', () => { 106 var parent = elem.parentElement; 107 if( parent.contains( parent.querySelector('ul') ) ) { 108 if( !parent.classList.contains( 'expand' ) ) { 109 event.preventDefault(); 110 document.querySelector( "#mainnav>ul>li.expand" )?.classList.remove( 'expand' ); 111 parent.classList.add( 'expand' ); 112 } 113 } 114 }); 115 }); 116 } 117 118 119 } else { 120 // do mobile stuff // 121 122 123 // Toggle slideNav 124 document.querySelectorAll( '.toggleNav' ).forEach( toggleNav => { 125 toggleNav.addEventListener( 'click', () => { 126 document.body.classList.toggle( 'slideNav' ); 127 }); 128 }); 129 130 131 // Close slideNav when clicked outside navContainer 132 document.addEventListener( 'click', checkTarget, false ); 133 document.addEventListener( 'touchstart', checkTarget, false ); 134 function checkTarget(event) { 135 if(document.body.classList.contains( 'slideNav' ) && 136 !document.querySelector('#navContainer').contains(event.target) && 137 !document.querySelector('#mobilenav .toggleNav').contains(event.target)) { 138 document.body.classList.remove('slideNav'); 139 } 140 } 141 142 143 // Expand current page / current page ancestor T1 items in mobile nav 144 document.querySelectorAll('#mainnav li.current_page_item, #mainnav li.current_page_parent, #mainnav li.current_page_ancestor, #mainnav li.current-page-ancestor').forEach(nav_item => { 145 nav_item.classList.add( 'expand' ); 146 var dropdown = nav_item.querySelector(':scope>ul'); 147 if ( dropdown ) { 148 dropdown.style.height = 'auto'; 149 } 150 }); 151 152 153 // Expand T1 dropdowns when + clicked 154 document.querySelectorAll( '#navContainer #mainnav>ul>li>button' ).forEach( button => { 155 button.addEventListener( 'click', () => { 156 157 button.parentElement.classList.toggle( 'expand' ); 158 159 if ( !button.parentElement.classList.contains( 'expand') ) { 160 let scroll_height = button.nextElementSibling.scrollHeight; 161 button.nextElementSibling.style.height = scroll_height + 'px'; 162 setTimeout( () => { 163 button.nextElementSibling.style.height = '0px'; 164 }, 30); 165 166 } else { 167 let scroll_height = button.nextElementSibling.scrollHeight; 168 button.nextElementSibling.style.height = scroll_height + 'px'; 169 // setTimeout( () => { 170 // button.nextElementSibling.style.height = 'auto'; 171 // }, 310); 172 } 173 174 }); 175 }); 176 177 178 } // end of mobile stuff // 179 180 181 // do desktop and mobile stuff // 182 mq.addListener( () => { 183 location.reload(); 184 }); 185 186 187 188 // Smooth scroll to anchor tag 189 document.querySelectorAll('a[href^="#"]:not([href="#"]):not([href="#main"])').forEach( anchor => { 190 anchor.addEventListener('click', (e) => { 191 e.preventDefault(); 192 193 let target = document.querySelector( anchor.getAttribute('href') ); 194 let header = document.querySelector( 'body>header' ).offsetHeight; // optional header height offset 195 let offset = target.getBoundingClientRect().top + window.pageYOffset - header; 196 197 ws_scroll_to( target, offset ); 198 }); 199 }); 200 201 202 203 // ScrollTo function with callback to set focus 204 function ws_scroll_to( target, offset ) { 205 let fixed_offset = offset.toFixed(); 206 207 function ws_on_scroll() { 208 if ( window.pageYOffset.toFixed() === fixed_offset ) { 209 window.removeEventListener( 'scroll', ws_on_scroll ); 210 ws_set_focus( target ); 211 } 212 } 213 214 window.addEventListener( 'scroll', ws_on_scroll ); 215 window.scrollTo({ 216 top: offset, 217 behavior: 'smooth' 218 }); 219 } 220 221 function ws_set_focus( target ) {
222 target.focus; // try to set focus 223 if( document.activeElement != target ) { 224 target.setAttribute( 'tabindex', '-1' ); // if focus wasn't set, set tabindex to make the element focusable 225 target.focus({ 226 preventScroll: true 227 }); 228 } 229 } 230 231 232 233 234 // 235 // Skip Link Focus 236 // 237 var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1, 238 is_opera = navigator.userAgent.toLowerCase().indexOf( 'opera' ) > -1, 239 is_ie = navigator.userAgent.toLowerCase().indexOf( 'msie' ) > -1; 240 241 if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) { 242 window.addEventListener( 'hashchange', function() { 243 var id = location.hash.substring( 1 ), 244 element; 245 if ( ! ( /^[A-z\d-]+$/.test( id ) ) ) { 246 return; 247 } 248 element = document.getElementById( id ); 249 if ( element ) { 250 if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { 251 element.tabIndex = -1; 252 } 253 element.focus(); 254 } 255 }, false ); 256 } 257 258 259 260 // Animations 261 const elements = document.querySelectorAll( '.hero .textbox>div, .blog-posts h2, .supporting-staff h2, .results-resources h2, .attorneys .textbox.retired h2, .translate-up ' ); 262 var offset = !window.mq.matches ? 50 : 150; 263 264 function intersectionObserver() { 265 var theRootMargin = '-' + offset + 'px 0px -' + offset + 'px 0px'; 266 const config = { rootMargin: theRootMargin, threshold: 0 }; 267 let observer = new IntersectionObserver(entries => { 268 entries.forEach(entry => { 269 if (entry.intersectionRatio > 0) { 270 entry.target.classList.add("animated"); 271 observer.unobserve(entry.target); 272 } else { 273 entry.target.classList.remove("animated"); 274 } 275 }); 276 }, config); 277 elements.forEach(element => { 278 observer.observe(element); 279 }); 280 } 281 282 setTimeout( () => { 283 intersectionObserver(); 284 }, 500); 285 286 287 288 // Stop animations during window resize event 289 var timer; 290 window.addEventListener( 'resize', () => { 291 document.body.classList.add( 'stop-transitions' ); 292 clearTimeout(timer); 293 timer = setTimeout(() => { 294 document.body.classList.remove( 'stop-transitions' ); 295 }, 500); 296 }, true); 297 298 299 300 301 function setParallax() { 302 var scroll = jQuery(window).scrollTop(); 303 304 jQuery('.parallax-bg').each(function() { 305 var theElement = jQuery(this); 306 307 var elementTop = theElement.offset().top; 308 var elementBottom = theElement.offset().top + theElement.outerHeight(); 309 var viewportBottom = scroll + jQuery(window).innerHeight(); 310 if ((viewportBottom > elementTop) && (scroll < elementBottom)) { 311 var yScroll = .1*(scroll - elementTop) + "px"; 312 theElement.css({ 'background-position': '50% calc(50% + ' + yScroll + ')' }); 313 } 314 }); 315 } 316 317 jQuery(window).scroll( setParallax ); 318 setParallax(); 319 320 321});
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.