
This commit contains no changes to code. It only breaks `i18n.ts` file into `i18n.ts` + `i18n_apply.ts` + `i18n_parse.ts` + `i18n_postprocess.ts` for easier maintenance. PR Close #38368
176 lines
7.4 KiB
TypeScript
176 lines
7.4 KiB
TypeScript
/**
|
||
* @license
|
||
* Copyright Google LLC All Rights Reserved.
|
||
*
|
||
* Use of this source code is governed by an MIT-style license that can be
|
||
* found in the LICENSE file at https://angular.io/license
|
||
*/
|
||
import '../../util/ng_dev_mode';
|
||
import '../../util/ng_i18n_closure_mode';
|
||
|
||
import {assertDefined} from '../../util/assert';
|
||
import {bindingUpdated} from '../bindings';
|
||
import {applyI18n, i18nEndFirstPass, pushI18nIndex, setMaskBit} from '../i18n/i18n_apply';
|
||
import {i18nAttributesFirstPass, i18nStartFirstPass} from '../i18n/i18n_parse';
|
||
import {i18nPostprocess} from '../i18n/i18n_postprocess';
|
||
import {HEADER_OFFSET} from '../interfaces/view';
|
||
import {getLView, getTView, nextBindingIndex} from '../state';
|
||
|
||
import {setDelayProjection} from './all';
|
||
|
||
/**
|
||
* Marks a block of text as translatable.
|
||
*
|
||
* The instructions `i18nStart` and `i18nEnd` mark the translation block in the template.
|
||
* The translation `message` is the value which is locale specific. The translation string may
|
||
* contain placeholders which associate inner elements and sub-templates within the translation.
|
||
*
|
||
* The translation `message` placeholders are:
|
||
* - `<60>{index}(:{block})<29>`: *Binding Placeholder*: Marks a location where an expression will be
|
||
* interpolated into. The placeholder `index` points to the expression binding index. An optional
|
||
* `block` that matches the sub-template in which it was declared.
|
||
* - `<60>#{index}(:{block})<29>`/`<60>/#{index}(:{block})<29>`: *Element Placeholder*: Marks the beginning
|
||
* and end of DOM element that were embedded in the original translation block. The placeholder
|
||
* `index` points to the element index in the template instructions set. An optional `block` that
|
||
* matches the sub-template in which it was declared.
|
||
* - `<60>!{index}(:{block})<29>`/`<60>/!{index}(:{block})<29>`: *Projection Placeholder*: Marks the
|
||
* beginning and end of <ng-content> that was embedded in the original translation block.
|
||
* The placeholder `index` points to the element index in the template instructions set.
|
||
* An optional `block` that matches the sub-template in which it was declared.
|
||
* - `<60>*{index}:{block}<7D>`/`<60>/*{index}:{block}<7D>`: *Sub-template Placeholder*: Sub-templates must be
|
||
* split up and translated separately in each angular template function. The `index` points to the
|
||
* `template` instruction index. A `block` that matches the sub-template in which it was declared.
|
||
*
|
||
* @param index A unique index of the translation in the static block.
|
||
* @param message The translation message.
|
||
* @param subTemplateIndex Optional sub-template index in the `message`.
|
||
*
|
||
* @codeGenApi
|
||
*/
|
||
export function ɵɵi18nStart(index: number, message: string, subTemplateIndex?: number): void {
|
||
const tView = getTView();
|
||
ngDevMode && assertDefined(tView, `tView should be defined`);
|
||
pushI18nIndex(index);
|
||
// We need to delay projections until `i18nEnd`
|
||
setDelayProjection(true);
|
||
if (tView.firstCreatePass && tView.data[index + HEADER_OFFSET] === null) {
|
||
i18nStartFirstPass(getLView(), tView, index, message, subTemplateIndex);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Translates a translation block marked by `i18nStart` and `i18nEnd`. It inserts the text/ICU nodes
|
||
* into the render tree, moves the placeholder nodes and removes the deleted nodes.
|
||
*
|
||
* @codeGenApi
|
||
*/
|
||
export function ɵɵi18nEnd(): void {
|
||
const lView = getLView();
|
||
const tView = getTView();
|
||
ngDevMode && assertDefined(tView, `tView should be defined`);
|
||
i18nEndFirstPass(tView, lView);
|
||
// Stop delaying projections
|
||
setDelayProjection(false);
|
||
}
|
||
|
||
/**
|
||
*
|
||
* Use this instruction to create a translation block that doesn't contain any placeholder.
|
||
* It calls both {@link i18nStart} and {@link i18nEnd} in one instruction.
|
||
*
|
||
* The translation `message` is the value which is locale specific. The translation string may
|
||
* contain placeholders which associate inner elements and sub-templates within the translation.
|
||
*
|
||
* The translation `message` placeholders are:
|
||
* - `<60>{index}(:{block})<29>`: *Binding Placeholder*: Marks a location where an expression will be
|
||
* interpolated into. The placeholder `index` points to the expression binding index. An optional
|
||
* `block` that matches the sub-template in which it was declared.
|
||
* - `<60>#{index}(:{block})<29>`/`<60>/#{index}(:{block})<29>`: *Element Placeholder*: Marks the beginning
|
||
* and end of DOM element that were embedded in the original translation block. The placeholder
|
||
* `index` points to the element index in the template instructions set. An optional `block` that
|
||
* matches the sub-template in which it was declared.
|
||
* - `<60>*{index}:{block}<7D>`/`<60>/*{index}:{block}<7D>`: *Sub-template Placeholder*: Sub-templates must be
|
||
* split up and translated separately in each angular template function. The `index` points to the
|
||
* `template` instruction index. A `block` that matches the sub-template in which it was declared.
|
||
*
|
||
* @param index A unique index of the translation in the static block.
|
||
* @param message The translation message.
|
||
* @param subTemplateIndex Optional sub-template index in the `message`.
|
||
*
|
||
* @codeGenApi
|
||
*/
|
||
export function ɵɵi18n(index: number, message: string, subTemplateIndex?: number): void {
|
||
ɵɵi18nStart(index, message, subTemplateIndex);
|
||
ɵɵi18nEnd();
|
||
}
|
||
|
||
/**
|
||
* Marks a list of attributes as translatable.
|
||
*
|
||
* @param index A unique index in the static block
|
||
* @param values
|
||
*
|
||
* @codeGenApi
|
||
*/
|
||
export function ɵɵi18nAttributes(index: number, values: string[]): void {
|
||
const lView = getLView();
|
||
const tView = getTView();
|
||
ngDevMode && assertDefined(tView, `tView should be defined`);
|
||
i18nAttributesFirstPass(lView, tView, index, values);
|
||
}
|
||
|
||
|
||
/**
|
||
* Stores the values of the bindings during each update cycle in order to determine if we need to
|
||
* update the translated nodes.
|
||
*
|
||
* @param value The binding's value
|
||
* @returns This function returns itself so that it may be chained
|
||
* (e.g. `i18nExp(ctx.name)(ctx.title)`)
|
||
*
|
||
* @codeGenApi
|
||
*/
|
||
export function ɵɵi18nExp<T>(value: T): typeof ɵɵi18nExp {
|
||
const lView = getLView();
|
||
setMaskBit(bindingUpdated(lView, nextBindingIndex(), value));
|
||
return ɵɵi18nExp;
|
||
}
|
||
|
||
/**
|
||
* Updates a translation block or an i18n attribute when the bindings have changed.
|
||
*
|
||
* @param index Index of either {@link i18nStart} (translation block) or {@link i18nAttributes}
|
||
* (i18n attribute) on which it should update the content.
|
||
*
|
||
* @codeGenApi
|
||
*/
|
||
export function ɵɵi18nApply(index: number) {
|
||
applyI18n(getTView(), getLView(), index);
|
||
}
|
||
|
||
/**
|
||
* Handles message string post-processing for internationalization.
|
||
*
|
||
* Handles message string post-processing by transforming it from intermediate
|
||
* format (that might contain some markers that we need to replace) to the final
|
||
* form, consumable by i18nStart instruction. Post processing steps include:
|
||
*
|
||
* 1. Resolve all multi-value cases (like [<5B>*1:1<><31>#2:1<>|<7C>#4:1<>|<7C>5<EFBFBD>])
|
||
* 2. Replace all ICU vars (like "VAR_PLURAL")
|
||
* 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
|
||
* 4. Replace all ICU references with corresponding values (like <20>ICU_EXP_ICU_1<5F>)
|
||
* in case multiple ICUs have the same placeholder name
|
||
*
|
||
* @param message Raw translation string for post processing
|
||
* @param replacements Set of replacements that should be applied
|
||
*
|
||
* @returns Transformed string that can be consumed by i18nStart instruction
|
||
*
|
||
* @codeGenApi
|
||
*/
|
||
export function ɵɵi18nPostprocess(
|
||
message: string, replacements: {[key: string]: (string|string[])} = {}): string {
|
||
return i18nPostprocess(message, replacements);
|
||
} |