Visitar URL original
perf(compiler): do not emit tag name when control flow root is foreig… · angular/angular@2e442f7 · GitHub
Skip to content

Commit 2e442f7

Browse files
leonsenftmattrbeck
authored andcommitted
perf(compiler): do not emit tag name when control flow root is foreign component (#69674)
When a control flow block (`@if`, `@switch`, `@for`) contains a single root element that is a foreign component, do not treat its name as a tag name for the template container (`conditionalCreate`, `repeaterCreate`). PR Close #69674
1 parent e3ac727 commit 2e442f7

3 files changed

Lines changed: 55 additions & 11 deletions

File tree

‎packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/standalone/foreign_component.js‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ function TestCmpRenderProps_Items_0_Template(rf, ctx) {
3636
}
3737
}
3838

39+
function TestCmpConditional_Conditional_0_Template(rf, ctx) {
40+
if (rf & 1) {
41+
i0.ɵɵforeignComponent(0, 0);
42+
}
43+
}
44+
3945
…
4046

4147
export class TestCmp {
@@ -95,3 +101,26 @@ export class TestCmpRenderProps {
95101
});
96102
}
97103

104+
…
105+
106+
export class TestCmpConditional {
107+
// ...
108+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({
109+
type: TestCmpConditional,
110+
selectors: [["main-conditional"]],
111+
decls: 1,
112+
vars: 1,
113+
consts: [frameworkImport(FancyButton)],
114+
template: function TestCmpConditional_Template(rf, ctx) {
115+
if (rf & 1) {
116+
i0.ɵɵconditionalCreate(0, TestCmpConditional_Conditional_0_Template, 1, 0);
117+
}
118+
if (rf & 2) {
119+
i0.ɵɵconditional(ctx.condition ? 0 : -1);
120+
}
121+
},
122+
encapsulation: 2
123+
});
124+
}
125+
126+

‎packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/standalone/foreign_component.ts‎

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,20 @@ import {Component} from '@angular/core';
22

33
export function FancyButton() {}
44

5-
// @angular/core does not expose the `ForeignComponent` type this should return.
5+
// @angular/core does not expose the `ForeignComponent` type this should return.
66
function frameworkImport(component: {}): Function {
77
return () => {};
88
}
99

1010
@Component({
1111
selector: 'main',
1212
template: `
13-
<FancyButton
14-
class="btn-cls"
15-
unsafe-attr="value"
16-
[label]="title"
17-
[unsafe-input]="title"
18-
/>
13+
<FancyButton class="btn-cls" unsafe-attr="value" [label]="title" [unsafe-input]="title" />
1914
`,
2015
// @ts-ignore: @angular/core does not expose the `foreignImports` property.
2116
foreignImports: [
2217
// @ts-ignore: @angular/core does not expose the `ForeignComponent` type this expects.
23-
frameworkImport(FancyButton)
18+
frameworkImport(FancyButton),
2419
],
2520
})
2621
export class TestCmp {
@@ -43,7 +38,7 @@ export class TestCmp {
4338
// @ts-ignore: @angular/core does not expose the `foreignImports` property.
4439
foreignImports: [
4540
// @ts-ignore: @angular/core does not expose the `ForeignComponent` type this expects.
46-
frameworkImport(FancyButton)
41+
frameworkImport(FancyButton),
4742
],
4843
})
4944
export class TestCmpChildren {
@@ -62,10 +57,27 @@ export class TestCmpChildren {
6257
// @ts-ignore: @angular/core does not expose the `foreignImports` property.
6358
foreignImports: [
6459
// @ts-ignore: @angular/core does not expose the `ForeignComponent` type this expects.
65-
frameworkImport(FancyButton)
60+
frameworkImport(FancyButton),
6661
],
6762
})
6863
export class TestCmpRenderProps {
6964
title = 'Submit';
7065
}
7166

67+
@Component({
68+
selector: 'main-conditional',
69+
template: `
70+
@if (condition) {
71+
<FancyButton />
72+
}
73+
`,
74+
// @ts-ignore: @angular/core does not expose the `foreignImports` property.
75+
foreignImports: [
76+
// @ts-ignore: @angular/core does not expose the `ForeignComponent` type this expects.
77+
frameworkImport(FancyButton),
78+
],
79+
})
80+
export class TestCmpConditional {
81+
title = 'Submit';
82+
condition = true;
83+
}

‎packages/compiler/src/template/pipeline/src/ingest.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,10 @@ function ingestControlFlowInsertionPoint(
19611961
}
19621962

19631963
// Root nodes can only elements or templates with a tag name (e.g. `<div *foo></div>`).
1964-
if (child instanceof t.Element || (child instanceof t.Template && child.tagName !== null)) {
1964+
if (
1965+
(child instanceof t.Element && unit.job.getForeignComponent(child) === null) ||
1966+
(child instanceof t.Template && child.tagName !== null)
1967+
) {
19651968
root = child;
19661969
} else {
19671970
return null;

0 commit comments

Comments
 (0)