1/*global jQuery*/ 2const dvSubnavItems = []; 3 4/** 5 * Navigation provider. 6 * 7 * @param {Object} $ jQuery 8 */ 9( function( $ ) { 10 $( document ).ready( function() { 11 const $subnav = $( '#menu-subnav' ); 12 13 const renderSubnavItems = () => { 14 dvSubnavItems.forEach( ( item ) => { 15 const label = item.dataset.dvSubnavItemLabel; 16 17 if ( label ) { 18 $subnav.append( ` 19 <li class="menu-item"> 20 <a 21 class="menu-link" 22 href="#${item.id}" 23 >${label}</a> 24 </li> 25 ` ); 26 } 27 } ); 28 }; 29 30 const getSubnavData = () => { 31 const $items = $( '[data-dv-subnav=true]' ); 32 33 dvSubnavItems.push( ...$items ); 34 }; 35 36 const init = () => { 37 getSubnavData(); 38 renderSubnavItems(); 39 scrollSpy(); 40 }; 41 42 init(); 43 } ); 44 45 /** 46 * Anchorpoint logic 47 */ 48 ( () => { 49 $( document ).ready( () => { 50 const siteNavigation = document.getElementById( 'site-navigation' ); 51 const navItems = siteNavigation.querySelectorAll( '.menu__wrapper--level-0' ); 52 const allowedBounds = siteNavigation.getBoundingClientRect().right; 53 54 navItems.forEach( ( item ) => { 55 // Right bounds position 56 const rightBounds = item.getBoundingClientRect().right; 57 58 if ( rightBounds > allowedBounds ) { 59 item.classList.add( 'menu__wrapper--anchor-right' ); 60 item.classList.add( 'menu__wrapper--level-0--anchor-right' ); 61 } 62 } ); 63 64 // Trigger Event when navigation is ready 65 const navigationReadyEvent = new Event( 'subNavigationReady' ); 66 dispatchEvent( navigationReadyEvent ); 67 } ); 68 } )(); 69 70 /** 71 * Highlight submenu entry of currently intersecting section 72 * 73 * @param id string The id of the currently intersecting section 74 */ 75 const highlightCurrentIntersection = ( id ) => { 76 const subMenu = document.getElementById( 'site-navigation-context' ); 77 const subMenuItems = subMenu.querySelectorAll( '.menu-item' ); 78 79 subMenuItems.forEach( ( item ) => { 80 item.classList.remove( 'menu-item--active' ); 81 82 if ( item.querySelector( 'a' ).getAttribute( 'href' ) === `#${id}` ) { 83 item.classList.add( 'menu-item--active' ); 84 } 85 } ); 86 }; 87 88 /** 89 * Scrollspy logic 90 */ 91 const scrollSpy = () => { 92 const subMenu = document.getElementById( 'site-navigation-context' ); 93 const subMenuItems = subMenu.querySelectorAll( '.menu-item' ); 94 95 if ( ! subMenuItems ) { 96 return; 97 } 98 99 const itemsToObserver = []; 100 101 subMenuItems.forEach( ( item ) => { 102 const target = item.querySelector( 'a' ).getAttribute( 'href' ); 103 if ( ! target ) { 104 return; 105 } 106 107 const isAnchor = target.split( '' ).shift() === '#'; 108 109 if ( isAnchor ) { 110 const targetName = item.querySelector( 'a' ).getAttribute( 'href' ).replace( '#', '' ); 111 112 itemsToObserver.push( document.getElementById( targetName ) ); 113 } 114 } ); 115 116 const observerOptions = { 117 threshold: 0.75, 118 rootMargin: '0% 0% -75%' 119 }; 120 121 const observer = new IntersectionObserver( ( entries ) => { 122 const itemsToHighlight = []; 123 124 entries.forEach( ( entry ) => { 125 if ( entry.isIntersecting ) { 126 itemsToHighlight.push( entry ); 127 } 128 } ); 129 130 if ( itemsToHighlight.length > 0 ) { 131 highlightCurrentIntersection( itemsToHighlight[0].target.id ); 132 } 133 }, observerOptions ); 134 135 itemsToObserver.forEach( ( item ) => { 136 observer.observe( item ); 137 } ); 138 139 // highlightCurrentIntersection( itemsToObserver[0].id ); 140 }; 141}( jQuery ) ); 142
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.