feat(ivy): support ng-content in runtime i18n translations (#30782)

Added a new syntax for projections (`¤` will represent `ng-content` nodes) so that we can treat them specifically.
When we enter an i18n block with the instruction `i18nStart`, a new `delayProjection` variable is set to true to prevent the instruction `projection` from projecting the nodes. Once we reach the `i18nEnd` instruction and encounter a projection in the translation we will project its nodes.
If a projection was removed from a translation, then its nodes won't be projected at all.
The variable `delayProjection` is restored to `false` at the end of `i18nEnd` so that it doesn't stop projections outside of i18n blocks.

FW-1261 #resolve
PR Close #30782
This commit is contained in:
Olivier Combe
2019-05-31 17:11:57 +02:00
committed by Miško Hevery
parent 337b6fe003
commit 00cc905b98
6 changed files with 222 additions and 13 deletions

View File

@ -14,7 +14,8 @@ import {assembleBoundTextPlaceholders, findIndex, getSeqNumberGenerator, updateP
enum TagType {
ELEMENT,
TEMPLATE
TEMPLATE,
PROJECTION
}
/**
@ -94,6 +95,12 @@ export class I18nContext {
appendElement(node: i18n.AST, index: number, closed?: boolean) {
this.appendTag(TagType.ELEMENT, node as i18n.TagPlaceholder, index, closed);
}
appendProjection(node: i18n.AST, index: number) {
// add open and close tags at the same time,
// since we process projected content separately
this.appendTag(TagType.PROJECTION, node as i18n.TagPlaceholder, index, false);
this.appendTag(TagType.PROJECTION, node as i18n.TagPlaceholder, index, true);
}
/**
* Generates an instance of a child context based on the root one,
@ -181,6 +188,7 @@ function findTemplateFn(ctx: number, templateIndex: number | null) {
function serializePlaceholderValue(value: any): string {
const element = (data: any, closed?: boolean) => wrapTag('#', data, closed);
const template = (data: any, closed?: boolean) => wrapTag('*', data, closed);
const projection = (data: any, closed?: boolean) => wrapTag('!', data, closed);
switch (value.type) {
case TagType.ELEMENT:
@ -198,6 +206,9 @@ function serializePlaceholderValue(value: any): string {
case TagType.TEMPLATE:
return template(value, value.closed);
case TagType.PROJECTION:
return projection(value, value.closed);
default:
return value;
}

View File

@ -483,6 +483,9 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
}
this.creationInstruction(ngContent.sourceSpan, R3.projection, parameters);
if (this.i18n) {
this.i18n.appendProjection(ngContent.i18n !, slot);
}
}