-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathtranslation.ts
64 lines (55 loc) · 2.27 KB
/
translation.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
type SprintfValues = (string | String | number)[] | [{ [key: string]: string | number }];
export type TranslationFunction = (string: string, ...values: SprintfValues) => string;
const defaultTranslate: TranslationFunction = (s: string) => s;
const defaultLoaded: () => boolean = () => false;
let _translate = defaultTranslate;
let _loaded = defaultLoaded;
function sprintf(s: string, ...values: SprintfValues): string {
if (values.length === 1 && typeof values[0] === "object" && !(values[0] instanceof String)) {
const valuesDict = values[0] as { [key: string]: string };
s = s.replace(/\%\(([^\)]+)\)s/g, (match, value) => valuesDict[value]);
} else if (values.length > 0) {
s = s.replace(/\%s/g, () => values.shift() as string);
}
return s;
}
/***
* Allow to inject a translation function from outside o-spreadsheet. This should be called before instantiating
* a model.
* @param tfn the function that will do the translation
* @param loaded a function that returns true when the translation is loaded
*/
export function setTranslationMethod(tfn: TranslationFunction, loaded: () => boolean = () => true) {
_translate = tfn;
_loaded = loaded;
}
/**
* If no translation function has been set, this will mark the translation are loaded.
*
* By default, the translations should not be set as loaded, otherwise top-level translated constants will never be
* translated. But if by the time the model is instantiated no custom translation function has been set, we can set
* the default translation function as loaded so o-spreadsheet can be run in standalone with no translations.
*/
export function setDefaultTranslationMethod() {
if (_translate === defaultTranslate && _loaded === defaultLoaded) {
_loaded = () => true;
}
}
export const _t: TranslationFunction = function (s: string, ...values: SprintfValues) {
if (!_loaded()) {
return new LazyTranslatedString(s, values) as unknown as string;
}
return sprintf(_translate(s), ...values);
};
class LazyTranslatedString extends String {
constructor(str: string, private values: SprintfValues) {
super(str);
}
valueOf() {
const str = super.valueOf();
return _loaded() ? sprintf(_translate(str), ...this.values) : sprintf(str, ...this.values);
}
toString() {
return this.valueOf();
}
}