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.