PageSourceSearch

http://aptekaiskitim.ru/bitrix/js/main/core/core_ajax.js

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