diff --git a/tracker/tracker/src/main/app/observer/cssInliner.ts b/tracker/tracker/src/main/app/observer/cssInliner.ts index b0aeb034f..afad8fd05 100644 --- a/tracker/tracker/src/main/app/observer/cssInliner.ts +++ b/tracker/tracker/src/main/app/observer/cssInliner.ts @@ -1,4 +1,4 @@ -let fakeIdHolder = 1000000 * 99; +let fakeIdHolder = 1000000 * 99 export function inlineRemoteCss( node: HTMLLinkElement, @@ -11,20 +11,20 @@ export function inlineRemoteCss( sendPlain?: boolean, onPlain?: (cssText: string, id: number) => void, ) { - const sheetId = sendPlain ? null : getNextID(); + const sheetId = sendPlain ? null : getNextID() if (!sendPlain) { - addOwner(sheetId!, id); + addOwner(sheetId!, id) } - const sheet = node.sheet; + const sheet = node.sheet if (sheet && !forceFetch) { try { - const cssText = stringifyStylesheet(sheet); + const cssText = stringifyStylesheet(sheet) if (cssText) { - processCssText(cssText); - return; + processCssText(cssText) + return } } catch (e) { // console.warn("Could not stringify sheet, falling back to fetch:", e); @@ -34,155 +34,152 @@ export function inlineRemoteCss( // Fall back to fetching if we couldn't get or stringify the sheet if (node.href) { fetch(node.href) - .then(response => { + .then((response) => { if (!response.ok) { - throw new Error(`response status ${response.status}`); + throw new Error(`response status ${response.status}`) } - return response.text(); + return response.text() }) - .then(cssText => { + .then((cssText) => { if (sendPlain && onPlain) { - onPlain(cssText, fakeIdHolder++); + onPlain(cssText, fakeIdHolder++) } else { - processCssText(cssText); + processCssText(cssText) } }) - .catch(error => { - console.error(`OpenReplay: Failed to fetch CSS from ${node.href}:`, error); - }); + .catch((error) => { + console.error(`OpenReplay: Failed to fetch CSS from ${node.href}:`, error) + }) } function processCssText(cssText: string) { // Remove comments - cssText = cssText.replace(/\/\*[\s\S]*?\*\//g, ''); + cssText = cssText.replace(/\/\*[\s\S]*?\*\//g, '') // Parse and process the CSS text to extract rules - const ruleTexts = parseCSS(cssText); + const ruleTexts = parseCSS(cssText) for (let i = 0; i < ruleTexts.length; i++) { - insertRule(sheetId!, ruleTexts[i], i, baseHref); + const expandedRule = expandShorthand(ruleTexts[i]).replace(';;', ';') + insertRule(sheetId!, expandedRule, i, baseHref) } } - function parseCSS(cssText: string): string[] { - const rules: string[] = []; - let inComment = false; - let inString = false; - let stringChar = ''; - let braceLevel = 0; - let currentRule = ''; + const rules: string[] = [] + let inComment = false + let inString = false + let stringChar = '' + let braceLevel = 0 + let currentRule = '' for (let i = 0; i < cssText.length; i++) { - const char = cssText[i]; - const nextChar = cssText[i + 1] || ''; + const char = cssText[i] + const nextChar = cssText[i + 1] || '' // comments if (!inString && char === '/' && nextChar === '*') { - inComment = true; - i++; // Skip the next character - continue; + inComment = true + i++ // Skip the next character + continue } if (inComment) { if (char === '*' && nextChar === '/') { - inComment = false; - i++; // Skip the next character + inComment = false + i++ // Skip the next character } - continue; + continue } - if (!inString && (char === '"' || char === "'")) { - inString = true; - stringChar = char; - currentRule += char; - continue; + inString = true + stringChar = char + currentRule += char + continue } if (inString) { - currentRule += char; + currentRule += char if (char === stringChar && cssText[i - 1] !== '\\') { - inString = false; + inString = false } - continue; + continue } - - currentRule += char; + currentRule += char if (char === '{') { - braceLevel++; + braceLevel++ } else if (char === '}') { - braceLevel--; + braceLevel-- if (braceLevel === 0) { // End of a top-level rule - rules.push(currentRule.trim()); - currentRule = ''; + rules.push(currentRule.trim()) + currentRule = '' } } } // Handle any remaining text (should be rare) if (currentRule.trim()) { - rules.push(currentRule.trim()); + rules.push(currentRule.trim()) } - return rules; + return rules } - function stringifyStylesheet(s: CSSStyleSheet): string | null { try { - const rules = s.rules || s.cssRules; + const rules = s.rules || s.cssRules if (!rules) { - return null; + return null } - let sheetHref = s.href; + let sheetHref = s.href if (!sheetHref && s.ownerNode && (s.ownerNode as HTMLElement).ownerDocument) { // an inline