99 * rights grant found at http://polymer.github.io/PATENTS.txt
1010 */
1111
12- import { Bundle , Message , Placeholder } from './interfaces' ;
12+ import { Bundle , Message , ProgramMessage , Placeholder } from './interfaces' ;
1313import { applyPatches , Patches } from './patches' ;
1414import { Locale } from './locales' ;
1515
@@ -50,21 +50,14 @@ export function generateMsgModule(
5050 ) } Messages} from './${ locale } .js';`
5151 )
5252 . join ( '\n' ) ;
53- const localeSwitchCases = targetLocales . map ( ( locale ) => {
54- return `case '${ locale } ':
55- value = ${ locale . replace ( '-' , '' ) } Messages[name];
56- break;` ;
57- } ) ;
5853 return `
5954 // Do not modify this file by hand!
6055 // Re-generate this file by running lit-localize
6156
6257 import {TemplateResult} from 'lit-html';
6358 ${ localeImports }
6459
65- export const getLocale = () => {
66- return locale;
67- };
60+ /* eslint-disable @typescript-eslint/no-explicit-any */
6861
6962 export const supportedLocales = [${ localesArray } ] as const;
7063
@@ -91,23 +84,52 @@ export function generateMsgModule(
9184
9285 const locale = getLocaleFromUrl();
9386
94- export const msg = (name: MessageName, defaultValue: string|TemplateResult): string|TemplateResult => {
95- let value;
87+ export const getLocale = () => {
88+ return locale;
89+ };
90+
91+ export function msg(name: MessageName, str: string): string;
92+
93+ export function msg(name: MessageName, tmpl: TemplateResult): TemplateResult;
94+
95+ export function msg<F extends (...args: any) => string>(
96+ name: MessageName,
97+ fn: F,
98+ ...params: Parameters<F>
99+ ): string;
100+
101+ export function msg<F extends (...args: any) => TemplateResult>(
102+ name: MessageName,
103+ fn: F,
104+ ...params: Parameters<F>
105+ ): TemplateResult;
106+
107+ export function msg(
108+ name: MessageName,
109+ source: string|TemplateResult|(() => string|TemplateResult),
110+ ...params: unknown[]): string|TemplateResult {
111+ let resolved;
96112 switch (locale) {
97113 case defaultLocale:
98- return defaultValue;
99- ${ localeSwitchCases }
114+ resolved = source;
115+ break;
116+ ${ targetLocales . map (
117+ ( locale ) => `
118+ case '${ locale } ':
119+ resolved = ${ locale . replace ( '-' , '' ) } Messages[name];
120+ break;`
121+ ) }
100122 default:
101- // TODO unreachable
102123 console.warn(\`\${locale} is not a supported locale\`);
103- return defaultValue;
104124 }
105- if (value !== undefined) {
106- return value;
125+ if (!resolved) {
126+ console.warn(\`Could not find \${locale} string for \${name}\`);
127+ resolved = source;
107128 }
108- console.warn(\`Could not find \${locale} string for \${name}\`);
109- return defaultValue;
110- };
129+ return typeof resolved === 'function'
130+ ? (resolved as any)(...params)
131+ : resolved;
132+ }
111133
112134 type MessageName = ${ messageNamesUnion } ;
113135 ` ;
@@ -119,15 +141,15 @@ export function generateMsgModule(
119141 */
120142export function generateLocaleModule (
121143 { locale, messages} : Bundle ,
122- canonMsgs : Message [ ] ,
144+ canonMsgs : ProgramMessage [ ] ,
123145 patches : Patches
124146) : string {
125147 messages = copyMessagesSortedByName ( messages ) ;
126148 // The unique set of message names in the canonical messages we extracted from
127149 // the TypeScript program.
128- const canonMsgNames = new Set < string > ( ) ;
150+ const canonMsgsByName = new Map < string , ProgramMessage > ( ) ;
129151 for ( const canon of canonMsgs ) {
130- canonMsgNames . add ( canon . name ) ;
152+ canonMsgsByName . set ( canon . name , canon ) ;
131153 }
132154
133155 // The unique set of message names we found in this XLB translations file.
@@ -138,15 +160,16 @@ export function generateLocaleModule(
138160
139161 const entries = [ ] ;
140162 for ( const msg of messages ) {
141- if ( ! canonMsgNames . has ( msg . name ) ) {
163+ const canon = canonMsgsByName . get ( msg . name ) ;
164+ if ( canon === undefined ) {
142165 console . warn (
143166 `${ locale } message ${ msg . name } does not exist in canonical messages, skipping`
144167 ) ;
145168 continue ;
146169 }
147170 translatedMsgNames . add ( msg . name ) ;
148- const { msgStr, usesLit } = makeMessageString ( msg . contents ) ;
149- if ( usesLit ) {
171+ const msgStr = makeMessageString ( msg . contents , canon ) ;
172+ if ( canon . isLitTemplate ) {
150173 importLit = true ;
151174 }
152175 const patchedMsgStr = applyPatches ( patches , locale , msg . name , msgStr ) ;
@@ -159,15 +182,19 @@ export function generateLocaleModule(
159182 console . warn (
160183 `${ locale } message ${ msg . name } is missing, using canonical text as fallback`
161184 ) ;
162- const { msgStr} = makeMessageString ( msg . contents ) ;
185+ const msgStr = makeMessageString ( msg . contents , msg ) ;
163186 entries . push ( `${ msg . name } : ${ msgStr } ,` ) ;
164187 }
165188 return `
166189 // Do not modify this file by hand!
167190 // Re-generate this file by running lit-localize
191+
168192 ${ importLit ? "import {html} from 'lit-html';" : '' }
169193
170194 /* eslint-disable no-irregular-whitespace */
195+ /* eslint-disable @typescript-eslint/camelcase */
196+ /* eslint-disable @typescript-eslint/no-explicit-any */
197+
171198 export const messages = {
172199 ${ entries . join ( '\n' ) }
173200 };
@@ -188,23 +215,28 @@ function copyMessagesSortedByName(messages: Message[]): Message[] {
188215 * possibly using lit-html if there is embedded HTML.
189216 */
190217function makeMessageString (
191- contents : Array < string | Placeholder >
192- ) : { msgStr : string ; usesLit : boolean } {
193- let hasPlaceholders = false ;
218+ contents : Array < string | Placeholder > ,
219+ canon : ProgramMessage
220+ ) : string {
194221 const fragments = [ ] ;
195222 for ( const content of contents ) {
196223 if ( typeof content === 'string' ) {
197224 fragments . push ( escapeStringLiteral ( content ) ) ;
198225 } else {
199- fragments . push ( escapeStringLiteral ( content . untranslatable ) ) ;
200- hasPlaceholders = true ;
226+ fragments . push ( content . untranslatable ) ;
201227 }
202228 }
203- // We use <ph> placeholders to safely pass embedded HTML markup through
204- // translation. If we encounter a placeholder, then this translated string
205- // needs to use the lit-html "html" function.
206- const msgStr = `${ hasPlaceholders ? 'html' : '' } \`${ fragments . join ( '' ) } \`` ;
207- return { msgStr, usesLit : hasPlaceholders } ;
229+ // We use <ph> placeholders to safely pass embedded HTML markup and
230+ // template expressions through translation.
231+ const tag = canon . isLitTemplate ? 'html' : '' ;
232+ const msgStr = `${ tag } \`${ fragments . join ( '' ) } \`` ;
233+ if ( canon . params !== undefined && canon . params . length > 0 ) {
234+ return `(${ canon . params
235+ . map ( ( param ) => `${ param } : any` )
236+ . join ( ', ' ) } ) => ${ msgStr } `;
237+ } else {
238+ return msgStr ;
239+ }
208240}
209241
210242/**
0 commit comments