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