diff options
author | Yury German <blueknight@gentoo.org> | 2019-04-28 21:40:16 -0400 |
---|---|---|
committer | Yury German <blueknight@gentoo.org> | 2019-04-28 21:40:16 -0400 |
commit | f74389cedb2f722a6247735c19c986a63977c8c8 (patch) | |
tree | b1e9522d59551f05a8c85be9460d508909eaf1e0 /themes/twentynineteen/js/priority-menu.js | |
parent | Updating the themes (diff) | |
download | blogs-gentoo-f74389cedb2f722a6247735c19c986a63977c8c8.tar.gz blogs-gentoo-f74389cedb2f722a6247735c19c986a63977c8c8.tar.bz2 blogs-gentoo-f74389cedb2f722a6247735c19c986a63977c8c8.zip |
Adding Twentyninetten
Signed-off-by: Yury German <blueknight@gentoo.org>
Diffstat (limited to 'themes/twentynineteen/js/priority-menu.js')
-rw-r--r-- | themes/twentynineteen/js/priority-menu.js | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/themes/twentynineteen/js/priority-menu.js b/themes/twentynineteen/js/priority-menu.js new file mode 100644 index 00000000..7cd6bb06 --- /dev/null +++ b/themes/twentynineteen/js/priority-menu.js @@ -0,0 +1,216 @@ +(function() { + + /** + * Debounce + * + * @param {Function} func + * @param {number} wait + * @param {boolean} immediate + */ + function debounce(func, wait, immediate) { + 'use strict'; + + var timeout; + wait = (typeof wait !== 'undefined') ? wait : 20; + immediate = (typeof immediate !== 'undefined') ? immediate : true; + + return function() { + + var context = this, args = arguments; + var later = function() { + timeout = null; + + if (!immediate) { + func.apply(context, args); + } + }; + + var callNow = immediate && !timeout; + + clearTimeout(timeout); + timeout = setTimeout(later, wait); + + if (callNow) { + func.apply(context, args); + } + }; + } + + /** + * Prepends an element to a container. + * + * @param {Element} container + * @param {Element} element + */ + function prependElement(container, element) { + if (container.firstChild.nextSibling) { + return container.insertBefore(element, container.firstChild.nextSibling); + } else { + return container.appendChild(element); + } + } + + /** + * Shows an element by adding a hidden className. + * + * @param {Element} element + */ + function showButton(element) { + // classList.remove is not supported in IE11 + element.className = element.className.replace('is-empty', ''); + } + + /** + * Hides an element by removing the hidden className. + * + * @param {Element} element + */ + function hideButton(element) { + // classList.add is not supported in IE11 + if (!element.classList.contains('is-empty')) { + element.className += ' is-empty'; + } + } + + /** + * Returns the currently available space in the menu container. + * + * @returns {number} Available space + */ + function getAvailableSpace( button, container ) { + return container.offsetWidth - button.offsetWidth - 22; + } + + /** + * Returns whether the current menu is overflowing or not. + * + * @returns {boolean} Is overflowing + */ + function isOverflowingNavivation( list, button, container ) { + return list.offsetWidth > getAvailableSpace( button, container ); + } + + /** + * Set menu container variable + */ + var navContainer = document.querySelector('.main-navigation'); + var breaks = []; + + /** + * Let’s bail if we our menu doesn't exist + */ + if ( ! navContainer ) { + return; + } + + /** + * Refreshes the list item from the menu depending on the menu size + */ + function updateNavigationMenu( container ) { + + /** + * Let’s bail if our menu is empty + */ + if ( ! container.parentNode.querySelector('.main-menu[id]') ) { + return; + } + + // Adds the necessary UI to operate the menu. + var visibleList = container.parentNode.querySelector('.main-menu[id]'); + var hiddenList = visibleList.parentNode.nextElementSibling.querySelector('.hidden-links'); + var toggleButton = visibleList.parentNode.nextElementSibling.querySelector('.main-menu-more-toggle'); + + if ( isOverflowingNavivation( visibleList, toggleButton, container ) ) { + + // Record the width of the list + breaks.push( visibleList.offsetWidth ); + // Move last item to the hidden list + prependElement( hiddenList, ! visibleList.lastChild || null === visibleList.lastChild ? visibleList.previousElementSibling : visibleList.lastChild ); + // Show the toggle button + showButton( toggleButton ); + + } else { + + // There is space for another item in the nav + if ( getAvailableSpace( toggleButton, container ) > breaks[breaks.length - 1] ) { + // Move the item to the visible list + visibleList.appendChild( hiddenList.firstChild.nextSibling ); + breaks.pop(); + } + + // Hide the dropdown btn if hidden list is empty + if (breaks.length < 2) { + hideButton( toggleButton ); + } + } + + // Recur if the visible list is still overflowing the nav + if ( isOverflowingNavivation( visibleList, toggleButton, container ) ) { + updateNavigationMenu( container ); + } + } + + /** + * Run our priority+ function as soon as the document is `ready` + */ + document.addEventListener( 'DOMContentLoaded', function() { + + updateNavigationMenu( navContainer ); + + // Also, run our priority+ function on selective refresh in the customizer + var hasSelectiveRefresh = ( + 'undefined' !== typeof wp && + wp.customize && + wp.customize.selectiveRefresh && + wp.customize.navMenusPreview.NavMenuInstancePartial + ); + + if ( hasSelectiveRefresh ) { + // Re-run our priority+ function on Nav Menu partial refreshes + wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function ( placement ) { + + var isNewNavMenu = ( + placement && + placement.partial.id.includes( 'nav_menu_instance' ) && + 'null' !== placement.container[0].parentNode && + placement.container[0].parentNode.classList.contains( 'main-navigation' ) + ); + + if ( isNewNavMenu ) { + updateNavigationMenu( placement.container[0].parentNode ); + } + }); + } + }); + + /** + * Run our priority+ function on load + */ + window.addEventListener( 'load', function() { + updateNavigationMenu( navContainer ); + }); + + /** + * Run our priority+ function every time the window resizes + */ + var isResizing = false; + window.addEventListener( 'resize', + debounce( function() { + if ( isResizing ) { + return; + } + + isResizing = true; + setTimeout( function() { + updateNavigationMenu( navContainer ); + isResizing = false; + }, 150 ); + } ) + ); + + /** + * Run our priority+ function + */ + updateNavigationMenu( navContainer ); + +})(); |