From dfbf6d72b059258493826ded51481563a37d6e69 Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Wed, 12 Dec 2018 15:23:12 -0800 Subject: [PATCH] fix(ivy): provide an ability to match tags (#27636) Prior to this change, we were unable to match directives using `ng-template` tags (for example the following selector would not work even though there might be some s in a template: `ng-template[directiveA]`. As a result, that broke some components that relies on such selectors to work. In order to resolve the problem, we now pass tag name to the `template` instruction (where we passed `null` before) and this tag name is used for matching at runtime. This update should also help support projecting containers, because the tag name is required to properly match such elements. PR Close #27636 --- .../compliance/r3_compiler_compliance_spec.ts | 36 +++--- .../r3_view_compiler_directives_spec.ts | 120 +++++++++++++++++- .../compliance/r3_view_compiler_i18n_spec.ts | 64 +++++----- .../r3_view_compiler_listener_spec.ts | 2 +- .../r3_view_compiler_template_spec.ts | 30 ++--- packages/compiler/src/render3/r3_ast.ts | 6 +- .../src/render3/r3_template_transform.ts | 9 +- .../compiler/src/render3/view/template.ts | 12 +- packages/core/src/render3/instructions.ts | 10 +- .../core/src/render3/node_selector_matcher.ts | 36 +++++- .../bundling/todo/bundle.golden_symbols.json | 6 + .../test/render3/change_detection_spec.ts | 2 +- .../test/render3/common_integration_spec.ts | 57 +++++---- packages/core/test/render3/component_spec.ts | 6 +- packages/core/test/render3/content_spec.ts | 4 +- packages/core/test/render3/di_spec.ts | 20 +-- packages/core/test/render3/directive_spec.ts | 109 +++++++++++++++- .../core/test/render3/discovery_utils_spec.ts | 2 +- packages/core/test/render3/exports_spec.ts | 4 +- .../core/test/render3/host_binding_spec.ts | 2 +- packages/core/test/render3/i18n_spec.ts | 4 +- .../core/test/render3/instructions_spec.ts | 4 +- .../core/test/render3/integration_spec.ts | 19 ++- packages/core/test/render3/lifecycle_spec.ts | 7 +- .../render3/node_selector_matcher_spec.ts | 4 +- .../core/test/render3/pure_function_spec.ts | 2 +- packages/core/test/render3/query_spec.ts | 49 ++++--- .../core/test/render3/template_ref_spec.ts | 10 +- .../test/render3/view_container_ref_spec.ts | 57 ++++++--- 29 files changed, 488 insertions(+), 205 deletions(-) diff --git a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts index 154cf18dbe..f0edc25f51 100644 --- a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts @@ -11,9 +11,10 @@ import {setup} from '@angular/compiler/test/aot/test_util'; import {compile, expectEmit} from './mock_compile'; -/* These tests are codified version of the tests in compiler_canonical_spec.ts. Every - * test in compiler_canonical_spec.ts should have a corresponding test here. - */ +/** + * These tests are codified version of the tests in compiler_canonical_spec.ts. Every + * test in compiler_canonical_spec.ts should have a corresponding test here. + */ describe('compiler compliance', () => { const angularFiles = setup({ @@ -794,7 +795,7 @@ describe('compiler compliance', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵelementStart(0, "ul", null, $c1$); - $r3$.ɵtemplate(2, MyComponent_li_Template_2, 2, 2, null, $c2$); + $r3$.ɵtemplate(2, MyComponent_li_Template_2, 2, 2, "li", $c2$); $r3$.ɵelementEnd(); } }, @@ -1218,7 +1219,7 @@ describe('compiler compliance', () => { $r3$.ɵelementEnd(); } } - function Template_2(rf, ctx) { + function Cmp_ng_template_Template_2(rf, ctx) { if (rf & 1) { $r3$.ɵprojectionDef(); $r3$.ɵtext(0, " '*' selector: "); @@ -1228,9 +1229,9 @@ describe('compiler compliance', () => { … template: function Cmp_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, Cmp_div_Template_0, 2, 0, null, $_c0$); - $r3$.ɵtemplate(1, Cmp_div_Template_1, 2, 0, null, $_c0$); - $r3$.ɵtemplate(2, Template_2, 2, 0); + $r3$.ɵtemplate(0, Cmp_div_Template_0, 2, 0, "div", $_c0$); + $r3$.ɵtemplate(1, Cmp_div_Template_1, 2, 0, "div", $_c0$); + $r3$.ɵtemplate(2, Cmp_ng_template_Template_2, 2, 0, "ng-template"); } if (rf & 2) { $r3$.ɵelementProperty(0, "ngIf", $r3$.ɵbind(ctx.visible)); @@ -1867,7 +1868,7 @@ describe('compiler compliance', () => { if (rf & 1) { $r3$.ɵelementStart(0, "div"); $r3$.ɵtext(1); - $r3$.ɵtemplate(2, MyComponent_div_span_Template_2, 2, 3, null, $c2$); + $r3$.ɵtemplate(2, MyComponent_div_span_Template_2, 2, 3, "span", $c2$); $r3$.ɵelement(3, "span", null, $c4$); $r3$.ɵelementEnd(); } @@ -1889,7 +1890,7 @@ describe('compiler compliance', () => { if (rf & 1) { $r3$.ɵelement(0, "div", null, $c1$); $r3$.ɵtext(2); - $r3$.ɵtemplate(3, MyComponent_div_Template_3, 5, 2, null, $c2$); + $r3$.ɵtemplate(3, MyComponent_div_Template_3, 5, 2, "div", $c2$); $r3$.ɵelement(4, "div", null, $c3$); } if (rf & 2) { @@ -1954,7 +1955,7 @@ describe('compiler compliance', () => { if (rf & 1) { $i0$.ɵelementStart(0, "div"); $i0$.ɵelement(1, "div", null, $c1$); - $i0$.ɵtemplate(3, MyComponent_div_span_Template_3, 2, 2, null, $c2$); + $i0$.ɵtemplate(3, MyComponent_div_span_Template_3, 2, 2, "span", $c2$); $i0$.ɵelementEnd(); } if (rf & 2) { @@ -1966,7 +1967,7 @@ describe('compiler compliance', () => { // ... template:function MyComponent_Template(rf, ctx){ if (rf & 1) { - $i0$.ɵtemplate(0, MyComponent_div_Template_0, 4, 1, null, $c0$); + $i0$.ɵtemplate(0, MyComponent_div_Template_0, 4, 1, "div", $c0$); } if (rf & 2) { $i0$.ɵelementProperty(0, "ngForOf", $i0$.ɵbind(ctx.items)); @@ -2119,6 +2120,9 @@ describe('compiler compliance', () => { } }; + // TODO(akushnir): tag name generated for element inside is incorrect. + // It's generated as ":svg:g", when it should be just "g". Potentially related to + // the issue described in FW-672. it('should support embedded views in the SVG namespace', () => { const files = { app: { @@ -2177,7 +2181,7 @@ describe('compiler compliance', () => { if (rf & 1) { $r3$.ɵnamespaceSVG(); $r3$.ɵelementStart(0,"svg"); - $r3$.ɵtemplate(1, MyComponent__svg_g_Template_1, 2, 0, null, $t1_attrs$); + $r3$.ɵtemplate(1, MyComponent__svg_g_Template_1, 2, 0, ":svg:g", $t1_attrs$); $r3$.ɵelementEnd(); } if (rf & 2) { $r3$.ɵelementProperty(1,"forOf",$r3$.ɵbind(ctx.items)); } @@ -2255,7 +2259,7 @@ describe('compiler compliance', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵelementStart(0, "ul"); - $r3$.ɵtemplate(1, MyComponent_li_Template_1, 2, 1, null, $t1_attrs$); + $r3$.ɵtemplate(1, MyComponent_li_Template_1, 2, 1, "li", $t1_attrs$); $r3$.ɵelementEnd(); } if (rf & 2) { @@ -2334,7 +2338,7 @@ describe('compiler compliance', () => { $r3$.ɵtext(2); $r3$.ɵelementEnd(); $r3$.ɵelementStart(3, "ul"); - $r3$.ɵtemplate(4, MyComponent_li_li_Template_4, 2, 2, null, $t4_attrs$); + $r3$.ɵtemplate(4, MyComponent_li_li_Template_4, 2, 2, "li", $t4_attrs$); $r3$.ɵelementEnd(); $r3$.ɵelementEnd(); } @@ -2355,7 +2359,7 @@ describe('compiler compliance', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵelementStart(0, "ul"); - $r3$.ɵtemplate(1, MyComponent_li_Template_1, 5, 2, null, $c1$); + $r3$.ɵtemplate(1, MyComponent_li_Template_1, 5, 2, "li", $c1$); $r3$.ɵelementEnd(); } if (rf & 2) { diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts index 5118dfdbd1..055f50be49 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts @@ -23,7 +23,7 @@ describe('compiler compliance: directives', () => { const files = { app: { 'spec.ts': ` - import {Component, Directive, Input, NgModule} from '@angular/core'; + import {Component, Directive, NgModule} from '@angular/core'; @Directive({selector: '[i18n]'}) export class I18nDirective {} @@ -63,7 +63,7 @@ describe('compiler compliance: directives', () => { const files = { app: { 'spec.ts': ` - import {Component, Directive, Input, NgModule} from '@angular/core'; + import {Component, Directive, NgModule} from '@angular/core'; @Directive({selector: '[i18n]'}) export class I18nDirective {} @@ -154,6 +154,118 @@ describe('compiler compliance: directives', () => { expectEmit(source, MyComponentDefinition, 'Incorrect ChildComponent.ngComponentDef'); }); + it('should match directives on ng-templates', () => { + const files = { + app: { + 'spec.ts': ` + import {Component, Directive, NgModule, TemplateRef} from '@angular/core'; + + @Directive({ + selector: 'ng-template[directiveA]' + }) + export class DirectiveA { + constructor(public templateRef: TemplateRef) {} + } + + @Component({ + selector: 'my-component', + template: \` + Some content + \` + }) + export class MyComponent {} + + @NgModule({declarations: [DirectiveA, MyComponent]}) + export class MyModule{} + ` + } + }; + + const MyComponentDefinition = ` + … + const $_c0$ = ["directiveA", ""]; + function MyComponent_ng_template_Template_0(rf, ctx) { + if (rf & 1) { + $r3$.ɵtext(0, "Some content"); + } + } + … + MyComponent.ngComponentDef = $r3$.ɵdefineComponent({ + … + template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵtemplate(0, MyComponent_ng_template_Template_0, 1, 0, "ng-template", $_c0$); + } + }, + … + directives: [DirectiveA], + … + }); + `; + + const result = compile(files, angularFiles); + expectEmit(result.source, MyComponentDefinition, 'Incorrect ChildComponent.ngComponentDef'); + }); + + it('should match directives on ng-container', () => { + const files = { + app: { + 'spec.ts': ` + import {Component, Directive, NgModule, TemplateRef} from '@angular/core'; + + @Directive({ + selector: 'ng-container[directiveA]' + }) + export class DirectiveA { + constructor(public templateRef: TemplateRef) {} + } + + @Component({ + selector: 'my-component', + template: \` + Some content + \` + }) + export class MyComponent {} + + @NgModule({declarations: [DirectiveA, MyComponent]}) + export class MyModule{} + ` + } + }; + + const MyComponentDefinition = ` + … + const $_c0$ = [1, "ngIf"]; + const $_c1$ = ["directiveA", ""]; + function MyComponent_ng_container_Template_0(rf, ctx) { + if (rf & 1) { + $r3$.ɵelementContainerStart(0, $_c1$); + $r3$.ɵtext(1, "Some content"); + $r3$.ɵelementContainerEnd(); + } + } + … + MyComponent.ngComponentDef = $r3$.ɵdefineComponent({ + … + template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵtemplate(0, MyComponent_ng_container_Template_0, 2, 0, "ng-container", $_c0$); + } + if (rf & 2) { + $r3$.ɵelementProperty(0, "ngIf", $r3$.ɵbind(ctx.showing)); + } + }, + … + directives: [DirectiveA], + … + }); + `; + + const result = compile(files, angularFiles); + expectEmit(result.source, MyComponentDefinition, 'Incorrect ChildComponent.ngComponentDef'); + }); + it('should match directives on ng-template bindings', () => { const files = { @@ -185,7 +297,7 @@ describe('compiler compliance: directives', () => { … template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, Template_0, 0, 0, null, $c0_a0$); + $r3$.ɵtemplate(0, MyComponent_ng_template_Template_0, 0, 0, "ng-template", $c0_a0$); } if (rf & 2) { $r3$.ɵelementProperty(0, "someDirective", $r3$.ɵbind(true)); @@ -233,7 +345,7 @@ describe('compiler compliance: directives', () => { … template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, MyComponent_div_Template_0, 1, 0, null, $c0_a0$); + $r3$.ɵtemplate(0, MyComponent_div_Template_0, 1, 0, "div", $c0_a0$); } }, … diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts index 37338d89c9..03afb5932b 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts @@ -422,7 +422,7 @@ describe('i18n support in the view compiler', () => { vars: 1, template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, MyComponent_div_Template_0, 4, 3, null, $_c0$); + $r3$.ɵtemplate(0, MyComponent_div_Template_0, 4, 3, "div", $_c0$); } if (rf & 2) { $r3$.ɵelementProperty(0, "ngForOf", $r3$.ɵbind(ctx.items)); @@ -551,7 +551,7 @@ describe('i18n support in the view compiler', () => { vars: 1, template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, MyComponent_div_Template_0, 4, 3, null, $_c0$); + $r3$.ɵtemplate(0, MyComponent_div_Template_0, 4, 3, "div", $_c0$); } if (rf & 2) { $r3$.ɵelementProperty(0, "ngForOf", $r3$.ɵbind(ctx.items)); @@ -955,7 +955,7 @@ describe('i18n support in the view compiler', () => { if (rf & 1) { $r3$.ɵelementStart(0, "div"); $r3$.ɵtext(1, " Some content "); - $r3$.ɵtemplate(2, MyComponent_div_Template_2, 5, 4, null, $_c0$); + $r3$.ɵtemplate(2, MyComponent_div_Template_2, 5, 4, "div", $_c0$); $r3$.ɵelementEnd(); } if (rf & 2) { @@ -1004,8 +1004,8 @@ describe('i18n support in the view compiler', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵelement(0, "img", $_c0$); - $r3$.ɵtemplate(1, MyComponent_img_Template_1, 1, 0, null, $_c1$); - $r3$.ɵtemplate(2, MyComponent_img_Template_2, 2, 1, null, $_c1$); + $r3$.ɵtemplate(1, MyComponent_img_Template_1, 1, 0, "img", $_c1$); + $r3$.ɵtemplate(2, MyComponent_img_Template_2, 2, 1, "img", $_c1$); } if (rf & 2) { $r3$.ɵelementProperty(1, "ngIf", $r3$.ɵbind(ctx.visible)); @@ -1065,7 +1065,7 @@ describe('i18n support in the view compiler', () => { $r3$.ɵelementStart(1, "div"); $r3$.ɵelementStart(2, "div"); $r3$.ɵpipe(3, "uppercase"); - $r3$.ɵtemplate(4, MyComponent_div_div_Template_4, 3, 2, null, $_c1$); + $r3$.ɵtemplate(4, MyComponent_div_div_Template_4, 3, 2, "div", $_c1$); $r3$.ɵelementEnd(); $r3$.ɵelementEnd(); $r3$.ɵi18nEnd(); @@ -1115,8 +1115,8 @@ describe('i18n support in the view compiler', () => { if (rf & 1) { $r3$.ɵelementStart(0, "div"); $r3$.ɵi18nStart(1, $I18N_EXTERNAL_1221890473527419724$$APP_SPEC_TS_0$); - $r3$.ɵtemplate(2, MyComponent_div_Template_2, 5, 5, null, $_c1$); - $r3$.ɵtemplate(3, MyComponent_div_Template_3, 4, 4, null, $_c1$); + $r3$.ɵtemplate(2, MyComponent_div_Template_2, 5, 5, "div", $_c1$); + $r3$.ɵtemplate(3, MyComponent_div_Template_3, 4, 4, "div", $_c1$); $r3$.ɵi18nEnd(); $r3$.ɵelementEnd(); } @@ -1162,7 +1162,7 @@ describe('i18n support in the view compiler', () => { vars: 1, template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, MyComponent_div_Template_0, 3, 1, null, $_c0$); + $r3$.ɵtemplate(0, MyComponent_div_Template_0, 3, 1, "div", $_c0$); } if (rf & 2) { $r3$.ɵelementProperty(0, "ngIf", $r3$.ɵbind(ctx.visible)); @@ -1233,7 +1233,7 @@ describe('i18n support in the view compiler', () => { const output = String.raw ` const $MSG_EXTERNAL_2413150872298537152$$APP_SPEC_TS_0$ = goog.getMsg("My i18n block #2"); const $MSG_EXTERNAL_4890179241114413722$$APP_SPEC_TS__1$ = goog.getMsg("My i18n block #1"); - function Template_0(rf, ctx) { + function MyComponent_ng_template_Template_0(rf, ctx) { if (rf & 1) { $r3$.ɵi18n(0, $MSG_EXTERNAL_4890179241114413722$$APP_SPEC_TS__1$); } @@ -1241,7 +1241,7 @@ describe('i18n support in the view compiler', () => { … template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, Template_0, 1, 0); + $r3$.ɵtemplate(0, MyComponent_ng_template_Template_0, 1, 0, "ng-template"); $r3$.ɵelementContainerStart(1); $r3$.ɵi18n(2, $MSG_EXTERNAL_2413150872298537152$$APP_SPEC_TS_0$); $r3$.ɵelementContainerEnd(); @@ -1325,7 +1325,7 @@ describe('i18n support in the view compiler', () => { const $MSG_EXTERNAL_355394464191978948$$APP_SPEC_TS__0$ = goog.getMsg("Some content: {$interpolation}", { "interpolation": "\uFFFD0\uFFFD" }); - function Template_0(rf, ctx) { + function MyComponent_ng_template_Template_0(rf, ctx) { if (rf & 1) { $r3$.ɵi18n(0, $MSG_EXTERNAL_355394464191978948$$APP_SPEC_TS__0$); $r3$.ɵpipe(1, "uppercase"); @@ -1340,7 +1340,7 @@ describe('i18n support in the view compiler', () => { vars: 0, template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, Template_0, 2, 3); + $r3$.ɵtemplate(0, MyComponent_ng_template_Template_0, 2, 3, "ng-template"); } } `; @@ -1365,7 +1365,7 @@ describe('i18n support in the view compiler', () => { "closeTagNgContainer": "\uFFFD/#3\uFFFD", "interpolation": "\uFFFD0:1\uFFFD" }); - function Template_2(rf, ctx) { + function MyComponent_ng_template_Template_2(rf, ctx) { if (rf & 1) { $r3$.ɵi18n(0, $MSG_EXTERNAL_702706566400598764$$APP_SPEC_TS_0$, 1); $r3$.ɵpipe(1, "uppercase"); @@ -1383,7 +1383,7 @@ describe('i18n support in the view compiler', () => { if (rf & 1) { $r3$.ɵelementStart(0, "div"); $r3$.ɵi18nStart(1, $MSG_EXTERNAL_702706566400598764$$APP_SPEC_TS_0$); - $r3$.ɵtemplate(2, Template_2, 2, 3); + $r3$.ɵtemplate(2, MyComponent_ng_template_Template_2, 2, 3, "ng-template"); $r3$.ɵelementContainerStart(3); $r3$.ɵpipe(4, "uppercase"); $r3$.ɵelementContainerEnd(); @@ -1415,7 +1415,7 @@ describe('i18n support in the view compiler', () => { const $I18N_EXTERNAL_7842238767399919809$$APP_SPEC_TS__1$ = $r3$.ɵi18nPostprocess($MSG_EXTERNAL_7842238767399919809$$APP_SPEC_TS__1$, { "VAR_SELECT": "\uFFFD0\uFFFD" }); - function Template_0(rf, ctx) { + function MyComponent_ng_template_Template_0(rf, ctx) { if (rf & 1) { $r3$.ɵi18n(0, $I18N_EXTERNAL_7842238767399919809$$APP_SPEC_TS__1$); } @@ -1430,7 +1430,7 @@ describe('i18n support in the view compiler', () => { vars: 1, template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, Template_0, 1, 1); + $r3$.ɵtemplate(0, MyComponent_ng_template_Template_0, 1, 1, "ng-template"); $r3$.ɵelementContainerStart(1); $r3$.ɵi18n(2, $I18N_EXTERNAL_8806993169187953163$$APP_SPEC_TS_0$); $r3$.ɵelementContainerEnd(); @@ -1461,7 +1461,7 @@ describe('i18n support in the view compiler', () => { `; const output = String.raw ` - function Template_1(rf, ctx) { + function MyComponent_ng_template_ng_template_ng_template_Template_1(rf, ctx) { if (rf & 1) { $r3$.ɵi18n(0, $I18N_EXTERNAL_2051477021417799640$$APP_SPEC_TS_0$, 3); } @@ -1471,10 +1471,10 @@ describe('i18n support in the view compiler', () => { $r3$.ɵi18nApply(0); } } - function Template_2(rf, ctx) { + function MyComponent_ng_template_ng_template_Template_2(rf, ctx) { if (rf & 1) { $r3$.ɵi18nStart(0, $I18N_EXTERNAL_2051477021417799640$$APP_SPEC_TS_0$, 2); - $r3$.ɵtemplate(1, Template_1, 1, 1); + $r3$.ɵtemplate(1, MyComponent_ng_template_ng_template_ng_template_Template_1, 1, 1, "ng-template"); $r3$.ɵi18nEnd(); } if (rf & 2) { @@ -1491,11 +1491,11 @@ describe('i18n support in the view compiler', () => { "interpolation_2": "\uFFFD0:3\uFFFD" }); const $I18N_EXTERNAL_2051477021417799640$$APP_SPEC_TS_0$ = $r3$.ɵi18nPostprocess($MSG_EXTERNAL_2051477021417799640$$APP_SPEC_TS_0$); - function Template_2(rf, ctx) { + function MyComponent_ng_template_Template_2(rf, ctx) { if (rf & 1) { $r3$.ɵi18nStart(0, $I18N_EXTERNAL_2051477021417799640$$APP_SPEC_TS_0$, 1); $r3$.ɵpipe(1, "uppercase"); - $r3$.ɵtemplate(2, Template_2, 2, 1); + $r3$.ɵtemplate(2, MyComponent_ng_template_ng_template_Template_2, 2, 1, "ng-template"); $r3$.ɵi18nEnd(); } if (rf & 2) { @@ -1511,7 +1511,7 @@ describe('i18n support in the view compiler', () => { if (rf & 1) { $r3$.ɵelementStart(0, "div"); $r3$.ɵi18nStart(1, $I18N_EXTERNAL_2051477021417799640$$APP_SPEC_TS_0$); - $r3$.ɵtemplate(2, Template_2, 3, 3); + $r3$.ɵtemplate(2, MyComponent_ng_template_Template_2, 3, 3, "ng-template"); $r3$.ɵi18nEnd(); $r3$.ɵelementEnd(); } @@ -1536,7 +1536,7 @@ describe('i18n support in the view compiler', () => { const $I18N_EXTERNAL_8806993169187953163$$APP_SPEC_TS__1$ = $r3$.ɵi18nPostprocess($MSG_EXTERNAL_8806993169187953163$$APP_SPEC_TS__1$, { "VAR_SELECT": "\uFFFD0\uFFFD" }); - function Template_2(rf, ctx) { + function MyComponent_ng_template_Template_2(rf, ctx) { if (rf & 1) { $r3$.ɵi18n(0, $I18N_EXTERNAL_8806993169187953163$$APP_SPEC_TS__1$); } @@ -1554,7 +1554,7 @@ describe('i18n support in the view compiler', () => { $r3$.ɵelementContainerStart(0); $r3$.ɵi18n(1, $I18N_EXTERNAL_7842238767399919809$$APP_SPEC_TS_0$); $r3$.ɵelementContainerEnd(); - $r3$.ɵtemplate(2, Template_2, 1, 1); + $r3$.ɵtemplate(2, MyComponent_ng_template_Template_2, 1, 1, "ng-template"); } if (rf & 2) { $r3$.ɵi18nExp($r3$.ɵbind(ctx.gender)); @@ -1584,7 +1584,7 @@ describe('i18n support in the view compiler', () => { const $MSG_EXTERNAL_461986953980355147$$APP_SPEC_TS__2$ = goog.getMsg("{$tagImg} is my logo #2 ", { "tagImg": "\uFFFD#1\uFFFD\uFFFD/#1\uFFFD" }); - function Template_3(rf, ctx) { + function MyComponent_ng_template_Template_3(rf, ctx) { if (rf & 1) { $r3$.ɵi18nStart(0, $MSG_EXTERNAL_461986953980355147$$APP_SPEC_TS__2$); $r3$.ɵelement(1, "img", $_c0$); @@ -1599,7 +1599,7 @@ describe('i18n support in the view compiler', () => { $r3$.ɵelement(2, "img", $_c0$); $r3$.ɵi18nEnd(); $r3$.ɵelementContainerEnd(); - $r3$.ɵtemplate(3, Template_3, 2, 0); + $r3$.ɵtemplate(3, MyComponent_ng_template_Template_3, 2, 0, "ng-template"); } } `; @@ -1749,8 +1749,8 @@ describe('i18n support in the view compiler', () => { $r3$.ɵelementStart(0, "div"); $r3$.ɵi18n(1, $I18N_EXTERNAL_7842238767399919809$$APP_SPEC_TS_0$); $r3$.ɵelementEnd(); - $r3$.ɵtemplate(2, MyComponent_div_Template_2, 2, 1, null, $_c0$); - $r3$.ɵtemplate(3, MyComponent_div_Template_3, 4, 2, null, $_c0$); + $r3$.ɵtemplate(2, MyComponent_div_Template_2, 2, 1, "div", $_c0$); + $r3$.ɵtemplate(3, MyComponent_div_Template_3, 4, 2, "div", $_c0$); } if (rf & 2) { $r3$.ɵi18nExp($r3$.ɵbind(ctx.gender)); @@ -1976,7 +1976,7 @@ describe('i18n support in the view compiler', () => { $r3$.ɵelementStart(0, "div"); $r3$.ɵi18nStart(1, $I18N_APP_SPEC_TS_0$); $r3$.ɵelement(2, "div"); - $r3$.ɵtemplate(3, MyComponent_div_Template_3, 2, 1, null, $_c3$); + $r3$.ɵtemplate(3, MyComponent_div_Template_3, 2, 1, "div", $_c3$); $r3$.ɵi18nEnd(); $r3$.ɵelementEnd(); } @@ -2080,7 +2080,7 @@ describe('i18n support in the view compiler', () => { if (rf & 1) { $r3$.ɵelementStart(0, "div"); $r3$.ɵi18nStart(1, $MSG_EXTERNAL_1194472282609532229$$APP_SPEC_TS_0$); - $r3$.ɵtemplate(2, MyComponent_span_Template_2, 2, 1, null, $_c2$); + $r3$.ɵtemplate(2, MyComponent_span_Template_2, 2, 1, "span", $_c2$); $r3$.ɵi18nEnd(); $r3$.ɵelementEnd(); } @@ -2146,7 +2146,7 @@ describe('i18n support in the view compiler', () => { if (rf & 1) { $r3$.ɵelementStart(0, "div"); $r3$.ɵi18nStart(1, $MSG_EXTERNAL_7186042105600518133$$APP_SPEC_TS_0$); - $r3$.ɵtemplate(2, MyComponent_span_Template_2, 2, 2, null, $_c2$); + $r3$.ɵtemplate(2, MyComponent_span_Template_2, 2, 2, "span", $_c2$); $r3$.ɵi18nEnd(); $r3$.ɵelementEnd(); } diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts index f053ce6c11..e8c993e387 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts @@ -160,7 +160,7 @@ describe('compiler compliance: listen()', () => { // ... template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵtemplate(0, MyComponent_div_Template_0, 3, 0, null, $c0$); + $r3$.ɵtemplate(0, MyComponent_div_Template_0, 3, 0, "div", $c0$); } if (rf & 2) { $i0$.ɵelementProperty(0, "ngIf", $i0$.ɵbind(ctx.showing)); diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts index 1e3dce804f..d7ebaf48a0 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts @@ -82,7 +82,7 @@ describe('compiler compliance: template', () => { function MyComponent_ul_li_Template_1(rf, ctx) { if (rf & 1) { $i0$.ɵelementStart(0, "li"); - $i0$.ɵtemplate(1, MyComponent_ul_li_div_Template_1, 2, 2, null, _c0); + $i0$.ɵtemplate(1, MyComponent_ul_li_div_Template_1, 2, 2, "div", _c0); $i0$.ɵelementEnd(); } if (rf & 2) { @@ -94,7 +94,7 @@ describe('compiler compliance: template', () => { function MyComponent_ul_Template_0(rf, ctx) { if (rf & 1) { $i0$.ɵelementStart(0, "ul"); - $i0$.ɵtemplate(1, MyComponent_ul_li_Template_1, 2, 1, null, _c0); + $i0$.ɵtemplate(1, MyComponent_ul_li_Template_1, 2, 1, "li", _c0); $i0$.ɵelementEnd(); } if (rf & 2) { @@ -105,7 +105,7 @@ describe('compiler compliance: template', () => { // ... template:function MyComponent_Template(rf, ctx){ if (rf & 1) { - $i0$.ɵtemplate(0, MyComponent_ul_Template_0, 2, 1, null, _c0); + $i0$.ɵtemplate(0, MyComponent_ul_Template_0, 2, 1, "ul", _c0); } if (rf & 2) { $i0$.ɵelementProperty(0, "ngForOf", $i0$.ɵbind(ctx.items)); @@ -156,7 +156,7 @@ describe('compiler compliance: template', () => { // ... template:function MyComponent_Template(rf, ctx){ if (rf & 1) { - $i0$.ɵtemplate(0, MyComponent_span_Template_0, 2, 2, null, _c0); + $i0$.ɵtemplate(0, MyComponent_span_Template_0, 2, 2, "span", _c0); } if (rf & 2) { $i0$.ɵelementProperty(0, "ngForOf", $i0$.ɵbind(ctx.items)); @@ -212,7 +212,7 @@ describe('compiler compliance: template', () => { function MyComponent_div_Template_0(rf, ctx) { if (rf & 1) { $i0$.ɵelementStart(0, "div"); - $i0$.ɵtemplate(1, MyComponent_div_span_Template_1, 2, 2, null, $c1$); + $i0$.ɵtemplate(1, MyComponent_div_span_Template_1, 2, 2, "span", $c1$); $i0$.ɵelementEnd(); } if (rf & 2) { @@ -224,7 +224,7 @@ describe('compiler compliance: template', () => { // ... template:function MyComponent_Template(rf, ctx){ if (rf & 1) { - $i0$.ɵtemplate(0, MyComponent_div_Template_0, 2, 1, null, $c0$); + $i0$.ɵtemplate(0, MyComponent_div_Template_0, 2, 1, "div", $c0$); } if (rf & 2) { $i0$.ɵelementProperty(0, "ngForOf", $i0$.ɵbind(ctx.items)); @@ -280,7 +280,7 @@ describe('compiler compliance: template', () => { function MyComponent_div_div_Template_1(rf, ctx) { if (rf & 1) { $i0$.ɵelementStart(0, "div"); - $i0$.ɵtemplate(1, MyComponent_div_div_div_Template_1, 2, 2, null, _c0); + $i0$.ɵtemplate(1, MyComponent_div_div_div_Template_1, 2, 2, "div", _c0); $i0$.ɵelementEnd(); } if (rf & 2) { @@ -292,7 +292,7 @@ describe('compiler compliance: template', () => { function MyComponent_div_Template_0(rf, ctx) { if (rf & 1) { $i0$.ɵelementStart(0, "div"); - $i0$.ɵtemplate(1, MyComponent_div_div_Template_1, 2, 1, null, _c0); + $i0$.ɵtemplate(1, MyComponent_div_div_Template_1, 2, 1, "div", _c0); $i0$.ɵelementEnd(); } if (rf & 2) { @@ -303,7 +303,7 @@ describe('compiler compliance: template', () => { // ... template:function MyComponent_Template(rf, ctx){ if (rf & 1) { - $i0$.ɵtemplate(0, MyComponent_div_Template_0, 2, 1, null, _c0); + $i0$.ɵtemplate(0, MyComponent_div_Template_0, 2, 1, "div", _c0); } if (rf & 2) { $i0$.ɵelementProperty(0, "ngForOf", $i0$.ɵbind(ctx.items)); @@ -339,7 +339,7 @@ describe('compiler compliance: template', () => { const template = ` const $c0$ = ["attr", "l", ${AttributeMarker.SelectOnly}, "boundAttr"]; - function Template_0(rf, ctx) { + function MyComponent_ng_template_Template_0(rf, ctx) { if (rf & 1) { $i0$.ɵtext(0, " some-content "); } @@ -349,7 +349,7 @@ describe('compiler compliance: template', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $i0$.ɵtemplate(0, Template_0, 1, 0, null, $c0$); + $i0$.ɵtemplate(0, MyComponent_ng_template_Template_0, 1, 0, "ng-template", $c0$); } if (rf & 2) { $i0$.ɵelementProperty(0, "boundAttr", $i0$.ɵbind(ctx.b)); @@ -383,7 +383,7 @@ describe('compiler compliance: template', () => { const template = ` const $t0_refs$ = ["foo", ""]; - function Template_0(rf, ctx) { + function MyComponent_ng_template_Template_0(rf, ctx) { if (rf & 1) { $i0$.ɵtext(0, "some-content"); } @@ -393,7 +393,7 @@ describe('compiler compliance: template', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $i0$.ɵtemplate(0, Template_0, 1, 0, null, null, $t0_refs$, $i0$.ɵtemplateRefExtractor); + $i0$.ɵtemplate(0, MyComponent_ng_template_Template_0, 1, 0, "ng-template", null, $t0_refs$, $i0$.ɵtemplateRefExtractor); } }`; @@ -424,13 +424,13 @@ describe('compiler compliance: template', () => { const template = ` const $t0_attrs$ = [${AttributeMarker.SelectOnly}, "outDirective"]; - function Template_0(rf, ctx) { } + function MyComponent_ng_template_Template_0(rf, ctx) { } // ... template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $i0$.ɵtemplate(0, Template_0, 0, 0, null, $t0_attrs$); + $i0$.ɵtemplate(0, MyComponent_ng_template_Template_0, 0, 0, "ng-template", $t0_attrs$); $i0$.ɵlistener("outDirective", function MyComponent_Template_ng_template_outDirective_listener($event) { return $event.doSth(); }); } }`; diff --git a/packages/compiler/src/render3/r3_ast.ts b/packages/compiler/src/render3/r3_ast.ts index ec7a355aa4..ba7eaeb6bf 100644 --- a/packages/compiler/src/render3/r3_ast.ts +++ b/packages/compiler/src/render3/r3_ast.ts @@ -73,7 +73,7 @@ export class Element implements Node { export class Template implements Node { constructor( - public attributes: TextAttribute[], public inputs: BoundAttribute[], + public tagName: string, public attributes: TextAttribute[], public inputs: BoundAttribute[], public outputs: BoundEvent[], public children: Node[], public references: Reference[], public variables: Variable[], public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan|null, public endSourceSpan: ParseSourceSpan|null, @@ -189,8 +189,8 @@ export class TransformVisitor implements Visitor { newChildren != template.children || newVariables != template.variables || newReferences != template.references) { return new Template( - newAttributes, newInputs, newOutputs, newChildren, newReferences, newVariables, - template.sourceSpan, template.startSourceSpan, template.endSourceSpan); + template.tagName, newAttributes, newInputs, newOutputs, newChildren, newReferences, + newVariables, template.sourceSpan, template.startSourceSpan, template.endSourceSpan); } return template; } diff --git a/packages/compiler/src/render3/r3_template_transform.ts b/packages/compiler/src/render3/r3_template_transform.ts index 284b103b1f..33a24fb424 100644 --- a/packages/compiler/src/render3/r3_template_transform.ts +++ b/packages/compiler/src/render3/r3_template_transform.ts @@ -167,8 +167,8 @@ class HtmlAstToIvyAst implements html.Visitor { const attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta); parsedElement = new t.Template( - attributes, attrs.bound, boundEvents, children, references, variables, element.sourceSpan, - element.startSourceSpan, element.endSourceSpan, element.i18n); + element.name, attributes, attrs.bound, boundEvents, children, references, variables, + element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); } else { const attrs = this.extractAttributes(element.name, parsedProperties, i18nAttrsMeta); parsedElement = new t.Element( @@ -180,8 +180,9 @@ class HtmlAstToIvyAst implements html.Visitor { const attrs = this.extractAttributes('ng-template', templateParsedProperties, i18nAttrsMeta); // TODO(pk): test for this case parsedElement = new t.Template( - attrs.literal, attrs.bound, [], [parsedElement], [], templateVariables, - element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n); + (parsedElement as t.Element).name, attrs.literal, attrs.bound, [], [parsedElement], [], + templateVariables, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, + element.i18n); } return parsedElement; } diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index b8dd7e93ff..21ee059439 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -685,21 +685,15 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver this.i18n.appendTemplate(template.i18n !, templateIndex); } - let elName = ''; - if (isSingleElementTemplate(template.children)) { - // When the template as a single child, derive the context name from the tag - elName = sanitizeIdentifier(template.children[0].name); - } - - const contextName = elName ? `${this.contextName}_${elName}` : ''; - + const tagName = sanitizeIdentifier(template.tagName || ''); + const contextName = tagName ? `${this.contextName}_${tagName}` : ''; const templateName = contextName ? `${contextName}_Template_${templateIndex}` : `Template_${templateIndex}`; const parameters: o.Expression[] = [ o.literal(templateIndex), o.variable(templateName), - o.TYPED_NULL_EXPR, + o.literal(template.tagName), ]; // find directives matching on a given node diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index b5466a9467..2c35e2226e 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -194,7 +194,7 @@ export function createNodeAtIndex( index: number, type: TNodeType.Projection, native: null, name: null, attrs: TAttributes | null): TProjectionNode; export function createNodeAtIndex( - index: number, type: TNodeType.ElementContainer, native: RComment, name: null, + index: number, type: TNodeType.ElementContainer, native: RComment, name: string | null, attrs: TAttributes | null): TElementContainerNode; export function createNodeAtIndex( index: number, type: TNodeType.IcuContainer, native: RComment, name: null, @@ -490,15 +490,17 @@ export function elementContainerStart( const lView = getLView(); const tView = lView[TVIEW]; const renderer = lView[RENDERER]; + const tagName = 'ng-container'; ngDevMode && assertEqual( lView[BINDING_INDEX], tView.bindingStartIndex, 'element containers should be created before any bindings'); ngDevMode && ngDevMode.rendererCreateComment++; - const native = renderer.createComment(ngDevMode ? 'ng-container' : ''); + const native = renderer.createComment(ngDevMode ? tagName : ''); ngDevMode && assertDataInRange(lView, index - 1); - const tNode = createNodeAtIndex(index, TNodeType.ElementContainer, native, null, attrs || null); + const tNode = + createNodeAtIndex(index, TNodeType.ElementContainer, native, tagName, attrs || null); appendChild(native, tNode, lView); createDirectivesAndLocals(tView, lView, localRefs); @@ -1646,7 +1648,7 @@ function findDirectiveMatches(tView: TView, viewData: LView, tNode: TNode): Dire if (registry) { for (let i = 0; i < registry.length; i++) { const def = registry[i] as ComponentDef| DirectiveDef; - if (isNodeMatchingSelectorList(tNode, def.selectors !)) { + if (isNodeMatchingSelectorList(tNode, def.selectors !, /* isProjectionMode */ false)) { matches || (matches = []); diPublicInInjector( getOrCreateNodeInjectorForNode( diff --git a/packages/core/src/render3/node_selector_matcher.ts b/packages/core/src/render3/node_selector_matcher.ts index dcdfaa5307..ed56726ec4 100644 --- a/packages/core/src/render3/node_selector_matcher.ts +++ b/packages/core/src/render3/node_selector_matcher.ts @@ -9,11 +9,13 @@ import './ng_dev_mode'; import {assertDefined, assertNotEqual} from './assert'; -import {AttributeMarker, TAttributes, TNode, unusedValueExportToPlacateAjd as unused1} from './interfaces/node'; +import {AttributeMarker, TAttributes, TNode, TNodeType, unusedValueExportToPlacateAjd as unused1} from './interfaces/node'; import {CssSelector, CssSelectorList, NG_PROJECT_AS_ATTR_NAME, SelectorFlags, unusedValueExportToPlacateAjd as unused2} from './interfaces/projection'; const unusedValueToPlacateAjd = unused1 + unused2; +const NG_TEMPLATE_SELECTOR = 'ng-template'; + function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string): boolean { const nodeClassesLen = nodeClassAttrVal.length; const matchIndex = nodeClassAttrVal !.indexOf(cssClassToMatch); @@ -28,6 +30,24 @@ function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string): return true; } +/** + * Function that checks whether a given tNode matches tag-based selector and has a valid type. + * + * Matching can be perfomed in 2 modes: projection mode (when we project nodes) and regular + * directive matching mode. In "projection" mode, we do not need to check types, so if tag name + * matches selector, we declare a match. In "directive matching" mode, we also check whether tNode + * is of expected type: + * - whether tNode has either Element or ElementContainer type + * - or if we want to match "ng-template" tag, we check for Container type + */ +function hasTagAndTypeMatch( + tNode: TNode, currentSelector: string, isProjectionMode: boolean): boolean { + return currentSelector === tNode.tagName && + (isProjectionMode || + (tNode.type === TNodeType.Element || tNode.type === TNodeType.ElementContainer) || + (tNode.type === TNodeType.Container && currentSelector === NG_TEMPLATE_SELECTOR)); +} + /** * A utility function to match an Ivy node static data against a simple CSS selector * @@ -35,7 +55,8 @@ function isCssClassMatching(nodeClassAttrVal: string, cssClassToMatch: string): * @param selector * @returns true if node matches the selector. */ -export function isNodeMatchingSelector(tNode: TNode, selector: CssSelector): boolean { +export function isNodeMatchingSelector( + tNode: TNode, selector: CssSelector, isProjectionMode: boolean): boolean { ngDevMode && assertDefined(selector[0], 'Selector should have a tag name'); let mode: SelectorFlags = SelectorFlags.ELEMENT; @@ -65,7 +86,8 @@ export function isNodeMatchingSelector(tNode: TNode, selector: CssSelector): boo if (mode & SelectorFlags.ELEMENT) { mode = SelectorFlags.ATTRIBUTE | mode & SelectorFlags.NOT; - if (current !== '' && current !== tNode.tagName || current === '' && selector.length === 1) { + if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) || + current === '' && selector.length === 1) { if (isPositive(mode)) return false; skipToNextSelector = true; } @@ -139,9 +161,10 @@ function findAttrIndexInNode(name: string, attrs: TAttributes | null): number { return -1; } -export function isNodeMatchingSelectorList(tNode: TNode, selector: CssSelectorList): boolean { +export function isNodeMatchingSelectorList( + tNode: TNode, selector: CssSelectorList, isProjectionMode: boolean = false): boolean { for (let i = 0; i < selector.length; i++) { - if (isNodeMatchingSelector(tNode, selector[i])) { + if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) { return true; } } @@ -176,7 +199,8 @@ export function matchingSelectorIndex( // if a node has the ngProjectAs attribute match it against unparsed selector // match a node against a parsed selector only if ngProjectAs attribute is not present if (ngProjectAsAttrVal === textSelectors[i] || - ngProjectAsAttrVal === null && isNodeMatchingSelectorList(tNode, selectors[i])) { + ngProjectAsAttrVal === null && + isNodeMatchingSelectorList(tNode, selectors[i], /* isProjectionMode */ true)) { return i + 1; // first matching selector "captures" a given node } } diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index 44364736cd..edefdd0c71 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -113,6 +113,9 @@ { "name": "NG_PROJECT_AS_ATTR_NAME" }, + { + "name": "NG_TEMPLATE_SELECTOR" + }, { "name": "NOT_FOUND" }, @@ -830,6 +833,9 @@ { "name": "hasPlayerBuilderChanged" }, + { + "name": "hasTagAndTypeMatch" + }, { "name": "hasValueChanged" }, diff --git a/packages/core/test/render3/change_detection_spec.ts b/packages/core/test/render3/change_detection_spec.ts index 05c7c9a61e..0d924733b3 100644 --- a/packages/core/test/render3/change_detection_spec.ts +++ b/packages/core/test/render3/change_detection_spec.ts @@ -126,7 +126,7 @@ describe('change detection', () => { */ const App = createComponent('app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, FooTemplate, 2, 1, '', null, ['foo', ''], templateRefExtractor); + template(0, FooTemplate, 2, 1, 'ng-template', null, ['foo', ''], templateRefExtractor); element(2, 'structural-comp'); } if (rf & RenderFlags.Update) { diff --git a/packages/core/test/render3/common_integration_spec.ts b/packages/core/test/render3/common_integration_spec.ts index 41c0413545..9acd912e89 100644 --- a/packages/core/test/render3/common_integration_spec.ts +++ b/packages/core/test/render3/common_integration_spec.ts @@ -48,7 +48,7 @@ describe('@angular/common integration', () => { template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { elementStart(0, 'ul'); - { template(1, liTemplate, 2, 1, undefined, ['ngForOf', '']); } + { template(1, liTemplate, 2, 1, 'li', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -111,7 +111,7 @@ describe('@angular/common integration', () => { template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { elementStart(0, 'ul'); - { template(1, liTemplate, 2, 3, undefined, ['ngForOf', '']); } + { template(1, liTemplate, 2, 3, 'li', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -175,7 +175,7 @@ describe('@angular/common integration', () => { vars: 1, template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { - template(0, ngForTemplate, 1, 0, undefined, ['ngForOf', '']); + template(0, ngForTemplate, 1, 0, 'comp', ['ngForOf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngForOf', bind(ctx.rows)); @@ -247,7 +247,7 @@ describe('@angular/common integration', () => { } elementEnd(); elementStart(2, 'ul'); - { template(3, liTemplate, 2, 1, undefined, ['ngForOf', '']); } + { template(3, liTemplate, 2, 1, 'li', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -302,7 +302,7 @@ describe('@angular/common integration', () => { template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { elementStart(0, 'ul'); - { template(1, liTemplate, 2, 1, null, ['ngForOf', '']); } + { template(1, liTemplate, 2, 1, 'li', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -317,7 +317,7 @@ describe('@angular/common integration', () => { function liTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'li'); - { template(1, spanTemplate, 2, 3, null, ['ngForOf', '']); } + { template(1, spanTemplate, 2, 3, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -392,7 +392,7 @@ describe('@angular/common integration', () => { vars: 1, template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { - template(0, divTemplate, 2, 1, null, ['ngForOf', '']); + template(0, divTemplate, 2, 1, 'div', ['ngForOf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngForOf', bind(ctx.items)); @@ -406,7 +406,7 @@ describe('@angular/common integration', () => { function divTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'div'); - { template(1, pTemplate, 3, 2, null, ['ngForOf', '']); } + { template(1, pTemplate, 3, 2, 'p', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -486,7 +486,7 @@ describe('@angular/common integration', () => { vars: 1, template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { - template(0, divTemplate, 2, 1, null, ['ngForOf', '']); + template(0, divTemplate, 2, 1, 'div', ['ngForOf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngForOf', bind(ctx.items)); @@ -500,7 +500,7 @@ describe('@angular/common integration', () => { function divTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'div'); - { template(1, innerDivTemplate, 2, 1, null, ['ngForOf', '']); } + { template(1, innerDivTemplate, 2, 1, 'div', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -512,7 +512,7 @@ describe('@angular/common integration', () => { function innerDivTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'div'); - { template(1, spanTemplate, 2, 2, null, ['ngForOf', '']); } + { template(1, spanTemplate, 2, 2, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -654,7 +654,7 @@ describe('@angular/common integration', () => { vars: 1, template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { - template(0, itemTemplate0, 2, 1, null, ['ngForOf', '']); + template(0, itemTemplate0, 2, 1, 'span', ['ngForOf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngForOf', bind(ctx.items)); @@ -668,7 +668,7 @@ describe('@angular/common integration', () => { function itemTemplate0(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate1, 2, 1, null, ['ngForOf', '']); } + { template(1, itemTemplate1, 2, 1, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -680,7 +680,7 @@ describe('@angular/common integration', () => { function itemTemplate1(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate2, 2, 1, null, ['ngForOf', '']); } + { template(1, itemTemplate2, 2, 1, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -692,7 +692,7 @@ describe('@angular/common integration', () => { function itemTemplate2(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate3, 2, 1, null, ['ngForOf', '']); } + { template(1, itemTemplate3, 2, 1, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -704,7 +704,7 @@ describe('@angular/common integration', () => { function itemTemplate3(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate4, 2, 1, null, ['ngForOf', '']); } + { template(1, itemTemplate4, 2, 1, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -716,7 +716,7 @@ describe('@angular/common integration', () => { function itemTemplate4(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate5, 2, 1, null, ['ngForOf', '']); } + { template(1, itemTemplate5, 2, 1, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -728,7 +728,7 @@ describe('@angular/common integration', () => { function itemTemplate5(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate6, 2, 1, null, ['ngForOf', '']); } + { template(1, itemTemplate6, 2, 1, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -740,7 +740,7 @@ describe('@angular/common integration', () => { function itemTemplate6(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate7, 2, 1, null, ['ngForOf', '']); } + { template(1, itemTemplate7, 2, 1, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -752,7 +752,7 @@ describe('@angular/common integration', () => { function itemTemplate7(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'span'); - { template(1, itemTemplate8, 2, 10, null, ['ngForOf', '']); } + { template(1, itemTemplate8, 2, 10, 'span', ['ngForOf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -822,8 +822,8 @@ describe('@angular/common integration', () => { */ template: (rf: RenderFlags, ctx: MyApp) => { if (rf & RenderFlags.Create) { - template(0, templateOne, 2, 1, undefined, ['ngIf', '']); - template(1, templateTwo, 2, 1, undefined, ['ngIf', '']); + template(0, templateOne, 2, 1, 'div', ['ngIf', '']); + template(1, templateTwo, 2, 1, 'div', ['ngIf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngIf', bind(ctx.showing)); @@ -892,7 +892,7 @@ describe('@angular/common integration', () => { vars: 1, template: (rf: RenderFlags, ctx: AppComponent) => { if (rf & RenderFlags.Create) { - template(0, divTemplate, 2, 1, undefined, ['ngIf', '']); + template(0, divTemplate, 2, 1, 'div', ['ngIf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngIf', bind(ctx.showing)); @@ -906,7 +906,7 @@ describe('@angular/common integration', () => { function divTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'div'); - { template(1, outerDivTemplate, 2, 1, undefined, ['ngIf', '']); } + { template(1, outerDivTemplate, 2, 1, 'div', ['ngIf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -918,7 +918,7 @@ describe('@angular/common integration', () => { function outerDivTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'div'); - { template(1, innerDivTemplate, 2, 1, undefined, ['ngIf', '']); } + { template(1, innerDivTemplate, 2, 1, 'div', ['ngIf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -971,8 +971,9 @@ describe('@angular/common integration', () => { if (rf1 & RenderFlags.Create) { text(0, 'from tpl'); } - }, 1, 0, undefined, undefined, ['tpl', ''], templateRefExtractor); - template(2, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); + }, 1, 0, 'ng-template', undefined, ['tpl', ''], templateRefExtractor); + template( + 2, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); } if (rf & RenderFlags.Update) { const tplRef = load(1); @@ -1014,7 +1015,7 @@ describe('@angular/common integration', () => { if (rf1 & RenderFlags.Create) { text(0, 'from tpl'); } - }, 1, 0, undefined, undefined, ['tpl', ''], templateRefExtractor); + }, 1, 0, 'ng-template', undefined, ['tpl', ''], templateRefExtractor); elementContainerStart(2, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); elementContainerEnd(); } diff --git a/packages/core/test/render3/component_spec.ts b/packages/core/test/render3/component_spec.ts index 1a6f545c86..817e2594ef 100644 --- a/packages/core/test/render3/component_spec.ts +++ b/packages/core/test/render3/component_spec.ts @@ -185,7 +185,7 @@ it('should not invoke renderer destroy method for embedded views', () => { elementStart(0, 'div'); text(1, 'Root view'); elementEnd(); - template(2, MyComponent_div_Template_2, 2, 0, null, [1, 'ngIf']); + template(2, MyComponent_div_Template_2, 2, 0, null, [AttributeMarker.SelectOnly, 'ngIf']); } if (rf & RenderFlags.Update) { elementProperty(2, 'ngIf', bind(ctx.visible)); @@ -511,8 +511,8 @@ describe('recursive components', () => { if (rf & RenderFlags.Create) { text(0); - template(1, IfTemplate, 1, 1, '', [AttributeMarker.SelectOnly, 'ngIf']); - template(2, IfTemplate2, 1, 1, '', [AttributeMarker.SelectOnly, 'ngIf']); + template(1, IfTemplate, 1, 1, 'ng-if-tree', [AttributeMarker.SelectOnly, 'ngIf']); + template(2, IfTemplate2, 1, 1, 'ng-if-tree', [AttributeMarker.SelectOnly, 'ngIf']); } if (rf & RenderFlags.Update) { textBinding(0, bind(ctx.data.value)); diff --git a/packages/core/test/render3/content_spec.ts b/packages/core/test/render3/content_spec.ts index 0ebee9870a..b8611afd90 100644 --- a/packages/core/test/render3/content_spec.ts +++ b/packages/core/test/render3/content_spec.ts @@ -813,7 +813,7 @@ describe('content projection', () => { if (rf & RenderFlags.Create) { projectionDef(); text(0, 'Before-'); - template(1, IfTemplate, 1, 0, '', [AttributeMarker.SelectOnly, 'ngIf']); + template(1, IfTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']); text(2, '-After'); } if (rf & RenderFlags.Update) { @@ -878,7 +878,7 @@ describe('content projection', () => { if (rf & RenderFlags.Create) { projectionDef(); text(0, 'Before-'); - template(1, IfTemplate, 1, 0, '', [AttributeMarker.SelectOnly, 'ngIf']); + template(1, IfTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']); text(2, '-After'); } if (rf & RenderFlags.Update) { diff --git a/packages/core/test/render3/di_spec.ts b/packages/core/test/render3/di_spec.ts index 8d7c83d80b..41701f6fd4 100644 --- a/packages/core/test/render3/di_spec.ts +++ b/packages/core/test/render3/di_spec.ts @@ -489,7 +489,7 @@ describe('di', () => { const App = createComponent('app', (rf: RenderFlags, ctx: any) => { if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dirB', '']); - { template(1, IfTemplate, 4, 1, '', [AttributeMarker.SelectOnly, 'ngIf', '']); } + { template(1, IfTemplate, 4, 1, 'div', [AttributeMarker.SelectOnly, 'ngIf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -609,7 +609,10 @@ describe('di', () => { const App = createComponent('app', (rf: RenderFlags, ctx: any) => { if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dirB', '', 'value', 'declaration']); - { template(1, FooTemplate, 3, 1, '', null, ['foo', ''], templateRefExtractor); } + { + template( + 1, FooTemplate, 3, 1, 'ng-template', null, ['foo', ''], templateRefExtractor); + } elementEnd(); elementStart(3, 'div', ['dirB', '', 'value', 'insertion']); { element(4, 'div', ['structuralDir', '']); } @@ -1157,7 +1160,7 @@ describe('di', () => { const App = createComponent('app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'div', ['dirB', '']); - { template(1, IfTemplate, 1, 0, '', ['ngIf', '']); } + { template(1, IfTemplate, 1, 0, 'div', ['ngIf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { @@ -1300,7 +1303,7 @@ describe('di', () => { /** */ const App = createComponent('app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, () => {}, 0, 0, null, ['dir', '']); + template(0, () => {}, 0, 0, 'ng-template', ['dir', '']); lContainer = load(0) as any; } }, 1, 0, [Directive]); @@ -1347,8 +1350,9 @@ describe('di', () => { */ const App = createComponent('app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, function() { - }, 0, 0, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']); + template( + 0, function() {}, 0, 0, 'ng-template', ['dir', '', 'dirSame', ''], + ['dir', 'dir', 'dirSame', 'dirSame']); text(3); } if (rf & RenderFlags.Update) { @@ -1703,7 +1707,7 @@ describe('di', () => { /**
{{ dir.value }}
*/ template: function(rf: RenderFlags, ctx: MyApp) { if (rf & RenderFlags.Create) { - template(0, C1, 3, 1, null, ['ngIf', 'showing']); + template(0, C1, 3, 1, 'div', ['ngIf', 'showing']); } }, directives: directives @@ -1827,7 +1831,7 @@ describe('di', () => { const MyApp = createComponent('my-app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { template( - 0, null, 0, 0, null, + 0, null, 0, 0, 'ng-template', ['myDirective', 'initial', 'exist', 'existValue', 'other', 'ignore']); } if (rf & RenderFlags.Update) { diff --git a/packages/core/test/render3/directive_spec.ts b/packages/core/test/render3/directive_spec.ts index cf9076d20d..63bc33692c 100644 --- a/packages/core/test/render3/directive_spec.ts +++ b/packages/core/test/render3/directive_spec.ts @@ -6,13 +6,14 @@ * found in the LICENSE file at https://angular.io/license */ -import {EventEmitter} from '@angular/core'; +import {EventEmitter, TemplateRef, ViewContainerRef} from '@angular/core'; -import {AttributeMarker, RenderFlags, defineDirective} from '../../src/render3/index'; +import {AttributeMarker, RenderFlags, defineComponent, defineDirective, directiveInject} from '../../src/render3/index'; -import {bind, element, elementEnd, elementProperty, elementStart, listener, template, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions'; +import {bind, element, elementEnd, elementProperty, elementStart, listener, template, elementContainerStart, elementContainerEnd, text} from '../../src/render3/instructions'; import {ComponentFixture, TemplateFixture, createComponent} from './render_util'; +import {NgIf} from './common_with_def'; describe('directive', () => { @@ -121,6 +122,106 @@ describe('directive', () => { expect(directiveInstance !.testValue).toBe(false); }); + it('should match directives on ', () => { + /** + * @Directive({ + * selector: 'ng-template[directiveA]' + * }) + * export class DirectiveA { + * constructor(public templateRef: TemplateRef) {} + * } + */ + let tmplRef: any; + class DirectiveA { + constructor(public templateRef: any) { tmplRef = templateRef; } + static ngDirectiveDef = defineDirective({ + type: DirectiveA, + selectors: [['ng-template', 'directiveA', '']], + factory: () => new DirectiveA(directiveInject(TemplateRef as any)) + }); + } + + function MyComponent_ng_template_Template_0(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { + text(0, 'Some content'); + } + } + class MyComponent { + static ngComponentDef = defineComponent({ + type: MyComponent, + selectors: [['my-component']], + factory: () => new MyComponent(), + consts: 1, + vars: 0, + // Some content + template: function MyComponent_Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { + template( + 0, MyComponent_ng_template_Template_0, 1, 0, 'ng-template', ['directiveA', '']); + } + }, + directives: [DirectiveA] + }); + } + + new ComponentFixture(MyComponent); + expect(tmplRef instanceof TemplateRef).toBeTruthy(); + }); + + it('should match directives on ', () => { + /** + * @Directive({ + * selector: 'ng-container[directiveA]' + * }) + * export class DirectiveA { + * constructor(public vcRef: ViewContainerRef) {} + * } + */ + let vcRef: any; + class DirectiveA { + constructor(public viewContainerRef: any) { vcRef = viewContainerRef; } + static ngDirectiveDef = defineDirective({ + type: DirectiveA, + selectors: [['ng-container', 'directiveA', '']], + factory: () => new DirectiveA(directiveInject(ViewContainerRef as any)) + }); + } + + function MyComponent_ng_container_Template_0(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { + elementContainerStart(0, ['directiveA', '']); + text(1, 'Some content'); + elementContainerEnd(); + } + } + class MyComponent { + visible = true; + + static ngComponentDef = defineComponent({ + type: MyComponent, + selectors: [['my-component']], + factory: () => new MyComponent(), + consts: 1, + vars: 1, + // Some content + template: function MyComponent_Template(rf: RenderFlags, ctx: any) { + if (rf & RenderFlags.Create) { + template( + 0, MyComponent_ng_container_Template_0, 2, 0, 'ng-container', + [AttributeMarker.SelectOnly, 'ngIf']); + } + if (rf & RenderFlags.Update) { + elementProperty(0, 'ngIf', bind(ctx.visible)); + } + }, + directives: [DirectiveA, NgIf] + }); + } + + new ComponentFixture(MyComponent); + expect(vcRef instanceof ViewContainerRef).toBeTruthy(); + }); + it('should match directives with attribute selectors on outputs', () => { let directiveInstance: Directive; @@ -173,7 +274,7 @@ describe('directive', () => { */ const Cmpt = createComponent('Cmpt', function(rf: RenderFlags, ctx: {value: any}) { if (rf & RenderFlags.Create) { - template(0, null, 0, 0, null, [AttributeMarker.SelectOnly, 'out']); + template(0, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'out']); listener('out', () => { ctx.value = true; }); } }, 1, 0, [Directive]); diff --git a/packages/core/test/render3/discovery_utils_spec.ts b/packages/core/test/render3/discovery_utils_spec.ts index ceaf899dae..085ff607f1 100644 --- a/packages/core/test/render3/discovery_utils_spec.ts +++ b/packages/core/test/render3/discovery_utils_spec.ts @@ -120,7 +120,7 @@ describe('discovery utils', () => { if (rf & RenderFlags.Create) { element(0, 'child'); } - }, 1, 0, null, ['ngIf', '']); + }, 1, 0, 'child', ['ngIf', '']); } if (rf & RenderFlags.Update) { textBinding(1, bind(ctx.text)); diff --git a/packages/core/test/render3/exports_spec.ts b/packages/core/test/render3/exports_spec.ts index 023d956b83..a5f5524dd7 100644 --- a/packages/core/test/render3/exports_spec.ts +++ b/packages/core/test/render3/exports_spec.ts @@ -365,7 +365,7 @@ describe('exports', () => { if (rf & RenderFlags.Create) { elementStart(0, 'input', ['value', 'one'], ['outerInput', '']); elementEnd(); - template(2, outerTemplate, 5, 2, '', [AttributeMarker.SelectOnly, 'ngIf']); + template(2, outerTemplate, 5, 2, 'div', [AttributeMarker.SelectOnly, 'ngIf']); } if (rf & RenderFlags.Update) { elementProperty(2, 'ngIf', bind(app.outer)); @@ -379,7 +379,7 @@ describe('exports', () => { text(1); elementStart(2, 'input', ['value', 'two'], ['innerInput', '']); elementEnd(); - template(4, innerTemplate, 2, 2, '', [AttributeMarker.SelectOnly, 'ngIf']); + template(4, innerTemplate, 2, 2, 'div', [AttributeMarker.SelectOnly, 'ngIf']); } elementEnd(); } diff --git a/packages/core/test/render3/host_binding_spec.ts b/packages/core/test/render3/host_binding_spec.ts index 792fd688a5..c87ae25259 100644 --- a/packages/core/test/render3/host_binding_spec.ts +++ b/packages/core/test/render3/host_binding_spec.ts @@ -472,7 +472,7 @@ describe('host bindings', () => { */ const App = createComponent('parent', (rf: RenderFlags, ctx: any) => { if (rf & RenderFlags.Create) { - template(0, NgForTemplate, 2, 0, null, ['ngForOf', '']); + template(0, NgForTemplate, 2, 0, 'div', ['ngForOf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngForOf', bind(ctx.rows)); diff --git a/packages/core/test/render3/i18n_spec.ts b/packages/core/test/render3/i18n_spec.ts index 0782a55ab9..e64c420812 100644 --- a/packages/core/test/render3/i18n_spec.ts +++ b/packages/core/test/render3/i18n_spec.ts @@ -595,7 +595,7 @@ describe('Runtime i18n', () => { if (rf & RenderFlags.Create) { i18nStart(0, MSG_DIV, 1); elementStart(1, 'div'); - template(2, subTemplate_2, 2, 0, null, ['ngIf', '']); + template(2, subTemplate_2, 2, 0, 'span', ['ngIf', '']); elementEnd(); i18nEnd(); } @@ -624,7 +624,7 @@ describe('Runtime i18n', () => { if (rf & RenderFlags.Create) { elementStart(0, 'div'); i18nStart(1, MSG_DIV); - template(2, subTemplate_1, 3, 1, null, ['ngIf', '']); + template(2, subTemplate_1, 3, 1, 'div', ['ngIf', '']); i18nEnd(); elementEnd(); } diff --git a/packages/core/test/render3/instructions_spec.ts b/packages/core/test/render3/instructions_spec.ts index 215da8c36f..e82aa4fd5f 100644 --- a/packages/core/test/render3/instructions_spec.ts +++ b/packages/core/test/render3/instructions_spec.ts @@ -297,7 +297,7 @@ describe('instructions', () => { function ToDoAppComponent_NgForOf_Template_0(rf: RenderFlags, ctx0: NgForOfContext) { if (rf & RenderFlags.Create) { elementStart(0, 'ul'); - template(1, ToDoAppComponent_NgForOf_NgForOf_Template_1, 2, 1, null, _c0); + template(1, ToDoAppComponent_NgForOf_NgForOf_Template_1, 2, 1, 'li', _c0); elementEnd(); } if (rf & RenderFlags.Update) { @@ -335,7 +335,7 @@ describe('instructions', () => { vars: 1, template: function ToDoAppComponent_Template(rf: RenderFlags, ctx: NestedLoops) { if (rf & RenderFlags.Create) { - template(0, ToDoAppComponent_NgForOf_Template_0, 2, 1, null, _c0); + template(0, ToDoAppComponent_NgForOf_Template_0, 2, 1, 'ul', _c0); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngForOf', bind(ctx.rows)); diff --git a/packages/core/test/render3/integration_spec.ts b/packages/core/test/render3/integration_spec.ts index f7de4aa0f8..89468d775f 100644 --- a/packages/core/test/render3/integration_spec.ts +++ b/packages/core/test/render3/integration_spec.ts @@ -719,7 +719,8 @@ describe('render3 integration test', () => { const TestCmpt = createComponent('test-cmpt', function(rf: RenderFlags, ctx: {value: any}) { if (rf & RenderFlags.Create) { - template(0, ngIfTemplate, 2, 0, null, [AttributeMarker.SelectOnly, 'ngIf']); + template( + 0, ngIfTemplate, 2, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngIf', bind(ctx.value)); @@ -778,7 +779,8 @@ describe('render3 integration test', () => { const TestCmpt = createComponent('test-cmpt', function(rf: RenderFlags) { if (rf & RenderFlags.Create) { template( - 0, embeddedTemplate, 2, 0, null, [AttributeMarker.SelectOnly, 'testDirective']); + 0, embeddedTemplate, 2, 0, 'ng-template', + [AttributeMarker.SelectOnly, 'testDirective']); } }, 1, 0, [TestDirective]); @@ -893,7 +895,9 @@ describe('render3 integration test', () => { */ const TestCmpt = createComponent('test-cmpt', function(rf: RenderFlags) { if (rf & RenderFlags.Create) { - template(0, embeddedTemplate, 4, 0, null, [AttributeMarker.SelectOnly, 'testDirective']); + template( + 0, embeddedTemplate, 4, 0, 'ng-template', + [AttributeMarker.SelectOnly, 'testDirective']); } }, 1, 0, [TestDirective]); @@ -981,7 +985,8 @@ describe('render3 integration test', () => { const App = createComponent('app', function(rf: RenderFlags) { if (rf & RenderFlags.Create) { elementContainerStart(0, [AttributeMarker.SelectOnly, 'dir']); - template(1, ContentTemplate, 1, 0, '', null, ['content', ''], templateRefExtractor); + template( + 1, ContentTemplate, 1, 0, 'ng-template', null, ['content', ''], templateRefExtractor); elementContainerEnd(); } if (rf & RenderFlags.Update) { @@ -1037,7 +1042,7 @@ describe('render3 integration test', () => { if (rf & RenderFlags.Create) { elementContainerStart(0); template( - 1, ContentTemplate, 1, 0, '', [AttributeMarker.SelectOnly, 'dir'], [], + 1, ContentTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'dir'], [], templateRefExtractor); elementContainerEnd(); } @@ -1610,7 +1615,7 @@ describe('render3 integration test', () => { */ const App = createComponent('app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, FooTemplate, 1, 0, '', null, ['foo', ''], templateRefExtractor); + template(0, FooTemplate, 1, 0, 'ng-template', null, ['foo', ''], templateRefExtractor); elementStart(2, 'structural-comp'); elementStyling(['active']); elementEnd(); @@ -1990,7 +1995,7 @@ describe('render3 integration test', () => { elementEnd(); element(2, 'div'); } - }, 3, 0, null, ['ngIf', '']); + }, 3, 0, 'ng-template', ['ngIf', '']); elementEnd(); } if (rf & RenderFlags.Update) { diff --git a/packages/core/test/render3/lifecycle_spec.ts b/packages/core/test/render3/lifecycle_spec.ts index c6f1a581fc..b501cb0847 100644 --- a/packages/core/test/render3/lifecycle_spec.ts +++ b/packages/core/test/render3/lifecycle_spec.ts @@ -196,7 +196,7 @@ describe('lifecycles', () => { /** */ const App = createComponent('app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, IfTemplate, 1, 0, '', ['ngIf', '']); + template(0, IfTemplate, 1, 0, 'comp', ['ngIf', '']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngIf', bind(ctx.showing)); @@ -2586,7 +2586,8 @@ describe('lifecycles', () => { function conditionTpl(rf: RenderFlags, ctx: Cmpt) { if (rf & RenderFlags.Create) { - template(0, null, 0, 1, null, [AttributeMarker.SelectOnly, 'onDestroyDirective']); + template( + 0, null, 0, 1, 'ng-template', [AttributeMarker.SelectOnly, 'onDestroyDirective']); } } @@ -2597,7 +2598,7 @@ describe('lifecycles', () => { */ function cmptTpl(rf: RenderFlags, cmpt: Cmpt) { if (rf & RenderFlags.Create) { - template(0, conditionTpl, 1, 1, null, [AttributeMarker.SelectOnly, 'ngIf']); + template(0, conditionTpl, 1, 1, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngIf', bind(cmpt.showing)); diff --git a/packages/core/test/render3/node_selector_matcher_spec.ts b/packages/core/test/render3/node_selector_matcher_spec.ts index b0eb3dfb7d..5974dd4391 100644 --- a/packages/core/test/render3/node_selector_matcher_spec.ts +++ b/packages/core/test/render3/node_selector_matcher_spec.ts @@ -20,7 +20,7 @@ function testLStaticData(tagName: string, attrs: TAttributes | null): TNode { describe('css selector matching', () => { function isMatching(tagName: string, attrs: TAttributes | null, selector: CssSelector): boolean { return isNodeMatchingSelector( - createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null), selector); + createTNode(getLView(), TNodeType.Element, 0, tagName, attrs, null), selector, false); } describe('isNodeMatchingSimpleSelector', () => { @@ -417,7 +417,7 @@ describe('css selector matching', () => { function isAnyMatching( tagName: string, attrs: string[] | null, selector: CssSelectorList): boolean { - return isNodeMatchingSelectorList(testLStaticData(tagName, attrs), selector); + return isNodeMatchingSelectorList(testLStaticData(tagName, attrs), selector, false); } it('should match when there is only one simple selector without negations', () => { diff --git a/packages/core/test/render3/pure_function_spec.ts b/packages/core/test/render3/pure_function_spec.ts index e8851f8e4d..81e4a3519e 100644 --- a/packages/core/test/render3/pure_function_spec.ts +++ b/packages/core/test/render3/pure_function_spec.ts @@ -87,7 +87,7 @@ describe('array literals', () => { */ const App = createComponent('app', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, IfTemplate, 1, 3, null, [AttributeMarker.SelectOnly, 'ngIf']); + template(0, IfTemplate, 1, 3, 'my-comp', [AttributeMarker.SelectOnly, 'ngIf']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngIf', bind(ctx.showing)); diff --git a/packages/core/test/render3/query_spec.ts b/packages/core/test/render3/query_spec.ts index e6ef332636..ba1c172e27 100644 --- a/packages/core/test/render3/query_spec.ts +++ b/packages/core/test/render3/query_spec.ts @@ -661,7 +661,7 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, null, null, ['foo', '']); + template(1, null, 0, 0, 'ng-template', null, ['foo', '']); } }, 3, 0, [], [], @@ -693,7 +693,7 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, null, null, ['foo', '']); + template(1, null, 0, 0, 'ng-template', null, ['foo', '']); } }, 3, 0, [], [], @@ -728,7 +728,7 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, null, null, ['foo', '']); + template(1, null, 0, 0, 'ng-template', null, ['foo', '']); } }, 3, 0, [], [], @@ -760,7 +760,7 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, null, 0, 0, null, null, ['foo', '']); + template(1, null, 0, 0, 'ng-template', null, ['foo', '']); } }, 3, 0, [], [], @@ -1276,9 +1276,15 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(2, Cmpt_Template_1, 2, 0, null, null, ['foo', ''], templateRefExtractor); - template(3, Cmpt_Template_1, 2, 0, null, null, ['bar', ''], templateRefExtractor); - template(4, Cmpt_Template_1, 2, 0, null, null, ['baz', ''], templateRefExtractor); + template( + 2, Cmpt_Template_1, 2, 0, 'ng-template', null, ['foo', ''], + templateRefExtractor); + template( + 3, Cmpt_Template_1, 2, 0, 'ng-template', null, ['bar', ''], + templateRefExtractor); + template( + 4, Cmpt_Template_1, 2, 0, 'ng-template', null, ['baz', ''], + templateRefExtractor); } }, 5, 0, [], [], @@ -1361,7 +1367,7 @@ describe('query', () => { 'cmpt', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, Cmpt_Template_1, 2, 0, null, ['ngIf', '']); + template(1, Cmpt_Template_1, 2, 0, 'ng-template', ['ngIf', '']); } if (rf & RenderFlags.Update) { elementProperty(1, 'ngIf', bind(ctx.value)); @@ -1422,7 +1428,7 @@ describe('query', () => { vars: 1, template: function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(1, Cmpt_Template_1, 2, 1, null, ['ngForOf', '']); + template(1, Cmpt_Template_1, 2, 1, 'ng-template', ['ngForOf', '']); } if (rf & RenderFlags.Update) { elementProperty(1, 'ngForOf', bind(ctx.value)); @@ -1501,11 +1507,13 @@ describe('query', () => { function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { template( - 1, Cmpt_Template_1, 2, 1, null, null, ['tpl1', ''], templateRefExtractor); + 1, Cmpt_Template_1, 2, 1, 'ng-template', null, ['tpl1', ''], + templateRefExtractor); element(3, 'div', ['id', 'middle'], ['foo', '']); template( - 5, Cmpt_Template_5, 2, 1, null, null, ['tpl2', ''], templateRefExtractor); - template(7, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']); + 5, Cmpt_Template_5, 2, 1, 'ng-template', null, ['tpl2', ''], + templateRefExtractor); + template(7, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); } if (rf & RenderFlags.Update) { @@ -1599,9 +1607,11 @@ describe('query', () => { template: function(rf: RenderFlags, ctx: any) { let tmp: any; if (rf & RenderFlags.Create) { - template(1, Cmpt_Template_1, 2, 1, null, [], ['tpl', ''], templateRefExtractor); - template(3, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']); - template(4, null, 0, 0, null, [AttributeMarker.SelectOnly, 'vc']); + template( + 1, Cmpt_Template_1, 2, 1, 'ng-template', [], ['tpl', ''], + templateRefExtractor); + template(3, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); + template(4, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'vc']); } if (rf & RenderFlags.Update) { @@ -1671,9 +1681,10 @@ describe('query', () => { template: (rf: RenderFlags, myApp: MyApp) => { if (rf & RenderFlags.Create) { template( - 1, MyApp_Template_1, 2, 0, undefined, undefined, ['tpl', ''], + 1, MyApp_Template_1, 2, 0, 'ng-template', undefined, ['tpl', ''], templateRefExtractor); - template(3, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); + template( + 3, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngTemplateOutlet']); } if (rf & RenderFlags.Update) { const tplRef = reference(2); @@ -2195,7 +2206,7 @@ describe('query', () => { function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { template( - 1, AppComponent_Template_1, 1, 0, null, [AttributeMarker.SelectOnly, 'someDir']); + 1, AppComponent_Template_1, 1, 0, 'div', [AttributeMarker.SelectOnly, 'someDir']); element(2, 'div', null, ['foo', '']); } }, @@ -2377,7 +2388,7 @@ describe('query', () => { const AppComponent = createComponent('app-component', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { elementStart(0, 'shallow-comp'); - { template(1, IfTemplate, 2, 0, null, [AttributeMarker.SelectOnly, 'ngIf', '']); } + { template(1, IfTemplate, 2, 0, 'div', [AttributeMarker.SelectOnly, 'ngIf', '']); } elementEnd(); } if (rf & RenderFlags.Update) { diff --git a/packages/core/test/render3/template_ref_spec.ts b/packages/core/test/render3/template_ref_spec.ts index a2fe6883ae..6abede7cef 100644 --- a/packages/core/test/render3/template_ref_spec.ts +++ b/packages/core/test/render3/template_ref_spec.ts @@ -50,7 +50,7 @@ describe('TemplateRef', () => { */ const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, embeddedTemplate, 3, 0, null, ['tplRef', '']); + template(0, embeddedTemplate, 3, 0, 'ng-template', ['tplRef', '']); directiveWithTplRef = getDirectiveOnNode(0, 0); } }, 1, 0, [DirectiveWithTplRef]); @@ -79,7 +79,7 @@ describe('TemplateRef', () => { */ const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, () => {}, 0, 0, null, ['tplRef', '']); + template(0, () => {}, 0, 0, 'ng-template', ['tplRef', '']); directiveWithTplRef = getDirectiveOnNode(0, 0); } }, 1, 0, [DirectiveWithTplRef]); @@ -108,7 +108,7 @@ describe('TemplateRef', () => { function embeddedTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, ngIfTemplate, 1, 0, null, [AttributeMarker.SelectOnly, 'ngIf']); + template(0, ngIfTemplate, 1, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngIf']); } if (rf & RenderFlags.Update) { elementProperty(0, 'ngIf', bind(ctx.showing)); @@ -120,7 +120,7 @@ describe('TemplateRef', () => { */ const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, embeddedTemplate, 1, 1, null, ['tplRef', '']); + template(0, embeddedTemplate, 1, 1, 'ng-template', ['tplRef', '']); directiveWithTplRef = getDirectiveOnNode(0, 0); } }, 1, 0, [DirectiveWithTplRef, NgIf]); @@ -158,7 +158,7 @@ describe('TemplateRef', () => { */ const AppComponent = createComponent('app-cmp', function(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, embeddedTemplate, 2, 0, null, ['tplRef', '']); + template(0, embeddedTemplate, 2, 0, 'ng-template', ['tplRef', '']); directiveWithTplRef = getDirectiveOnNode(0, 0); } }, 1, 0, [DirectiveWithTplRef]); diff --git a/packages/core/test/render3/view_container_ref_spec.ts b/packages/core/test/render3/view_container_ref_spec.ts index 3312beeec5..6efbdcd38c 100644 --- a/packages/core/test/render3/view_container_ref_spec.ts +++ b/packages/core/test/render3/view_container_ref_spec.ts @@ -75,7 +75,8 @@ describe('ViewContainerRef', () => { *

*/ function createTemplate() { - template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor); + template( + 0, embeddedTemplate, 1, 1, 'ng-template', null, ['tplRef', ''], templateRefExtractor); element(2, 'p', ['vcref', '']); } @@ -92,7 +93,8 @@ describe('ViewContainerRef', () => { *
*/ function createTemplate() { - template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor); + template( + 0, embeddedTemplate, 1, 1, 'ng-template', null, ['tplRef', ''], templateRefExtractor); element(2, 'header', ['vcref', '']); element(3, 'footer'); } @@ -128,7 +130,8 @@ describe('ViewContainerRef', () => { *
*/ function createTemplate() { - template(0, embeddedTemplate, 1, 1, null, [], ['tplRef', ''], templateRefExtractor); + template( + 0, embeddedTemplate, 1, 1, 'ng-template', [], ['tplRef', ''], templateRefExtractor); element(2, 'header-cmp', ['vcref', '']); element(3, 'footer'); } @@ -164,7 +167,8 @@ describe('ViewContainerRef', () => { *
*/ function createTemplate() { - template(0, embeddedTemplate, 1, 1, null, null, ['tplRef', ''], templateRefExtractor); + template( + 0, embeddedTemplate, 1, 1, 'ng-template', null, ['tplRef', ''], templateRefExtractor); element(2, 'div', ['vcref', '']); element(3, 'div', ['vcref', '']); @@ -195,7 +199,8 @@ describe('ViewContainerRef', () => { */ function createTemplate() { template( - 0, embeddedTemplate, 1, 1, null, ['vcref', ''], ['tplRef', ''], templateRefExtractor); + 0, embeddedTemplate, 1, 1, 'ng-template', ['vcref', ''], ['tplRef', ''], + templateRefExtractor); element(2, 'footer'); } @@ -281,8 +286,8 @@ describe('ViewContainerRef', () => { template: (rf: RenderFlags, cmp: TestComponent) => { if (rf & RenderFlags.Create) { text(0, 'before|'); - template(1, EmbeddedTemplateA, 1, 0, null, ['testdir', '']); - template(2, EmbeddedTemplateB, 1, 0, null, ['testdir', '']); + template(1, EmbeddedTemplateA, 1, 0, 'ng-template', ['testdir', '']); + template(2, EmbeddedTemplateB, 1, 0, 'ng-template', ['testdir', '']); text(3, '|after'); } }, @@ -354,7 +359,7 @@ describe('ViewContainerRef', () => { template: (rf: RenderFlags, cmp: TestComponent) => { if (rf & RenderFlags.Create) { text(0, 'before|'); - template(1, EmbeddedTemplateA, 1, 0, null, ['testdir', '']); + template(1, EmbeddedTemplateA, 1, 0, 'ng-template', ['testdir', '']); container(2); text(3, '|after'); } @@ -466,7 +471,8 @@ describe('ViewContainerRef', () => { template: (rf: RenderFlags, cmp: SomeComponent) => { if (rf & RenderFlags.Create) { template( - 0, SomeComponent_Template_0, 2, 3, null, [], ['foo', ''], templateRefExtractor); + 0, SomeComponent_Template_0, 2, 3, 'ng-template', [], ['foo', ''], + templateRefExtractor); pipe(2, 'starPipe'); element(3, 'child', ['vcref', '']); pipe(4, 'starPipe'); @@ -557,7 +563,8 @@ describe('ViewContainerRef', () => { */ const Parent = createComponent('parent', function(rf: RenderFlags, parent: any) { if (rf & RenderFlags.Create) { - template(0, fooTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor); + template( + 0, fooTemplate, 2, 1, 'ng-template', null, ['foo', ''], templateRefExtractor); element(2, 'child'); } @@ -618,7 +625,7 @@ describe('ViewContainerRef', () => { vars: 2, template: function(rf: RenderFlags, loop: any) { if (rf & RenderFlags.Create) { - template(0, null, 0, 0, null, [AttributeMarker.SelectOnly, 'ngForOf']); + template(0, null, 0, 0, 'ng-template', [AttributeMarker.SelectOnly, 'ngForOf']); } if (rf & RenderFlags.Update) { @@ -648,7 +655,9 @@ describe('ViewContainerRef', () => { */ const Parent = createComponent('parent', function(rf: RenderFlags, parent: any) { if (rf & RenderFlags.Create) { - template(0, rowTemplate, 3, 2, null, null, ['rowTemplate', ''], templateRefExtractor); + template( + 0, rowTemplate, 3, 2, 'ng-template', null, ['rowTemplate', ''], + templateRefExtractor); element(2, 'loop-comp'); } @@ -662,7 +671,9 @@ describe('ViewContainerRef', () => { function rowTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { - template(0, cellTemplate, 2, 3, null, null, ['cellTemplate', ''], templateRefExtractor); + template( + 0, cellTemplate, 2, 3, 'ng-template', null, ['cellTemplate', ''], + templateRefExtractor); element(2, 'loop-comp'); } @@ -1247,7 +1258,7 @@ describe('ViewContainerRef', () => { it('should work on templates', () => { function createTemplate() { - template(0, embeddedTemplate, 1, 1, null, ['vcref', '']); + template(0, embeddedTemplate, 1, 1, 'ng-template', ['vcref', '']); element(1, 'footer'); } @@ -1312,7 +1323,9 @@ describe('ViewContainerRef', () => { vars: 2, template: (rf: RenderFlags, cmp: Parent) => { if (rf & RenderFlags.Create) { - template(0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor); + template( + 0, embeddedTemplate, 2, 1, 'ng-template', null, ['foo', ''], + templateRefExtractor); elementStart(2, 'child'); { elementStart(3, 'header', ['vcref', '']); @@ -1407,7 +1420,8 @@ describe('ViewContainerRef', () => { template: (rf: RenderFlags, cmp: Parent) => { if (rf & RenderFlags.Create) { template( - 0, embeddedTemplate, 2, 1, null, undefined, ['foo', ''], templateRefExtractor); + 0, embeddedTemplate, 2, 1, 'ng-template', undefined, ['foo', ''], + templateRefExtractor); elementStart(2, 'child-with-view'); text(3, 'Before projected'); elementStart(4, 'header', ['vcref', '']); @@ -1491,7 +1505,8 @@ describe('ViewContainerRef', () => { let tplRef: any; if (rf & RenderFlags.Create) { template( - 0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor); + 0, embeddedTemplate, 2, 1, 'ng-template', null, ['foo', ''], + templateRefExtractor); elementStart(2, 'child-with-selector'); elementStart(3, 'header', ['vcref', '']); text(4, 'blah'); @@ -1544,7 +1559,8 @@ describe('ViewContainerRef', () => { let tplRef: any; if (rf & RenderFlags.Create) { template( - 0, embeddedTemplate, 2, 1, null, null, ['foo', ''], templateRefExtractor); + 0, embeddedTemplate, 2, 1, 'ng-template', null, ['foo', ''], + templateRefExtractor); elementStart(2, 'child-with-selector'); elementStart(3, 'footer', ['vcref', '']); text(4, 'blah'); @@ -1649,7 +1665,8 @@ describe('ViewContainerRef', () => { template: (rf: RenderFlags, cmp: SomeComponent) => { if (rf & RenderFlags.Create) { template( - 0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''], templateRefExtractor); + 0, SomeComponent_Template_0, 1, 1, 'ng-template', [], ['foo', ''], + templateRefExtractor); element(2, 'hooks', ['vcref', '']); element(3, 'hooks'); } @@ -1864,7 +1881,7 @@ describe('ViewContainerRef', () => { vars: 0, template: (rf: RenderFlags, cmp: AppCmpt) => { if (rf & RenderFlags.Create) { - template(0, null, 0, 0, null, ['vcref', '']); + template(0, null, 0, 0, 'ng-template', ['vcref', '']); } }, directives: [HostBindingCmpt, DirectiveWithVCRef]