fixup! fix(ivy): incorrectly remapping certain properties that refer to inputs (#28765)
PR Close #28765
This commit is contained in:
parent
93a7836f7a
commit
32ae84da28
|
@ -137,6 +137,48 @@ describe('compiler compliance: bindings', () => {
|
||||||
const result = compile(files, angularFiles);
|
const result = compile(files, angularFiles);
|
||||||
expect(result.source).not.toContain('i0.ɵelementProperty');
|
expect(result.source).not.toContain('i0.ɵelementProperty');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not remap property names whose names do not correspond to their attribute names',
|
||||||
|
() => {
|
||||||
|
const files = {
|
||||||
|
app: {
|
||||||
|
'spec.ts': `
|
||||||
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-component',
|
||||||
|
template: \`
|
||||||
|
<label [for]="forValue"></label>\`
|
||||||
|
})
|
||||||
|
export class MyComponent {
|
||||||
|
forValue = 'some-input';
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [MyComponent]})
|
||||||
|
export class MyModule {}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const template = `
|
||||||
|
const $c0$ = [${AttributeMarker.SelectOnly}, "for"];
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
function MyComponent_Template(rf, ctx) {
|
||||||
|
if (rf & 1) {
|
||||||
|
$i0$.ɵelement(0, "label", _c0);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
$i0$.ɵelementProperty(0, "for", $i0$.ɵbind(ctx.forValue));
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const result = compile(files, angularFiles);
|
||||||
|
|
||||||
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('host bindings', () => {
|
describe('host bindings', () => {
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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 {Component, Input} from '@angular/core';
|
||||||
|
import {TestBed} from '@angular/core/testing';
|
||||||
|
import {By} from '@angular/platform-browser';
|
||||||
|
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
|
|
||||||
|
describe('elementProperty', () => {
|
||||||
|
it('should bind to properties whose names do not correspond to their attribute names', () => {
|
||||||
|
@Component({template: '<label [for]="forValue"></label>'})
|
||||||
|
class MyComp {
|
||||||
|
forValue?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||||
|
const fixture = TestBed.createComponent(MyComp);
|
||||||
|
const labelNode = fixture.debugElement.query(By.css('label'));
|
||||||
|
|
||||||
|
fixture.componentInstance.forValue = 'some-input';
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(labelNode.nativeElement.getAttribute('for')).toBe('some-input');
|
||||||
|
|
||||||
|
fixture.componentInstance.forValue = 'some-textarea';
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(labelNode.nativeElement.getAttribute('for')).toBe('some-textarea');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not map properties whose names do not correspond to their attribute names, ' +
|
||||||
|
'if they correspond to inputs',
|
||||||
|
() => {
|
||||||
|
|
||||||
|
@Component({template: '', selector: 'my-comp'})
|
||||||
|
class MyComp {
|
||||||
|
@Input() for !:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({template: '<my-comp [for]="forValue"></my-comp>'})
|
||||||
|
class App {
|
||||||
|
forValue?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({declarations: [App, MyComp]});
|
||||||
|
const fixture = TestBed.createComponent(App);
|
||||||
|
const myCompNode = fixture.debugElement.query(By.directive(MyComp));
|
||||||
|
fixture.componentInstance.forValue = 'hello';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy();
|
||||||
|
expect(myCompNode.componentInstance.for).toBe('hello');
|
||||||
|
|
||||||
|
fixture.componentInstance.forValue = 'hej';
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy();
|
||||||
|
expect(myCompNode.componentInstance.for).toBe('hej');
|
||||||
|
});
|
||||||
|
});
|
|
@ -76,26 +76,6 @@ describe('elementProperty', () => {
|
||||||
expect(fixture.html).toEqual('<span id="_otherId_"></span>');
|
expect(fixture.html).toEqual('<span id="_otherId_"></span>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should map properties whose names do not correspond to their attribute names', () => {
|
|
||||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & RenderFlags.Create) {
|
|
||||||
element(0, 'label');
|
|
||||||
}
|
|
||||||
if (rf & RenderFlags.Update) {
|
|
||||||
elementProperty(0, 'for', bind(ctx.forValue));
|
|
||||||
}
|
|
||||||
}, 1, 1);
|
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
|
||||||
fixture.component.forValue = 'some-input';
|
|
||||||
fixture.update();
|
|
||||||
expect(fixture.html).toEqual('<label for="some-input"></label>');
|
|
||||||
|
|
||||||
fixture.component.forValue = 'some-textarea';
|
|
||||||
fixture.update();
|
|
||||||
expect(fixture.html).toEqual('<label for="some-textarea"></label>');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('input properties', () => {
|
describe('input properties', () => {
|
||||||
let button: MyButton;
|
let button: MyButton;
|
||||||
let otherDir: OtherDir;
|
let otherDir: OtherDir;
|
||||||
|
@ -384,50 +364,6 @@ describe('elementProperty', () => {
|
||||||
expect(otherDir !.id).toEqual(3);
|
expect(otherDir !.id).toEqual(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not map properties whose names do not correspond to their attribute names, ' +
|
|
||||||
'if they correspond to inputs',
|
|
||||||
() => {
|
|
||||||
let comp: Comp;
|
|
||||||
|
|
||||||
class Comp {
|
|
||||||
// TODO(issue/24571): remove '!'.
|
|
||||||
// clang-format off
|
|
||||||
for !: string;
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
static ngComponentDef = defineComponent({
|
|
||||||
type: Comp,
|
|
||||||
selectors: [['comp']],
|
|
||||||
consts: 0,
|
|
||||||
vars: 0,
|
|
||||||
template: function(rf: RenderFlags, ctx: any) {},
|
|
||||||
factory: () => comp = new Comp(),
|
|
||||||
inputs: {for: 'for'}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** <comp [for]="forValue"></comp> */
|
|
||||||
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
|
|
||||||
if (rf & RenderFlags.Create) {
|
|
||||||
element(0, 'comp');
|
|
||||||
}
|
|
||||||
if (rf & RenderFlags.Update) {
|
|
||||||
elementProperty(0, 'for', bind(ctx.forValue));
|
|
||||||
}
|
|
||||||
}, 1, 1, [Comp]);
|
|
||||||
|
|
||||||
const fixture = new ComponentFixture(App);
|
|
||||||
fixture.component.forValue = 'hello';
|
|
||||||
fixture.update();
|
|
||||||
expect(fixture.html).toEqual(`<comp></comp>`);
|
|
||||||
expect(comp !.for).toEqual('hello');
|
|
||||||
|
|
||||||
fixture.component.forValue = 'hej';
|
|
||||||
fixture.update();
|
|
||||||
expect(fixture.html).toEqual(`<comp></comp>`);
|
|
||||||
expect(comp !.for).toEqual('hej');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('attributes and input properties', () => {
|
describe('attributes and input properties', () => {
|
||||||
|
|
|
@ -733,73 +733,9 @@ window.testBlocklist = {
|
||||||
"error": "Error: Expected null not to be null.",
|
"error": "Error: Expected null not to be null.",
|
||||||
"notes": "Unknown"
|
"notes": "Unknown"
|
||||||
},
|
},
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with formControl should update datepicker when formControl changes": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with formControl should update formControl when date is selected": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with formControl should disable input when form control disabled": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with formControl should disable toggle when form control disabled": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should set `aria-haspopup` on the toggle button": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should open calendar when toggle clicked": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should not open calendar when toggle clicked if datepicker is disabled": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should not open calendar when toggle clicked if input is disabled": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should set the `button` type on the trigger to prevent form submissions": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should remove the underlying SVG icon from the tab order": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should restore focus to the toggle after the calendar is closed": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should re-render when the i18n labels change": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should toggle the active state of the datepicker toggle": {
|
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should toggle the active state of the datepicker toggle": {
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
"error": "Error: this._portalOutlet is undefined.",
|
||||||
"notes": "Unknown"
|
"notes": "FW-1019: Design new API to replace static queries"
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with custom mat-datepicker-toggle icon should be able to override the mat-datepicker-toggle icon": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with tabindex on mat-datepicker-toggle should forward the tabindex to the underlying button": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with tabindex on mat-datepicker-toggle should clear the tabindex from the mat-datepicker-toggle host": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with tabindex on mat-datepicker-toggle should forward focus to the underlying button when the host is focused": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
},
|
||||||
"MatDatepicker with MatNativeDateModule datepicker inside mat-form-field should pass the form field theme color to the overlay": {
|
"MatDatepicker with MatNativeDateModule datepicker inside mat-form-field should pass the form field theme color to the overlay": {
|
||||||
"error": "TypeError: Cannot read property 'classList' of null",
|
"error": "TypeError: Cannot read property 'classList' of null",
|
||||||
|
@ -809,37 +745,9 @@ window.testBlocklist = {
|
||||||
"error": "TypeError: Cannot read property 'classList' of null",
|
"error": "TypeError: Cannot read property 'classList' of null",
|
||||||
"notes": "Unknown"
|
"notes": "Unknown"
|
||||||
},
|
},
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should use min and max dates specified by the input": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should mark invalid when value is before min": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should mark invalid when value is after max": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should not mark invalid when value equals min": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should not mark invalid when value equals max": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should not mark invalid when value is between min and max": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with filter and validation should mark input invalid": {
|
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatDatepicker with MatNativeDateModule datepicker with filter and validation should disable filtered calendar cells": {
|
"MatDatepicker with MatNativeDateModule datepicker with filter and validation should disable filtered calendar cells": {
|
||||||
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
|
"error": "Error: this._portalOutlet is undefined.",
|
||||||
"notes": "Unknown"
|
"notes": "FW-1019: Design new API to replace static queries"
|
||||||
},
|
},
|
||||||
"MatDialog should set the proper animation states": {
|
"MatDialog should set the proper animation states": {
|
||||||
"error": "TypeError: Cannot read property 'componentInstance' of null",
|
"error": "TypeError: Cannot read property 'componentInstance' of null",
|
||||||
|
|
Loading…
Reference in New Issue