PageSourceSearch

https://winter-project.eu/wp-content/themes/citadela/design/js/menu.js?ver=1697181508

js winter-project.eu collected 2026-10-08 09:09:43 UTC 15,951 bytes, 489 lines download raw bytes

1
2jQuery(document).ready(function(){
3	"use strict";
4	citadelaResponsiveClass();
5	citadelaMainMenuBurgerPrepare();
6	citadelaMainMenuBurger();
7	citadelaResponsiveMenuCloseBtn();
8	citadelaSubmenuManagement();
9	citadelaMainMenuScroll();
10	citadelaTriggers();
11});
12
13/* Window Resize Hook */
14jQuery(window).resize(function(){
15	citadelaResponsiveClass();
16	citadelaMainMenuBurger();
17	citadelaSubmenuManagement();
18	
19});
20
21function citadelaResponsiveClass(){
22	var $body = jQuery( 'body' );
23	if( citadela_isResponsive(600) ){
24		if( ! $body.hasClass('mobile-screen-width') ){
25			$body.addClass('mobile-screen-width');
26			$body.trigger('ctdl_device_design_swap', 'mobile' );
27		}
28	}else{
29		if( $body.hasClass('mobile-screen-width') ){
30			$body.removeClass('mobile-screen-width');
31			$body.trigger('ctdl_device_design_swap', 'desktop');
32		}
33	}
34	$body.find('.site-header.loading').removeClass('loading');
35}
36
37function citadelaTriggers(){
38	jQuery( 'body' ).on( 'ctdl_device_design_swap', function(e, device){
39		citadelaMainMenuScroll();
40	});
41
42}
43
44function citadelaResponsiveMenuCloseBtn() {
45	var $navContainer = jQuery('nav#site-navigation');
46	if( $navContainer.hasClass('no-main-menu') ) return;
47
48	$navContainer.find('.citadela-menu-container').prepend('<span class="responsive-close-button"></span>');
49	var $responsiveCloseButton = $navContainer.find('.responsive-close-button')
50
51	$responsiveCloseButton.on('click', function(e){
52		var $liWrapper = jQuery(this).siblings('ul.citadela-menu').find('li.menu-item-wrapper');
53		citadelaSubmenuClickAction( $liWrapper );
54	});
55
56}
57
58function citadelaMainMenuScroll(){
59	var $header = jQuery('header#masthead');
60	var $sticky_wrapper = jQuery('.sticky-header-wrapper');
61	var withStickyHeader = jQuery('body').hasClass('sticky-header-enabled');
62	var $element = withStickyHeader ? $sticky_wrapper : $header;
63	if( ! $element.length ) return;
64	var $body = jQuery('body');
65	// waypoints are enabled with delay because of wait for css transitions in header elements
66	setTimeout(function(){
67		var waypoint = new Waypoint({
68		  element: $element,
69		  handler: function(direction) {
70		    switch (direction) {
71			  case 'up':
72			    //scrolling from down to up
73			    $body.removeClass('header-scrolled');
74			    citadelaCloseAllTopItemsSubmenus();
75			    citadelaCloseWoocommerceCart();
76			    // do not manipulate with menu in desktop sticky header
77			    if( ! ( ! $body.hasClass( 'mobile-screen-width' ) && $body.hasClass( 'sticky-header-desktop-full' ) ) ){
78				    citadelaMainMenuBurger();
79				    citadelaSubmenuManagement();
80				}
81
82				if( withStickyHeader ){
83					citadelaHideStickyHeader( this.element );
84				}
85			  	break;
86			  case 'down':
87			    //scrolling from up to down
88			    $body.addClass('header-scrolled');
89			    citadelaCloseAllTopItemsSubmenus();
90			    citadelaCloseWoocommerceCart();
91			    
92			    // do not manipulate with menu in desktop sticky header
93			    if( ! ( ! $body.hasClass( 'mobile-screen-width' ) && $body.hasClass( 'sticky-header-desktop-full' ) ) ){
94			    	citadelaMainMenuBurger();
95			    	citadelaSubmenuManagement();
96			    }
97
98			    if( withStickyHeader ){
99			    	citadelaShowStickyHeader( this.element );
100			    }
101
102			  	break;
103			  default:
104			  	return;
105			}
106		  },
107		  offset: function() {
108		  	var offset = 0;
109		  	var $header = null;
110		  	
111		  	if( withStickyHeader ) {
112				$header = this.element.find('#masthead');		  		
113		  	}else{
114				$header	= this.element;
115		  	}
116
117			if( $header.hasClass('is-sticky') ){
118				offset = this.element.outerHeight();
119			}else{
120				offset = $header.outerHeight();
121			}
122
123		  	if( offset != 0 ){
124				$header.attr('data-offset', offset);
125				return -offset;
126		  	}else{
127		  		// if zero offset, return previously defined offset in header
128		  		return -$header.attr('data-offset');
129		  	}
130
131		  }
132		});
133	}, 300 );
134}
135
136function citadelaSubmenuManagement(){
137	
138	var menuArrow = '<span class="submenu-arrow"></span>';
139	var $navContainer = jQuery('nav#site-navigation');
140
141	if( $navContainer.hasClass('no-main-menu') ) return;
142
143	var $mainMenuUl = $navContainer.find('.citadela-menu-container').find('ul.citadela-menu');
144
145	var $menuItemWrapper = $mainMenuUl.children('li.menu-item-wrapper');
146
147	$menuItemWrapper.off();
148	$menuItemWrapper.children('a').off();
149
150	$mainMenuUl.find('li.menu-item-has-children').each(function(){
151		var $li = jQuery(this);
152
153		if( $li.hasClass('top-level-menu-item') ){
154			$li.children('.sub-menu').on('mouseleave', function(){
155				var $submenu = jQuery(this);
156				if( $submenu.parent().hasClass('opened') ) return;
157				$submenu.find('.opened').removeClass('opened');
158				
159			});
160		}
161
162		//close woocommerce when menu is opened on hover
163		$li.on('mouseenter focusin', function(){
164			citadelaCloseWoocommerceCart();
165		});
166
167		// do not apply following events for menu button
168		if( $li.hasClass("menu-item-wrapper") ) return;
169		//create submenu arrows
170		if( ! $li.children('span.submenu-arrow').length ) $li.append(menuArrow);
171		
172		//apply click for submenu arrow
173		$li.children('span.submenu-arrow').off();
174		$li.children('span.submenu-arrow').on('click', function(e){
175			citadelaCloseWoocommerceCart();
176			var $arrow = jQuery(this);
177			var $clickedLi = $arrow.parent('li');
178			citadelaSubmenuClickAction( $clickedLi );
179		});
180
181		//apply click for custom menu item with empty link or link to #
182		if($li.hasClass('menu-item-type-custom')){
183			var $a = $li.children('a');
184			if(!$a.attr('href') || $a.attr('href') == '#'){
185				$a.off();
186				$a.on('click', function(e){
187					e.preventDefault();
188					var $clickedLi = $a.parent('li');
189					citadelaSubmenuClickAction( $clickedLi );
190				});
191				
192			}
193		}
194	});
195	
196	var isResponsiveMenu = jQuery('body').hasClass('mobile-screen-width') || citadelaResponsiveMenuOnDesktop();
197
198	if( isResponsiveMenu ){
199		//apply events in responsive menu
200		$menuItemWrapper.children('a').on( 'click', function(e){
201			e.preventDefault();
202		});
203		$menuItemWrapper.children('a').on( 'mousedown', function(e){
204			citadelaSubmenuClickAction( jQuery(this).parent('li') );
205		});
206		$menuItemWrapper.focusin(function(){
207			jQuery('body').addClass('menu-opened');
208			citadelaCloseWoocommerceCart();
209		});
210		$menuItemWrapper.focusout(function(){
211			if( jQuery(this).hasClass('opened') ) return;
212			jQuery('body').removeClass('menu-opened');
213		});
214	}else{
215		$menuItemWrapper.children('a').on( 'click', function(e){
216			e.preventDefault();
217			citadelaSubmenuClickAction( jQuery(this).parent('li') );
218		})
219		
220	}
221
222
223}
224
225
226function citadelaSubmenuClickAction( $li ){
227	var $clickedLi = $li,
228		$body = jQuery('body');
229
230	if($clickedLi.hasClass('opened')){
231
232		if( $clickedLi.hasClass("menu-item-wrapper") || $clickedLi.hasClass("menu-item-type-custom") ){
233			//remove focus after click on opened wrapper menu
234			$clickedLi.children('a').blur();
235		}
236
237		$clickedLi.removeClass('opened');
238		$clickedLi.children('ul.sub-menu').removeClass('opened');
239		//close all child nodes
240		$clickedLi.find('li.opened').removeClass('opened');
241		$clickedLi.find('ul.sub-menu.opened').removeClass('opened');
242
243		//body class for opened responsive menu
244		if( $clickedLi.hasClass('menu-item-wrapper') && $body.hasClass('responsive-menu') ){
245			$body.removeClass('menu-opened');
246		}
247	}else{
248		citadelaCloseWoocommerceCart();
249		citadelaCloseAllSiblingTopLevelItems( $clickedLi );
250		$clickedLi.addClass('opened');
251		$clickedLi.children('ul.sub-menu').addClass('opened');
252
253		//body class for opened responsive menu
254		if( $clickedLi.hasClass('menu-item-wrapper') && $body.hasClass('responsive-menu') ){
255			$body.addClass('menu-opened');
256		}
257	}
258
259}
260	
261function citadelaCloseAllSiblingTopLevelItems( $li ){
262	var $clickedLi = $li;
263	var $sibling;
264	$clickedLi.siblings('.top-level-menu-item.opened').each(function(){
265		$sibling = jQuery(this);
266		$sibling.removeClass('opened');
267		$sibling.find('li.opened').removeClass('opened');
268	});
269}
270
271function citadelaGetMenuAdditions(){
272	//selectors of parts displayed in navigation place
273	return [ 
274		'.citadela-woocommerce-minicart' 
275	];
276}
277
278function citadelaGetMenuAvailableWidth(){
279	var $container = jQuery('nav#site-navigation');
280	var $burgerMenuWrapper = $container.find('li.menu-item-wrapper');
281	var headerAdditions = citadelaGetMenuAdditions();
282
283	if( jQuery('body').hasClass('center-header-layout') && ! $container.parents('#masthead').hasClass('is-sticky') ){
284		$container = $container.find('ul.citadela-menu');
285		headerAdditions = [];
286	}
287	
288	var availableWidth = $container.width() - 20;
289
290	jQuery.each( headerAdditions , function( $key, $value ){
291		if( jQuery( $value ).length ){
292			var w = Math.ceil( jQuery( $value ).outerWidth(true) );
293			availableWidth = availableWidth - w;
294		}
295	});
296
297	return Math.floor( availableWidth );
298}
299
300function citadelaMainMenuBurgerPrepare(){
301	var $navContainer = jQuery('nav#site-navigation');
302	if( $navContainer.hasClass('no-main-menu') ) return;
303
304	// menu items widths
305	var $menuContainer = $navContainer.find('ul.citadela-menu');
306	var widthLiAll = 0,
307		widthLi = 0;
308	$menuContainer.children('li').each(function(pos){
309		jQuery(this).addClass('menu-item-position-' + pos);
310		if( ! jQuery('body').hasClass('mobile-screen-width') ){
311			//calculate sizes only for desktop design, in responsive design is li size = 0
312			widthLi = Math.ceil( jQuery(this).outerWidth(true) );
313			jQuery(this).attr('data-width', widthLi);
314			widthLiAll += widthLi;
315		}
316	});
317	$menuContainer.attr('data-liWidth', widthLiAll);
318
319	// append burger li .. burger is always created
320	var hamburgerHtml = '<i class="fa fa-bars"></i>';
321	$menuContainer.append('<li class="menu-item-wrapper menu-item-has-children sub-menu-right-position top-level-menu-item"><a href="#">' + hamburgerHtml + '</a><ul class="sub-menu"></ul></li>');
322	var $burgerMenuWrapper = $menuContainer.find('li.menu-item-wrapper');
323	var $burgerMenuContainer = $burgerMenuWrapper.find('.sub-menu');
324	
325	// fill up burger menu with data
326	var $menuContainerChildren = $menuContainer.children('li:not(.menu-item-wrapper)').clone(true);
327	$menuContainerChildren.appendTo($burgerMenuContainer);
328	
329	$burgerMenuWrapper.find('li').each(function(){
330		jQuery(this).addClass('menu-item-cloned');
331	});
332	
333	// add new classes
334	$burgerMenuContainer.find('li').each(function(){
335		if(jQuery(this).children('ul').length > 0){
336			jQuery(this).addClass('menu-item-has-children');
337		}
338	});
339
340	var burgerMenuItemWidth = $burgerMenuWrapper.outerWidth();
341	
342	var availableWidth = citadelaGetMenuAvailableWidth();
343
344	$navContainer.attr('data-availablespace', availableWidth );
345	$navContainer.attr('data-burgerspace', burgerMenuItemWidth);
346	
347	availableWidth = availableWidth - burgerMenuItemWidth;	
348
349	// will the burger be shown by default
350	if(availableWidth < widthLiAll){
351		$burgerMenuWrapper.css({'display': 'inline-block'});
352	} else {
353		$burgerMenuWrapper.css({'display': 'none'});
354	}
355
356	// reset all styles added by script
357	$navContainer.removeClass('menu-hidden');
358}
359
360function citadelaMainMenuBurger(){
361	var $navContainer = jQuery('nav#site-navigation');
362	
363
364	var $menuContainer = $navContainer.find('.citadela-menu');
365	if( ! citadelaResponsiveMenuOnDesktop() && ! jQuery('body').hasClass('mobile-screen-width') ) {
366		//desktop design
367		//remove body class for responsive menu
368		jQuery('body').removeClass('responsive-menu menu-opened');
369		
370		//do not continue if there is no menu defined
371		if( $navContainer.hasClass('no-main-menu') ) return;
372		
373		citadelaCloseAllTopItemsSubmenus();
374		
375		// calculate real size of menu li items after screen change
376		// necessary after move from responsive to desktop design
377		var widthLiAll = 0,
378			widthLi = 0;
379		$menuContainer.children('li:not(.menu-item-wrapper)').each(function(pos){
380			widthLi = Math.ceil( jQuery(this).outerWidth(true) );
381			jQuery(this).attr('data-width', widthLi);
382			widthLiAll += widthLi;
383		});
384		$menuContainer.attr('data-liWidth', widthLiAll);
385		
386		// update available space
387		var headerAdditions = citadelaGetMenuAdditions();
388		var widthNav = $navContainer.width();
389		var availableSpace = widthNav;
390		jQuery.each( headerAdditions , function($key, $value ){
391			var w = jQuery( $value ).outerWidth(true);
392			availableSpace = availableSpace - w;
393		});
394		var $wooCart = jQuery('.citadela-woocommerce-minicart');
395
396
397		var availableWidth = citadelaGetMenuAvailableWidth();
398
399		$navContainer.attr('data-availablespace', availableWidth );
400
401		var $burgerMenuWrapper = $menuContainer.find('li.menu-item-wrapper');
402		
403		$burgerMenuWrapper.show();
404
405		var burgerMenuItemWidth;
406		burgerMenuItemWidth = parseInt($navContainer.attr('data-burgerspace'));
407		
408		availableWidth = availableWidth - burgerMenuItemWidth;
409		
410		if(parseInt($menuContainer.attr('data-liWidth')) > availableWidth ){
411			// the menu is bigger than available width in menu container
412			var fittingWidth = availableWidth;
413			$menuContainer.children('li:not(.menu-item-wrapper)').each(function(pos){
414				// for every li, get his width and try to fit it
415				var liWidth = parseInt(jQuery(this).attr('data-width')) == 0 ? Math.ceil( jQuery(this).outerWidth(true) ) : parseInt(jQuery(this).attr('data-width'));
416				fittingWidth = parseInt(fittingWidth - liWidth);
417				if(fittingWidth > 0){
418					// no problem .. li fits
419					jQuery(this).show().css('white-space', '');;
420					jQuery(this).addClass('top-level-menu-item');
421					// hide in the wrapmenu
422					$menuContainer.find('.menu-item-cloned.menu-item-position-' + pos).hide().removeClass('opened');
423				} else {
424					// problem .. li doesnt fit
425					jQuery(this).hide().css('white-space', 'nowrap');
426					jQuery(this).removeClass('top-level-menu-item opened');
427					// show in the wrapmenu
428					$menuContainer.find('.menu-item-cloned.menu-item-position-' + pos).show();
429				}
430			});
431			$menuContainer.find('.menu-item-wrapper').css({'display': 'inline-block'});
432		} else {
433			var fittingWidth = availableWidth;
434			$menuContainer.children('li:not(.menu-item-wrapper)').each(function(pos){
435				var liWidth = parseInt(jQuery(this).attr('data-width')) == 0 ? jQuery(this).width() : parseInt(jQuery(this).attr('data-width'));
436				fittingWidth = parseInt(fittingWidth - liWidth);
437				if(fittingWidth > 0){
438					// no problem .. li fits
439					jQuery(this).show();
440					jQuery(this).addClass('top-level-menu-item');
441					// hide in the wrapmenu
442					$menuContainer.find('.menu-item-cloned.menu-item-position-' + pos).hide();
443				}
444			});
445			// hide wrapping menu
446			$menuContainer.find('.menu-item-wrapper').css({'display': 'none'});
447		}
448
449	}else{
450		//responsive design
451		//add body class for responsive menu
452		jQuery('body').addClass('responsive-menu');
453
454		//do not continue if there is no menu defined
455		if( $navContainer.hasClass('no-main-menu') ) return;
456
457		$menuContainer.attr('data-liWidth', 0);
458		$menuContainer.find('.menu-item-wrapper').css({'display': 'inline-block'});
459		$menuContainer.children('li:not(.menu-item-wrapper)').each(function(pos){
460			jQuery(this).hide().css('white-space', 'nowrap');
461			$menuContainer.find('.menu-item-cloned.menu-item-position-' + pos).show();
462		});
463	}
464}
465
466function citadelaCloseAllTopItemsSubmenus(){
467	$mainMenuUl = jQuery('#masthead').find('.citadela-menu-container').find('ul.citadela-menu');
468	$mainMenuUl.find('li.top-level-menu-item.opened').each(function(){
469		jQuery(this).removeClass('opened');
470		
471		// make sure that :focus-within from menu wrapper is removed too,
472		// prevent problem with focused dropdown and page scroll down what cause immediate responsive menu opening in some cases
473		if( jQuery(this).hasClass('menu-item-wrapper') && jQuery(document.activeElement).parent().hasClass('menu-item-wrapper') ){
474			document.activeElement.blur();
475		}
476	});
477}
478
479function citadelaCloseWoocommerceCart(){
480	$cart = jQuery('#masthead').find('.citadela-woocommerce-minicart');
481	if( ! $cart.length ) return;
482
483	$cart.removeClass('opened');
484	jQuery('body').removeClass('cart-opened');
485}
486
487function citadelaResponsiveMenuOnDesktop() {
488	return jQuery('body').hasClass('responsive-menu-on-desktop') || ( jQuery('body').hasClass('sticky-header-desktop-burger') && jQuery('body').hasClass('header-scrolled') );
489}

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.