fix(core): remove obsolete check for [class] and [className] presence (#41254)
Previously presence of both [class] and [className] bindings on an element was treated as compiler error (implemented in6f203c9575
). Later, the situation was improved to actually allow both bindings to co-exist (seea153b61098
), however the compiler check was not removed completely. The only situation where the error is thrown at this moment is when static (but with interpolation) and bound `class` attributes are present on an element, for ex.: ``` <div class="{{ one }}" [class]="'two'"></div> ``` In the current situation the error is acually misleading (as it refers to `[className]`). This commit removes the mentioned compiler check as obsolete and makes the `class` and `style` attribute processing logically the same (the last occurrence is used to compute the value). PR Close #41254
This commit is contained in:
parent
2ccb579e06
commit
3a55698402
|
@ -246,10 +246,6 @@ export class StylingBuilder {
|
|||
const entry:
|
||||
BoundStylingEntry = {name: property, value, sourceSpan, hasOverrideFlag, suffix: null};
|
||||
if (isMapBased) {
|
||||
if (this._classMapInput) {
|
||||
throw new Error(
|
||||
'[class] and [className] bindings cannot be used on the same element simultaneously');
|
||||
}
|
||||
this._classMapInput = entry;
|
||||
} else {
|
||||
(this._singleClassInputs = this._singleClassInputs || []).push(entry);
|
||||
|
|
|
@ -17,6 +17,40 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
|||
import {ivyEnabled, modifiedInIvy, onlyInIvy} from '@angular/private/testing';
|
||||
|
||||
describe('styling', () => {
|
||||
/**
|
||||
* This helper function tests to see if the current browser supports non standard way of writing
|
||||
* into styles.
|
||||
*
|
||||
* This is not the correct way to write to style and is not supported in IE11.
|
||||
* ```
|
||||
* div.style = 'color: white';
|
||||
* ```
|
||||
*
|
||||
* This is the correct way to write to styles:
|
||||
* ```
|
||||
* div.style.cssText = 'color: white';
|
||||
* ```
|
||||
*
|
||||
* Even though writing to `div.style` is not officially supported, it works in all
|
||||
* browsers except IE11.
|
||||
*
|
||||
* This function detects this condition and allows us to skip affected tests.
|
||||
*/
|
||||
let _supportsWritingStringsToStyleProperty: boolean|null = null;
|
||||
function supportsWritingStringsToStyleProperty() {
|
||||
if (_supportsWritingStringsToStyleProperty === null) {
|
||||
const div = document.createElement('div');
|
||||
const CSS = 'color: white;';
|
||||
try {
|
||||
(div as any).style = CSS;
|
||||
} catch (e) {
|
||||
_supportsWritingStringsToStyleProperty = false;
|
||||
}
|
||||
_supportsWritingStringsToStyleProperty = (div.style.cssText === CSS);
|
||||
}
|
||||
return _supportsWritingStringsToStyleProperty;
|
||||
}
|
||||
|
||||
beforeEach(ngDevModeResetPerfCounters);
|
||||
|
||||
describe('apply in prioritization order', () => {
|
||||
|
@ -3069,6 +3103,64 @@ describe('styling', () => {
|
|||
expect(fixture.debugElement.nativeElement.innerHTML).toContain('three');
|
||||
});
|
||||
|
||||
it('should allow static and bound `class` attribute, but use last occurrence', () => {
|
||||
@Component({
|
||||
template: `
|
||||
<div id="first" class="zero {{one}}" [class]="'two'"></div>
|
||||
<div id="second" [class]="'two'" class="zero {{one}}"></div>
|
||||
`,
|
||||
})
|
||||
class MyComp {
|
||||
one = 'one';
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const first = fixture.nativeElement.querySelector('#first').outerHTML;
|
||||
expect(first).not.toContain('zero');
|
||||
expect(first).not.toContain('one');
|
||||
expect(first).toContain('two');
|
||||
|
||||
const second = fixture.nativeElement.querySelector('#second').outerHTML;
|
||||
expect(second).toContain('zero');
|
||||
expect(second).toContain('one');
|
||||
expect(second).not.toContain('two');
|
||||
});
|
||||
|
||||
it('should allow static and bound `style` attribute, but use last occurrence', () => {
|
||||
if (!ivyEnabled && !supportsWritingStringsToStyleProperty()) {
|
||||
// VE does not treat `[style]` as anything special, instead it simply writes to the
|
||||
// `style` property on the element like so `element.style=value`. This seems to work fine
|
||||
// every where except IE11, where it throws an error and as a consequence this test fails in
|
||||
// VE on IE11.
|
||||
return;
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<div id="first" style="margin: {{margin}}" [style]="'padding: 20px;'"></div>
|
||||
<div id="second" [style]="'padding: 20px;'" style="margin: {{margin}}"></div>
|
||||
`,
|
||||
})
|
||||
class MyComp {
|
||||
margin = '10px';
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const first = fixture.nativeElement.querySelector('#first').outerHTML;
|
||||
expect(first).not.toContain('margin');
|
||||
expect(first).toContain('padding');
|
||||
|
||||
const second = fixture.nativeElement.querySelector('#second').outerHTML;
|
||||
expect(second).toContain('margin');
|
||||
expect(second).not.toContain('padding');
|
||||
});
|
||||
|
||||
it('should allow to reset style property value defined using [style.prop.px] binding', () => {
|
||||
@Component({
|
||||
template: '<div [style.left.px]="left"></div>',
|
||||
|
@ -3625,35 +3717,6 @@ describe('styling', () => {
|
|||
expectStyle(div).toEqual({color: 'white', display: 'block'});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests to see if the current browser supports non standard way of writing into styles.
|
||||
*
|
||||
* This is not the correct way to write to style and is not supported in IE11.
|
||||
* ```
|
||||
* div.style = 'color: white';
|
||||
* ```
|
||||
*
|
||||
* This is the correct way to write to styles:
|
||||
* ```
|
||||
* div.style.cssText = 'color: white';
|
||||
* ```
|
||||
*
|
||||
* Even though writing to `div.style` is not officially supported, it works in all
|
||||
* browsers except IE11.
|
||||
*
|
||||
* This function detects this condition and allows us to skip the test.
|
||||
*/
|
||||
function supportsWritingStringsToStyleProperty() {
|
||||
const div = document.createElement('div');
|
||||
const CSS = 'color: white;';
|
||||
try {
|
||||
(div as any).style = CSS;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return div.style.cssText === CSS;
|
||||
}
|
||||
|
||||
onlyInIvy('styling priority resolution is Ivy only feature.')
|
||||
.it('should allow lookahead binding on second pass #35118', () => {
|
||||
@Component({
|
||||
|
|
Loading…
Reference in New Issue