PageSourceSearch

https://newseoul.ru/bitrix/js/main/core/core_frame_cache.js?161772046316871

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

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.