diff --git a/packages/compiler/src/render3/view/styling_builder.ts b/packages/compiler/src/render3/view/styling_builder.ts index 5430d04b07..c14812e483 100644 --- a/packages/compiler/src/render3/view/styling_builder.ts +++ b/packages/compiler/src/render3/view/styling_builder.ts @@ -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); diff --git a/packages/core/test/acceptance/styling_spec.ts b/packages/core/test/acceptance/styling_spec.ts index e6ac22da21..a300052077 100644 --- a/packages/core/test/acceptance/styling_spec.ts +++ b/packages/core/test/acceptance/styling_spec.ts @@ -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: ` +
+ + `, + }) + 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: ` + + + `, + }) + 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: '', @@ -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({