PageSourceSearch

https://www.maayot.com/blog/wp-content/themes/generatepress/assets/js/menu.js?ver=3.6.1

js maayot.com collected 2026-10-02 03:38:06 UTC 14,502 bytes, 449 lines download raw bytes

1( function() {
2	'use strict';
3	var allSubMenus = document.querySelectorAll( '.main-nav .sub-menu, .main-nav .children' );
4
5	// Add missing aria roles and attributes for accessibility.
6	if ( allSubMenus ) {
7		allSubMenus.forEach( function( subMenu ) {
8			var parentLi = subMenu.closest( 'li' );
9			var button = parentLi.querySelector( '.dropdown-menu-toggle[role="button"]' );
10
11			if ( ! subMenu.id ) {
12				var itemId = parentLi.id
13					? parentLi.id
14					: 'menu-item-' + Math.floor( Math.random() * 100000 ); // Just in case our menu item has no ID.
15
16				subMenu.id = itemId + '-sub-menu';
17			}
18
19			// Bail if no button to update
20			if ( ! button ) {
21				button = parentLi.querySelector( 'a[role="button"]' );
22
23				if ( ! button ) {
24					return;
25				}
26			}
27
28			button.setAttribute( 'aria-controls', subMenu.id );
29		} );
30	}
31
32	if ( 'querySelector' in document && 'addEventListener' in window ) {
33		/**
34		 * matches() pollyfil
35		 *
36		 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility
37		 */
38		if ( ! Element.prototype.matches ) {
39			Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
40		}
41
42		/**
43		 * closest() pollyfil
44		 *
45		 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility
46		 * @param {Object} s The element to check.
47		 * @return {Object} The closest object.
48		 */
49		if ( ! Element.prototype.closest ) {
50			Element.prototype.closest = function( s ) {
51				var el = this;
52				var ancestor = this;
53				if ( ! document.documentElement.contains( el ) ) {
54					return null;
55				}
56				do {
57					if ( ancestor.matches( s ) ) {
58						return ancestor;
59					}
60					ancestor = ancestor.parentElement;
61				} while ( ancestor !== null );
62				return null;
63			};
64		}
65
66		var getSiblings = function( elem ) {
67			return Array.prototype.filter.call( elem.parentNode.children, function( sibling ) {
68				return sibling !== elem;
69			} );
70		};
71
72		var allNavToggles = document.querySelectorAll( '.menu-toggle' ),
73			dropdownToggles = document.querySelectorAll( 'nav .dropdown-menu-toggle' ),
74			navLinks = document.querySelectorAll( 'nav .main-nav ul a' ),
75			mobileMenuControls = document.querySelector( '.mobile-menu-control-wrapper' ),
76			body = document.body,
77			htmlEl = document.documentElement,
78			i;
79
80		var enableDropdownArrows = function( nav ) {
81			if ( nav && body.classList.contains( 'dropdown-hover' ) ) {
82				var dropdownItems = nav.querySelectorAll( 'li.menu-item-has-children' );
83
84				for ( i = 0; i < dropdownItems.length; i++ ) {
85					var toggle = dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' );
86					var parentLi = toggle.closest( 'li' );
87					var subMenu = parentLi.querySelector( '.sub-menu, .children' );
88
89					toggle.setAttribute( 'tabindex', '0' );
90					toggle.setAttribute( 'role', 'button' );
91					toggle.setAttribute( 'aria-expanded', 'false' );
92					toggle.setAttribute( 'aria-controls', subMenu.id );
93					toggle.setAttribute( 'aria-label', generatepressMenu.openSubMenuLabel );
94				}
95			}
96		};
97
98		var disableDropdownArrows = function( nav ) {
99			if ( nav && body.classList.contains( 'dropdown-hover' ) ) {
100				var dropdownItems = nav.querySelectorAll( 'li.menu-item-has-children' );
101
102				for ( i = 0; i < dropdownItems.length; i++ ) {
103					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'tabindex' );
104					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).setAttribute( 'role', 'presentation' );
105					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-expanded' );
106					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-controls' );
107					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-label' );
108				}
109			}
110		};
111
112		var setDropdownArrowAttributes = function( arrow ) {
113			if ( 'false' === arrow.getAttribute( 'aria-expanded' ) || ! arrow.getAttribute( 'aria-expanded' ) ) {
114				arrow.setAttribute( 'aria-expanded', 'true' );
115				arrow.setAttribute( 'aria-label', generatepressMenu.closeSubMenuLabel );
116			} else {
117				arrow.setAttribute( 'aria-expanded', 'false' );
118				arrow.setAttribute( 'aria-label', generatepressMenu.openSubMenuLabel );
119			}
120		};
121
122		/**
123		 * Start mobile menu toggle.
124		 *
125		 * @param {Object} e     The event.
126		 * @param {Object} _this The clicked item.
127		 */
128		var toggleNav = function( e, _this ) {
129			if ( ! _this ) {
130				_this = this;
131			}
132
133			var parentContainer = '';
134
135			if ( _this.getAttribute( 'data-nav' ) ) {
136				parentContainer = document.getElementById( _this.getAttribute( 'data-nav' ) );
137			} else {
138				parentContainer = document.getElementById( _this.closest( 'nav' ).getAttribute( 'id' ) );
139			}
140
141			if ( ! parentContainer ) {
142				return;
143			}
144
145			var isExternalToggle = false;
146
147			if ( _this.closest( '.mobile-menu-control-wrapper' ) ) {
148				isExternalToggle = true;
149			}
150
151			var nav = parentContainer.getElementsByTagName( 'ul' )[ 0 ];
152
153			if ( parentContainer.classList.contains( 'toggled' ) ) {
154				parentContainer.classList.remove( 'toggled' );
155				htmlEl.classList.remove( 'mobile-menu-open' );
156
157				if ( nav ) {
158					nav.setAttribute( 'aria-hidden', 'true' );
159				}
160
161				_this.setAttribute( 'aria-expanded', 'false' );
162
163				if ( isExternalToggle ) {
164					mobileMenuControls.classList.remove( 'toggled' );
165				} else if ( mobileMenuControls && parentContainer.classList.contains( 'main-navigation' ) ) {
166					mobileMenuControls.classList.remove( 'toggled' );
167				}
168
169				disableDropdownArrows( nav );
170			} else {
171				parentContainer.classList.add( 'toggled' );
172				htmlEl.classList.add( 'mobile-menu-open' );
173
174				if ( nav ) {
175					nav.setAttribute( 'aria-hidden', 'false' );
176				}
177
178				_this.setAttribute( 'aria-expanded', 'true' );
179
180				if ( isExternalToggle ) {
181					mobileMenuControls.classList.add( 'toggled' );
182
183					if ( mobileMenuControls.querySelector( '.search-item' ) ) {
184						if ( mobileMenuControls.querySelector( '.search-item' ).classList.contains( 'active' ) ) {
185							mobileMenuControls.querySelector( '.search-item' ).click();
186						}
187					}
188				} else if ( mobileMenuControls && parentContainer.classList.contains( 'main-navigation' ) ) {
189					mobileMenuControls.classList.add( 'toggled' );
190				}
191
192				enableDropdownArrows( nav );
193			}
194		};
195
196		for ( i = 0; i < allNavToggles.length; i++ ) {
197			allNavToggles[ i ].addEventListener( 'click', toggleNav, false );
198		}
199
200		/**
201		 * Open sub-menus
202		 *
203		 * @param {Object} e     The event.
204		 * @param {Object} _this The clicked item.
205		 */
206		var toggleSubNav = function( e, _this ) {
207			if ( ! _this ) {
208				_this = this;
209			}
210
211			if ( ( _this.closest( 'nav' ).classList.contains( 'toggled' ) || htmlEl.classList.contains( 'slide-opened' ) ) && ! body.classList.contains( 'dropdown-click' ) ) {
212				e.preventDefault();
213				var closestLi = _this.closest( 'li' );
214
215				setDropdownArrowAttributes( closestLi.querySelector( '.dropdown-menu-toggle' ) );
216
217				if ( closestLi.querySelector( '.sub-menu' ) ) {
218					var subMenu = closestLi.querySelector( '.sub-menu' );
219				} else {
220					subMenu = closestLi.querySelector( '.children' );
221				}
222
223				if ( generatepressMenu.toggleOpenedSubMenus ) {
224					var siblings = getSiblings( closestLi );
225
226					for ( i = 0; i < siblings.length; i++ ) {
227						if ( siblings[ i ].classList.contains( 'sfHover' ) ) {
228							siblings[ i ].classList.remove( 'sfHover' );
229							siblings[ i ].querySelector( '.toggled-on' ).classList.remove( 'toggled-on' );
230							setDropdownArrowAttributes( siblings[ i ].querySelector( '.dropdown-menu-toggle' ) );
231						}
232					}
233				}
234
235				closestLi.classList.toggle( 'sfHover' );
236				subMenu.classList.toggle( 'toggled-on' );
237			}
238
239			e.stopPropagation();
240		};
241
242		for ( i = 0; i < dropdownToggles.length; i++ ) {
243			dropdownToggles[ i ].addEventListener( 'click', toggleSubNav, false );
244			dropdownToggles[ i ].addEventListener( 'keypress', function( e ) {
245				if ( 'Enter' === e.key || ' ' === e.key ) {
246					toggleSubNav( e, this );
247				}
248			}, false );
249		}
250
251		/**
252		 * Disable the mobile menu if our toggle isn't visible.
253		 * Makes it possible to style mobile item with .toggled class.
254		 */
255		var checkMobile = function() {
256			var openedMobileMenus = document.querySelectorAll( '.toggled, .has-active-search' );
257
258			for ( i = 0; i < openedMobileMenus.length; i++ ) {
259				var menuToggle = openedMobileMenus[ i ].querySelector( '.menu-toggle' );
260
261				if ( mobileMenuControls && ! menuToggle.closest( 'nav' ).classList.contains( 'mobile-menu-control-wrapper' ) ) {
262					menuToggle = mobileMenuControls.querySelector( '.menu-toggle' );
263				}
264
265				if ( menuToggle && menuToggle.offsetParent === null ) {
266					if ( openedMobileMenus[ i ].classList.contains( 'toggled' ) ) {
267						var remoteNav = false;
268
269						if ( openedMobileMenus[ i ].classList.contains( 'mobile-menu-control-wrapper' ) ) {
270							remoteNav = true;
271						}
272
273						if ( ! remoteNav ) {
274							// Navigation is toggled, but .menu-toggle isn't visible on the page (display: none).
275							var closestNav = openedMobileMenus[ i ].getElementsByTagName( 'ul' )[ 0 ],
276								closestNavItems = closestNav ? closestNav.getElementsByTagName( 'li' ) : [],
277								closestSubMenus = closestNav ? closestNav.getElementsByTagName( 'ul' ) : [];
278						}
279
280						document.activeElement.blur();
281						openedMobileMenus[ i ].classList.remove( 'toggled' );
282
283						htmlEl.classList.remove( 'mobile-menu-open' );
284						menuToggle.setAttribute( 'aria-expanded', 'false' );
285
286						if ( ! remoteNav ) {
287							for ( var li = 0; li < closestNavItems.length; li++ ) {
288								closestNavItems[ li ].classList.remove( 'sfHover' );
289							}
290
291							for ( var sm = 0; sm < closestSubMenus.length; sm++ ) {
292								closestSubMenus[ sm ].classList.remove( 'toggled-on' );
293							}
294
295							if ( closestNav ) {
296								closestNav.removeAttribute( 'aria-hidden' );
297							}
298						}
299
300						disableDropdownArrows( openedMobileMenus[ i ] );
301					}
302
303					if ( mobileMenuControls.querySelector( '.search-item' ) ) {
304						if ( mobileMenuControls.querySelector( '.search-item' ).classList.contains( 'active' ) ) {
305							mobileMenuControls.querySelector( '.search-item' ).click();
306						}
307					}
308				}
309			}
310		};
311		window.addEventListener( 'resize', checkMobile, false );
312		window.addEventListener( 'orientationchange', checkMobile, false );
313
314		if ( body.classList.contains( 'dropdown-hover' ) ) {
315			/**
316			 * Do some essential things when menu items are clicked.
317			 */
318			for ( i = 0; i < navLinks.length; i++ ) {
319				navLinks[ i ].addEventListener( 'click', function( e ) {
320					// Remove sfHover class if we're going to another site.
321					if ( this.hostname !== window.location.hostname ) {
322						document.activeElement.blur();
323					}
324
325					var closestNav = this.closest( 'nav' );
326					if ( closestNav.classList.contains( 'toggled' ) || htmlEl.classList.contains( 'slide-opened' ) ) {
327						var url = this.getAttribute( 'href' );
328
329						// Open the sub-menu if the link has no destination
330						if ( '#' === url || '' === url ) {
331							e.preventDefault();
332							var closestLi = this.closest( 'li' );
333							closestLi.classList.toggle( 'sfHover' );
334							var subMenu = closestLi.querySelector( '.sub-menu' );
335
336							if ( subMenu ) {
337								subMenu.classList.toggle( 'toggled-on' );
338							}
339						}
340					}
341				}, false );
342			}
343		}
344
345		if ( body.classList.contains( 'dropdown-hover' ) ) {
346			var menuBarItems = document.querySelectorAll( '.menu-bar-items .menu-bar-item > a' );
347
348			/**
349			 * Make menu items tab accessible when using the hover dropdown type
350			 */
351			var toggleFocus = function() {
352				if ( this.closest( 'nav' ).classList.contains( 'toggled' ) || this.closest( 'nav' ).classList.contains( 'slideout-navigation' ) ) {
353					return;
354				}
355
356				var self = this;
357
358				while ( -1 === self.className.indexOf( 'main-nav' ) ) {
359					if ( 'li' === self.tagName.toLowerCase() ) {
360						self.classList.toggle( 'sfHover' );
361					}
362
363					self = self.parentElement;
364				}
365			};
366
367			/**
368			 * Make our menu bar items tab accessible.
369			 */
370			var toggleMenuBarItemFocus = function() {
371				if ( this.closest( 'nav' ).classList.contains( 'toggled' ) || this.closest( 'nav' ).classList.contains( 'slideout-navigation' ) ) {
372					return;
373				}
374
375				var self = this;
376
377				while ( -1 === self.className.indexOf( 'menu-bar-items' ) ) {
378					if ( self.classList.contains( 'menu-bar-item' ) ) {
379						self.classList.toggle( 'sfHover' );
380					}
381
382					self = self.parentElement;
383				}
384			};
385
386			for ( i = 0; i < navLinks.length; i++ ) {
387				navLinks[ i ].addEventListener( 'focus', toggleFocus );
388				navLinks[ i ].addEventListener( 'blur', toggleFocus );
389			}
390
391			for ( i = 0; i < menuBarItems.length; i++ ) {
392				menuBarItems[ i ].addEventListener( 'focus', toggleMenuBarItemFocus );
393				menuBarItems[ i ].addEventListener( 'blur', toggleMenuBarItemFocus );
394			}
395		}
396
397		/**
398		 * Make hover dropdown touch-friendly.
399		 */
400		if ( 'ontouchend' in document.documentElement && document.body.classList.contains( 'dropdown-hover' ) ) {
401			var parentElements = document.querySelectorAll( '.sf-menu .menu-item-has-children' );
402
403			for ( i = 0; i < parentElements.length; i++ ) {
404				parentElements[ i ].addEventListener( 'touchend', function( e ) {
405					// Bail on mobile
406					if ( this.closest( 'nav' ).classList.contains( 'toggled' ) ) {
407						return;
408					}
409
410					if ( e.touches.length === 1 || e.touches.length === 0 ) {
411						// Prevent touch events within dropdown bubbling down to document
412						e.stopPropagation();
413
414						// Toggle hover
415						if ( ! this.classList.contains( 'sfHover' ) ) {
416							// Prevent link on first touch
417							if ( e.target === this || e.target.parentNode === this || e.target.parentNode.parentNode ) {
418								e.preventDefault();
419							}
420
421							// Close other sub-menus.
422							var closestLi = this.closest( 'li' ),
423								siblings = getSiblings( closestLi );
424
425							for ( i = 0; i < siblings.length; i++ ) {
426								if ( siblings[ i ].classList.contains( 'sfHover' ) ) {
427									siblings[ i ].classList.remove( 'sfHover' );
428								}
429							}
430
431							this.classList.add( 'sfHover' );
432
433							// Hide dropdown on touch outside
434							var closeDropdown,
435								thisItem = this;
436
437							document.addEventListener( 'touchend', closeDropdown = function( event ) {
438								event.stopPropagation();
439
440								thisItem.classList.remove( 'sfHover' );
441								document.removeEventListener( 'touchend', closeDropdown );
442							} );
443						}
444					}
445				} );
446			}
447		}
448	}
449}() );

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.