PageSourceSearch

https://studio-lebel.com/g/s3/lp/lpc.v4/js/lpc-styling.js

js studio-lebel.com collected 2026-10-08 17:24:29 UTC 11,933 bytes, 529 lines download raw bytes

1document.addEventListener("DOMContentLoaded", () => {
2	let lpContent = document.getElementById("lp_constructor");
3	let iframeBody = document;
4	let iframeWindow = window;
5	let timeout = 20;
6
7	if (lpContent) {
8		timeout = 4000;
9	}
10
11	setTimeout(() => {
12		if (lpContent) {
13			let iframe = document.querySelector("#lpc_contructor_iframe");
14
15			if (iframe) {
16				iframeBody = iframe.contentDocument.body;
17				iframeWindow = iframe.contentWindow;
18			}
19		}
20
21		const detectedTagId = {
22			h1: "lpc-config-h1",
23			h2: "lpc-config-h2",
24			h3: "lpc-config-h3",
25			h4: "lpc-config-h4",
26			h5: "lpc-config-h5",
27			h6: "lpc-config-h6",
28			p: "lpc-config-p",
29			button: "lpc-config-button",
30			h: "lpc-config-h2-main",
31			text: "lpc-config-p-main"
32		};
33
34		const configBlockId = "lpc-config-block";
35
36		const configBlock = `
37			<div id="${configBlockId}" style="display: none">
38			<h1 id="${detectedTagId.h1}"></h1>
39			<h2 id="${detectedTagId.h2}"></h2>
40			<h3 id="${detectedTagId.h3}"></h3>
41			<h4 id="${detectedTagId.h4}"></h4>
42			<h5 id="${detectedTagId.h5}"></h5>
43			<h6 id="${detectedTagId.h6}"></h6>
44			<p id="${detectedTagId.p}"></p>
45			<p id="${detectedTagId.button}"></p>
46			<p id="${detectedTagId.text}"></p>
47			<h2 id="${detectedTagId.h}"></h2>
48			</div>
49		`;
50
51		let root;
52
53		const contentWrapper = iframeBody.querySelector(".lpc-content-wrapper");
54		let content = contentWrapper
55			? contentWrapper.parentElement
56			: undefined;
57
58		try {
59			root = iframeBody.querySelector(".mosaic-wrap >.root");
60		} catch (error) {
61			console.log(error.message);
62		}
63
64		if (content) {
65			let lpcStyleConfig = {};
66
67			const findBackgroundStyles = (content) => {
68				const convertRgbToRgba = (color) => {
69					if (color.startsWith("rgb(")) {
70						return color.replace("rgb(", "rgba(").replace(")", ", 1)");
71					}
72
73					return color;
74				};
75
76				const isColorOpaque = (color) => {
77					const rgbaColor = convertRgbToRgba(color);
78					return parseFloat(rgbaColor.split(",")[3]) > 0;
79				};
80
81				const getBackgroundColor = (color) => {
82					return isColorOpaque(color)
83						? convertRgbToRgba(color)
84						: null;
85				};
86
87				const resultStyles = [];
88
89				const currentElement = content;
90				let parent = currentElement;
91
92				while (parent && parent.tagName !== "HTML") {
93					const computedStyle = getComputedStyle(parent);
94					const currentBackground = computedStyle.backgroundColor;
95					const currentBackgroundImage = computedStyle.backgroundImage;
96					let currentBackgroundGradient = currentBackgroundImage;
97
98					if (
99						currentBackgroundImage &&
100						currentBackgroundImage.includes("gradient")
101					) {
102						const imageUrlRegex = /url\("([^"]+)"\)/g;
103						const imageUrlMatches =
104							currentBackgroundImage.match(imageUrlRegex);
105
106						if (imageUrlMatches) {
107							for (const imageUrlMatch of imageUrlMatches) {
108								currentBackgroundGradient =
109									currentBackgroundGradient.replace(
110										imageUrlMatch,
111										"none"
112									);
113							}
114						}
115
116						resultStyles.push(currentBackgroundGradient);
117					}
118
119					if (!currentBackgroundImage.includes("linear-gradient")) {
120						const bgColor = getBackgroundColor(currentBackground);
121
122						if (bgColor) {
123							resultStyles.push(
124								`linear-gradient(to right, ${bgColor} 0%, ${bgColor} 100%)`
125							);
126						}
127					}
128
129					parent = parent.parentNode;
130				}
131
132				return resultStyles;
133			};
134
135			const getElementStyles = (elementId, styles) => {
136				let element;
137
138				if (elementId === detectedTagId.h1 && root) {
139					element = iframeBody.querySelector(".page-title");
140
141					if (!element) {
142						element = iframeBody.querySelector(
143							`#${detectedTagId.h2}`
144						);
145					}
146				} else {
147					element = iframeBody.querySelector(`#${elementId}`);
148				}
149
150				if (element) {
151					const object = {};
152					const cssObj = iframeWindow.getComputedStyle(
153						element,
154						null
155					);
156
157					styles.forEach((style) => {
158						object[style] =
159							cssObj.getPropertyValue(style) + ";";
160					});
161
162					lpcStyleConfig[elementId] = object;
163				}
164			};
165
166			const extractRGB = (color) => {
167				const regex = /^rgba?\((\d+),\s*(\d+),\s*(\d+)/;
168				let match = regex.exec(color);
169
170				return [match[1], match[2], match[3]];
171			};
172
173			const checkFontFamily = (fontFamily) => {
174				fontFamily = fontFamily
175					.replace(/'/g, "")
176					.replace(/"/g, "");
177
178				try {
179					if (!document.fonts.check(`12px ${fontFamily}`)) {
180						const link = document.createElement("link");
181
182						link.href =
183							`https://fonts.googleapis.com/css2?family=${fontFamily}`;
184
185						link.rel = "stylesheet";
186
187						document.head.appendChild(link);
188					}
189				} catch (error) {
190					console.log(error.message);
191				}
192			};
193
194			const createCssVariable = (headerColor, textColor) => {
195				let textColorBase = extractRGB(textColor);
196
197				return `
198          :root {
199              --text-color-base: rgb(${textColorBase});
200              --text-color-a-005: rgba(${textColorBase}, 0.05);
201              --text-color-a-01: rgba(${textColorBase}, 0.1);
202              --text-color-a-02: rgba(${textColorBase}, 0.2);
203              --text-color-a-03: rgba(${textColorBase}, 0.3);
204              --text-color-a-04: rgba(${textColorBase}, 0.4);
205              --text-color-a-05: rgba(${textColorBase}, 0.5);
206              --text-color-a-06: rgba(${textColorBase}, 0.6);
207              --text-color-a-07: rgba(${textColorBase}, 0.7);
208              --text-color-a-08: rgba(${textColorBase}, 0.8);
209              --text-color-a-09: rgba(${textColorBase}, 0.9);
210              --text-color-base-header: ${headerColor};
211          }
212        `;
213			};
214
215			const getAllStyles = () => {
216				const styleAttributes = [
217					{
218						tagId: detectedTagId.h1,
219						properties: [
220							"font-family",
221							"font-style",
222							"font-weight"
223						]
224					},
225					{
226						tagId: detectedTagId.h2,
227						properties: [
228							"font-family",
229							"font-style",
230							"font-weight"
231						]
232					},
233					{
234						tagId: detectedTagId.h3,
235						properties: [
236							"font-family",
237							"font-style",
238							"font-weight"
239						]
240					},
241					{
242						tagId: detectedTagId.h4,
243						properties: [
244							"font-family",
245							"font-style",
246							"font-weight"
247						]
248					},
249					{
250						tagId: detectedTagId.h5,
251						properties: [
252							"font-family",
253							"font-style",
254							"font-weight"
255						]
256					},
257					{
258						tagId: detectedTagId.h6,
259						properties: [
260							"font-family",
261							"font-style",
262							"font-weight"
263						]
264					},
265					{
266						tagId: detectedTagId.p,
267						properties: [
268							"font-family",
269							"font-style",
270							"font-weight"
271						]
272					},
273					{
274						tagId: detectedTagId.button,
275						properties: [
276							"font-family",
277							"font-style"
278						]
279					},
280					{
281						tagId: detectedTagId.text,
282						properties: [
283							"color",
284							"font-family"
285						]
286					},
287					{
288						tagId: detectedTagId.h,
289						properties: [
290							"color",
291							"font-family"
292						]
293					}
294				];
295
296				if (!content.querySelector(`#${configBlockId}`)) {
297					content.insertAdjacentHTML(
298						"beforeend",
299						configBlock
300					);
301				}
302
303				styleAttributes.forEach(({
304					tagId,
305					properties
306				}) => {
307					getElementStyles(tagId, properties);
308				});
309
310				try {
311					const styleBlock =
312						content.querySelector(`#${configBlockId}`);
313
314					if (styleBlock) {
315						styleBlock.remove();
316					}
317				} catch (e) {
318					console.error(e.message);
319				}
320			};
321
322			const setAllStyles = () => {
323				let styleConfig = lpcStyleConfig;
324
325				let headerColor =
326					styleConfig[detectedTagId.h]["color"]
327						.replace(";", "");
328
329				let headerFontFamily =
330					styleConfig[detectedTagId.h]["font-family"]
331						.split(",");
332
333				let textColor =
334					styleConfig[detectedTagId.text]["color"]
335						.replace(";", "");
336
337				let textFontFamily =
338					styleConfig[detectedTagId.text]["font-family"]
339						.split(",");
340
341				// Шрифтовая пара. заголовок и текст
342				const fontVariables = `
343					:root {
344						--header-title-family-base: ${headerFontFamily.join(",")}; 
345						--header-text-family-base: ${textFontFamily.join(",")};
346					}
347					`;
348
349							let bgStyle = `
350					:root {
351						--content-background-lpc: ${findBackgroundStyles(content)};
352					}
353				`;
354
355				// Если передана fontVariable, font-family заменяется только для конкретной шрифтовой пары.
356				const generateStyle = (
357					classSelector,
358					styleKey,
359					fontVariable = null
360				) => {
361					const style = styleConfig[styleKey];
362
363					if (style) {
364						const styles = {
365							...style
366						};
367
368						if (fontVariable) {
369							styles["font-family"] =
370								`var(${fontVariable})`;
371						}
372
373						const cleanedStyle = JSON.stringify(styles)
374							.replace(/\\"/gm, "&")
375							.replace(/"+,|"/gm, "")
376							.replace(/&/gm, '"');
377
378						return `${classSelector} ${cleanedStyle}`;
379					}
380
381					return "";
382				};
383
384				const styleContent = `
385          ${generateStyle(
386					".lpc-wrap .lp-header-text-1, .lpc-wrap .lp-header-text-2, .lpc-wrap .lp-header-text-3, .lpc-wrap .lp-header-text-4",
387					detectedTagId.p,
388					"--header-text-family-base"
389				)}
390
391          ${generateStyle(
392					".lp-button",
393					detectedTagId.button
394				)}
395
396          ${generateStyle(
397					".lpc-wrap h1, .lpc-wrap .lp-header-title-1",
398					detectedTagId.h1,
399					"--header-title-family-base"
400				)}
401
402          ${generateStyle(
403					".lpc-wrap h2, .lpc-wrap .lp-header-title-2",
404					detectedTagId.h2,
405					"--header-title-family-base"
406				)}
407
408          ${generateStyle(
409					".lpc-wrap h3, .lpc-wrap .lp-header-title-3",
410					detectedTagId.h3,
411					"--header-title-family-base"
412				)}
413
414          ${generateStyle(
415					".lpc-wrap h4, .lpc-wrap .lp-header-title-4",
416					detectedTagId.h4,
417					"--header-title-family-base"
418				)}
419
420          ${generateStyle(
421					".lpc-wrap h5, .lpc-wrap .lp-header-title-5",
422					detectedTagId.h5,
423					"--header-title-family-base"
424				)}
425
426          ${generateStyle(
427					".lpc-wrap h6, .lpc-wrap .lp-header-title-6",
428					detectedTagId.h6,
429					"--header-title-family-base"
430				)}
431        `;
432
433				const style = `
434          <style id="lpc-stylesheet">
435            ${createCssVariable(headerColor, textColor)}
436
437            ${fontVariables}
438
439            ${bgStyle}
440
441            ${styleContent}
442          </style>
443        `;
444
445				let constructor =
446					document.querySelector("#landing_page_site");
447
448				if (constructor) {
449					let lpcStylesheet =
450						document.querySelector("#lpc-stylesheet");
451
452					if (lpcStylesheet) {
453						lpcStylesheet.remove();
454					}
455
456					let placeToInsert =
457						document.querySelector(
458							'script[src="/g/s3/lp/lpc.v4/js/main.js"]'
459						);
460
461					placeToInsert.insertAdjacentHTML(
462						"afterend",
463						style
464					);
465
466					checkFontFamily(headerFontFamily[0]);
467					checkFontFamily(textFontFamily[0]);
468				} else {
469					let lpcStylesheet =
470						document.querySelector("#lpc-stylesheet");
471
472					if (lpcStylesheet) {
473						lpcStylesheet.remove();
474					}
475
476					document.querySelector(
477						"#lpc-styles-container"
478					).innerHTML += style;
479				}
480			};
481
482			getAllStyles();
483			setAllStyles();
484
485			document.addEventListener(
486				"dataMediaSourceChange",
487				() => {
488					getAllStyles();
489					setAllStyles();
490				}
491			);
492
493			let target = document.querySelector("body");
494
495			let observer = new MutationObserver(
496				(mutations) => {
497					mutations.forEach(() => {
498						if (
499							document.querySelectorAll(
500								".s3solution-panel-root"
501							).length > 0
502						) {
503							$(document).on(
504								"click",
505								".js-panel-themes-list .js-theme-item",
506								() => {
507									setTimeout(() => {
508										getAllStyles();
509										setAllStyles();
510									}, 180);
511								}
512							);
513
514							observer.disconnect();
515						}
516					});
517				}
518			);
519
520			let config = {
521				attributes: true,
522				childList: true,
523				characterData: true
524			};
525
526			observer.observe(target, config);
527		}
528	}, timeout);
529});

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.