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 6ee98313b1..ccf6bb2eef 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 @@ -580,8 +580,8 @@ describe('i18n support in the view compiler', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵelementStart(0, "div"); - $r3$.ɵi18n(1, $MSG_EXTERNAL_4969674997806975147$$APP_SPEC_TS_0$); - $r3$.ɵi18nAttributes(2, $_c0$); + $r3$.ɵi18nAttributes(1, $_c0$); + $r3$.ɵi18n(2, $MSG_EXTERNAL_4969674997806975147$$APP_SPEC_TS_0$); $r3$.ɵelementEnd(); } } diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index 7058630ada..4f1f1762bf 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -619,10 +619,6 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver this.creationInstruction(element.sourceSpan, R3.disableBindings); } - if (isI18nRootElement) { - this.i18nStart(element.sourceSpan, element.i18n !, createSelfClosingI18nInstruction); - } - // process i18n element attributes if (i18nAttrs.length) { let hasBindings: boolean = false; @@ -656,6 +652,12 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver } } + // Note: it's important to keep i18n/i18nStart instructions after i18nAttributes ones, + // to make sure i18nAttributes instruction targets current element at runtime. + if (isI18nRootElement) { + this.i18nStart(element.sourceSpan, element.i18n !, createSelfClosingI18nInstruction); + } + // The style bindings code is placed into two distinct blocks within the template function AOT // code: creation and update. The creation code contains the `elementStyling` instructions // which will apply the collected binding values to the element. `elementStyling` is diff --git a/packages/core/test/i18n_integration_spec.ts b/packages/core/test/i18n_integration_spec.ts index e4d2f3bbf0..6463305be2 100644 --- a/packages/core/test/i18n_integration_spec.ts +++ b/packages/core/test/i18n_integration_spec.ts @@ -117,19 +117,18 @@ onlyInIvy('Ivy i18n logic').describe('i18n', function() { } }); - fixmeIvy('FW-904: i18n attributes placed on i18n root node don\'t work') - .it('should work correctly when placed on i18n root node', () => { - const title = 'Hello {{ name }}'; - const content = 'Hello'; - const template = ` + it('should work correctly when placed on i18n root node', () => { + const title = 'Hello {{ name }}'; + const content = 'Hello'; + const template = `
${content}
`; - const fixture = getFixtureWithOverrides({template}); + const fixture = getFixtureWithOverrides({template}); - const element = fixture.nativeElement.firstChild; - expect(element.title).toBe('Bonjour John'); - expect(element).toHaveText('Bonjour'); - }); + const element = fixture.nativeElement.firstChild; + expect(element.title).toBe('Bonjour John'); + expect(element).toHaveText('Bonjour'); + }); it('should add i18n attributes on self-closing tags', () => { const title = 'Hello {{ name }}';