PageSourceSearch

https://www.duim24.ru/local/templates/duim/components/arturgolubev…/.default/script.js?175619963614090

js duim24.ru collected 2026-09-24 09:44:32 UTC 14,090 bytes, 563 lines download raw bytes

1function JCTitleSearchAG(arParams)
2{
3	var _this = this;
4
5	if(!arParams.POPUP_HISTORY){
6		arParams.POPUP_HISTORY = 'N';
7	}
8
9	this.arParams = {
10		'AJAX_PAGE': arParams.AJAX_PAGE,
11		'CONTAINER_ID': arParams.CONTAINER_ID,
12		'INPUT_ID': arParams.INPUT_ID,
13		'POPUP_HISTORY': arParams.POPUP_HISTORY,
14		'POPUP_HISTORY_TITLE': arParams.POPUP_HISTORY_TITLE,
15		'PAGE': arParams.PAGE,
16		'MIN_QUERY_LEN': parseInt(arParams.MIN_QUERY_LEN)
17	};
18	if(arParams.WAIT_IMAGE)
19		this.arParams.WAIT_IMAGE = arParams.WAIT_IMAGE;
20	
21	this.elements = {
22		'clear': null,
23		'preloader': null,
24	};
25
26	if(arParams.PRELODER_ID){
27		this.elements.preloader = BX(arParams.PRELODER_ID);
28	}
29	if(arParams.CLEAR_ID){
30		this.elements.clear = BX(arParams.CLEAR_ID);
31	}
32	if(arParams.VOICE_ID){
33		this.elements.voice = BX(arParams.VOICE_ID);
34	}
35	
36	if(arParams.MIN_QUERY_LEN <= 0)
37		arParams.MIN_QUERY_LEN = 1;
38
39	this.cache = [];
40	this.cache_key = null;
41
42	this.startText = '';
43	this.running = false;
44	
45	this.currentRow = -1;
46	this.RESULT = null;
47	this.CONTAINER = null;
48	this.INPUT = null;
49	this.WAIT = null;
50
51	this.ShowResult = function(result)
52	{
53		if(BX.type.isString(result))
54		{
55			_this.RESULT.innerHTML = result;
56		}
57
58		_this.RESULT.style.display = _this.RESULT.innerHTML !== '' ? 'block' : 'none';
59		var pos = _this.adjustResultNode();
60
61		//adjust left column to be an outline
62		var res_pos;
63		var th;
64		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
65		if(tbl)
66		{
67			th = BX.findChild(tbl, {'tag':'th'}, true);
68		}
69
70		if(th)
71		{
72			var tbl_pos = BX.pos(tbl);
73			tbl_pos.width = tbl_pos.right - tbl_pos.left;
74
75			var th_pos = BX.pos(th);
76			th_pos.width = th_pos.right - th_pos.left;
77			th.style.width = th_pos.width + 'px';
78
79			_this.RESULT.style.width = (pos.width + th_pos.width) + 'px';
80
81			//Move table to left by width of the first column
82			_this.RESULT.style.left = (pos.left - th_pos.width - 1)+ 'px';
83
84			//Shrink table when it's too wide
85			if((tbl_pos.width - th_pos.width) > pos.width)
86				_this.RESULT.style.width = (pos.width + th_pos.width -1) + 'px';
87
88			//Check if table is too wide and shrink result div to it's width
89			tbl_pos = BX.pos(tbl);
90			res_pos = BX.pos(_this.RESULT);
91			if(res_pos.right > tbl_pos.right)
92			{
93				_this.RESULT.style.width = (tbl_pos.right - tbl_pos.left) + 'px';
94			}
95		}
96
97		var fade;
98		if(tbl) fade = BX.findChild(_this.RESULT, {'class':'title-search-fader'}, true);
99		if(fade && th)
100		{
101			res_pos = BX.pos(_this.RESULT);
102			fade.style.left = (res_pos.right - res_pos.left - 18) + 'px';
103			fade.style.width = 18 + 'px';
104			fade.style.top = 0 + 'px';
105			fade.style.height = (res_pos.bottom - res_pos.top) + 'px';
106			fade.style.display = 'block';
107		}
108	};
109
110	this.onKeyPress = function(keyCode)
111	{
112		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
113		if(!tbl)
114			return false;
115
116		var i;
117		var cnt = tbl.rows.length;
118
119		switch (keyCode)
120		{
121		case 27: // escape key - close search div
122			_this.RESULT.style.display = 'none';
123			_this.currentRow = -1;
124			_this.UnSelectAll();
125		return true;
126
127		case 40: // down key - navigate down on search results
128			if(_this.RESULT.style.display == 'none')
129				_this.RESULT.style.display = 'block';
130
131			var first = -1;
132			for(i = 0; i < cnt; i++)
133			{
134				if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
135				{
136					if(first == -1)
137						first = i;
138
139					if(_this.currentRow < i)
140					{
141						_this.currentRow = i;
142						break;
143					}
144					else if(tbl.rows[i].className == 'title-search-selected')
145					{
146						tbl.rows[i].className = '';
147					}
148				}
149			}
150
151			if(i == cnt && _this.currentRow != i)
152				_this.currentRow = first;
153
154			tbl.rows[_this.currentRow].className = 'title-search-selected';
155		return true;
156
157		case 38: // up key - navigate up on search results
158			if(_this.RESULT.style.display == 'none')
159				_this.RESULT.style.display = 'block';
160
161			var last = -1;
162			for(i = cnt-1; i >= 0; i--)
163			{
164				if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
165				{
166					if(last == -1)
167						last = i;
168
169					if(_this.currentRow > i)
170					{
171						_this.currentRow = i;
172						break;
173					}
174					else if(tbl.rows[i].className == 'title-search-selected')
175					{
176						tbl.rows[i].className = '';
177					}
178				}
179			}
180
181			if(i < 0 && _this.currentRow != i)
182				_this.currentRow = last;
183
184			tbl.rows[_this.currentRow].className = 'title-search-selected';
185		return true;
186
187		case 13: // enter key - choose current search result
188			if(_this.RESULT.style.display == 'block')
189			{
190				for(i = 0; i < cnt; i++)
191				{
192					if(_this.currentRow == i)
193					{
194						if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
195						{
196							var a = BX.findChild(tbl.rows[i], {'tag':'a'}, true);
197							if(a)
198							{
199								window.location = a.href;
200								return true;
201							}
202						}
203					}
204				}
205			}
206		return false;
207		}
208
209		return false;
210	};
211
212	this.onTimeout = function()
213	{
214		_this.onChange(function(){
215			setTimeout(_this.onTimeout, 500);
216		});
217	};
218	
219	this.onChange = function(callback)
220	{
221		if (_this.running)
222			return;
223
224		_this.checkButtonsVisible();
225
226		_this.running = true;
227
228		if(_this.INPUT.value != _this.oldValue && _this.INPUT.value != _this.startText)
229		{
230			_this.oldValue = _this.INPUT.value;
231			if(_this.INPUT.value.length >= _this.arParams.MIN_QUERY_LEN)
232			{
233				_this.cache_key = _this.arParams.INPUT_ID + '|' + _this.INPUT.value;
234				if(_this.cache[_this.cache_key] == null)
235				{
236					if(_this.WAIT)
237					{
238						var pos = BX.pos(_this.INPUT);
239						var height = (pos.bottom - pos.top)-2;
240						_this.WAIT.style.top = (pos.top+1) + 'px';
241						_this.WAIT.style.height = height + 'px';
242						_this.WAIT.style.width = height + 'px';
243						_this.WAIT.style.left = (pos.right - height + 2) + 'px';
244						_this.WAIT.style.display = 'block';
245					}
246					
247					if(_this.elements.preloader){
248						BX.show(_this.elements.preloader);
249					}
250					
251					// console.log('ajax call ' + _this.INPUT.value);
252					
253					BX.ajax.post(
254						_this.arParams.AJAX_PAGE,
255						{
256							'ajax_call':'y',
257							'INPUT_ID':_this.arParams.INPUT_ID,
258							'q':_this.INPUT.value,
259							'l':_this.arParams.MIN_QUERY_LEN
260						},
261						function(result)
262						{
263							_this.cache[_this.cache_key] = result;
264							_this.ShowResult(result);
265							_this.currentRow = -1;
266							_this.EnableMouseEvents();
267							if(_this.WAIT)
268								_this.WAIT.style.display = 'none';
269							
270							if(_this.elements.preloader){
271								BX.hide(_this.elements.preloader);
272							}
273							
274							if (!!callback)
275								callback();
276							_this.running = false;
277							
278							if(_this.INPUT.value != _this.oldValue)
279							{
280								_this.onChange();
281							}
282						}
283					);
284					return;
285				}
286				else
287				{
288					_this.ShowResult(_this.cache[_this.cache_key]);
289					_this.currentRow = -1;
290					_this.EnableMouseEvents();
291				}
292			}
293			else
294			{
295				_this.RESULT.style.display = 'none';
296				_this.currentRow = -1;
297				_this.UnSelectAll();
298			}
299		}
300		if (!!callback)
301			callback();
302		_this.running = false;
303	};
304
305	this.onScroll = function ()
306	{
307		if(BX.type.isElementNode(_this.RESULT)
308			&& _this.RESULT.style.display !== "none"
309			&& _this.RESULT.innerHTML !== ''
310		)
311		{
312			_this.adjustResultNode();
313		}
314	};
315
316	this.UnSelectAll = function()
317	{
318		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
319		if(tbl)
320		{
321			var cnt = tbl.rows.length;
322			for(var i = 0; i < cnt; i++)
323				tbl.rows[i].className = '';
324		}
325	};
326
327	this.EnableMouseEvents = function()
328	{
329		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
330		if(tbl)
331		{
332			var cnt = tbl.rows.length;
333			for(var i = 0; i < cnt; i++)
334				if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
335				{
336					tbl.rows[i].id = 'row_' + i;
337					tbl.rows[i].onmouseover = function (e) {
338						if(_this.currentRow != this.id.substr(4))
339						{
340							_this.UnSelectAll();
341							this.className = 'title-search-selected';
342							_this.currentRow = this.id.substr(4);
343						}
344					};
345					tbl.rows[i].onmouseout = function (e) {
346						this.className = '';
347						_this.currentRow = -1;
348					};
349				}
350		}
351	};
352
353	this.onFocusLost = function(hide)
354	{
355		setTimeout(function(){_this.RESULT.style.display = 'none';}, 250);
356	};
357
358	this.onFocusGain = function()
359	{
360		if(_this.RESULT.innerHTML.length && _this.INPUT.value.length >= _this.arParams.MIN_QUERY_LEN)
361			_this.ShowResult();
362		else if(_this.arParams.POPUP_HISTORY == 'Y'){
363			_this.ShowResult(_this.getHistoryHtml());
364		}
365	};
366
367	this.onKeyDown = function(e)
368	{
369		if(!e)
370			e = window.event;
371
372		if (_this.RESULT.style.display == 'block')
373		{
374			if(_this.onKeyPress(e.keyCode))
375				return BX.PreventDefault(e);
376		}
377	};
378
379	this.adjustResultNode = function()
380	{
381		if(!(BX.type.isElementNode(_this.RESULT)
382			&& BX.type.isElementNode(_this.CONTAINER))
383		)
384		{
385			return { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
386		}
387
388		var pos = BX.pos(_this.CONTAINER);
389
390		_this.RESULT.style.position = 'absolute';
391		_this.RESULT.style.top = (pos.bottom + 2) + 'px';
392		_this.RESULT.style.left = pos.left + 'px';
393		_this.RESULT.style.width = pos.width + 'px';
394
395		return pos;
396	};
397
398	this._onContainerLayoutChange = function()
399	{
400		if(BX.type.isElementNode(_this.RESULT)
401			&& _this.RESULT.style.display !== "none"
402			&& _this.RESULT.innerHTML !== ''
403		)
404		{
405			_this.adjustResultNode();
406		}
407	};
408
409	// voice input
410	this.initVoiceInput = function(){
411		if(_this.elements.voice){
412			window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
413			if (window.SpeechRecognition) {
414				_this.elements.voice.classList.add('voice-show');
415
416				_this.voiceRecorderActive = 0;
417
418				_this.voiceRecorder = new SpeechRecognition();
419				_this.voiceRecorder.interimResults = true;
420				_this.voiceRecorder.lang = 'ru-RU';
421
422				_this.voiceRecorder.addEventListener("start", function(){
423					_this.voiceRecorderActive = 1;
424					_this.elements.voice.classList.add('active');
425				});
426
427				_this.voiceRecorder.addEventListener("end", function(){
428					_this.voiceRecorderActive = 0;
429					_this.elements.voice.classList.remove('active');
430				});
431
432				_this.voiceRecorder.addEventListener("result", function(e){
433					_this.INPUT.value = e.results[0][0].transcript;
434					if(e.results[0].isFinal){
435						_this.onChange();
436					}
437				});
438
439				_this.voiceRecorder.addEventListener("error", function(e){
440					_this.voiceRecorderActive = 0;
441					_this.elements.voice.classList.remove('active');
442
443					// e.error == 'no-speech'
444				});
445				
446				_this.elements.voice.addEventListener('click', function(){
447					if(!_this.voiceRecorderActive){
448						_this.voiceRecorder.start();
449					}else{
450						_this.voiceRecorder.stop();
451					}
452				});
453			}
454		}
455	};
456
457	// clear
458	this.initClear = function(){
459		if(this.elements.clear){
460			this.elements.clear.addEventListener('click', function(){
461				_this.INPUT.value = '';
462				_this.onChange();
463			});
464		}
465	};
466	this.checkButtonsVisible = function(){
467		if(_this.elements.clear){
468			if(_this.INPUT.value){
469				_this.elements.clear.style.display = 'block';
470			}else{
471				_this.elements.clear.style.display = 'none';
472			}
473		}
474
475		if(_this.elements.voice && window.SpeechRecognition){
476			if(_this.INPUT.value){
477				_this.elements.voice.style.display = 'none';
478			}else{
479				_this.elements.voice.style.display = 'block';
480			}
481		}
482	};
483
484	// history 
485	this.getCookie = function(name) {
486		const value = `; ${document.cookie}`;
487		const parts = value.split(`; ${name}=`);
488		if (parts.length === 2) return parts.pop().split(';').shift();
489	};
490
491	this.getHistoryHtml = function(){
492		var html = '', history = _this.getCookie('BITRIX_SM_AG_SMSE_H');
493
494		if(history){
495			history = decodeURI(history).replace('+', ' ');
496
497			var arHistory = history.split('|');
498			if(arHistory.length){
499				html = html + '<div class="bx_smart_searche bx_searche"><div class="bx-searchtitle-popup-history">';
500					html = html + '<div class="bx-searchtitle-popup-history-title">'+_this.arParams.POPUP_HISTORY_TITLE+'</div>';
501					arHistory.reverse().forEach(function(item){
502						item = decodeURIComponent(item);
503
504						html = html + '<div class="bx-searchtitle-popup-history-item"><a class="js_search_href" href="'+_this.arParams.PAGE+'?q='+item+'">'+item+'</a></div>';
505					});
506				html = html + '</div></div>';
507			}
508		}
509
510		return html;
511	};
512
513	// init
514	this.Init = function()
515	{
516		this.CONTAINER = document.getElementById(this.arParams.CONTAINER_ID);
517		BX.addCustomEvent(this.CONTAINER, "OnNodeLayoutChange", this._onContainerLayoutChange);
518
519		this.RESULT = document.body.appendChild(document.createElement("DIV"));
520		this.RESULT.className = 'title-search-result';
521		
522		this.INPUT = document.getElementById(this.arParams.INPUT_ID);
523		BX.bind(this.INPUT, 'focus', function() {_this.onFocusGain()});
524		BX.bind(this.INPUT, 'blur', function(e) {
525			if(!!e.relatedTarget){
526				if(!BX.hasClass(BX(e.relatedTarget), 'js_search_href')){
527					_this.onFocusLost();
528				}
529			}else{
530				_this.onFocusLost();
531			}
532		});
533		this.INPUT.onkeydown = this.onKeyDown;
534		
535		this.startText = this.oldValue = this.INPUT.value;
536
537		if(this.arParams.WAIT_IMAGE)
538		{
539			this.WAIT = document.body.appendChild(document.createElement("DIV"));
540			this.WAIT.style.backgroundImage = "url('" + this.arParams.WAIT_IMAGE + "')";
541			if(!BX.browser.IsIE())
542				this.WAIT.style.backgroundRepeat = 'none';
543			this.WAIT.style.display = 'none';
544			this.WAIT.style.position = 'absolute';
545			this.WAIT.style.zIndex = '1100';
546		}
547
548		BX.bind(this.INPUT, 'bxchange', function() {_this.onChange()});
549		BX.bind(this.INPUT, 'paste', function(e) {setTimeout(function(){_this.onChange();}, 200);});
550
551		this.initClear();
552		this.initVoiceInput();
553
554		/* var fixedParent = BX.findParent(this.CONTAINER, BX.is_fixed);
555		if(BX.type.isElementNode(fixedParent)){
556			BX.bind(window, 'scroll', BX.throttle(this.onScroll, 100, this));
557		} */
558		
559		BX.bind(window, 'scroll', BX.throttle(this.onScroll, 100, this));
560		BX.bind(window, 'resize', BX.throttle(this.onScroll, 100, this));
561	};
562	BX.ready(function (){_this.Init(arParams)});
563}

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.