##// END OF EJS Templates
Added tag v1.3.0 for changeset 15c829aa08a2
Added tag v1.3.0 for changeset 15c829aa08a2

File last commit:

r79:e5bb5e80ce96 v1.2.3 default
r105:9750d34f83d3 default
Show More
NlsBundle.ts
73 lines | 2.1 KiB | video/mp2t | TypeScriptLexer
import { MapOf, PromiseOrValue } from "@implab/core-amd/interfaces";
import { argumentNotEmptyString, isPromise, mixin } from "@implab/core-amd/safe";
export type LocaleProvider<T> = () => PromiseOrValue<T | { default: T }>;
type ResolveCallback<T> = () => PromiseOrValue<T>;
function when<T, T2>(value: PromiseOrValue<T>, cb: (v: T) => PromiseOrValue<T2>): PromiseOrValue<T2> {
return isPromise(value) ?
value.then(cb) :
cb(value);
}
function isCallback<T>(v: ResolveCallback<T> | PromiseOrValue<T>): v is ResolveCallback<T> {
return typeof v === "function";
}
function chainObjects<T extends object>(o1: T, o2: T) {
if (!o1)
return o2;
if (!o2)
return o1;
return mixin(Object.create(o1) as T, o2);
}
export class NlsBundle<T extends object> {
private _locales: MapOf<LocaleProvider<Partial<T>>>;
private _default: T;
private _cache: MapOf<PromiseOrValue<T>>;
constructor(defNls: T, locales?: MapOf<LocaleProvider<Partial<T>>>) {
this._default = defNls;
this._locales = locales || {};
this._cache = {};
}
getLocale(locale: string) {
argumentNotEmptyString(locale, "locale");
const _loc = locale;
// en-US => ["en", "en-US"]
const locales = _loc.split(/-|_/).map((x, i, a) => a.slice(0, i + 1).join("-"));
return this._resolveLocale(locales);
}
_resolveLocale(locales: string[]): PromiseOrValue<T> {
if (!locales.length)
return this._default;
const locale = locales.pop();
if (!locale)
throw new Error("The locale can't be empty");
if (this._cache[locale])
return this._cache[locale];
const data = this._loadPackage(this._locales[locale]);
const parent = this._resolveLocale(locales);
return this._cache[locale] = when(data, x => {
return when(parent, y => this._cache[locale] = chainObjects(y, x));
});
}
_loadPackage(localeData: any) {
if (isCallback(localeData))
return when(localeData(), data => data && "default" in data ? data.default : data);
return localeData;
}
}