PageSourceSearch

http://electricprojects.ru/bitrix/js/main/core/core_ajax.js?1462740666

js electricprojects.ru collected 2026-10-06 04:15:10 UTC 25,340 bytes, 1,116 lines download raw bytes

1(function(window){
2if (window.BX.ajax) return;
3
4var
5	BX = window.BX,
6
7	tempDefaultConfig = {},
8	defaultConfig = {
9		method: 'GET', // request method: GET|POST
10		dataType: 'html', // type of data loading: html|json|script
11		timeout: 0, // request timeout in seconds. 0 for browser-default
12		async: true, // whether request is asynchronous or not
13		processData: true, // any data processing is disabled if false, only callback call
14		scriptsRunFirst: false, // whether to run _all_ found scripts before onsuccess call. script tag can have an attribute "bxrunfirst" to turn  this flag on only for itself
15		emulateOnload: true,
16		start: true, // send request immediately (if false, request can be started manually via XMLHttpRequest object returned)
17		cache: true, // whether NOT to add random addition to URL
18		preparePost: true, // whether set Content-Type x-www-form-urlencoded in POST
19
20		lsTimeout: 30, //local storage data TTL. useless without lsId.
21		lsForce: false //wheter to force query instead of using localStorage data. useless without lsId.
22/*
23other parameters:
24	url: url to get/post
25	data: data to post
26	onsuccess: successful request callback. BX.proxy may be used.
27	onfailure: request failure callback. BX.proxy may be used.
28
29	lsId: local storage id - for constantly updating queries which can communicate via localStorage. core_ls.js needed
30
31any of the default parameters can be overridden. defaults can be changed by BX.ajax.Setup() - for all further requests!
32*/
33	},
34	ajax_session = null,
35	loadedScripts = {},
36	r = {
37		'url_utf': /[^\034-\254]+/g,
38		'script_self': /\/bitrix\/js\/main\/core\/core(_ajax)*.js$/i,
39		'script_self_window': /\/bitrix\/js\/main\/core\/core_window.js$/i,
40		'script_self_admin': /\/bitrix\/js\/main\/core\/core_admin.js$/i,
41		'script_onload': /window.onload/g
42	};
43
44// low-level method
45BX.ajax = function(config)
46{
47	var status, data;
48
49	if (!config || !config.url || !BX.type.isString(config.url))
50	{
51		return false;
52	}
53
54	for (var i in tempDefaultConfig)
55		if (typeof (config[i]) == "undefined") config[i] = tempDefaultConfig[i];
56
57	tempDefaultConfig = {};
58
59	for (var i in defaultConfig)
60		if (typeof (config[i]) == "undefined") config[i] = defaultConfig[i];
61
62	config.method = config.method.toUpperCase();
63
64	if (!BX.localStorage)
65		config.lsId = null;
66
67	if (BX.browser.IsIE())
68	{
69		var result = r.url_utf.exec(config.url);
70		if (result)
71		{
72			do
73			{
74				config.url = config.url.replace(result, BX.util.urlencode(result));
75				result = r.url_utf.exec(config.url);
76			} while (result);
77		}
78	}
79
80	if (!config.cache && config.method == 'GET')
81		config.url = BX.ajax._uncache(config.url);
82
83	if (config.method == 'POST' && config.preparePost)
84	{
85		config.data = BX.ajax.prepareData(config.data);
86	}
87
88	var bXHR = true;
89	if (config.lsId && !config.lsForce)
90	{
91		var v = BX.localStorage.get('ajax-' + config.lsId);
92		if (v !== null)
93		{
94			bXHR = false;
95
96			var lsHandler = function(lsData) {
97				if (lsData.key == 'ajax-' + config.lsId && lsData.value != 'BXAJAXWAIT')
98				{
99					var data = lsData.value, 
100						bRemove = !!lsData.oldValue && data == null;
101					if (!bRemove)
102						BX.ajax.__run(config, data);
103					else if (config.onfailure)
104						config.onfailure("timeout");
105
106					BX.removeCustomEvent('onLocalStorageChange', lsHandler);
107				}
108			}
109
110			if (v == 'BXAJAXWAIT')
111			{
112				BX.addCustomEvent('onLocalStorageChange', lsHandler);
113			}
114			else
115			{
116				setTimeout(function() {lsHandler({key: 'ajax-' + config.lsId, value: v})}, 10);
117			}
118		}
119	}
120
121	if (bXHR)
122	{
123		config.xhr = BX.ajax.xhr();
124		if (!config.xhr) return;
125
126		if (config.lsId)
127		{
128			BX.localStorage.set('ajax-' + config.lsId, 'BXAJAXWAIT', config.lsTimeout);
129		}
130
131		config.xhr.open(config.method, config.url, config.async);
132		if (config.method == 'POST' && config.preparePost)
133		{
134			config.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
135		}
136
137		var bRequestCompleted = false;
138		var onreadystatechange = config.xhr.onreadystatechange = function(additional)
139		{
140			if (bRequestCompleted)
141				return;
142
143			if (additional === 'timeout')
144			{
145				if (config.onfailure)
146					config.onfailure("timeout");
147
148				BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['timeout', '', config]);
149
150				config.xhr.onreadystatechange = BX.DoNothing;
151				config.xhr.abort();
152
153				if (config.async)
154				{
155					config.xhr = null;
156				}
157			}
158			else
159			{
160				if (config.xhr.readyState == 4 || additional == 'run')
161				{
162					status = BX.ajax.xhrSuccess(config.xhr) ? "success" : "error";
163					bRequestCompleted = true;
164					config.xhr.onreadystatechange = BX.DoNothing;
165
166					// var status = oAjax.arThreads[TID].httpRequest.getResponseHeader('X-Bitrix-Ajax-Status');
167					// var bRedirect = (status == 'Redirect');
168
169					if (status == 'success')
170					{
171						var data = config.xhr.responseText;
172
173						if (config.lsId)
174						{
175							BX.localStorage.set('ajax-' + config.lsId, data, config.lsTimeout);
176						}
177
178						BX.ajax.__run(config, data);
179					}
180					else if (config.onfailure)
181					{
182						config.onfailure("status", config.xhr.status);
183						BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['status', config.xhr.status, config]);
184					}
185
186					if (config.async)
187					{
188						config.xhr = null;
189					}
190				}
191			}
192		}
193
194		if (config.async && config.timeout > 0)
195		{
196			setTimeout(function() {
197				if (config.xhr && !bRequestCompleted)
198				{
199					onreadystatechange("timeout");
200				}
201			}, config.timeout * 1000);
202		}
203
204		if (config.start)
205		{
206			config.xhr.send(config.data);
207
208			if (!config.async)
209			{
210				onreadystatechange('run');
211			}
212		}
213
214		return config.xhr;
215	}
216}
217
218BX.ajax.xhr = function()
219{
220	if (window.XMLHttpRequest)
221	{
222		try {return new XMLHttpRequest();} catch(e){}
223	}
224	else if (window.ActiveXObject)
225	{
226		try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
227			catch(e) {}
228		try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
229			catch(e) {}
230		try { return new ActiveXObject("Msxml2.XMLHTTP"); }
231			catch(e) {}
232		try { return new ActiveXObject("Microsoft.XMLHTTP"); }
233			catch(e) {}
234		throw new Error("This browser does not support XMLHttpRequest.");
235	}
236
237	return null;
238}
239
240BX.ajax.__prepareOnload = function(scripts)
241{
242	if (scripts.length > 0)
243	{
244		BX.ajax['onload_' + ajax_session] = null;
245
246		for (var i=0,len=scripts.length;i<len;i++)
247		{
248			if (scripts[i].isInternal)
249			{
250				scripts[i].JS = scripts[i].JS.replace(r.script_onload, 'BX.ajax.onload_' + ajax_session);
251			}
252		}
253	}
254
255	BX.CaptureEventsGet();
256	BX.CaptureEvents(window, 'load');
257}
258
259BX.ajax.__runOnload = function()
260{
261	if (null != BX.ajax['onload_' + ajax_session])
262	{
263		BX.ajax['onload_' + ajax_session].apply(window);
264		BX.ajax['onload_' + ajax_session] = null;
265	}
266
267	var h = BX.CaptureEventsGet();
268
269	if (h)
270	{
271		for (var i=0; i<h.length; i++)
272			h[i].apply(window);
273	}
274}
275
276BX.ajax.__run = function(config, data)
277{
278	if (!config.processData)
279	{
280		if (config.onsuccess)
281		{
282			config.onsuccess(data);
283		}
284
285		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [data, config]);
286	}
287	else
288	{
289		try
290		{
291			data = BX.ajax.processRequestData(data, config);
292		}
293		catch (e)
294		{
295			if (config.onfailure)
296				config.onfailure("processing", e);
297			BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['processing', e, config]);
298		}
299	}
300}
301
302BX.ajax.processRequestData = function(data, config)
303{
304	var result, scripts = [], styles = [];
305	switch (config.dataType.toUpperCase())
306	{
307		case 'JSON':
308			result = BX.parseJSON(data);
309		break;
310		case 'SCRIPT':
311			scripts.push({"isInternal": true, "JS": data, bRunFirst: config.scriptsRunFirst});
312			result = data;
313		break;
314
315		default: // HTML
316			var ob = BX.processHTML(data, config.scriptsRunFirst);
317			result = ob.HTML; scripts = ob.SCRIPT; styles = ob.STYLE
318		break;
319	}
320
321	var bSessionCreated = false;
322	if (null == ajax_session)
323	{
324		ajax_session = parseInt(Math.random() * 1000000);
325		bSessionCreated = true;
326	}
327
328	if (styles.length > 0)
329		BX.loadCSS(styles);
330
331	if (config.emulateOnload)
332		BX.ajax.__prepareOnload(scripts);
333
334	BX.ajax.processScripts(scripts, true);
335
336	if (config.onsuccess)
337	{
338		config.onsuccess(result);
339	}
340
341	BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [result, config]);
342
343	BX.ajax.processScripts(scripts, false);
344
345	setTimeout(function()
346	{
347		if (config.emulateOnload)
348			BX.ajax.__runOnload();
349		if (bSessionCreated)
350			ajax_session = null;
351	}, 10);
352}
353
354BX.ajax.processScripts = function(scripts, bRunFirst)
355{
356	for (var i = 0, length = scripts.length; i < length; i++)
357	{
358		if (null != bRunFirst && bRunFirst != !!scripts[i].bRunFirst)
359			continue;
360
361		if (scripts[i].isInternal)
362		{
363			BX.evalGlobal(scripts[i].JS);
364		}
365		else
366		{
367			BX.ajax.loadScriptAjax([scripts[i].JS]);
368		}
369	}
370}
371
372// TODO: extend this function to use with any data objects or forms
373BX.ajax.prepareData = function(arData, prefix)
374{
375	var data = '';
376	if (BX.type.isString(arData))
377		data = arData;
378	else if (null != arData)
379	{
380		for(var i in arData)
381		{
382			if (data.length > 0) data += '&';
383			var name = BX.util.urlencode(i);
384			if(prefix)
385				name = prefix + '[' + name + ']';
386			if(typeof arData[i] == 'object')
387				data += BX.ajax.prepareData(arData[i], name)
388			else
389				data += name + '=' + BX.util.urlencode(arData[i])
390		}
391	}
392	return data;
393}
394
395BX.ajax.xhrSuccess = function(xhr)
396{
397	return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
398}
399
400BX.ajax.Setup = function(config, bTemp)
401{
402	bTemp = !!bTemp;
403
404	for (var i in config)
405	{
406		if (bTemp)
407			tempDefaultConfig[i] = config[i];
408		else
409			defaultConfig[i] = config[i];
410	}
411}
412
413BX.ajax.replaceLocalStorageValue = function(lsId, data, ttl)
414{
415	if (!!BX.localStorage)
416		BX.localStorage.set('ajax-' + lsId, data, ttl);
417}
418
419
420BX.ajax._uncache = function(url)
421{
422	return url + ((url.indexOf('?') !== -1 ? "&" : "?") + '_=' + (new Date).getTime());
423}
424
425/* simple interface */
426BX.ajax.get = function(url, data, callback)
427{
428	if (BX.type.isFunction(data))
429	{
430		callback = data;
431		data = '';
432	}
433
434	data = BX.ajax.prepareData(data);
435
436	if (data)
437	{
438		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
439		data = '';
440	}
441
442	return BX.ajax({
443		'method': 'GET',
444		'dataType': 'html',
445		'url': url,
446		'data':  '',
447		'onsuccess': callback
448	});
449}
450
451BX.ajax.getCaptcha = function(callback)
452{
453	return BX.ajax.loadJSON('/bitrix/tools/ajax_captcha.php', callback);
454}
455
456BX.ajax.insertToNode = function(url, node)
457{
458	if (node = BX(node))
459	{
460		BX.onCustomEvent('onAjaxInsertToNode', [{url: url, node: node}]);
461
462		var show = null;
463		if (!tempDefaultConfig.denyShowWait)
464		{
465			show = BX.showWait(node);
466			delete tempDefaultConfig.denyShowWait;
467		}
468
469		return BX.ajax.get(url, function(data) {
470			node.innerHTML = data;
471			BX.closeWait(node, show);
472		});
473	}
474}
475
476BX.ajax.post = function(url, data, callback)
477{
478	data = BX.ajax.prepareData(data);
479
480	return BX.ajax({
481		'method': 'POST',
482		'dataType': 'html',
483		'url': url,
484		'data':  data,
485		'onsuccess': callback
486	});
487}
488
489/* load and execute external file script with onload emulation */
490BX.ajax.loadScriptAjax = function(script_src, callback)
491{
492	if (BX.type.isArray(script_src))
493	{
494		for (var i=0,len=script_src.length;i<len;i++)
495			BX.ajax.loadScriptAjax(script_src[i], callback);
496	}
497	else
498	{
499		if (r.script_self.test(script_src)) return;
500		if (r.script_self_window.test(script_src) && BX.CWindow) return;
501		if (r.script_self_admin.test(script_src) && BX.admin) return;
502
503		if (!loadedScripts[script_src])
504		{
505			return BX.ajax({
506				url: script_src,
507				method: 'GET',
508				dataType: 'script',
509				processData: true,
510				emulateOnload: false,
511				async: false,
512				start: true,
513				onsuccess: function(result) {
514					loadedScripts[script_src] = result;
515					if (callback)
516						callback(result);
517				}
518			});
519		}
520		else if (callback)
521		{
522			callback(loadedScripts[script_src]);
523		}
524	}
525}
526
527/* non-xhr loadings */
528BX.ajax.loadJSON = function(url, data, callback)
529{
530	if (BX.type.isFunction(data))
531	{
532		callback = data;
533		data = '';
534	}
535
536	data = BX.ajax.prepareData(data);
537
538	if (data)
539	{
540		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
541		data = '';
542	}
543
544	return BX.ajax({
545		'method': 'GET',
546		'dataType': 'json',
547		'url': url,
548		'onsuccess': callback
549	});
550}
551
552/*
553arObs = [{
554	url: url,
555	type: html|script|json|css,
556	callback: function
557}]
558*/
559BX.ajax.load = function(arObs, callback)
560{
561	if (!BX.type.isArray(arObs))
562		arObs = [arObs];
563
564	var cnt = 0;
565
566	if (!BX.type.isFunction(callback))
567		callback = BX.DoNothing;
568
569	var handler = function(data)
570		{
571			if (BX.type.isFunction(this.callback))
572				this.callback(data);
573
574			if (++cnt >= len)
575				callback();
576		};
577
578	for (var i = 0, len = arObs.length; i<len; i++)
579	{
580		switch(arObs.type.toUpperCase())
581		{
582			case 'SCRIPT':
583				BX.loadScript([arObs[i].url], jsBX.proxy(handler, arObs[i]));
584			break;
585			case 'CSS':
586				BX.loadCSS([arObs[i].url]);
587
588				if (++cnt >= len)
589					callback();
590			break;
591			case 'JSON':
592				BX.ajax.loadJSON(arObs.url, jsBX.proxy(handler, arObs[i]));
593			break;
594
595			default:
596				BX.ajax.get(arObs.url, '', jsBX.proxy(handler, arObs[i]));
597			break;
598		}
599	}
600}
601
602/* ajax form sending */
603BX.ajax.submit = function(obForm, callback)
604{
605	if (!obForm.target)
606	{
607		if (null == obForm.BXFormTarget)
608		{
609			var frame_name = 'formTarget_' + Math.random();
610			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
611				props: {
612					name: frame_name,
613					id: frame_name,
614					src: 'javascript:void(0)'
615				},
616				style: {
617					display: 'none'
618				}
619			}));
620		}
621
622		obForm.target = obForm.BXFormTarget.name;
623	}
624
625	obForm.BXFormCallback = callback;
626	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
627
628	BX.submit(obForm);
629
630	return false;
631}
632
633BX.ajax.submitComponentForm = function(obForm, container)
634{
635	if (!obForm.target)
636	{
637		if (null == obForm.BXFormTarget)
638		{
639			var frame_name = 'formTarget_' + Math.random();
640			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
641				props: {
642					name: frame_name,
643					id: frame_name,
644					src: 'javascript:void(0)'
645				},
646				style: {
647					display: 'none'
648				}
649			}));
650		}
651
652		obForm.target = obForm.BXFormTarget.name;
653	}
654
655	obForm.BXFormCallback = function(d) {
656		BX(container).innerHTML = d;
657		if (window.bxcompajaxframeonload){
658			setTimeout("window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;", 10)
659		};
660		BX.onCustomEvent('onAjaxSuccess', []);
661	};
662
663	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
664
665	return true;
666}
667
668// func will be executed in form context
669BX.ajax._submit_callback = function()
670{
671	//opera triggers onload event even on empty iframe
672	if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0)
673		return;
674
675	if (this.BXFormCallback)
676		this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]);
677
678	BX.unbindAll(this.BXFormTarget);
679}
680
681// TODO: currently in window extension. move it here.
682BX.ajax.submitAjax = function(obForm, callback)
683{
684
685}
686
687BX.ajax.UpdatePageData = function (arData)
688{
689	if (arData.TITLE)
690		BX.ajax.UpdatePageTitle(arData.TITLE);
691	if (arData.NAV_CHAIN)
692		BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN);
693	if (arData.CSS && arData.CSS.length > 0)
694		BX.loadCSS(arData.CSS);
695	if (arData.SCRIPTS && arData.SCRIPTS.length > 0)
696		BX.loadScript(arData.SCRIPTS);
697}
698
699BX.ajax.UpdatePageTitle = function(title)
700{
701	var obTitle = BX('pagetitle');
702	if (obTitle)
703	{
704		obTitle.removeChild(obTitle.firstChild);
705		if (!obTitle.firstChild)
706			obTitle.appendChild(document.createTextNode(title));
707		else
708			obTitle.insertBefore(document.createTextNode(title), obTitle.firstChild);
709	}
710
711	document.title = title;
712}
713
714BX.ajax.UpdatePageNavChain = function(nav_chain)
715{
716	var obNavChain = BX('navigation');
717	if (obNavChain)
718	{
719		obNavChain.innerHTML = nav_chain;
720	}
721}
722
723/* user options handling */
724BX.userOptions = {
725	options: null,
726	bSend: false,
727	delay: 5000
728}
729
730BX.userOptions.save = function(sCategory, sName, sValName, sVal, bCommon)
731{
732	if (null == BX.userOptions.options)
733		BX.userOptions.options = {};
734
735	bCommon = !!bCommon;
736	BX.userOptions.options[sCategory+'.'+sName+'.'+sValName] = [sCategory, sName, sValName, sVal, bCommon];
737
738	var sParam = BX.userOptions.__get();
739	if (sParam != '')
740		document.cookie = BX.message('COOKIE_PREFIX')+"_LAST_SETTINGS=" + sParam + "&sessid="+BX.bitrix_sessid()+"; expires=Thu, 31 Dec 2020 23:59:59 GMT; path=/;";
741
742	if(!BX.userOptions.bSend)
743	{
744		BX.userOptions.bSend = true;
745		setTimeout(function(){BX.userOptions.send(null)}, BX.userOptions.delay);
746	}
747}
748
749BX.userOptions.send = function(callback)
750{
751	var sParam = BX.userOptions.__get();
752	BX.userOptions.options = null;
753	BX.userOptions.bSend = false;
754
755	if (sParam != '')
756	{
757		document.cookie = BX.message('COOKIE_PREFIX') + "_LAST_SETTINGS=; path=/;";
758		BX.ajax({
759			'method': 'GET',
760			'dataType': 'html',
761			'processData': false,
762			'cache': false,
763			'url': '/bitrix/admin/user_options.php?'+sParam+'&sessid='+BX.bitrix_sessid(),
764			'onsuccess': callback
765		});
766	}
767}
768
769BX.userOptions.del = function(sCategory, sName, bCommon, callback)
770{
771	BX.ajax.get('/bitrix/admin/user_options.php?action=delete&c='+sCategory+'&n='+sName+(bCommon == true? '&common=Y':'')+'&sessid='+BX.bitrix_sessid(), callback);
772}
773
774BX.userOptions.__get = function()
775{
776	if (!BX.userOptions.options) return '';
777
778	var sParam = '', n = -1, prevParam = '', arOpt, i;
779
780	for (i in BX.userOptions.options)
781	{
782		aOpt = BX.userOptions.options[i];
783
784		if (prevParam != aOpt[0]+'.'+aOpt[1])
785		{
786			n++;
787			sParam += '&p['+n+'][c]='+BX.util.urlencode(aOpt[0]);
788			sParam += '&p['+n+'][n]='+BX.util.urlencode(aOpt[1]);
789			if (aOpt[4] == true)
790				sParam += '&p['+n+'][d]=Y';
791			prevParam = aOpt[0]+'.'+aOpt[1];
792		}
793
794		sParam += '&p['+n+'][v]['+BX.util.urlencode(aOpt[2])+']='+BX.util.urlencode(aOpt[3]);
795	}
796
797	return sParam.substr(1);
798}
799
800BX.ajax.history = {
801	expected_hash: '',
802
803	obParams: null,
804
805	obFrame: null,
806	obImage: null,
807
808	obTimer: null,
809
810	bInited: false,
811	bHashCollision: false,
812	bPushState: !!(history.pushState && BX.type.isFunction(history.pushState)),
813
814	init: function(obParams)
815	{
816		if (BX.ajax.history.bInited)
817			return;
818
819		this.obParams = obParams;
820		var obCurrentState = this.obParams.getState();
821
822		if (BX.ajax.history.bPushState)
823		{
824			BX.ajax.history.expected_hash = window.location.pathname;
825			if (window.location.search)
826				BX.ajax.history.expected_hash += window.location.search;
827
828			BX.ajax.history.put(obCurrentState, BX.ajax.history.expected_hash);
829			BX.bind(window, 'popstate', BX.ajax.history.__hashListener);
830		}
831		else
832		{
833			BX.ajax.history.expected_hash = window.location.hash;
834
835			if (!BX.ajax.history.expected_hash || BX.ajax.history.expected_hash == '#')
836				BX.ajax.history.expected_hash = '__bx_no_hash__';
837
838			jsAjaxHistoryContainer.put(BX.ajax.history.expected_hash, obCurrentState);
839			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
840
841			if (BX.browser.IsIE())
842			{
843				BX.ajax.history.obFrame = document.createElement('IFRAME');
844				BX.hide_object(BX.ajax.history.obFrame);
845
846				document.body.appendChild(BX.ajax.history.obFrame);
847
848				BX.ajax.history.obFrame.contentWindow.document.open();
849				BX.ajax.history.obFrame.contentWindow.document.write(BX.ajax.history.expected_hash);
850				BX.ajax.history.obFrame.contentWindow.document.close();
851			}
852			else if (BX.browser.IsOpera())
853			{
854				BX.ajax.history.obImage = document.createElement('IMG');
855				BX.hide_object(BX.ajax.history.obImage);
856
857				document.body.appendChild(BX.ajax.history.obImage);
858
859				BX.ajax.history.obImage.setAttribute('src', 'javascript:location.href = \'javascript:BX.ajax.history.__hashListener();\';');
860			}
861		}
862
863		BX.ajax.history.bInited = true;
864	},
865
866	__hashListener: function(e)
867	{
868		e = e || window.event || {state:false};
869
870		if (BX.ajax.history.bPushState && e.state)
871		{
872			BX.ajax.history.obParams.setState(e.state);
873		}
874		else
875		{
876			if (BX.ajax.history.obTimer)
877			{
878				window.clearTimeout(BX.ajax.history.obTimer);
879				BX.ajax.history.obTimer = null;
880			}
881
882			if (null != BX.ajax.history.obFrame)
883				var current_hash = BX.ajax.history.obFrame.contentWindow.document.body.innerText;
884			else
885				var current_hash = window.location.hash;
886
887			if (!current_hash || current_hash == '#')
888				current_hash = '__bx_no_hash__';
889
890			if (current_hash.indexOf('#') == 0)
891				current_hash = current_hash.substring(1);
892
893			if (current_hash != BX.ajax.history.expected_hash)
894			{
895				var state = jsAjaxHistoryContainer.get(current_hash);
896				if (state)
897				{
898					BX.ajax.history.obParams.setState(state);
899
900					BX.ajax.history.expected_hash = current_hash;
901					if (null != BX.ajax.history.obFrame)
902					{
903						var __hash = current_hash == '__bx_no_hash__' ? '' : current_hash;
904						if (window.location.hash != __hash && window.location.hash != '#' + __hash)
905							window.location.hash = __hash;
906					}
907				}
908			}
909
910			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
911		}
912	},
913
914	put: function(state, new_hash, new_hash1)
915	{
916		if (this.bPushState)
917		{
918			history.pushState(state, '', new_hash);
919		}
920		else
921		{
922			if (typeof new_hash1 != 'undefined')
923				new_hash = new_hash1;
924			else
925				new_hash = 'view' + new_hash;
926
927			jsAjaxHistoryContainer.put(new_hash, state);
928			BX.ajax.history.expected_hash = new_hash;
929
930			window.location.hash = BX.util.urlencode(new_hash);
931
932			if (null != BX.ajax.history.obFrame)
933			{
934				BX.ajax.history.obFrame.contentWindow.document.open();
935				BX.ajax.history.obFrame.contentWindow.document.write(new_hash);
936				BX.ajax.history.obFrame.contentWindow.document.close();
937			}
938		}
939	},
940
941	checkRedirectStart: function(param_name, param_value)
942	{
943		var current_hash = window.location.hash;
944		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
945
946		var test = current_hash.substring(0, 5);
947		if (test == 'view/' || test == 'view%')
948		{
949			BX.ajax.history.bHashCollision = true;
950			document.write('<' + 'div id="__ajax_hash_collision_' + param_value + '" style="display: none;">');
951		}
952	},
953
954	checkRedirectFinish: function(param_name, param_value)
955	{
956		document.write('</div>');
957
958		var current_hash = window.location.hash;
959		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
960
961		BX.ready(function ()
962		{
963			var test = current_hash.substring(0, 5);
964			if (test == 'view/' || test == 'view%')
965			{
966				var obColNode = BX('__ajax_hash_collision_' + param_value);
967				var obNode = obColNode.firstChild;
968				BX.cleanNode(obNode);
969				obColNode.style.display = 'block';
970
971				// IE, Opera and Chrome automatically modifies hash with urlencode, but FF doesn't ;-(
972				if (test != 'view%')
973					current_hash = BX.util.urlencode(current_hash);
974
975				current_hash += (current_hash.indexOf('%3F') == -1 ? '%3F' : '%26') + param_name + '=' + param_value;
976
977				var url = '/bitrix/tools/ajax_redirector.php?hash=' + current_hash;
978
979				BX.ajax.insertToNode(url, obNode);
980			}
981		});
982	}
983}
984
985BX.ajax.component = function(node)
986{
987	this.node = node;
988}
989
990BX.ajax.component.prototype.getState = function()
991{
992	var state = {
993		'node': this.node,
994		'title': window.document.title,
995		'data': BX(this.node).innerHTML
996	};
997
998	var obNavChain = BX('navigation');
999	if (null != obNavChain)
1000		state.nav_chain = obNavChain.innerHTML;
1001
1002	return state;
1003}
1004
1005BX.ajax.component.prototype.setState = function(state)
1006{
1007	BX(state.node).innerHTML = state.data;
1008	BX.ajax.UpdatePageTitle(state.title);
1009
1010	if (state.nav_chain)
1011		BX.ajax.UpdatePageNavChain(state.nav_chain);
1012}
1013
1014var jsAjaxHistoryContainer = {
1015	arHistory: {},
1016
1017	put: function(hash, state)
1018	{
1019		this.arHistory[hash] = state;
1020	},
1021
1022	get: function(hash)
1023	{
1024		return this.arHistory[hash];
1025	}
1026}
1027
1028
1029BX.ajax.FormData = function()
1030{
1031	this.elements = [];
1032	this.files = [];
1033	this.features = {};
1034	this.isSupported();
1035	this.log('BX FormData init');
1036}
1037
1038BX.ajax.FormData.isSupported = function()
1039{
1040	var f = new BX.ajax.FormData()
1041	var result = f.features.supported;
1042	f = null;
1043	return result;
1044}
1045
1046BX.ajax.FormData.prototype.log = function(o)
1047{
1048	if (false) {
1049		try {
1050			if (BX.browser.IsIE()) o = JSON.stringify(o);
1051			console.log(o);
1052		} catch(e) {}
1053	}
1054}
1055
1056BX.ajax.FormData.prototype.isSupported = function()
1057{
1058	var f = {};
1059	f.fileReader = (window.FileReader && window.FileReader.prototype.readAsBinaryString);
1060	f.readFormData = f.sendFormData = !!(window.FormData);
1061	f.supported = !!(f.readFormData && f.sendFormData);
1062	this.features = f;
1063	this.log('features:');
1064	this.log(f);
1065
1066	return f.supported;
1067}
1068
1069BX.ajax.FormData.prototype.append = function(name, value)
1070{
1071	if (typeof(value) === 'object') { // seems to be files element
1072		this.files.push({'name': name, 'value':value});
1073	} else {
1074		this.elements.push({'name': name, 'value':value});
1075	}
1076}
1077
1078BX.ajax.FormData.prototype.send = function(url, callbackOk, callbackProgress, callbackError)
1079{
1080	this.log('FD send');
1081	this.xhr = BX.ajax({
1082			'method': 'POST',
1083			'dataType': 'html',
1084			'url': url,
1085			'onsuccess': callbackOk,
1086			'onerror': callbackError,
1087			'start': false,
1088			'preparePost':false
1089		});
1090
1091	if (callbackProgress)
1092	{
1093		this.xhr.upload.addEventListener(
1094			'progress', 
1095			function(e) {
1096				if (e.lengthComputable)
1097					callbackProgress(e.loaded / e.totalSize);
1098			},
1099			false
1100		);
1101	}
1102
1103	if (this.features.readFormData && this.features.sendFormData)
1104	{
1105		var fd = new FormData();
1106		this.log('use browser formdata');
1107		for (i in this.elements)
1108			fd.append(this.elements[i].name,this.elements[i].value);
1109		for (i in this.files)
1110			fd.append(this.files[i].name, this.files[i].value);
1111		this.xhr.send(fd);
1112	}
1113
1114	return this.xhr;
1115}
1116})(window)

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.