PageSourceSearch

https://santosepulcro.co.il/bitrix/js/main/core/core_ajax.js?161486529741997

js santosepulcro.co.il collected 2026-10-02 07:14:34 UTC 41,997 bytes, 1,868 lines download raw bytes

1;(function(window){
2
3if (window.BX.ajax)
4	return;
5
6var
7	BX = window.BX,
8
9	tempDefaultConfig = {},
10	defaultConfig = {
11		method: 'GET', // request method: GET|POST
12		dataType: 'html', // type of data loading: html|json|script
13		timeout: 0, // request timeout in seconds. 0 for browser-default
14		async: true, // whether request is asynchronous or not
15		processData: true, // any data processing is disabled if false, only callback call
16		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
17		emulateOnload: true,
18		skipAuthCheck: false, // whether to check authorization failure (SHOUD be set to true for CORS requests)
19		start: true, // send request immediately (if false, request can be started manually via XMLHttpRequest object returned)
20		cache: true, // whether NOT to add random addition to URL
21		preparePost: true, // whether set Content-Type x-www-form-urlencoded in POST
22		headers: false, // add additional headers, example: [{'name': 'If-Modified-Since', 'value': 'Wed, 15 Aug 2012 08:59:08 GMT'}, {'name': 'If-None-Match', 'value': '0'}]
23		lsTimeout: 30, //local storage data TTL. useless without lsId.
24		lsForce: false //wheter to force query instead of using localStorage data. useless without lsId.
25/*
26other parameters:
27	url: url to get/post
28	data: data to post
29	onsuccess: successful request callback. BX.proxy may be used.
30	onfailure: request failure callback. BX.proxy may be used.
31	onprogress: request progress callback. BX.proxy may be used.
32
33	lsId: local storage id - for constantly updating queries which can communicate via localStorage. core_ls.js needed
34
35any of the default parameters can be overridden. defaults can be changed by BX.ajax.Setup() - for all further requests!
36*/
37	},
38	ajax_session = null,
39	loadedScripts = {},
40	loadedScriptsQueue = [],
41	r = {
42		'url_utf': /[^\034-\254]+/g,
43		'script_self': /\/bitrix\/js\/main\/core\/core(_ajax)*.js$/i,
44		'script_self_window': /\/bitrix\/js\/main\/core\/core_window.js$/i,
45		'script_self_admin': /\/bitrix\/js\/main\/core\/core_admin.js$/i,
46		'script_onload': /window.onload/g
47	};
48
49// low-level method
50BX.ajax = function(config)
51{
52	var status, data;
53
54	if (!config || !config.url || !BX.type.isString(config.url))
55	{
56		return false;
57	}
58
59	for (var i in tempDefaultConfig)
60		if (typeof (config[i]) == "undefined") config[i] = tempDefaultConfig[i];
61
62	tempDefaultConfig = {};
63
64	for (i in defaultConfig)
65		if (typeof (config[i]) == "undefined") config[i] = defaultConfig[i];
66
67	config.method = config.method.toUpperCase();
68
69	if (!BX.localStorage)
70		config.lsId = null;
71
72	if (BX.browser.IsIE())
73	{
74		var result = r.url_utf.exec(config.url);
75		if (result)
76		{
77			do
78			{
79				config.url = config.url.replace(result, BX.util.urlencode(result));
80				result = r.url_utf.exec(config.url);
81			} while (result);
82		}
83	}
84
85	if(config.dataType == 'json')
86		config.emulateOnload = false;
87
88	if (!config.cache && config.method == 'GET')
89		config.url = BX.ajax._uncache(config.url);
90
91	if (config.method == 'POST' && config.preparePost)
92	{
93		config.data = BX.ajax.prepareData(config.data);
94	}
95
96	var bXHR = true;
97	if (config.lsId && !config.lsForce)
98	{
99		var v = BX.localStorage.get('ajax-' + config.lsId);
100		if (v !== null)
101		{
102			bXHR = false;
103
104			var lsHandler = function(lsData) {
105				if (lsData.key == 'ajax-' + config.lsId && lsData.value != 'BXAJAXWAIT')
106				{
107					var data = lsData.value,
108						bRemove = !!lsData.oldValue && data == null;
109					if (!bRemove)
110						BX.ajax.__run(config, data);
111					else if (config.onfailure)
112						config.onfailure("timeout");
113
114					BX.removeCustomEvent('onLocalStorageChange', lsHandler);
115				}
116			};
117
118			if (v == 'BXAJAXWAIT')
119			{
120				BX.addCustomEvent('onLocalStorageChange', lsHandler);
121			}
122			else
123			{
124				setTimeout(function() {lsHandler({key: 'ajax-' + config.lsId, value: v})}, 10);
125			}
126		}
127	}
128
129	if (bXHR)
130	{
131		config.xhr = BX.ajax.xhr();
132		if (!config.xhr) return;
133
134		if (config.lsId)
135		{
136			BX.localStorage.set('ajax-' + config.lsId, 'BXAJAXWAIT', config.lsTimeout);
137		}
138
139		config.xhr.open(config.method, config.url, config.async);
140
141		if (!config.skipBxHeader && !BX.ajax.isCrossDomain(config.url))
142		{
143			config.xhr.setRequestHeader('Bx-ajax', 'true');
144		}
145
146		if (config.method == 'POST' && config.preparePost)
147		{
148			config.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
149		}
150		if (typeof(config.headers) == "object")
151		{
152			for (i = 0; i < config.headers.length; i++)
153				config.xhr.setRequestHeader(config.headers[i].name, config.headers[i].value);
154		}
155
156		if(!!config.onprogress)
157		{
158			BX.bind(config.xhr, 'progress', config.onprogress);
159		}
160
161		var bRequestCompleted = false;
162		var onreadystatechange = config.xhr.onreadystatechange = function(additional)
163		{
164			if (bRequestCompleted)
165				return;
166
167			if (additional === 'timeout')
168			{
169				if (config.onfailure)
170				{
171					config.onfailure("timeout");
172				}
173
174				BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['timeout', '', config]);
175
176				config.xhr.onreadystatechange = BX.DoNothing;
177				config.xhr.abort();
178
179				if (config.async)
180				{
181					config.xhr = null;
182				}
183			}
184			else
185			{
186				if (config.xhr.readyState == 4 || additional == 'run')
187				{
188					status = BX.ajax.xhrSuccess(config.xhr) ? "success" : "error";
189					bRequestCompleted = true;
190					config.xhr.onreadystatechange = BX.DoNothing;
191
192					if (status == 'success')
193					{
194						var authHeader = (!!config.skipAuthCheck || BX.ajax.isCrossDomain(config.url))
195							? false
196							: config.xhr.getResponseHeader('X-Bitrix-Ajax-Status');
197
198						if(!!authHeader && authHeader == 'Authorize')
199						{
200							if (config.onfailure)
201							{
202								config.onfailure("auth", config.xhr.status);
203							}
204
205							BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['auth', config.xhr.status, config]);
206						}
207						else
208						{
209							var data = config.xhr.responseText;
210
211							if (config.lsId)
212							{
213								BX.localStorage.set('ajax-' + config.lsId, data, config.lsTimeout);
214							}
215
216							BX.ajax.__run(config, data);
217						}
218					}
219					else
220					{
221						if (config.onfailure)
222						{
223							config.onfailure("status", config.xhr.status);
224						}
225
226						BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['status', config.xhr.status, config]);
227					}
228
229					if (config.async)
230					{
231						config.xhr = null;
232					}
233				}
234			}
235		};
236
237		if (config.async && config.timeout > 0)
238		{
239			setTimeout(function() {
240				if (config.xhr && !bRequestCompleted)
241				{
242					onreadystatechange("timeout");
243				}
244			}, config.timeout * 1000);
245		}
246
247		if (config.start)
248		{
249			config.xhr.send(config.data);
250
251			if (!config.async)
252			{
253				onreadystatechange('run');
254			}
255		}
256
257		return config.xhr;
258	}
259};
260
261BX.ajax.xhr = function()
262{
263	if (window.XMLHttpRequest)
264	{
265		try {return new XMLHttpRequest();} catch(e){}
266	}
267	else if (window.ActiveXObject)
268	{
269		try { return new window.ActiveXObject("Msxml2.XMLHTTP.6.0"); }
270			catch(e) {}
271		try { return new window.ActiveXObject("Msxml2.XMLHTTP.3.0"); }
272			catch(e) {}
273		try { return new window.ActiveXObject("Msxml2.XMLHTTP"); }
274			catch(e) {}
275		try { return new window.ActiveXObject("Microsoft.XMLHTTP"); }
276			catch(e) {}
277		throw new Error("This browser does not support XMLHttpRequest.");
278	}
279
280	return null;
281};
282
283BX.ajax.isCrossDomain = function(url, location)
284{
285	location = location || window.location;
286
287	//Relative URL gets a current protocol
288	if (url.indexOf("//") === 0)
289	{
290		url = location.protocol + url;
291	}
292
293	//Fast check
294	if (url.indexOf("http") !== 0)
295	{
296		return false;
297	}
298
299	var link = window.document.createElement("a");
300	link.href = url;
301
302	return  link.protocol !== location.protocol ||
303			link.hostname !== location.hostname ||
304			BX.ajax.getHostPort(link.protocol, link.host) !== BX.ajax.getHostPort(location.protocol, location.host);
305};
306
307BX.ajax.getHostPort = function(protocol, host)
308{
309	var match = /:(\d+)$/.exec(host);
310	if (match)
311	{
312		return match[1];
313	}
314	else
315	{
316		if (protocol === "http:")
317		{
318			return "80";
319		}
320		else if (protocol === "https:")
321		{
322			return "443";
323		}
324	}
325
326	return "";
327};
328
329BX.ajax.__prepareOnload = function(scripts)
330{
331	if (scripts.length > 0)
332	{
333		BX.ajax['onload_' + ajax_session] = null;
334
335		for (var i=0,len=scripts.length;i<len;i++)
336		{
337			if (scripts[i].isInternal)
338			{
339				scripts[i].JS = scripts[i].JS.replace(r.script_onload, 'BX.aja
339x.onload_' + ajax_session);
340			}
341		}
342	}
343
344	BX.CaptureEventsGet();
345	BX.CaptureEvents(window, 'load');
346};
347
348BX.ajax.__runOnload = function()
349{
350	if (null != BX.ajax['onload_' + ajax_session])
351	{
352		BX.ajax['onload_' + ajax_session].apply(window);
353		BX.ajax['onload_' + ajax_session] = null;
354	}
355
356	var h = BX.CaptureEventsGet();
357
358	if (h)
359	{
360		for (var i=0; i<h.length; i++)
361			h[i].apply(window);
362	}
363};
364
365BX.ajax.__run = function(config, data)
366{
367	if (!config.processData)
368	{
369		if (config.onsuccess)
370		{
371			config.onsuccess(data);
372		}
373
374		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [data, config]);
375	}
376	else
377	{
378		data = BX.ajax.processRequestData(data, config);
379	}
380};
381
382
383BX.ajax._onParseJSONFailure = function(data)
384{
385	this.jsonFailure = true;
386	this.jsonResponse = data;
387	this.jsonProactive = /^\[WAF\]/.test(data);
388};
389
390BX.ajax.processRequestData = function(data, config)
391{
392	var result, scripts = [], styles = [];
393	switch (config.dataType.toUpperCase())
394	{
395		case 'JSON':
396
397			BX.addCustomEvent(config.xhr, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
398			result = BX.parseJSON(data, config.xhr);
399			BX.removeCustomEvent(config.xhr, 'onParseJSONFailure', BX.proxy(BX.ajax._onParseJSONFailure, config));
400
401			if(!!result && BX.type.isArray(result['bxjs']))
402			{
403				for(var i = 0; i < result['bxjs'].length; i++)
404				{
405					if(BX.type.isNotEmptyString(result['bxjs'][i]))
406					{
407						scripts.push({
408							"isInternal": false,
409							"JS": result['bxjs'][i],
410							"bRunFirst": config.scriptsRunFirst
411						});
412					}
413					else
414					{
415						scripts.push(result['bxjs'][i])
416					}
417				}
418			}
419
420			if(!!result && BX.type.isArray(result['bxcss']))
421			{
422				styles = result['bxcss'];
423			}
424
425		break;
426		case 'SCRIPT':
427			scripts.push({"isInternal": true, "JS": data, "bRunFirst": config.scriptsRunFirst});
428			result = data;
429		break;
430
431		default: // HTML
432			var ob = BX.processHTML(data, config.scriptsRunFirst);
433			result = ob.HTML; scripts = ob.SCRIPT; styles = ob.STYLE;
434		break;
435	}
436
437	var bSessionCreated = false;
438	if (null == ajax_session)
439	{
440		ajax_session = parseInt(Math.random() * 1000000);
441		bSessionCreated = true;
442	}
443
444	if (styles.length > 0)
445		BX.loadCSS(styles);
446
447	if (config.emulateOnload)
448			BX.ajax.__prepareOnload(scripts);
449
450	var cb = BX.DoNothing;
451	if(config.emulateOnload || bSessionCreated)
452	{
453		cb = BX.defer(function()
454		{
455			if (config.emulateOnload)
456				BX.ajax.__runOnload();
457			if (bSessionCreated)
458				ajax_session = null;
459			BX.onCustomEvent(config.xhr, 'onAjaxSuccessFinish', [config]);
460		});
461	}
462
463	try
464	{
465		if (!!config.jsonFailure)
466		{
467			throw {type: 'json_failure', data: config.jsonResponse, bProactive: config.jsonProactive};
468		}
469
470		config.scripts = scripts;
471
472		BX.ajax.processScripts(config.scripts, true);
473
474		if (config.onsuccess)
475		{
476			config.onsuccess(result);
477		}
478
479		BX.onCustomEvent(config.xhr, 'onAjaxSuccess', [result, config]);
480
481		BX.ajax.processScripts(config.scripts, false, cb);
482	}
483	catch (e)
484	{
485		if (config.onfailure)
486			config.onfailure("processing", e);
487		BX.onCustomEvent(config.xhr, 'onAjaxFailure', ['processing', e, config]);
488	}
489};
490
491BX.ajax.processScripts = function(scripts, bRunFirst, cb)
492{
493	var scriptsExt = [], scriptsInt = '';
494
495	cb = cb || BX.DoNothing;
496
497	for (var i = 0, length = scripts.length; i < length; i++)
498	{
499		if (typeof bRunFirst != 'undefined' && bRunFirst != !!scripts[i].bRunFirst)
500			continue;
501
502		if (scripts[i].isInternal)
503			scriptsInt += ';' + scripts[i].JS;
504		else
505			scriptsExt.push(scripts[i].JS);
506	}
507
508	scriptsExt = BX.util.array_unique(scriptsExt);
509	var inlineScripts = scriptsInt.length > 0 ? function() { BX.evalGlobal(scriptsInt); } : BX.DoNothing;
510
511	if (scriptsExt.length > 0)
512	{
513		BX.load(scriptsExt, function() {
514			inlineScripts();
515			cb();
516		});
517	}
518	else
519	{
520		inlineScripts();
521		cb();
522	}
523};
524
525// TODO: extend this function to use with any data objects or forms
526BX.ajax.prepareData = function(arData, prefix)
527{
528	var data = '';
529	if (BX.type.isString(arData))
530		data = arData;
531	else if (null != arData)
532	{
533		for(var i in arData)
534		{
535			if (arData.hasOwnProperty(i))
536			{
537				if (data.length > 0)
538					data += '&';
539				var name = BX.util.urlencode(i);
540				if(prefix)
541					name = prefix + '[' + name + ']';
542				if(typeof arData[i] == 'object')
543					data += BX.ajax.prepareData(arData[i], name);
544				else
545					data += name + '=' + BX.util.urlencode(arData[i]);
546			}
547		}
548	}
549	return data;
550};
551
552BX.ajax.xhrSuccess = function(xhr)
553{
554	return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
555};
556
557BX.ajax.Setup = function(config, bTemp)
558{
559	bTemp = !!bTemp;
560
561	for (var i in config)
562	{
563		if (bTemp)
564			tempDefaultConfig[i] = config[i];
565		else
566			defaultConfig[i] = config[i];
567	}
568};
569
570BX.ajax.replaceLocalStorageValue = function(lsId, data, ttl)
571{
572	if (!!BX.localStorage)
573		BX.localStorage.set('ajax-' + lsId, data, ttl);
574};
575
576
577BX.ajax._uncache = function(url)
578{
579	return url + ((url.indexOf('?') !== -1 ? "&" : "?") + '_=' + (new Date()).getTime());
580};
581
582/* simple interface */
583BX.ajax.get = function(url, data, callback)
584{
585	if (BX.type.isFunction(data))
586	{
587		callback = data;
588		data = '';
589	}
590
591	data = BX.ajax.prepareData(data);
592
593	if (data)
594	{
595		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
596		data = '';
597	}
598
599	return BX.ajax({
600		'method': 'GET',
601		'dataType': 'html',
602		'url': url,
603		'data':  '',
604		'onsuccess': callback
605	});
606};
607
608BX.ajax.getCaptcha = function(callback)
609{
610	return BX.ajax.loadJSON('/bitrix/tools/ajax_captcha.php', callback);
611};
612
613BX.ajax.insertToNode = function(url, node)
614{
615	node = BX(node);
616	if (!!node)
617	{
618		var eventArgs = { cancel: false };
619		BX.onCustomEvent('onAjaxInsertToNode', [{ url: url, node: node, eventArgs: eventArgs }]);
620		if(eventArgs.cancel === true)
621		{
622			return;
623		}
624
625		var show = null;
626		if (!tempDefaultConfig.denyShowWait)
627		{
628			show = BX.showWait(node);
629			delete tempDefaultConfig.denyShowWait;
630		}
631
632		return BX.ajax.get(url, function(data) {
633			node.innerHTML = data;
634			BX.closeWait(node, show);
635		});
636	}
637};
638
639BX.ajax.post = function(url, data, callback)
640{
641	data = BX.ajax.prepareData(data);
642
643	return BX.ajax({
644		'method': 'POST',
645		'dataType': 'html',
646		'url': url,
647		'data':  data,
648		'onsuccess': callback
649	});
650};
651
652/**
653 * BX.ajax with BX.Promise
654 *
655 * @param config
656 * @returns {BX.Promise|false}
657 */
658BX.ajax.promise = function(config)
659{
660	var result = new BX.Promise();
661
662	config.onsuccess = function(data)
663	{
664		result.fulfill(data);
665	};
666	config.onfailure = function(reason, data)
667	{
668		result.reject({
669			reason: reason,
670			data: data
671		});
672	};
673	config.onprogress = function(data)
674	{
675		if (data.position == 0 && data.totalSize == 0)
676		{
677			result.reject({
678				reason: 'progress',
679				data: data
680			});
681		}
682	};
683
684	var xhr = BX.ajax(config);
685	if (xhr)
686	{
687		if (typeof config.onrequeststart === 'function')
688		{
689			config.onrequeststart(xhr);
690		}
691	}
692	else
693	{
694		result.reject({
695			reason: "init",
696			data: false
697		});
698	}
699
700	return result;
701};
702
703/* load and execute external file script with onload emulation */
704BX.ajax.loadScriptAjax = function(script_src, callback, bPreload)
705{
706	if (BX.type.isArray(script_src))
707	{
708		for (var i=0,len=script_src.length;i<len;i++)
709		{
710			BX.ajax.loadScriptAjax(script_src[i], callback, bPreload);
711		}
712	}
713	else
714	{
715		var script_src_test = script_src.replace(/\.js\?.*/, '.js');
716
717		if (r.script_self.test(script_src_test)) return;
718		if (r.script_self_window.test(script_src_test) && BX.CWindow) return;
719		if (r.script_self_admin.test(script_src_test) && BX.admin) return;
720
721		if (typeof loadedScripts[script_src_test] == 'undefined')
722		{
723			if (!!bPreload)
724			{
725				loadedScripts[script_src_test] = '';
726				return BX.loadScript(script_src);
727			}
728			else
729			{
730				return BX.ajax({
731					url: script_src,
732					method: 'GET',
733					dataType: 'script',
734					processData: true,
735					emulateOnload: false,
736					scriptsRunFirst: true,
737					async: false,
738					start: true,
739					onsuccess: function(result) {
740						loadedScripts[script_src_test] = result;
741						if (callback)
742							callback(result);
743					}
744				});
745			}
746		}
747		else if (callback)
748		{
749			callback(loadedScripts[script_src_test]);
750		}
751	}
752};
753
754/* non-xhr loadings */
755BX.ajax.loadJSON = function(url, data, callback, callback_failure)
756{
757	if (BX.type.isFunction(data))
758	{
759		callback_failure = callback;
760		callback = data;
761		data = '';
762	}
763
764	data = BX.ajax.prepareData(data);
765
766	if (data)
767	{
768		url += (url.indexOf('?') !== -1 ? "&" : "?") + data;
769		data = '';
770	}
771
772	return BX.ajax({
773		'method': 'GET',
774		'dataType': 'json',
775		'url': url,
776		'onsuccess': callback,
777		'onfailure': callback_failure
778	});
779};
780
781
782var prepareAjaxGetParameters = function(config)
783{
784	var getParameters = config.getParameters || {};
785	if (BX.type.isNotEmptyString(config.analyticsLabel))
786	{
787		getParameters.analyticsLabel = config.analyticsLabel;
788	}
789	else if (BX.type.isNotEmptyObject(config.analyticsLabel))
790	{
791		getParameters.analyticsLabel = config.analyticsLabel;
792	}
793	if (typeof config.mode !== 'undefined')
794	{
795		getParameters.mode = config.mode;
796	}
797	if (config.navigation)
798	{
799		if(config.navigation.page)
800		{
801			getParameters.nav = 'page-' + config.navigation.page;
802		}
803		if(config.navigation.size)
804		{
805			if(getParameters.nav)
806			{
807				getParameters.nav += '-';
808			}
809			else
810			{
811				getParameters.nav = '';
812			}
813			getParameters.nav += 'size-' + config.navigation.size;
814		}
815	}
816
817	return getParameters;
818};
819
820var prepareAjaxConfig = function(config)
821{
822	config = BX.type.isPlainObject(config) ? config : {};
823
824	if (config.data instanceof FormData)
825	{
826		config.preparePost = false;
827
828		config.data.append('sessid', BX.bitrix_sessid());
829		if (BX.message.SITE_ID)
830		{
831			config.data.append('SITE_ID', BX.message.SITE_ID);
832		}
833		if (typeof config.signedParameters !== 'undefined')
834		{
835			config.data.append('signedParameters', config.signedParameters);
836		}
837	}
838	else
839	{
840		config.data = BX.type.isPlainObject(config.data) ? config.data : {};
841		if (BX.message.SITE_ID)
842		{
843			config.data.SITE_ID = BX.message.SITE_ID;
844		}
845		config.data.sessid = BX.bitrix_sessid();
846		if (typeof config.signedParameters !== 'undefined')
847		{
848			config.data.signedParameters = config.signedParameters;
849		}
850	}
851
852	if (!config.method)
853	{
854		config.method = 'POST'
855	}
856
857	return config;
858};
859
860var buildAjaxPromiseToRestoreCsrf = function(config, withoutRestoringCsrf)
861{
862	withoutRestoringCsrf = withoutRestoringCsrf || false;
863	var originalConfig = BX.clone(config);
864	var promise = BX.ajax.promise(config);
865
866	return promise.then(function(response) {
867		if (!withoutRestoringCsrf && BX.type.isPlainObject(response) && BX.type.isArray(response.errors))
868		{
869			var csrfProblem = false;
870			response.errors.forEach(function(error) {
871				if (error.code === 'invalid_csrf' && error.customData.csrf)
872				{
873					BX.message({'bitrix_sessid': error.customData.csrf});
874					originalConfig.data.sessid = BX.bitrix_sessid();
875
876					csrfProblem = true;
877				}
878			});
879
880			if (csrfProblem)
881			{
882				return buildAjaxPromiseToRestoreCsrf(originalConfig, true);
883			}
884		}
885
886		if (!BX.type.isPlainObject(response) || response.status !== 'success')
887		{
888			var errorPromise = new BX.Promise();
889			errorPromise.reject(response);
890
891			return errorPromise;
892		}
893
894		return response;
895	}).catch(function(data) {
896		var ajaxReject = new BX.Promise();
897
898		if (BX.type.isPlainObject(data) && data.status && data.hasOwnProperty('data'))
899		{
900			ajaxReject.reject(data);
901		}
902		else
903		{
904			ajaxReject.reject({
905				status: 'error',
906				data: {
907					ajaxRejectData: data
908				},
909				errors: [
910					{
911						code: 'NETWORK_ERROR',
912						message: 'Network error'
913					}
914				]
915			});
916		}
917
918		return ajaxReject;
919	});
920};
921
922/**
923 *
924 * @param {string} action
925 * @param {Object} config
926 * @param {?string|?Object} [config.analyticsLabel]
927 * @param {string} [config.method='POST']
928 * @param {Object} [config.data]
929 * @param {?Object} [config.getParameters]
930 * @param {?Object} [config.headers]
931 * @param {?Object} [config.timeout]
932 * @param {Object} [config.navigation]
933 * @param {number} [config.navigation.page]
934 */
935BX.ajax.runAction = function(action, config)
936{
937	config = prepareAjaxConfig(config);
938	var getParameters = prepareAjaxGetParameters(config);
939	getParameters.action = action;
940
941	var url = '/bitrix/services/main/ajax.php?' + BX.ajax.prepareData(getParameters);
942
943	return buildAjaxPromiseToRestoreCsrf({
944		method: config.method,
945		dataType: 'json',
946		url: url,
947		data: config.data,
948		timeout: config.timeout,
949		preparePost: config.preparePost,
950		headers: config.headers,
951		onrequeststart: config.onrequeststart
952	});
953};
954
955/**
956 *
957 * @param {string} component
958 * @param {string} action
959 * @param {Object} config
960 * @param {?string|?Object} [config.analyticsLabel]
961 * @param {?string} [config.signedParameters]
962 * @param {string} [config.method='POST']
963 * @param {string} [config.mode='ajax'] Ajax or class.
964 * @param {Object} [config.data]
965 * @param {?Object} [config.getParameters]
966 * @param {?array} [config.headers]
967 * @param {?number} [config.timeout]
968 * @param {Object} [config.navigation]
969 */
970BX.ajax.runComponentAction = function (component, action, config)
971{
972	config = prepareAjaxConfig(config);
973	config.mode = config.mode || 'ajax';
974
975	var getParameters = prepareAjaxGetParameters(config);
976	getParameters.c = component;
977	getParameters.action = action;
978
979	var url = '/bitrix/services/main/ajax.php?' + BX.ajax.prepareData(getParameters);
980
981	return buildAjaxPromiseToRestoreCsrf({
982		method: config.method,
983		dataType: 'json',
984		url: url,
985		data: config.data,
986		timeout: config.timeout,
987		preparePost: config.preparePost,
988		headers: config.headers,
989		onrequeststart: (config.onrequeststart ? config.onrequeststart : null)
990	});
991};
992
993/*
994arObs = [{
995	url: url,
996	type: html|script|json|css,
997	callback: function
998}]
999*/
1000BX.ajax.load = function(arObs, callback)
1001{
1002	if (!BX.type.isArray(arObs))
1003		arObs = [arObs];
1004
1005	var cnt = 0;
1006
1007	if (!BX.type.isFunction(callback))
1008		callback = BX.DoNothing;
1009
1010	var handler = function(data)
1011		{
1012			if (BX.type.isFunction(this.callback))
1013				this.callback(data);
1014
1015			if (++cnt >= len)
1016				callback();
1017		};
1018
1019	for (var i = 0, len = arObs.length; i<len; i++)
1020	{
1021		switch(arObs[i].type.toUpperCase())
1022		{
1023			case 'SCRIPT':
1024				BX.loadScript([arObs[i].url], BX.proxy(handler, arObs[i]));
1025			break;
1026			case 'CSS':
1027				BX.loadCSS([arObs[i].url]);
1028
1029				if (++cnt >= len)
1030					callback();
1031			break;
1032			case 'JSON':
1033				BX.ajax.loadJSON(arObs[i].url, BX.proxy(handler, arObs[i]));
1034			break;
1035
1036			default:
1037				BX.ajax.get(arObs[i].url, '', BX.proxy(handler, arObs[i]));
1038			break;
1039		}
1040	}
1041};
1042
1043/* ajax form sending */
1044BX.ajax.submit = function(obForm, callback)
1045{
1046	if (!obForm.target)
1047	{
1048		if (null == obForm.BXFormTarget)
1049		{
1050			var frame_name = 'formTarget_' + Math.random();
1051			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
1052				props: {
1053					name: frame_name,
1054					id: frame_name,
1055					src: 'javascript:void(0)'
1056				},
1057				style: {
1058					display: 'none'
1059				}
1060			}));
1061		}
1062
1063		obForm.target = obForm.BXFormTarget.name;
1064	}
1065
1066	obForm.BXFormCallback = callback;
1067	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
1068
1069	BX.submit(obForm);
1070
1071	return false;
1072};
1073
1074BX.ajax.submitComponentForm = function(obForm, container, bWait)
1075{
1076	if (!obForm.target)
1077	{
1078		if (null == obForm.BXFormTarget)
1079		{
1080			var frame_name = 'formTarget_' + Math.random();
1081			obForm.BXFormTarget = document.body.appendChild(BX.create('IFRAME', {
1082				props: {
1083					name: frame_name,
1084					id: frame_name,
1085					src: 'javascript:void(0)'
1086				},
1087				style: {
1088					display: 'none'
1089				}
1090			}));
1091		}
1092
1093		obForm.target = obForm.BXFormTarget.name;
1094	}
1095
1096	if (!!bWait)
1097		var w = BX.showWait(container);
1098
1099	obForm.BXFormCallback = function(d) {
1100		if (!!bWait)
1101			BX.closeWait(w);
1102
1103		var callOnload = function(){
1104			if(!!window.bxcompajaxframeonload)
1105			{
1106				setTimeout(function(){window.bxcompajaxframeonload();window.bxcompajaxframeonload=null;}, 10);
1107			}
1108		};
1109
1110		BX(container).innerHTML = d;
1111		BX.onCustomEvent('onAjaxSuccess', [null,null,callOnload]);
1112	};
1113
1114	BX.bind(obForm.BXFormTarget, 'load', BX.proxy(BX.ajax._submit_callback, obForm));
1115
1116	return true;
1117};
1118
1119// func will be executed in form context
1120BX.ajax._submit_callback = function()
1121{
1122	//opera and IE8 triggers onload event even on empty iframe
1123	try
1124	{
1125		if(this.BXFormTarget.contentWindow.location.href.indexOf('http') != 0)
1126			return;
1127	} catch (e) {
1128		return;
1129	}
1130
1131	if (this.BXFormCallback)
1132		this.BXFormCallback.apply(this, [this.BXFormTarget.contentWindow.document.body.innerHTML]);
1133
1134	BX.unbindAll(this.BXFormTarget);
1135};
1136
1137BX.ajax.prepareForm = function(obForm, data)
1138{
1139	data = (!!data ? data : {});
1140	var i, ii, el,
1141		_data = [],
1142		n = obForm.elements.length,
1143		files = 0, length = 0;
1144	if(!!obForm)
1145	{
1146		for (i = 0; i < n; i++)
1147		{
1148			el = obForm.elements[i];
1149			if (el.disabled)
1150				continue;
1151
1152			if(!el.type)
1153				continue;
1154
1155			switch(el.type.toLowerCase())
1156			{
1157				case 'text':
1158				case 'textarea':
1159				case 'password':
1160				case 'number':
1161				case 'hidden':
1162				case 'select-one':
1163					_data.push({name: el.name, value: el.value});
1164					length += (el.name.length + el.value.length);
1165					break;
1166				case 'file':
1167					if (!!el.files)
1168					{
1169						for (ii = 0; ii < el.files.length; ii++)
1170						{
1171							files++;
1172							_data.push({name: el.name, value: el.files[ii], file : true});
1173							length += el.files[ii].size;
1174						}
1175					}
1176					break;
1177				case 'radio':
1178				case 'checkbox':
1179					if(el.checked)
1180					{
1181						_data.push({name: el.name, value: el.value});
1182						length += (el.name.length + el.value.length);
1183					}
1184					break;
1185				case 'select-multiple':
1186					for (var j = 0; j < el.options.length; j++)
1187					{
1188						if (el.options[j].selected)
1189						{
1190							_data.push({name : el.name, value : el.options[j].value});
1191							length += (el.name.length + el.options[j].length);
1192						}
1193					}
1194					break;
1195				default:
1196					break;
1197			}
1198		}
1199
1200		i = 0; length = 0;
1201		var current = data, name, rest, pp, tmpKey;
1202
1203		while(i < _data.length)
1204		{
1205			var p = _data[i].name.indexOf('[');
1206			if (tmpKey)
1207			{
1208				current[_data[i].name] = {};
1209				current[_data[i].name][tmpKey.replace(/\[|\]/gi, '')] = _data[i].value;
1210				current = data;
1211				tmpKey = null;
1212				i++;
1213			}
1214			else if (p == -1)
1215			{
1216				current[_data[i].name] = _data[i].value;
1217				current = data;
1218				i++;
1219			}
1220			else
1221			{
1222				name = _data[i].name.substring(0, p);
1223				rest = _data[i].name.substring(p+1);
1224				pp = rest.indexOf(']');
1225
1226				if(pp == -1)
1227				{
1228					if (!current[name])
1229						current[name] = [];
1230					current = data;
1231					i++;
1232				}
1233				else if(pp == 0)
1234				{
1235					if (!current[name])
1236						current[name] = [];
1237					//No index specified - so take the next integer
1238					current = current[name];
1239					_data[i].name = '' + current.length;
1240					if (rest.substring(pp+1).indexOf('[') === 0)
1241						tmpKey = rest.substring(0, pp) + rest.substring(pp+1);
1242				}
1243				else
1244				{
1245					if (!current[name])
1246						current[name] = {};
1247					//Now index name becomes and name and we go deeper into the array
1248					current = current[name];
1249					_data[i].name = rest.substring(0, pp) + rest.substring(pp+1);
1250				}
1251			}
1252		}
1253	}
1254	return {data : data, filesCount : files, roughSize : length};
1255};
1256BX.ajax.submitAjax = function(obForm, config)
1257{
1258	config = (config !== null && typeof config == "object" ? config : {});
1259	config.url = (config["url"] || obForm.getAttribute("action"));
1260
1261	var additionalData = (config["data"] || {});
1262	config.data = BX.ajax.prepareForm(obForm).data;
1263	for (var ii in additionalData)
1264	{
1265		if (additionalData.hasOwnProperty(ii))
1266		{
1267			config.data[ii] = additionalData[ii];
1268		}
1269	}
1270
1271	if (!window["FormData"])
1272	{
1273		BX.ajax(config);
1274	}
1275	else
1276	{
1277		var isFile = function(item)
1278		{
1279			var res = Object.prototype.toString.call(item);
1280			return (res == '[object File]' || res == '[object Blob]');
1281		},
1282		appendToForm = function(fd, key, val)
1283		{
1284			if (!!val && typeof val == "object" && !isFile(val))
1285			{
1286				for (var ii in val)
1287				{
1288					if (val.hasOwnProperty(ii))
1289					{
1290						appendToForm(fd, (key == '' ? ii : key + '[' + ii + ']'), val[ii]);
1291					}
1292				}
1293			}
1294			else
1295				fd.append(key, (!!val ? val : ''));
1296		},
1297		prepareData = function(arData)
1298		{
1299			var data = {};
1300			if (null != arData)
1301			{
1302				if(typeof arData == 'object')
1303				{
1304					for(var i in arData)
1305					{
1306						if (arData.hasOwnProperty(i))
1307						{
1308							var name = BX.util.urlencode(i);
1309							if(typeof arData[i] == 'object' && arData[i]["file"] !== true)
1310								data[name] = prepareData(arData[i]);
1311							else if (arData[i]["file"] === true)
1312								data[name] = arData[i]["value"];
1313							else
1314								data[name] = BX.util.urlencode(arData[i]);
1315						}
1316					}
1317				}
1318				else
1319					data = BX.util.urlencode(arData);
1320			}
1321			return data;
1322		},
1323		fd = new window.FormData();
1324
1325		if (config.method !== 'POST')
1326		{
1327			config.data = BX.ajax.prepareData(config.data);
1328			if (config.data)
1329			{
1330				config.url += (config.url.indexOf('?') !== -1 ? "&" : "?") + config.data;
1331				config.data = '';
1332			}
1333		}
1334		else
1335		{
1336			if (config.preparePost === true)
1337				config.data = prepareData(config.data);
1338			appendToForm(fd, '', config.data);
1339			config.data = fd;
1340		}
1341
1342		config.preparePost = false;
1343		config.start = false;
1344
1345		var xhr = BX.ajax(config);
1346		if (!!config["onprogress"])
1347			xhr.upload.addEventListener(
1348				'progress',
1349				function(e){
1350					var percent = null;
1351					if(e.lengthComputable && (e.total || e["totalSize"])) {
1352						percent = e.loaded * 100 / (e.total || e["totalSize"]);
1353					}
1354					config["onprogress"](e, percent);
1355				}
1356			);
1357		xhr.send(fd);
1358	}
1359};
1360
1361BX.ajax.UpdatePageData = function (arData)
1362{
1363	if (arData.TITLE)
1364		BX.ajax.UpdatePageTitle(arData.TITLE);
1365	if (arData.WINDOW_TITLE || arData.TITLE)
1366		BX.ajax.UpdateWindowTitle(arData.WINDOW_TITLE || arData.TITLE);
1367	if (arData.NAV_CHAIN)
1368		BX.ajax.UpdatePageNavChain(arData.NAV_CHAIN);
1369	if (arData.CSS && arData.CSS.length > 0)
1370		BX.loadCSS(arData.CSS);
1371	if (arData.SCRIPTS && arData.SCRIPTS.length > 0)
1372	{
1373		var f = function(result,config,cb){
1374
1375			if(!!config && BX.type.isArray(config.scripts))
1376			{
1377				for(var i=0,l=arData.SCRIPTS.length;i<l;i++)
1378				{
1379					config.scripts.push({isInternal:false,JS:arData.SCRIPTS[i]});
1380				}
1381			}
1382			else
1383			{
1384				BX.loadScript(arData.SCRIPTS,cb);
1385			}
1386
1387			BX.removeCustomEvent('onAjaxSuccess',f);
1388		};
1389		BX.addCustomEvent('onAjaxSuccess',f);
1390	}
1391	else
1392	{
1393		var f1 = function(result,config,cb){
1394			if(BX.type.isFunction(cb))
1395			{
1396				cb();
1397			}
1398			BX.removeCustomEvent('onAjaxSuccess',f1);
1399		};
1400		BX.addCustomEvent('onAjaxSuccess', f1);
1401	}
1402};
1403
1404BX.ajax.UpdatePageTitle = function(title)
1405{
1406	var obTitle = BX('pagetitle');
1407	if (obTitle)
1408	{
1409		obTitle.removeChild(obTitle.firstChild);
1410		if (!obTitle.firstChild)
1411			obTitle.appendChild(document.createTextNode(title));
1412		else
1413			obTitle.insertBefore(document.createTextNode(title), obTitle.firstChild);
1414	}
1415};
1416
1417BX.ajax.UpdateWindowTitle = function(title)
1418{
1419	document.title = title;
1420};
1421
1422BX.ajax.UpdatePageNavChain = function(nav_chain)
1423{
1424	var obNavChain = BX('navigation');
1425	if (obNavChain)
1426	{
1427		obNavChain.innerHTML = nav_chain;
1428	}
1429};
1430
1431/* user options handling */
1432BX.userOptions = {
1433	options: null,
1434	bSend: false,
1435	delay: 5000,
1436	path: '/bitrix/admin/user_options.php?'
1437};
1438
1439BX.userOptions.setAjaxPath = function(url)
1440{
1441	BX.userOptions.path = url.indexOf('?') == -1? url+'?': url+'&';
1442}
1443BX.userOptions.save = function(sCategory, sName, sValName, sVal, bCommon)
1444{
1445	if (null == BX.userOptions.options)
1446		BX.userOptions.options = {};
1447
1448	bCommon = !!bCommon;
1449	BX.userOptions.options[sCategory+'.'+sName+'.'+sValName] = [sCategory, sName, sValName, sVal, bCommon];
1450
1451	var sParam = BX.userOptions.__get();
1452	if (sParam != '')
1453		document.cookie = BX.message('COOKIE_PREFIX')+"_LAST_SETTINGS=" + encodeURIComponent(sParam) + "&sessid="+BX.bitrix_sessid()+"; expires=Thu, 31 Dec 2020 23:59:59 GMT; path=/;";
1454
1455	if(!BX.userOptions.bSend)
1456	{
1457		BX.userOptions.bSend = true;
1458		setTimeout(function(){BX.userOptions.send(null)}, BX.userOptions.delay);
1459	}
1460};
1461
1462BX.userOptions.send = function(callback)
1463{
1464	var sParam = BX.userOptions.__get();
1465	BX.userOptions.options = null;
1466	BX.userOptions.bSend = false;
1467
1468	if (sParam != '')
1469	{
1470		document.cookie = BX.message('COOKIE_PREFIX') + "_LAST_SETTINGS=; path=/;";
1471		BX.ajax({
1472			'method': 'GET',
1473			'dataType': 'html',
1474			'processData': false,
1475			'cache': false,
1476			'url': BX.userOptions.path+sParam+'&sessid='+BX.bitrix_sessid(),
1477			'onsuccess': callback
1478		});
1479	}
1480};
1481
1482BX.userOptions.del = function(sCategory, sName, bCommon, callback)
1483{
1484	BX.ajax.get(BX.userOptions.path+'action=delete&c='+sCategory+'&n='+sName+(bCommon == true? '&common=Y':'')+'&sessid='+BX.bitrix_sessid(), callback);
1485};
1486
1487BX.userOptions.__get = function()
1488{
1489	if (!BX.userOptions.options) return '';
1490
1491	var sParam = '', n = -1, prevParam = '', aOpt, i;
1492
1493	for (i in BX.userOptions.options)
1494	{
1495		if(BX.userOptions.options.hasOwnProperty(i))
1496		{
1497			aOpt = BX.userOptions.options[i];
1498
1499			if (prevParam != aOpt[0]+'.'+aOpt[1])
1500			{
1501				n++;
1502				sParam += '&p['+n+'][c]='+BX.util.urlencode(aOpt[0]);
1503				sParam += '&p['+n+'][n]='+BX.util.urlencode(aOpt[1]);
1504				if (aOpt[4] == true)
1505					sParam += '&p['+n+'][d]=Y';
1506				prevParam = aOpt[0]+'.'+aOpt[1];
1507			}
1508
1509			var valueName = aOpt[2];
1510			var value = aOpt[3];
1511
1512			if (valueName === null)
1513			{
1514				sParam += '&p['+n+'][v]='+BX.util.urlencode(value);
1515			}
1516			else
1517			{
1518				sParam += '&p['+n+'][v]['+BX.util.urlencode(valueName)+']='+BX.util.urlencode(value);
1519			}
1520		}
1521	}
1522
1523	return sParam.substr(1);
1524};
1525
1526BX.ajax.history = {
1527	expected_hash: '',
1528
1529	obParams: null,
1530
1531	obFrame: null,
1532	obImage: null,
1533
1534	obTimer: null,
1535
1536	bInited: false,
1537	bHashCollision: false,
1538	bPushState: !!(history.pushState && BX.type.isFunction(history.pushState)),
1539
1540	startState: null,
1541
1542	init: function(obParams)
1543	{
1544		if (BX.ajax.history.bInited)
1545			return;
1546
1547		this.obParams = obParams;
1548		var obCurrentState = this.obParams.getState();
1549
1550		if (BX.ajax.history.bPushState)
1551		{
1552			BX.ajax.history.expected_hash = window.location.pathname;
1553			if (window.location.search)
1554				BX.ajax.history.expected_hash += window.location.search;
1555
1556			BX.ajax.history.put(obCurrentState, BX.ajax.history.expected_hash, '', true);
1557			// due to some strange thing, chrome calls popstate event on page start. so we should delay it
1558			setTimeout(function(){BX.bind(window, 'popstate', BX.ajax.history.__hashListener);}, 500);
1559		}
1560		else
1561		{
1562			BX.ajax.history.expected_hash = window.location.hash;
1563
1564			if (!BX.ajax.history.expected_hash || BX.ajax.history.expected_hash == '#')
1565				BX.ajax.history.expected_hash = '__bx_no_hash__';
1566
1567			jsAjaxHistoryContainer.put(BX.ajax.history.expected_hash, obCurrentState);
1568			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
1569
1570			if (BX.browser.IsIE())
1571			{
1572				BX.ajax.history.obFrame = document.createElement('IFRAME');
1573				BX.hide_object(BX.ajax.history.obFrame);
1574
1575				document.body.appendChild(BX.ajax.history.obFrame);
1576
1577				BX.ajax.history.obFrame.contentWindow.document.open();
1578				BX.ajax.history.obFrame.contentWindow.document.write(BX.ajax.history.expected_hash);
1579				BX.ajax.history.obFrame.contentWindow.document.close();
1580			}
1581			else if (BX.browser.IsOpera())
1582			{
1583				BX.ajax.history.obImage = document.createElement('IMG');
1584				BX.hide_object(BX.ajax.history.obImage);
1585
1586				document.body.appendChild(BX.ajax.history.obImage);
1587
1588				BX.ajax.history.obImage.setAttribute('src', 'javascript:location.href = \'javascript:BX.ajax.history.__hashListener();\';');
1589			}
1590		}
1591
1592		BX.ajax.history.bInited = true;
1593	},
1594
1595	__hashListener: function(e)
1596	{
1597		e = e || window.event || {state:false};
1598
1599		if (BX.ajax.history.bPushState)
1600		{
1601			BX.ajax.history.obParams.setState(e.state||BX.ajax.history.startState);
1602		}
1603		else
1604		{
1605			if (BX.ajax.history.obTimer)
1606			{
1607				window.clearTimeout(BX.ajax.history.obTimer);
1608				BX.ajax.history.obTimer = null;
1609			}
1610
1611			var current_hash;
1612			if (null != BX.ajax.history.obFrame)
1613				current_hash = BX.ajax.history.obFrame.contentWindow.document.body.innerText;
1614			else
1615				current_hash = window.location.hash;
1616
1617			if (!current_hash || current_hash == '#')
1618				current_hash = '__bx_no_hash__';
1619
1620			if (current_hash.indexOf('#') == 0)
1621				current_hash = current_hash.substring(1);
1622
1623			if (current_hash != BX.ajax.history.expected_hash)
1624			{
1625				var state = jsAjaxHistoryContainer.get(current_hash);
1626				if (state)
1627				{
1628					BX.ajax.history.obParams.setState(state);
1629
1630					BX.ajax.history.expected_hash = current_hash;
1631					if (null != BX.ajax.history.obFrame)
1632					{
1633						var __hash = current_hash == '__bx_no_hash__' ? '' : current_hash;
1634						if (window.location.hash != __hash && window.location.hash != '#' + __hash)
1635							window.location.hash = __hash;
1636					}
1637				}
1638			}
1639
1640			BX.ajax.history.obTimer = setTimeout(BX.ajax.history.__hashListener, 500);
1641		}
1642	},
1643
1644	put: function(state, new_hash, new_hash1, bStartState)
1645	{
1646		if (this.bPushState)
1647		{
1648			if(!bStartState)
1649			{
1650				history.pushState(state, '', new_hash);
1651			}
1652			else
1653			{
1654				BX.ajax.history.startState = state;
1655			}
1656		}
1657		else
1658		{
1659			if (typeof new_hash1 != 'undefined')
1660				new_hash = new_hash1;
1661			else
1662				new_hash = 'view' + new_hash;
1663
1664			jsAjaxHistoryContainer.put(new_hash, state);
1665			BX.ajax.history.expected_hash = new_hash;
1666
1667			window.location.hash = BX.util.urlencode(new_hash);
1668
1669			if (null != BX.ajax.history.obFrame)
1670			{
1671				BX.ajax.history.obFrame.contentWindow.document.open();
1672				BX.ajax.history.obFrame.contentWindow.document.write(new_hash);
1673				BX.ajax.history.obFrame.contentWindow.document.close();
1674			}
1675		}
1676	},
1677
1678	checkRedirectStart: function(param_name, param_value)
1679	{
1680		var current_hash = window.location.hash;
1681		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
1682
1683		var test = current_hash.substring(0, 5);
1684		if (test == 'view/' || test == 'view%')
1685		{
1686			BX.ajax.history.bHashCollision = true;
1687			document.write('<' + 'div id="__ajax_hash_collision_' + param_value + '" style="display: none;">');
1688		}
1689	},
1690
1691	checkRedirectFinish: function(param_name, param_value)
1692	{
1693		document.write('</div>');
1694
1695		var current_hash = window.location.hash;
1696		if (current_hash.substring(0, 1) == '#') current_hash = current_hash.substring(1);
1697
1698		BX.ready(function ()
1699		{
1700			var test = current_hash.substring(0, 5);
1701			if (test == 'view/' || test == 'view%')
1702			{
1703				var obColNode = BX('__ajax_hash_collision_' + param_value);
1704				var obNode = obColNode.firstChild;
1705				BX.cleanNode(obNode);
1706				obColNode.style.display = 'block';
1707
1708				// IE, Opera and Chrome automatically modifies hash with urlencode, but FF doesn't ;-(
1709				if (test != 'view%')
1710					current_hash = BX.util.urlencode(current_hash);
1711
1712				current_hash += (current_hash.indexOf('%3F') == -1 ? '%3F' : '%26') + param_name + '=' + param_value;
1713
1714				var url = '/bitrix/tools/ajax_redirector.php?hash=' + current_hash;
1715
1716				BX.ajax.insertToNode(url, obNode);
1717			}
1718		});
1719	}
1720};
1721
1722BX.ajax.component = function(node)
1723{
1724	this.node = node;
1725};
1726
1727BX.ajax.component.prototype.getState = function()
1728{
1729	var state = {
1730		'node': this.node,
1731		'title': window.document.title,
1732		'data': BX(this.node).innerHTML
1733	};
1734
1735	var obNavChain = BX('navigation');
1736	if (null != obNavChain)
1737		state.nav_chain = obNavChain.innerHTML;
1738
1739	BX.onCustomEvent(BX(state.node), "onComponentAjaxHistoryGetState", [state]);
1740
1741	return state;
1742};
1743
1744BX.ajax.component.prototype.setState = function(state)
1745{
1746	BX(state.node).innerHTML = state.data;
1747	BX.ajax.UpdatePageTitle(state.title);
1748
1749	if (state.nav_chain)
1750	{
1751		BX.ajax.UpdatePageNavChain(state.nav_chain);
1752	}
1753
1754	BX.onCustomEvent(BX(state.node), "onComponentAjaxHistorySetState", [state]);
1755};
1756
1757var jsAjaxHistoryContainer = {
1758	arHistory: {},
1759
1760	put: function(hash, state)
1761	{
1762		this.arHistory[hash] = state;
1763	},
1764
1765	get: function(hash)
1766	{
1767		return this.arHistory[hash];
1768	}
1769};
1770
1771
1772BX.ajax.FormData = function()
1773{
1774	this.elements = [];
1775	this.files = [];
1776	this.features = {};
1777	this.isSupported();
1778	this.log('BX FormData init');
1779};
1780
1781BX.ajax.FormData.isSupported = function()
1782{
1783	var f = new BX.ajax.FormData();
1784	var result = f.features.supported;
1785	f = null;
1786	return result;
1787};
1788
1789BX.ajax.FormData.prototype.log = function(o)
1790{
1791	if (false) {
1792		try {
1793			if (BX.browser.IsIE()) o = JSON.stringify(o);
1794			console.log(o);
1795		} catch(e) {}
1796	}
1797};
1798
1799BX.ajax.FormData.prototype.isSupported = function()
1800{
1801	var f = {};
1802	f.fileReader = (window.FileReader && window.FileReader.prototype.readAsBinaryString);
1803	f.readFormData = f.sendFormData = !!(window.FormData);
1804	f.supported = !!(f.readFormData && f.sendFormData);
1805	this.features = f;
1806	this.log('features:');
1807	this.log(f);
1808
1809	return f.supported;
1810};
1811
1812BX.ajax.FormData.prototype.append = function(name, value)
1813{
1814	if (typeof(value) === 'object') { // seems to be files element
1815		this.files.push({'name': name, 'value':value});
1816	} else {
1817		this.elements.push({'name': name, 'value':value});
1818	}
1819};
1820
1821BX.ajax.FormData.prototype.send = function(url, callbackOk, callbackProgress, callbackError)
1822{
1823	this.log('FD send');
1824	this.xhr = BX.ajax({
1825			'method': 'POST',
1826			'dataType': 'html',
1827			'url': url,
1828			'onsuccess': callbackOk,
1829			'onfailure': callbackError,
1830			'start': false,
1831			'preparePost':false
1832		});
1833
1834	if (callbackProgress)
1835	{
1836		this.xhr.upload.addEventListener(
1837			'progress',
1838			function(e) {
1839				if (e.lengthComputable)
1840					callbackProgress(e.loaded / (e.total || e.totalSize));
1841			},
1842			false
1843		);
1844	}
1845
1846	if (this.features.readFormData && this.features.sendFormData)
1847	{
1848		var fd = new FormData();
1849		this.log('use browser formdata');
1850		for (var i in this.elements)
1851		{
1852			if(this.elements.hasOwnProperty(i))
1853				fd.append(this.elements[i].name,this.elements[i].value);
1854		}
1855		for (i in this.files)
1856		{
1857			if(this.files.hasOwnProperty(i))
1858				fd.append(this.files[i].name, this.files[i].value);
1859		}
1860		this.xhr.send(fd);
1861	}
1862
1863	return this.xhr;
1864};
1865
1866BX.addCustomEvent('onAjaxFailure', BX.debug);
1867})(window);
1868

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.