fix(ivy): handle SafeStyles in [style.prop] correctly (#34286)
Prior to this commit, values wrapped into SafeStyle were not handled correctly in [style.prop] bindings in case style sanitizer is present (when template contains some style props that require sanitization). Style sanitizer was not unwrapping values in case a given prop doesn't require sanitization.As a result, wrapped values were used as final styling values (see https://github.com/angular/angular/blob/master/packages/core/src/render3/styling/bindings.ts#L620). This commit updates the logic to unwrap safe values in sanitizer in case no sanitization is required. PR Close #34286
This commit is contained in:
parent
2ecf9f3f2a
commit
bb52fb798c
|
@ -196,7 +196,7 @@ export const ɵɵdefaultStyleSanitizer =
|
|||
}
|
||||
|
||||
if (mode & StyleSanitizeMode.SanitizeOnly) {
|
||||
return doSanitizeValue ? ɵɵsanitizeStyle(value) : value;
|
||||
return doSanitizeValue ? ɵɵsanitizeStyle(value) : unwrapSafeValue(value);
|
||||
} else {
|
||||
return doSanitizeValue;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {Component, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, HostBinding, Input, NgModule, Renderer2, ViewChild, ViewContainerRef} from '@angular/core';
|
||||
import {getDebugNode} from '@angular/core/src/render3/util/discovery_utils';
|
||||
import {ngDevModeResetPerfCounters} from '@angular/core/src/util/ng_dev_mode';
|
||||
|
@ -1563,6 +1564,64 @@ describe('styling', () => {
|
|||
expect(html).toMatch(/style=["|']clip-path:\s*url\(.*#test.*\)/);
|
||||
});
|
||||
|
||||
it('should handle values wrapped into SafeValue', () => {
|
||||
@Component({
|
||||
template: `
|
||||
<!-- Verify sanitizable style prop values wrapped in SafeValue -->
|
||||
<div [style.background]="getBackgroundSafe()"></div>
|
||||
|
||||
<!-- Verify regular style prop values wrapped in SafeValue -->
|
||||
<p [style.width]="getWidthSafe()" [style.height]="getHeightSafe()"></p>
|
||||
|
||||
<!-- Verify regular style prop values not wrapped in SafeValue -->
|
||||
<span [style.color]="getColorUnsafe()"></span>
|
||||
`,
|
||||
})
|
||||
class MyComp {
|
||||
constructor(private sanitizer: DomSanitizer) {}
|
||||
public width: string = 'calc(20%)';
|
||||
public height: string = '10px';
|
||||
public background: string = '1.png';
|
||||
public color: string = 'red';
|
||||
|
||||
private getSafeStyle(value: string) { return this.sanitizer.bypassSecurityTrustStyle(value); }
|
||||
|
||||
getBackgroundSafe() { return this.getSafeStyle(`url("/${this.background}")`); }
|
||||
getWidthSafe() { return this.getSafeStyle(this.width); }
|
||||
getHeightSafe() { return this.getSafeStyle(this.height); }
|
||||
getColorUnsafe() { return this.color; }
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [MyComp],
|
||||
});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const comp = fixture.componentInstance;
|
||||
const div = fixture.nativeElement.querySelector('div');
|
||||
const p = fixture.nativeElement.querySelector('p');
|
||||
const span = fixture.nativeElement.querySelector('span');
|
||||
|
||||
expect(div.style.background).toContain('url("/1.png")');
|
||||
expect(p.style.width).toBe('calc(20%)');
|
||||
expect(p.style.height).toBe('10px');
|
||||
expect(span.style.color).toBe('red');
|
||||
|
||||
comp.background = '2.png';
|
||||
comp.width = '5px';
|
||||
comp.height = '100%';
|
||||
comp.color = 'green';
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(div.style.background).toContain('url("/2.png")');
|
||||
expect(p.style.width).toBe('5px');
|
||||
expect(p.style.height).toBe('100%');
|
||||
expect(span.style.color).toBe('green');
|
||||
});
|
||||
|
||||
onlyInIvy('only ivy has style/class bindings debugging support')
|
||||
.it('should evaluate follow-up [style] maps even if a former map is null', () => {
|
||||
@Directive({selector: '[dir-with-styling]'})
|
||||
|
|
Loading…
Reference in New Issue