fix(core): error if CSS custom property in host binding has number in name (#38432)

Fixes an error if a CSS custom property, used inside a host binding, has a
number in its name. The error is thrown because the styling parser only
expects characters from A to Z,dashes, underscores and a handful of other
characters.

Fixes #37292.

PR Close #38432
This commit is contained in:
crisbeto 2020-08-13 08:02:59 +02:00 committed by Andrew Scott
parent aa847cb014
commit a80f654af9
3 changed files with 35 additions and 9 deletions

View File

@ -210,7 +210,8 @@ export function consumeStyleKey(text: string, startIndex: number, endIndex: numb
let ch: number;
while (startIndex < endIndex &&
((ch = text.charCodeAt(startIndex)) === CharCode.DASH || ch === CharCode.UNDERSCORE ||
((ch & CharCode.UPPER_CASE) >= CharCode.A && (ch & CharCode.UPPER_CASE) <= CharCode.Z))) {
((ch & CharCode.UPPER_CASE) >= CharCode.A && (ch & CharCode.UPPER_CASE) <= CharCode.Z) ||
(ch >= CharCode.ZERO && ch <= CharCode.NINE))) {
startIndex++;
}
return startIndex;

View File

@ -22,6 +22,8 @@ export const enum CharCode {
SEMI_COLON = 59, // ";"
BACK_SLASH = 92, // "\\"
AT_SIGN = 64, // "@"
ZERO = 48, // "0"
NINE = 57, // "9"
A = 65, // "A"
U = 85, // "U"
R = 82, // "R"

View File

@ -214,28 +214,51 @@ describe('styling', () => {
});
});
describe('css variables', () => {
onlyInIvy('css variables').it('should support css variables', () => {
onlyInIvy('CSS variables are only supported in Ivy').describe('css variables', () => {
const supportsCssVariables = typeof getComputedStyle !== 'undefined' &&
typeof CSS !== 'undefined' && typeof CSS.supports !== 'undefined' &&
CSS.supports('color', 'var(--fake-var)');
it('should support css variables', () => {
// This test only works in browsers which support CSS variables.
if (!(typeof getComputedStyle !== 'undefined' && typeof CSS !== 'undefined' &&
typeof CSS.supports !== 'undefined' && CSS.supports('color', 'var(--fake-var)')))
if (!supportsCssVariables) {
return;
}
@Component({
template: `
<div [style.--my-var]=" '100px' ">
<span style="width: var(--my-var)">CONTENT</span>
</div>`
<div [style.--my-var]="'100px'">
<span style="width: var(--my-var)">CONTENT</span>
</div>
`
})
class Cmp {
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
// document.body.appendChild(fixture.nativeElement);
fixture.detectChanges();
const span = fixture.nativeElement.querySelector('span') as HTMLElement;
expect(getComputedStyle(span).getPropertyValue('width')).toEqual('100px');
});
it('should support css variables with numbers in their name inside a host binding', () => {
// This test only works in browsers which support CSS variables.
if (!supportsCssVariables) {
return;
}
@Component({template: `<h1 style="width: var(--my-1337-var)">Hello</h1>`})
class Cmp {
@HostBinding('style') style = '--my-1337-var: 100px;';
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
fixture.detectChanges();
const header = fixture.nativeElement.querySelector('h1') as HTMLElement;
expect(getComputedStyle(header).getPropertyValue('width')).toEqual('100px');
});
});
modifiedInIvy('shadow bindings include static portion')