PageSourceSearch

https://www.kalporz.com/wp-content/plugins/trx_addons/components/cpt/layouts/shortcodes/menu/menu.js

js kalporz.com collected 2026-09-24 21:34:20 UTC 21,187 bytes, 584 lines download raw bytes

1/* global jQuery */
2
3( function() {
4	"use strict";
5
6	var $document = jQuery(document);
7
8	$document.on( 'action.before_ready_trx_addons', function() {
9
10		// Init Superfish menu - global declaration to use in other scripts
11		window.trx_addons_init_sfmenu = function( selector ) {
12
13			jQuery( selector ).show().each( function() {
14
15				var $self = jQuery( this );
16
17				var is_touch_device = ( 'ontouchstart' in document.documentElement );
18
19				var animation_in = $self.parent().data( 'animation-in' );
20				if ( animation_in == undefined || is_touch_device ) {
21					animation_in = "none";
22				}
23				var animation_out = $self.parent().data( 'animation-out' );
24				if ( animation_out == undefined || is_touch_device ) {
25					animation_out = "none";
26				}
27
28				var sf_init = {
29
30					delay:		300,
31					speed: 		animation_in  != 'none' ? 500 : 200,
32					speedOut:	animation_out != 'none' ? 300 : 200,
33					autoArrows: false,
34					dropShadows:false,
35
36					onBeforeShow: function() {
37						jQuery( this ).each( function() {
38							var menu_item = jQuery( this ).data( 'menu-state', 'before-show' );
39							if ( menu_item.hasClass('sc_layouts_submenu') && ! menu_item.hasClass('layouts_inited') && menu_item.find('.slider_container').length > 0 ) {
40								menu_item.addClass('sc_layouts_submenu_prepare');
41							} else {
42								trx_addons_do_action( 'trx_addons_action_menu_on_before_show', menu_item );
43								trx_addons_before_show_menu(menu_item);
44							}
45						} );
46					},
47
48					onShow: function() {
49						jQuery( this ).each( function() {
50							var menu_item = jQuery( this );
51							if ( menu_item.data( 'menu-state' ) != 'before-show' ) {
52								trx_addons_do_action( 'trx_addons_action_menu_on_show', menu_item );
53								trx_addons_before_show_menu(menu_item);
54							}
55							menu_item.data('menu-state', 'show');
56							trx_addons_do_action( 'trx_addons_action_menu_after_show', menu_item );
57							trx_addons_after_show_menu(menu_item);
58
59						} );
60					},
61
62					onBeforeHide: function() {
63						jQuery( this ).each( function() {
64							var menu_item = jQuery( this );
65							if ( menu_item.data( 'menu-state' ) == 'show' ) {
66								menu_item.data('menu-state', 'before-hide');
67								trx_addons_do_action( 'trx_addons_action_menu_on_before_hide', menu_item );
68								trx_addons_before_hide_menu(menu_item);
69							}
70						} );
71					},
72
73					onHide: function() {
74						jQuery(this).each( function() {
75							var menu_item = jQuery( this ).data('menu-state', 'hide');
76							trx_addons_do_action( 'trx_addons_action_menu_on_hide', menu_item );
77							trx_addons_after_hide_menu(menu_item);
78						} );
79					},
80
81					onHandleTouch: function() {
82						// Hack for iPad - disallow hide parents submenus on open nested level to prevent blink effect
83						var $ul = jQuery( this ).parents('ul');
84						if ( trx_addons_browser_is_ios() && $ul.length > 1 ) {
85							$ul.addClass('sc_layouts_submenu_freeze');
86							setTimeout( function() {
87								$ul.removeClass('sc_layouts_submenu_freeze');
88							}, 1000 );
89						}
90					}
91				};
92
93				if ( animation_in == 'none' ) {
94					sf_init.animation = {
95						opacity: 'show'
96					};
97				}
98				if ( animation_out == 'none' ) {
99					sf_init.animationOut = {
100						opacity: 'hide'
101					};
102				}
103
104				// Prevent close a submenu with layout '.sc_layouts_submenu' after click on any element with tabindex (can got focus)
105				// and next click on the empty place inside the submenu layout.
106				$self.find( '.sc_layouts_submenu_wrap' ).on( 'focusout', function( e ) {
107					if ( e.currentTarget && jQuery( e.currentTarget ).hasClass( 'sc_layouts_submenu_wrap' ) ) {
108						e.stopPropagation();
109						return false;
110					}
111				} );
112
113				// Init SuperFish
114				$self.addClass('inited').superfish( trx_addons_apply_filters( 'trx_addons_filter_menu_init_args', sf_init ) );
115
116				// Before show submenu
117				function trx_addons_before_show_menu(menu_item) {
118					// Disable show submenus in the vertical menu on the mobile screen
119					//if (jQuery(window).width() < 768 && menu_item.parents(".sc_layouts_menu_dir_vertical").length > 0)
120					//	return false;
121
122					var in_columns = menu_item.parents('li[class*="columns-"]').length > 0
123										&& ( ! menu_item.parent().attr('class')
124											|| menu_item.parent().attr('class').indexOf('columns-') == -1
125											);
126
127					if ( ! in_columns ) {
128
129						var window_width = jQuery(window).width(),
130							page_wrap = jQuery(trx_addons_apply_filters( 'trx_addons_filter_page_wrap_class', TRX_ADDONS_STORAGE['page_wrap_class'] ? TRX_ADDONS_STORAGE['page_wrap_class'] : '.page_wrap', 'menu-before-show' )).eq(0),
131							page_wrap_width = page_wrap.length > 0 ? page_wrap.width() : window_width,
132							page_wrap_offset = page_wrap.length > 0 ? page_wrap.offset().left : 0,
133							par = menu_item.parents("ul").eq(0),
134							par_offset = par.length > 0 ? par.offset().left : 0,
135							par_width  = par.length > 0 ? par.outerWidth() : 0,
136							ul_width   = menu_item.outerWidth(),
137							rtl = jQuery( 'body' ).hasClass( 'rtl' );
138
139						// Detect horizontal position (left | right)
140						if ( menu_item.parents("ul").length > 1 ) {
141							if ( ( ! rtl && (
142											( par_offset + par_width + ul_width > page_wrap_offset + page_wrap_width - 10 && par_offset - ul_width > page_wrap_offset )
143											||
144											( par_offset + par_width + ul_width > window_width && par_offset - ul_width > 0 )
145											)
146									)
147								||
148								( rtl && (
149											( par_offset - ul_width < page_wrap_offset + 10 && par_offset + par_width + ul_width < page_wrap_offset + page_wrap_width )
150											||
151											( par_offset - ul_width < 0 && par_offset + par_width + ul_width < window_width )
152										)
153									)
154							) {
155								menu_item.addClass('submenu_left');
156							} else {
157								menu_item.removeClass('submenu_left');
158							}
159						}
160
161						// Shift submenu in the main menu (if submenu is going out of the window)
162						if (menu_item.parents('.top_panel').length > 0) {
163							// Stretch submenu
164							var wide = trx_addons_stretch_submenu(menu_item);
165
166							// Shift horizontal
167							if ( ! wide ) {
168								var ul_pos = menu_item.data('ul_pos'),
169									// submenu_left = menu_item.hasClass('submenu_left');
170									submenu_left = ( menu_item.hasClass('submenu_left') && ! rtl ) || ( ! menu_item.hasClass('submenu_left') && rtl );
171								if (ul_pos === undefined) {
172									ul_pos = parseFloat( menu_item.css( submenu_left ? 'right' : 'left' ) );
173								}
174								if ( isNaN(ul_pos) ) {
175									ul_pos = 0;
176								}
177								var ul_offset = menu_item.parents("ul").length > 1
178													? par_offset + ul_pos	// menu_item.offset().left
179													: menu_item.parent().offset().left;
180								if ( submenu_left ) {
181									if (ul_offset < 0) {
182										if (menu_item.data('ul_pos') == undefined) {
183											menu_item.data('ul_pos', ul_pos);
184										}
185										menu_item.css( {
186											'right': ul_pos + ul_offset + 'px'
187										} );
188									}
189								} else {
190									if (ul_offset + ul_width >= window_width) {
191										if (menu_item.data('ul_pos') == undefined) {
192											menu_item.data('ul_pos', ul_pos);
193										}
194										menu_item.css( {
195											'left': ( ul_pos - ( ul_offset + ul_width - window_width ) ) + 'px'
196										} );
197									}
198								}
199
200								// Shift vertical
201								var ul_height = menu_item.outerHeight(),
202									w_height = jQuery(window).height(),
203									menu = menu_item.parents('.sc_layouts_menu').eq(0),
204									row_offset = menu.length ? menu.offset().top - jQuery(window).scrollTop() : 0,
205									row_height = 0,
206									par_top = 0;
207								par = menu_item.parent();
208								par_offset = 0;
209								while ( par.length > 0 ) {
210									par_top = par.position().top;
211									par_offset += par_top + par.parent().position().top;
212									row_height = par.outerHeight();
213									if (par_top === 0) break;
214									par = par.parents('li').eq(0);
215								}
216								if (row_offset + par_offset + ul_height > w_height) {
217									if (par_offset > ul_height) {
218										menu_item.css( {
219											'top': 'auto',
220											'bottom': '-' + ( menu_item.css('padding-bottom') || 0 )
221										} );
222									} else {
223										menu_item.css( {
224											'top': '-' + ( par_offset - row_height - 2 ) + 'px',
225											'bottom': 'auto'
226										} );
227									}
228								}
229							}
230						}
231
232						// Animation in
233						var animated = false;
234						trx_addons_do_action( 'trx_addons_action_menu_before_animation_in', menu_item, animation_in, animation_out );								
235						if ( animation_in != 'none' ) {	// && ! menu_item.hasClass('sc_layouts_submenu_freeze')) {
236							// To allow theme make own animation - filter handler must return true
237							animated = trx_addons_apply_filters( 'trx_addons_filter_menu_animation_in', false, menu_item, animation_in, animation_out );
238							if ( ! animated ) {
239								if ( menu_item.hasClass('animated') && menu_item.hasClass(animation_out) ) {
240									menu_item.removeClass('animated faster '+animation_out);
241								}
242								menu_item.addClass('animated fast '+animation_in);
243								animated = true;
244							}
245						}
246
247						// Trigger action
248						$document.trigger('action.before_show_submenu', [menu_item] );
249					}
250
251					return animated;
252				}
253
254				// After show submenu
255				function trx_addons_after_show_menu(menu_item) {
256
257					// Init layouts
258					if ( menu_item.hasClass('sc_layouts_submenu') ) {
259						if ( ! menu_item.hasClass('layouts_inited') ) {
260							trx_addons_stretch_submenu(menu_item);
261							$document.trigger( 'action.init_hidden_elements', [menu_item] );
262							if (menu_item.find('.slider_container').length > 0) {
263								$document.on('action.slider_inited', function(e, slider, id) {
264									trx_addons_before_show_menu(menu_item);
265									menu_item
266										.removeClass('sc_layouts_submenu_prepare')
267										.addClass('layouts_inited');
268								});
269							} else {
270								menu_item.addClass('layouts_inited');
271							}
272						}
273						// Trigger 'resize' action
274						$document.trigger('action.resize_trx_addons', [menu_item]);
275					}
276
277					// Trigger action
278					$document.trigger('action.after_show_submenu', [menu_item] );
279				}
280
281				// Before hide submenu
282				function trx_addons_before_hide_menu(menu_item) {
283					// Remove video
284					menu_item.find('.trx_addons_video_player.with_cover.video_play').removeClass('video_play').find('.video_embed').empty();
285					
286					// Disable show submenus in the vertival menu on the mobile screen
287					//if (jQuery(window).width() < 768 && menu_item.parents(".sc_layouts_menu_dir_vertical").length > 0)
288					//	return false;
289					
290					// Animation out
291					var animated = false;
292					trx_addons_do_action( 'trx_addons_action_menu_before_animation_out', menu_item, animation_in, animation_out );								
293					if ( animation_out!='none' ) {	// && ! menu_item.hasClass('sc_layouts_submenu_freeze') ) {
294						// To allow theme make own animation - filter handler must return true
295						animated = trx_addons_apply_filters( 'trx_addons_filter_menu_animation_out', false, menu_item, animation_in, animation_out );
296						if ( ! animated ) {
297							if (menu_item.parents('[class*="columns-"]').length === 0 ) {
298								if ( menu_item.hasClass('animated') && menu_item.hasClass(animation_in) ) {
299									menu_item.removeClass('animated fast '+animation_in);
300								}
301								if ( menu_item.data('menu-state') == 'show' || menu_item.data('menu-state') == 'before-hide' ) {
302									menu_item.addClass('animated faster '+animation_out);
303									animated = true;
304								}
305							}
306						}
307					}
308
309					// Trigger action
310					$document.trigger('action.before_hide_submenu', [menu_item] );
311
312					return animated;
313				}
314
315				// After hide submenu
316				function trx_addons_after_hide_menu(menu_item) {
317					// Restore submenu position after 0.5s (if hidden)
318					setTimeout( function() {
319						if ( menu_item.data('menu-state') == 'hide' ) {
320							// Menu: Delete styles that are set programmatically
321							menu_item.removeAttr( 'style' );
322							// Menu bg: Delete styles that are set programmatically
323							//          and restore background color
324							var bg = menu_item.find('> .sc_layouts_menu_stretch_bg');
325							if ( bg.length ) {
326								bg.removeAttr( 'style' )		
327									.css( {
328										'background-color': menu_item.css('background-color')
329									} );
330							}
331							// Inner container: Delete styles that are set programmatically
332							var container = menu_item.data( 'reset-style' );
333							if ( container ) {
334								menu_item.find( container ).removeAttr( 'style' );
335							}
336							// Trigger action
337							$document.trigger('action.after_hide_submenu', [menu_item] );
338						}
339					}, 500 );
340				}
341			} );
342		};
343
344		// Init superfish menus
345//		trx_addons_init_sfmenu('.sc_layouts_menu:not(.inited):not(.sc_layouts_menu_dir_vertical.sc_layouts_submenu_dropdown) > ul:not(.inited)');
346		trx_addons_init_sfmenu('.sc_layouts_menu:not(.inited):not(.sc_layouts_submenu_dropdown) > ul:not(.inited)');
347
348		// Check if menu need collapse (before menu showed)
349		trx_addons_menu_collapse();
350
351		// Show menu		
352		jQuery('.sc_layouts_menu:not(.inited)').each(function() {
353			if (jQuery(this).find('>ul.inited').length == 1) jQuery(this).addClass('inited');
354		});
355	
356		// Slide effect for menu
357		jQuery('.menu_hover_slide_line:not(.slide_inited),.menu_hover_slide_box:not(.slide_inited)').each(function() {
358			var menu = jQuery(this).addClass('slide_inited');
359			var style = menu.hasClass('menu_hover_slide_line') ? 'line' : 'box';
360			setTimeout(function() {
361				if (jQuery.fn.spasticNav !== undefined) {
362					menu.find('>ul').spasticNav({
363						style: style,
364						//color: '',
365						colorOverride: false
366					});
367				}
368			}, 500);
369		});
370	
371		// Burger with popup
372		jQuery('.sc_layouts_menu_mobile_button_burger:not(.inited)').each(function() {
373			var burger = jQuery(this);
374			var popup = burger.find('.sc_layouts_menu_popup');
375			if (popup.length == 1) {
376				burger.addClass('inited').on('click', '>a', function(e) {
377					popup.toggleClass('opened').slideToggle();
378					e.preventDefault();
379					return false;
380				});
381				popup.on('click', 'a', function(e) {
382					var $item = jQuery(this);
383					if ( $item.next().hasClass('sub-menu') ) {
384						$item.parent().siblings().find( '>.sub-menu' ).fadeOut();
385						$item.next().fadeToggle();
386						e.preventDefault();
387						return false;
388					}
389				});
390				$document.on('click', function(e) {
391					jQuery('.sc_layouts_menu_popup.opened').removeClass('opened').slideUp();
392				});
393			}
394		});
395	
396	});
397	
398
399	// Collapse menu on resize
400	$document.on('action.resize_trx_addons', function() {
401		trx_addons_menu_collapse();
402	});
403	
404	// Collapse menu items
405	function trx_addons_menu_collapse() {
406		if ( TRX_ADDONS_STORAGE['menu_collapse'] == 0 ) {
407			return;
408		}
409		jQuery('.sc_layouts_menu:not(.sc_layouts_menu_no_collapse):not(.sc_layouts_menu_dir_vertical)').each( function() {
410			var nav = jQuery( this );
411			if ( nav.parents('div:hidden,section:hidden,article:hidden').length > 0 ) {
412				return;
413			}
414			var ul = nav.find( '>ul:not(.sc_layouts_menu_no_collapse).inited' );
415			if ( ul.length === 0 ) {		//|| ul.find('> li').length < 2
416				return;
417			}
418			// Check if an item is a one of supported menu wrappers
419			function check_menu_wrapper( item ) {
420				var allow_any_wrapper = trx_addons_apply_filters( 'trx_addons_filter_menu_collapse_allow_any_wrapper', true );
421				var rez = allow_any_wrapper;
422				// Check for supported wrapper
423				if ( ! allow_any_wrapper ) {
424					var wrappers_list = trx_addons_apply_filters(
425											'trx_addons_filter_menu_collapse_wrapper_classes',
426											[
427												'sc_layouts_column',		// Hardcoded column
428												'wpb_wrapper',				// VC column
429												'elementor-widget-wrap',	// Elementor widget wrapper
430												'e-con',					// Elementor container
431												'e-con-inner',				// Elementor container inner
432												'wp-block-column',			// Gutenberg column
433												'kt-inside-inner-col'		// Kadence blocks column
434											]
435										);
436					for (var i = 0; i < wrappers_list.length; i++ ){
437						if ( item.hasClass( wrappers_list[i] ) ) {
438							rez = true;
439							break;
440						}
441					}
442				}
443				return rez;
444			}
445			// Check if an item is a one of allowed delimiters
446			function check_item_delimiter( item ) {
447				var delimiters_list = trx_addons_apply_filters(
448											'trx_addons_filter_menu_collapse_delimiter_classes',
449											[
450												'vc_empty_space',					// VC Spacer
451												'vc_separator',						// VC Separator
452												'elementor-widget-spacer',			// Elementor Spacer
453												'elementor-widget-divider',			// Elementor Divider
454												'wp-block-spacer',					// Gutenberg Spacer
455												'wp-block-separator',				// Gutenberg Separator
456												'wp-block-kadence-spacer',			// Kadence Spacer
457												'wp-block-coblocks-shape-divider'	// CoBlocks Divider
458											]
459										);
460				var rez = false;
461				for (var i = 0; i < delimiters_list.length; i++ ){
462					if ( item.hasClass( delimiters_list[i] ) ) {
463						rez = true;
464						break;
465					}
466				}
467				return rez;
468			}
469			var sc_layouts_item_wrapper = nav.parents('.sc_layouts_item').eq(0),
470				sc_layouts_item = sc_layouts_item_wrapper.length > 0 ? sc_layouts_item_wrapper : nav,
471				sc_layouts_item_parent = sc_layouts_item.parent();
472			if ( ! check_menu_wrapper( sc_layouts_item_parent ) ) {
473				return;
474			}
475			// Calculate max free space for menu
476			var w_max = sc_layouts_item_parent.width()
477						- ( Math.ceil( parseFloat( sc_layouts_item.css('marginLeft') ) ) + Math.
477ceil( parseFloat( sc_layouts_item.css('marginRight') ) ) )
478						- 2;	// Leave additional 2px empty
479			var w_siblings = 0, in_group = 0, ul_id = ul.attr('id');
480			sc_layouts_item_parent.find( '>div' + ( sc_layouts_item_parent.attr( 'class' ).indexOf( 'elementor-' ) >= 0 ? '.elementor-element' : '' ) ).each( function() {
481				if ( in_group > 1 ) {
482					return;
483				}
484				var $self = jQuery(this);
485				if ( check_item_delimiter( $self ) ) {
486					if ( in_group == 1 ) {
487						in_group = 2;
488					} else {
489						w_siblings = 0;
490					}
491				} else {
492					if ( $self.find( '#' + ul_id ).length > 0 ) {
493						in_group = 1;
494					} else {
495						w_siblings += ( $self.outerWidth() + Math.ceil(parseFloat( $self.css('marginLeft') ) ) + Math.ceil( parseFloat( $self.css('marginRight') ) ) );
496					}
497				}
498			});
499			w_max -= w_siblings;
500			// Add collapse item if not exists
501			var w_all = 0;
502			var move = false;
503			var li_collapse = ul.find('li.menu-item.menu-collapse');
504			if ( li_collapse.length === 0 ) {
505				ul.append('<li class="menu-item menu-collapse"><a href="#" class="sf-with-ul '+TRX_ADDONS_STORAGE['menu_collapse_icon']+'"></a><ul class="submenu"></ul></li>');
506				li_collapse = ul.find('li.menu-item.menu-collapse');
507			}
508			var li_collapse_ul = li_collapse.find('> ul');
509			// Check if need to move items
510			ul.find('> li').each( function( idx ) {
511				var cur_item = jQuery( this );
512				cur_item.data( 'index', idx );
513				if ( move || cur_item.attr('id') == 'blob' ) {
514					return;
515				}
516				w_all += ! cur_item.hasClass('menu-collapse') || cur_item.css('display') != 'none' 
517							? cur_item.outerWidth()
518								+ Math.ceil( parseFloat( cur_item.css( 'marginLeft' ) ) )
519								+ Math.ceil( parseFloat( cur_item.css( 'marginRight' ) ) )
520							: 0;
521				if ( w_all > w_max ) {
522					move = true;
523				}
524			} );
525			// If need to move items to the collapsed item
526			if ( move ) {
527				w_all = li_collapse.outerWidth()
528							+ Math.ceil( parseFloat( li_collapse.css( 'marginLeft' ) ) )
529							+ Math.ceil( parseFloat( li_collapse.css( 'marginRight' ) ) );
530				ul.find( "> li:not('.menu-collapse')" ).each( function( idx ) {
531					var cur_item = jQuery( this );
532					var cur_width = cur_item.outerWidth()
533										+ Math.ceil( parseFloat( cur_item.css( 'marginLeft' ) ) )
534										+ Math.ceil( parseFloat( cur_item.css( 'marginRight' ) ) );
535					if ( w_all <= w_max ) {
536						w_all += cur_width;
537					}
538					if ( w_all > w_max ) {
539						var moved = false;
540						li_collapse_ul.find( '>li' ).each( function() {
541							if ( ! moved && Number( jQuery( this ).data( 'index' ) ) > idx ) {
542								cur_item.attr( 'data-width', cur_width ).insertBefore( jQuery( this ) );
543								moved = true;
544							}
545						} );
546						if ( ! moved ) {
547							cur_item.attr( 'data-width', cur_width ).appendTo( li_collapse_ul );
548						}
549					}
550				} );
551				li_collapse.show();
552				
553			// Else - move items to the menu again
554			} else {
555				var items = li_collapse_ul.find( '>li' );
556				var cnt = 0;
557				move = true;
558				//w_all += 20; 	// Leave 20px empty
559				items.each( function() {
560					if ( ! move ) {
561						return;
562					}
563					if ( items.length - cnt == 1 ) {
564						w_all -= ( li_collapse.outerWidth()
565									+ Math.ceil( parseFloat( li_collapse.css( 'marginLeft' ) ) )
566									+ Math.ceil( parseFloat( li_collapse.css( 'marginRight' ) ) )
567									);
568					}
569					w_all += parseFloat( jQuery( this ).data( 'width' ) );
570					if ( w_all < w_max ) {
571						jQuery( this ).insertBefore( li_collapse );
572						cnt++;
573					} else {
574						move = false;
575					}
576				} );
577				if ( items.length - cnt === 0 ) {
578					li_collapse.hide();
579				}
580			}
581		} );
582	}
583
584} )();

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.