NlsBundle.ts
81 lines
| 2.2 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r0 | import { MapOf } from "@implab/core-amd/interfaces"; | ||
| import { isPromise, mixin } from "@implab/core-amd/safe"; | ||||
| import { locale as sysLocale } from "dojo/_base/kernel"; | ||||
| import { id as mid } from "module"; | ||||
| import { TraceSource } from "@implab/core-amd/log/TraceSource"; | ||||
| const trace = TraceSource.get(mid); | ||||
| type PromiseOrValue<T> = PromiseLike<T> | T; | ||||
| type ResolveCallback<T> = () => PromiseOrValue<T>; | ||||
| trace.debug("Current sysLocale: {0}", sysLocale); | ||||
| 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> { | ||||
| _locales: MapOf<ResolveCallback<T> | PromiseOrValue<T>>; | ||||
| default: T; | ||||
| _cache: MapOf<PromiseOrValue<T>>; | ||||
|
|
r1 | constructor(defNls: T, locales?: MapOf<any>) { | ||
|
|
r0 | this.default = defNls; | ||
| this._locales = locales || {}; | ||||
| this._cache = {}; | ||||
| } | ||||
| getLocale(locale: string) { | ||||
| const _loc = locale || sysLocale; | ||||
| const locales = new Array<string>(); | ||||
| _loc.split("-").reduce((a, x) => { | ||||
| a.push(x); | ||||
| locales.unshift(a.join("-")); | ||||
| return a; | ||||
|
|
r1 | }, new Array<string>()); | ||
|
|
r0 | |||
| return this._resolveLocale(locales); | ||||
| } | ||||
| _resolveLocale(locales: string[]): PromiseOrValue<T> { | ||||
| if (!locales.length) | ||||
|
|
r1 | return this.default; | ||
|
|
r0 | |||
| const locale = locales.shift(); | ||||
|
|
r1 | if (!locale) | ||
| return this._resolveLocale(locales); | ||||
|
|
r0 | if (this._cache[locale]) | ||
| return this._cache[locale]; | ||||
| let data = this._locales[locale]; | ||||
| if (isCallback(data)) | ||||
| data = data(); | ||||
|
|
r1 | const parent = this._resolveLocale(locales); | ||
|
|
r0 | |||
| return this._cache[locale] = when(data, x => { | ||||
| return when(parent, y => this._cache[locale] = chainObjects(y, x)); | ||||
| }); | ||||
| } | ||||
| } | ||||
