diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts index 013d28e5b9..7c973a01cc 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts @@ -120,4 +120,70 @@ describe('r3_view_compiler', () => { expectEmit(result.source, bV_call, 'Incorrect bV call'); }); }); + + describe('animations', () => { + it('should keep @attr but suppress [@attr]', () => { + const files: MockDirectory = { + app: { + 'example.ts': ` + import {Component, NgModule} from '@angular/core'; + + @Component({ + selector: 'my-app', + template: '
' + }) + export class MyApp { + } + + @NgModule({declarations: [MyApp]}) + export class MyModule {}` + } + }; + + const template = ` + const _c0 = ["@attrOnly", ""]; + // ... + template: function MyApp_Template(rf, ctx) { + if (rf & 1) { + $i0$.ɵelement(0, "div", _c0); + // ... + } + // ... + }`; + const result = compile(files, angularFiles); + expectEmit(result.source, template, 'Incorrect initialization attributes'); + }); + + it('should dedup multiple [@event] listeners', () => { + const files: MockDirectory = { + app: { + 'example.ts': ` + import {Component, NgModule} from '@angular/core'; + + @Component({ + selector: 'my-app', + template: '' + }) + export class MyApp { + } + + @NgModule({declarations: [MyApp]}) + export class MyModule {}` + } + }; + + const template = ` + const _c0 = [1, "mySelector"]; + // ... + template: function MyApp_Template(rf, ctx) { + if (rf & 1) { + $i0$.ɵelementStart(0, "div", _c0); + // ... + } + // ... + }`; + const result = compile(files, angularFiles); + expectEmit(result.source, template, 'Incorrect initialization attributes'); + }); + }); }); diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts index 3827ff7294..9a99dc7f98 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts @@ -214,7 +214,6 @@ describe('compiler compliance: styling', () => { }; const template = ` - const $e0_attrs$ = ["@foo", ""]; const $e1_attrs$ = ["@bar", ""]; const $e2_attrs$ = ["@baz", ""]; … @@ -224,7 +223,7 @@ describe('compiler compliance: styling', () => { vars: 1, template: function MyComponent_Template(rf, $ctx$) { if (rf & 1) { - $r3$.ɵelement(0, "div", $e0_attrs$); + $r3$.ɵelement(0, "div"); $r3$.ɵelement(1, "div", $e1_attrs$); $r3$.ɵelement(2, "div", $e2_attrs$); } diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index 188c0e4712..293b32571c 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -10,7 +10,7 @@ import {flatten, sanitizeIdentifier} from '../../compile_metadata'; import {BindingForm, BuiltinFunctionCall, LocalResolver, convertActionBinding, convertPropertyBinding} from '../../compiler_util/expression_converter'; import {ConstantPool} from '../../constant_pool'; import * as core from '../../core'; -import {AST, AstMemoryEfficientTransformer, BindingPipe, BindingType, FunctionCall, ImplicitReceiver, Interpolation, LiteralArray, LiteralMap, LiteralPrimitive, ParsedEventType, PropertyRead} from '../../expression_parser/ast'; +import {AST, ASTWithSource, AstMemoryEfficientTransformer, BindingPipe, BindingType, FunctionCall, ImplicitReceiver, Interpolation, LiteralArray, LiteralMap, LiteralPrimitive, ParsedEventType, PropertyRead} from '../../expression_parser/ast'; import {Lexer} from '../../expression_parser/lexer'; import {Parser} from '../../expression_parser/parser'; import * as i18n from '../../i18n/i18n_ast'; @@ -967,6 +967,29 @@ export class TemplateDefinitionBuilder implements t.Visitor