MCPcopy Create free account
hub / github.com/angular/angular / i18nPostprocess

Function i18nPostprocess

packages/core/src/render3/i18n/i18n_postprocess.ts:43–135  ·  view source on GitHub ↗
(
  message: string,
  replacements: {[key: string]: string | string[]} = {},
)

Source from the content-addressed store, hash-verified

41 * @codeGenApi
42 */
43export function i18nPostprocess(
44 message: string,
45 replacements: {[key: string]: string | string[]} = {},
46): string {
47 /**
48 * Step 1: resolve all multi-value placeholders like [�#5�|�*1:1��#2:1�|�#4:1�]
49 *
50 * Note: due to the way we process nested templates (BFS), multi-value placeholders are typically
51 * grouped by templates, for example: [�#5�|�#6�|�#1:1�|�#3:2�] where �#5� and �#6� belong to root
52 * template, �#1:1� belong to nested template with index 1 and �#1:2� - nested template with index
53 * 3. However in real templates the order might be different: i.e. �#1:1� and/or �#3:2� may go in
54 * front of �#6�. The post processing step restores the right order by keeping track of the
55 * template id stack and looks for placeholders that belong to the currently active template.
56 */
57 let result: string = message;
58 if (PP_MULTI_VALUE_PLACEHOLDERS_REGEXP.test(message)) {
59 const matches: {[key: string]: PostprocessPlaceholder[]} = {};
60 const templateIdsStack: number[] = [ROOT_TEMPLATE_ID];
61 result = result.replace(PP_PLACEHOLDERS_REGEXP, (m: any, phs: string, tmpl: string): string => {
62 const content = phs || tmpl;
63 const placeholders: PostprocessPlaceholder[] = matches[content] || [];
64 if (!placeholders.length) {
65 content.split('|').forEach((placeholder: string) => {
66 const match = placeholder.match(PP_TEMPLATE_ID_REGEXP);
67 const templateId = match ? parseInt(match[1], 10) : ROOT_TEMPLATE_ID;
68 const isCloseTemplateTag = PP_CLOSE_TEMPLATE_REGEXP.test(placeholder);
69 placeholders.push([templateId, isCloseTemplateTag, placeholder]);
70 });
71 matches[content] = placeholders;
72 }
73
74 if (!placeholders.length) {
75 throw new Error(`i18n postprocess: unmatched placeholder - ${content}`);
76 }
77
78 const currentTemplateId = templateIdsStack[templateIdsStack.length - 1];
79 let idx = 0;
80 // find placeholder index that matches current template id
81 for (let i = 0; i < placeholders.length; i++) {
82 if (placeholders[i][0] === currentTemplateId) {
83 idx = i;
84 break;
85 }
86 }
87 // update template id stack based on the current tag extracted
88 const [templateId, isCloseTemplateTag, placeholder] = placeholders[idx];
89 if (isCloseTemplateTag) {
90 templateIdsStack.pop();
91 } else if (currentTemplateId !== templateId) {
92 templateIdsStack.push(templateId);
93 }
94 // remove processed tag from the list
95 placeholders.splice(idx, 1);
96 return placeholder;
97 });
98 }
99
100 // return current result if no replacements specified

Callers 1

ɵɵi18nPostprocessFunction · 0.90

Calls 7

popMethod · 0.80
keysMethod · 0.65
testMethod · 0.45
replaceMethod · 0.45
forEachMethod · 0.45
matchMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected