1document.addEventListener("DOMContentLoaded", () => { 2 let lpContent = document.getElementById("lp_constructor"); 3 let iframeBody = document; 4 let iframeWindow = window; 5 let timeout = 20; 6 if (lpContent) { 7 timeout = 1500; 8 } 9 setTimeout(() => { 10 if (lpContent) { 11 let iframe = document.querySelector("#lpc_contructor_iframe"); 12 13 if (iframe) { 14 iframeBody = iframe.contentDocument.body; 15 iframeWindow = iframe.contentWindow; 16 } 17 } 18 19 const detectedTagId = { 20 h1: "lpc-config-h1", 21 h2: "lpc-config-h2", 22 h3: "lpc-config-h3", 23 h4: "lpc-config-h4", 24 h5: "lpc-config-h5", 25 h6: "lpc-config-h6", 26 p: "lpc-config-p", 27 button: "lpc-config-button", 28 h: "lpc-config-h2-main", 29 text: "lpc-config-p-main" 30 } 31 32 const configBlockId = "lpc-config-block"; 33 34 const configBlock = ` 35 <div id="${configBlockId}" style="display: none"> 36 <h1 id="${detectedTagId.h1}"></h1> 37 <h2 id="${detectedTagId.h2}"></h2> 38 <h3 id="${detectedTagId.h3}"></h3> 39 <h4 id="${detectedTagId.h4}"></h4> 40 <h5 id="${detectedTagId.h5}"></h5> 41 <h6 id="${detectedTagId.h6}"></h6> 42 <p id="${detectedTagId.p}"></p> 43 <p id="${detectedTagId.button}"></p> 44 <p id="${detectedTagId.text}"></p> 45 <h2 id="${detectedTagId.h}"></h2> 46 </div> 47 `; 48 49 let root;
50 let content = iframeBody.querySelector(".lpc-content-wrapper").parentElement; 51 52 try { 53 root = iframeBody.querySelector(".mosaic-wrap >.root"); 54 } catch (error) { 55 console.log(error.message) 56 } 57 58 if (content) { 59 let lpcStyleConfig = {}; 60 61 const findBackgroundStyles = (content) => { 62 const convertRgbToRgba = (color) => { 63 if (color.startsWith("rgb(")) { 64 return color.replace("rgb(", "rgba(").replace(")", ", 1)"); 65 } 66 return color; 67 }; 68 69 const isColorOpaque = (color) => { 70 const rgbaColor = convertRgbToRgba(color); 71 return parseFloat(rgbaColor.split(",")[3]) > 0; 72 }; 73 74 const getBackgroundColor = (color) => { 75 return isColorOpaque(color) ? convertRgbToRgba(color) : null; 76 }; 77 78 const resultStyles = []; 79 80 const currentElement = content; 81 let parent = currentElement; 82 83 while (parent && parent.tagName !== "HTML") { 84 const computedStyle = getComputedStyle(parent); 85 const currentBackground = computedStyle.backgroundColor; 86 const currentBackgroundImage = computedStyle.backgroundImage; 87 let currentBackgroundGradient = currentBackgroundImage; 88 89 if (currentBackgroundImage && currentBackgroundImage.includes("gradient")) { 90 const imageUrlRegex = /url\("([^"]+)"\)/g; 91 const imageUrlMatches = currentBackgroundImage.match(imageUrlRegex); 92 93 if (imageUrlMatches) { 94 for (const imageUrlMatch of imageUrlMatches) { 95 currentBackgroundGradient = currentBackgroundGradient.replace(imageUrlMatch, "none"); 96 } 97 } 98 resultStyles.push(currentBackgroundGradient); 99 } 100 101 if (!currentBackgroundImage.includes("linear-gradient")) { 102 const bgColor = getBackgroundColor(currentBackground); 103 if (bgColor) { 104 resultStyles.push(`linear-gradient(to right, ${bgColor} 0%, ${bgColor} 100%)`); 105 } 106 } 107 parent = parent.parentNode; 108 } 109 110 return resultStyles; 111 }; 112 113 const getElementStyles = (elementId, styles) => { 114 let element; 115 if (elementId === detectedTagId.h1 && root) { 116 element = iframeBody.querySelector(".page-title"); 117 if(!element) { 118 element = iframeBody.querySelector(`#${detectedTagId.h2}`); 119 } 120 } else { 121 element = iframeBody.querySelector(`#${elementId}`); 122 } 123 124 if(element) { 125 const object = {}; 126 const cssObj = iframeWindow.getComputedStyle(element, null); 127 128 styles.forEach((style) => { 129 object[style] = cssObj.getPropertyValue(style) + ";"; 130 }); 131 132 lpcStyleConfig[elementId] = object; 133 } 134 }; 135 136 const extractRGB = (color) => { 137 const regex = /^rgba?\((\d+),\s*(\d+),\s*(\d+)/; 138 let match = regex.exec(color); 139 return [match[1], match[2], match[3]]; 140 }; 141 142 const checkFontFamily = (fontFamily) => { 143 fontFamily = fontFamily.replace(/'/g, '').replace(/"/g, ''); 144 try { 145 if (!document.fonts.check(`12px ${fontFamily}`)) { 146 const link = document.createElement("link"); 147 link.href = `https://fonts.googleapis.com/css2?family=${fontFamily}`; 148 link.rel = "stylesheet"; 149 document.head.appendChild(link); 150 } 151 } catch (error) { 152 console.log(error.message) 153 } 154 }; 155 156 const createCssVariable = (headerColor, textColor) => { 157 let textColorBase = extractRGB(textColor); 158 159 return ` 160 :root { 161 --text-color-base: rgb(${textColorBase}); 162 --text-color-a-005: rgba(${textColorBase}, 0.05); 163 --text-color-a-01: rgba(${textColorBase}, 0.1); 164 --text-color-a-02: rgba(${textColorBase}, 0.2); 165 --text-color-a-03: rgba(${textColorBase}, 0.3); 166 --text-color-a-04: rgba(${textColorBase}, 0.4); 167 --text-color-a-05: rgba(${textColorBase}, 0.5); 168 --text-color-a-06: rgba(${textColorBase}, 0.6); 169 --text-color-a-07: rgba(${textColorBase}, 0.7);
170 --text-color-a-08: rgba(${textColorBase}, 0.8); 171 --text-color-a-09: rgba(${textColorBase}, 0.9); 172 --text-color-base-header: ${headerColor}; 173 } 174 `; 175 }; 176 177 const getAllStyles = () => { 178 const styleAttributes = [ 179 { 180 tagId: detectedTagId.h1, 181 properties: ["font-family", "font-style", "font-weight"] 182 }, 183 { 184 tagId: detectedTagId.h2, 185 properties: ["font-family", "font-style", "font-weight"] 186 }, 187 { 188 tagId: detectedTagId.h3, 189 properties: ["font-family", "font-style", "font-weight"] 190 }, 191 { 192 tagId: detectedTagId.h4, 193 properties: ["font-family", "font-style", "font-weight"] 194 }, 195 { 196 tagId: detectedTagId.h5, 197 properties: ["font-family", "font-style", "font-weight"] 198 }, 199 { 200 tagId: detectedTagId.h6, 201 properties: ["font-family", "font-style", "font-weight"] 202 }, 203 { 204 tagId: detectedTagId.p, 205 properties: ["font-family", "font-style", "font-weight"] 206 }, 207 { 208 tagId: detectedTagId.button, 209 properties: ["font-family", "font-style"] 210 }, 211 { 212 tagId: detectedTagId.text, 213 properties: ["color", "font-family"] 214 }, 215 { 216 tagId: detectedTagId.h, 217 properties: ["color", "font-family"] 218 } 219 ]; 220 221 if (!content.querySelector(`#${configBlockId}`)) { 222 content.insertAdjacentHTML("beforeend", configBlock); 223 } 224 225 styleAttributes.forEach(({ 226 tagId, 227 properties 228 }) => getElementStyles(tagId, properties)); 229 230 try { 231 const styleBlock = content.querySelector(`#${configBlockId}`); 232 if (styleBlock) { 233 styleBlock.remove(); 234 } 235 } catch (e) { 236 console.error(e.message); 237 } 238 }; 239 240 const setAllStyles = () => { 241 let styleConfig = lpcStyleConfig; 242 let headerColor = styleConfig[detectedTagId.h]["color"].replace(";", ""); 243 let headerFontFamily = styleConfig[detectedTagId.h]["font-family"].split(","); 244 let textColor = styleConfig[detectedTagId.text]["color"].replace(";", ""); 245 let textFontFamily = styleConfig[detectedTagId.text]["font-family"].split(","); 246 247 let bgStyle = ` 248 :root { 249 --content-background-lpc: ${findBackgroundStyles(content)}; 250 } 251 `; 252 253 const generateStyle = (classSelector, styleKey) => { 254 const style = styleConfig[styleKey]; 255 if(style) { 256 const cleanedStyle = JSON.stringify(style) 257 .replace(/\\"/gm, "&") 258 .replace(/"+,|"/gm, "") 259 .replace(/&/gm, '"'); 260 return `${classSelector} ${cleanedStyle}`; 261 } 262 263 }; 264 265 const styleClasses = [ 266 [".lpc-wrap .lp-header-text-1, .lpc-wrap .lp-header-text-2, .lpc-wrap .lp-header-text-3, .lpc-wrap .lp-header-text-4", detectedTagId.p], 267 [".lp-button", detectedTagId.button], 268 [".lpc-wrap h1, .lpc-wrap .lp-header-title-1", detectedTagId.h1], 269 [".lpc-wrap h2, .lpc-wrap .lp-header-title-2", detectedTagId.h2], 270 [".lpc-wrap h3, .lpc-wrap .lp-header-title-3", detectedTagId.h3], 271 [".lpc-wrap h4, .lpc-wrap .lp-header-title-4", detectedTagId.h4], 272 [".lpc-wrap h5, .lpc-wrap .lp-header-title-5", detectedTagId.h5], 273 [".lpc-wrap h6, .lpc-wrap .lp-header-title-6", detectedTagId.h6] 274 ]; 275 276 const styleContent = styleClasses.map(([classSelector, styleKey]) => generateStyle(classSelector, styleKey)).join("\n"); 277 278 const style = ` 279 <style id="lpc-stylesheet"> 280 ${createCssVariable(headerColor, textColor)} 281 ${bgStyle} 282 ${styleContent} 283 </style> 284 `; 285 286 let constructor = document.querySelector("#landing_page_site"); 287 if (constructor) { 288 let lpcStylesheet = document.querySelector("#lpc-stylesheet"); 289 if (lpcStylesheet) { 290 lpcStylesheet.remove(); 291 } 292 let placeToInsert = document.querySelector('script[src="/g/s3/lp/lpc.v4/js/main.js"]'); 293 placeToInsert.insertAdjacentHTML("afterend", style); 294 checkFontFamily(headerFontFamily[0]); 295 checkFontFamily(textFontFamily[0]); 296 } else { 297 let lpcStylesheet = document.querySelector("#lpc-stylesheet"); 298 if (lpcStylesheet) { 299 lpcStylesheet.remove(); 300 } 301 document.querySelector("#lpc-styles-container").innerHTML += style; 302 } 303 }; 304 305 getAllStyles(); 306 setAllStyles(); 307 308 document.addEventListener("dataMediaSourceChange", () => { 309 getAllStyles(); 310 setAllStyles(); 311 }); 312 313 let target = document.querySelector("body"); 314 let observer = new MutationObserver((mutations) => { 315 mutations.forEach(() => { 316 if (document.querySelectorAll(".s3solution-panel-root").length > 0) { 317 318 $(document).on("click", ".js-panel-themes-list .js-theme-item", () => { 319 setTimeout(() => { 320 getAllStyles(); 321 setAllStyles(); 322 }, 180); 323 }); 324 325 observer.disconnect(); 326 } 327 }); 328 }); 329 let config = { 330 attributes: true, 331 childList: true, 332 characterData: true 333 }; 334 335 observer.observe(target, config); 336 } 337 }, timeout); 338});
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.