PageSourceSearch

https://far.ru/local/components/far/search.title/script.js?17842073259736

js far.ru collected 2026-10-02 05:45:56 UTC 9,736 bytes, 332 lines download raw bytes

1function JCTitleSearch(arParams) {
2	var _this = this;
3
4	this.arParams = {
5		AJAX_PAGE: arParams.AJAX_PAGE,
6		CONTAINER_ID: arParams.CONTAINER_ID,
7		INPUT_ID: arParams.INPUT_ID,
8		MIN_QUERY_LEN: parseInt(arParams.MIN_QUERY_LEN),
9	};
10	if (arParams.WAIT_IMAGE) this.arParams.WAIT_IMAGE = arParams.WAIT_IMAGE;
11	if (arParams.MIN_QUERY_LEN <= 0) arParams.MIN_QUERY_LEN = 1;
12
13	this.cache = [];
14	this.cache_key = null;
15
16	this.startText = '';
17	this.running = false;
18	this.runningCall = false;
19	this.currentRow = -1;
20	this.RESULT = null;
21	this.CONTAINER = null;
22	this.INPUT = null;
23	this.WAIT = null;
24
25	this.ShowResult = function (result) {
26		if (BX.type.isString(result)) {
27			_this.RESULT.innerHTML = result;
28		}
29
30		_this.RESULT.style.display = _this.RESULT.innerHTML !== '' ? 'block' : 'none';
31		var pos = _this.adjustResultNode();
32
33		//adjust left column to be an outline
34		var res_pos;
35		var th;
36		var tbl = BX.findChild(_this.RESULT, { tag: 'table', class: 'title-search-result' }, true);
37		if (tbl) {
38			th = BX.findChild(tbl, { tag: 'th' }, true);
39		}
40
41		if (th) {
42			var tbl_pos = BX.pos(tbl);
43			tbl_pos.width = tbl_pos.right - tbl_pos.left;
44
45			var th_pos = BX.pos(th);
46			th_pos.width = th_pos.right - th_pos.left;
47			th.style.width = th_pos.width + 'px';
48
49			_this.RESULT.style.width = pos.width + th_pos.width + 'px';
50
51			//Move table to left by width of the first column
52			_this.RESULT.style.left = pos.left - th_pos.width - 1 + 'px';
53
54			//Shrink table when it's too wide
55			if (tbl_pos.width - th_pos.width > pos.width) _this.RESULT.style.width = pos.width + th_pos.width - 1 + 'px';
56
57			//Check if table is too wide and shrink result div to it's width
58			tbl_pos = BX.pos(tbl);
59			res_pos = BX.pos(_this.RESULT);
60			if (res_pos.right > tbl_pos.right) {
61				_this.RESULT.style.width = tbl_pos.right - tbl_pos.left + 'px';
62			}
63		}
64
65		var fade;
66		if (tbl) fade = BX.findChild(_this.RESULT, { class: 'title-search-fader' }, true);
67		if (fade && th) {
68			res_pos = BX.pos(_this.RESULT);
69			fade.style.left = res_pos.right - res_pos.left - 18 + 'px';
70			fade.style.width = 18 + 'px';
71			fade.style.top = 0 + 'px';
72			fade.style.height = res_pos.bottom - res_pos.top + 'px';
73			fade.style.display = 'block';
74		}
75	};
76
77	this.onKeyPress = function (keyCode) {
78		var tbl = BX.findChild(_this.RESULT, { tag: 'table', class: 'title-search-result' }, true);
79		if (!tbl) return false;
80
81		var i;
82		var cnt = tbl.rows.length;
83
84		switch (keyCode) {
85			case 27: // escape key - close search div
86				_this.RESULT.style.display = 'none';
87				_this.currentRow = -1;
88				_this.UnSelectAll();
89				return true;
90
91			case 40: // down key - navigate down on search results
92				if (_this.RESULT.style.display == 'none') _this.RESULT.style.display = 'block';
93
94				var first = -1;
95				for (i = 0; i < cnt; i++) {
96					if (!BX.findChild(tbl.rows[i], { class: 'title-search-separator' }, true)) {
97						if (first == -1) first = i;
98
99						if (_this.currentRow < i) {
100							_this.currentRow = i;
101							break;
102						} else if (tbl.rows[i].className == 'title-search-selected') {
103							tbl.rows[i].className = '';
104						}
105					}
106				}
107
108				if (i == cnt && _this.currentRow != i) _this.currentRow = first;
109
110				tbl.rows[_this.currentRow].className = 'title-search-selected';
111				return true;
112
113			case 38: // up key - navigate up on search results
114				if (_this.RESULT.style.display == 'none') _this.RESULT.style.display = 'block';
115
116				var last = -1;
117				for (i = cnt - 1; i >= 0; i--) {
118					if (!BX.findChild(tbl.rows[i], { class: 'title-search-separator' }, true)) {
119						if (last == -1) last = i;
120
121						if (_this.currentRow > i) {
122							_this.currentRow = i;
123							break;
124						} else if (tbl.rows[i].className == 'title-search-selected') {
125							tbl.rows[i].className = '';
126						}
127					}
128				}
129
130				if (i < 0 && _this.currentRow != i) _this.currentRow = last;
131
132				tbl.rows[_this.currentRow].className = 'title-search-selected';
133				return true;
134
135			case 13: // enter key - choose current search result
136				if (_this.RESULT.style.display == 'block') {
137					for (i = 0; i < cnt; i++) {
138						if (_this.currentRow == i) {
139							if (!BX.findChild(tbl.rows[i], { class: 'title-search-separator' }, true)) {
140								var a = BX.findChild(tbl.rows[i], { tag: 'a' }, true);
141								if (a) {
142									window.location = a.href;
143									return true;
144								}
145							}
146						}
147					}
148				}
149				return false;
150		}
151
152		return false;
153	};
154
155	this.onTimeout = function () {
156		_this.onChange(function () {
157			setTimeout(_this.onTimeout, 500);
158		});
159	};
160
161	this.onChange = function (callback) {
162		if (_this.running) {
163			_this.runningCall = true;
164			return;
165		}
166		_this.running = true;
167
168		if (_this.INPUT.value != _this.oldValue && _this.INPUT.value != _this.startText) {
169			_this.oldValue = _this.INPUT.value;
170			if (_this.INPUT.value.length >= _this.arParams.MIN_QUERY_LEN) {
171				_this.cache_key = _this.arParams.INPUT_ID + '|' + _this.INPUT.value;
172				if (_this.cache[_this.cache_key] == null) {
173					if (_this.WAIT) {
174						var pos = BX.pos(_this.INPUT);
175						var height = pos.bottom - pos.top - 2;
176						_this.WAIT.style.top = pos.top + 1 + 'px';
177						_this.WAIT.style.height = height + 'px';
178						_this.WAIT.style.width = height + 'px';
179						_this.WAIT.style.left = pos.right - height + 2 + 'px';
180						_this.WAIT.style.display = 'block';
181					}
182
183					BX.ajax.post(
184						_this.arParams.AJAX_PAGE,
185						{
186							ajax_call: 'y',
187							INPUT_ID: _this.arParams.INPUT_ID,
188							q: _this.INPUT.value,
189							l: _this.arParams.MIN_QUERY_LEN,
190						},
191						function (result) {
192							_this.cache[_this.cache_key] = result;
193							_this.ShowResult(result);
194							_this.currentRow = -1;
195							_this.EnableMouseEvents();
196							if (_this.WAIT) _this.WAIT.style.display = 'none';
197							if (!!callback) callback();
198							_this.running = false;
199							if (_this.runningCall) {
200								_this.runningCall = false;
201								_this.onChange();
202							}
203						},
204					);
205					return;
206				} else {
207					_this.ShowResult(_this.cache[_this.cache_key]);
208					_this.currentRow = -1;
209					_this.EnableMouseEvents();
210				}
211			} else {
212				_this.RESULT.style.display = 'none';
213				_this.currentRow = -1;
214				_this.UnSelectAll();
215			}
216		}
217		if (!!callback) callback();
218		_this.running = false;
219	};
220
221	this.onScroll = function () {
222		if (BX.type.isElementNode(_this.RESULT) && _this.RESULT.style.display !== 'none' && _this.RESULT.innerHTML !== '') {
223			_this.adjustResultNode();
224		}
225	};
226
227	this.UnSelectAll = function () {
228		var tbl = BX.findChild(_this.RESULT, { tag: 'table', class: 'title-search-result' }, true);
229		if (tbl) {
230			var cnt = tbl.rows.length;
231			for (var i = 0; i < cnt; i++) tbl.rows[i].className = '';
232		}
233	};
234
235	this.EnableMouseEvents = function () {
236		var tbl = BX.findChild(_this.RESULT, { tag: 'table', class: 'title-search-result' }, true);
237		if (tbl) {
238			var cnt = tbl.rows.length;
239			for (var i = 0; i < cnt; i++)
240				if (!BX.findChild(tbl.rows[i], { class: 'title-search-separator' }, true)) {
241					tbl.rows[i].id = 'row_' + i;
242					tbl.rows[i].onmouseover = function (e) {
243						if (_this.currentRow != this.id.substr(4)) {
244							_this.UnSelectAll();
245							this.className = 'title-search-selected';
246							_this.currentRow = this.id.substr(4);
247						}
248					};
249					tbl.rows[i].onmouseout = function (e) {
250						this.className = '';
251						_this.currentRow = -1;
252					};
253				}
254		}
255	};
256
257	this.onFocusLost = function (hide) {
258		setTimeout(function () {
259			_this.RESULT.style.display = 'none';
260		}, 250);
261	};
262
263	this.onFocusGain = function () {
264		if (_this.RESULT.innerHTML.length) _this.ShowResult();
265	};
266
267	this.onKeyDown = function (e) {
268		if (!e) e = window.event;
269
270		if (_this.RESULT.style.display == 'block') {
271			if (_this.onKeyPress(e.keyCode)) return BX.PreventDefault(e);
272		}
273	};
274
275	this.adjustResultNode = function () {
276		if (!(BX.type.isElementNode(_this.RESULT) && BX.type.isElementNode(_this.CONTAINER))) {
277			return { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
278		}
279
280		var pos = BX.pos(_this.CONTAINER);
281
282		_this.RESULT.style.position = 'absolute';
283		_this.RESULT.style.top = pos.bottom + 2 + 'px';
284		_this.RESULT.style.left = pos.left + 'px';
285		_this.RESULT.style.width = pos.width + 'px';
286
287		return pos;
288	};
289
290	this._onContainerLayoutChange = function () {
291		if (BX.type.isElementNode(_this.RESULT) && _this.RESULT.style.display !== 'none' && _this.RESULT.innerHTML !== '') {
292			_this.adjustResultNode();
293		}
294	};
295	this.Init = function () {
296		this.CONTAINER = document.getElementById(this.arParams.CONTAINER_ID);
297		BX.addCustomEvent(this.CONTAINER, 'OnNodeLayoutChange', this._onContainerLayoutChange);
298
299		this.RESULT = document.body.appendChild(document.createElement('DIV'));
300		this.RESULT.className = 'title-search-result';
301		this.INPUT = document.getElementById(this.arParams.INPUT_ID);
302		this.startText = this.oldValue = this.INPUT.value;
303		BX.bind(this.INPUT, 'focus', function () {
304			_this.onFocusGain();
305		});
306		BX.bind(this.INPUT, 'blur', function () {
307			_this.onFocusLost();
308		});
309		this.INPUT.onkeydown = this.onKeyDown;
310
311		if (this.arParams.WAIT_IMAGE) {
312			this.WAIT = document.body.appendChild(document.createElement('DIV'));
313			this.WAIT.style.backgroundImage = "url('" + this.arParams.WAIT_IMAGE + "')";
314			if (!BX.browser.IsIE()) this.WAIT.style.backgroundRepeat = 'none';
315			this.WAIT.style.display = 'none';
316			this.WAIT.style.position = 'absolute';
317			this.WAIT.style.zIndex = '1100';
318		}
319
320		BX.bind(this.INPUT, 'bxchange', function () {
321			_this.onChange();
322		});
323
324		var fixedParent = BX.findParent(this.CONTAINER, BX.is_fixed);
325		if (BX.type.isElementNode(fixedParent)) {
326			BX.bind(window, 'scroll', BX.throttle(this.onScroll, 100, this));
327		}
328	};
329	BX.ready(function () {
330		_this.Init(arParams);
331	});
332}

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.