refactor(i18n): misc
This commit is contained in:
parent
58b18d7fe7
commit
99587ea4ed
|
@ -20,60 +20,7 @@ let _PLACEHOLDER_EXPANDED_REGEXP = /<ph(\s)+name=("(\w)+")><\/ph>/gi;
|
||||||
*
|
*
|
||||||
* Algorithm:
|
* Algorithm:
|
||||||
*
|
*
|
||||||
* To understand the algorithm, you need to know how partitioning works.
|
* See `message_extractor.ts` for details on the partitioning algorithm.
|
||||||
* Partitioning is required as we can use two i18n comments to group node siblings together.
|
|
||||||
* That is why we cannot just use nodes.
|
|
||||||
*
|
|
||||||
* Partitioning transforms an array of HtmlAst into an array of Part.
|
|
||||||
* A part can optionally contain a root element or a root text node. And it can also contain
|
|
||||||
* children.
|
|
||||||
* A part can contain i18n property, in which case it needs to be translated.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* The following array of nodes will be split into four parts:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* <a>A</a>
|
|
||||||
* <b i18n>B</b>
|
|
||||||
* <!-- i18n -->
|
|
||||||
* <c>C</c>
|
|
||||||
* D
|
|
||||||
* <!-- /i18n -->
|
|
||||||
* E
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Part 1 containing the a tag. It should not be translated.
|
|
||||||
* Part 2 containing the b tag. It should be translated.
|
|
||||||
* Part 3 containing the c tag and the D text node. It should be translated.
|
|
||||||
* Part 4 containing the E text node. It should not be translated.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* It is also important to understand how we stringify nodes to create a message.
|
|
||||||
*
|
|
||||||
* We walk the tree and replace every element node with a placeholder. We also replace
|
|
||||||
* all expressions in interpolation with placeholders. We also insert a placeholder element
|
|
||||||
* to wrap a text node containing interpolation.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* The following tree:
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* <a>A{{I}}</a><b>B</b>
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* will be stringified into:
|
|
||||||
* ```
|
|
||||||
* <ph name="e0"><ph name="t1">A<ph name="0"/></ph></ph><ph name="e2">B</ph>
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* This is what the algorithm does:
|
|
||||||
*
|
|
||||||
* 1. Use the provided html parser to get the html AST of the template.
|
|
||||||
* 2. Partition the root nodes, and process each part separately.
|
|
||||||
* 3. If a part does not have the i18n attribute, recurse to process children and attributes.
|
|
||||||
* 4. If a part has the i18n attribute, merge the translated i18n part with the original tree.
|
|
||||||
*
|
*
|
||||||
* This is how the merging works:
|
* This is how the merging works:
|
||||||
*
|
*
|
||||||
|
|
|
@ -147,6 +147,7 @@ export class MessageExtractor {
|
||||||
isPresent(this._implicitAttrs[p.name]) ? this._implicitAttrs[p.name] : [];
|
isPresent(this._implicitAttrs[p.name]) ? this._implicitAttrs[p.name] : [];
|
||||||
let explicitAttrs: string[] = [];
|
let explicitAttrs: string[] = [];
|
||||||
|
|
||||||
|
// `i18n-` prefixed attributes should be translated
|
||||||
p.attrs.filter(attr => attr.name.startsWith(I18N_ATTR_PREFIX)).forEach(attr => {
|
p.attrs.filter(attr => attr.name.startsWith(I18N_ATTR_PREFIX)).forEach(attr => {
|
||||||
try {
|
try {
|
||||||
explicitAttrs.push(attr.name.substring(I18N_ATTR_PREFIX.length));
|
explicitAttrs.push(attr.name.substring(I18N_ATTR_PREFIX.length));
|
||||||
|
@ -161,6 +162,7 @@ export class MessageExtractor {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// implicit attributes should also be translated
|
||||||
p.attrs.filter(attr => !attr.name.startsWith(I18N_ATTR_PREFIX))
|
p.attrs.filter(attr => !attr.name.startsWith(I18N_ATTR_PREFIX))
|
||||||
.filter(attr => explicitAttrs.indexOf(attr.name) == -1)
|
.filter(attr => explicitAttrs.indexOf(attr.name) == -1)
|
||||||
.filter(attr => transAttrs.indexOf(attr.name) > -1)
|
.filter(attr => transAttrs.indexOf(attr.name) > -1)
|
||||||
|
|
|
@ -77,7 +77,7 @@ function _isOpeningComment(n: HtmlAst): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
function _isClosingComment(n: HtmlAst): boolean {
|
function _isClosingComment(n: HtmlAst): boolean {
|
||||||
return n instanceof HtmlCommentAst && isPresent(n.value) && n.value == '/i18n';
|
return n instanceof HtmlCommentAst && isPresent(n.value) && n.value === '/i18n';
|
||||||
}
|
}
|
||||||
|
|
||||||
function _findI18nAttr(p: HtmlElementAst): HtmlAttrAst {
|
function _findI18nAttr(p: HtmlElementAst): HtmlAttrAst {
|
||||||
|
|
Loading…
Reference in New Issue