[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 (function() { 2 3 /** 4 * Debounce. 5 * 6 * @param {Function} func 7 * @param {number} wait 8 * @param {boolean} immediate 9 */ 10 function debounce(func, wait, immediate) { 11 'use strict'; 12 13 var timeout; 14 wait = (typeof wait !== 'undefined') ? wait : 20; 15 immediate = (typeof immediate !== 'undefined') ? immediate : true; 16 17 return function() { 18 19 var context = this, args = arguments; 20 var later = function() { 21 timeout = null; 22 23 if (!immediate) { 24 func.apply(context, args); 25 } 26 }; 27 28 var callNow = immediate && !timeout; 29 30 clearTimeout(timeout); 31 timeout = setTimeout(later, wait); 32 33 if (callNow) { 34 func.apply(context, args); 35 } 36 }; 37 } 38 39 /** 40 * Prepends an element to a container. 41 * 42 * @param {Element} container 43 * @param {Element} element 44 */ 45 function prependElement(container, element) { 46 if (container.firstChild.nextSibling) { 47 return container.insertBefore(element, container.firstChild.nextSibling); 48 } else { 49 return container.appendChild(element); 50 } 51 } 52 53 /** 54 * Shows an element by adding a hidden className. 55 * 56 * @param {Element} element 57 */ 58 function showButton(element) { 59 // classList.remove is not supported in IE11. 60 element.className = element.className.replace('is-empty', ''); 61 } 62 63 /** 64 * Hides an element by removing the hidden className. 65 * 66 * @param {Element} element 67 */ 68 function hideButton(element) { 69 // classList.add is not supported in IE11. 70 if (!element.classList.contains('is-empty')) { 71 element.className += ' is-empty'; 72 } 73 } 74 75 /** 76 * Returns the currently available space in the menu container. 77 * 78 * @returns {number} Available space 79 */ 80 function getAvailableSpace( button, container ) { 81 return container.offsetWidth - button.offsetWidth - 22; 82 } 83 84 /** 85 * Returns whether the current menu is overflowing or not. 86 * 87 * @returns {boolean} Is overflowing 88 */ 89 function isOverflowingNavivation( list, button, container ) { 90 return list.offsetWidth > getAvailableSpace( button, container ); 91 } 92 93 /** 94 * Set menu container variable. 95 */ 96 var navContainer = document.querySelector('.main-navigation'); 97 var breaks = []; 98 99 /** 100 * Let’s bail if we our menu doesn't exist. 101 */ 102 if ( ! navContainer ) { 103 return; 104 } 105 106 /** 107 * Refreshes the list item from the menu depending on the menu size. 108 */ 109 function updateNavigationMenu( container ) { 110 111 /** 112 * Let’s bail if our menu is empty. 113 */ 114 if ( ! container.parentNode.querySelector('.main-menu[id]') ) { 115 return; 116 } 117 118 // Adds the necessary UI to operate the menu. 119 var visibleList = container.parentNode.querySelector('.main-menu[id]'); 120 var hiddenList = visibleList.parentNode.nextElementSibling.querySelector('.hidden-links'); 121 var toggleButton = visibleList.parentNode.nextElementSibling.querySelector('.main-menu-more-toggle'); 122 123 if ( isOverflowingNavivation( visibleList, toggleButton, container ) ) { 124 125 // Record the width of the list. 126 breaks.push( visibleList.offsetWidth ); 127 // Move last item to the hidden list. 128 prependElement( hiddenList, ! visibleList.lastChild || null === visibleList.lastChild ? visibleList.previousElementSibling : visibleList.lastChild ); 129 // Show the toggle button. 130 showButton( toggleButton ); 131 132 } else { 133 134 // There is space for another item in the nav. 135 if ( getAvailableSpace( toggleButton, container ) > breaks[breaks.length - 1] ) { 136 // Move the item to the visible list. 137 visibleList.appendChild( hiddenList.firstChild.nextSibling ); 138 breaks.pop(); 139 } 140 141 // Hide the dropdown btn if hidden list is empty. 142 if (breaks.length < 2) { 143 hideButton( toggleButton ); 144 } 145 } 146 147 // Recur if the visible list is still overflowing the nav. 148 if ( isOverflowingNavivation( visibleList, toggleButton, container ) ) { 149 updateNavigationMenu( container ); 150 } 151 } 152 153 /** 154 * Run our priority+ function as soon as the document is `ready`. 155 */ 156 document.addEventListener( 'DOMContentLoaded', function() { 157 158 updateNavigationMenu( navContainer ); 159 160 // Also, run our priority+ function on selective refresh in the customizer. 161 var hasSelectiveRefresh = ( 162 'undefined' !== typeof wp && 163 wp.customize && 164 wp.customize.selectiveRefresh && 165 wp.customize.navMenusPreview.NavMenuInstancePartial 166 ); 167 168 if ( hasSelectiveRefresh ) { 169 // Re-run our priority+ function on Nav Menu partial refreshes. 170 wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function ( placement ) { 171 172 var isNewNavMenu = ( 173 placement && 174 placement.partial.id.includes( 'nav_menu_instance' ) && 175 'null' !== placement.container[0].parentNode && 176 placement.container[0].parentNode.classList.contains( 'main-navigation' ) 177 ); 178 179 if ( isNewNavMenu ) { 180 updateNavigationMenu( placement.container[0].parentNode ); 181 } 182 }); 183 } 184 }); 185 186 /** 187 * Run our priority+ function on load. 188 */ 189 window.addEventListener( 'load', function() { 190 updateNavigationMenu( navContainer ); 191 }); 192 193 /** 194 * Run our priority+ function every time the window resizes. 195 */ 196 var isResizing = false; 197 window.addEventListener( 'resize', 198 debounce( function() { 199 if ( isResizing ) { 200 return; 201 } 202 203 isResizing = true; 204 setTimeout( function() { 205 updateNavigationMenu( navContainer ); 206 isResizing = false; 207 }, 150 ); 208 } ) 209 ); 210 211 /** 212 * Run our priority+ function. 213 */ 214 updateNavigationMenu( navContainer ); 215 216 })();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 25 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |