PageSourceSearch

https://iot.ru/bitrix/templates/.default/components/bitrix/search.tags.input/page_tags/script.js

js iot.ru collected 2026-10-02 07:12:35 UTC 13,020 bytes, 601 lines download raw bytes

1var Errors = {
2	"result_unval" : "Error in result",
3	"result_empty" : "Empty result"
4};
5
6function JsTc(oHandler, sParams, sParser) // TC = TagCloud
7{
8	var t = this;
9
10	t.oObj = typeof oHandler == 'object' ? oHandler : document.getElementById("TAGS");
11	t.sParams = sParams;
12	// Arrays for data
13	if (sParser)
14	{
15		t.sExp = new RegExp("["+sParser+"]+", "i");
16	}
17	else
18	{
19		t.sExp = new RegExp(",");
20	}
21	t.oLast = {"str":false, "arr":false};
22	t.oThis = {"str":false, "arr":false};
23	t.oEl = {"start":false, "end":false};
24	t.oUnfinedWords = {};
25	// Flags
26	t.bReady = true;
27	t.eFocus = true;
28	// Array with results & it`s showing
29	t.aDiv = null;
30	t.oDiv = null;
31	// Pointers
32	t.oActive = null;
33	t.oPointer = [];
34	t.oPointer_default = [];
35	t.oPointer_this = 'input_field';
36
37	t.oObj.onblur = function()
38	{
39		t.eFocus = false;
40	};
41
42	t.oObj.onfocus = function()
43	{
44		if (!t.eFocus)
45		{
46			t.eFocus = true;
47			setTimeout(function(){t.CheckModif('focus')}, 500);
48		}
49	};
50
51	t.oLast["arr"] = t.oObj.value.split(t.sExp);
52	t.oLast["str"] = t.oLast["arr"].join(":");
53
54	setTimeout(function(){t.CheckModif('this')}, 500);
55
56	this.CheckModif = function(__data)
57	{
58		var
59			sThis = false, tmp = 0,
60			bUnfined = false, word = "",
61			cursor = {};
62
63		if (!t.eFocus)
64			return;
65
66		if (t.bReady && t.oObj.value.length > 0)
67		{
68			// Preparing input data
69			t.oThis["arr"] = t.oObj.value.split(t.sExp);
70			t.oThis["str"] = t.oThis["arr"].join(":");
71
72			// Getting modificated element
73			if (t.oThis["str"] && (t.oThis["str"] != t.oLast["str"]))
74			{
75				cursor['position'] = TCJsUtils.getCursorPosition(t.oObj);
76				if (cursor['position']['end'] > 0 && !t.sExp.test(t.oObj.value.substr(cursor['position']['end']-1, 1)))
77				{
78					cursor['arr'] = t.oObj.value.substr(0, cursor['position']['end']).split(t.sExp);
79					sThis = t.oThis["arr"][cursor['arr'].length - 1];
80
81					t.oEl['start'] = cursor['position']['end'] - cursor['arr'][cursor['arr'].length - 1].length;
82					t.oEl['end'] = t.oEl['start'] + sThis.length;
83					t.oEl['content'] = sThis;
84
85					t.oLast["arr"] = t.oThis["arr"];
86					t.oLast["str"] = t.oThis["str"];
87				}
88			}
89			if (sThis)
90			{
91				// Checking for UnfinedWords
92				for (tmp = 2; tmp <= sThis.length; tmp++)
93				{
94					word = sThis.substr(0, tmp);
95					if (t.oUnfinedWords[word] == '!fined')
96					{
97						bUnfined = true;
98						break;
99					}
100				}
101				if (!bUnfined)
102					t.Send(sThis);
103			}
104		}
105		setTimeout(function(){t.CheckModif('this')}, 500);
106	};
107
108	t.Send = function(sSearch)
109	{
110		if (!sSearch)
111			return false;
112
113		var oError = [];
114		t.bReady = false;
115		if (BX('wait_container'))
116		{
117			BX('wait_container').innerHTML = BX.message('JS_CORE_LOADING');
118			BX.show(BX('wait_container'));
119		}
120		BX.ajax.post(
121			'/bitrix/components/bitrix/search.tags.input/search.php',
122			{"search":sSearch, "params":t.sParams},
123			function(data)
124			{
125				var result = {};
126				t.bReady = true;
127
128				try
129				{
130					eval("result = " + data + ";");
131				}
132				catch(e)
133				{
134					oError['result_unval'] = e;
135				}
136
137				if (TCJsUtils.empty(result))
138					oError['result_empty'] = Errors['result_empty'];
139
140				try
141				{
142					if (TCJsUtils.empty(oError) && (typeof result == 'object'))
143					{
144						if (!(result.length == 1 && result[0]['NAME'] == t.oEl['content']))
145						{
146							t.Show(result);
147							return;
148						}
149					}
150					else
151					{
152						t.oUnfinedWords[t.oEl['content']] = '!fined';
153					}
154				}
155				catch(e)
156				{
157					oError['unknown_error'] = e;
158				}
159
160				if(BX('wait_container'))
161					BX.hide(BX('wait_container'));
162			}
163		);
164	};
165
166	t.Show = function(result)
167	{
168		t.Destroy();
169		t.oDiv = document.body.appendChild(document.createElement("DIV"));
170		t.oDiv.id = t.oObj.id+'_div';
171
172		t.oDiv.className = "search-popup";
173		t.oDiv.style.position = 'absolute';
174
175		t.aDiv = t.Print(result);
176		var pos = TCJsUtils.GetRealPos(t.oObj);
177		t.oDiv.style.width = parseInt(pos["width"]) + "px";
178		TCJsUtils.show(t.oDiv, pos["left"], pos["bottom"]);
179		TCJsUtils.addEvent(document, "click", t.CheckMouse);
180		TCJsUtils.addEvent(document, "keydown", t.CheckKeyword);
181	};
182
183	t.Print = function(aArr)
184	{
185		var aEl = null;
186		var aResult = [];
187		var aRes = [];
188		var iCnt = 0;
189		var oDiv = null;
190		var oSpan = null;
191		var sPrefix = t.oDiv.id;
192
193		for (var tmp_ in aArr)
194		{
195			// Math
196			if (aArr.hasOwnProperty(tmp_))
197			{
198				aEl = aArr[tmp_];
199				aRes = [];
200				aRes['ID'] = (aEl['ID'] && aEl['ID'].length > 0) ? aEl['ID'] : iCnt++;
201				aRes['GID'] = sPrefix + '_' + aRes['ID'];
202				aRes['NAME'] = TCJsUtils.htmlspecialcharsEx(aEl['NAME']);
203				aRes['~NAME'] = aEl['NAME'];
204				aRes['CNT'] = aEl['CNT'];
205				aResult[aRes['GID']] = aRes;
206				t.oPointer.push(aRes['GID']);
207				// Graph
208				oDiv = t.oDiv.appendChild(document.createElement("DIV"));
209				oDiv.id = aRes['GID'];
210				oDiv.name = sPrefix + '_div';
211
212				oDiv.className = 'search-popup-row';
213
214				oDiv.onmouseover = function(){t.Init(); this.className='search-popup-row-active';};
215				oDiv.onmouseout = function(){t.Init(); this.className='search-popup-row';};
216				oDiv.onclick = function(e){
217						t.oActive = this.id;
218						t.Replace();
219						t.Destroy();
220						BX.PreventDefault(e);
221					};
222
223				oSpan = oDiv.appendChild(document.createElement("DIV"));
224				oSpan.id = oDiv.id + '_NAME';
225				oSpan.className = "search-popup-el search-popup-el-cnt";
226				oSpan.innerHTML = aRes['CNT'];
227
228				oSpan = oDiv.appendChild(document.createElement("DIV"));
229				oSpan.id = oDiv.id + '_NAME';
230				oSpan.className = "search-popup-el search-popup-el-name";
231				oSpan.innerHTML = aRes['NAME'];
232			}
233		}
234		t.oPointer.push('input_field');
235		t.oPointer_default = t.oPointer;
236		return aResult;
237	};
238
239	t.Destroy = function()
240	{
241		try
242		{
243			TCJsUtils.hide(t.oDiv);
244			t.oDiv.parentNode.removeChild(t.oDiv);
245		}
246		catch(e)
247		{}
248		t.aDiv = [];
249		t.oPointer = [];
250		t.oPointer_default = [];
251		t.oPointer_this = 'input_field';
252		t.bReady = true;
253		t.eFocus = true;
254		t.oActive = null;
255
256		TCJsUtils.removeEvent(document, "click", t.CheckMouse);
257		TCJsUtils.removeEvent(document, "keydown", t.CheckKeyword);
258	};
259
260	t.Replace = function()
261	{
262		if (typeof t.oActive == 'string')
263		{
264			var tmp = t.aDiv[t.oActive];
265			var tmp1 = '';
266			if (typeof tmp == 'object')
267			{
268				var elEntities = document.createElement("textarea");
269				elEntities.innerHTML = tmp['~NAME'];
270				tmp1 = elEntities.value;
271			}
272			//this preserves leading spaces
273			var start = t.oEl['start'];
274			while(start < t.oObj.value.length && t.oObj.value.substring(start, start+1) == " ")
275				start++;
276
277			t.oObj.value = t.oObj.value.substring(0, start) + tmp1 + t.oObj.value.substr(t.oEl['end']);
278			TCJsUtils.setCursorPosition(t.oObj, start + tmp1.length);
279		}
280	};
281
282	t.Init = function()
283	{
284		t.oActive = false;
285		t.oPointer = t.oPointer_default;
286		t.Clear();
287		t.oPointer_this = 'input_pointer';
288	};
289
290	t.Clear = function()
291	{
292		var oEl = t.oDiv.getElementsByTagName("div");
293		if (oEl.length > 0 && typeof oEl == 'object')
294		{
295			for (var ii in oEl)
296			{
297				if (oEl.hasOwnProperty(ii))
298				{
299					var oE = oEl[ii];
300					if (oE && (typeof oE == 'object') && (oE.name == t.oDiv.id + '_div'))
301					{
302						oE.className = "search-popup-row";
303					}
304				}
305			}
306		}
307	};
308
309	t.CheckMouse = function()
310	{
311		t.Replace();
312		t.Destroy();
313	};
314
315	t.CheckKeyword = function(e)
316	{
317		if (!e)
318			e = window.event;
319		var oP = null;
320		var oEl = null;
321		if ((37 < e.keyCode && e.keyCode <41) || (e.keyCode == 13))
322		{
323			t.Clear();
324
325			switch (e.keyCode)
326			{
327				case 38:
328					oP = t.oPointer.pop();
329					if (t.oPointer_this == oP)
330					{
331						t.oPointer.unshift(oP);
332						oP = t.oPointer.pop();
333					}
334
335					if (oP != 'input_field')
336					{
337						t.oActive = oP;
338						oEl = document.getElementById(oP);
339						if (typeof oEl == 'object')
340						{
341							oEl.className = "search-popup-row-active";
342						}
343					}
344					t.oPointer.unshift(oP);
345					break;
346				case 40:
347					oP = t.oPointer.shift();
348					if (t.oPointer_this == oP)
349					{
350						t.oPointer.push(oP);
351						oP = t.oPointer.shift();
352					}
353					if (oP != 'input_field')
354					{
355						t.oActive = oP;
356						oEl = document.getElementById(oP);
357						if (typeof oEl == 'object')
358						{
359							oEl.className = "search-popup-row-active";
360						}
361					}
362					t.oPointer.push(oP);
363					break;
364				case 39:
365					t.Replace();
366					t.Destroy();
367					break;
368				case 13:
369					t.Replace();
370					t.Destroy();
371					if (TCJsUtils.IsIE())
372					{
373						e.returnValue = false;
374						e.cancelBubble = true;
375					}
376					else
377					{
378						e.preventDefault();
379						e.stopPropagation();
380					}
381					break;
382			}
383			t.oPointer_this	= oP;
384		}
385		else
386		{
387			t.Destroy();
388		}
389	}
390}
391
392var TCJsUtils =
393{
394	arEvents:  [],
395
396	addEvent: function(el, evname, func)
397	{
398		if(el.attachEvent) // IE
399			el.attachEvent("on" + evname, func);
400		else if(el.addEventListener) // Gecko / W3C
401			el.addEventListener(evname, func, false);
402		else
403			el["on" + evname] = func;
404		this.arEvents[this.arEvents.length] = {'element': el, 'event': evname, 'fn': func};
405	},
406
407	removeEvent: function(el, evname, func)
408	{
409		if(el.detachEvent) // IE
410			el.detachEvent("on" + evname, func);
411		else if(el.removeEventListener) // Gecko / W3C
412			el.removeEventListener(evname, func, false);
413		else
414			el["on" + evname] = null;
415	},
416
417	getCursorPosition: function(oObj)
418	{
419		var result = {'start': 0, 'end': 0};
420		if (!oObj || (typeof oObj != 'object'))
421			return result;
422		try
423		{
424			if (document.selection != null && oObj.selectionStart == null)
425			{
426				oObj.focus();
427				var oRange = document.selection.createRange();
428				var oParent = oRange.parentElement();
429				var sBookmark = oRange.getBookmark();
430				var sContents_ = oObj.value;
431				var sContents = sContents_;
432				var sMarker = '__' + Math.random() + '__';
433
434				while(sContents.indexOf(sMarker) != -1)
435				{
436					sMarker = '__' + Math.random() + '__';
437				}
438
439				if (!oParent || oParent == null || (oParent.type != "textarea" && oParent.type != "text"))
440				{
441					return result;
442				}
443
444				oRange.text = sMarker + oRange.text + sMarker;
445				sContents = oObj.value;
446				result['start'] = sContents.indexOf(sMarker);
447				sContents = sContents.replace(sMarker, "");
448				result['end'] = sContents.indexOf(sMarker);
449				oObj.value = sContents_;
450				oRange.moveToBookmark(sBookmark);
451				oRange.select();
452				return result;
453			}
454			else
455			{
456				return {
457					'start': oObj.selectionStart,
458					'end': oObj.selectionEnd
459				};
460			}
461		}
462		catch(e){}
463		return result;
464	},
465
466	setCursorPosition: function(oObj, iPosition)
467	{
468		if (typeof oObj != 'object')
469			return false;
470
471		oObj.focus();
472
473		try
474		{
475			if (document.selection != null && oObj.selectionStart == null)
476			{
477				var oRange = document.selection.createRange();
478				oRange.select();
479			}
480			else
481			{
482				oObj.selectionStart = iPosition;
483				oObj.selectionEnd = iPosition;
484			}
485			return true;
486		}
487		catch(e)
488		{
489			return false;
490		}
491	},
492
493	printArray: function (oObj, sParser, iLevel)
494	{
495		try
496		{
497			var result = '';
498			var space = '';
499
500			if (iLevel==undefined)
501				iLevel = 0;
502			if (!sParser)
503				sParser = "\n";
504
505			for (var j=0; j<=iLevel; j++)
506				space += '  ';
507
508			for (var i in oObj)
509			{
510				if (oObj.hasOwnProperty(i))
511				{
512					if (typeof oObj[i] == 'object')
513						result += space+i + " = {"+ sParser + TCJsUtils.printArray(oObj[i], sParser, iLevel+1) + ", " + sParser + "}" + sParser;
514					else
515						result += space+i + " = " + oObj[i] + "; " + sParser;
516				}
517			}
518			return result;
519		}
520		catch(e)
521		{
522		}
523	},
524
525	empty: function(oObj)
526	{
527		if (oObj)
528		{
529			for (var i in oObj)
530			{
531				if (oObj.hasOwnProperty(i))
532				{
533					return false;
534				}
535			}
536		}
537		return true;
538	},
539
540	show: function(oDiv, iLeft, iTop)
541	{
542		if (typeof oDiv != 'object')
543			return;
544		var zIndex = parseInt(oDiv.style.zIndex);
545		if(zIndex <= 0 || isNaN(zIndex))
546			zIndex = 2200;
547		oDiv.style.zIndex = zIndex;
548		oDiv.style.left = iLeft + "px";
549		oDiv.style.top = iTop + "px";
550		return oDiv;
551	},
552
553	hide: function(oDiv)
554	{
555		if (oDiv)
556			oDiv.style.display = 'none';
557	},
558
559	GetRealPos: function(el)
560	{
561		if(!el || !el.offsetParent)
562			return false;
563
564		var res = {};
565		var objParent = el.offsetParent;
566		res["left"] = el.offsetLeft;
567		res["top"] = el.offsetTop;
568		while(objParent && objParent.tagName != "BODY")
569		{
570			res["left"] += objParent.offsetLeft;
571			res["top"] += objParent.offsetTop;
572			objParent = objParent.offsetParent;
573		}
574		res["right"]=res["left"] + el.offsetWidth;
575		res["bottom"]=res["top"] + el.offsetHeight;
576		res["width"]=el.offsetWidth;
577		res["height"]=el.offsetHeight;
578
579		return res;
580	},
581
582	IsIE: function()
583	{
584		return (document.attachEvent && !TCJsUtils.IsOpera());
585	},
586
587	IsOpera: function()
588	{
589		return (navigator.userAgent.toLowerCase().indexOf('opera') != -1);
590	},
591
592	htmlspecialcharsEx: function(str)
593	{
594		return str.replace(/&amp;/g, '&amp;amp;').replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g, '&amp;gt;').replace(/&quot;/g, '&amp;quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
595	},
596
597	htmlspecialcharsback: function(str)
598	{
599		return str.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;;/g, '"').replace(/&amp;/g, '&');
600	}
601};

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.