Skip to content

Commit 620fb2f

Browse files
authored
fix: [#1837] Fixes issue where CSS var() isn't parsed correctly when inside CSS functions (#1838)
1 parent f4bd4eb commit 620fb2f

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

packages/happy-dom/src/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ import CSSScopeRule from '../../rules/CSSScopeRule.js';
2323
import CSSStyleSheet from '../../CSSStyleSheet.js';
2424

2525
const CSS_MEASUREMENT_REGEXP = /[0-9.]+(px|rem|em|vw|vh|%|vmin|vmax|cm|mm|in|pt|pc|Q)/g;
26-
const CSS_VARIABLE_REGEXP = /var\( *(--[^), ]+)\)|var\( *(--[^), ]+), *(.+)\)/;
2726
const HOST_REGEXP = /:host\s*\(([^)]+)\)|:host-context\s*\(([^)]+)\)/;
27+
const SINGLE_CSS_VARIABLE_REGEXP = /var\( *(--[^), ]+)\)/;
28+
const CSS_VARIABLE_REGEXP = /var\( *(--[^), ]+), *([^), ]+)\)/;
2829

2930
type IStyleAndElement = {
3031
element: Element | ShadowRoot | Document | null;
@@ -460,13 +461,14 @@ export default class CSSStyleDeclarationComputedStyle {
460461
let newValue = value;
461462
let match: RegExpMatchArray | null;
462463

464+
while ((match = newValue.match(SINGLE_CSS_VARIABLE_REGEXP)) != null) {
465+
// Without fallback value - E.g. var(--my-var)
466+
newValue = newValue.replace(match[0], cssVariables[match[1]] || '');
467+
}
468+
463469
while ((match = newValue.match(CSS_VARIABLE_REGEXP)) !== null) {
464470
// Fallback value - E.g. var(--my-var, #FFFFFF)
465-
if (match[2] !== undefined) {
466-
newValue = newValue.replace(match[0], cssVariables[match[2]] || match[3]);
467-
} else {
468-
newValue = newValue.replace(match[0], cssVariables[match[1]] || '');
469-
}
471+
newValue = newValue.replace(match[0], cssVariables[match[1]] || match[2]);
470472
}
471473

472474
return newValue;

packages/happy-dom/test/css/declaration/computed-style/CSSStyleDeclarationComputedStyle.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,27 @@ describe('CSSStyleDeclarationElementStyle', () => {
2828

2929
expect(computedElementStyleDeclaration.getComputedStyle()).not.toBe(computedElementStyle);
3030
});
31+
it('parses variables correctly.', () => {
32+
document.body.appendChild(element);
33+
element.setAttribute(
34+
'style',
35+
`--bg-color: rgb(0 128 0 / 1); background-color: var(--bg-color);`
36+
);
37+
38+
const computedElementStyleDeclaration = new CSSStyleDeclarationElementStyle(element);
39+
const computedElementStyle = computedElementStyleDeclaration.getComputedStyle();
40+
expect(computedElementStyle.get('background-color').value).toBe('rgb(0 128 0 / 1)');
41+
});
42+
it('parses nested variables correctly.', () => {
43+
document.body.appendChild(element);
44+
element.setAttribute(
45+
'style',
46+
`--bg-color-alpha: 1; background-color: rgb(0 128 0 / var(--bg-color-alpha, 1));`
47+
);
48+
49+
const computedElementStyleDeclaration = new CSSStyleDeclarationElementStyle(element);
50+
const computedElementStyle = computedElementStyleDeclaration.getComputedStyle();
51+
expect(computedElementStyle.get('background-color').value).toBe('rgb(0 128 0 / 1)');
52+
});
3153
});
3254
});

0 commit comments

Comments
 (0)