fix(core): fix placeholders handling in i18n.

Prior to this commit, translations were built in the serializers. This
could not work as a single translation can be used for different source
messages having different placeholder content.

Serializers do not try to replace the placeholders any more.
Placeholders are replaced by the translation bundle and the source
message is given as parameter so that the content of the placeholders is
taken into account.

Also XMB ids are now independent of the expression which is replaced by
a placeholder in the extracted file.
fixes #12512
This commit is contained in:
Victor Berchet
2016-11-02 17:40:15 -07:00
parent ed5e98d0df
commit 76e4911e8b
25 changed files with 624 additions and 440 deletions

View File

@ -13,7 +13,9 @@ export function digest(message: i18n.Message): string {
}
export function decimalDigest(message: i18n.Message): string {
return fingerprint(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);
const visitor = new _SerializerIgnoreIcuExpVisitor();
const parts = message.nodes.map(a => a.visit(visitor, null));
return fingerprint(parts.join('') + `[${message.meaning}]`);
}
/**
@ -43,7 +45,7 @@ class _SerializerVisitor implements i18n.Visitor {
}
visitPlaceholder(ph: i18n.Placeholder, context: any): any {
return `<ph name="${ph.name}">${ph.value}</ph>`;
return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
}
visitIcuPlaceholder(ph: i18n.IcuPlaceholder, context?: any): any {
@ -57,6 +59,21 @@ export function serializeNodes(nodes: i18n.Node[]): string[] {
return nodes.map(a => a.visit(serializerVisitor, null));
}
/**
* Serialize the i18n ast to something xml-like in order to generate an UID.
*
* Ignore the ICU expressions so that message IDs stays identical if only the expression changes.
*
* @internal
*/
class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {
visitIcu(icu: i18n.Icu, context: any): any {
let strCases = Object.keys(icu.cases).map((k: string) => `${k} {${icu.cases[k].visit(this)}}`);
// Do not take the expression into account
return `{${icu.type}, ${strCases.join(', ')}}`;
}
}
/**
* Compute the SHA1 of the given string
*