PageSourceSearch

https://www.mts.by/bitrix/js/main/core/core_frame_cache.js?175377761416945

js mts.by collected 2026-09-24 08:48:53 UTC 16,945 bytes, 806 lines download raw bytes

1(function (window)
2{
3	if (window.BX.frameCache) return;
4
5	var BX = window.BX;
6	var localStorageKey = "compositeCache";
7	var lolalStorageTTL = 1440;
8	var compositeMessageIds = ["bitrix_sessid", "USER_ID", "SERVER_TIME", "USER_TZ_OFFSET", "USER_TZ_AUTO"];
9	var compositeDataFile = "/bitrix/tools/composite_data.php";
10	var sessidWasUpdated = false;
11
12	BX.frameCache = function()
13	{
14	};
15
16	if (typeof(localStorage) !== "undefined")
17	{
18		BX.frameCache.localStorage = new BX.localStorage();
19	}
20	else
21	{
22		BX.frameCache.localStorage = {
23			set : BX.DoNothing,
24			get : function() { return null; },
25			remove : BX.DoNothing
26		};
27	}
28
29	BX.frameCache.localStorage.prefix = function()
30	{
31		return "bx-";
32	};
33
34	BX.frameCache.init = function()
35	{
36		this.cacheDataBase = null;
37		this.tableParams =
38		{
39			tableName: "composite",
40			fields: [
41				{name: "id", unique: true},
42				"content",
43				"hash",
44				"props"
45			]
46		};
47
48		this.frameDataReceived = false;
49		this.frameDataInserted = false;
50
51		if (BX.type.isString(window.frameDataString) && window.frameDataString.length > 0)
52		{
53			BX.frameCache.onFrameDataReceived(window.frameDataString);
54		}
55
56		this.vars = window.frameCacheVars ? window.frameCacheVars : {
57			dynamicBlocks: {},
58			page_url: "",
59			params: {},
60			storageBlocks: []
61		};
62
63		//local storage warming up
64		var lsCache = BX.frameCache.localStorage.get(localStorageKey) || {};
65		for (var i = 0; i < compositeMessageIds.length; i++)
66		{
67			var messageId = compositeMessageIds[i];
68			if (typeof(BX.message[messageId]) != "undefined")
69			{
70				lsCache[messageId] = BX.message[messageId];
71			}
72		}
73		BX.frameCache.localStorage.set(localStorageKey, lsCache, lolalStorageTTL);
74
75		BX.addCustomEvent("onBXMessageNotFound", function(mess)
76		{
77			if (BX.util.in_array(mess, compositeMessageIds))
78			{
79				var cache = BX.frameCache.localStorage.get(localStorageKey);
80				if (cache && typeof(cache[mess]) != "undefined")
81				{
82					BX.message[mess] = cache[mess];
83				}
84				else
85				{
86					BX.frameCache.getCompositeMessages();
87				}
88			}
89		});
90
91		if (!window.frameUpdateInvoked)
92		{
93			this.update(false);
94			window.frameUpdateInvoked = true;
95		}
96
97		if (window.frameRequestStart)
98		{
99			BX.ready(function() {
100				BX.onCustomEvent("onCacheDataRequestStart");
101				BX.frameCache.tryUpdateSessid();
102			});
103		}
104
105		if (window.frameRequestFail)
106		{
107			BX.ready(function() {
108				setTimeout(function() {
109					BX.onCustomEvent("onFrameDataRequestFail", [window.frameRequestFail]);
110				}, 0);
111			});
112		}
113
114		BX.frameCache.insertBanner();
115	};
116
117	BX.frameCache.getCompositeMessages = function()
118	{
119		try {
120			BX.ajax({
121				method: "GET",
122				dataType: "json",
123				url: compositeDataFile,
124				async : false,
125				data:  '',
126				onsuccess: function(json)
127				{
128					BX.frameCache.setCompositeVars(json);
129				}
130			});
131		}
132		catch (exeption)
133		{
134			BX.debug("Composite sync request failed.");
135		}
136	};
137
138	BX.frameCache.setCompositeVars = function(vars)
139	{
140		if (!vars)
141		{
142			return;
143		}
144		else if (vars.lang)
145		{
146			vars = vars.lang;
147		}
148
149		var lsCache = BX.frameCache.localStorage.get(localStorageKey) || {};
150		for (var name in vars)
151		{
152			if (vars.hasOwnProperty(name))
153			{
154				BX.message[name] = vars[name];
155
156				if (BX.util.in_array(name, compositeMessageIds))
157				{
158					lsCache[name] = vars[name];
159				}
160			}
161		}
162
163		BX.frameCache.localStorage.set(localStorageKey, lsCache, lolalStorageTTL);
164	};
165
166	BX.frameCache.insertBlock = function(block, callback)
167	{
168		if (!BX.type.isFunction(callback))
169		{
170			callback = function() {};
171		}
172
173		if (!block)
174		{
175			callback();
176			return;
177		}
178
179		var container = null;
180		var dynamicStart = null;
181		var dynamicEnd = null;
182
183		var autoContainerPrefix = "bxdynamic_";
184		if (block.ID.substr(0, autoContainerPrefix.length) === autoContainerPrefix)
185		{
186			dynamicStart = BX(block.ID + "_start");
187			dynamicEnd = BX(block.ID + "_end");
188			if (!dynamicStart || !dynamicEnd)
189			{
190				BX.debug("Dynamic area " + block.ID + " was not found");
191				callback();
192				return;
193			}
194		}
195		else
196		{
197			container = BX(block.ID);
198			if (!container)
199			{
200				BX.debug("Container " + block.ID + " was not found");
201				callback();
202				return;
203			}
204		}
205
206		let htmlWasInserted = false;
207		let scriptsLoaded = false;
208		const assets = getAssets();
209
210		processStrings();
211		processAssets(() => {
212			scriptsLoaded = true;
213			insertHTML();
214		});
215
216		function processAssets(callback)
217		{
218			let styles = assets.styles;
219			if (BX.type.isArray(block.PROPS.CSS) && block.PROPS.CSS.length > 0)
220			{
221				styles = block.PROPS.CSS.concat(styles);
222			}
223
224			let scripts = assets.externalJS;
225			if (BX.type.isArray(block.PROPS.JS) && block.PROPS.JS.length > 0)
226			{
227				scripts = scripts.concat(block.PROPS.JS);
228			}
229
230			const items = styles.concat(scripts);
231			if (items.length > 0)
232			{
233				BX.load(items, callback);
234			}
235			else
236			{
237				callback();
238			}
239		}
240
241		function insertHTML()
242		{
243			if (container)
244			{
245				if (block.PROPS.USE_ANIMATION)
246				{
247					container.style.opacity = 0;
248					container.innerHTML = block.CONTENT;
249					(new BX.easing({
250						duration : 1500,
251						start : { opacity: 0 },
252						finish : { opacity: 100 },
253						transition : BX.easing.makeEaseOut(BX.easing.transitions.quart),
254						step : function(state){
255							container.style.opacity = state.opacity / 100;
256						},
257						complete : function() {
258							container.style.cssText = '';
259						}
260					})).animate();
261				}
262				else
263				{
264					container.innerHTML = block.CONTENT;
265				}
266			}
267			else
268			{
269				BX.frameCache.removeNodes(dynamicStart, dynamicEnd);
270				dynamicStart.insertAdjacentHTML("afterEnd", block.CONTENT);
271			}
272
273			htmlWasInserted = true;
274			if (scriptsLoaded)
275			{
276				processInlineJS();
277			}
278		}
279
280		function processStrings()
281		{
282			if (BX.Type.isStringFilled(assets.html))
283			{
284				document.head.insertAdjacentHTML("beforeend", assets.html);
285			}
286
287			BX.evalGlobal(assets.inlineJS.join(";"));
288		}
289
290		function getAssets()
291		{
292			var result = { styles: [], inlineJS: [], externalJS: [], html: "" };
293			if (!BX.type.isArray(block.PROPS.STRINGS) || block.PROPS.STRINGS.length < 1)
294			{
295				return result;
296			}
297
298			var parts = BX.processHTML(block.PROPS.STRINGS.join(""), false);
299			for (var i = 0, l = parts.SCRIPT.length; i < l; i++)
300			{
301				var script = parts.SCRIPT[i];
302				if (script.isInternal)
303				{
304					result.inlineJS.push(script.JS);
305				}
306				else
307				{
308					result.externalJS.push(script.JS);
309				}
310			}
311
312			result.styles = parts.STYLE;
313			result.html = parts.HTML;
314
315			return result;
316		}
317
318		function processInlineJS()
319		{
320			scriptsLoaded = true;
321			if (htmlWasInserted)
322			{
323				BX.ajax.processRequestData(block.CONTENT, {scriptsRunFirst: false, dataType: "HTML"});
324
325				if (BX.type.isArray(block.PROPS.BUNDLE_JS))
326				{
327					BX.setJSList(block.PROPS.BUNDLE_JS);
328				}
329
330				if (BX.type.isArray(block.PROPS.BUNDLE_CSS))
331				{
332					BX.setCSSList(block.PROPS.BUNDLE_CSS);
333				}
334
335				callback();
336			}
337		}
338	};
339
340	BX.frameCache.removeNodes = function(fromElement, toElement)
341	{
342		var startFound = false;
343		var parent = fromElement.parentNode;
344		var nodes = Array.prototype.slice.call(parent.childNodes);
345		for (var i = 0, length = nodes.length; i < length; i++)
346		{
347			if (startFound)
348			{
349				if (nodes[i] === toElement)
350				{
351					break;
352				}
353				else
354				{
355					parent.removeChild(nodes[i]);
356				}
357			}
358			else if (nodes[i] === fromElement)
359			{
360				startFound = true;
361			}
362		}
363	};
364
365	BX.frameCache.update = function(makeRequest, noInvoke)
366	{
367		noInvoke = !!noInvoke;
368		makeRequest = typeof(makeRequest) == "undefined" ? true : makeRequest;
369		if (makeRequest)
370		{
371			this.requestData();
372		}
373
374		if (!noInvoke)
375		{
376			BX.ready(BX.proxy(function() {
377				if (!this.frameDataReceived)
378				{
379					this.invokeCache();
380				}
381			}, this));
382		}
383	};
384
385	BX.frameCache.invokeCache = function()
386	{
387		//getting caching dynamic blocks
388		if (this.vars.storageBlocks && this.vars.storageBlocks.length > 0)
389		{
390			BX.onCustomEvent(this, "onCacheInvokeBefore", [this.vars.storageBlocks]);
391			this.readCacheWithID(this.vars.storageBlocks, BX.proxy(this.insertFromCache, this));
392		}
393	};
394
395	BX.frameCache.handleResponse = function(json)
396	{
397		if (json == null)
398			return;
399
400		BX.onCustomEvent("onFrameDataReceivedBefore", [json]);
401
402		if (json.dynamicBlocks && json.dynamicBlocks.length > 0)//we have dynamic blocks
403		{
404			this.insertBlocks(json.dynamicBlocks, false);
405			this.writeCache(json.dynamicBlocks);
406		}
407
408		BX.onCustomEvent("onFrameDataReceived", [json]);
409
410		if (
411			json.isManifestUpdated == "1"
412			&& this.vars.CACHE_MODE === "APPCACHE"
413			&& window.applicationCache
414			&& (
415				window.applicationCache.status == window.applicationCache.IDLE
416				|| window.applicationCache.status == window.applicationCache.UPDATEREADY
417			)
418		) //the manifest has been changed
419		{
420			window.applicationCache.update();
421		}
422
423		if (json.htmlCacheChanged === true && this.vars.CACHE_MODE === "HTMLCACHE")
424		{
425			BX.onCustomEvent("onHtmlCacheChanged", [json]);
426		}
427
428		if (BX.type.isArray(json.spread))
429		{
430			for (var i = 0; i < json.spread.length; i++)
431			{
432				new Image().src = json.spread[i];
433			}
434		}
435
436	};
437
438	BX.frameCache.requestData = function()
439	{
440		var headers = [
441			{ name: "BX-ACTION-TYPE", value: "get_dynamic" },
442			{ name: "BX-REF", value: document.referrer },
443			{ name: "BX-CACHE-MODE", value: this.vars.CACHE_MODE },
444			{ name: "BX-CACHE-BLOCKS", value: this.vars.dynamicBlocks ? JSON.stringify(this.vars.dynamicBlocks) : "" }
445		];
446
447		if (this.vars.AUTO_UPDATE === false && this.vars.AUTO_UPDATE_TTL && this.vars.AUTO_UPDATE_TTL > 0)
448		{
449			var lastModified = Date.parse(document.lastModified);
450			if (!isNaN(lastModified))
451			{
452				var now = new Date().getTime();
453				if ((lastModified + this.vars.AUTO_UPDATE_TTL * 1000) < now)
454				{
455					headers.push({ name: "BX-INVALIDATE-CACHE", value: "Y" });
456				}
457			}
458		}
459
460		if (this.vars.CACHE_MODE === "APPCACHE")
461		{
462			headers.push({ name: "BX-APPCACHE-PARAMS", value: JSON.stringify(this.vars.PARAMS) });
463			headers.push({ name: "BX-APPCACHE-URL", value: this.vars.PAGE_URL ? this.vars.PAGE_URL : "" });
464		}
465
466		BX.onCustomEvent("onCacheDataRequestStart");
467
468		var requestURI = window.location.href;
469		var index = requestURI.indexOf("#");
470		if (index > 0)
471		{
472			requestURI = requestURI.substring(0, index);
473		}
474		requestURI += (requestURI.indexOf("?") >= 0 ? "&" : "?") + "bxrand=" + new Date().getTime();
475
476		BX.ajax({
477			timeout: 60,
478			method: "GET",
479			url: requestURI,
480			data: {},
481			headers: headers,
482			skipBxHeader : true,
483			processData: false,
484			onsuccess: BX.proxy(BX.frameCache.onFrameDataReceived, this),
485			onfailure: function()
486			{
487				window.frameRequestFail = {
488					error: true,
489					reason: "bad_response",
490					url : requestURI,
491					xhr: this.xhr,
492					status: this.xhr ? this.xhr.status : 0
493				};
494
495				BX.onCustomEvent("onFrameDataRequestFail", [window.frameRequestFail]);
496			}
497		});
498	};
499
500	BX.frameCache.onFrameDataReceived = function(response)
501	{
502		var result = null;
503		try
504		{
505			result = JSON.parse(response);
506		}
507		catch (e)
508		{
509			var error = {
510				error: true,
511				reason: "bad_eval",
512				response: response
513			};
514
515			window.frameRequestFail = error;
516
517			BX.ready(function() {
518				setTimeout(function() {
519					BX.onCustomEvent("onFrameDataRequestFail", [error]);
520				}, 0);
521			});
522
523			return;
524		}
525
526		this.frameDataReceived = true;
527
528		if (result && BX.type.isNotEmptyString(result.redirect_url))
529		{
530			window.location = result.redirect_url;
531			return;
532		}
533
534		if (result && result.error === true)
535		{
536			window.frameRequestFail = result;
537
538			BX.ready(BX.proxy(function() {
539				setTimeout(BX.proxy(function() {
540					BX.onCustomEvent("onFrameDataRequestFail", [result]);
541				}, this), 0);
542			}, this));
543
544			return;
545		}
546
547		BX.frameCache.setCompositeVars(result);
548		BX.ready(BX.proxy(function() {
549			this.handleResponse(result);
550			this.tryUpdateSessid();
551		}, this));
552	};
553
554	BX.frameCache.insertFromCache = function(resultSet, transaction)
555	{
556		if (!this.frameDataReceived)
557		{
558			var items = resultSet.items;
559			if (items.length > 0)
560			{
561				for (var i = 0; i < items.length; i++)
562				{
563					items[i].PROPS = JSON.parse(items[i].PROPS);
564				}
565
566				this.insertBlocks(items, true);
567			}
568
569			BX.onCustomEvent(this, "onCacheInvokeAfter", [this.vars.storageBlocks, resultSet]);
570		}
571	};
572
573	BX.frameCache.insertBlocks = function(blocks, fromCache)
574	{
575		var blocksToInsert = new Set();
576		for (var i = 0; i < blocks.length; i++)
577		{
578			var block = blocks[i];
579			BX.onCustomEvent("onBeforeDynamicBlockUpdate", [block, fromCache]);
580
581			if (block.PROPS.AUTO_UPDATE === false)
582			{
583				continue;
584			}
585
586			blocksToInsert.add(block);
587		}
588
589		let inserted = 0;
590
591		const finalize = () => {
592			if (window.performance)
593			{
594				var entries = performance.getEntries();
595				for (var i = 0; i < entries.length; i++)
596				{
597					var entry = entries[i];
598					if (entry.initiatorType === 'xmlhttprequest' && entry.name && entry.name.match(/bxrand=[0-9]+/))
599					{
600						// uses in ba.js
601						this.requestTiming = entry;
602					}
603				}
604
605				if (window.performance.measure)
606				{
607					window.performance.measure('Composite:LCP');
608
609					var lcpEntries = performance.getEntriesByName('Composite:LCP');
610					if (lcpEntries.length > 0 && lcpEntries[0].duration)
611					{
612						// uses in ba.js
613						this.lcp = Math.ceil(lcpEntries[0].duration);
614					}
615				}
616			}
617
618			BX.onCustomEvent("onFrameDataProcessed", [blocks, fromCache]);
619			this.frameDataInserted = true;
620		};
621
622		const handleBlockInsertion = () => {
623			if (++inserted === blocksToInsert.size)
624			{
625				finalize();
626			}
627		};
628
629		if (blocksToInsert.size === 0)
630		{
631			finalize();
632		}
633		else
634		{
635			blocksToInsert.forEach(function(block) {
636
637				if (block && block.HASH && block.PROPS && block.PROPS.ID)
638				{
639					this.vars.dynamicBlocks[block.PROPS.ID] = block.HASH;
640				}
641
642				this.insertBlock(block, handleBlockInsertion);
643			}, this);
644		}
645	};
646
647	BX.frameCache.writeCache = function(blocks)
648	{
649		for (var i = 0; i < blocks.length; i++)
650		{
651			if (blocks[i].PROPS.USE_BROWSER_STORAGE === true)
652			{
653				this.writeCacheWithID(
654					blocks[i].ID,
655					blocks[i].CONTENT,
656					blocks[i].HASH,
657					JSON.stringify(blocks[i].PROPS)
658				);
659			}
660		}
661	};
662
663	BX.frameCache.openDatabase = function()
664	{
665		var isDatabaseOpened = (this.cacheDataBase != null);
666
667		if(!isDatabaseOpened)
668		{
669			this.cacheDataBase = new BX.Dexie("composite");
670			if(this.cacheDataBase != null)
671			{
672				this.cacheDataBase.version(1).stores({
673					composite: '&ID,CONTENT,HASH,PROPS'
674				});
675				isDatabaseOpened = true;
676			}
677		}
678
679		return isDatabaseOpened;
680	};
681
682	BX.frameCache.writeCacheWithID = function(id, content, hash, props)
683	{
684		if(BX.frameCache.openDatabase())
685		{
686			if (typeof props == "object")
687			{
688				props = JSON.stringify(props);
689			}
690
691			this.cacheDataBase.composite.put({
692				ID: id,
693				CONTENT: content,
694				HASH: hash,
695				PROPS : props
696			});
697		}
698	};
699
700	BX.frameCache.readCacheWithID = function(id, callback)
701	{
702		if(BX.frameCache.openDatabase())
703		{
704			this.cacheDataBase.composite
705				.where("ID").anyOf(id).toArray()
706				.then((function(items){
707					callback({items:items});
708				}).bind(this));
709		}
710		else if(typeof callback != "undefined")
711		{
712			callback({items:[]});
713		}
714	};
715
716	BX.frameCache.insertBanner = function()
717	{
718		if (!this.vars.banner || !BX.type.isNotEmptyString(this.vars.banner.text))
719		{
720			return;
721		}
722
723		BX.ready(BX.proxy(function() {
724			var banner = BX.create("a", {
725				props : {
726					className : "bx-composite-btn" + (
727						BX.type.isNotEmptyString(this.vars.banner.style) ?
728						" bx-btn-" + this.vars.banner.style :
729						""
730					),
731					href : this.vars.banner.url
732				},
733				attrs : {
734					target : "_blank"
735				},
736				text : this.vars.banner.text
737			});
738
739			if (BX.type.isNotEmptyString(this.vars.banner.bgcolor))
740			{
741				banner.style.backgroundColor = this.vars.banner.bgcolor;
742				if (BX.util.in_array(this.vars.banner.bgcolor.toUpperCase(), ["#FFF", "#FFFFFF", "WHITE"]))
743				{
744					BX.addClass(banner, "bx-btn-border");
745				}
746			}
747
748			var container = BX("bx-composite-banner");
749			if (container)
750			{
751				container.appendChild(banner);
752			}
753			else
754			{
755				BX.addClass(banner, "bx-composite-btn-fixed");
756				document.body.appendChild(BX.create("div", {
757					style : { position: "relative" },
758					children: [ banner ]
759				}));
760			}
761		}, this));
762	};
763
764	BX.frameCache.tryUpdateSessid = function()
765	{
766		if (sessidWasUpdated)
767		{
768			return;
769		}
770
771		var name = "bitrix_sessid";
772		var sessid = false;
773
774		if (typeof(BX.message[name]) != "undefined")
775		{
776			sessid = BX.message[name];
777		}
778		else
779		{
780			var cache = BX.frameCache.localStorage.get(localStorageKey) || {};
781			if (typeof(cache[name]) != "undefined")
782			{
783				sessid = cache[name];
784			}
785		}
786
787		if (sessid !== false)
788		{
789			sessidWasUpdated = true;
790			this.updateSessid(sessid);
791		}
792	};
793
794	BX.frameCache.updateSessid = function(sessid)
795	{
796		var inputs = document.getElementsByName("sessid");
797		for (var i = 0; i < inputs.length; i++)
798		{
799			inputs[i].value = sessid;
800		}
801	};
802
803	//initialize
804	BX.frameCache.init();
805
806})(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.