PageSourceSearch

https://recalls.vornado.com/wp-content/themes/shopkeeper/inc/search/assets/js/search.js

js vornado.com collected 2026-10-03 23:16:55 UTC 34,041 bytes, 954 lines download raw bytes

1/**
2 *  Ajax Autocomplete for jQuery, version 1.2.27
3 *  (c) 2015 Tomas Kirda
4 *
5 *  Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
6 *  For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete
7 *
8 *  Modified by Damian Góra: http://damiangora.com
9 */
10
11/*jslint  browser: true, white: true, single: true, this: true, multivar: true */
12/*global define, window, document, jQuery, exports, require */
13
14// Expose plugin as an AMD module if AMD loader is present:
15( function ( factory ) {
16    "use strict";
17    if ( typeof define === 'function' && define.amd ) {
18        // AMD. Register as an anonymous module.
19        define( [ 'jquery' ], factory );
20    } else if ( typeof exports === 'object' && typeof require === 'function' ) {
21        // Browserify
22        factory( require( 'jquery' ) );
23    } else {
24        // Browser globals
25        factory( jQuery );
26    }
27}( function ( $ ) {
28    'use strict';
29
30    var utils = ( function () {
31        return {
32            escapeRegExChars: function ( value ) {
33                return value.replace( /[|\\{}()[\]^$+*?.]/g, "\\$&" );
34            },
35            createNode: function ( containerClass ) {
36                var div = document.createElement( 'div' );
37                div.className = containerClass;
38                div.style.display = 'none';
39                return div;
40            }
41        };
42    }() ),
43        keys = {
44            ESC: 27,
45            TAB: 9,
46            RETURN: 13,
47            LEFT: 37,
48            UP: 38,
49            RIGHT: 39,
50            DOWN: 40
51        };
52
53    function Autocomplete( el, options ) {
54        var noop = $.noop,
55            that = this,
56            defaults = {
57                ajaxSettings: { },
58                autoSelectFirst: false,
59                appendTo: document.body,
60                serviceUrl: null,
61                lookup: null,
62                onSelect: null,
63                onMouseOver: null,
64                onMouseLeave: null,
65                width: '100%',
66                minChars: 1,
67                maxHeight: 1000,
68                deferRequestBy: 0,
69                params: { },
70                delimiter: null,
71                zIndex: 9999,
72                type: 'GET',
73                noCache: false,
74                is_rtl: false,
75                onSearchStart: noop,
76                onSearchComplete: noop,
77                onSearchError: noop,
78                preserveInput: false,
79                wrapperaClass: 'search-wrapp',
80                containerClass: 'search-suggestions-wrapp',
81                preloaderClass: 'search-preloader',
82                closeTrigger: 'search-close',
83                tabDisabled: false,
84                dataType: 'text',
85                currentRequest: null,
86                triggerSelectOnValidInput: true,
87                preventBadQueries: true,
88                lookupFilter: function ( suggestion, originalQuery, queryLowerCase ) {
89                    return suggestion.value.toLowerCase().indexOf( queryLowerCase ) !== -1;
90                },
91                paramName: 'query',
92                transformResult: function ( response ) {
93                    return typeof response === 'string' ? JSON.parse( response ) : response;
94                },
95                showNoSuggestionNotice: false,
96                noSuggestionNotice: 'No results',
97                orientation: 'bottom'
98            };
99
100        // Shared variables:
101        that.element = el;
102        that.el = $( el );
103        that.suggestions = [ ];
104        that.badQueries = [ ];
105        that.selectedIndex = -1;
106        that.currentValue = that.element.value;
107        that.intervalId = 0;
108        that.cachedResponse = { };
109        that.detailsRequestsSent = [ ];
110        that.onChangeInterval = null;
111        that.onChange = null;
112        that.isLocal = false;
113        that.suggestionsContainer = null;
114        that.detailsContainer = null;
115        that.noSuggestionsContainer = null;
116        that.options = $.extend( { }, defaults, options );
117        that.classes = {
118            selected: 'search-suggestion-selected',
119            suggestion: 'search-suggestion'
120        };
121        that.hint = null;
122        that.hintValue = '';
123        that.selection = null;
124
125        // Initialize and set options:
126        that.initialize();
127        that.setOptions( options );
128    }
129
130    Autocomplete.utils = utils;
131
132    $.Autocomplete = Autocomplete;
133
134    Autocomplete.prototype = {
135        killerFn: null,
136        initialize: function () {
137            var that = this,
138                suggestionSelector = '.' + that.classes.suggestion,
139                selected = that.classes.selected,
140                options = that.options,
141                container,
142                closeTrigger = '.' + options.closeTrigger;
143
144            that.killerFn = function ( e ) {
145                if ( $( e.target ).closest( '.' + that.options.containerClass ).length === 0 ) {
146                    that.killSuggestions();
147                    that.disableKillerFn();
148                }
149            };
150
151            // html() deals with many types: htmlString or Element or Array or jQuery
152            // that.noSuggestionsContainer = $( '<li class="search-no-suggestion"></li>' )
153            //     .html( this.options.noSuggestionNotice ).get( 0 );
154
155            // Create sugestions container
156            that.suggestionsContainer = Autocomplete.utils.createNode( options.containerClass );
157
158            container = $( that.suggestionsContainer );
159
160            container.appendTo( that.el.closest( '.' + options.wrapperaClass ) );
161
162            // Only set width if it was provided:
163            if ( options.width !== 'auto' ) {
164                container.width( options.width );
165            }
166
167            // Listen for mouse over event on suggestions list:
168            container.on( 'mouseover.autocomplete', suggestionSelector, function () {
169                that.onMouseOver( $( this ).data( 'index' ) );
170                that.activate( $( this ).data( 'index' ) );
171            } );
172
173            // Deselect active element when mouse leaves suggestions container:
174            container.on( 'mouseout.autocomplete', function () {
175                //that.selectedIndex = -1;
176                // container.children( '.' + selected ).removeClass( selected );
177            } );
178
179            // Listen for click event on suggestions list:
180            $( document ).on( 'click.autocomplete', closeTrigger, function ( e ) {
181                that.killerFn( e );
182                that.clear( e );
183                $( this ).removeClass( options.closeTrigger );
184                that.el.val( '' ).focus();
185            } );
186
187            // Listen for click close button:
188            container.on( 'click.autocomplete', suggestionSelector, function () {
189                that.select( $( this ).data( 'index' ) );
190                return false;
191            } );
192
193            that.el.on( 'keydown.autocomplete', function ( e ) {
194                that.onKeyPress( e );
195            } );
196            that.el.on( 'keyup.autocomplete', function ( e ) {
197                that.onKeyUp( e );
198            } );
199            // that.el.on( 'blur.autocomplete', function () {
200            //     that.onBlur();
201            // } );
202            // that.el.on( 'focus.autocomplete', function () {
203            //     that.onFocus();
204            // } );
205            that.el.on( 'change.autocomplete', function ( e ) {
206                that.onKeyUp( e );
207            } );
208            that.el.on( 'input.autocomplete', function ( e ) {
209                that.onKeyUp( e );
210            } );
211        },
212        onFocus: function () {
213            var that = this;
214            if ( that.el.val().length >= that.options.minChars ) {
215                that.onValueChange();
216            }
217        },
218        onBlur: function () {
219            this.enableKillerFn();
220        },
221        abortAjax: function () {
222            var that = this;
223            if ( that.currentRequest ) {
224                that.currentRequest.abort();
225                that.currentRequest = null;
226            }
227        },
228        setOptions: function ( suppliedOptions ) {
229            var that = this,
230                options = that.options;
231
232            $.extend( options, suppliedOptions );
233
234            that.isLocal = Array.isArray( options.lookup );
235
236            if ( that.isLocal ) {
237                options.lookup = that.verifySuggestionsFormat( options.lookup );
238            }
239
240            options.orientation = that.validateOrientation( options.orientation, 'bottom' );
241
242            that.options.onSearchComplete = function () {
243                that.preloader( 'hide', $( '.' + options.preloaderClass ), options.closeTrigger );
244            };
245
246
247        },
248        clearCache: function () {
249            this.cachedResponse = { };
250            this.badQueries = [ ];
251        },
252        clear: function () {
253            this.clearCache();
254            this.currentValue = '';
255            this.suggestions = [ ];
256        },
257        disable: function () {
258            var that = this;
259            that.disabled = true;
260            clearInterval( that.onChangeInterval );
261            that.abortAjax();
262        },
263        enable: function () {
264            this.disabled = false;
265        },
266        enableKillerFn: function () {
267            var that = this;
268            $( document ).on( 'click.autocomplete', that.killerFn );
269        },
270        disableKillerFn: function () {
271            var that = this;
272            $( document ).off( 'click.autocomplete', that.killerFn );
273        },
274        killSuggestions: function () {
275            var that = this,
276                containerParent = $( that.suggestionsContainer ).parent();
277            that.stopKillSuggestions();
278            that.intervalId = window.setInterval( function () {
279                if ( that.visible ) {
280
281                    // No need to restore value when
282                    // preserveInput === true,
283                    // because we did not change it
284                    if ( !that.options.preserveInput ) {
285                        that.el.val( that.currentValue );
286                    }
287
288                    that.hide();
289                }
290
291                that.stopKillSuggestions();
292            }, 50 );
293        },
294        stopKillSuggestions: function () {
295            window.clearInterval( this.intervalId );
296        },
297        isCursorAtEnd: function () {
298            var that = this,
299                valLength = that.el.val().length,
300                selectionStart = that.element.selectionStart,
301                range;
302
303            if ( typeof selectionStart === 'number' ) {
304                return selectionStart === valLength;
305            }
306            if ( document.selection ) {
307                range = document.selection.createRange();
308                range.moveStart( 'character', -valLength );
309                return valLength === range.text.length;
310            }
311            return true;
312        },
313        onKeyPress: function ( e ) {
314            var that = this;
315
316            // If suggestions are hidden and user presses arrow down, display suggestions:
317            if ( !that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue ) {
318                that.suggest();
319                return;
320            }
321
322            if ( that.disabled || !that.visible ) {
323                return;
324            }
325
326            switch ( e.which ) {
327                case keys.ESC:
328                    that.el.val( that.currentValue );
329                    that.hide();
330                    break;
331                case keys.RIGHT:
332                    if ( that.hint && that.options.onHint && that.isCursorAtEnd() ) {
333                        that.selectHint();
334                        break;
335                    }
336                    return;
337                case keys.TAB:
338                    if ( that.hint && that.options.onHint ) {
339                        that.selectHint();
340                        return;
341                    }
342                    if ( that.selectedIndex === -1 ) {
343                        that.hide();
344                        return;
345                    }
346                    that.select( that.selectedIndex );
347                    if ( that.options.tabDisabled === false ) {
348                        return;
349                    }
350                    break;
351                case keys.RETURN:
352                    if ( that.selectedIndex === -1 ) {
353                        that.hide();
354                        return;
355                    }
356                    that.select( that.selectedIndex );
357                    break;
358                case keys.UP:
359                    that.moveUp();
360                    break;
361                case keys.DOWN:
362                    that.moveDown();
363                    break;
364                default:
365                    return;
366            }
367
368            // Cancel event if function did not return:
369            e.stopImmediatePropagation();
370            e.preventDefault();
371        },
372        onKeyUp: function ( e ) {
373            var that = this;
374
375            if ( that.disabled ) {
376                return;
377            }
378
379            switch ( e.which ) {
380                case keys.UP:
381                case keys.DOWN:
382                    return;
383            }
384
385            clearInterval( that.onChangeInterval );
386
387            if ( that.currentValue !== that.el.val() ) {
388                that.findBestHint();
389                if ( that.options.deferRequestBy > 0 ) {
390                    // Defer lookup in case when value changes very quickly:
391                    that.onChangeInterval = setInterval( function () {
392                        that.onValueChange();
393                    }, that.options.deferRequestBy );
394                } else {
395                    that.onValueChange();
396                }
397            }
398        },
399        onValueChange: function () {
400            var that = this,
401                options = that.options,
402                value = that.el.val(),
403                query = that.getQuery( value );
404
405            if ( that.selection && that.currentValue !== query ) {
406                that.selection = null;
407                ( options.onInvalidateSelection || $.noop ).call( that.element );
408            }
409
410            clearInterval( that.onChangeInterval );
411            that.currentValue = value;
412            that.selectedIndex = -1;
413
414            // Check existing suggestion for the match before proceeding:
415            if ( options.triggerSelectOnValidInput && that.isExactMatch( query ) ) {
416                that.select( 0 );
417                return;
418            }
419
420            if ( query.length < options.minChars ) {
421                $( '.' + that.options.closeTrigger ).removeClass( that.options.closeTrigger );
422                that.hide();
423            } else {
424                that.getSuggestions( query );
425            }
426        },
427        isExactMatch: function ( query ) {
428            var suggestions = this.suggestions;
429
430            return ( suggestions.length === 1 && suggestions[0].value.toLowerCase() === query.toLowerCase() );
431        },
432        getQuery: function ( value ) {
433            var delimiter = this.options.delimiter,
434                parts;
435
436            if ( !delimiter ) {
437                return value;
438            }
439            parts = value.split( delimiter );
440            return $.trim( parts[parts.length - 1] );
441        },
442        getSuggestionsLocal: function ( query ) {
443            var that = this,
444                options = that.options,
445                queryLowerCase = query.toLowerCase(),
446                filter = options.lookupFilter,
447                limit = parseInt( options.lookupLimit, 10 ),
448                data;
449
450            data = {
451                suggestions: $.grep( options.lookup, function ( suggestion ) {
452                    return filter( suggestion, query, queryLowerCase );
453                } )
454            };
455
456            if ( limit && data.suggestions.length > limit ) {
457                data.suggestions = data.suggestions.slice( 0, limit );
458            }
459
460            return data;
461        },
462        getSuggestions: function ( q ) {
463            var response,
464                that = this,
465                container = $( that.suggestionsContainer ),
466                options = that.options,
467                serviceUrl = options.serviceUrl,
468                params,
469                cacheKey,
470                ajaxSettings;
471
472            options.params[options.paramName] = q;
473            params = options.ignoreParams ? null : options.params;
474
475            that.preloader( 'show', $( '.' + options.preloaderClass ), 'search-inner-preloader', container );
476
477            if ( options.onSearchStart.call( that.element, options.params ) === false ) {
478                return;
479            }
480
481            if ( $.isFunction( options.lookup ) ) {
482                options.lookup( q, function ( data ) {
483                    that.suggestions = data.suggestions;
484                    that.suggest();
485                    options.onSearchComplete.call( that.element, q, data.suggestions );
486                } );
487                return;
488            }
489
490            if ( that.isLocal ) {
491                response = that.getSuggestionsLocal( q );
492            } else {
493                if ( $.isFunction( serviceUrl ) ) {
494                    serviceUrl = serviceUrl.call( that.element, q );
495                }
496                cacheKey = serviceUrl + '?' + $.param( params || { } );
497                response = that.cachedResponse[cacheKey];
498            }
499
500            if ( response && Array.isArray( response.suggestions ) ) {
501                that.suggestions = response.suggestions;
502                that.suggest();
503                options.onSearchComplete.call( that.element, q, response.suggestions );
504            } else if ( !that.isBadQuery( q ) ) {
505                that.abortAjax();
506
507                ajaxSettings = {
508                    url: serviceUrl,
509                    data: params,
510                    type: options.type,
511                    dataType: options.dataType
512                };
513
514                $.extend( ajaxSettings, options.ajaxSettings );
515
516                that.currentRequest = $.ajax( ajaxSettings ).done( function ( data ) {
517                    var result;
518                    that.currentRequest = null;
519                    result = options.transformResult( data, q );
520
521                    if ( typeof result.suggestions !== 'undefined' ) {
522                        that.processResponse( result, q, cacheKey );
523                    }
524                    options.onSearchComplete.call( that.element, q, result.suggestions );
525                } ).fail( function ( jqXHR, textStatus, errorThrown ) {
526                    options.onSearchError.call( that.element, q, jqXHR, textStatus, errorThrown );
527                } );
528            } else {
529                options.onSearchComplete.call( that.element, q, [ ] );
530            }
531        },
532        isBadQuery: function ( q ) {
533            if ( !this.options.preventBadQueries ) {
534                return false;
535            }
536
537            var badQueries = this.badQueries,
538                i = badQueries.length;
539
540            while ( i-- ) {
541                if ( q.indexOf( badQueries[i] ) === 0 ) {
542                    return true;
543                }
544            }
545
546            return false;
547        },
548        hide: function () {
549            var that = this,
550                container = $( that.suggestionsContainer ),
551                containerParent = $( that.suggestionsContainer ).parent();
552
553            if ( $.isFunction( that.options.onHide ) && that.visible ) {
554                that.options.onHide.call( that.element, container );
555            }
556
557            that.visible = false;
558            that.selectedIndex = -1;
559            clearInterval( that.onChangeInterval );
560            $( that.suggestionsContainer ).hide();
561            $( that.detailsContainer ).hide();
562            containerParent.removeClass( 'search-open' );
563            that.signalHint( null );
564        },
565        suggest: function () {
566            if ( this.suggestions == '') {
567                if ( this.options.showNoSuggestionNotice ) {
568                    this.noSuggestions();
569                } else {
570                    this.hide();
571                }
572                return;
573            }
574
575            var that = this,
576                options = that.options,
577                groupBy = options.groupBy,
578                formatResult = options.formatResult,
579                value = that.getQuery( that.currentValue ),
580                className = that.classes.suggestion,
581                classSelected = that.classes.selected,
582                container = $( that.suggestionsContainer ),
583                noSuggestionsContainer = $( that.noSuggestionsContainer ),
584                beforeRender = options.beforeRender,
585                category,
586                formatGroup = function ( suggestion, index ) {
587                    var currentCategory = suggestion.data[groupBy];
588
589                    if ( category === currentCategory ) {
590                        return '';
591                    }
592
593                    category = currentCategory;
594
595                    return '<div class="autocomplete-group"><strong>' + category + '</strong></div>';
596                };
597
598            if ( options.triggerSelectOnValidInput && that.isExactMatch( value ) ) {
599                that.select( 0 );
600                return;
601            }
602
603            this.adjustContainerWidth();
604
605            noSuggestionsContainer.detach();
606            container.html( that.suggestions );
607
608            if ( $.isFunction( beforeRender ) ) {
609                beforeRender.call( that.element, container, that.suggestions );
610            }
611
612            container.show();
613
614            // Add class on show
615            container.parent().addClass( 'search-open' );
616
617            // Select first value by default:
618            if ( options.autoSelectFirst ) {
619                that.selectedIndex = 0;
620                container.scrollTop( 0 );
621                container.children( '.' + className ).first().addClass( classSelected );
622            }
623
624            that.visible = true;
625            that.findBestHint();
626        },
627        noSuggestions: function () {
628
629            // var that = this,
630            //     container = $( that.suggestionsContainer ),
631            //     noSuggestionsContainer = $( that.noSuggestionsContainer );
632
633            // this.adjustContainerWidth();
634
635            // // Some explicit steps. Be careful here as it easy to get
636            // // noSuggestionsContainer removed from DOM if not detached properly.
637            // noSuggestionsContainer.detach();
638            // container.empty(); // clean suggestions if any
639            // container.append( noSuggestionsContainer );
640
641            // container.show();
642            // that.visible = true;
643        },
644        adjustContainerWidth: function () {
645            var that = this,
646                options = that.options,
647                width,
648                container = $( that.suggestionsContainer ).parent(),
649                containerSugg = $( that.suggestionsContainer ),
650                maxWidth = 550;
651
652            // If width is auto, adjust width before displaying suggestions,
653            if ( options.width === 'auto' ) {
654                width = that.el.outerWidth();
655                containerSugg.css( 'width', width + 'px' );
656            }
657        },
658        findBestHint: function () {
659            var that = this,
660                value = that.el.val().toLowerCase(),
661                bestMatch = null;
662
663            if ( !value ) {
664                return;
665            }
666
667            that.signalHint( bestMatch );
668        },
669        signalHint: function ( suggestion ) {
670            var hintValue = '',
671                that = this;
672            if ( suggestion ) {
673                hintValue = that.currentValue + suggestion.value.substr( that.currentValue.length );
674            }
675            if ( that.hintValue !== hintValue ) {
676                that.hintValue = hintValue;
677                that.hint = suggestion;
678                ( this.options.onHint || $.noop )( hintValue );
679            }
680        },
681        /*
682         * Manages preloader
683         *
684         * @param action (show or hide)
685         * @param container (parent selector)
686         * @param cssClass
687         * @param detailsBox bool
688         */
689        preloader: function ( action, container, cssClass, suggestionsContainer ) {
690
691            var html,
692                defaultClass = 'search-preloader-wrapp',
693                cssClasses = cssClass == null ? defaultClass : defaultClass + ' ' + cssClass;
694
695            // Disable preloader and check if container exist
696
697            if ( search.show_preloader != 1 || container.length == 0 ) {
698                return;
699            }
700
701            // Action hide
702            if ( action === 'hide' ) {
703                $( defaultClass ).remove();
704                container.html( '' );
705
706                if( !($('.search-suggestions-wrapp .products')[0]) ) {
707                }
708            }
709
710            // Action show
711            if ( action === 'show' ) {
712                suggestionsContainer.html( '' );
713                container.html( '<div class="'+cssClasses+'"></div>' );
714            }
715        },
716        validateOrientation: function ( orientation, fallback ) {
717            orientation = $.trim( orientation || '' ).toLowerCase();
718
719            if ( $.inArray( orientation, [ 'auto', 'bottom', 'top' ] ) === -1 ) {
720                orientation = fallback;
721            }
722
723            return orientation;
724        },
725        processResponse: function ( result, originalQuery, cacheKey ) {
726            var that = this,
727                options = that.options;
728
729            //result.suggestions = that.verifySuggestionsFormat( result.suggestions );
730
731            // Cache results if cache is not disabled:
732            if ( !options.noCache ) {
733                that.cachedResponse[cacheKey] = result;
734                if (options.preventBadQueries && !result.suggestions.length) {
735                    that.badQueries.push( originalQuery );
736                }
737            }
738
739            // Return if originalQuery is not matching current query:
740            if ( originalQuery !== that.getQuery( that.currentValue ) ) {
741                return;
742            }
743
744            that.suggestions = result.suggestions;
745            that.suggest();
746        },
747        activate: function ( index ) {
748            var that = this,
749                activeItem,
750                selected = that.classes.selected,
751                container = $( that.suggestionsContainer ),
752                children = container.find( '.' + that.classes.suggestion );
753
754            container.find( '.' + selected ).removeClass( selected );
755
756            that.selectedIndex = index;
757
758            if ( that.selectedIndex !== -1 && children.length > that.selectedIndex ) {
759                activeItem = children.get( that.selectedIndex );
760                $( activeItem ).addClass( selected );
761                return activeItem;
762            }
763
764            return null;
765        },
766        selectHint: function () {
767            var that = this,
768                i = $.inArray( that.hint, that.suggestions );
769
770            that.select( i );
771        },
772        select: function ( i ) {
773            var that = this;
774            that.hide();
775            that.onSelect( i );
776            that.disableKillerFn();
777        },
778        moveUp: function () {
779            var that = this;
780
781            if ( that.selectedIndex === -1 ) {
782                return;
783            }
784
785            if ( that.selectedIndex === 0 ) {
786                $( that.suggestionsContainer ).children().first().removeClass( that.classes.selected );
787                that.selectedIndex = -1;
788                that.el.val( that.currentValue );
789                that.findBestHint();
790                return;
791            }
792
793            that.adjustScroll( that.selectedIndex - 1 );
794        },
795        moveDown: function () {
796            var that = this;
797
798            if ( that.selectedIndex === ( that.suggestions.length - 1 ) ) {
799                return;
800            }
801
802            that.adjustScroll( that.selectedIndex + 1 );
803        },
804        adjustScroll: function ( index ) {
805            var that = this,
806                activeItem = that.activate( index );
807
808            if ( !activeItem ) {
809                return;
810            }
811
812            var offsetTop,
813                upperBound,
814                lowerBound,
815                heightDelta = $( activeItem ).outerHeight();
816
817            offsetTop = activeItem.offsetTop;
818            upperBound = $( that.suggestionsContainer ).scrollTop();
819            lowerBound = upperBound + that.options.maxHeight - heightDelta;
820
821            if ( offsetTop < upperBound ) {
822                $( that.suggestionsContainer ).scrollTop( offsetTop );
823            } else if ( offsetTop > lowerBound ) {
824                $( that.suggestionsContainer ).scrollTop( offsetTop - that.options.maxHeight + heightDelta );
825            }
826
827            if ( !that.options.preserveInput ) {
828                that.el.val( that.getValue( that.suggestions[index].value ) );
829            }
830            that.signalHint( null );
831        },
832        onSelect: function ( index ) {
833            var that = this,
834                onSelectCallback = that.options.onSelect,
835                suggestion = that.suggestions[index];
836
837            that.currentValue = that.getValue( suggestion.value );
838
839            if ( that.currentValue !== that.el.val() && !that.options.preserveInput ) {
840                that.el.val( that.currentValue );
841            }
842
843            if ( suggestion.id != -1 ) {
844                window.location.href = suggestion.url;
845            }
846
847            that.signalHint( null );
848            that.suggestions = [ ];
849            that.selection = suggestion;
850            if ( $.isFunction( onSelectCallback ) ) {
851                onSelectCallback.call( that.element, suggestion );
852            }
853        },
854        onMouseOver: function ( index ) {
855            var that = this,
856                onMouseOverCallback = that.options.onMouseOver,
857                suggestion = that.suggestions[index];
858
859            if ( $.isFunction( onMouseOverCallback ) ) {
860                onMouseOverCallback.call( that.element, suggestion );
861            }
862        },
863        onMouseLeave: function ( index ) {
864            var that = this,
865                onMouseLeaveCallback = that.options.onMouseLeave,
866                suggestion = that.suggestions[index];
867
868            if ( $.isFunction( onMouseLeaveCallback ) ) {
869                onMouseLeaveCallback.call( that.element, suggestion );
870            }
871        },
872        getValue: function ( value ) {
873            var that = this,
874                delimiter = that.options.delimiter,
875                currentValue,
876                parts;
877
878            if ( !delimiter ) {
879                return value;
880            }
881
882            currentValue = that.currentValue;
883            parts = currentValue.split( delimiter );
884
885            if ( parts.length === 1 ) {
886                return value;
887            }
888
889            return currentValue.substr( 0, currentValue.length - parts[parts.length - 1].length ) + value;
890        },
891        dispose: function () {
892            var that = this;
893            that.el.off( '.autocomplete' ).removeData( 'autocomplete' );
894            that.disableKillerFn();
895            $( that.suggestionsContainer ).remove();
896        }
897    };
898
899
900
901
902    // Create chainable jQuery plugin:
903    $.fn.dgwtWcasAutocomplete = function ( options, args ) {
904        var dataKey = 'autocomplete';
905        // If function invoked without argument return
906        // instance of the first matched element:
907        if (!arguments.length) {
908            return this.first().data( dataKey );
909        }
910
911        return this.each( function () {
912            var inputElement = $( this ),
913                instance = inputElement.data( dataKey );
914
915            if ( typeof options === 'string' ) {
916                if ( instance && typeof instance[options] === 'function' ) {
917                    instance[options]( args );
918                }
919            } else {
920                // If instance already exists, destroy it:
921                if ( instance && instance.dispose ) {
922                    instance.dispose();
923                }
924                instance = new Autocomplete( this, options );
925                inputElement.data( dataKey, instance );
926            }
927        } );
928    };
929
930
931
932    ( function () {
933
934        // RUN
935        $( function () {
936            "use strict";
937
938            /*-----------------------------------------------------------------
939             /* Fire autocomplete
940             /*------------ -----------------------------------------------------*/
941
942            $( '.search-input' ).dgwtWcasAutocomplete( {
943                minChars: 3,
944                autoSelectFirst: false,
945                triggerSelectOnValidInput: false,
946                serviceUrl: search.ajax_search_endpoint,
947                paramName: 'search_keyword',
948            } );
949
950        } );
951
952    }() );
953
954} ) );

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.