PageSourceSearch

https://laphotoparty.com/wp-content/plugins/jet-search/assets/js/jet-search.js

js laphotoparty.com collected 2026-10-02 06:11:46 UTC 79,467 bytes, 2,589 lines download raw bytes

1(function( $ ) {
2
3	'use strict';
4
5	var JetSearch = {
6
7		addedScripts: [],
8		addedStyles: [],
9		addedPostCSS: [],
10		assetsPromises: [],
11
12		initElementor: function() {
13
14			var widgets = {
15				'jet-ajax-search.default': JetSearch.widgetAjaxSearch,
16				'jet-search-suggestions.default': JetSearch.widgetSearchSuggestions
17			};
18
19			$.each( widgets, function( widget, callback ) {
20				window.elementorFrontend.hooks.addAction( 'frontend/element_ready/' + widget, callback );
21			} );
22
23			// Re-init widgets in nested tabs
24			window.elementorFrontend.elements.$window.on(
25				'elementor/nested-tabs/activate',
26				( event, content ) => {
27
28					const $content = $( content );
29					JetSearch.reinitSlickSlider( $content );
30					JetSearch.initElementsHandlers( $content );
31				}
32			);
33
34			window.addEventListener( 'elementor/popup/show', ( event ) => {
35				const instance = event.detail.instance;
36
37				const interval = setInterval( () => {
38
39					if ( ! instance.keyboardHandler ) return;
40
41					const handler = instance.keyboardHandler;
42					const config  = handler.config;
43
44					if ( ! config || ! config.$modalElements ) return;
45
46					if ( handler.changeFocusAfterAnimation !== true ) {
47						clearInterval( interval );
48						return;
49					}
50
51					const $input = instance.$element.find('.jet-ajax-search__field');
52
53					if ( $input.length ) {
54						handler.firstFocusableElement = $input[0];
55					}
56
57					clearInterval( interval );
58
59				}, 50) ;
60
61				setTimeout( () => clearInterval( interval ), 1000 );
62
63			});
64
65			/*
66			// Example of usage AJAX success trigger
67			$( document ).on( 'jet-ajax-search/show-results', function( event, searchResults ) {
68				searchResults.find( '.jet-ajax-search__results-item' ).css( 'border', '2px solid red' );
69			} );
70			*/
71
72			/*
73			* Example of usage `jet-ajax-search/results-area/listing-add-suggestion` trigger
74			*
75			* Parameters:
76			* - itemWrapper: A CSS selector that points to the element containing the wrapper of the search result item.
77			* - itemLink: Represents the element that contains the link of the search result item.
78			* - itemTitle: A CSS selector that points to the element containing the title of the search result item.
79			* - itemUrlAttr: Specifies the attribute used to extract the URL from the itemLink.
80			$( document ).on( "jet-ajax-search/results-area/listing-add-suggestion", function( event, itemWrapper, itemLink, itemTitle, itemUrlAttr ) {
81				itemWrapper = '.jet-ajax-search__results-item',
82				itemLink    = $( '.jet-listing-dynamic-image__link', itemWrapper );
83				itemTitle   = '.jet-ajax-search-item-title .jet-listing-dynamic-field__content';
84				itemUrlAttr = 'href';
85
86				window.JetSearch.addSuggestionFromResultAreaItem( itemWrapper, itemLink, itemTitle, itemUrlAttr );
87			} );
88			*/
89		},
90
91		initBricks: function( $scope ) {
92
93			if ( window.bricksIsFrontend ) {
94				return;
95			}
96
97			$scope = $scope || $( 'body' );
98
99			JetSearch.initBlocks( $scope );
100
101		},
102
103		initBlocks: function( $scope ) {
104
105			$scope = $scope || $( 'body' );
106
107			window.JetPlugins.init( $scope, [
108				{
109					block: 'jet-search/ajax-search',
110					callback: JetSearch.widgetAjaxSearch
111				},
112				{
113					block: 'jet-search/search-suggestions',
114					callback: JetSearch.widgetSearchSuggestions
115				}
116			] );
117		},
118
119		widgetAjaxSearch: function( $scope ) {
120
121			var settings = {
122				searchClass:                 '.jet-ajax-search',
123				searchFormClass:             '.jet-ajax-search__form',
124				fieldsHolderClass:           '.jet-ajax-search__fields-holder',
125				inputClass:                  '.jet-ajax-search__field',
126				settingsInput:               'input[name="jet_ajax_search_settings"]',
127				submitClass:                 '.jet-ajax-search__submit',
128				chosenClass:                 '.jet-ajax-search__categories select[name="jet_ajax_search_categories"]',
129				resultsAreaClass:            '.jet-ajax-search__results-area',
130				resultsHeaderClass:          '.jet-ajax-search__results-header',
131				resultsFooterClass:          '.jet-ajax-search__results-footer',
132				listHolderClass:             '.jet-ajax-search__results-holder',
133				listClass:                   '.jet-ajax-search__results-list',
134				listInnerClass:              '.jet-ajax-search__results-list-inner',
135				listSlideClass:              '.jet-ajax-search__results-slide',
136				itemClass:                   '.jet-ajax-search__results-item',
137				inlineSuggestionsAreaClass:  '.jet-ajax-search__suggestions-inline-area',
138				inlineSuggestionsItemClass:  '.jet-ajax-search__suggestions-inline-area-item',
139				resultsSuggestionsAreaClass: '.jet-ajax-search__results-suggestions-area',
140				resultsSuggestionItemClass:  '.jet-ajax-search__results-suggestions-area-item',
141				countClass:                  '.jet-ajax-search__results-count',
142				messageHolderClass:          '.jet-ajax-search__message',
143				fullResultsClass:            '.jet-ajax-search__full-results',
144				navigationClass:             '.jet-ajax-search__navigation-holder',
145				navButtonClass:              '.jet-ajax-search__navigate-button',
146				bulletClass:                 '.jet-ajax-search__bullet-button',
147				numberClass:                 '.jet-ajax-search__number-button',
148				prevClass:                   '.jet-ajax-search__prev-button',
149				nextClass:                   '.jet-ajax-search__next-button',
150				activeNavClass:              '.jet-ajax-search__active-button',
151				disableNavClass:             '.jet-ajax-search__navigate-button-disable',
152				spinnerClass:                '.jet-ajax-search__spinner-holder',
153				handlerId:                   'jetSearchSettings',
154				isRtl:              ( window.elementorFrontend && window.elementorFrontend.config.is_rtl ) ? window.elementorFrontend.config.is_rtl : $( 'body' ).hasClass( 'rtl' )
155			};
156
157			if ( $scope.hasClass('jet-ajax-search-block') ) {
158				var resultAreaWidthBy             = $scope.find( settings.searchClass ).data('settings')['results_area_width_by'],
159					resultAreaCustomWidth         = $scope.find( settings.searchClass ).data('settings')['results_area_custom_width'],
160					resultAreaCustomWidthPosition = $scope.find( settings.searchClass ).data('settings')['results_area_custom_position'],
161					resultAreaContainer           = $( '.jet-ajax-search__results-area', $scope );
162
163				if ( "custom" === resultAreaWidthBy ) {
164					if ( "" !== resultAreaCustomWidth ) {
165						resultAreaContainer.width( resultAreaCustomWidth );
166					}
167
168					switch( resultAreaCustomWidthPosition ) {
169						case 'left':
170							resultAreaContainer.css( "left", 0 );
171							resultAreaContainer.css( "right", "auto" );
172							break;
173						case 'center':
174							resultAreaContainer.css( "left", "50%" );
175							resultAreaContainer.css( "right", "auto" );
176							resultAreaContainer.css( "-webkit-transform", "translateX(-55%)" );
177							resultAreaContainer.css( "transform", "translateX(-50%)" );
178							break;
179						case 'right':
180							resultAreaContainer.css( "left", "auto" );
181							resultAreaContainer.css( "right", 0 );
182							break;
183					}
184				}
185			}
186
187			$scope.find( settings.searchClass ).jetAjaxSearch( settings );
188
189			$scope.find( settings.inputClass )
190				.on( 'focus.jetSearchSlick input.jetSearchSlick', function() {
191					window.JetSearch.pauseAllSlick( $( document ) );
192				})
193				.on( 'blur.jetSearchSlick', function() {
194					window.JetSearch.playAllSlick( $( document ) );
195				});
196
197			var $chosenSelect = $scope.find( settings.chosenClass );
198
199			if ( $chosenSelect[0] ) {
200				$chosenSelect.chosen( {
201					disable_search: true,
202					placeholder_text: '',
203					placeholder_text_single: ''
204				} );
205			}
206		},
207
208		widgetSearchSuggestions: function( $scope ) {
209
210			let	$target  = $scope.find( '.jet-search-suggestions' ),
211				settings = {
212					searchClass:        '.jet-search-suggestions',
213					searchFormClass:    '.jet-search-suggestions__form',
214					fieldsHolderClass:  '.jet-search-suggestions__fields-holder',
215					inputClass:         '.jet-search-suggestions__field',
216					spinnerClass:       '.jet-search-suggestions__spinner-holder',
217					messageHolderClass: '.jet-search-suggestions__message',
218					settingsInput:      'input[name="jet_search_suggestions_settings"]',
219					submitClass:        '.jet-search-suggestions__submit',
220					chosenClass:        '.jet-search-suggestions__categories select[name="jet_search_suggestions_categories"]',
221					inlineClass:        '.jet-search-suggestions__inline-area',
222					inlineItemClass:    '.jet-search-suggestions__inline-area-item',
223					focusClass:         '.jet-search-suggestions__focus-area',
224					focusHolderClass:   '.jet-search-suggestions__focus-results-holder',
225					focusItemClass:     '.jet-search-suggestions__focus-area-item',
226					handlerId:          'jetSearchSettings',
227					isRtl:              ( window.elementorFrontend && window.elementorFrontend.config.is_rtl ) ? window.elementorFrontend.config.is_rtl : $( 'body' ).hasClass( 'rtl' )
228				},
229				$chosenSelect = $scope.find( settings.chosenClass );
230
231			$target.jetAjaxSearchSuggestions( settings );
232
233			if ( $chosenSelect[0] ) {
234				$chosenSelect.chosen( {
235					disable_search: true,
236					placeholder_text: '',
237					placeholder_text_single: ''
238				} );
239			}
240		},
241
242		setFormSuggestion: function( name, form, url = '' ) {
243			const ajaxSettings = window['jetSearchSettings']['searchSuggestions'] || {},
244				sendData       = {
245					name: name
246				},
247				nonce          = ajaxSettings.nonce_rest;
248
249			const ajaxData = {
250				action: ajaxSettings.add_action,
251				data: sendData || {},
252				nonce: ajaxSettings.nonce
253			};
254
255			$.ajax( {
256				type: 'POST',
257				url: ajaxSettings.add_suggestions_rest_api_url,
258				data: ajaxData,
259				dataType: 'json',
260				beforeSend: function( jqXHR ) {
261					jqXHR.setRequestHeader( 'X-WP-Nonce', nonce );
262				},
263				complete: function() {
264					if ( false != form ) {
265						if ( '' != url ) {
266							url = JetSearch.getResultsUrl( form, url );
267
268							window.location.href = url;
269						} else {
270							form.submit();
271						}
272					} else {
273						window.location.href = url;
274					}
275				}
276			} );
277		},
278		getResultsUrl: function( form, url = '' ) {
279			let redirectUrl = '';
280
281			if ( '' != url ) {
282				redirectUrl = url;
283			} else {
284				redirectUrl = form.attr( 'action' );
285			}
286
287			if ( redirectUrl && ! redirectUrl.startsWith( 'http' ) && ! redirectUrl.startsWith( '/' ) ) {
288				const actionBase = ( form.attr( 'action' ) || '/' ).replace( /\/+$/, '' );
289
290				redirectUrl = actionBase + '/' + redirectUrl.replace( /^\/+/, '' );
291			}
292
293			let formData = {},
294				result   = '';
295
296			formData = form.serializeArray().reduce( function( obj, item ) {
297				if ( item.name === 's' ) {
298					item.value = item.value.replace(/\u3000/g, ' ');
299				}
300
301				obj[item.name] = item.value;
302
303				return obj;
304			}, {} );
305
306			if ( Object.keys( formData ).length > 0 ) {
307				const queryString = $.param( formData ).replace(/=&/g, '&').replace(/=$/, '' );
308				const separator   = redirectUrl.indexOf( '?' ) === -1 ? '?' : '&';
309
310				result = redirectUrl + separator + queryString;
311			} else {
312				result = redirectUrl;
313			}
314
315			return result;
316		},
317		suggestionsPreloader: function( is_active, state, preloader ) {
318			if ( ! is_active ) {
319				return;
320			}
321
322			if ( '' != preloader ) {
323				if ( 'show' === state ) {
324					preloader.addClass( 'show' );
325				} else if ( 'hide' === state ) {
326					preloader.removeClass( 'show' );
327				}
328			}
329		},
330		getUrlParams: function() {
331			let params      = {},
332				queryString = window.location.search.slice(1);
333
334			if ( queryString ) {
335				let pairs = queryString.split( '&' );
336
337				for ( let i = 0; i < pairs.length; i++ ) {
338					let pair = pairs[i].split( '=' );
339
340					params[pair[0]] = decodeURIComponent( pair[1] || '' );
341				}
342			}
343
344			return params;
345		},
346		md5: function(str) {
347			let hash = '';
348
349			for (let i = 0; i < str.length; i++) {
350				let char = str.charCodeAt(i);
351				hash += char;
352			}
353			return hash;
354		},
355		generateHash: function( string, length = 6 ) {
356			let md5Hash = JetSearch.md5( string ),
357				hash = '';
358
359			for ( let i = 0; i < length; i++ ) {
360				hash += md5Hash.charAt( Math.floor( Math.random() * md5Hash.length ) );
361			}
362
363			hash = hash.toLowerCase();
364
365			return hash;
366		},
367		generateRandomId: function() {
368			let hash = JetSearch.generateHash( Math.random().toString() );
369
370			return hash;
371		},
372		initElementsHandlers: function( $selector ) {
373			// Actual init
374			window.JetPlugins.init( $selector );
375
376			// Legacy Elementor-only init
377			$selector.find( '[data-element_type]' ).each( function() {
378				var excludeWidgets = [
379					'jet-form-builder-form.default',
380					'nav-menu.default',
381					'jet-woo-product-gallery-slider.default',
382					'accordion.default'
383				];
384
385				var $this       = $( this ),
386					elementType = $this.data( 'element_type' );
387
388				if ( !elementType ) {
389					return;
390				}
391
392				if ( 'widget' === elementType ) {
393					elementType = $this.data( 'widget_type' );
394
395					if ( excludeWidgets.includes( elementType ) ) {
396						return;
397					}
398
399					window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ );
400				}
401
402				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ );
403				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ );
404			} );
405
406			if ( window.elementorFrontend ) {
407				const elementorLazyLoad = new Event( "elementor/lazyload/observe" );
408				document.dispatchEvent( elementorLazyLoad );
409			}
410
411			if ( window.JetPopupFrontend && window.JetPopupFrontend.initAttachedPopups ) {
412				window.JetPopupFrontend.initAttachedPopups( $selector );
413			}
414		},
415		reinitSlickSlider: function( $scope ) {
416			var $slider = $scope.find('.slick-initialized');
417
418			if ( $slider.length ) {
419
420				$slider.each( function() {
421					$( this ).slick('unslick');
422				} );
423			}
424		},
425
426		toggleSlickAutoplay: function( $root, shouldPlay ) {
427			const $slicks = $root ? $root.find( '.slick-initialized' ) : $( '.slick-initialized' );
428
429			$slicks.each( function(){
430				try {
431					$( this ).slick( shouldPlay ? 'slickPlay' : 'slickPause' );
432				} catch(e) {}
433			});
434		},
435
436		pauseAllSlick: function( $root ) {
437			this.toggleSlickAutoplay( $root || $( document ), false );
438		},
439
440		playAllSlick: function( $root ) {
441			setTimeout( () => this.toggleSlickAutoplay( $root || $( document ), true ), 60 );
442		},
443
444		enqueueAssetsFromResponse: function( response ) {
445			if ( response.data.scripts ) {
446				JetSearch.enqueueScripts( response.data.scripts );
447			}
448
449			if ( response.data.styles ) {
450				JetSearch.enqueueStyles( response.data.styles );
451			}
452		},
453
454		enqueueScripts: function( scripts ) {
455			$.each( scripts, function( handle, scriptHtml ) {
456				JetSearch.enqueueScript( handle, scriptHtml )
457			} );
458		},
459
460		enqueueStyles: function( styles ) {
461			$.each( styles, function( handle, styleHtml ) {
462				JetSearch.enqueueStyle( handle, styleHtml )
463			} );
464		},
465
466		enqueueScript: function( handle, scriptHtml ) {
467
468			if ( -1 !== JetSearch.addedScripts.indexOf( handle ) ) {
469				return;
470			}
471
472			if ( ! scriptHtml ) {
473				return;
474			}
475
476			var selector = 'script[id="' + handle + '-js"]';
477
478			if ( $( selector ).length ) {
479				return;
480			}
481
482			var scriptsTags = scriptHtml.match( /<script[\s\S]*?<\/script>/gm );
483
484			if ( scriptsTags.length ) {
485
486				for ( var i = 0; i < scriptsTags.length; i++ ) {
487
488					JetSearch.assetsPromises.push(
489						new Promise( function( resolve, reject ) {
490
491							var $tag = $( scriptsTags[i] );
492
493							if ( $tag[0].src ) {
494
495								var tag = document.createElement( 'script' );
496
497								tag.type   = $tag[0].type;
498								tag.src    = $tag[0].src;
499								tag.id     = $tag[0].id;
500								tag.async  = false;
501								tag.onload = function() {
502									resolve();
503								};
504
505								document.body.append( tag );
506							} else {
507								$( 'body' ).append( scriptsTags[i] );
508								resolve();
509							}
510						} )
511					);
512				}
513			}
514
515			JetSearch.addedScripts.push( handle );
516		},
517
518		enqueueStyle: function( handle, styleHtml ) {
519
520			if ( -1 !== handle.indexOf( 'google-fonts' ) ) {
521				JetSearch.enqueueGoogleFonts( handle, styleHtml );
522				return;
523			}
524
525			if ( -1 !== JetSearch.addedStyles.indexOf( handle ) ) {
526				return;
527			}
528
529			var selector = 'link[id="' + handle + '-css"],style[id="' + handle + '"]';
530
531			if ( $( selector ).length ) {
532				return;
533			}
534
535			$( 'head' ).append( styleHtml );
536
537			JetSearch.addedStyles.push( handle );
538
539			if ( -1 !== handle.indexOf( 'elementor-post' ) ) {
540				var postID = handle.replace( 'elementor-post-', '' );
541				JetSearch.addedPostCSS.push( postID );
542			}
543		},
544
545		enqueueGoogleFonts: function( handle, styleHtml ) {
546
547			var selector = 'link[id="' + handle + '-css"]';
548
549			if ( $( selector ).length ) {}
550
551			$( 'head' ).append( styleHtml );
552		},
553
554		reinitBricksScripts: function( _this ) {
555
556			if ( !$( 'body' ).hasClass( 'theme-bricks' ) && !$( 'body' ).hasClass( 'bricks-is-frontend') ) {
557				return;
558			}
559
560			const resultsArea   = $( '.jet-ajax-search__results-list', _this );
561			const sourcesHolder = $( '.jet-ajax-search__source-results-holder', _this );
562
563			//Results Area
564			resultsArea.find( '[data-script-id]' ).each( function() {
565				const newId = JetSearch.generateRandomId();
566
567				$( this ).attr( 'data-script-id', newId );
568			} );
569
570			resultsArea.find( '[id^="brxe-"]' ).each( function() {
571				var id = $( this ).attr( 'id' );
572
573				$( this ).addClass( id );
574			} );
575
576			const bricksScripts = {
577				".bricks-lightbox": 'bricksPhotoswipe',
578				".brxe-accordion, .brxe-accordion-nested": 'bricksAccordion',
579				".brxe-animated-typing": 'bricksAnimatedTyping',
580				".brxe-audio": 'bricksAudio',
581				".brxe-countdown": 'bricksCountdown',
582				".brxe-counter": 'bricksCounter',
583				".brxe-video": 'bricksVideo',
584				".bricks-lazy-hidden": 'bricksLazyLoad',
585				".brx-animated": 'bricksAnimation',
586				".brxe-pie-chart": 'bricksPieChart',
587				".brxe-progress-bar .bar span": 'bricksProgressBar',
588				".brxe-form": 'bricksForm',
589				".brx-query-trail": 'bricksInitQueryLoopInstances',
590				"[data-interactions]": 'bricksInteractions',
591				".brxe-alert svg": 'bricksAlertDismiss',
592				".brxe-tabs, .brxe-tabs-nested": 'bricksTabs',
593				".bricks-video-overlay, .bricks-video-overlay-icon, .bricks-video-preview-image": 'bricksVideoOverlayClickDetector',
594				".bricks-background-video-wrapper": 'bricksBackgroundVideoInit',
595				".brxe-toggle": 'bricksToggle',
596				".brxe-offcanvas": 'bricksOffcanvas',
597				'.brxe-slider': 'bricksSwiper',
598				'.brxe-slider-nested': 'bricksSplide',
599				'.brxe-image': 'bricksSwiper'
600			};
601
602			const contentWrapper = resultsArea[0];
603
604			//Result Area
605			for ( const key in bricksScripts ) {
606				const widget = contentWrapper.querySelector(key);
607
608				if ( widget && typeof window[bricksScripts[key]] === "function" && bricksScripts[key] ) {
609					window[bricksScripts[key]]();
610				}
611			}
612
613			//Sources Holder
614			if ( sourcesHolder.length ) {
615				sourcesHolder.find( '[data-script-id]' ).each( function() {
616					const newId = JetSearch.generateRandomId();
617
618					$( this ).attr( 'data-script-id', newId );
619				} );
620
621				sourcesHolder.find( '[id^="brxe-"]' ).each( function() {
622					var id = $( this ).attr( 'id' );
623
624					$( this ).addClass( id );
625				} );
626
627				const sourcesWrapper = sourcesHolder[0];
628
629				for ( const key in bricksScripts ) {
630					const widget = sourcesWrapper.querySelector( key );
631
632					if ( widget && typeof window[bricksScripts[key]] === "function" && bricksScripts[key] ) {
633						window[bricksScripts[key]]();
634					}
635				}
636			}
637		},
638
639		getCurrentDeviceMode: function() {
640			const width = window.innerWidth;
641
642			if ( width > 1024 ) {
643				return 'desktop';
644			} else if ( width <= 1024 && width > 767 ) {
645				return 'tablet';
646			} else {
647				return 'mobile';
648			}
649		},
650
651		trimString: function( str, numWords ) {
652			if ( typeof str !== 'string' ) {
653				return str;
654			}
655
656			let wordsArray = str.split( ' ' );
657
658			if ( wordsArray.length <= numWords ) {
659				return str;
660			}
661
662			let truncatedString = wordsArray.slice( 0, numWords ).join( ' ' );
663
664			return truncatedString + '...';
665		},
666
667		escapeHTML: function( str ) {
668			return str.replace(/[&<>"']/g, function ( match ) {
669				const escapeMap = {
670					'&': '&amp;',
671					'<': '&lt;',
672					'>': '&gt;',
673					'"': '&quot;',
674					"'": '&#039;'
675				};
676
677				return escapeMap[match];
678			} );
679		},
680
681		addSuggestionFromResultAreaItem: function( itemWrapper, itemLink, itemTitle, itemUrlAttr ) {
682			itemLink.on( 'click', function( e ) {
683				e.stopImmediatePropagation();
684				e.preventDefault();
685
686				let	item  = $( this ).closest( itemWrapper ),
687					value = $( itemTitle, item ).text(),
688					url   = $( this ).attr( itemUrlAttr );
689
690				JetSearch.setFormSuggestion( value, false, url );
691			} );
692		}
693	};
694
695	$.fn.getSuggestionsList = function( options, settings, showSpinner, hightlightText = false, callback = () => {} ) {
696		let self               = this[0],
697			outputHtml         = '',
698			listPosition       = options.list_position,
699			inlineItemTemplate = wp.template( 'jet-search-inline-suggestion-item' ),
700			focusItemTemplate  = wp.template( 'jet-search-focus-suggestion-item' ),
701			spinner            = $( settings.spinnerClass, self ),
702			manualList         = [];
703
704		const ajaxSettings = window['jetSearchSettings']['searchSuggestions'] || {};
705
706		function highlightMatches( item ) {
707			let searched = options.value.trim();
708
709			if ( searched !== "" ) {
710				let reg     = new RegExp("[\>][^\<]*"+searched+"[^\<]*[\<]","gi"),
711					reg2    = new RegExp( searched, "gi" ),
712					regHtml = new RegExp("<\/?[a-z](.*?)[\s\S]*>", "gi");
713
714				if ( reg.test( item ) ) {
715					item = item.replace( reg, function( item ) {
716						let subRegex = new RegExp( searched, "gi" );
717						return item.replace( subRegex,`<mark>${searched}</mark>` );
718					} );
719				}
720
721				if ( regHtml.test( item ) ) {
722					return item;
723				} else {
724					item = item.replace( reg2, str => `<mark>${str}</mark>` );
725				}
726			}
727
728			return item;
729		}
730
731		if ( 'manual' === options.list_type ) {
732
733			if ( options['manual_list'].length ) {
734				let list = options['manual_list'].split( "," );
735
736				list.map( function( suggestion, i ) {
737					manualList[i] = { name: suggestion };
738				} );
739
740				if ( 'inline' === listPosition ) {
741					manualList.map( function( suggestion ) {
742						outputHtml += inlineItemTemplate( suggestion );
743					} );
744
745					$( self ).html( outputHtml );
746				} else if ( 'focus' === listPosition ) {
747					manualList.map( function( suggestion ) {
748						outputHtml += focusItemTemplate( suggestion );
749					} );
750
751					$( settings.focusHolderClass ,self ).html( outputHtml );
752
753					if ( typeof callback === 'function' ) {
754						callback();
755					}
756
757					JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner );
758				}
759			}
760
761			return;
762		}
763
764		let sendData = {
765				list_type: options.list_type || '',
766				value: options.value || '',
767				limit: options.limit
768			},
769			ajaxData = {
770				action: ajaxSettings.get_action,
771				data: sendData || {},
772			};
773
774		jQuery.ajax( {
775			type: 'GET',
776			url: ajaxSettings.get_suggestions_rest_api_url,
777			data: ajaxData,
778			dataType: 'json',
779			cache: false,
780			processData: true,
781			error: function( jqXHR, textStatus, errorThrown ) {
782				errorCallback( jqXHR );
783			},
784			success: function( response, textStatus, jqXHR ) {
785				successCallback( response );
786				if ( typeof callback === 'function' ) {
787					callback();
788				}
789			}
790		} );
791
792		const successCallback = function( response ) {
793
794			if ( response ) {
795				JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner );
796
797				if ( 'inline' === listPosition ) {
798					response.map( function( suggestion ) {
799						suggestion['name']     = JetSearch.escapeHTML( suggestion['name'] );
800						suggestion['fullName'] = JetSearch.escapeHTML( suggestion['name'] );
801
802						if ( 0 < options.maxLength ) {
803							suggestion['name'] = JetSearch.trimString( suggestion['name'], options.maxLength );
804						}
805
806						outputHtml += inlineItemTemplate( suggestion );
807					} );
808
809					$( self ).html( outputHtml );
810				} else if ( 'focus' === listPosition ) {
811
812					response.map( function( suggestion ) {
813						suggestion['name']     = JetSearch.escapeHTML( suggestion['name'] );
814						suggestion['fullName'] = JetSearch.escapeHTML( suggestion['name'] );
815
816						if ( 0 < options.maxLength ) {
817							suggestion['name'] = JetSearch.trimString( suggestion['name'], options.maxLength );
818						}
819
820						if ( options.value && ( "yes" === hightlightText || true === hightlightText ) ) {
821							suggestion['name'] = highlightMatches( suggestion['name'] );
822						}
823
824						outputHtml += focusItemTemplate( suggestion );
825					} );
826
827					$( settings.focusHolderClass, self ).html( outputHtml );
828				}
829			}
830		}
831
832		const errorCallback = function( jqXHR ) {
833			if ( 'abort' !== jqXHR.statusText ) {
834				JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner );
835			}
836		};
837	};
838
839	/**
840	 * jetAjaxSearchSuggestions jQuery Plugin
841	 *
842	 * @param args
843	 */
844	$.fn.jetAjaxSearchSuggestions = function( args ) {
845		let self                   = this[0],
846			settings               = args,
847			options                = $( self ).data( 'settings' ) || {},
848			timer                  = null,
849			showformList           = options['show_search_suggestions_list_inline'] || false,
850			showfocusList          = options['show_search_suggestions_list_on_focus'] || false,
851			formListType           = options['search_suggestions_list_inline'] || false,
852			focusListType          = options['search_suggestions_list_on_focus'] || false,
853			searchSuggestionsLimit = options['search_suggestions_quantity_limit'] || 10,
854			inlineLimit            = options['search_suggestions_list_inline_quantity'] || 5,
855			focusLimit             = options['search_suggestions_list_on_focus_quantity'] || 5,
856			showSpinner            = options['show_search_suggestions_list_on_focus_preloader'] || '',
857			hightlightText         = options['highlight_searched_text'] || '',
858			spinner                = $( settings.spinnerClass, self ),
859			formFocusClass         = settings.searchFormClass.replace( '.', '' ) + '--focus',
860			form                   = $( settings.searchFormClass, self ),
861			focusTarget            = $( settings.focusHolderClass, self ),
862			disableInputs          = false,
863			customResultUrl        = options['search_results_url'] || '',
864			useSession             = 'false',
865			focusItem;
866
867		if ( window.elementorFrontend ) {
868			var editMode = Boolean( window.elementorFrontend.isEditMode() )
869		} else {
870			var editMode = false;
871		}
872
873		if ( !self.isInit ) {
874			self.isInit = true;
875
876			/**
877			 * Ajax settings from localized global variable
878			 */
879			self.ajaxSettings = window[ settings.handlerId ]['searchSuggestions'] || {};
880
881			customResultUrl = $.trim( customResultUrl );
882			useSession      = self.ajaxSettings.use_session;
883
884			self.selectSuggestion = function( event ) {
885				const keyCode = event.keyCode || event.which;
886				const $target = $( event.currentTarget );
887
888				let value = $target.attr( 'aria-label' );
889
890				if ( ! value ) {
891					return;
892				}
893
894				value = value.trim();
895
896				if ( false === disableInputs && !editMode ) {
897
898					if ( 'keydown' === event.type ) {
899						if ( 13 === keyCode ) {
900							disableInputs = true;
901
902							$( settings.inputClass, self )[0].value = value;
903
904							JetSearch.setFormSuggestion( value, form, customResultUrl );
905						}
906					} else if ( 'click' === event.type ) {
907						disableInputs = true;
908
909						$( settings.inputClass, self )[0].value = value;
910						JetSearch.setFormSuggestion( value, form, customResultUrl );
911					}
912				}
913			}
914
915			self.focusItemsNav = function() {
916				focusItem = $( '.jet-search-suggestions__focus-area-item', self );
917
918				if ( 0 < focusItem.length ) {
919					focusItem.on( 'keydown', function( e ) {
920						const keyCode = e.keyCode || e.which;
921
922						switch ( keyCode ) {
923						  	case 40: // Down arrow
924								e.preventDefault();
925
926								var next = $( this ).next();
927
928								if ( next.length > 0 ) {
929									focusItem.removeClass( 'focused' );
930									next.addClass( 'focused' );
931									next.focus();
932								}
933								break;
934
935							case 38: // Up arrow
936								e.preventDefault();
937
938								var prev = $( this ).prev();
939
940								if ( prev.length > 0 ) {
941									focusItem.removeClass( 'focused' );
942									prev.addClass( 'focused' );
943									prev.focus();
944								} else {
945									focusItem.removeClass( 'focused' );
946									$( settings.inputClass, self ).focus();
947								}
948								break;
949							case 13:
950								e.preventDefault();
951								let value = e.target.innerText.trim();
952								$( settings.inputClass, self )[0].value = value;
953
954								JetSearch.setFormSuggestion( value, form, customResultUrl );
955								break;
956						}
957
958						if ( $( this ).is( ':focus-visible' ) ) {
959							focusItem.removeClass( 'focused' );
960						}
961					} );
962				}
963			}
964
965			if ( formListType || focusListType ) {
966
967				if ( '' != formListType && ( "yes" === showformList || true === showformList ) ) {
968					let listOptions = {
969						list_position: 'inline',
970						list_type: formListType,
971						limit: inlineLimit,
972						maxLength: options.search_suggestions_list_inline_item_title_length,
973					};
974
975					if ( 'manual' === formListType ) {
976						listOptions.manual_list = options['search_suggestions_list_inline_manual'];
977					}
978
979					$( settings.inlineClass, self ).getSuggestionsList( listOptions, settings, showSpinner, false, () => {
980						let inlineItem = $( '.jet-search-suggestions__inline-area-item', self );
981
982						if ( 0 < inlineItem.length ) {
983							inlineItem.on( 'focus', function () {
984								if ( $( this ).is( ':focus-visible' ) ) {
985									self.hideList();
986								}
987							} );
988						}
989
990						inlineItem.on( 'keydown', function( e ) {
991							const keyCode = e.keyCode || e.which;
992
993							let value = $( this ).attr( 'aria-label' );
994
995							if ( ! value ) {
996								return;
997							}
998
999							value = value.trim();
1000
1001							if ( 13 === keyCode ) {
1002								$( settings.inputClass, self )[0].value = value;
1003
1004								JetSearch.setFormSuggestion( value, form, customResultUrl );
1005							}
1006						} );
1007					} );
1008				}
1009
1010				if ( '' != focusListType && ( "yes" === showfocusList || true === showfocusList ) ) {
1011					let listOptions = {
1012						list_position: 'focus',
1013						list_type: focusListType,
1014						limit: focusLimit,
1015						maxLength: options.search_suggestions_list_on_focus_item_title_length || 0,
1016					};
1017
1018					if ( 'manual' === focusListType ) {
1019						listOptions.manual_list = options['search_suggestions_list_on_focus_manual'];
1020					}
1021
1022					$( settings.focusClass, self ).getSuggestionsList( listOptions, settings, showSpinner, false, () => {
1023						self.focusItemsNav();
1024					} );
1025				}
1026			}
1027
1028			self.inputChangeHandler = function( event ) {
1029
1030				let value       = $( event.target ).val(),
1031					listOptions = {
1032						list_position: 'focus',
1033						value: value,
1034						limit: searchSuggestionsLimit,
1035						maxLength: options.search_suggestions_list_on_focus_item_title_length || 0,
1036					};
1037
1038				if ( '' != value ) {
1039					focusTarget.empty();
1040					self.showList();
1041					JetSearch.suggestionsPreloader( showSpinner, 'show', spinner );
1042
1043					clearTimeout( timer );
1044					timer = setTimeout( function() {
1045						$( settings.focusClass, self ).getSuggestionsList( listOptions, settings, showSpinner, hightlightText, () => {
1046							self.focusItemsNav();
1047						} );
1048					}, 450 );
1049				} else {
1050					clearTimeout( timer );
1051					focusTarget.empty();
1052					JetSearch.suggestionsPreloader( showSpinner, 'hide', spinner );
1053
1054					if ( false != focusListType && ( "yes" === showfocusList || true === showfocusList ) ) {
1055						JetSearch.suggestionsPreloader( showSpinner, 'show', spinner );
1056
1057						listOptions.limit = focusLimit;
1058
1059						if ( 'manual' === focusListType ) {
1060							listOptions.list_type = focusListType;
1061							listOptions.manual_list = options['search_suggestions_list_on_focus_manual'];
1062						}
1063
1064						$( settings.focusClass, self ).getSuggestionsList( listOptions, settings, showSpinner, false, () => {
1065							self.focusItemsNav();
1066						} );
1067					}
1068				}
1069			};
1070
1071			self.hideList = function(event) {
1072				$( settings.focusClass, self ).removeClass( 'show' );
1073				$( '.chosen-single', self ).removeClass( 'focused' );
1074
1075				if ( focusItem && 0 < focusItem.length ) {
1076					focusItem.removeClass( 'focused' );
1077				}
1078			};
1079
1080			self.showList = function() {
1081				$( settings.focusClass, self ).addClass( 'show' );
1082			};
1083
1084			self.focusHandler = function( event ) {
1085				$( settings.searchFormClass, self ).addClass( formFocusClass );
1086				self.showList();
1087			};
1088
1089			self.chosenFocusHandler = function() {
1090				self.hideList();
1091			};
1092
1093			self.formClick = function( event ) {
1094				event.stopPropagation();
1095			};
1096
1097			self.changeHandler = function( event ) {
1098				let target              = $( event.target ),
1099					settingsInput       = $( settings.settingsInput, self ),
1100					querySettings       = JSON.parse( settingsInput.val() ),
1101					globalQuerySettings = $( self ).data( 'settings' );
1102
1103				querySettings.category__in       = target.val();
1104				globalQuerySettings.category__in = target.val();
1105
1106				settingsInput.val( JSON.stringify( querySettings ) );
1107				$( self ).data( 'settings', globalQuerySettings );
1108
1109				self.inputChangeHandler( { target: $( settings.inputClass, self ) } )
1110			};
1111
1112			self.formSubmit = function( event ) {
1113				let keyCode = event.keyCode || event.which;
1114
1115				if ( false === disableInputs ) {
1116					let value = event.target.value;
1117
1118					if ( 13 === keyCode && value.length != 0 ) {
1119						disableInputs = true;
1120						event.preventDefault();
1121
1122						JetSearch.setFormSuggestion( value, form, customResultUrl );
1123					}
1124				}
1125
1126				if ( 40 === keyCode ) {
1127					if ( focusItem && 0 < focusItem.length ) {
1128						event.preventDefault();
1129						focusItem.removeClass( 'focused' );
1130						focusItem.first().addClass( 'focused' );
1131						focusItem.first().focus();
1132					}
1133				}
1134			}
1135
1136			self.blurHandler = function( event ) {
1137				$( settings.searchFormClass, self ).removeClass( formFocusClass );
1138			};
1139
1140			self.clickFullResults = function( event ) {
1141				if ( false === disableInputs ) {
1142					disableInputs = true;
1143
1144					var searchInput = $( settings.inputClass, self ),
1145						value       = searchInput.val();
1146
1147					event.preventDefault();
1148
1149					JetSearch.setFormSuggestion( value, form, customResultUrl );
1150				}
1151			};
1152
1153			$( settings.inputClass, self )
1154				.on( 'input' + settings.searchClass, self.inputChangeHandler )
1155				.on( 'focus' + settings.searchClass, self.focusHandler )
1156				.on( 'blur' + settings.searchClass, self.blurHandler )
1157				.on( 'keydown' + settings.searchClass, self.formSubmit );
1158
1159			$( settings.submitClass, self ).on( 'click' + settings.searchClass, self.clickFullResults );
1160
1161			$( self )
1162				.on( 'click' + settings.searchClass, settings.focusItemClass, self.selectSuggestion )
1163				.on( 'click keydown' + settings.searchClass, settings.inlineItemClass, self.selectSuggestion )
1164				.on( 'click' + settings.searchClass, self.formClick )
1165				.on( 'change', settings.chosenClass, self.changeHandler )
1166				.on( 'touchend' + settings.searchClass, self.formClick )
1167				.on( 'chosen:showing_dropdown', settings.chosenClass, self.chosenFocusHandler );
1168
1169			$( self ).on( 'keydown', function( e ) {
1170				const keyCode = e.keyCode || e.which;
1171
1172				if ( 9 === keyCode ) {
1173					setTimeout( () => {
1174						const focusedElement = document.activeElement;
1175
1176						if ( $( focusedElement ).is( '.chosen-search-input' ) ) {
1177							$( '.chosen-single', self ).addClass( 'focused' );
1178						} else {
1179							$( '.chosen-single', self ).removeClass( 'focused' );
1180						}
1181
1182						if ( $( focusedElement ).is( '.jet-search-suggestions__inline-area-item' ) ) {
1183							self.hideList();
1184						}
1185					}, 50 );
1186				}
1187			} );
1188
1189			$( settings.inputClass, self ).on( 'click' + settings.searchClass, () => {
1190				$( '.chosen-single', self ).removeClass( 'focused' );
1191			} );
1192
1193			$( 'body' )
1194				.on( 'click' + settings.searchClass, self.hideList )
1195				.on( 'touchend' + settings.searchClass, self.hideList );
1196
1197			// If after reloading the page the value of the select is not '0'.
1198			if ( '0' !== $( settings.chosenClass, self ).val() ) {
1199				$( settings.chosenClass, self ).trigger( 'change' );
1200			}
1201		}
1202	};
1203
1204	/**
1205	 * JetAjaxSearch jQuery Plugin
1206	 *
1207	 * @param args
1208	 */
1209	$.fn.jetAjaxSearch = function( args ) {
1210
1211		var self                    = this[0],
1212			settings                = args,
1213			timer                   = null,
1214			itemTemplate            = null,
1215			resultsArea             = $( settings.resultsAreaClass, self ),
1216			resultsHolder           = $( settings.listHolderClass, resultsArea ),
1217			resultsHeader           = $( settings.resultsHeaderClass, resultsArea ),
1218			resultsFooter           = $( settings.resultsFooterClass, resultsArea ),
1219			countHolder             = $( settings.countClass, resultsArea ),
1220			fullResults             = $( settings.fullResultsClass, resultsArea ),
1221			resultsList             = $( settings.listClass, resultsArea ),
1222			resultsListInner        = $( settings.listInnerClass, resultsArea ),
1223			resultsHeaderNav        = $( settings.navigationClass, resultsHeader ),
1224			resultsFooterNav        = $( settings.navigationClass, resultsFooter ),
1225			messageHolder           = $( settings.messageHolderClass, resultsArea ),
1226			spinner                 = $( settings.spinnerClass, resultsArea ),
1227			form                    = $( settings.searchFormClass, self ),
1228			resultsSuggestions      = $( settings.resultsSuggestionsAreaClass, self ),
1229			inlineSuggestions       = $( settings.inlineSuggestionsAreaClass, self ),
1230			data                    = $( self ).data( 'settings' ) || [],
1231			customResultUrl         = data['search_results_url'] || '',
1232			hightlightText          = data['highlight_searched_text'] || '',
1233			formFocusClass          = settings.searchFormClass.replace( '.', '' ) + '--focus',
1234			searchLogging           = data['search_logging'] || '',
1235			currentPosition         = 1,
1236			lang                    = '',
1237			disableInputs           = false,
1238			allowEmptyString        = false,
1239			allowSubmitOnEnter      = 1,
1240			urlParams               = JetSearch.getUrlParams(),
1241			listingID               = data['listing_id'] || '',
1242			categoryIndex           = urlParams.jet_ajax_search_categories || '',
1243			getResultsOnFocus       = true,
1244			maxUserSearches         = 20,
1245			showSearchSuggestions   = data['show_search_suggestions'] || false,
1246			suggestionsTitle        = '',
1247			suggestionsType         = data['search_suggestions_source'] || false,
1248			suggestionsPosition     = data['search_suggestions_position'] || false,
1249			searchSuggestionsLimits = data['search_suggestions_limits'] || 20,
1250			storedUserSearches      = JSON.parse( localStorage.getItem('jetUserSearches') ) || [],
1251			suggestionsList         = [];
1252
1253		if ( 'yes' === data.search_by_empty_value || true === data.search_by_empty_value ) {
1254			allowEmptyString = true;
1255		}
1256
1257		if ( !self.isInit ) {
1258			self.isInit = true;
1259
1260			/**
1261			 * Ajax request instance
1262			 */
1263			self.ajaxRequest = null;
1264
1265			self.suggestionsListLoaded = false;
1266
1267			if ( data.hasOwnProperty('lang') ) {
1268				lang = data.lang;
1269				delete data.lang;
1270			}
1271
1272			/**
1273			 * Ajax settings from localized global variable
1274			 */
1275			self.ajaxSettings        = window[ settings.handlerId ] || {};
1276			self.suggestionsSettings = window['jetSearchSettings']['searchSuggestions'] || {};
1277
1278			if ( self.ajaxSettings['ajaxSearchSuggestionsLimits'] ) {
1279				maxUserSearches = self.ajaxSettings['ajaxSearchSuggestionsLimits'];
1280			}
1281
1282			if ( 'yes' === data.submit_on_enter || true === data.submit_on_enter ) {
1283				allowSubmitOnEnter = false;
1284			} else {
1285				allowSubmitOnEnter = true;
1286			}
1287
1288			if ( '' === self.ajaxSettings.sumbitOnEnter ) {
1289				allowSubmitOnEnter = false;
1290			}
1291
1292			if ( window.elementorFrontend ) {
1293				var editMode = Boolean( window.elementorFrontend.isEditMode() )
1294			} else {
1295				var editMode = false;
1296			}
1297
1298			self.suggestionsListHTML = function( suggestionsList ) {
1299
1300				let resultsSuggestionsTemplate = wp.template('jet-ajax-search-results-suggestion-item'),
1301					inlineSuggestionsTemplate  = wp.template('jet-ajax-search-inline-suggestion-item'),
1302					inlineOutputHtml           = '',
1303					resultsOutputHtml          = '';
1304
1305
1306				suggestionsList.forEach( item => {
1307					let inlineListItemHtml  = '',
1308						resultsListItemHtml = '',
1309						maxLength           = data.search_suggestions_item_title_length || 0,
1310						suggestionItem      = {};
1311
1312					suggestionItem['fullName'] = JetSearch.escapeHTML( item );
1313					suggestionItem['name']     = JetSearch.escapeHTML( item );
1314
1315					if ( 0 < maxLength ) {
1316						suggestionItem['name'] = JetSearch.trimString( suggestionItem['name'], maxLength );
1317					}
1318
1319					if ( 'under_form' === suggestionsPosition ) {
1320						inlineListItemHtml  = inlineSuggestionsTemplate( suggestionItem );
1321					} else if ( 'inside_results_area' === suggestionsPosition ) {
1322						resultsListItemHtml = resultsSuggestionsTemplate( suggestionItem );
1323					}
1324
1325					inlineOutputHtml  += inlineListItemHtml;
1326					resultsOutputHtml += resultsListItemHtml;
1327				} );
1328
1329				if ( 'under_form' === suggestionsPosition ) {
1330					suggestionsTitle = inlineSuggestions.html();
1331
1332					inlineSuggestions.html( inlineOutputHtml ).prepend( suggestionsTitle );
1333				} else if ( 'inside_results_area' === suggestionsPosition ) {
1334					suggestionsTitle = resultsSuggestions.html();
1335
1336					resultsSuggestions.html( resultsOutputHtml ).prepend( suggestionsTitle );
1337				}
1338			};
1339
1340			self.showSuggestions = function() {
1341
1342				if ( suggestionsType ) {
1343					if ( 'popular' === suggestionsType ) {
1344
1345						if ( false === window.bricksIsFrontend ) {
1346
1347							let sendData = {
1348								list_type: 'popular',
1349								value: '',
1350								limit: searchSuggestionsLimits
1351							},
1352							ajaxData = {
1353								action: self.ajaxSettings['searchSuggestions'].get_action,
1354								data: sendData || {},
1355							};
1356
1357							$.ajax( {
1358								type: 'GET',
1359								url: self.ajaxSettings['searchSuggestions'].get_suggestions_rest_api_url,
1360								data: ajaxData,
1361								dataType: 'json',
1362								cache: false,
1363								processData: true,
1364								error: function( jqXHR, textStatus, errorThrown ) {
1365									errorCallback( jqXHR );
1366								},
1367								success: function( response, textStatus, jqXHR ) {
1368									if ( response.length ) {
1369										suggestionsList = $.map( response, function( obj ) {
1370											return obj.name;
1371										} );
1372
1373										self.suggestionsListLoaded = true;
1374
1375										if ( suggestionsList.length ) {
1376											suggestionsList = suggestionsList.slice( 0, searchSuggestionsLimits );
1377
1378											self.suggestionsListHTML( suggestionsList );
1379										} else {
1380											resultsSuggestions.hide();
1381											inlineSuggestions.hide();
1382										}
1383									}
1384								}
1385							} );
1386						} else {
1387							suggestionsList = self.ajaxSettings['ajaxSearchPopularSuggestions'] || [];
1388
1389							if ( suggestionsList.length ) {
1390								suggestionsList = suggestionsList.slice( 0, searchSuggestionsLimits );
1391
1392								self.suggestionsListHTML( suggestionsList );
1393							} else {
1394								resultsSuggestions.hide();
1395								inlineSuggestions.hide();
1396							}
1397						}
1398					} else if ( 'user' === suggestionsType ) {
1399						let userSearches = localStorage.getItem('jetUserSearches');
1400
1401						if ( userSearches ) {
1402							suggestionsList = JSON.parse( userSearches ) || [];
1403
1404							suggestionsList.reverse();
1405
1406							suggestionsList = suggestionsList.slice( 0, searchSuggestionsLimits );
1407
1408							self.suggestionsListHTML( suggestionsList );
1409						} else {
1410							resultsSuggestions.hide();
1411							inlineSuggestions.hide();
1412						}
1413					}
1414				}
1415			};
1416
1417			if ( 'yes' === showSearchSuggestions || true === showSearchSuggestions ) {
1418				self.showSuggestions();
1419			}
1420
1421			self.inputChangeHandler = function( event ) {
1422				var value = $( event.target ).val(),
1423					symbolNumberForStart = 'number' === $.type( data.symbols_for_start_searching ) ? data.symbols_for_start_searching : 2;
1424
1425				value = value.replace(/\u3000/g, ' ');
1426
1427				if ( 'number' === $.type( symbolNumberForStart ) && symbolNumberForStart > value.length ) {
1428					if ( 'inside_results_area' === suggestionsPosition && suggestionsList.length ) {
1429						resultsHeader.hide();
1430						resultsFooter.hide();
1431						resultsList.hide();
1432						resultsSuggestions.show();
1433						resultsSuggestions.addClass( 'active' );
1434						resultsHolder.addClass( 'show' );
1435						self.showList();
1436					} else {
1437						self.hideList();
1438					}
1439
1440					return false;
1441				}
1442
1443				if ( 'inside_results_area' === suggestionsPosition && suggestionsList.length ) {
1444					resultsSuggestions.removeClass( 'active' );
1445					resultsHeader.show();
1446					resultsFooter.show();
1447					resultsList.show();
1448				}
1449
1450				resultsHolder.removeClass( 'show' );
1451				self.outputMessage( '', '' );
1452				resultsListInner.css( 'transform', 'translateX(0)' );
1453				resultsList.css( 'height', 'auto' );
1454
1455				if ( value ) {
1456					self.showList();
1457					spinner.addClass( 'show' );
1458
1459					clearTimeout( timer );
1460					timer = setTimeout( function() {
1461						data.value = value;
1462						data.deviceMode = window.elementorFrontend && window.elementorFrontend.getCurrentDeviceMode() ? window.elementorFrontend.getCurrentDeviceMode() : JetSearch.getCurrentDeviceMode();
1463						self.ajaxSendData( data, lang );
1464					}, 450 );
1465				} else {
1466					self.hideList();
1467				}
1468			};
1469
1470			self.successCallback = function( response ) {
1471
1472				if ( response.error ) {
1473					spinner.removeClass( 'show' );
1474					self.outputMessage( data.server_error, 'error show' );
1475					return;
1476				}
1477
1478				JetSearch.enqueueAssetsFromResponse( response );
1479
1480				var responseData             = response.data,
1481					error                    = responseData.error,
1482					message                  = responseData.message,
1483					posts                    = responseData.posts,
1484					listingItems             = responseData.listing_items,
1485					post                     = null,
1486					outputHtml               = '',
1487					listItemHtml             = '',
1488					listHtml                 = '<div class="' + settings.listSlideClass.replace( '.', '' ) + '">%s</div>',
1489					searchSources            = responseData.sources,
1490					searchSourcesBeforePosts = null,
1491					searchSourcesAfterPosts  = null,
1492					countAllResults          = null,
1493					searchSourcesHolder      = $( '.jet-ajax-search__source-results-holder', self );
1494
1495				resultsHolder.removeClass( 'show' );
1496				spinner.removeClass( 'show' );
1497				currentPosition = 1;
1498
1499				searchSourcesHolder.remove();
1500
1501				resultsListInner.html( '' );
1502				resultsHeaderNav.html( '' );
1503				resultsFooterNav.html( '' );
1504
1505				searchSourcesBeforePosts = searchSources
1506					.filter( item => item.priority < 0 && '' != item.content )
1507					.sort( ( a, b ) => a.priority - b.priority );
1508
1509				searchSourcesAfterPosts = searchSources
1510					.filter( item => item.priority > 0 && '' != item.content )
1511					.sort( ( a, b ) => a.priority - b.priority );
1512
1513				if ( '' != listingID && 0 !== responseData.post_count && !error ) {
1514					var outputHtml   = '',
1515						listItemHtml = '',
1516						listHtml     = '<div class="jet-listing-grid__items jet-listing-base ' + settings.listSlideClass.replace( '.', '' ) + '">%s</div>';
1517
1518					if ( listingItems.length ) {
1519						$.each( listingItems, ( i, item ) => {
1520							listItemHtml += item;
1521
1522							if ( ( parseInt( i ) + 1 ) % responseData.limit_query == 0 || parseInt( i ) === listingItems.length - 1 ) {
1523								outputHtml += listHtml.replace( '%s', listItemHtml );
1524								listItemHtml = '';
1525							}
1526						} );
1527					}
1528
1529					messageHolder.removeClass( 'show' );
1530
1531					countAllResults = responseData.post_count;
1532
1533					if ( responseData.sources_results_count && 0 < responseData.sources_results_count ) {
1534						countAllResults += responseData.sources_results_count;
1535					}
1536
1537					$( 'span', countHolder ).html( countAllResults );
1538					resultsListInner
1539						.html( outputHtml )
1540						.data( 'columns', responseData.columns );
1541
1542					Promise.all( JetSearch.assetsPromises ).then( function() {
1543						JetSearch.initElementsHandlers( resultsListInner );
1544						JetSearch.reinitBricksScripts( self );
1545						JetSearch.assetsPromises = [];
1546					} );
1547
1548					resultsHeaderNav.html( responseData.results_navigation.in_header );
1549					resultsFooterNav.html( responseData.results_navigation.in_footer );
1550
1551					if ( !countHolder[0] && !responseData.results_navigation.in_header ) {
1552						resultsHeader.addClass( 'is-empty' );
1553					} else {
1554						resultsHeader.removeClass( 'is-empty' );
1555					}
1556
1557					if ( !fullResults[0] && !responseData.results_navigation.in_footer ) {
1558						resultsFooter.addClass( 'is-empty' );
1559					} else {
1560						resultsFooter.removeClass( 'is-empty' );
1561					}
1562
1563					resultsList.css( 'height', 'auto' );
1564
1565					$( document ).trigger( 'jet-ajax-search/show-results/listing', [ resultsListInner ] );
1566
1567					resultsHolder.addClass( 'show' );
1568
1569					if ( 'yes' === searchLogging || true === searchLogging ) {
1570						let itemWrapper = settings.itemClass,
1571							itemLink    = $( '.jet-engine-listing-overlay-wrap', itemWrapper ),
1572							itemTitle   = '.jet-ajax-search-item-title .jet-listing-dynamic-field__content',
1573							itemUrlAttr = 'data-url';
1574
1575						$( document ).trigger( 'jet-ajax-search/results-area/listing-ad
1575d-suggestion', [ self, itemWrapper, itemLink, itemTitle, itemUrlAttr ] );
1576
1577						JetSearch.addSuggestionFromResultAreaItem( itemWrapper, itemLink, itemTitle, itemUrlAttr );
1578					}
1579				}
1580
1581				const allowedHighlightFields = [ 'title', 'after_content', 'after_title', 'before_content', 'before_title', 'content', 'price' ];
1582
1583				function highlightMatches( item ) {
1584					let searched = responseData.search_value.trim();
1585
1586					if ( searched !== "" ) {
1587						let reg     = new RegExp("[\>][^\<]*"+searched+"[^\<]*[\<]","gi"),
1588							reg2    = new RegExp( searched, "gi" ),
1589							regHtml = new RegExp("<\/?[a-z](.*?)[\s\S]*>", "gi");
1590
1591						if ( reg.test( item ) ) {
1592							item = item.replace( reg, function( item ) {
1593								let subRegex = new RegExp( searched, "gi" );
1594								return item.replace( subRegex,`<mark>${searched}</mark>` );
1595							} );
1596						}
1597
1598						if ( regHtml.test( item ) ) {
1599							return item;
1600						} else {
1601							item = item.replace( reg2, str => `<mark>${str}</mark>` );
1602						}
1603					}
1604
1605					return item;
1606				}
1607
1608				function highlightFields( fields, allowHighlightFields ) {
1609
1610					$.each( fields, function( key, value ) {
1611						if ( -1 != $.inArray( key, allowHighlightFields ) && ( null != value && '' != value ) ) {
1612							fields[key] = highlightMatches( value );
1613						}
1614					} );
1615
1616					return fields;
1617				}
1618
1619				if ( 0 !== responseData.post_count && !error && '' === listingID) {
1620
1621					messageHolder.removeClass( 'show' );
1622					itemTemplate = wp.template( 'jet-ajax-search-results-item' );
1623
1624					for ( post in posts ) {
1625						if ( responseData.search_highlight && true === responseData.search_highlight ) {
1626							if ( '' != hightlightText && ( "yes" === hightlightText || true === hightlightText ) ) {
1627								highlightFields( posts[post], allowedHighlightFields );
1628							}
1629						}
1630
1631						if ( posts[post].is_product ) {
1632							let productType = posts[post].product_type,
1633								productTypeClass = 'add-to-cart-button';
1634
1635							if ( 'product_type_variable' === productType ) {
1636								productTypeClass = 'select-options-button';
1637							}
1638
1639							posts[post].add_to_cart = '<div class="jet-ajax-search__item-add-to-cart"><button data-quantity="1" class="jet-ajax-search__results-item-cart-button ' + productTypeClass + '" data-product_id="' + posts[post].product_id + '" data-product_sku="' + posts[post].product_sku + '" aria-label="' + posts[post].product_label + '" data-product_url="' + posts[post].product_url + '" rel="nofollow" target="_blank">' + posts[post].product_add_text + '</button></div>';
1640						}
1641
1642						let templateResult = itemTemplate( posts[post] );
1643
1644						listItemHtml += templateResult;
1645
1646						if ( (parseInt( post ) + 1) % responseData.limit_query == 0 || parseInt( post ) === posts.length - 1 ) {
1647							outputHtml += listHtml.replace( '%s', listItemHtml );
1648							listItemHtml = '';
1649						}
1650					}
1651
1652					countAllResults = responseData.post_count;
1653
1654					if ( responseData.sources_results_count && 0 < responseData.sources_results_count ) {
1655						countAllResults += responseData.sources_results_count;
1656					}
1657
1658					$( 'span', countHolder ).html( countAllResults );
1659					resultsListInner
1660						.html( outputHtml )
1661						.data( 'columns', responseData.columns );
1662
1663					$( '.jet-ajax-search__results-item-cart-button.add-to-cart-button', self ).on( 'click', function( e ) {
1664						e.preventDefault();
1665
1666						let _this = $( this);
1667
1668						if ( _this.attr( 'data-product_id' ) ) {
1669							let addToCartData = {};
1670
1671							$.each( _this[0].dataset, function( key, value ) {
1672								addToCartData[ key ] = value;
1673							} );
1674
1675							_this.prop( 'disabled', true );
1676
1677							$.ajax( {
1678								type: 'POST',
1679								url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ),
1680								dataType: 'json',
1681								data: addToCartData,
1682								success: function( response ) {
1683									$( document.body ).trigger( 'wc_fragment_refresh' );
1684									$( document.body ).trigger( 'added_to_cart' );
1685
1686									_this.prop( 'disabled', false );
1687								},
1688								error: function(xhr, status, error) {
1689									_this.prop( 'disabled', false );
1690								}
1691							} );
1692						}
1693					} );
1694
1695					$( '.jet-ajax-search__results-item-cart-button.select-options-button', self ).on( 'click', function( e ) {
1696						e.preventDefault();
1697
1698						const productUrl = $( this ).data( 'product_url' );
1699
1700						window.open( productUrl, '_blank' );
1701					} );
1702
1703					resultsHeaderNav.html( responseData.results_navigation.in_header );
1704					resultsFooterNav.html( responseData.results_navigation.in_footer );
1705
1706					if ( !countHolder[0] && !responseData.results_navigation.in_header ) {
1707						resultsHeader.addClass( 'is-empty' );
1708					} else {
1709						resultsHeader.removeClass( 'is-empty' );
1710					}
1711
1712					if ( !fullResults[0] && !responseData.results_navigation.in_footer ) {
1713						resultsFooter.addClass( 'is-empty' );
1714					} else {
1715						resultsFooter.removeClass( 'is-empty' );
1716					}
1717
1718					resultsHolder.addClass( 'show' );
1719
1720					$( document ).trigger( 'jet-ajax-search/show-results', [ resultsHolder ] );
1721
1722					var inputField  = $( '.jet-ajax-search__field', self ),
1723						resultsItem = $( '.jet-ajax-search__item-link', self ),
1724						focusedItem = resultsItem.filter( ':focus' );
1725
1726					inputField.on( 'keydown', function( e ) {
1727						const keyCode = e.keyCode || e.which;
1728
1729						if ( 40 === keyCode ) { // Down arrow
1730							e.preventDefault();
1731
1732							var position    = currentPosition - 1,
1733								activeSlide = $( settings.listSlideClass, resultsListInner ).eq( position ),
1734								next        = activeSlide.find( '.jet-ajax-search__item-link' ).first();
1735
1736							if ( focusedItem.length === 0 ) {
1737								setTimeout( () => {
1738									resultsItem.removeClass( 'focused' );
1739									next.addClass( 'focused' );
1740									next.focus();
1741								}, 0 );
1742							}
1743						}
1744					} );
1745
1746					resultsItem.on( 'keydown', function( e ) {
1747						const keyCode = e.keyCode || e.which;
1748
1749						switch ( keyCode ) {
1750							case 40: // Down arrow
1751								e.preventDefault();
1752
1753								var next = $( this ).parent().next().find( '.jet-ajax-search__item-link' ).first();
1754
1755								if ( 0 < next.length ) {
1756									resultsItem.removeClass( 'focused' );
1757									next.addClass( 'focused' );
1758									next.focus();
1759								}
1760								break;
1761
1762							case 38: // Up arrow
1763								e.preventDefault();
1764
1765								var prev = $( this ).parent().prev().find( '.jet-ajax-search__item-link' ).first();
1766
1767								if ( 0 < prev.length ) {
1768									resultsItem.removeClass( 'focused' );
1769									prev.addClass( 'focused' );
1770									prev.focus();
1771								} else {
1772									resultsItem.removeClass( 'focused' );
1773									inputField.focus();
1774								}
1775								break;
1776
1777							case 37: // Left arrow
1778								var prevSlide = $( this ).closest( '.jet-ajax-search__results-slide' ).prev();
1779
1780								if ( 0 < prevSlide.length ) {
1781
1782									$( settings.prevClass + ':not( ' + settings.disableNavClass + ' )' ).click();
1783
1784									resultsItem.removeClass( 'focused' );
1785
1786									setTimeout( () => {
1787										$( settings.listSlideClass, resultsListInner ).eq( currentPosition - 1 ).find( '.jet-ajax-search__item-link' ).first().focus().addClass( 'focused' );
1788									}, 350 );
1789								}
1790								break;
1791
1792							case 39: // Right arrow
1793								var nextSlide = $( this ).closest( '.jet-ajax-search__results-slide' ).next();
1794
1795								if ( 0 < nextSlide.length ) {
1796
1797									$( settings.nextClass + ':not( ' + settings.disableNavClass + ' )' ).click();
1798
1799									resultsItem.removeClass( 'focused' );
1800
1801									setTimeout( () => {
1802										$( settings.listSlideClass, resultsListInner ).eq( currentPosition - 1 ).find( '.jet-ajax-search__item-link' ).first().focus().addClass( 'focused' );
1803									}, 350 );
1804								}
1805								break;
1806							case 9:
1807								resultsItem.removeClass( 'focused' );
1808								break;
1809						}
1810					} );
1811
1812					if ( 'yes' === searchLogging || true === searchLogging ) {
1813						let	itemWrapper           = settings.itemClass,
1814							resultAreaItemLink    = $( '.jet-ajax-search__item-link', itemWrapper ),
1815							resultAreaItemTitle   = '.jet-ajax-search__item-title',
1816							resultAreaItemUrlAttr = 'href';
1817
1818						JetSearch.addSuggestionFromResultAreaItem( itemWrapper, resultAreaItemLink, resultAreaItemTitle, resultAreaItemUrlAttr );
1819					}
1820
1821					searchSourcesBeforePosts.forEach( function( item ) {
1822						self.maybeHasListing( item );
1823
1824						resultsListInner.before( item.content );
1825						resultsHolder.addClass( 'show' );
1826					} );
1827
1828					searchSourcesAfterPosts.forEach( function( item ) {
1829						self.maybeHasListing( item );
1830
1831						resultsListInner.after( item.content );
1832						resultsHolder.addClass( 'show' );
1833					} );
1834				} else {
1835
1836					if ( searchSourcesBeforePosts.length || searchSourcesAfterPosts.length ) {
1837						searchSourcesBeforePosts.forEach( function( item ) {
1838							self.maybeHasListing( item );
1839
1840							resultsListInner.before( item.content );
1841							resultsHolder.addClass( 'show' );
1842						} );
1843
1844						searchSourcesAfterPosts.forEach( function( item ) {
1845							self.maybeHasListing( item );
1846
1847							resultsListInner.after( item.content );
1848							resultsHolder.addClass( 'show' );
1849						} );
1850
1851						countAllResults = responseData.post_count;
1852
1853						if ( responseData.sources_results_count && 0 < responseData.sources_results_count ) {
1854							countAllResults += responseData.sources_results_count;
1855						}
1856
1857						$( 'span', countHolder ).html( countAllResults );
1858
1859					} else {
1860						self.outputMessage( message, 'show' );
1861					}
1862				}
1863			};
1864
1865			self.maybeHasListing = function( item ) {
1866				if ( typeof item.listing_template !== 'undefined' && true === item.listing_template ) {
1867					Promise.all( JetSearch.assetsPromises ).then( function() {
1868						JetSearch.initElementsHandlers( resultsListInner );
1869						JetSearch.reinitBricksScripts( self );
1870						JetSearch.assetsPromises = [];
1871					} );
1872				}
1873			}
1874
1875			self.errorCallback = function( jqXHR ) {
1876				if ( 'abort' !== jqXHR.statusText ) {
1877					spinner.removeClass( 'show' );
1878					self.outputMessage( data.server_error, 'error show' );
1879				}
1880			};
1881
1882			self.ajaxSendData = function( sendData, lang = '' ) {
1883				let filteredData = {};
1884
1885				Object.keys( sendData ).forEach( key => {
1886					if (
1887						sendData[key] !== '' &&
1888						sendData[key] !== null &&
1889						sendData[key] !== undefined &&
1890						!( Array.isArray( sendData[key] ) && sendData[key].length === 0 )
1891					) {
1892						filteredData[key] = sendData[key];
1893					}
1894				} );
1895
1896				var ajaxData = {
1897					action: self.ajaxSettings.action,
1898					nonce: self.ajaxSettings.nonce,
1899					data: filteredData || {}
1900				};
1901
1902				if ( '' != lang ) {
1903					ajaxData.lang = lang;
1904				}
1905
1906				const isRestAPI = self.ajaxSettings.rest_api_url && self.ajaxSettings.rest_api_url.includes( '/wp-json/' );
1907
1908				self.ajaxRequest = jQuery.ajax( {
1909					type: 'GET',
1910					url: self.ajaxSettings.rest_api_url,
1911					data: ajaxData,
1912					dataType: 'json',
1913					cache: false,
1914					processData: true,
1915					beforeSend: function( jqXHR, ajaxSettings ) {
1916
1917						if ( null !== self.ajaxRequest ) {
1918							self.ajaxRequest.abort();
1919						}
1920
1921						if ( isRestAPI ) {
1922							jqXHR.setRequestHeader( 'X-WP-Nonce', self.ajaxSettings.nonce );
1923						}
1924
1925					},
1926					error: function( jqXHR, textStatus, errorThrown ) {
1927						self.errorCallback( jqXHR );
1928					},
1929					success: function( response, textStatus, jqXHR ) {
1930						self.successCallback( response );
1931					}
1932				} );
1933			};
1934
1935			self.hideList = function() {
1936				resultsArea.removeClass( 'show' );
1937				$( '.chosen-single', self ).removeClass( 'focused' );
1938			};
1939
1940			self.showList = function() {
1941				resultsArea.addClass( 'show' );
1942			};
1943
1944			self.focusHandler = function( event ) {
1945				var value = event.target.value,
1946					symbolNumberForStart = 'number' === $.type( data.symbols_for_start_searching ) ? data.symbols_for_start_searching : 2;
1947
1948				$( settings.searchFormClass, self ).addClass( formFocusClass );
1949
1950				if ( 'inside_results_area' === suggestionsPosition && suggestionsList.length ) {
1951					if ( value && getResultsOnFocus ) {
1952						spinner.addClass( 'show' );
1953
1954						data.value      = value;
1955						data.deviceMode = window.elementorFrontend && window.elementorFrontend.getCurrentDeviceMode() ? window.elementorFrontend.getCurrentDeviceMode() : JetSearch.getCurrentDeviceMode();
1956
1957						self.ajaxSendData( data, lang );
1958
1959						getResultsOnFocus = false;
1960					}
1961
1962					if ( '' === value ) {
1963						resultsHeader.hide();
1964						resultsFooter.hide();
1965						resultsList.hide();
1966						resultsSuggestions.addClass( 'active' );
1967						resultsHolder.addClass( 'show' );
1968						self.showList();
1969					}
1970				}
1971
1972				if ( 'number' === $.type( symbolNumberForStart ) && symbolNumberForStart > value.length ) {
1973					return;
1974				}
1975
1976				self.showList();
1977			};
1978
1979			self.blurHandler = function( event ) {
1980				$( settings.searchFormClass, self ).removeClass( formFocusClass );
1981			};
1982
1983			self.outputMessage = function( message, messageClass ) {
1984				message = message.replace( /\\/g, '' ); // remove slashes
1985				//message = $( "<div/>" ).html( message ).text();
1986				message = message.replace( /\\*"/g, '' );
1987				messageHolder.removeClass( 'error show' ).addClass( messageClass ).html( message );
1988			};
1989
1990			self.formClick = function( event ) {
1991				event.stopPropagation();
1992			};
1993
1994			self.clickFullResults = function( event ) {
1995
1996				var searchInput = $( settings.inputClass, self ),
1997					value       = searchInput.val(),
1998					url         = JetSearch.getResultsUrl( form );
1999
2000				event.preventDefault();
2001
2002				if ( value.length != 0 || true === allowEmptyString ) {
2003					if ( false === disableInputs ) {
2004						disableInputs = true;
2005
2006						value = value.replace(/\u3000/g, ' ');
2007
2008						searchInput.val( value );
2009
2010						if ( '' != customResultUrl ) {
2011							customResultUrl = $.trim( customResultUrl );
2012
2013							url = JetSearch.getResultsUrl( form, customResultUrl );
2014						}
2015
2016						if ( 'yes' === showSearchSuggestions || true === showSearchSuggestions ) {
2017							self.addUserSearch( value );
2018						}
2019
2020						if ( 'yes' === searchLogging || true === searchLogging ) {
2021							JetSearch.setFormSuggestion( value, form, url );
2022						} else {
2023							window.location.href = url;
2024						}
2025					}
2026				}
2027			};
2028
2029			self.changeSlide = function( number ) {
2030				var currentSlide = $( settings.listSlideClass, resultsListInner ).eq( number ),
2031					direction    = settings.isRtl ? 1 : -1,
2032					position     = number * 100 * direction;
2033
2034				currentSlide.scrollTop( 0 );
2035				resultsListInner.css( 'transform', 'translateX(' + position + '%)' );
2036				resultsList.css( 'height', 'auto' );
2037			};
2038
2039			self.clickBulletHandler = function( event ) {
2040				var target = $( event.target );
2041
2042				currentPosition = target.data( 'number' );
2043				self.syncNavigation();
2044
2045				self.changeSlide( currentPosition - 1 );
2046			};
2047
2048			self.clickNavigationButtonHandler = function( event ) {
2049				var target    = $( event.target ),
2050					direction = target.data( 'direction' );
2051
2052				currentPosition = currentPosition + direction;
2053				self.syncNavigation();
2054
2055				self.changeSlide( currentPosition - 1 );
2056			};
2057
2058			self.syncNavigation = function() {
2059				var lastPosition = resultsListInner.data( 'columns' ),
2060					disableClass = settings.disableNavClass.replace( '.', '' ),
2061					activeClass  = settings.activeNavClass.replace( '.', '' );
2062
2063				$( settings.activeNavClass, self ).removeClass( activeClass );
2064				$( settings.disableNavClass, self ).removeClass( disableClass );
2065
2066				$( settings.navButtonClass + '[data-number="' + currentPosition +'"]', self ).addClass( activeClass );
2067
2068				if ( 1 === currentPosition ) {
2069					$( settings.prevClass, self ).addClass( disableClass );
2070				}
2071
2072				if ( lastPosition === currentPosition ) {
2073					$( settings.nextClass, self ).addClass( disableClass );
2074				}
2075			};
2076
2077			self.formSubmit = function( event ) {
2078				var value = event.target.value,
2079					url   = JetSearch.getResultsUrl( form );
2080
2081				if ( ( 1 > value.length && false === allowEmptyString ) && ( 13 === event.keyCode || 'click' === event.type ) ) {
2082					return false;
2083				} else {
2084					if ( 13 === event.keyCode && allowSubmitOnEnter ) {
2085						if ( false === disableInputs ) {
2086							disableInputs = true;
2087
2088							event.preventDefault();
2089
2090							if ( '' != customResultUrl ) {
2091								customResultUrl = $.trim( customResultUrl );
2092
2093								url = JetSearch.getResultsUrl( form, customResultUrl );
2094							}
2095
2096							self.addUserSearch( value );
2097
2098							if ( 'yes' === searchLogging || true === searchLogging ) {
2099								JetSearch.setFormSuggestion( value, form, url );
2100							} else {
2101								window.location.href = url;
2102							}
2103						}
2104					}
2105				}
2106			};
2107
2108			self.changeHandler = function( event ) {
2109				var target              = $( event.target ),
2110					globalQuerySettings = $( self ).data( 'settings' );
2111
2112				globalQuerySettings.category__in = target.val();
2113				data.category__in                = target.val();
2114
2115				$( self ).data( 'settings', globalQuerySettings );
2116
2117				self.inputChangeHandler( { target: $( settings.inputClass, self ) } )
2118			};
2119
2120			self.chosenFocusHandler = function() {
2121				self.hideList();
2122			};
2123
2124			self.setResultsAreaWidth = function() {
2125
2126				if ( 'fields_holder' !== data.results_area_width_by ) {
2127					return;
2128				}
2129
2130				resultsArea.css( 'width', $( settings.fieldsHolderClass, self ).outerWidth() );
2131			};
2132
2133			self.addUserSearch = function( newSearchRequest ) {
2134				if ( 'user' === suggestionsType ) {
2135					newSearchRequest = newSearchRequest.trim();
2136
2137					if ( ! storedUserSearches.some( search => search === newSearchRequest ) ) {
2138						if ( storedUserSearches.length >= maxUserSearches ) {
2139							storedUserSearches.shift();
2140						}
2141
2142						storedUserSearches.push( newSearchRequest );
2143
2144						localStorage.setItem( 'jetUserSearches', JSON.stringify( storedUserSearches ) );
2145					}
2146				}
2147			}
2148
2149			self.selectSuggestion = function( event ) {
2150				const keyCode = event.keyCode || event.which;
2151				const $target = $( event.currentTarget );
2152
2153				let value = $target.attr( 'aria-label' );
2154
2155				if ( ! value ) {
2156					return;
2157				}
2158
2159				value = value.trim();
2160
2161				let url = null;
2162
2163				if ( false === disableInputs && !editMode ) {
2164
2165					if ( 'keydown' === event.type ) {
2166						if ( 13 === keyCode ) {
2167							disableInputs = true;
2168
2169							$( settings.inputClass, self )[0].value = value;
2170
2171							self.addUserSearch( value );
2172
2173							url = JetSearch.getResultsUrl( form );
2174
2175							if ( '' != customResultUrl ) {
2176								customResultUrl = $.trim( customResultUrl );
2177
2178								url = JetSearch.getResultsUrl( form, customResultUrl );
2179							}
2180
2181							if ( 'yes' === searchLogging || true === searchLogging ) {
2182								JetSearch.setFormSuggestion( value, false, url );
2183							} else {
2184								window.location.href = url;
2185							}
2186						}
2187					} else if ( 'click' === event.type ) {
2188						disableInputs = true;
2189
2190						$( settings.inputClass, self )[0].value = value;
2191
2192						self.addUserSearch( value );
2193
2194						url = JetSearch.getResultsUrl( form );
2195
2196						if ( '' != customResultUrl ) {
2197							customResultUrl = $.trim( customResultUrl );
2198
2199							url = JetSearch.getResultsUrl( form, customResultUrl );
2200						}
2201
2202						if ( 'yes' === searchLogging || true === searchLogging ) {
2203							JetSearch.setFormSuggestion( value, false, url );
2204						} else {
2205							window.location.href = url;
2206						}
2207					}
2208				}
2209			}
2210
2211			self.customUrlActions = {
2212				selectorOnClick: 'a[href^="#jet-engine-action"][href*="event=click"]',
2213				selectorOnHover: 'a[href^="#jet-engine-action"][href*="event=hover"], [data-url^="#jet-engine-action"][data-url*="event=hover"]',
2214
2215				init: function() {
2216					var timeout = null;
2217
2218					$( document ).on( 'click.JetSearch', this.selectorOnClick, function( event ) {
2219						event.preventDefault();
2220						self.customUrlActions.actionHandler( event )
2221					} );
2222
2223					$( document ).on( 'click.JetSearch', this.selectorOnHover, function( event ) {
2224						if ( 'A' === event.currentTarget.nodeName ) {
2225							event.preventDefault();
2226						}
2227					} );
2228
2229					$( document ).on( {
2230						'mouseenter.JetSearch': function( event ) {
2231
2232							if ( timeout ) {
2233								clearTimeout( timeout );
2234							}
2235
2236							timeout = setTimeout( function() {
2237								self.customUrlActions.actionHandler( event )
2238							}, window.JetEngineSettings.hoverActionTimeout );
2239						},
2240						'mouseleave.JetSearch': function() {
2241							if ( timeout ) {
2242								clearTimeout( timeout );
2243								timeout = null;
2244							}
2245						},
2246					}, this.selectorOnHover );
2247				},
2248
2249				actions: {},
2250
2251				addAction: function( name, callback ) {
2252					this.actions[ name ] = callback;
2253				},
2254
2255				actionHandler: function( event ) {
2256					var url = $( event.currentTarget ).attr( 'href' ) || $( event.currentTarget ).attr( 'data-url' );
2257
2258					this.runAction( url );
2259				},
2260
2261				runAction: function( url ) {
2262					var queryParts = url.split( '&' ),
2263						settings = {};
2264
2265					queryParts.forEach( function( item ) {
2266						if ( -1 !== item.indexOf( '=' ) ) {
2267							var pair = item.split( '=' );
2268
2269							settings[ pair[0] ] = decodeURIComponent( pair[1] );
2270						}
2271					} );
2272
2273					if ( ! settings.action ) {
2274						return;
2275					}
2276
2277					var actionCb = this.actions[ settings.action ];
2278
2279					if ( ! actionCb ) {
2280						return;
2281					}
2282
2283					actionCb( settings );
2284				}
2285			};
2286
2287			self.handleListingItemClick = function( event ) {
2288				var url	   = $( this ).data( 'url' ),
2289					target = $( this ).data( 'target' ) || false;
2290
2291				if ( url ) {
2292
2293					event.preventDefault();
2294
2295					if ( window.elementorFrontend && window.elementorFrontend.isEditMode() ) {
2296						return;
2297					}
2298
2299					if ( -1 !== url.indexOf( '#jet-engine-action' ) ) {
2300
2301						self.customUrlActions.runAction( url );
2302
2303					} else {
2304
2305						if ( '_blank' === target ) {
2306							window.open( url );
2307							return;
2308						}
2309
2310						window.location = url;
2311					}
2312				}
2313			};
2314
2315			self.isWooAddToCartTrigger = function( $target ) {
2316
2317				if ( $target.data( 'product_id' ) || $target.attr( 'data-product_id' ) ) {
2318					return true;
2319				}
2320
2321				const href = $target.attr( 'href' ) || '';
2322
2323				if ( href && href.includes( 'add-to-cart=' ) ) {
2324					return true;
2325				}
2326
2327				if ( $target.closest( 'form.cart' ).length ) {
2328					return true;
2329				}
2330
2331				if ( $target.is( '.add_to_cart_button, .ajax_add_to_cart, .single_add_to_cart_button' ) ) {
2332					return true;
2333				}
2334
2335				return false;
2336			};
2337
2338			self.getWooAddToCartData = function( $trigger ) {
2339				let addToCartData = {},
2340					href          = $trigger.attr( 'href' ) || '',
2341					form          = $trigger.closest( 'form.cart' ),
2342					productId     = $trigger.attr( 'data-product_id' ) || $trigger.data( 'product_id' ) || '',
2343					quantity      = $trigger.attr( 'data-quantity' ) || $trigger.data( 'quantity' ) || 1;
2344
2345				$.each( $trigger[0].dataset || {}, function( key, value ) {
2346					addToCartData[ key ] = value;
2347				} );
2348
2349				if ( form.length ) {
2350					$.each( form.serializeArray(), function( index, field ) {
2351						if ( '' !== field.value ) {
2352							addToCartData[ field.name ] = field.value;
2353						}
2354					} );
2355				}
2356
2357				if ( href && -1 !== href.indexOf( 'add-to-cart=' ) && ! productId ) {
2358					try {
2359						let parsedUrl   = new URL( href, window.location.origin ),
2360							hrefProduct = parsedUrl.searchParams.get( 'add-to-cart' );
2361
2362						if ( hrefProduct ) {
2363							productId = hrefProduct;
2364						}
2365					} catch ( e ) {}
2366				}
2367
2368				if ( ! productId && addToCartData.product_id ) {
2369					productId = addToCartData.product_id;
2370				}
2371
2372				if ( ! productId && addToCartData['add-to-cart'] ) {
2373					productId = addToCartData['add-to-cart'];
2374				}
2375
2376				if ( productId ) {
2377					addToCartData.product_id = productId;
2378				}
2379
2380				if ( quantity && ! addToCartData.quantity ) {
2381					addToCartData.quantity = quantity;
2382				}
2383
2384				$( document ).trigger( 'jet-ajax-search/resolve-add-to-cart-data', [ addToCartData, $trigger, self ] );
2385
2386				return addToCartData;
2387			};
2388
2389			self.normalizeWooAddToCartData = function( addToCartData ) {
2390				let normalizedData = {};
2391
2392				if ( addToCartData.product_id ) {
2393					normalizedData.product_id = addToCartData.product_id;
2394				}
2395
2396				if ( addToCartData.quantity ) {
2397					normalizedData.quantity = addToCartData.quantity;
2398				} else {
2399					normalizedData.quantity = 1;
2400				}
2401
2402				if ( addToCartData.variation_id ) {
2403					normalizedData.variation_id = addToCartData.variation_id;
2404				}
2405
2406				$.each( addToCartData, function( key, value ) {
2407					if ( 0 === key.indexOf( 'attribute_' ) ) {
2408						normalizedData[ key ] = value;
2409					}
2410				} );
2411
2412				return normalizedData;
2413			};
2414
2415			self.handleWooAddToCartInResults = function( event ) {
2416				const $trigger = $( event.target ).closest(
2417					'.add_to_cart_button, .ajax_add_to_cart, .single_add_to_cart_button, [data-product_id], a[href*="add-to-cart="], form.cart button'
2418				);
2419
2420				if ( ! $trigger.length || ! self.isWooAddToCartTrigger( $trigger ) ) {
2421					return;
2422				}
2423
2424				if ( 'undefined' === typeof wc_add_to_cart_params || ! wc_add_to_cart_params.wc_ajax_url ) {
2425					return;
2426				}
2427
2428				event.preventDefault();
2429				event.stopImmediatePropagation();
2430
2431				if ( $trigger.prop( 'disabled' ) || $trigger.hasClass( 'loading' ) ) {
2432					return;
2433				}
2434
2435				let addToCartData = self.getWooAddToCartData( $trigger );
2436
2437				addToCartData = self.normalizeWooAddToCartData( addToCartData );
2438
2439				if ( ! addToCartData.product_id ) {
2440					return;
2441				}
2442
2443				$trigger.addClass( 'loading' ).prop( 'disabled', true );
2444
2445				$( document.body ).trigger( 'adding_to_cart', [ $trigger, addToCartData ] );
2446
2447				$.ajax( {
2448					type: 'POST',
2449					url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ),
2450					dataType: 'json',
2451					data: addToCartData,
2452					success: function( response ) {
2453						if ( response && response.error && response.product_url ) {
2454							window.location = response.product_url;
2455							return;
2456						}
2457
2458						if ( response && response.fragments ) {
2459							$.each( response.fragments, function( key, value ) {
2460								$( key ).replaceWith( value );
2461							} );
2462						}
2463
2464						$( document.body ).trigger( 'added_to_cart', [ response.fragments || {}, response.cart_hash || '', $trigger ] );
2465					},
2466					complete: function() {
2467						$trigger.removeClass( 'loading' ).prop( 'disabled', false );
2468					}
2469				} );
2470			};
2471
2472			$( settings.inputClass, self )
2473				.on( 'input' + settings.searchClass, self.inputChangeHandler )
2474				.on( 'focus' + settings.searchClass, self.focusHandler )
2475				.on( 'blur' + settings.searchClass, self.blurHandler )
2476				.on( 'keydown' + settings.searchClass, self.formSubmit );
2477
2478			$( settings.submitClass, self ).on( 'click' + settings.searchClass, self.clickFullResults );
2479
2480			$( self )
2481				.on( 'click' + settings.searchClass, self.formClick )
2482				.on( 'touchend' + settings.searchClass, self.formClick )
2483				.on( 'click' + settings.searchClass, settings.fullResultsClass, self.clickFullResults )
2484				.on( 'click' + settings.searchClass, settings.countClass, self.clickFullResults )
2485				.on( 'click' + settings.searchClass, settings.bulletClass, self.clickBulletHandler )
2486				.on( 'click' + settings.searchClass, settings.numberClass, self.clickBulletHandler )
2487				.on( 'click' + settings.searchClass, settings.prevClass + ':not( ' + settings.disableNavClass + ' )', self.clickNavigationButtonHandler )
2488				.on( 'click' + settings.searchClass, settings.nextClass + ':not( ' + settings.disableNavClass + ' )', self.clickNavigationButtonHandler )
2489				.on( 'click keydown' + settings.searchClass, settings.inlineSuggestionsItemClass, self.selectSuggestion )
2490				.on( 'click keydown' + settings.searchClass, settings.resultsSuggestionItemClass, self.selectSuggestion )
2491				.on( 'change', settings.chosenClass, self.changeHandler )
2492				.on( 'chosen:showing_dropdown', settings.chosenClass, self.chosenFocusHandler )
2493				.on( 'click' + settings.searchClass, '.jet-engine-listing-overlay-wrap:not([data-url*="event=hover"])', self.handleListingItemClick )
2494				.on( 'click' + settings.searchClass,
2495					settings.resultsAreaClass + ' .add_to_cart_button, ' +
2496					settings.resultsAreaClass + ' .ajax_add_to_cart, ' +
2497					settings.resultsAreaClass + ' form.cart .single_add_to_cart_button',
2498					self.handleWooAddToCartInResults
2499				);
2500
2501			if ( ! allowSubmitOnEnter ){
2502				$( window ).keydown( function( event ) {
2503					if ( 13 === event.keyCode && event.target.className.includes( 'jet-ajax-search' ) ) {
2504						event.preventDefault();
2505						return false;
2506					}
2507				});
2508			}
2509
2510			$( self ).on( 'keydown', function( e ) {
2511				const keyCode = e.keyCode || e.which;
2512
2513				if ( 9 === keyCode ) {
2514					setTimeout( () => {
2515						const focusedElement = document.activeElement;
2516
2517						if ( $( focusedElement ).is( '.chosen-search-input' ) ) {
2518							$( '.chosen-single', self ).addClass( 'focused' );
2519						} else {
2520							$( '.chosen-single', self ).removeClass( 'focused' );
2521						}
2522					}, 50 );
2523				}
2524			} );
2525
2526			$( settings.inputClass, self ).on( 'click' + settings.searchClass, () => {
2527				$( '.chosen-single', self ).removeClass( 'focused' );
2528			} );
2529
2530			if ( '' != categoryIndex ) {
2531				let target              = $( settings.chosenClass, self ),
2532					globalQuerySettings = $( self ).data( 'settings' ),
2533					categorySelect      = $( '.jet-ajax-search__categories-select', self ),
2534					currentCategory     = '';
2535
2536				categorySelect.find( 'option' ).each( function() {
2537					var value = $( this ).val();
2538
2539					if ( value === categoryIndex ) {
2540						currentCategory = $( this ).text();
2541					}
2542				} );
2543
2544				categorySelect.find( 'option:contains("' + currentCategory + '")' ).attr( 'selected', 'selected' );
2545
2546				globalQuerySettings.category__in = target.val();
2547				data.category__in                = target.val();
2548
2549				$( self ).data( 'settings', globalQuerySettings );
2550			} else {
2551				// If after reloading the page the value of the select is not '0'.
2552
2553				if ( '0' !== $( settings.chosenClass, self ).val() ) {
2554					$( settings.chosenClass, self ).trigger( 'change' );
2555				}
2556			}
2557
2558			$( 'body' )
2559				.on( 'click' + settings.searchClass, self.hideList )
2560				.on( 'touchend' + settings.searchClass, self.hideList );
2561
2562			self.setResultsAreaWidth();
2563			$( window ).on( 'resize' + settings.searchClass, self.setResultsAreaWidth );
2564
2565			$( window ).on( 'orientationchange resize', function () {
2566				resultsListInner.imagesLoaded( function() {
2567					const $firstSlide      = $( settings.listSlideClass, resultsListInner ).eq(0);
2568					const firstSlideHeight = $firstSlide.length ? $firstSlide.outerHeight() : 0;
2569
2570					resultsList.css( 'height', firstSlideHeight > 0 ? firstSlideHeight : 'auto' );
2571				} );
2572			} );
2573
2574		} else {
2575			return 'is init: true';
2576		}
2577	};
2578
2579	// initialize after all is defined
2580	$( window ).on( 'elementor/frontend/init', JetSearch.initElementor );
2581	JetSearch.initBlocks();
2582
2583	window.jetSearchBricks = function() {
2584		JetSearch.initBricks();
2585	}
2586
2587	window.JetSearch = JetSearch;
2588
2589}( jQuery ));

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.