PageSourceSearch

https://st-tools.ru/local/templates/geon/components/logema.regiona…/js/auto-complete.js?177624653711078

js st-tools.ru collected 2026-10-04 22:37:58 UTC 11,078 bytes, 225 lines download raw bytes

1/*
2    JavaScript autoComplete v1.0.4
3    Copyright (c) 2014 Simon Steinberger / Pixabay
4    GitHub: https://github.com/Pixabay/JavaScript-autoComplete
5    License: http://www.opensource.org/licenses/mit-license.php
6*/
7
8var autoComplete = (function(){
9    // "use strict";
10    function autoComplete(options){
11        if (!document.querySelector) return;
12
13        // helpers
14        function hasClass(el, className){ return el.classList ? el.classList.contains(className) : new RegExp('\\b'+ className+'\\b').test(el.className); }
15
16        function addEvent(el, type, handler){
17            if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler);
18        }
19        function removeEvent(el, type, handler){
20            // if (el.removeEventListener) not working in IE11
21            if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler);
22        }
23        function live(elClass, event, cb, context){
24            addEvent(context || document, event, function(e){
25                var found, el = e.target || e.srcElement;
26                while (el && !(found = hasClass(el, elClass))) el = el.parentElement;
27                if (found) cb.call(el, e);
28            });
29        }
30
31        var o = {
32            selector: 0,
33            source: 0,
34            minChars: 3,
35            delay: 150,
36            offsetLeft: 0,
37            offsetTop: 1,
38            cache: 1,
39            menuClass: '',
40            renderItem: function (item, search){
41                // escape special characters
42                search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
43                var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
44                return '<div class="autocomplete-suggestion" data-val="' + item + '">' + item.replace(re, "<b>$1</b>") + '</div>';
45            },
46            onSelect: function(e, term, item){}
47        };
48        for (var k in options) { if (options.hasOwnProperty(k)) o[k] = options[k]; }
49
50        // init
51        var elems = typeof o.selector == 'object' ? [o.selector] : document.querySelectorAll(o.selector);
52        for (var i=0; i<elems.length; i++) {
53            var that = elems[i];
54
55            // create suggestions container "sc"
56            that.sc = document.createElement('div');
57            that.sc.className = 'autocomplete-suggestions '+o.menuClass;
58
59            that.autocompleteAttr = that.getAttribute('autocomplete');
60            that.setAttribute('autocomplete', 'off');
61            that.cache = {};
62            that.last_val = '';
63
64            that.updateSC = function(resize, next){
65                var rect = that.getBoundingClientRect();
66                that.sc.style.left = Math.round(rect.left + (window.pageXOffset || document.documentElement.scrollLeft) + o.offsetLeft) + 'px';
67                that.sc.style.top = Math.round(rect.bottom + (window.pageYOffset || document.documentElement.scrollTop) + o.offsetTop) + 'px';
68                that.sc.style.width = Math.round(rect.right - rect.left) + 'px'; // outerWidth
69                if (!resize) {
70                    that.sc.style.display = 'block';
71                    $('.popup-regionality__searcher-no-result').removeClass('--open')
72                    if (!that.sc.maxHeight) { that.sc.maxHeight = parseInt((window.getComputedStyle ? getComputedStyle(that.sc, null) : that.sc.currentStyle).maxHeight); }
73                    if (!that.sc.suggestionHeight) that.sc.suggestionHeight = that.sc.querySelector('.autocomplete-suggestion').offsetHeight;
74                    if (that.sc.suggestionHeight)
75                        if (!next) that.sc.scrollTop = 0;
76                        else {
77                            var scrTop = that.sc.scrollTop, selTop = next.getBoundingClientRect().top - that.sc.getBoundingClientRect().top;
78                            if (selTop + that.sc.suggestionHeight - that.sc.maxHeight > 0)
79                                that.sc.scrollTop = selTop + that.sc.suggestionHeight + scrTop - that.sc.maxHeight;
80                            else if (selTop < 0)
81                                that.sc.scrollTop = selTop + scrTop;
82                        }
83                }
84            }
85            addEvent(window, 'resize', that.updateSC);
86            document.body.appendChild(that.sc);
87
88            live('autocomplete-suggestion', 'mouseleave', function(e){
89                var sel = that.sc.querySelector('.autocomplete-suggestion.selected');
90                if (sel) setTimeout(function(){ sel.className = sel.className.replace('selected', ''); }, 20);
91            }, that.sc);
92
93            live('autocomplete-suggestion', 'mouseover', function(e){
94                var sel = that.sc.querySelector('.autocomplete-suggestion.selected');
95                if (sel) sel.className = sel.className.replace('selected', '');
96                this.className += ' selected';
97            }, that.sc);
98
99            live('autocomplete-suggestion', 'mousedown', function(e){
100                if (hasClass(this, 'autocomplete-suggestion')) { // else outside click
101                    var v = this.getAttribute('data-val');
102                    that.value = v;
103                    o.onSelect(e, v, this);
104                    that.sc.style.display = 'none';
105                    $('.popup-regionality__searcher-no-result').addClass('--open')
106                }
107            }, that.sc);
108
109            that.blurHandler = function(){
110                try { var over_sb = document.querySelector('.autocomplete-suggestions:hover'); } catch(e){ var over_sb = 0; }
111                if (!over_sb) {
112                    that.last_val = that.value;
113                    that.sc.style.display = 'none';
114                    setTimeout(function(){ that.sc.style.display = 'none'; }, 350); // hide suggestions on fast input
115                } else if (that !== document.activeElement) setTimeout(function(){ that.focus(); }, 20);
116            };
117            addEvent(that, 'blur', that.blurHandler);
118
119            var suggest = function(data){
120                var val = that.value;
121                that.cache[val] = data;
122                if (data.length && val.length >= o.minChars) {
123                    var s = '';
124                    for (var i=0;i<data.length;i++) s += o.renderItem(data[i], val);
125                    that.sc.innerHTML = s;
126                    that.updateSC(0);
127                }
128                else
129                    that.sc.style.display = 'none';
130            }
131
132            that.keydownHandler = function(e){
133                var key = window.event ? e.keyCode : e.which;
134                // down (40), up (38)
135                if ((key == 40 || key == 38) && that.sc.innerHTML) {
136                    var next, sel = that.sc.querySelector('.autocomplete-suggestion.selected');
137                    if (!sel) {
138                        next = (key == 40) ? that.sc.querySelector('.autocomplete-suggestion') : that.sc.childNodes[that.sc.childNodes.length - 1]; // first : last
139                        next.className += ' selected';
140                        that.value = next.getAttribute('data-val');
141                    } else {
142                        next = (key == 40) ? sel.nextSibling : sel.previousSibling;
143                        if (next) {
144                            sel.className = sel.className.replace('selected', '');
145                            next.className += ' selected';
146                            that.value = next.getAttribute('data-val');
147                        }
148                        else { sel.className = sel.className.replace('selected', ''); that.value = that.last_val; next = 0; }
149                    }
150                    that.updateSC(0, next);
151                    return false;
152                }
153                // esc
154                else if (key == 27) { that.value = that.last_val; that.sc.style.display = 'none'; }
155                // enter
156                else if (key == 13 || key == 9) {
157                    var sel = that.sc.querySelector('.autocomplete-suggestion.selected');
158                    if (sel && that.sc.style.display != 'none') { o.onSelect(e, sel.getAttribute('data-val'), sel); setTimeout(function(){ that.sc.style.display = 'none'; }, 20); }
159                }
160            };
161            addEvent(that, 'keydown', that.keydownHandler);
162
163            that.keyupHandler = function(e){
164                var key = window.event ? e.keyCode : e.which;
165                if (!key || (key < 35 || key > 40) && key != 13 && key != 27) {
166                    var val = that.value;
167                    if (val.length >= o.minChars) {
168                        if (val != that.last_val) {
169                            that.last_val = val;
170                            clearTimeout(that.timer);
171                            if (o.cache) {
172                                if (val in that.cache) { suggest(that.cache[val]); return; }
173                                // no requests if previous suggestions were empty
174                                for (var i=1; i<val.length-o.minChars; i++) {
175                                    var part = val.slice(0, val.length-i);
176                                    if (part in that.cache && !that.cache[part].length) { suggest([]); return; }
177                                }
178                            }
179                            that.timer = setTimeout(function(){ o.source(val, suggest) }, o.delay);
180                        }
181                    } else {
182                        that.last_val = val;
183                        that.sc.style.display = 'none';
184                        $('.popup-regionality__searcher-no-result').addClass('--open')
185                    }
186                }
187            };
188            addEvent(that, 'keyup', that.keyupHandler);
189
190            that.focusHandler = function(e){
191                that.last_val = '\n';
192                that.keyupHandler(e)
193            };
194            if (!o.minChars) addEvent(that, 'focus', that.focusHandler);
195        }
196
197        // public destroy method
198        this.destroy = function(){
199            for (var i=0; i<elems.length; i++) {
200                var that = elems[i];
201                removeEvent(window, 'resize', that.updateSC);
202                removeEvent(that, 'blur', that.blurHandler);
203                removeEvent(that, 'focus', that.focusHandler);
204                removeEvent(that, 'keydown', that.keydownHandler);
205                removeEvent(that, 'keyup', that.keyupHandler);
206                if (that.autocompleteAttr)
207                    that.setAttribute('autocomplete', that.autocompleteAttr);
208                else
209                    that.removeAttribute('autocomplete');
210                document.body.removeChild(that.sc);
211                that = null;
212            }
213        };
214    }
215    return autoComplete;
216})();
217
218(function(){
219    if (typeof define === 'function' && define.amd)
220        define('autoComplete', function () { return autoComplete; });
221    else if (typeof module !== 'undefined' && module.exports)
222        module.exports = autoComplete;
223    else
224        window.autoComplete = autoComplete;
225})();

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.