From e112e320bf6c2b60e8ecea46f80bcaec593c65b7 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 30 Mar 2021 11:08:56 +0200 Subject: [PATCH] fix(compiler): handle case-sensitive CSS custom properties (#41380) Currently we normalize all CSS property names in the `StylingBuilder` which breaks custom properties, because they're case-sensitive. These changes add a check so that custom properties aren't normalized. Fixes #41364. PR Close #41380 --- .../src/render3/view/styling_builder.ts | 14 ++++++++--- packages/core/test/acceptance/styling_spec.ts | 23 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/compiler/src/render3/view/styling_builder.ts b/packages/compiler/src/render3/view/styling_builder.ts index c14812e483..eea4fe75ad 100644 --- a/packages/compiler/src/render3/view/styling_builder.ts +++ b/packages/compiler/src/render3/view/styling_builder.ts @@ -219,7 +219,11 @@ export class StylingBuilder { if (isEmptyExpression(value)) { return null; } - name = normalizePropName(name); + // CSS custom properties are case-sensitive so we shouldn't normalize them. + // See: https://www.w3.org/TR/css-variables-1/#defining-variables + if (!isCssCustomProperty(name)) { + name = hyphenate(name); + } const {property, hasOverrideFlag, suffix: bindingSuffix} = parseProperty(name); suffix = typeof suffix === 'string' && suffix.length !== 0 ? suffix : bindingSuffix; const entry: @@ -607,6 +611,10 @@ function getStylePropInterpolationExpression(interpolation: Interpolation) { } } -function normalizePropName(prop: string): string { - return hyphenate(prop); +/** + * Checks whether property name is a custom CSS property. + * See: https://www.w3.org/TR/css-variables-1 + */ +function isCssCustomProperty(name: string): boolean { + return name.startsWith('--'); } diff --git a/packages/core/test/acceptance/styling_spec.ts b/packages/core/test/acceptance/styling_spec.ts index a300052077..2013613a9a 100644 --- a/packages/core/test/acceptance/styling_spec.ts +++ b/packages/core/test/acceptance/styling_spec.ts @@ -294,6 +294,29 @@ describe('styling', () => { const header = fixture.nativeElement.querySelector('h1') as HTMLElement; expect(getComputedStyle(header).getPropertyValue('width')).toEqual('100px'); }); + + it('should support case-sensitive css variables', () => { + // This test only works in browsers which support CSS variables. + if (!supportsCssVariables) { + return; + } + + @Component({ + template: ` +
+ CONTENT +
+ ` + }) + class Cmp { + } + TestBed.configureTestingModule({declarations: [Cmp]}); + const fixture = TestBed.createComponent(Cmp); + fixture.detectChanges(); + + const span = fixture.nativeElement.querySelector('span') as HTMLElement; + expect(getComputedStyle(span).getPropertyValue('width')).toEqual('100px'); + }); }); modifiedInIvy('shadow bindings include static portion')