From 8a3cebde8bda94f59541adcbf84a65aa317213ff Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Fri, 4 Jan 2019 15:51:33 +0100 Subject: [PATCH] fix(ivy): support ICU messages inside (#27925) PR Close #27925 --- .../core/src/render3/node_manipulation.ts | 13 +++++----- packages/core/test/render3/i18n_spec.ts | 24 ++++++++++++++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/packages/core/src/render3/node_manipulation.ts b/packages/core/src/render3/node_manipulation.ts index e6b817562e..746506edcf 100644 --- a/packages/core/src/render3/node_manipulation.ts +++ b/packages/core/src/render3/node_manipulation.ts @@ -518,13 +518,12 @@ export function getRenderParent(tNode: TNode, currentView: LView): RElement|null return nativeParentNode(currentView[RENDERER], getNativeByTNode(tNode, currentView)); } - const hostTNode = currentView[HOST_NODE]; - - const tNodeParent = tNode.parent; + const tNodeParent = getFirstNonICUParent(tNode); if (tNodeParent != null && tNodeParent.type === TNodeType.ElementContainer) { tNode = getHighestElementContainer(tNodeParent); } + const hostTNode = currentView[HOST_NODE]; return tNode.parent == null && hostTNode !.type === TNodeType.View ? getContainerRenderParent(hostTNode as TViewNode, currentView) : getParentNative(tNode, currentView) as RElement; @@ -677,10 +676,12 @@ export function appendChild( getBeforeNodeForView(index, views, lContainer[NATIVE])); } else if (parentTNode.type === TNodeType.ElementContainer) { const renderParent = getRenderParent(childTNode, currentView) !; - nativeInsertBefore(renderer, renderParent, childEl, parentEl); + const ngContainerAnchorNode = getNativeByTNode(parentTNode, currentView); + nativeInsertBefore(renderer, renderParent, childEl, ngContainerAnchorNode); } else if (parentTNode.type === TNodeType.IcuContainer) { - const icuAnchorNode = getNativeByTNode(childTNode.parent !, currentView) !as RElement; - nativeInsertBefore(renderer, parentEl as RElement, childEl, icuAnchorNode); + const renderParent = getRenderParent(childTNode, currentView) !; + const icuAnchorNode = getNativeByTNode(parentTNode, currentView); + nativeInsertBefore(renderer, renderParent, childEl, icuAnchorNode); } else { isProceduralRenderer(renderer) ? renderer.appendChild(parentEl !as RElement, childEl) : parentEl !.appendChild(childEl); diff --git a/packages/core/test/render3/i18n_spec.ts b/packages/core/test/render3/i18n_spec.ts index b39783b1fc..0c6c6332e0 100644 --- a/packages/core/test/render3/i18n_spec.ts +++ b/packages/core/test/render3/i18n_spec.ts @@ -15,7 +15,7 @@ import {getNativeByIndex} from '../../src/render3/util'; import {NgIf} from './common_with_def'; -import {element, elementEnd, elementStart, template, text, nextContext, bind, elementProperty, projectionDef, projection} from '../../src/render3/instructions'; +import {element, elementEnd, elementStart, template, text, nextContext, bind, elementProperty, projectionDef, projection, elementContainerStart, elementContainerEnd} from '../../src/render3/instructions'; import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nUpdateOpCode, I18nUpdateOpCodes, TI18n} from '../../src/render3/interfaces/i18n'; import {HEADER_OFFSET, LView, TVIEW} from '../../src/render3/interfaces/view'; import {ComponentFixture, TemplateFixture} from './render_util'; @@ -713,6 +713,28 @@ describe('Runtime i18n', () => { expect(fixture.html) .toEqual( '
3 emails
'); + }); + + it('for ICU expressions inside ', () => { + const MSG_DIV = `{�0�, plural, + =0 {no emails!} + =1 {one email} + other {�0� emails} + }`; + const fixture = prepareFixture(() => { + elementStart(0, 'div'); { + elementContainerStart(1); { + i18n(2, MSG_DIV); + } + elementContainerEnd(); + } + elementEnd(); + }, () => { + i18nExp(bind(0)); + i18nApply(2); + }, 3, 1); + + expect(fixture.html).toEqual('
no emails!
'); }); it('for nested ICU expressions', () => {