update formatters
This commit is contained in:
parent
6be922d6fe
commit
af148a30cd
@ -7,7 +7,7 @@
|
|||||||
- 以下定义了一些格式化器,在中文场景下,会启用这些格式化器。
|
- 以下定义了一些格式化器,在中文场景下,会启用这些格式化器。
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
export default {
|
export default {
|
||||||
$options:{...},
|
$config:{...},
|
||||||
$types:{
|
$types:{
|
||||||
Date:(value)=>dayjs(value).format("YYYY年MM月DD日 HH:mm:ss"),
|
Date:(value)=>dayjs(value).format("YYYY年MM月DD日 HH:mm:ss"),
|
||||||
},
|
},
|
||||||
@ -32,7 +32,7 @@
|
|||||||
{{if moduleType === "esm"}}
|
{{if moduleType === "esm"}}
|
||||||
export default{{else}}module.exports = {{/if}}{
|
export default{{else}}module.exports = {{/if}}{
|
||||||
// 格式化器参数
|
// 格式化器参数
|
||||||
$options:{
|
$config:{
|
||||||
|
|
||||||
},
|
},
|
||||||
// 指定数据类型的默认格式化器
|
// 指定数据类型的默认格式化器
|
||||||
|
@ -3,27 +3,147 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { toDate,toCurrency } = require("../utils")
|
const { toDate,toCurrency,formatDatetime,formatTime,Formatter } = require("../utils")
|
||||||
|
|
||||||
|
// 日期格式化器
|
||||||
|
// format取字符串"long","short","local","iso","gmt","utc"或者日期模块字符串
|
||||||
|
// { value | date } == '2022/8/15'
|
||||||
|
// { value | date('long') } == '2022/8/15 12:08:32'
|
||||||
|
// { value | date('short') } == '8/15'
|
||||||
|
// { value | date('GMT') } == 'Mon, 15 Aug 2022 06:39:38 GMT'
|
||||||
|
// { value | date('ISO') } == 'Mon, 15 Aug 2022 06:39:38 ISO'
|
||||||
|
// { value | date('YYYY-MM-DD HH:mm:ss') } == '2022-8-15 12:08:32'
|
||||||
|
const dateFormatter = Formatter((value,format,$config)=>{
|
||||||
|
const optionals = ["long","short","local","iso","gmt","utc"]
|
||||||
|
const optionIndex = optionals.findIndex((v,i)=>{
|
||||||
|
if(typeof(format)=="string"){
|
||||||
|
return v==format || v== format.toUpperCase()
|
||||||
|
}else if(typeof(format)=="number"){
|
||||||
|
return format === i
|
||||||
|
}
|
||||||
|
})
|
||||||
|
switch(optionIndex){
|
||||||
|
case 0: // long
|
||||||
|
return formatDatetime(value,$config.long)
|
||||||
|
case 1: // short
|
||||||
|
return formatDatetime(value,$config.short)
|
||||||
|
case 2: // local
|
||||||
|
return value.toLocaleString()
|
||||||
|
case 3: // ISO
|
||||||
|
return value.toISOString()
|
||||||
|
case 4: // GMT
|
||||||
|
return value.toGMTString()
|
||||||
|
case 5: // UTC
|
||||||
|
return value.toUTCString()
|
||||||
|
default:
|
||||||
|
return formatDatetime(value,format)
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
normalize: toDate, // 转换输入为Date类型
|
||||||
|
params : ['format'],
|
||||||
|
configKey: "datetime.date"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 月份格式化器 format可以取值0,1,2,也可以取字符串long,short,number
|
||||||
|
const monthFormatter = Formatter((value,format,$config)=>{
|
||||||
|
const month = value.getMonth()
|
||||||
|
if(typeof(format)==='string'){
|
||||||
|
format = ['long','short','number'].indexOf(format)
|
||||||
|
}
|
||||||
|
if(format<0 && format>2) format = 0
|
||||||
|
return format==0 ? $config.names[month] : (format==1 ? $config.shortNames[month] : month+1)
|
||||||
|
},{
|
||||||
|
normalize: toDate,
|
||||||
|
params : ['format'],
|
||||||
|
configKey: "datetime.month"
|
||||||
|
})
|
||||||
|
|
||||||
|
// 周格式化器 format可以取值0,1,2,也可以取字符串long,short,number
|
||||||
|
const weekdayFormatter = Formatter((value,format,$config)=>{
|
||||||
|
const day = value.getDay()
|
||||||
|
if(typeof(format)==='string'){
|
||||||
|
format = ['long','short','number'].indexOf(format)
|
||||||
|
}
|
||||||
|
if(format<0 && format>2) format = 0
|
||||||
|
return format==0 ? $config.names[day] : (format==1 ? $config.shortNames[day] : day)
|
||||||
|
},{
|
||||||
|
normalize: toDate,
|
||||||
|
params : ['format'],
|
||||||
|
configKey: "datetime.weekday"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 时间格式化器 format可以取值0,1,2,也可以取字符串long,short,timestamp,local
|
||||||
|
const timeFormatter = Formatter((value,format,$config)=>{
|
||||||
|
const month = value.getMonth()
|
||||||
|
const optionals = ['long','short','timestamp','local'] //toLocaleTimeString
|
||||||
|
const optionIndex = optionals.findIndex((v,i)=>{
|
||||||
|
if(typeof(format)=="string"){
|
||||||
|
return v==format || v== format.toUpperCase()
|
||||||
|
}else if(typeof(format)=="number"){
|
||||||
|
return format === i
|
||||||
|
}
|
||||||
|
})
|
||||||
|
switch(optionIndex){
|
||||||
|
case 0: // long
|
||||||
|
return formatTime(value,$config.long)
|
||||||
|
case 1: // short
|
||||||
|
return formatTime(value,$config.short)
|
||||||
|
case 2: // timestamp
|
||||||
|
return value.getTime()
|
||||||
|
case 3: // local
|
||||||
|
return value.toLocaleTimeString()
|
||||||
|
default:
|
||||||
|
return formatTime(value,format)
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
normalize: toDate,
|
||||||
|
params : ['format'],
|
||||||
|
configKey: "datetime.month"
|
||||||
|
})
|
||||||
|
|
||||||
|
// 货币格式化器, CNY $13,456.00
|
||||||
|
const currencyFormatter = Formatter((value, unit,prefix ,suffix, division,precision) =>{
|
||||||
|
return toCurrency(value, { unit,division, prefix, precision,suffix })
|
||||||
|
},{
|
||||||
|
normalize: toNumber,
|
||||||
|
params:["prefix","suffix", "division","precision"],
|
||||||
|
configKey: "currency"
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// 配置参数: 格式化器函数的最后一个参数就是该配置参数
|
// 配置参数
|
||||||
$options:{
|
$config:{
|
||||||
datetime : {
|
datetime : {
|
||||||
units : ["Year","Quarter","Month","Week","Day","Hour","Minute","Second","Millisecond","Microsecond"],
|
units : ["Year","Quarter","Month","Week","Day","Hour","Minute","Second","Millisecond","Microsecond"],
|
||||||
weekday : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
date :{
|
||||||
shortWeekdays : ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"],
|
long : 'YYYY/MM/DD HH:mm:ss',
|
||||||
monthNames : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
short : "MM/DD",
|
||||||
shorMonthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"]
|
format : "local"
|
||||||
},
|
},
|
||||||
|
month:{
|
||||||
|
names : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||||
|
shortNames : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"],
|
||||||
|
format : 0 // 0-长名称,1-短名称,2-数字
|
||||||
|
},
|
||||||
|
weekday:{
|
||||||
|
names :["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
||||||
|
shortNames : ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"],
|
||||||
|
format : 0, // 0-长名称,1-短名称,2-数字
|
||||||
|
},
|
||||||
|
time : {
|
||||||
|
long : "HH:mm:ss",
|
||||||
|
short : "HH:mm:ss",
|
||||||
|
format : 'local'
|
||||||
|
},
|
||||||
|
}
|
||||||
currency : {
|
currency : {
|
||||||
unit : "$",
|
unit : "$", // 单位
|
||||||
prefix : "",
|
prefix : "", // 前缀
|
||||||
suffix : "",
|
suffix : "", // 后缀
|
||||||
division : 3,
|
division : 3, // ,分割位
|
||||||
precision : 2
|
precision : 2, // 精度
|
||||||
},
|
},
|
||||||
number : {
|
number : {
|
||||||
division : 3,
|
division : 3,
|
||||||
@ -50,32 +170,27 @@
|
|||||||
Date : value => { const d = toDate(value); return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}` },
|
Date : value => { const d = toDate(value); return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}` },
|
||||||
Null : value =>"",
|
Null : value =>"",
|
||||||
Undefined: value =>"",
|
Undefined: value =>"",
|
||||||
Error : value => "ERROR"
|
Error : value => "ERROR",
|
||||||
|
Boolean : value =>value ? "True":"False"
|
||||||
},
|
},
|
||||||
// 以下是格式化定义
|
// 以下是格式化定义
|
||||||
// 日期
|
// ******************* 日期 *******************
|
||||||
date : value => { const d = toDate(value); return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}` },
|
date : dateFormatter,
|
||||||
shortdate : value => { const d = toDate(value); return `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}` },
|
time : timeFormatter,
|
||||||
time : value => { const d = toDate(value); return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}` },
|
|
||||||
shorttime : value => { const d = toDate(value); return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}` },
|
|
||||||
year : value => toDate(value).getFullYear(),
|
year : value => toDate(value).getFullYear(),
|
||||||
month : value => toDate(value).getMonth() + 1,
|
month : value => toDate(value).getMonth() + 1,
|
||||||
day : value => toDate(value).getDate(),
|
day : value => toDate(value).getDate(),
|
||||||
weekdayValue : value => toDate(value).getDay(),
|
weekday : weekdayFormatter,
|
||||||
weekday : value => ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][toDate(value).getDay()],
|
month : monthFormatter,
|
||||||
shortWeekday : value => ["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"][toDate(value).getDay()],
|
// ******************* 时间 *******************
|
||||||
monthName : value => ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][toDate(value).getMonth()],
|
|
||||||
shorMonthName : value => ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"][toDate(value).getMonth()],
|
|
||||||
// 时间
|
|
||||||
hour : value => toDate(value).getHours(),
|
hour : value => toDate(value).getHours(),
|
||||||
hour12 : value => {const hour = toDate(value).getHours(); return hour > 12 ? hour - 12 : thour},
|
hour12 : value => {const hour = toDate(value).getHours(); return hour > 12 ? hour - 12 : thour},
|
||||||
minute : value => toDate(value).getMinutes(),
|
minute : value => toDate(value).getMinutes(),
|
||||||
second : value => toDate(value).getSeconds(),
|
second : value => toDate(value).getSeconds(),
|
||||||
millisecond : value => toDate(value).getMilliseconds(),
|
millisecond : value => toDate(value).getMilliseconds(),
|
||||||
timestamp : value => toDate(value).getTime(),
|
timestamp : value => toDate(value).getTime(),
|
||||||
// 货币
|
// ******************* 货币 *******************
|
||||||
// 常规货币形式 $111,233.33
|
currency : currencyFormatter,
|
||||||
currency : (value, prefix = "$",suffix="", division = 3,precision = 2) => toCurrency(value, { division, prefix, precision,suffix }),
|
|
||||||
// 数字,如,使用分割符
|
// 数字,如,使用分割符
|
||||||
number : (value, division = 3,precision = 0) => toCurrency(value, { division, precision})
|
number : (value, division = 3,precision = 0) => toCurrency(value, { division, precision})
|
||||||
}
|
}
|
@ -8,19 +8,35 @@
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
// 配置参数: 格式化器函数的最后一个参数就是该配置参数
|
// 配置参数: 格式化器函数的最后一个参数就是该配置参数
|
||||||
$options:{
|
$config:{
|
||||||
datetime : {
|
datetime : {
|
||||||
units : CN_DATETIME_UNITS,
|
units : CN_DATETIME_UNITS,
|
||||||
weekdays : CN_WEEK_DAYS,
|
date :{
|
||||||
shortWeekdays : CN_SHORT_WEEK_DAYS,
|
long : 'YYYY年MM月DD日 HH点mm分ss秒',
|
||||||
monthNames : CN_MONTH_NAMES,
|
short : "MM/DD",
|
||||||
shorMonthNames: CN_SHORT_MONTH_NAMES
|
format : 'YYYY年MM月DD日 HH点mm分ss秒'
|
||||||
},
|
},
|
||||||
|
month:{
|
||||||
|
names : CN_MONTH_NAMES,
|
||||||
|
shortNames : CN_SHORT_MONTH_NAMES,
|
||||||
|
format : 0, // 0-长名称,1-短名称,2-数字
|
||||||
|
},
|
||||||
|
weekday:{
|
||||||
|
names : CN_WEEK_DAYS,
|
||||||
|
shortNames : CN_SHORT_WEEK_DAYS,
|
||||||
|
format : 0, // 0-长名称,1-短名称,2-数字
|
||||||
|
},
|
||||||
|
time:{
|
||||||
|
long : "HH点mm分ss秒",
|
||||||
|
short : "HH:mm:ss",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
currency : {
|
currency : {
|
||||||
unit : "¥",
|
unit : "¥",
|
||||||
prefix : "",
|
prefix : "",
|
||||||
suffix : "",
|
suffix : "元",
|
||||||
division : 3,
|
division : 4,
|
||||||
precision : 2
|
precision : 2
|
||||||
},
|
},
|
||||||
number : {
|
number : {
|
||||||
@ -29,16 +45,10 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
$types: {
|
$types: {
|
||||||
Date: value => {const d = toDate(value);return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日 ${d.getHours()}点${d.getMinutes()}分${d.getSeconds()}秒`}
|
Date: value => {const d = toDate(value);return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日 ${d.getHours()}点${d.getMinutes()}分${d.getSeconds()}秒`},
|
||||||
|
Boolean : value =>value ? "是":"否"
|
||||||
|
|
||||||
},
|
},
|
||||||
// 日期
|
|
||||||
date : value => { const d = toDate(value); return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日` },
|
|
||||||
weekday : value => CN_WEEK_DAYS[toDate(value).getDay()],
|
|
||||||
shortWeekday : value => CN_SHORT_WEEK_DAYS[toDate(value).getDay()],
|
|
||||||
monthName : value => CN_MONTH_NAMES[toDate(value).getMonth()],
|
|
||||||
shorMonthName: value => CN_SHORT_MONTH_NAMES[toDate(value).getMonth()],
|
|
||||||
// 时间
|
|
||||||
time : value =>{const d = toDate(value);return `${d.getHours()}点${d.getMinutes()}分${d.getSeconds()}秒`},
|
|
||||||
// 货币
|
// 货币
|
||||||
currency : (value,prefix = "¥",suffix="", division = 4, precision = 2) => toCurrency(value, { division, prefix, precision,suffix }),
|
currency : (value,prefix = "¥",suffix="", division = 4, precision = 2) => toCurrency(value, { division, prefix, precision,suffix }),
|
||||||
// 中文货币,big=true代表大写形式
|
// 中文货币,big=true代表大写形式
|
||||||
|
@ -271,7 +271,7 @@ function getFormatter(scope,activeLanguage,name){
|
|||||||
resetScopeCache(scope,activeLanguage)
|
resetScopeCache(scope,activeLanguage)
|
||||||
}
|
}
|
||||||
const fallbackLanguage = scope.getLanguage(activeLanguage).fallback
|
const fallbackLanguage = scope.getLanguage(activeLanguage).fallback
|
||||||
// 2. 先在当前作用域中查找,再在全局查找 formatters={$types,$options,[格式化器名称]:()=>{},[格式化器名称]:()=>{}}
|
// 2. 先在当前作用域中查找,再在全局查找 formatters={$types,$config,[格式化器名称]:()=>{},[格式化器名称]:()=>{}}
|
||||||
const range = [
|
const range = [
|
||||||
scope.activeFormatters,
|
scope.activeFormatters,
|
||||||
scope.formatters[fallbackLanguage], // 如果指定了回退语言时,也在该回退语言中查找
|
scope.formatters[fallbackLanguage], // 如果指定了回退语言时,也在该回退语言中查找
|
||||||
@ -305,9 +305,9 @@ function executeChecker(checker,value){
|
|||||||
/**
|
/**
|
||||||
* 执行格式化器并返回结果
|
* 执行格式化器并返回结果
|
||||||
*
|
*
|
||||||
* 格式化器this指向当前scope,并且最后一个参数是当前scope格式化器的$options
|
* 格式化器this指向当前scope,并且最后一个参数是当前scope格式化器的$config
|
||||||
*
|
*
|
||||||
* 这样格式化器可以读取$options
|
* 这样格式化器可以读取$config
|
||||||
*
|
*
|
||||||
* @param {*} value
|
* @param {*} value
|
||||||
* @param {Array[Function]} formatters 多个格式化器函数(经过包装过的)顺序执行,前一个输出作为下一个格式化器的输入
|
* @param {Array[Function]} formatters 多个格式化器函数(经过包装过的)顺序执行,前一个输出作为下一个格式化器的输入
|
||||||
@ -655,7 +655,7 @@ function translate(message) {
|
|||||||
get activeLanguage(){ return this._settings.activeLanguage} // 当前激活语言 名称
|
get activeLanguage(){ return this._settings.activeLanguage} // 当前激活语言 名称
|
||||||
get defaultLanguage(){ return this._settings.defaultLanguage} // 默认语言名称
|
get defaultLanguage(){ return this._settings.defaultLanguage} // 默认语言名称
|
||||||
get languages(){ return this._settings.languages} // 支持的语言列表
|
get languages(){ return this._settings.languages} // 支持的语言列表
|
||||||
get formatters(){ return this._settings.formatters } // 内置格式化器{*:{$options,$types,...},zh:{$options,$types,...},en:{$options,$types,...}}
|
get formatters(){ return this._settings.formatters } // 内置格式化器{*:{$config,$types,...},zh:{$config,$types,...},en:{$config,$types,...}}
|
||||||
get defaultMessageLoader(){ return this._defaultMessageLoader} // 默认语言包加载器
|
get defaultMessageLoader(){ return this._defaultMessageLoader} // 默认语言包加载器
|
||||||
|
|
||||||
// 通过默认加载器加载文件
|
// 通过默认加载器加载文件
|
||||||
|
@ -25,7 +25,7 @@ module.exports = class i18nScope {
|
|||||||
this._default = options.default; // 默认语言包
|
this._default = options.default; // 默认语言包
|
||||||
this._messages = options.messages; // 当前语言包
|
this._messages = options.messages; // 当前语言包
|
||||||
this._idMap = options.idMap; // 消息id映射列表
|
this._idMap = options.idMap; // 消息id映射列表
|
||||||
this._formatters = options.formatters; // 当前作用域的格式化函数列表{<lang>: {$types,$options,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
|
this._formatters = options.formatters; // 当前作用域的格式化函数列表{<lang>: {$types,$config,[格式化器名称]: () => {},[格式化器名称]: () => {}}}
|
||||||
this._loaders = options.loaders; // 异步加载语言文件的函数列表
|
this._loaders = options.loaders; // 异步加载语言文件的函数列表
|
||||||
this._global = null; // 引用全局VoerkaI18n配置,注册后自动引用
|
this._global = null; // 引用全局VoerkaI18n配置,注册后自动引用
|
||||||
this._patchMessages = {}; // 语言包补丁信息{<language>: {....},<language>:{....}}
|
this._patchMessages = {}; // 语言包补丁信息{<language>: {....},<language>:{....}}
|
||||||
@ -62,8 +62,8 @@ module.exports = class i18nScope {
|
|||||||
get languages() {return this._languages;} // 当前作用域支持的语言列表[{name,title,fallback}]
|
get languages() {return this._languages;} // 当前作用域支持的语言列表[{name,title,fallback}]
|
||||||
get loaders() { return this._loaders;} // 异步加载语言文件的函数列表
|
get loaders() { return this._loaders;} // 异步加载语言文件的函数列表
|
||||||
get global() { return this._global;} // 引用全局VoerkaI18n配置,注册后自动引用
|
get global() { return this._global;} // 引用全局VoerkaI18n配置,注册后自动引用
|
||||||
get formatters() { return this._formatters;} // 当前作用域的所有格式化器定义 {<语言名称>: {$types,$options,[格式化器名称]: () = >{},[格式化器名称]: () => {}}}
|
get formatters() { return this._formatters;} // 当前作用域的所有格式化器定义 {<语言名称>: {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () => {}}}
|
||||||
get activeFormatters() {return this._activeFormatters} // 当前作用域激活的格式化器定义 {$types,$options,[格式化器名称]: () = >{},[格式化器名称]: () = >{}}
|
get activeFormatters() {return this._activeFormatters} // 当前作用域激活的格式化器定义 {$types,$config,[格式化器名称]: () = >{},[格式化器名称]: () = >{}}
|
||||||
get activeFormatterOptions(){return this._activeFormatterOptions} // 当前格式化器合并后的配置参数,参数已经合并了全局格式化器中的参数
|
get activeFormatterOptions(){return this._activeFormatterOptions} // 当前格式化器合并后的配置参数,参数已经合并了全局格式化器中的参数
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,10 +86,12 @@ module.exports = class i18nScope {
|
|||||||
registerFormatter(name,value=>{...},{langauge:["zh","cht"]}) // 注册到zh和cht语言
|
registerFormatter(name,value=>{...},{langauge:["zh","cht"]}) // 注册到zh和cht语言
|
||||||
registerFormatter(name,value=>{...},{langauge:"zh,cht"})
|
registerFormatter(name,value=>{...},{langauge:"zh,cht"})
|
||||||
* @param {*} formatter 格式化器
|
* @param {*} formatter 格式化器
|
||||||
language : 声明该格式化器适用语言
|
language : 字符串或数组,声明该格式化器适用语言
|
||||||
|
*代表适用于所有语言
|
||||||
|
语言名称,语言名称数组,或者使用,分割的语言名称字符串
|
||||||
asGlobal : 注册到全局
|
asGlobal : 注册到全局
|
||||||
*/
|
*/
|
||||||
registerFormatter(name, formatter, { language = "*", asGlobal } = {}) {
|
registerFormatter(name, formatter, { language = "*", global : asGlobal } = {}) {
|
||||||
if (!isFunction(formatter) || typeof name !== "string") {
|
if (!isFunction(formatter) || typeof name !== "string") {
|
||||||
throw new TypeError("Formatter must be a function");
|
throw new TypeError("Formatter must be a function");
|
||||||
}
|
}
|
||||||
@ -110,6 +112,20 @@ module.exports = class i18nScope {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 注册多种格式化器
|
||||||
|
* registerFormatters(={"*",zh:{...},en:{...}})
|
||||||
|
* registerFormatters(={"*",zh:{...},en:{...}},true) 在全局注册
|
||||||
|
* @param {*} formatters ={"*",zh:{...},en:{...}}
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
registerFormatters(formatters,isGlobal=false) {
|
||||||
|
Object.entries(formatters).forEach(([language,fns]=>{
|
||||||
|
Object.entries(fns).forEach(([name,formatter])=>{
|
||||||
|
this.registerFormatter(name,formatter,{language})
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 注册默认文本信息加载器
|
* 注册默认文本信息加载器
|
||||||
* @param {Function} 必须是异步函数或者是返回Promise
|
* @param {Function} 必须是异步函数或者是返回Promise
|
||||||
@ -144,7 +160,7 @@ module.exports = class i18nScope {
|
|||||||
/**
|
/**
|
||||||
* 初始化格式化器
|
* 初始化格式化器
|
||||||
* 激活和默认语言的格式化器采用静态导入的形式,而没有采用异步块的形式,这是为了确保首次加载时的能马上读取,而减少延迟加载
|
* 激活和默认语言的格式化器采用静态导入的形式,而没有采用异步块的形式,这是为了确保首次加载时的能马上读取,而减少延迟加载
|
||||||
* _activeFormatters={$options:{...},$types:{...},[格式化器名称]:()=>{...},[格式化器名称]:()=>{...},...}}
|
* _activeFormatters={$config:{...},$types:{...},[格式化器名称]:()=>{...},[格式化器名称]:()=>{...},...}}
|
||||||
*/
|
*/
|
||||||
_initFormatters(newLanguage){
|
_initFormatters(newLanguage){
|
||||||
this._activeFormatters = {}
|
this._activeFormatters = {}
|
||||||
@ -167,7 +183,7 @@ module.exports = class i18nScope {
|
|||||||
* 当切换语言时,格式化器应该切换到对应语言的格式化器
|
* 当切换语言时,格式化器应该切换到对应语言的格式化器
|
||||||
*
|
*
|
||||||
* 重要需要处理:
|
* 重要需要处理:
|
||||||
* $options参数采用合并继承机制
|
* $config参数采用合并继承机制
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param {*} language
|
* @param {*} language
|
||||||
@ -192,19 +208,19 @@ module.exports = class i18nScope {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 生成格式化器的配置参数,该参数由以下合并而成:
|
* 生成格式化器的配置参数,该参数由以下合并而成:
|
||||||
* - global.formatters[*].$options
|
* - global.formatters[*].$config
|
||||||
* - global.formatters[language].$options
|
* - global.formatters[language].$config
|
||||||
* - scope.activeFormatters.$options 当前优先
|
* - scope.activeFormatters.$config 当前优先
|
||||||
*/
|
*/
|
||||||
_generateFormatterOptions(language){
|
_generateFormatterOptions(language){
|
||||||
let options
|
let options
|
||||||
try{
|
try{
|
||||||
options = Object.assign({},getByPath(this._global.formatters,`*.$options`,{}))
|
options = Object.assign({},getByPath(this._global.formatters,`*.$config`,{}))
|
||||||
deepMixin(options,getByPath(this._global.formatters,`${language}.$options`,{}))
|
deepMixin(options,getByPath(this._global.formatters,`${language}.$config`,{}))
|
||||||
deepMixin(options,getByPath(this._activeFormatters,"$options",{}))
|
deepMixin(options,getByPath(this._activeFormatters,"$config",{}))
|
||||||
}catch(e){
|
}catch(e){
|
||||||
if(this.debug) console.error(`Error while generate <${language}> formatter options: `,e)
|
if(this.debug) console.error(`Error while generate <${language}> formatter options: `,e)
|
||||||
if(!options) options = this._activeFormatters.$options || {}
|
if(!options) options = this._activeFormatters.$config || {}
|
||||||
}
|
}
|
||||||
return this._activeFormatterOptions = options
|
return this._activeFormatterOptions = options
|
||||||
}
|
}
|
||||||
|
@ -151,12 +151,12 @@ function toNumber(value,defualt=0) {
|
|||||||
*
|
*
|
||||||
* @param {*} value 可以是数字也可以是字符串
|
* @param {*} value 可以是数字也可以是字符串
|
||||||
* @param {*} division 分割符号位数,3代表每3个数字添加一个,号
|
* @param {*} division 分割符号位数,3代表每3个数字添加一个,号
|
||||||
* @param {*} prefix 前缀,货币单位
|
* @param {*} prefix 前缀
|
||||||
* @param {*} suffix 前缀,货币单位
|
* @param {*} suffix 后缀
|
||||||
* @param {*} precision 小数点精确到几位,0-自动
|
* @param {*} precision 小数点精确到几位,0-自动
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function toCurrency(value,{division=3,prefix="",precision=0,suffix=""}={}){
|
function toCurrency(value,{unit="",division=3,prefix="",precision=0,suffix=""}={}){
|
||||||
let [wholeValue,decimalValue] = String(value).split(".")
|
let [wholeValue,decimalValue] = String(value).split(".")
|
||||||
let result = []
|
let result = []
|
||||||
for(let i=0;i<wholeValue.length;i++){
|
for(let i=0;i<wholeValue.length;i++){
|
||||||
@ -169,7 +169,7 @@ function toNumber(value,defualt=0) {
|
|||||||
}
|
}
|
||||||
result.push(`.${decimalValue}`)
|
result.push(`.${decimalValue}`)
|
||||||
}
|
}
|
||||||
return prefix + result.join("") + suffix
|
return `${prefix}${unit}${result.join("")}${suffix}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,9 +225,9 @@ function getByPath(obj,path,defaultValue){
|
|||||||
function formatDatetime(value,templ="YYYY/MM/DD HH:mm:ss"){
|
function formatDatetime(value,templ="YYYY/MM/DD HH:mm:ss"){
|
||||||
const v = toDate(value)
|
const v = toDate(value)
|
||||||
const year =String(v.getFullYear()),month = String(v.getMonth()+1),weekday=String(v.getDay()),day=String(v.getDate())
|
const year =String(v.getFullYear()),month = String(v.getMonth()+1),weekday=String(v.getDay()),day=String(v.getDate())
|
||||||
const minute = String(v.getMinutes()),second = String(v.getSeconds()),millisecond=String(v.getMilliseconds()),hour = String(v.getHours())
|
const hourNum = v.getHours()
|
||||||
const time = String(v.getTime())
|
const hour = String(hourNum).minute = String(v.getMinutes()),second = String(v.getSeconds()),millisecond=String(v.getMilliseconds())
|
||||||
let result = templ
|
const timezone = v.getTimezoneOffset()
|
||||||
const vars = [
|
const vars = [
|
||||||
["YYYY", year], // 2018 年,四位数
|
["YYYY", year], // 2018 年,四位数
|
||||||
["YY", year.substring(year.length - 2, year.length)], // 18 年,两位数
|
["YY", year.substring(year.length - 2, year.length)], // 18 年,两位数
|
||||||
@ -236,10 +236,33 @@ function formatDatetime(value,templ="YYYY/MM/DD HH:mm:ss"){
|
|||||||
["M", month], // 1-12 月,从1开始
|
["M", month], // 1-12 月,从1开始
|
||||||
["DD", day.padStart(2, "0")], // 01-31 日,两位数
|
["DD", day.padStart(2, "0")], // 01-31 日,两位数
|
||||||
["D", day], // 1-31 日
|
["D", day], // 1-31 日
|
||||||
["HH", String(hour).padStart(2, "0")], // 00-23 24小时,两位数
|
["HH", hour.padStart(2, "0")], // 00-23 24小时,两位数
|
||||||
["H", String(hour)], // 0-23 24小时
|
["H", hour], // 0-23 24小时
|
||||||
|
["hh", String(hourNum > 12 ? hourNum - 12 : hourNum).padStart(2, "0")], // 01-12 12小时,两位数
|
||||||
|
["h", String(hourNum > 12 ? hourNum - 12 : hourNum)], // 1-12 12小时
|
||||||
|
["mm", minute.padStart(2, "0")], // 00-59 分钟,两位数
|
||||||
|
["m", minute], // 0-59 分钟
|
||||||
|
["ss", second.padStart(2, "0")], // 00-59 秒,两位数
|
||||||
|
["s", second], // 0-59 秒
|
||||||
|
["SSS", millisecond], // 000-999 毫秒,三位数
|
||||||
|
["SS", millisecond.substring(year.length - 2, year.length)], // 00-99 毫秒(十),两位数
|
||||||
|
["S",millisecond[millisecond.length - 1]], // 0-9 毫秒(百),一位数
|
||||||
|
["A", hour > 12 ? "PM" : "AM"], // AM / PM 上/下午,大写
|
||||||
|
["a", hour > 12 ? "pm" : "am"], // am / pm 上/下午,小写
|
||||||
|
]
|
||||||
|
vars.forEach(([key,value])=>result = replaceAll(result,key,value))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
function formatTime(value,templ="HH:mm:ss"){
|
||||||
|
const v = toDate(value)
|
||||||
|
const hourNum = v.getHours()
|
||||||
|
const hour = String(hourNum).minute = String(v.getMinutes()),second = String(v.getSeconds()),millisecond=String(v.getMilliseconds())
|
||||||
|
let result = templ
|
||||||
|
const vars = [
|
||||||
|
["HH", hour.padStart(2, "0")], // 00-23 24小时,两位数
|
||||||
|
["H", hour], // 0-23 24小时
|
||||||
["hh", String(hour > 12 ? hour - 12 : hour).padStart(2, "0")], // 01-12 12小时,两位数
|
["hh", String(hour > 12 ? hour - 12 : hour).padStart(2, "0")], // 01-12 12小时,两位数
|
||||||
["h", hour > 12 ? hour - 12 : hour], // 1-12 12小时
|
["h", String(hour > 12 ? hour - 12 : hour)], // 1-12 12小时
|
||||||
["mm", minute.padStart(2, "0")], // 00-59 分钟,两位数
|
["mm", minute.padStart(2, "0")], // 00-59 分钟,两位数
|
||||||
["m", minute], // 0-59 分钟
|
["m", minute], // 0-59 分钟
|
||||||
["ss", second.padStart(2, "0")], // 00-59 秒,两位数
|
["ss", second.padStart(2, "0")], // 00-59 秒,两位数
|
||||||
@ -250,10 +273,9 @@ function formatDatetime(value,templ="YYYY/MM/DD HH:mm:ss"){
|
|||||||
["A", hour > 12 ? "PM" : "AM"], // AM / PM 上/下午,大写
|
["A", hour > 12 ? "PM" : "AM"], // AM / PM 上/下午,大写
|
||||||
["a", hour > 12 ? "pm" : "am"] // am / pm 上/下午,小写
|
["a", hour > 12 ? "pm" : "am"] // am / pm 上/下午,小写
|
||||||
]
|
]
|
||||||
vars.forEach(([key,value])=>result = result.replace(key,value))
|
vars.forEach(([key,value])=>result = replaceAll(result,key,value))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 替换所有字符串
|
* 替换所有字符串
|
||||||
* 低版本ES未提供replaceAll,此函数用来替代
|
* 低版本ES未提供replaceAll,此函数用来替代
|
||||||
@ -282,10 +304,23 @@ function replaceAll(str,findValue,replaceValue){
|
|||||||
*
|
*
|
||||||
* - 函数第一个参数是上一上格式化器的输出
|
* - 函数第一个参数是上一上格式化器的输出
|
||||||
* - 支持0-N个简单类型的入参
|
* - 支持0-N个简单类型的入参
|
||||||
* - 格式化器可以在格式化器的$options参数指定一个键值来配置不同语言时的参数
|
* - 格式化器可以在格式化器的$config参数指定一个键值来配置不同语言时的参数
|
||||||
*
|
*
|
||||||
* createFormatter((value,prefix,suffix, division ,precision,options)=>{
|
* "currency":createFormatter((value,prefix,suffix, division ,precision,options)=>{
|
||||||
|
* // 无论在格式化入参数是多少个,经过处理后在此得到prefix,suffix, division ,precision参数已经是经过处理后的参数
|
||||||
|
* 依次读取格式化器的参数合并:
|
||||||
|
* - 从当前激活格式化器的$config中读取配置参数
|
||||||
|
* - 在t函数后传入参数
|
||||||
|
* 比如currency格式化器支持4参数,其入参顺序是prefix,suffix, division ,precision
|
||||||
|
* 那么在t函数中可以使用以下五种入参数方式
|
||||||
|
* {value | currency } //prefix=undefined,suffix=undefined, division=undefined ,precision=undefined
|
||||||
|
* {value | currency(prefix) }
|
||||||
|
* {value | currency(prefix,suffix) }
|
||||||
|
* {value | currency(prefix,suffix,division) }
|
||||||
|
* {value | currency(prefix,suffix,division,precision)}
|
||||||
*
|
*
|
||||||
|
* 经过createFormatter处理后,会从当前激活格式化器的$config中读取prefix,suffix, division ,precision参数作为默认参数
|
||||||
|
* 然后t函数中的参数会覆盖默认参数,优先级更高
|
||||||
* },
|
* },
|
||||||
* {
|
* {
|
||||||
* unit:"$",
|
* unit:"$",
|
||||||
@ -295,8 +330,9 @@ function replaceAll(str,findValue,replaceValue){
|
|||||||
* precision
|
* precision
|
||||||
* },
|
* },
|
||||||
* {
|
* {
|
||||||
|
* normalize:value=>{...},
|
||||||
* params:["prefix","suffix", "division" ,"precision"] // 声明参数顺序
|
* params:["prefix","suffix", "division" ,"precision"] // 声明参数顺序
|
||||||
* optionKey:"currency" // 声明特定语言下的配置在$options.currency
|
* configKey:"currency" // 声明特定语言下的配置在$config.currency
|
||||||
* }
|
* }
|
||||||
* )
|
* )
|
||||||
*
|
*
|
||||||
@ -309,13 +345,13 @@ function replaceAll(str,findValue,replaceValue){
|
|||||||
let opts = Object.assign({
|
let opts = Object.assign({
|
||||||
normalize : null, // 对输入值进行规范化处理,如进行时间格式化时,为了提高更好的兼容性,支持数字时间戳/字符串/Date等,需要对输入值进行处理,如强制类型转换等
|
normalize : null, // 对输入值进行规范化处理,如进行时间格式化时,为了提高更好的兼容性,支持数字时间戳/字符串/Date等,需要对输入值进行处理,如强制类型转换等
|
||||||
params : [], // 声明参数顺序
|
params : [], // 声明参数顺序
|
||||||
optionKeyPath: null // 声明该格式化器在$options中的路径,支持简单的使用.的路径语法
|
configKey : null // 声明该格式化器在$config中的路径,支持简单的使用.的路径语法
|
||||||
})
|
})
|
||||||
|
|
||||||
// 最后一个参数是传入activeFormatterOptions参数
|
// 最后一个参数是传入activeFormatterOptions参数
|
||||||
const wrappedFn = function(value,...args){
|
const wrappedFn = function(value,...args){
|
||||||
let finalValue = value
|
let finalValue = value
|
||||||
// 1. 输入值规范处理,主要的类型转换等
|
// 1. 输入值规范处理,主要是进行类型转换,确保输入的数据类型及相关格式的正确性,提高数据容错性
|
||||||
if(isFunction(opts.normalize)){
|
if(isFunction(opts.normalize)){
|
||||||
try{
|
try{
|
||||||
finalValue = opts.normalize(finalValue)
|
finalValue = opts.normalize(finalValue)
|
||||||
@ -325,16 +361,16 @@ function replaceAll(str,findValue,replaceValue){
|
|||||||
let activeFormatterOpts = args.length>0 ? args[args.length-1] : {}
|
let activeFormatterOpts = args.length>0 ? args[args.length-1] : {}
|
||||||
if(!isPlainObject( activeFormatterOpts)) activeFormatterOpts ={}
|
if(!isPlainObject( activeFormatterOpts)) activeFormatterOpts ={}
|
||||||
// 3. 从当前语言的激活语言中读取配置参数
|
// 3. 从当前语言的激活语言中读取配置参数
|
||||||
const activeOptions =Object.assign({},defaultParams,getByPath(activeFormatterOpts,opts.optionKey,{}))
|
const activeConfig =Object.assign({},defaultParams,getByPath(activeFormatterOpts,opts.configKey,{}))
|
||||||
let finalArgs = opts.params.map(param=>getByPath(activeOptions,param,undefined))
|
let finalArgs = opts.params.map(param=>getByPath(activeConfig,param,undefined))
|
||||||
// 4. 将翻译函数执行格式化器时传入的参数具有高优先级
|
// 4. 将翻译函数执行格式化器时传入的参数覆盖默认参数
|
||||||
for(let i =0; i<finalArgs.length-1;i++){
|
for(let i =0; i<finalArgs.length-1;i++){
|
||||||
if(i>=args.length-1) break // 最后一参数是配置
|
if(i>=args.length-1) break // 最后一参数是配置
|
||||||
if(args[i]!==undefined) finalArgs[i] = args[i]
|
if(args[i]!==undefined) finalArgs[i] = args[i]
|
||||||
}
|
}
|
||||||
return fn(finalValue,...finalArgs,activeFormatterOpts)
|
return fn(finalValue,...finalArgs,activeFormatterOpts)
|
||||||
}
|
}
|
||||||
fn.paramCount = opts.paramCount
|
wrappedFn.configurable = true // 当函数是可配置时才在最后一个参数中传入$config
|
||||||
return wrappedFn
|
return wrappedFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,6 +388,8 @@ module.exports ={
|
|||||||
replaceAll,
|
replaceAll,
|
||||||
getByPath,
|
getByPath,
|
||||||
getDataTypeName,
|
getDataTypeName,
|
||||||
|
formatDatetime,
|
||||||
|
formatTime,
|
||||||
toDate,
|
toDate,
|
||||||
toNumber,
|
toNumber,
|
||||||
toCurrency,
|
toCurrency,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const dayjs = require('dayjs');
|
const dayjs = require('dayjs');
|
||||||
const { getInterpolatedVars, replaceInterpolatedVars , translate} = require('../packages/runtime/index.js')
|
const { i18nScope, translate, getInterpolatedVars } = require('../packages/runtime/dist/runtime.cjs')
|
||||||
|
|
||||||
const messages = {
|
const loaders = {
|
||||||
zh:{
|
zh:{
|
||||||
1:"你好",
|
1:"你好",
|
||||||
2:"现在是{}",
|
2:"现在是{}",
|
||||||
@ -16,88 +16,60 @@ const messages = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const idMap = {
|
|
||||||
"你好":1,
|
|
||||||
"现在是{}":2,
|
|
||||||
"我出生于{year}年,今年{age}岁":3,
|
|
||||||
"我有{}个朋友":4
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const formatters = {
|
||||||
|
|
||||||
|
|
||||||
let scope1 ={
|
|
||||||
defaultLanguage: "zh", // 默认语言名称
|
|
||||||
default: messages.zh,
|
|
||||||
messages :messages.zh,
|
|
||||||
idMap,
|
|
||||||
formatters:{ // 当前作用域的格式化函数列表
|
|
||||||
"*":{
|
|
||||||
$types:{
|
|
||||||
Date:(v)=>dayjs(v).format('YYYY-MM-DD HH:mm:ss'),
|
|
||||||
Boolean:(v)=>v?"True":"False",
|
|
||||||
},
|
|
||||||
sum:(v,n=1)=>v+n,
|
|
||||||
double:(v)=>v*2,
|
|
||||||
upper:(v)=>v.toUpperCase(),
|
|
||||||
lower:(v)=>v.toLowerCase()
|
|
||||||
},
|
|
||||||
zh:{
|
zh:{
|
||||||
$types:{
|
$config:{},
|
||||||
Date:(v)=>dayjs(v).format('YYYY年MM月DD日 HH点mm分ss秒'),
|
$types:{},
|
||||||
Boolean:(v)=>v?"是":"否",
|
|
||||||
},
|
|
||||||
book:(v)=>`《${v}》`,
|
book:(v)=>`《${v}》`,
|
||||||
},
|
},
|
||||||
en:{
|
en:{
|
||||||
$types:{
|
$config:{},
|
||||||
|
$types:{ },
|
||||||
},
|
|
||||||
book:(v)=>`<${v}>`,
|
book:(v)=>`<${v}>`,
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
loaders:{}, // 异步加载语言文件的函数列表
|
const idMap = {
|
||||||
global:{// 引用全局VoerkaI18n配置
|
1:"你好",
|
||||||
defaultLanguage: "zh",
|
2:"现在是{}",
|
||||||
activeLanguage: "zh",
|
3:"我出生于{year}年,今年{age}岁"
|
||||||
languages:[
|
4:"我有{}个朋友"
|
||||||
{name:"zh",title:"中文",default:true},
|
}
|
||||||
|
const languages = [
|
||||||
|
{ name: "zh", title: "中文" },
|
||||||
{ name: "en", title: "英文" },
|
{ name: "en", title: "英文" },
|
||||||
{ name: "de", title: "德语" },
|
{ name: "de", title: "德语" },
|
||||||
{ name: "jp", title: "日语" }
|
{ name: "jp", title: "日语" }
|
||||||
],
|
]
|
||||||
formatters:{ // 当前作用域的格式化函数列表
|
|
||||||
|
|
||||||
|
const scope = new i18nScope({
|
||||||
|
id : "test",
|
||||||
|
defaultLanguage: "zh",
|
||||||
|
activeLanguage : "zh",
|
||||||
|
namespaces : {},
|
||||||
|
default : loaders.zh, // 默认语言包
|
||||||
|
messages : loaders.zh, // 当前语言包
|
||||||
|
languages, // 语言配置
|
||||||
|
idMap, // 消息id映射列表
|
||||||
|
formatters, // 扩展自定义格式化器
|
||||||
|
loaders // 语言包加载器
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const t = translate.bind(scope)
|
||||||
|
|
||||||
|
// 适用于所有语言的格式化器,并且注册到全局
|
||||||
|
scope.registerFormatters({
|
||||||
"*":{
|
"*":{
|
||||||
$types:{
|
sum : (v,n=1)=>v+n,
|
||||||
|
double: (v)=>v*2,
|
||||||
}
|
upper : (v)=>v.toUpperCase(),
|
||||||
},
|
|
||||||
zh:{
|
|
||||||
$types:{
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
en:{
|
|
||||||
$types:{
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const replaceVars = replaceInterpolatedVars.bind(scope1)
|
|
||||||
const t = translate.bind(scope1)
|
|
||||||
|
|
||||||
|
|
||||||
function changeLanguage(language){
|
|
||||||
scope1.global.activeLanguage = language
|
|
||||||
scope1.messages = messages[language]
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
},true)
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
scope1.global.activeLanguage = "zh" // 切换到中文
|
scope.change("zh")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -121,7 +93,6 @@ test("获取翻译内容中的插值变量",done=>{
|
|||||||
expect(results[1].name).toEqual("city");
|
expect(results[1].name).toEqual("city");
|
||||||
expect(results[1].formatters.length).toEqual(0);
|
expect(results[1].formatters.length).toEqual(0);
|
||||||
|
|
||||||
|
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -136,7 +107,6 @@ test("获取翻译内容中定义了重复的插值变量",done=>{
|
|||||||
expect(results[1].formatters[0].name).toEqual("x");
|
expect(results[1].formatters[0].name).toEqual("x");
|
||||||
expect(results[1].formatters[0].args).toEqual([]);
|
expect(results[1].formatters[0].args).toEqual([]);
|
||||||
|
|
||||||
|
|
||||||
expect(results[2].name).toEqual("a");
|
expect(results[2].name).toEqual("a");
|
||||||
expect(results[2].formatters.length).toEqual(2);
|
expect(results[2].formatters.length).toEqual(2);
|
||||||
expect(results[2].formatters[0].name).toEqual("x");
|
expect(results[2].formatters[0].name).toEqual("x");
|
||||||
@ -148,45 +118,45 @@ test("获取翻译内容中定义了重复的插值变量",done=>{
|
|||||||
})
|
})
|
||||||
|
|
||||||
test("替换翻译内容的位置插值变量",done=>{
|
test("替换翻译内容的位置插值变量",done=>{
|
||||||
expect(replaceVars("{}{}{}",1,2,3)).toBe("123");
|
expect(t("{}{}{}",1,2,3)).toBe("123");
|
||||||
expect(replaceVars("{a}{b}{c}",1,2,3)).toBe("123");
|
expect(t("{a}{b}{c}",1,2,3)).toBe("123");
|
||||||
// 定义了一些无效的格式化器,直接忽略
|
// 定义了一些无效的格式化器,直接忽略
|
||||||
expect(replaceVars("{a|xxx}{b|dd}{c|}",1,2,3)).toBe("123");
|
expect(t("{a|xxx}{b|dd}{c|}",1,2,3)).toBe("123");
|
||||||
expect(replaceVars("{a|xxx}{b|dd}{c|}",1,2,3,4,5,6)).toBe("123");
|
expect(t("{a|xxx}{b|dd}{c|}",1,2,3,4,5,6)).toBe("123");
|
||||||
expect(replaceVars("{ a|}{b|dd}{c|}{}",1,2,3)).toBe("123{}");
|
expect(t("{ a|}{b|dd}{c|}{}",1,2,3)).toBe("123{}");
|
||||||
// 中文状态下true和false被转换成中文的"是"和"否"
|
// 中文状态下true和false被转换成中文的"是"和"否"
|
||||||
expect(replaceVars("{}{}{}",1,"2",true)).toBe("12是");
|
expect(t("{}{}{}",1,"2",true)).toBe("12是");
|
||||||
expect(replaceVars("{|double}{}{}",1,"2",true)).toBe("22是");
|
expect(trim("{|double}{}{}",1,"2",true)).toBe("22是");
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("替换翻译内容的命名插值变量",done=>{
|
test("替换翻译内容的命名插值变量",done=>{
|
||||||
expect(replaceVars("{a}{b}{c}",{a:11,b:22,c:33})).toBe("112233");
|
expect(t("{a}{b}{c}",{a:11,b:22,c:33})).toBe("112233");
|
||||||
expect(replaceVars("{a}{b}{c}{a}{b}{c}",{a:1,b:"2",c:3})).toBe("123123");
|
expect(t("{a}{b}{c}{a}{b}{c}",{a:1,b:"2",c:3})).toBe("123123");
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("命名插值变量使用格式化器",done=>{
|
test("命名插值变量使用格式化器",done=>{
|
||||||
// 提供无效的格式化器,直接忽略
|
// 提供无效的格式化器,直接忽略
|
||||||
expect(replaceVars("{a|x}{b|x|y}{c|}",{a:1,b:2,c:3})).toBe("123");
|
expect(t("{a|x}{b|x|y}{c|}",{a:1,b:2,c:3})).toBe("123");
|
||||||
expect(replaceVars("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
expect(t("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
||||||
// 默认的字符串格式化器,不需要定义使用字符串方法
|
// 默认的字符串格式化器,不需要定义使用字符串方法
|
||||||
expect(replaceVars("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
expect(t("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
||||||
// padStart格式化器是字符串的方法,不需要额外定义可以直接使用
|
// padStart格式化器是字符串的方法,不需要额外定义可以直接使用
|
||||||
expect(replaceVars("{a|padStart(10)}",{a:"123"})).toBe(" 123");
|
expect(t("{a|padStart(10)}",{a:"123"})).toBe(" 123");
|
||||||
expect(replaceVars("{a|padStart(10)|trim}",{a:"123"})).toBe("123");
|
expect(t("{a|padStart(10)|trim}",{a:"123"})).toBe("123");
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
test("命名插值变量使用格式化器",done=>{
|
test("命名插值变量使用格式化器",done=>{
|
||||||
// 提供无效的格式化器,直接忽略
|
// 提供无效的格式化器,直接忽略
|
||||||
expect(replaceVars("{a|x}{b|x|y}{c|}",{a:1,b:2,c:3})).toBe("123");
|
expect(t("{a|x}{b|x|y}{c|}",{a:1,b:2,c:3})).toBe("123");
|
||||||
expect(replaceVars("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
expect(t("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
||||||
// 默认的字符串格式化器,不需要定义使用字符串方法
|
// 默认的字符串格式化器,不需要定义使用字符串方法
|
||||||
expect(replaceVars("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
expect(t("{a|x}{b|x|y}{c|double}",{a:1,b:2,c:3})).toBe("126");
|
||||||
expect(replaceVars("{a|padStart(10)}",{a:"123"})).toBe(" 123");
|
expect(t("{a|padStart(10)}",{a:"123"})).toBe(" 123");
|
||||||
expect(replaceVars("{a|padStart(10)|trim}",{a:"123"})).toBe("123");
|
expect(t("{a|padStart(10)|trim}",{a:"123"})).toBe("123");
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -194,11 +164,11 @@ test("命名插值变量使用格式化器",done=>{
|
|||||||
|
|
||||||
test("切换到其他语言时的自动匹配同名格式化器",done=>{
|
test("切换到其他语言时的自动匹配同名格式化器",done=>{
|
||||||
// 默认的字符串类型的格式化器
|
// 默认的字符串类型的格式化器
|
||||||
expect(replaceVars("{a}",{a:true})).toBe("是");
|
expect(t("{a}",{a:true})).toBe("是");
|
||||||
expect(replaceVars("{name|book}是毛泽东思想的重要载体","毛泽东选集")).toBe("《毛泽东选集》是毛泽东思想的重要载体");
|
expect(t("{name|book}是毛泽东思想的重要载体","毛泽东选集")).toBe("《毛泽东选集》是毛泽东思想的重要载体");
|
||||||
changeLanguage("en")
|
changeLanguage("en")
|
||||||
expect(replaceVars("{a}",{a:false})).toBe("False");
|
expect(t("{a}",{a:false})).toBe("False");
|
||||||
expect(replaceVars("{name|book}是毛泽东思想的重要载体","毛泽东选集")).toBe("<毛泽东选集>是毛泽东思想的重要载体");
|
expect(t("{name|book}是毛泽东思想的重要载体","毛泽东选集")).toBe("<毛泽东选集>是毛泽东思想的重要载体");
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user