[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-content/themes/twentynineteen/js/ -> priority-menu.js (source)

   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  })();


Generated: Sat Nov 23 20:47:33 2019 Cross-referenced by PHPXref 0.7