diff --git a/packages/compiler/src/render3/r3_identifiers.ts b/packages/compiler/src/render3/r3_identifiers.ts index e5fb36727e..f665b557dd 100644 --- a/packages/compiler/src/render3/r3_identifiers.ts +++ b/packages/compiler/src/render3/r3_identifiers.ts @@ -23,7 +23,9 @@ export class Identifiers { static namespaceSVG: o.ExternalReference = {name: 'ɵNS', moduleName: CORE}; - static createElement: o.ExternalReference = {name: 'ɵE', moduleName: CORE}; + static element: o.ExternalReference = {name: 'ɵEe', moduleName: CORE}; + + static elementStart: o.ExternalReference = {name: 'ɵE', moduleName: CORE}; static elementEnd: o.ExternalReference = {name: 'ɵe', moduleName: CORE}; diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index eca3a45a39..57ab502aa6 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -357,32 +357,44 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver this.addNamespaceInstruction(currentNamespace, element); } - this.instruction( - this._creationCode, element.sourceSpan, R3.createElement, ...trimTrailingNulls(parameters)); + const isEmptyElement = element.children.length === 0 && element.outputs.length === 0; const implicit = o.variable(CONTEXT_NAME); - // Generate Listeners (outputs) - element.outputs.forEach((outputAst: t.BoundEvent) => { - const elName = sanitizeIdentifier(element.name); - const evName = sanitizeIdentifier(outputAst.name); - const functionName = `${this.templateName}_${elName}_${evName}_listener`; - const localVars: o.Statement[] = []; - const bindingScope = - this._bindingScope.nestedScope((lhsVar: o.ReadVarExpr, rhsExpression: o.Expression) => { - localVars.push( - lhsVar.set(rhsExpression).toDeclStmt(o.INFERRED_TYPE, [o.StmtModifier.Final])); - }); - const bindingExpr = convertActionBinding( - bindingScope, implicit, outputAst.handler, 'b', () => error('Unexpected interpolation')); - const handler = o.fn( - [new o.FnParam('$event', o.DYNAMIC_TYPE)], [...localVars, ...bindingExpr.render3Stmts], - o.INFERRED_TYPE, null, functionName); + if (isEmptyElement) { this.instruction( - this._creationCode, outputAst.sourceSpan, R3.listener, o.literal(outputAst.name), - handler); - }); + this._creationCode, element.sourceSpan, R3.element, ...trimTrailingNulls(parameters)); + } else { + // Generate the instruction create element instruction + if (i18nMessages.length > 0) { + this._creationCode.push(...i18nMessages); + } + this.instruction( + this._creationCode, element.sourceSpan, R3.elementStart, + ...trimTrailingNulls(parameters)); + // Generate Listeners (outputs) + element.outputs.forEach((outputAst: t.BoundEvent) => { + const elName = sanitizeIdentifier(element.name); + const evName = sanitizeIdentifier(outputAst.name); + const functionName = `${this.templateName}_${elName}_${evName}_listener`; + const localVars: o.Statement[] = []; + const bindingScope = + this._bindingScope.nestedScope((lhsVar: o.ReadVarExpr, rhsExpression: o.Expression) => { + localVars.push( + lhsVar.set(rhsExpression).toDeclStmt(o.INFERRED_TYPE, [o.StmtModifier.Final])); + }); + const bindingExpr = convertActionBinding( + bindingScope, implicit, outputAst.handler, 'b', + () => error('Unexpected interpolation')); + const handler = o.fn( + [new o.FnParam('$event', o.DYNAMIC_TYPE)], [...localVars, ...bindingExpr.render3Stmts], + o.INFERRED_TYPE, null, functionName); + this.instruction( + this._creationCode, outputAst.sourceSpan, R3.listener, o.literal(outputAst.name), + handler); + }); + } // Generate element input bindings element.inputs.forEach((input: t.BoundAttribute) => { @@ -422,9 +434,11 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver t.visitAll(this, element.children); } - // Finish element construction mode. - this.instruction( - this._creationCode, element.endSourceSpan || element.sourceSpan, R3.elementEnd); + if (!isEmptyElement) { + // Finish element construction mode. + this.instruction( + this._creationCode, element.endSourceSpan || element.sourceSpan, R3.elementEnd); + } // Restore the state before exiting this node this._inI18nSection = wasInI18nSection; diff --git a/packages/compiler/test/render3/r3_compiler_compliance_spec.ts b/packages/compiler/test/render3/r3_compiler_compliance_spec.ts index f0371076b3..a61016f656 100644 --- a/packages/compiler/test/render3/r3_compiler_compliance_spec.ts +++ b/packages/compiler/test/render3/r3_compiler_compliance_spec.ts @@ -52,8 +52,7 @@ describe('compiler compliance', () => { $r3$.ɵE(0, 'div', $c1$); $r3$.ɵNS(); $r3$.ɵE(1, 'svg'); - $r3$.ɵE(2, 'circle', $c2$); - $r3$.ɵe(); + $r3$.ɵEe(2, 'circle', $c2$); $r3$.ɵe(); $r3$.ɵNH(); $r3$.ɵE(3, 'p'); @@ -101,8 +100,7 @@ describe('compiler compliance', () => { $r3$.ɵE(0, 'div', $c1$); $r3$.ɵNM(); $r3$.ɵE(1, 'math'); - $r3$.ɵE(2, 'infinity'); - $r3$.ɵe(); + $r3$.ɵEe(2, 'infinity'); $r3$.ɵe(); $r3$.ɵNH(); $r3$.ɵE(3, 'p'); @@ -189,8 +187,7 @@ describe('compiler compliance', () => { const template = ` template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.id)); @@ -234,9 +231,8 @@ describe('compiler compliance', () => { const template = ` template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { if (rf & 1) { - $r3$.ɵE(0, 'div'); + $r3$.ɵEe(0, 'div'); $r3$.ɵPp(1,'pipe'); - $r3$.ɵe(); $r3$.ɵrS(10); } if (rf & 2) { @@ -280,8 +276,7 @@ describe('compiler compliance', () => { const template = ` template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵkn(0, 'error', $r3$.ɵb(ctx.error)); @@ -353,8 +348,7 @@ describe('compiler compliance', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { if (rf & 1) { - $r3$.ɵE(0, 'child', $c1$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'child', $c1$); $r3$.ɵT(1, '!'); } }, @@ -560,8 +554,7 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-comp'); $r3$.ɵrS(2); } if (rf & 2) { @@ -640,8 +633,7 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-comp'); $r3$.ɵrS(10); } if (rf & 2) { @@ -702,8 +694,7 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'object-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'object-comp'); $r3$.ɵrS(2); } if (rf & 2) { @@ -768,8 +759,7 @@ describe('compiler compliance', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'nested-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'nested-comp'); $r3$.ɵrS(7); } if (rf & 2) { @@ -913,8 +903,7 @@ describe('compiler compliance', () => { var $tmp$: $any$; if (rf & 1) { $r3$.ɵQ(0, SomeDirective, true); - $r3$.ɵE(1, 'div', $e0_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(1, 'div', $e0_attrs$); } if (rf & 2) { ($r3$.ɵqR(($tmp$ = $r3$.ɵld(0))) && (ctx.someDir = $tmp$.first)); @@ -1108,8 +1097,7 @@ describe('compiler compliance', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { if (rf & 1) { - $r3$.ɵE(0, 'input', null, $c1$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'input', null, $c1$); $r3$.ɵT(2); } const $user$ = $r3$.ɵld(1); @@ -1188,10 +1176,8 @@ describe('compiler compliance', () => { factory: function SimpleLayout_Factory() { return new SimpleLayout(); }, template: function SimpleLayout_Template(rf: IDENT, ctx: IDENT) { if (rf & 1) { - $r3$.ɵE(0, 'lifecycle-comp'); - $r3$.ɵe(); - $r3$.ɵE(1, 'lifecycle-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'lifecycle-comp'); + $r3$.ɵEe(1, 'lifecycle-comp'); } if (rf & 2) { $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1)); @@ -1319,8 +1305,7 @@ describe('compiler compliance', () => { if (rf & 1) { $r3$.ɵNS(); $r3$.ɵE(0,'g'); - $r3$.ɵE(1,'circle'); - $r3$.ɵe(); + $r3$.ɵEe(1,'circle'); $r3$.ɵe(); } } diff --git a/packages/compiler/test/render3/r3_view_compiler_binding_spec.ts b/packages/compiler/test/render3/r3_view_compiler_binding_spec.ts index 8b0a9edcbe..a9f4f3672e 100644 --- a/packages/compiler/test/render3/r3_view_compiler_binding_spec.ts +++ b/packages/compiler/test/render3/r3_view_compiler_binding_spec.ts @@ -75,8 +75,7 @@ describe('compiler compliance: bindings', () => { const template = ` template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ if (rf & 1) { - $i0$.ɵE(0, 'a'); - $i0$.ɵe(); + $i0$.ɵEe(0, 'a'); } if (rf & 2) { $i0$.ɵp(0, 'title', $i0$.ɵb($ctx$.title)); @@ -108,8 +107,7 @@ describe('compiler compliance: bindings', () => { const template = ` template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ if (rf & 1) { - $i0$.ɵE(0, 'a'); - $i0$.ɵe(); + $i0$.ɵEe(0, 'a'); } if (rf & 2) { $i0$.ɵp(0, 'title', $i0$.ɵi1('Hello ', $ctx$.name, '')); diff --git a/packages/compiler/test/render3/r3_view_compiler_i18n_spec.ts b/packages/compiler/test/render3/r3_view_compiler_i18n_spec.ts index 3839df2615..1065b3acb9 100644 --- a/packages/compiler/test/render3/r3_view_compiler_i18n_spec.ts +++ b/packages/compiler/test/render3/r3_view_compiler_i18n_spec.ts @@ -148,8 +148,7 @@ describe('i18n support in the view compiler', () => { … template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { if (rf & 1) { - $r3$.ɵE(0, 'div', $c1$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div', $c1$); } } `; diff --git a/packages/compiler/test/render3/r3_view_compiler_styling_spec.ts b/packages/compiler/test/render3/r3_view_compiler_styling_spec.ts index df527a99d5..05249bcd1e 100644 --- a/packages/compiler/test/render3/r3_view_compiler_styling_spec.ts +++ b/packages/compiler/test/render3/r3_view_compiler_styling_spec.ts @@ -40,8 +40,7 @@ describe('compiler compliance: styling', () => { const template = ` template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵs(0,$r3$.ɵb($ctx$.myStyleExp)); @@ -78,8 +77,7 @@ describe('compiler compliance: styling', () => { const template = ` template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵk(0,$r3$.ɵb($ctx$.myClassExp)); diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 60df2a44cd..c944bace23 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -33,6 +33,7 @@ export { NH as ɵNH, NM as ɵNM, NS as ɵNS, + Ee as ɵEe, L as ɵL, T as ɵT, V as ɵV, diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index e57520dc1c..df2efee76c 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -44,6 +44,7 @@ export { containerRefreshStart as cR, containerRefreshEnd as cr, + element as Ee, elementAttribute as a, elementClass as k, elementClassNamed as kn, diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index 24d25effdf..133decaf37 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -573,6 +573,20 @@ export function namespaceHTML() { //// Element ////////////////////////// +/** + * Creates an empty element using {@link elementStart} and {@link elementEnd} + * + * @param index Index of the element in the data array + * @param name Name of the DOM Node + * @param attrs Statically bound set of attributes to be written into the DOM element on creation. + * @param localRefs A set of local reference bindings on the element. + */ +export function element( + index: number, name: string, attrs?: TAttributes | null, localRefs?: string[] | null): void { + elementStart(index, name, attrs, localRefs); + elementEnd(); +} + /** * Create DOM element. The instruction must later be followed by `elementEnd()` call. * diff --git a/packages/core/src/render3/jit/environment.ts b/packages/core/src/render3/jit/environment.ts index 0496c64a8b..3db548c1da 100644 --- a/packages/core/src/render3/jit/environment.ts +++ b/packages/core/src/render3/jit/environment.ts @@ -41,6 +41,7 @@ export const angularCoreEnv: {[name: string]: Function} = { 'ɵNS': r3.NS, 'ɵE': r3.E, 'ɵe': r3.e, + 'ɵEe': r3.Ee, 'ɵf0': r3.f0, 'ɵf1': r3.f1, 'ɵf2': r3.f2, diff --git a/packages/core/test/render3/compiler_canonical/component_directives_spec.ts b/packages/core/test/render3/compiler_canonical/component_directives_spec.ts index 7c1e6a7845..d15391a594 100644 --- a/packages/core/test/render3/compiler_canonical/component_directives_spec.ts +++ b/packages/core/test/render3/compiler_canonical/component_directives_spec.ts @@ -69,8 +69,7 @@ describe('components & directives', () => { factory: () => new MyComponent(), template: function(rf: $RenderFlags$, ctx: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'child', $e0_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'child', $e0_attrs$); $r3$.ɵT(1, '!'); } } @@ -121,8 +120,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'div', $e0_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div', $e0_attrs$); } } }); @@ -217,8 +215,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'div', $e0_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div', $e0_attrs$); } } }); @@ -265,8 +262,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'div', $e0_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div', $e0_attrs$); } } }); @@ -325,8 +321,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-comp'); } if (rf & 2) { $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name)); @@ -455,8 +450,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-array-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-array-comp'); } if (rf & 2) { $r3$.ɵp(0, 'names', rf & 1 ? $e0_arr$ : $r3$.ɵNC); @@ -500,8 +494,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-array-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-array-comp'); $r3$.ɵrS(1); } if (rf & 2) { @@ -562,8 +555,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-comp'); $r3$.ɵrS(1); } if (rf & 2) { @@ -606,8 +598,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-array-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-array-comp'); $r3$.ɵrS(2); } if (rf & 2) { @@ -717,8 +708,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, c: $any$) { if (rf & 1) { - $r3$.ɵE(0, 'my-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-comp'); $r3$.ɵrS(10); } if (rf & 2) { @@ -796,8 +786,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'object-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'object-comp'); $r3$.ɵrS(2); } if (rf & 2) { @@ -882,8 +871,7 @@ describe('components & directives', () => { factory: function MyApp_Factory() { return new MyApp(); }, template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'nested-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'nested-comp'); $r3$.ɵrS(7); } if (rf & 2) { diff --git a/packages/core/test/render3/compiler_canonical/content_projection_spec.ts b/packages/core/test/render3/compiler_canonical/content_projection_spec.ts index 12171ea99a..c7a35758c0 100644 --- a/packages/core/test/render3/compiler_canonical/content_projection_spec.ts +++ b/packages/core/test/render3/compiler_canonical/content_projection_spec.ts @@ -28,9 +28,8 @@ describe('content projection', () => { template: function(rf: $RenderFlags$, ctx: $SimpleComponent$) { if (rf & 1) { $r3$.ɵpD(0); - $r3$.ɵE(1, 'div'); + $r3$.ɵEe(1, 'div'); $r3$.ɵP(2, 0); - $r3$.ɵe(); } } }); @@ -58,12 +57,10 @@ describe('content projection', () => { template: function(rf: $RenderFlags$, ctx: $ComplexComponent$) { if (rf & 1) { $r3$.ɵpD(0, $pD_0P$, $pD_0R$); - $r3$.ɵE(1, 'div', ['id', 'first']); + $r3$.ɵEe(1, 'div', ['id', 'first']); $r3$.ɵP(2, 0, 1); - $r3$.ɵe(); - $r3$.ɵE(3, 'div', ['id', 'second']); + $r3$.ɵEe(3, 'div', ['id', 'second']); $r3$.ɵP(4, 0, 2); - $r3$.ɵe(); } } }); diff --git a/packages/core/test/render3/compiler_canonical/elements_spec.ts b/packages/core/test/render3/compiler_canonical/elements_spec.ts index 1155b8b229..0f1dd08873 100644 --- a/packages/core/test/render3/compiler_canonical/elements_spec.ts +++ b/packages/core/test/render3/compiler_canonical/elements_spec.ts @@ -91,8 +91,7 @@ describe('elements', () => { let $tmp$: any; let $tmp_2$: any; if (rf & 1) { - $r3$.ɵE(0, 'div', $e0_attrs$, $e0_locals$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div', $e0_attrs$, $e0_locals$); $r3$.ɵT(3); } if (rf & 2) { @@ -165,8 +164,7 @@ describe('elements', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someProperty)); @@ -197,8 +195,7 @@ describe('elements', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵa(0, 'title', $r3$.ɵb(ctx.someAttribute)); @@ -229,8 +226,7 @@ describe('elements', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵkn(0, 'foo', $r3$.ɵb(ctx.someFlag)); @@ -265,8 +261,7 @@ describe('elements', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵsn(0, 'color', $r3$.ɵb(ctx.someColor)); @@ -315,8 +310,7 @@ describe('elements', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div', $e0_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div', $e0_attrs$); } if (rf & 2) { $r3$.ɵp(0, 'id', $r3$.ɵb(ctx.someString + 1)); @@ -351,8 +345,7 @@ describe('elements', () => { factory: function StyleComponent_Factory() { return new StyleComponent(); }, template: function StyleComponent_Template(rf: $RenderFlags$, ctx: $StyleComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); } if (rf & 2) { $r3$.ɵk(0, $r3$.ɵb(ctx.classExp)); diff --git a/packages/core/test/render3/compiler_canonical/injection_spec.ts b/packages/core/test/render3/compiler_canonical/injection_spec.ts index 827cd27a77..9dc873476a 100644 --- a/packages/core/test/render3/compiler_canonical/injection_spec.ts +++ b/packages/core/test/render3/compiler_canonical/injection_spec.ts @@ -54,8 +54,7 @@ describe('injection', () => { /** */ template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-comp'); } }, directives: () => [MyComp] @@ -101,8 +100,7 @@ describe('injection', () => { /** */ template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { if (rf & 1) { - $r3$.ɵE(0, 'my-comp', e0_attrs); - $r3$.ɵe(); + $r3$.ɵEe(0, 'my-comp', e0_attrs); } }, directives: () => [MyComp] diff --git a/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts b/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts index 0f4f5113a0..6577777e51 100644 --- a/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts +++ b/packages/core/test/render3/compiler_canonical/life_cycle_spec.ts @@ -70,10 +70,8 @@ describe('lifecycle hooks', () => { factory: function SimpleLayout_Factory() { return simpleLayout = new SimpleLayout(); }, template: function SimpleLayout_Template(rf: $RenderFlags$, ctx: $SimpleLayout$) { if (rf & 1) { - $r3$.ɵE(0, 'lifecycle-comp'); - $r3$.ɵe(); - $r3$.ɵE(1, 'lifecycle-comp'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'lifecycle-comp'); + $r3$.ɵEe(1, 'lifecycle-comp'); } if (rf & 2) { $r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1)); diff --git a/packages/core/test/render3/compiler_canonical/local_reference_spec.ts b/packages/core/test/render3/compiler_canonical/local_reference_spec.ts index 99b6c6ecbf..a5c404814c 100644 --- a/packages/core/test/render3/compiler_canonical/local_reference_spec.ts +++ b/packages/core/test/render3/compiler_canonical/local_reference_spec.ts @@ -28,8 +28,7 @@ describe('local references', () => { template: function(rf: $RenderFlags$, ctx: $MyComponent$) { let l1_user: any; if (rf & 1) { - $r3$.ɵE(0, 'input', null, ['user', '']); - $r3$.ɵe(); + $r3$.ɵEe(0, 'input', null, ['user', '']); $r3$.ɵT(2); } if (rf & 2) { diff --git a/packages/core/test/render3/compiler_canonical/query_spec.ts b/packages/core/test/render3/compiler_canonical/query_spec.ts index d3e19413e3..10f6f1221e 100644 --- a/packages/core/test/render3/compiler_canonical/query_spec.ts +++ b/packages/core/test/render3/compiler_canonical/query_spec.ts @@ -58,8 +58,7 @@ describe('queries', () => { if (rf & 1) { $r3$.ɵQ(0, SomeDirective, false); $r3$.ɵQ(1, SomeDirective, false); - $r3$.ɵE(2, 'div', $e1_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(2, 'div', $e1_attrs$); } if (rf & 2) { $r3$.ɵqR($tmp$ = $r3$.ɵld>(0)) && (ctx.someDir = $tmp$.first); @@ -147,8 +146,7 @@ describe('queries', () => { if (rf & 1) { $r3$.ɵE(0, 'content-query-component'); contentQueryComp = $r3$.ɵd(0)[0]; - $r3$.ɵE(1, 'div', $e2_attrs$); - $r3$.ɵe(); + $r3$.ɵEe(1, 'div', $e2_attrs$); $r3$.ɵe(); } } diff --git a/packages/core/test/render3/compiler_canonical/sanitize_spec.ts b/packages/core/test/render3/compiler_canonical/sanitize_spec.ts index 8137445076..bc73d1e105 100644 --- a/packages/core/test/render3/compiler_canonical/sanitize_spec.ts +++ b/packages/core/test/render3/compiler_canonical/sanitize_spec.ts @@ -43,10 +43,8 @@ describe('compiler sanitization', () => { factory: function MyComponent_Factory() { return new MyComponent(); }, template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { if (rf & 1) { - $r3$.ɵE(0, 'div'); - $r3$.ɵe(); - $r3$.ɵE(1, 'img'); - $r3$.ɵe(); + $r3$.ɵEe(0, 'div'); + $r3$.ɵEe(1, 'img'); } if (rf & 2) { $r3$.ɵp(0, 'innerHTML', $r3$.ɵb(ctx.innerHTML), $r3$.ɵsanitizeHtml); diff --git a/packages/core/test/render3/instructions_spec.ts b/packages/core/test/render3/instructions_spec.ts index 7a59ec8834..d3302788eb 100644 --- a/packages/core/test/render3/instructions_spec.ts +++ b/packages/core/test/render3/instructions_spec.ts @@ -10,7 +10,7 @@ import {NgForOfContext} from '@angular/common'; import {RenderFlags, directiveInject} from '../../src/render3'; import {defineComponent} from '../../src/render3/definition'; -import {bind, container, elementAttribute, elementClass, elementEnd, elementProperty, elementStart, elementStyle, elementStyleNamed, interpolation1, renderTemplate, text, textBinding} from '../../src/render3/instructions'; +import {bind, container, element, elementAttribute, elementClass, elementEnd, elementProperty, elementStart, elementStyle, elementStyleNamed, interpolation1, renderTemplate, text, textBinding} from '../../src/render3/instructions'; import {LElementNode, LNode} from '../../src/render3/interfaces/node'; import {RElement, domRendererFactory3} from '../../src/render3/interfaces/renderer'; import {TrustedString, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization'; @@ -72,6 +72,23 @@ describe('instructions', () => { }); }); + describe('element', () => { + it('should create an element', () => { + const t = new TemplateFixture(() => { element(0, 'div', ['id', 'test', 'title', 'Hello']); }); + + const div = (t.hostNode.native as HTMLElement).querySelector('div') !; + expect(div.id).toEqual('test'); + expect(div.title).toEqual('Hello'); + + expect(ngDevMode).toHaveProperties({ + firstTemplatePass: 1, + tNode: 2, // 1 for div, 1 for host element + tView: 1, + rendererCreateElement: 1, + }); + }); + }); + describe('elementAttribute', () => { it('should use sanitizer function', () => { const t = new TemplateFixture(createDiv);