fix(ivy): ngClass not applying classes with trailing/leading spaces (#34539)

Fixes classes with trailing or leading space that are passed to `ngClass` (e.g. `{'foo ': bar}`) not being applied in Ivy. The issue comes from the fact that when the styling differ builds up the style map it uses the trimmed key to look up the value in the map that uses non-trimmed keys.

Fixes #34476.

PR Close #34539
This commit is contained in:
crisbeto 2020-01-07 06:33:57 +01:00 committed by Alex Rickabaugh
parent 6fda7f3da4
commit d909fb0b1f
2 changed files with 24 additions and 2 deletions

View File

@ -212,11 +212,11 @@ function bulidMapFromValues(
// case 1: map // case 1: map
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
let key = keys[i]; let key = keys[i];
key = trim ? key.trim() : key;
const value = (values as{[key: string]: any})[key]; const value = (values as{[key: string]: any})[key];
if (value !== undefined) { if (value !== undefined) {
setMapValues(map, key, value, parseOutUnits, allowSubKeys); // Map uses untrimmed keys, so don't trim until passing to `setMapValues`
setMapValues(map, trim ? key.trim() : key, value, parseOutUnits, allowSubKeys);
} }
} }
} else { } else {

View File

@ -2485,6 +2485,28 @@ describe('styling', () => {
const div = fixture.nativeElement.querySelector('div'); const div = fixture.nativeElement.querySelector('div');
expect(getComputedStyle(div).width).toBe('10px'); expect(getComputedStyle(div).width).toBe('10px');
}); });
it('should allow classes with trailing and leading spaces in [ngClass]', () => {
@Component({
template: `
<div leading-space [ngClass]="{' foo': applyClasses}"></div>
<div trailing-space [ngClass]="{'foo ': applyClasses}"></div>
`
})
class Cmp {
applyClasses = true;
}
TestBed.configureTestingModule({declarations: [Cmp]});
const fixture = TestBed.createComponent(Cmp);
fixture.detectChanges();
const leading = fixture.nativeElement.querySelector('[leading-space]');
const trailing = fixture.nativeElement.querySelector('[trailing-space]');
expect(leading.className).toBe('foo', 'Expected class to be applied despite leading space.');
expect(trailing.className).toBe('foo', 'Expected class to be applied despite trailing space.');
});
}); });
function assertStyleCounters(countForSet: number, countForRemove: number) { function assertStyleCounters(countForSet: number, countForRemove: number) {