From b6f03f28833b4e38a42c1102e02a04f745dc1017 Mon Sep 17 00:00:00 2001 From: Dylan Hunn Date: Wed, 6 Dec 2023 11:47:21 -0800 Subject: [PATCH] refactor(compiler): listeners should be ingested before i18nStart Listener instructions should not be inside the i18n block. Listeners are the only kind of binding that gets ingested into the create block, so we previously missed this case. --- .../nested_nodes/TEST_CASES.json | 10 ++++++++-- ..._listeners.js => event_listeners_template.js} | 0 .../event_listeners_template.pipeline.js | 16 ++++++++++++++++ .../compiler/src/template/pipeline/src/ingest.ts | 12 +++++++++--- 4 files changed, 33 insertions(+), 5 deletions(-) rename packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/{event_listeners.js => event_listeners_template.js} (100%) create mode 100644 packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners_template.pipeline.js diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/TEST_CASES.json index 866074bc69a693..b27f73f74c3df4 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/TEST_CASES.json +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/TEST_CASES.json @@ -240,13 +240,19 @@ ], "expectations": [ { + "files": [ + { + "generated": "event_listeners.js", + "expected": "event_listeners_template.js", + "templatePipelineExpected": "event_listeners_template.pipeline.js" + } + ], "extraChecks": [ "verifyPlaceholdersIntegrity", "verifyUniqueConsts" ] } - ], - "skipForTemplatePipeline": true + ] }, { "description": "should handle ng-content in i18n block", diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners_template.js similarity index 100% rename from packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners.js rename to packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners_template.js diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners_template.pipeline.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners_template.pipeline.js new file mode 100644 index 00000000000000..d8ed304fe1281f --- /dev/null +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_i18n/nested_nodes/event_listeners_template.pipeline.js @@ -0,0 +1,16 @@ +consts: () => { + __i18nMsg__('Hello', [], {}, {}) + return [ + $i18n_0$, + [__AttributeMarker.Bindings__, "click"] + ]; + }, + template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵelementStart(0, "div", 1); + $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener() { return ctx.onClick(); }); + $r3$.ɵɵi18n(1, 0); + $r3$.ɵɵelementEnd(); + } + } + \ No newline at end of file diff --git a/packages/compiler/src/template/pipeline/src/ingest.ts b/packages/compiler/src/template/pipeline/src/ingest.ts index 90843c73cc7935..2d70a764f3b93a 100644 --- a/packages/compiler/src/template/pipeline/src/ingest.ts +++ b/packages/compiler/src/template/pipeline/src/ingest.ts @@ -167,6 +167,14 @@ function ingestElement(unit: ViewCompilationUnit, element: t.Element): void { ingestBindings(unit, startOp, element); ingestReferences(startOp, element); + + // Start i18n, if needed, goes after the element create and bindings, but before the nodes + let i18nBlockId: ir.XrefId|null = null; + if (element.i18n instanceof i18n.Message) { + i18nBlockId = unit.job.allocateXrefId(); + unit.create.push(ir.createI18nStartOp(i18nBlockId, element.i18n)); + } + ingestNodes(unit, element.children); // The source span for the end op is typically the element closing tag. However, if no closing tag @@ -178,9 +186,7 @@ function ingestElement(unit: ViewCompilationUnit, element: t.Element): void { unit.create.push(endOp); // If there is an i18n message associated with this element, insert i18n start and end ops. - if (element.i18n instanceof i18n.Message) { - const i18nBlockId = unit.job.allocateXrefId(); - ir.OpList.insertAfter(ir.createI18nStartOp(i18nBlockId, element.i18n), startOp); + if (i18nBlockId !== null) { ir.OpList.insertBefore(ir.createI18nEndOp(i18nBlockId), endOp); } }