feat(compiler): add id property to i18nMessage
This commit is contained in:
parent
72361fb68f
commit
6dd5201765
@ -18,6 +18,8 @@ import {TranslationBundle} from './translation_bundle';
|
|||||||
const _I18N_ATTR = 'i18n';
|
const _I18N_ATTR = 'i18n';
|
||||||
const _I18N_ATTR_PREFIX = 'i18n-';
|
const _I18N_ATTR_PREFIX = 'i18n-';
|
||||||
const _I18N_COMMENT_PREFIX_REGEXP = /^i18n:?/;
|
const _I18N_COMMENT_PREFIX_REGEXP = /^i18n:?/;
|
||||||
|
const MEANING_SEPARATOR = '|';
|
||||||
|
const ID_SEPARATOR = '@@';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract translatable messages from an html AST
|
* Extract translatable messages from an html AST
|
||||||
@ -77,7 +79,7 @@ class _Visitor implements html.Visitor {
|
|||||||
// _VisitorMode.Merge only
|
// _VisitorMode.Merge only
|
||||||
private _translations: TranslationBundle;
|
private _translations: TranslationBundle;
|
||||||
private _createI18nMessage:
|
private _createI18nMessage:
|
||||||
(msg: html.Node[], meaning: string, description: string) => i18n.Message;
|
(msg: html.Node[], meaning: string, description: string, id: string) => i18n.Message;
|
||||||
|
|
||||||
|
|
||||||
constructor(private _implicitTags: string[], private _implicitAttrs: {[k: string]: string[]}) {}
|
constructor(private _implicitTags: string[], private _implicitAttrs: {[k: string]: string[]}) {}
|
||||||
@ -330,15 +332,15 @@ class _Visitor implements html.Visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add a translatable message
|
// add a translatable message
|
||||||
private _addMessage(ast: html.Node[], meaningAndDesc?: string): i18n.Message {
|
private _addMessage(ast: html.Node[], msgMeta?: string): i18n.Message {
|
||||||
if (ast.length == 0 ||
|
if (ast.length == 0 ||
|
||||||
ast.length == 1 && ast[0] instanceof html.Attribute && !(<html.Attribute>ast[0]).value) {
|
ast.length == 1 && ast[0] instanceof html.Attribute && !(<html.Attribute>ast[0]).value) {
|
||||||
// Do not create empty messages
|
// Do not create empty messages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [meaning, description] = _splitMeaningAndDesc(meaningAndDesc);
|
const {meaning, description, id} = _parseMessageMeta(msgMeta);
|
||||||
const message = this._createI18nMessage(ast, meaning, description);
|
const message = this._createI18nMessage(ast, meaning, description, id);
|
||||||
this._messages.push(message);
|
this._messages.push(message);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
@ -368,7 +370,7 @@ class _Visitor implements html.Visitor {
|
|||||||
attributes.forEach(attr => {
|
attributes.forEach(attr => {
|
||||||
if (attr.name.startsWith(_I18N_ATTR_PREFIX)) {
|
if (attr.name.startsWith(_I18N_ATTR_PREFIX)) {
|
||||||
i18nAttributeMeanings[attr.name.slice(_I18N_ATTR_PREFIX.length)] =
|
i18nAttributeMeanings[attr.name.slice(_I18N_ATTR_PREFIX.length)] =
|
||||||
_splitMeaningAndDesc(attr.value)[0];
|
_parseMessageMeta(attr.value).meaning;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -382,7 +384,7 @@ class _Visitor implements html.Visitor {
|
|||||||
|
|
||||||
if (attr.value && attr.value != '' && i18nAttributeMeanings.hasOwnProperty(attr.name)) {
|
if (attr.value && attr.value != '' && i18nAttributeMeanings.hasOwnProperty(attr.name)) {
|
||||||
const meaning = i18nAttributeMeanings[attr.name];
|
const meaning = i18nAttributeMeanings[attr.name];
|
||||||
const message: i18n.Message = this._createI18nMessage([attr], meaning, '');
|
const message: i18n.Message = this._createI18nMessage([attr], meaning, '', '');
|
||||||
const nodes = this._translations.get(message);
|
const nodes = this._translations.get(message);
|
||||||
if (nodes) {
|
if (nodes) {
|
||||||
if (nodes[0] instanceof html.Text) {
|
if (nodes[0] instanceof html.Text) {
|
||||||
@ -496,8 +498,15 @@ function _getI18nAttr(p: html.Element): html.Attribute {
|
|||||||
return p.attrs.find(attr => attr.name === _I18N_ATTR) || null;
|
return p.attrs.find(attr => attr.name === _I18N_ATTR) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _splitMeaningAndDesc(i18n: string): [string, string] {
|
function _parseMessageMeta(i18n: string): {meaning: string, description: string, id: string} {
|
||||||
if (!i18n) return ['', ''];
|
if (!i18n) return {meaning: '', description: '', id: ''};
|
||||||
const pipeIndex = i18n.indexOf('|');
|
|
||||||
return pipeIndex == -1 ? ['', i18n] : [i18n.slice(0, pipeIndex), i18n.slice(pipeIndex + 1)];
|
const idIndex = i18n.indexOf(ID_SEPARATOR);
|
||||||
|
const descIndex = i18n.indexOf(MEANING_SEPARATOR);
|
||||||
|
const [meaningAndDesc, id] = (idIndex > -1) ? [i18n.slice(0, idIndex), i18n.slice(idIndex + 2)] :
|
||||||
|
[i18n, ''];
|
||||||
|
const [meaning, description] = (descIndex > -1) ? [meaningAndDesc.slice(0, descIndex), meaningAndDesc.slice(descIndex + 1)] :
|
||||||
|
['', meaningAndDesc];
|
||||||
|
|
||||||
|
return {meaning, description, id};
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,12 @@ export class Message {
|
|||||||
* @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
|
* @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
|
||||||
* @param meaning
|
* @param meaning
|
||||||
* @param description
|
* @param description
|
||||||
|
* @param id
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
public nodes: Node[], public placeholders: {[phName: string]: string},
|
public nodes: Node[], public placeholders: {[phName: string]: string},
|
||||||
public placeholderToMessage: {[phName: string]: Message}, public meaning: string,
|
public placeholderToMessage: {[phName: string]: Message}, public meaning: string,
|
||||||
public description: string) {}
|
public description: string, public id: string) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Node {
|
export interface Node {
|
||||||
|
@ -22,11 +22,11 @@ const _expParser = new ExpressionParser(new ExpressionLexer());
|
|||||||
* Returns a function converting html nodes to an i18n Message given an interpolationConfig
|
* Returns a function converting html nodes to an i18n Message given an interpolationConfig
|
||||||
*/
|
*/
|
||||||
export function createI18nMessageFactory(interpolationConfig: InterpolationConfig): (
|
export function createI18nMessageFactory(interpolationConfig: InterpolationConfig): (
|
||||||
nodes: html.Node[], meaning: string, description: string) => i18n.Message {
|
nodes: html.Node[], meaning: string, description: string, id: string) => i18n.Message {
|
||||||
const visitor = new _I18nVisitor(_expParser, interpolationConfig);
|
const visitor = new _I18nVisitor(_expParser, interpolationConfig);
|
||||||
|
|
||||||
return (nodes: html.Node[], meaning: string, description: string) =>
|
return (nodes: html.Node[], meaning: string, description: string, id: string) =>
|
||||||
visitor.toI18nMessage(nodes, meaning, description);
|
visitor.toI18nMessage(nodes, meaning, description, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _I18nVisitor implements html.Visitor {
|
class _I18nVisitor implements html.Visitor {
|
||||||
@ -40,7 +40,7 @@ class _I18nVisitor implements html.Visitor {
|
|||||||
private _expressionParser: ExpressionParser,
|
private _expressionParser: ExpressionParser,
|
||||||
private _interpolationConfig: InterpolationConfig) {}
|
private _interpolationConfig: InterpolationConfig) {}
|
||||||
|
|
||||||
public toI18nMessage(nodes: html.Node[], meaning: string, description: string): i18n.Message {
|
public toI18nMessage(nodes: html.Node[], meaning: string, description: string, id: string): i18n.Message {
|
||||||
this._isIcu = nodes.length == 1 && nodes[0] instanceof html.Expansion;
|
this._isIcu = nodes.length == 1 && nodes[0] instanceof html.Expansion;
|
||||||
this._icuDepth = 0;
|
this._icuDepth = 0;
|
||||||
this._placeholderRegistry = new PlaceholderRegistry();
|
this._placeholderRegistry = new PlaceholderRegistry();
|
||||||
@ -50,7 +50,7 @@ class _I18nVisitor implements html.Visitor {
|
|||||||
const i18nodes: i18n.Node[] = html.visitAll(this, nodes, {});
|
const i18nodes: i18n.Node[] = html.visitAll(this, nodes, {});
|
||||||
|
|
||||||
return new i18n.Message(
|
return new i18n.Message(
|
||||||
i18nodes, this._placeholderToContent, this._placeholderToMessage, meaning, description);
|
i18nodes, this._placeholderToContent, this._placeholderToMessage, meaning, description, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitElement(el: html.Element, context: any): i18n.Node {
|
visitElement(el: html.Element, context: any): i18n.Node {
|
||||||
@ -115,7 +115,7 @@ class _I18nVisitor implements html.Visitor {
|
|||||||
// TODO(vicb): add a html.Node -> i18n.Message cache to avoid having to re-create the msg
|
// TODO(vicb): add a html.Node -> i18n.Message cache to avoid having to re-create the msg
|
||||||
const phName = this._placeholderRegistry.getPlaceholderName('ICU', icu.sourceSpan.toString());
|
const phName = this._placeholderRegistry.getPlaceholderName('ICU', icu.sourceSpan.toString());
|
||||||
const visitor = new _I18nVisitor(this._expressionParser, this._interpolationConfig);
|
const visitor = new _I18nVisitor(this._expressionParser, this._interpolationConfig);
|
||||||
this._placeholderToMessage[phName] = visitor.toI18nMessage([icu], '', '');
|
this._placeholderToMessage[phName] = visitor.toI18nMessage([icu], '', '', '');
|
||||||
return new i18n.IcuPlaceholder(i18nIcu, phName, icu.sourceSpan);
|
return new i18n.IcuPlaceholder(i18nIcu, phName, icu.sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user