update for typescript

This commit is contained in:
wxzhang 2023-04-09 14:49:57 +08:00
parent a9f63c2c35
commit 88db8cb686
7 changed files with 206 additions and 119 deletions

View File

@ -6,13 +6,21 @@ import zhFormatters from '../formatters/zh';
import enFormatters from '../formatters/en';
import { VoerkaI18nManager } from '../manager';
import { VoerkaI18nFormatterRegistry } from '../formatterRegistry';
import { VoerkaI18nLanguageMessages } from '../types';
import { VoerkaI18nLanguageMessages, VoerkaI18nFormatterConfigs } from '../types';
import { deepMerge } from 'flex-tools/object/deepMerge';
import { isPlainObject } from 'flex-tools/typecheck/isPlainObject';
import { default as inlineFormatters } from '../formatters';
function mergeFormattersConfigs(configSources:any[]){
return configSources.reduce((finalConfig, curConfig)=>{
if(isPlainObject(curConfig)) deepMerge(finalConfig,curConfig,{newObject:false,array:'replace'})
return finalConfig
},{})
}
const zhMessages:VoerkaI18nLanguageMessages = {
$config:{
x:{a:1},
y:{b:1}
add:{a:1},
dec:{b:1}
},
"1": "你好",
"2": "你好,{name}",
@ -42,19 +50,51 @@ const languages = [
{ name: "en"}
]
Object.assign(zhFormatters.$config,{
x:{x1:1,x2:2},
y:{y1:1,y2:2}
})
Object.assign(enFormatters.$config,{
x:{x1:11,x2:22},
y:{y1:11,y2:22},
z:{z1:11,z2:22}
})
const formatters ={
zh:zhFormatters,
en:enFormatters,
"*":{
$config:{
x:{g:1},
y:{g:1},
g:{g1:1,g2:2}
},
add:(value:any,args?:any[],$config?:VoerkaI18nFormatterConfigs)=>'*'+ value+1,
},
zh:{
first:(value:any)=>'ZH'+value[0],
...zhFormatters
},
en:{
first:(value:any)=>'EN'+value[0],
...enFormatters,
},
jp:()=>{}
}
describe("VoerkaI18nScope", () => {
let scope = new VoerkaI18nScope({
id: "test",
languages,
idMap,
messages,
formatters
describe("VoerkaI18nScope", () => {
let scope:VoerkaI18nScope;
beforeAll(async ()=>{
return new Promise((resolve)=>{
scope = new VoerkaI18nScope({
id: "test",
languages,
idMap,
messages,
formatters,
callback:()=>{
resolve()
}
})
})
})
test("成功创建实例", () => {
expect(scope).toBeInstanceOf(VoerkaI18nScope)
@ -63,20 +103,50 @@ describe("VoerkaI18nScope", () => {
expect(scope.messages).toEqual(messages)
expect(scope.default).toEqual(zhMessages)
expect(scope.current).toEqual(zhMessages)
expect(scope.idMap).toEqual(idMap)
// 格式化器配置
expect(scope.formatters).toBeInstanceOf(VoerkaI18nFormatterRegistry)
expect(scope.formatters.language).toBe("zh")
expect(scope.formatters.formatters).toEqual(formatters)
expect(scope.formatters.config).toBe(zhFormatters.$config)
expect(scope.formatters.types).toBe(zhFormatters.$types)
expect(scope.idMap).toEqual(idMap)
// 全局管理器
expect(scope.global).toBeInstanceOf(VoerkaI18nManager)
})
test("格式化器配置", async () => {
expect(scope.formatters).toBeInstanceOf(VoerkaI18nFormatterRegistry)
expect(scope.formatters.activeLanguage).toBe("zh")
expect(scope.formatters.formatters).toEqual(formatters)
expect(scope.formatters.config).toBe(zhFormatters.$config)
expect(scope.formatters.types).toBe(zhFormatters.$types)
})
test("查找格式化器", async () => {
expect(scope.formatters.get("add")).toBe(formatters['*'].add)
expect(scope.formatters.get("first")).toBe(formatters.zh.first)
await scope.change("en")
expect(scope.formatters.get("first")).toBe(formatters.en.first)
})
test("格式化器配置", async () => {
let fallbackLanguage = scope.getLanguage(scope.activeLanguage)?.fallback
const globalFormatters = inlineFormatters
let scopeConfig = mergeFormattersConfigs([
globalFormatters['*'].$config,
(fallbackLanguage! in globalFormatters) ? (globalFormatters as any)?.[fallbackLanguage!].$config:{},
globalFormatters.zh.$config,
formatters['*'].$config,
(fallbackLanguage! in formatters) ? (formatters as any)?.[fallbackLanguage!]?.$config:{},
formatters.zh.$config
])
expect(scope.formatters.config).toEqual(scopeConfig)
//
await scope.change("en")
fallbackLanguage = scope.getLanguage(scope.activeLanguage)?.fallback
scopeConfig = mergeFormattersConfigs([
globalFormatters['*'].$config,
(fallbackLanguage! in globalFormatters) ? (globalFormatters as any)?.[fallbackLanguage!].$config:{},
// globalFormatters.zh.$config,
formatters['*'].$config,
(fallbackLanguage! in formatters) ? (formatters as any)?.[fallbackLanguage!]?.$config:{},
formatters.en.$config
])
expect(scope.formatters.config).toEqual(scopeConfig)
})
})
test('translate', () => {})

View File

@ -6,13 +6,19 @@
*/
import { isPlainObject } from 'flex-tools/typecheck/isPlainObject';
import type { VoerkaI18nScope } from './scope';
import { VoerkaI18nFormatter, VoerkaI18nFormatters, VoerkaI18nFormattersLoader, VoerkaI18nLanguageFormatters, SupportedDateTypes, VoerkaI18nFormatterConfigs, VoerkaI18nTypesFormatters } from './types';
import { DataTypes } from './utils';
import { get as getByPath } from "flex-tools/object/get"
import { isFunction } from 'flex-tools/typecheck/isFunction';
import { deepMerge } from 'flex-tools/object/deepMerge';
import { assignObject } from 'flex-tools/object/assignObject';
import { VoerkaI18nFormatter,
VoerkaI18nFormatters,
VoerkaI18nFormattersLoader,
VoerkaI18nLanguageFormatters,
SupportedDateTypes,
VoerkaI18nFormatterConfigs,
VoerkaI18nTypesFormatters
} from './types';
export interface VoerkaI18nScopeCache{
activeLanguage :string | null,
@ -46,14 +52,15 @@ export class VoerkaI18nFormatterRegistry{
#activeFormatters:VoerkaI18nFormatters = {}
#activeFormattersConfigs :VoerkaI18nFormatterConfigs = {}
#scope?:VoerkaI18nScope
#language:string // 当前语言
#language?:string // 当前语言
#formatterCache:VoerkaI18nScopeFormatterCache = {typedFormatters:{},formatters:{}}
constructor(scope?:VoerkaI18nScope){
this.#scope = scope
this.#language = scope?.activeLanguage || "zh"
this.#scope = scope
}
get activeLanguage(){ return this.#language } // 当前语言
get activeFormatters(){ return this.#activeFormatters } // 当前语言的格式化器集合
get activeLanguage(){
if(!this.#language) this.#language = this.#scope?.activeLanguage || "zh"
return this.#language
} // 当前语言
get scope(){ return this.#scope }
/**
*
@ -62,7 +69,7 @@ export class VoerkaI18nFormatterRegistry{
*/
async change(language:string){
try {
if (language in this.formatters) {
if (language in this. formatters) {
this.#language = language
const formatters = this.formatters[language]
if(isFunction(formatters)){
@ -81,19 +88,19 @@ export class VoerkaI18nFormatterRegistry{
if (this.scope?.debug) console.error(`Error loading ${language} formatters: ${e.message}`);
}
}
private async generateFormattersConfigs(language:string){
private generateFormattersConfigs(language:string){
try{
const configSources = [ ]
const fallbackLanguage = this.scope?.getLanguage(language)?.fallback || 'en';
const fallbackLanguage = this.scope?.getLanguage(language)?.fallback ;
if(this.scope){ // 从全局Scope读取
configSources.push(this.scope.global.formatters.getConfig('*'))
configSources.push(this.scope.global.formatters.getConfig(fallbackLanguage))
configSources.push(this.scope.global.formatters.config)
if(fallbackLanguage) configSources.push(this.scope.global.formatters.getConfig(fallbackLanguage))
configSources.push(this.scope.global.formatters.getConfig(language))
}
// 从当前Scope读取
configSources.push(this.getConfig('*'))
configSources.push(this.getConfig(fallbackLanguage))
configSources.push(this.config)
if(fallbackLanguage) configSources.push(this.getConfig(fallbackLanguage))
configSources.push(this.getConfig(language))
// 合并当前语言的格式化器配置参数
this.#activeFormattersConfigs = configSources.reduce((finalConfig, curConfig)=>{
if(isPlainObject(curConfig)) deepMerge(finalConfig,curConfig,{newObject:false,array:'replace'})
@ -182,11 +189,12 @@ export class VoerkaI18nFormatterRegistry{
//****************** 以下方法和属性只作用于当前语言 *********************** */
get formatters(){ return this.#formatters } // 所有语言的格式化器集合
get activeFormatters(){ return this.#activeFormatters } // 当前语言的格式化器集合
/**
*
*/
get config(){
return (this.#activeFormatters as VoerkaI18nFormatters).$config as VoerkaI18nFormatterConfigs
return this.#activeFormattersConfigs
}
get types(){
return (this.#activeFormatters as VoerkaI18nFormatters).$types as VoerkaI18nFormatterConfigs
@ -213,28 +221,28 @@ export class VoerkaI18nFormatterRegistry{
if(on=="types" && name in this.#formatterCache.typedFormatters) return this.#formatterCache.typedFormatters[name as SupportedDateTypes]
if(on=="scope" && name in this.#formatterCache.formatters) return this.#formatterCache.formatters[name]
const fallbackLanguage = this.scope?.getLanguage(this.activeLanguage)?.fallback || 'en';
const fallbackLanguage = this.scope?.getLanguage(this.activeLanguage)?.fallback
// 先在当前作用域中查找,再在全局查找
const targets =[]
if(on=="types"){
targets.push(this.types)
targets.push(this.getTypes(fallbackLanguage))
if(fallbackLanguage) targets.push(this.getTypes(fallbackLanguage))
targets.push(this.getTypes("*"))
if(inGlobal){
targets.push(this.scope?.global.formatters.types)
targets.push(this.scope?.global.formatters.getTypes(fallbackLanguage))
if(fallbackLanguage) targets.push(this.scope?.global.formatters.getTypes(fallbackLanguage))
targets.push(this.scope?.global.formatters.getTypes("*"))
}
}else if(on=='scope'){
targets.push(this.formatters)
targets.push(this.getFormatters(fallbackLanguage))
targets.push(this.#activeFormatters)
if(fallbackLanguage) targets.push(this.getFormatters(fallbackLanguage))
targets.push(this.getFormatters("*"))
if(inGlobal){
targets.push(this.scope?.global.formatters.types)
targets.push(this.scope?.global.formatters.getTypes(fallbackLanguage))
targets.push(this.scope?.global.formatters.getTypes("*"))
targets.push(this.scope?.global.formatters.activeFormatters)
if(fallbackLanguage) targets.push(this.scope?.global.formatters.getFormatters(fallbackLanguage))
targets.push(this.scope?.global.formatters.getFormatters("*"))
}
}
// 查找指定名称的格式化器

View File

@ -8,9 +8,7 @@ import zhFormatters from "./zh"
import defaultFormatters from "./default"
export default {
"*":{
...enFormatters,
...defaultFormatters
},
"*":defaultFormatters,
en:enFormatters,
zh:zhFormatters
}

View File

@ -118,7 +118,7 @@ function executeChecker(checker:FormatterChecker, value:any,scope:VoerkaI18nScop
let result = { value, next: "skip" };
if (!isFunction(checker)) return result;
try {
const r = checker(value,scope.activeFormatterConfig);
const r = checker(value,scope.formatters.config);
if (isPlainObject(r) && ("next" in r) && ("value" in r)) {
Object.assign(result, r);
} else {
@ -174,7 +174,7 @@ function executeFormatter(value:any, formatters:VoerkaI18nFormatter[], scope:Voe
// 3. 分别执行格式化器函数
for (let formatter of formatters) {
try {
result = formatter(result, [result],scope.activeFormatterConfig);
result = formatter(result, [result],scope.formatters.config);
} catch (e:any) {
e.formatter = (formatter as any).$name;
if (scope.debug)
@ -234,7 +234,9 @@ function wrapperFormatters(scope:VoerkaI18nScope, activeLanguage:string, formatt
let fn = scope.formatters.get(name,{on:'scope'})
let formatter;
if (isFunction(fn)) {
formatter = (value:any, args?:any[],config?:VoerkaI18nFormatterConfigs) =>fn.call(scope.activeFormatterConfig, value, args, config);
formatter = (value:any, args?:any[],config?:VoerkaI18nFormatterConfigs) =>{
return (fn as Function).call(scope.formatters.config, value, args, config);
}
} else {
// 格式化器无效或者没有定义时,查看当前值是否具有同名的原型方法,如果有则执行调用
// 比如padStart格式化器是String的原型方法不需要配置就可以直接作为格式化器调用
@ -264,7 +266,7 @@ function wrapperFormatters(scope:VoerkaI18nScope, activeLanguage:string, formatt
function getFormattedValue(scope:VoerkaI18nScope, activeLanguage:string, formatters:FormatterDefineChain, value:any, template:string) {
// 1. 取得格式化器函数列表,然后经过包装以传入当前格式化器的配置参数
const formatterFuncs = wrapperFormatters(scope, activeLanguage, formatters);
// 3. 执行格式化器
// 2. 执行格式化器
// EMPTY和ERROR是默认两个格式化器如果只有两个则说明在t(...)中没有指定格式化器
if (formatterFuncs.length == 2) {
// 当没有格式化器时,查询是否指定了默认数据类型的格式化器,如果有则执行

View File

@ -4,8 +4,7 @@ import { EventEmitter } from "./eventemitter"
import inlineFormatters from "./formatters"
import type { VoerkaI18nScope } from "./scope"
import type { VoerkaI18nLanguageDefine, VoerkaI18nLanguageFormatters, VoerkaI18nDefaultMessageLoader, VoerkaI18nFormatter, VoerkaI18nTypesFormatters } from "./types"
import { VoerkaI18nFormatterRegistry } from "./formatterRegistry"
import { DataTypes } from "./utils"
import { VoerkaI18nFormatterRegistry } from "./formatterRegistry"
// 默认语言配置
const defaultLanguageSettings = {

View File

@ -4,7 +4,6 @@ import { translate } from "./translate"
import { assignObject } from "flex-tools/object/assignObject"
import {VoerkaI18nManager } from "./manager"
import type {
VoerkaI18nFormatterConfigs,
VoerkaI18nDefaultMessageLoader,
VoerkaI18nFormatter,
VoerkaI18nLanguageFormatters,
@ -12,27 +11,26 @@ import type {
VoerkaI18nLanguageDefine,
VoerkaI18nLanguageMessages,
VoerkaI18nLanguagePack,
VoerkaI18nTranslate,
VoerkaI18nMessageLoaders,
VoerkaI18nTypesFormatters,
VoerkaI18nFormatters,
VoerkaI18nTranslate,
VoerkaI18nDynamicLanguageMessages,
VoerkaI18nLanguageMessagePack,
VoerkaI18nMessageLoader,
VoerkaI18nLanguageMessagePack,
VoerkaI18nMessageLoader,
} from "./types"
import { VoerkaI18nFormatterRegistry } from './formatterRegistry';
import { InvalidLanguageError } from "./errors"
import { randomId } from "./utils"
import { DefaultLanguageSettings, DefaultFallbackLanguage } from './consts';
export interface VoerkaI18nScopeOptions {
id?: string
debug?: boolean
languages: VoerkaI18nLanguageDefine[] // 当前作用域支持的语言列表
defaultLanguage?: string // 默认语言名称
activeLanguage?: string // 当前语言名称
messages: VoerkaI18nLanguageMessagePack // 当前语言包
idMap: Voerkai18nIdMap // 消息id映射列表
languages: VoerkaI18nLanguageDefine[] // 当前作用域支持的语言列表
defaultLanguage?: string // 默认语言名称
activeLanguage?: string // 当前语言名称
messages: VoerkaI18nLanguageMessagePack // 当前语言包
idMap: Voerkai18nIdMap // 消息id映射列表
formatters: VoerkaI18nLanguageFormatters // 当前作用域的格式化函数列表{<lang>: {$types,$config,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
callback?:(e?:Error)=>void // 当注册到全局管理器后的回调函数
}
export class VoerkaI18nScope {
@ -40,14 +38,17 @@ export class VoerkaI18nScope {
#global:VoerkaI18nManager // 引用全局VoerkaI18nManager配置注册后自动引用
#refreshing:boolean = false
#t:VoerkaI18nTranslate
#activeFormatters:VoerkaI18nFormatters = {}
#activeFormatterConfig: VoerkaI18nFormatterConfigs={}
#formatterRegistry:VoerkaI18nFormatterRegistry
#formatterRegistry?:VoerkaI18nFormatterRegistry
#defaultLanguage:string ='zh'
#activeLanguage:string='zh'
#currentMessages:VoerkaI18nLanguageMessages = {} // 当前语言包
#patchedMessages:VoerkaI18nLanguagePack = {} // 补丁语言包
constructor(options:VoerkaI18nScopeOptions, callback?:(e?:Error)=>void) {
/**
*
* @param options
* @param callback
*/
constructor(options:VoerkaI18nScopeOptions) {
this.#options = assignObject({
id : randomId(), // 作用域唯一id
debug : false,
@ -56,62 +57,51 @@ export class VoerkaI18nScope {
idMap : {}, // 消息id映射列表
formatters : {}, // 当前作用域的格式化函数列表{<lang>: {$types,$config,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
},options) as Required<VoerkaI18nScopeOptions>
this.#formatterRegistry= new VoerkaI18nFormatterRegistry(this)
// 初始化
this.init()
// 将当前实例注册到全局单例VoerkaI18nManager中
this.#global = this.registerToManager(callback)
// 从本地缓存中读取并合并补丁语言包
this._mergePatchedMessages();
// 延后执行补丁命令,该命令会向远程下载补丁包
this._patch(this.#currentMessages, this.activeLanguage);
this.#global = this.registerToManager()
this.#t = translate.bind(this)
}
get id() {return this.#options.id;} // 作用域唯一id
get debug() {return this.#options.debug;} // 调试开关
get defaultLanguage() {return this.#global.defaultLanguage;} // 默认语言名称
get activeLanguage() {return this.#global.activeLanguage;} // 默认语言名称
get id() {return this.#options.id;} // 作用域唯一id
get debug() {return this.#options.debug;} // 调试开关
get defaultLanguage() {return this.#global.defaultLanguage;} // 默认语言名称
get activeLanguage() {return this.#global.activeLanguage;} // 默认语言名称
// 默认语言包,只能静态语言包,不能是动态语言包
get default() {return this.#options.messages[this.#defaultLanguage] as VoerkaI18nLanguageMessages;}
get current() {return this.#currentMessages;} // 当前语言包
get messages() {return this.#options.messages; } // 所有语言包
get idMap() {return this.#options.idMap;} // 消息id映射列表
get languages() {return this.#options.languages;} // 当前作用域支持的语言列表[{name,title,fallback}]
get global() { return this.#global;} // 引用全局VoerkaI18n配置注册后自动引用
get formatters() { return this.#formatterRegistry;} // 当前作用域的所有格式化器定义 {<语言名称>: {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () => {}}}
get activeFormatters() {return this.#formatterRegistry.formatters} // 当前作用域激活的格式化器定义 {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () = >{}}
get activeFormatterConfig(){return this.#activeFormatterConfig} // 当前格式化器合并后的配置参数,参数已经合并了全局格式化器中的参数
get translate(){return this.#t}
get current() {return this.#currentMessages;} // 当前语言包
get messages() {return this.#options.messages; } // 所有语言包
get idMap() {return this.#options.idMap;} // 消息id映射列表
get languages() {return this.#options.languages;} // 当前作用域支持的语言列表[{name,title,fallback}]
get global() { return this.#global;} // 引用全局VoerkaI18n配置注册后自动引用
get formatters() { return this.#formatterRegistry!;} // 当前作用域的所有格式化器定义 {<语言名称>: {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () => {}}}
get activeFormatters() {return this.#formatterRegistry!.formatters} // 当前作用域激活的格式化器定义 {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () = >{}}
get t(){return this.#t}
/**
*
* - en配置为默认回退语言
* -
*/
private init(){
// 1. 检测语言配置列表是否有效
if(!Array.isArray(this.languages)){
console.warn("[VoerkaI18n] invalid languages config,use default languages config instead.")
this.#options.languages = [
{name: "zh",title: "中文",default:true,active:true},
{name: "en",title: "英文"}
]
this.#options.languages =Object.assign([],DefaultLanguageSettings)
}else{
if(this.languages.length==0){
throw new Error("[VoerkaI18n] invalid languages config, languages must not be empty.")
}
}
// 2.为语言配置默认回退语言,并且提取默认语言和活动语言
this.languages.forEach(language=>{
if(!language.fallback) language.fallback = "en"
if(!language.fallback) language.fallback = DefaultFallbackLanguage
if(language.default) this.#defaultLanguage = language.name
if(language.active) this.#activeLanguage = language.name
})
// 确保提供了有效的默认语言和活动语言
// 3. 确保提供了有效的默认语言和活动语言
const lanMessages = this.#options.messages
if(!(this.#defaultLanguage in lanMessages)) {
this.#defaultLanguage = Object.keys(lanMessages)[0]
}
if(!(this.#activeLanguage in lanMessages)){
this.#activeLanguage = this.#defaultLanguage
}
if(!(this.#defaultLanguage in lanMessages)) this.#defaultLanguage = Object.keys(lanMessages)[0]
if(!(this.#activeLanguage in lanMessages)) this.#activeLanguage = this.#defaultLanguage
if(!(this.#defaultLanguage in lanMessages)){
throw new Error("[VoerkaI18n] invalid <defaultLanguage> config, messages not specified.")
}
@ -141,9 +131,31 @@ export class VoerkaI18nScope {
}
this.#global = globalThis.VoerkaI18n as unknown as VoerkaI18nManager;
if (!isFunction(callback)) callback = () => {};
this.#global.register(this).then(()=>(callback as any)()).catch((e)=>(callback as any)(e));
this.#global.register(this)
.then(this.onRegisterSuccess.bind(this))
.catch(this.onRegisterFail.bind(this))
return this.#global
}
/**
* Manager后
*/
private onRegisterSuccess(){
if(typeof(this.#options.callback)=='function'){
this.#options.callback.call(this)
}
// 从本地缓存中读取并合并补丁语言包
this._mergePatchedMessages();
// 延后执行补丁命令,该命令会向远程下载补丁包
this._patch(this.#currentMessages, this.activeLanguage);
}
/**
* Manager失败时
*/
private onRegisterFail(e:any){
if(typeof(this.#options.callback)=='function'){
this.#options.callback.call(this,e)
}
}
/**
*
*
@ -165,7 +177,7 @@ export class VoerkaI18nScope {
if(asGlobal){
this.global.registerFormatter(name, formatter, {language});
}else{
this.#formatterRegistry.register(name, formatter, {language});
this.formatters!.register(name, formatter, {language});
}
}
// /**
@ -195,11 +207,10 @@ export class VoerkaI18nScope {
* ...
* }
*/
private loadInitialFormatters(){
private loadInitialFormatters(){
this.#formatterRegistry= new VoerkaI18nFormatterRegistry(this)
// 初始化格式化器
this.formatters.loadInitials(this.#options.formatters)
// 切换到当前语言的格式化器上下文
this.formatters.change(this.activeLanguage)
// 保存到Registry中就可以从options中删除了
delete (this.#options as any).formatters
}
@ -230,9 +241,9 @@ export class VoerkaI18nScope {
/**
* 退
*/
private _fallback() {
private fallbackToDefault() {
this.#currentMessages = this.default;
this.#activeLanguage = this.defaultLanguage;
this.#activeLanguage = this.#defaultLanguage;
}
/**
*
@ -240,8 +251,7 @@ export class VoerkaI18nScope {
*
* - {}
* - Promise<VoerkaI18nLanguageMessages>
* -
*
* -
*
* @param language
* @returns
@ -302,11 +312,11 @@ export class VoerkaI18nScope {
// 切换到对应语言的格式化器
await this.formatters.change(newLanguage);
}else{
this._fallback();
this.fallbackToDefault();
}
}catch(e:any){
if (this.debug) console.warn(`Error while loading language <${newLanguage}> on i18nScope(${this.id}): ${e.message}`);
this._fallback();
this.fallbackToDefault();
} finally {
this.#refreshing = false;
}

View File

@ -119,13 +119,13 @@ export function translate(this:VoerkaI18nScope,message:string,...args:any[]):str
// 当源文件运用了babel插件后会将原始文本内容转换为msgId
// 如果是msgId则从scope.default中读取,scope.default=默认语言包={<id>:<message>}
if(isMessageId(result)){
result = scope.default[result] || message
result = (scope.default as any)[result] || message
}
}else{
// 2.2 从当前语言包中取得翻译文本模板字符串
// 如果没有启用babel插件将源文本转换为msgId需要先将文本内容转换为msgId
let msgId = isMessageId(result) ? result : scope.idMap[result]
result = scope.current[msgId] || result
result = (scope.current as any)[msgId] || result
}
// 2. 处理复数
// 经过上面的处理content可能是字符串或者数组