PageSourceSearch

https://plumrocket.com/docs/wp-content/themes/twentynineteen/js/priority-menu.js?ver=20181214

js plumrocket.com collected 2026-09-24 09:31:46 UTC 5,375 bytes, 216 lines download raw bytes

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

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.