feat(ivy): render flags support in host bindings function (FW-649) (#27204)
PR Close #27204
This commit is contained in:

committed by
Misko Hevery

parent
bf71b107b3
commit
dc300c5c41
@ -145,8 +145,10 @@ describe('compiler compliance: bindings', () => {
|
||||
type: HostBindingDir,
|
||||
selectors: [["", "hostBindingDir", ""]],
|
||||
factory: function HostBindingDir_Factory(t) { return new (t || HostBindingDir)(); },
|
||||
hostBindings: function HostBindingDir_HostBindings(dirIndex, elIndex) {
|
||||
$r3$.ɵelementProperty(elIndex, "id", $r3$.ɵbind($r3$.ɵload(dirIndex).dirId));
|
||||
hostBindings: function HostBindingDir_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementProperty(elIndex, "id", $r3$.ɵbind(ctx.dirId));
|
||||
}
|
||||
},
|
||||
hostVars: 1
|
||||
});
|
||||
@ -188,8 +190,10 @@ describe('compiler compliance: bindings', () => {
|
||||
type: HostBindingComp,
|
||||
selectors: [["host-binding-comp"]],
|
||||
factory: function HostBindingComp_Factory(t) { return new (t || HostBindingComp)(); },
|
||||
hostBindings: function HostBindingComp_HostBindings(dirIndex, elIndex) {
|
||||
$r3$.ɵelementProperty(elIndex, "id", $r3$.ɵbind($r3$.ɵpureFunction1(1, $ff$, $r3$.ɵload(dirIndex).id)));
|
||||
hostBindings: function HostBindingComp_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementProperty(elIndex, "id", $r3$.ɵbind($r3$.ɵpureFunction1(1, $ff$, ctx.id)));
|
||||
}
|
||||
},
|
||||
hostVars: 3,
|
||||
consts: 0,
|
||||
@ -232,8 +236,10 @@ describe('compiler compliance: bindings', () => {
|
||||
type: HostAttributeDir,
|
||||
selectors: [["", "hostAttributeDir", ""]],
|
||||
factory: function HostAttributeDir_Factory(t) { return new (t || HostAttributeDir)(); },
|
||||
hostBindings: function HostAttributeDir_HostBindings(dirIndex, elIndex) {
|
||||
$r3$.ɵelementAttribute(elIndex, "required", $r3$.ɵbind($r3$.ɵload(dirIndex).required));
|
||||
hostBindings: function HostAttributeDir_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementAttribute(elIndex, "required", $r3$.ɵbind(ctx.required));
|
||||
}
|
||||
},
|
||||
hostVars: 1
|
||||
});
|
||||
|
@ -771,12 +771,16 @@ describe('compiler compliance: styling', () => {
|
||||
const _c0 = ["foo", "baz", ${InitialStylingFlags.VALUES_MODE}, "foo", true, "baz", true];
|
||||
const _c1 = ["width", "height", "color", ${InitialStylingFlags.VALUES_MODE}, "width", "200px", "height", "500px"];
|
||||
…
|
||||
hostBindings: function MyComponent_HostBindings(dirIndex, elIndex) {
|
||||
$r3$.ɵelementStyling(_c0, _c1, $r3$.ɵdefaultStyleSanitizer, dirIndex);
|
||||
$r3$.ɵelementStylingMap(elIndex, $r3$.ɵload(dirIndex).myClass, $r3$.ɵload(dirIndex).myStyle, dirIndex);
|
||||
$r3$.ɵelementStyleProp(elIndex, 2, $r3$.ɵload(dirIndex).myColorProp, null, dirIndex);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, $r3$.ɵload(dirIndex).myFooClass, dirIndex);
|
||||
$r3$.ɵelementStylingApply(elIndex, dirIndex);
|
||||
hostBindings: function MyComponent_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵelementStyling(_c0, _c1, $r3$.ɵdefaultStyleSanitizer, ctx);
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementStylingMap(elIndex, ctx.myClass, ctx.myStyle, ctx);
|
||||
$r3$.ɵelementStyleProp(elIndex, 2, ctx.myColorProp, null, ctx);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, ctx.myFooClass, ctx);
|
||||
$r3$.ɵelementStylingApply(elIndex, ctx);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -825,14 +829,18 @@ describe('compiler compliance: styling', () => {
|
||||
const _c0 = ["bar", "foo"];
|
||||
const _c1 = ["height", "width"];
|
||||
…
|
||||
hostBindings: function MyComponent_HostBindings(dirIndex, elIndex) {
|
||||
$r3$.ɵelementStyling(_c0, _c1, $r3$.ɵdefaultStyleSanitizer, dirIndex);
|
||||
$r3$.ɵelementStylingMap(elIndex, $r3$.ɵload(dirIndex).myClasses, $r3$.ɵload(dirIndex).myStyle, dirIndex);
|
||||
$r3$.ɵelementStyleProp(elIndex, 0, $r3$.ɵload(dirIndex).myHeightProp, "pt", dirIndex);
|
||||
$r3$.ɵelementStyleProp(elIndex, 1, $r3$.ɵload(dirIndex).myWidthProp, null, dirIndex);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, $r3$.ɵload(dirIndex).myBarClass, dirIndex);
|
||||
$r3$.ɵelementClassProp(elIndex, 1, $r3$.ɵload(dirIndex).myFooClass, dirIndex);
|
||||
$r3$.ɵelementStylingApply(elIndex, dirIndex);
|
||||
hostBindings: function MyComponent_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵelementStyling(_c0, _c1, $r3$.ɵdefaultStyleSanitizer, ctx);
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementStylingMap(elIndex, ctx.myClasses, ctx.myStyle, ctx);
|
||||
$r3$.ɵelementStyleProp(elIndex, 0, ctx.myHeightProp, "pt", ctx);
|
||||
$r3$.ɵelementStyleProp(elIndex, 1, ctx.myWidthProp, null, ctx);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, ctx.myBarClass, ctx);
|
||||
$r3$.ɵelementClassProp(elIndex, 1, ctx.myFooClass, ctx);
|
||||
$r3$.ɵelementStylingApply(elIndex, ctx);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -886,18 +894,26 @@ describe('compiler compliance: styling', () => {
|
||||
const _c2 = ["bar"];
|
||||
const _c3 = ["height"];
|
||||
…
|
||||
function WidthDirective_HostBindings(dirIndex, elIndex) {
|
||||
$r3$.ɵelementStyling(_c0, _c1, null, dirIndex);
|
||||
$r3$.ɵelementStyleProp(elIndex, 0, $r3$.ɵload(dirIndex).myWidth, null, dirIndex);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, $r3$.ɵload(dirIndex).myFooClass, dirIndex);
|
||||
$r3$.ɵelementStylingApply(elIndex, dirIndex);
|
||||
function WidthDirective_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵelementStyling(_c0, _c1, null, ctx);
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementStyleProp(elIndex, 0, ctx.myWidth, null, ctx);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, ctx.myFooClass, ctx);
|
||||
$r3$.ɵelementStylingApply(elIndex, ctx);
|
||||
}
|
||||
}
|
||||
…
|
||||
function HeightDirective_HostBindings(dirIndex, elIndex) {
|
||||
$r3$.ɵelementStyling(_c2, _c3, null, dirIndex);
|
||||
$r3$.ɵelementStyleProp(elIndex, 0, $r3$.ɵload(dirIndex).myHeight, null, dirIndex);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, $r3$.ɵload(dirIndex).myBarClass, dirIndex);
|
||||
$r3$.ɵelementStylingApply(elIndex, dirIndex);
|
||||
function HeightDirective_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵelementStyling(_c2, _c3, null, ctx);
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementStyleProp(elIndex, 0, ctx.myHeight, null, ctx);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, ctx.myBarClass, ctx);
|
||||
$r3$.ɵelementStylingApply(elIndex, ctx);
|
||||
}
|
||||
}
|
||||
…
|
||||
`;
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
import {NgtscTestEnvironment} from './env';
|
||||
|
||||
const trim = (input: string): string => input.replace(/\s+/g, ' ').trim();
|
||||
|
||||
describe('ngtsc behavioral tests', () => {
|
||||
if (!NgtscTestEnvironment.supported) {
|
||||
// These tests should be excluded from the non-Bazel build.
|
||||
@ -449,6 +451,37 @@ describe('ngtsc behavioral tests', () => {
|
||||
expect(jsContents).toContain(`i0.ɵquery(null, ViewContainerRef, true)`);
|
||||
});
|
||||
|
||||
it('should generate host listeners for components', () => {
|
||||
env.tsconfig();
|
||||
env.write(`test.ts`, `
|
||||
import {Component, HostListener} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'test',
|
||||
template: 'Test'
|
||||
})
|
||||
class FooCmp {
|
||||
@HostListener('document:click', ['$event.target'])
|
||||
onClick(eventTarget: HTMLElement): void {}
|
||||
|
||||
@HostListener('window:scroll')
|
||||
onScroll(event: any): void {}
|
||||
}
|
||||
`);
|
||||
|
||||
env.driveMain();
|
||||
const jsContents = env.getContents('test.js');
|
||||
const hostBindingsFn = `
|
||||
hostBindings: function FooCmp_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
i0.ɵlistener("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onClick($event.target); });
|
||||
i0.ɵlistener("scroll", function FooCmp_scroll_HostBindingHandler($event) { return ctx.onScroll(); });
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(trim(jsContents)).toContain(trim(hostBindingsFn));
|
||||
});
|
||||
|
||||
it('should generate host bindings for directives', () => {
|
||||
env.tsconfig();
|
||||
env.write(`test.ts`, `
|
||||
@ -476,39 +509,33 @@ describe('ngtsc behavioral tests', () => {
|
||||
|
||||
env.driveMain();
|
||||
const jsContents = env.getContents('test.js');
|
||||
expect(jsContents)
|
||||
.toContain(`i0.ɵelementAttribute(elIndex, "hello", i0.ɵbind(i0.ɵload(dirIndex).foo));`);
|
||||
expect(jsContents)
|
||||
.toContain(`i0.ɵelementProperty(elIndex, "prop", i0.ɵbind(i0.ɵload(dirIndex).bar));`);
|
||||
expect(jsContents)
|
||||
.toContain('i0.ɵelementClassProp(elIndex, 0, i0.ɵload(dirIndex).someClass, dirIndex)');
|
||||
|
||||
const factoryDef = `
|
||||
factory: function FooCmp_Factory(t) {
|
||||
var f = new (t || FooCmp)();
|
||||
i0.ɵlistener("click", function FooCmp_click_HostBindingHandler($event) {
|
||||
return f.onClick($event);
|
||||
});
|
||||
i0.ɵlistener("change", function FooCmp_change_HostBindingHandler($event) {
|
||||
return f.onChange(f.arg1, f.arg2, f.arg3);
|
||||
});
|
||||
return f;
|
||||
const hostBindingsFn = `
|
||||
hostBindings: function FooCmp_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
i0.ɵlistener("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onClick($event); });
|
||||
i0.ɵlistener("change", function FooCmp_change_HostBindingHandler($event) { return ctx.onChange(ctx.arg1, ctx.arg2, ctx.arg3); });
|
||||
i0.ɵelementStyling(_c0, null, null, ctx);
|
||||
}
|
||||
if (rf & 2) {
|
||||
i0.ɵelementAttribute(elIndex, "hello", i0.ɵbind(ctx.foo));
|
||||
i0.ɵelementProperty(elIndex, "prop", i0.ɵbind(ctx.bar));
|
||||
i0.ɵelementClassProp(elIndex, 0, ctx.someClass, ctx);
|
||||
i0.ɵelementStylingApply(elIndex, ctx);
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(jsContents).toContain(factoryDef.replace(/\s+/g, ' ').trim());
|
||||
expect(trim(jsContents)).toContain(trim(hostBindingsFn));
|
||||
});
|
||||
|
||||
it('should generate host listeners for directives with base factories', () => {
|
||||
it('should generate host listeners for directives within hostBindings section', () => {
|
||||
env.tsconfig();
|
||||
env.write(`test.ts`, `
|
||||
import {Directive, HostListener} from '@angular/core';
|
||||
|
||||
class Base {}
|
||||
|
||||
@Directive({
|
||||
selector: '[test]',
|
||||
})
|
||||
class Dir extends Base {
|
||||
class Dir {
|
||||
@HostListener('change', ['arg'])
|
||||
onChange(event: any, arg: any): void {}
|
||||
}
|
||||
@ -516,17 +543,14 @@ describe('ngtsc behavioral tests', () => {
|
||||
|
||||
env.driveMain();
|
||||
const jsContents = env.getContents('test.js');
|
||||
const factoryDef = `
|
||||
factory: function Dir_Factory(t) {
|
||||
var f = ɵDir_BaseFactory((t || Dir));
|
||||
i0.ɵlistener("change", function Dir_change_HostBindingHandler($event) {
|
||||
return f.onChange(f.arg);
|
||||
});
|
||||
return f;
|
||||
const hostBindingsFn = `
|
||||
hostBindings: function Dir_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
i0.ɵlistener("change", function Dir_change_HostBindingHandler($event) { return ctx.onChange(ctx.arg); });
|
||||
}
|
||||
}
|
||||
`;
|
||||
expect(jsContents).toContain(factoryDef.replace(/\s+/g, ' ').trim());
|
||||
expect(jsContents).toContain('var ɵDir_BaseFactory = i0.ɵgetInheritedFactory(Dir)');
|
||||
expect(trim(jsContents)).toContain(trim(hostBindingsFn));
|
||||
});
|
||||
|
||||
it('should correctly recognize local symbols', () => {
|
||||
|
Reference in New Issue
Block a user