update
This commit is contained in:
parent
1cf4f313b3
commit
e060827dc1
@ -207,7 +207,6 @@ describe("格式化化配置与参数", () => {
|
||||
})
|
||||
|
||||
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)
|
||||
@ -312,7 +311,17 @@ describe('插值变量格式化器', () => {
|
||||
expect(t("hello {|bookname}","tom")).toBe("hello 《tom》")
|
||||
expect(t("hello {|bookname('#')}","tom")).toBe("hello #tom#")
|
||||
expect(t("hello {|bookname('#','!')}","tom")).toBe("hello #tom!")
|
||||
expect(t("hello {|bookname|bookname|bookname}","tom")).toBe("hello 《《《tom》》》")
|
||||
await scope.change("en")
|
||||
expect(t("hello {|bookname}","tom")).toBe("hello <tom>")
|
||||
})
|
||||
|
||||
test('空值格式化器',async () => {
|
||||
expect(t("hello {|bookname|empty('空')}",undefined)).toBe("hello 《空》")
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('内置格式化器', () => {
|
||||
|
||||
})
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
|
||||
import { FlexFormatter, Formatter } from '../formatter'
|
||||
import { FlexFormatter, IFormatter } from '../formatter'
|
||||
import { toChineseNumber } from "flex-tools/chinese/toChineseNumber"
|
||||
import { toChineseCurrency } from "flex-tools/chinese/toChineseCurrency"
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
*/
|
||||
import { toDate } from '../utils'
|
||||
import { Formatter } from '../formatter';
|
||||
import { IFormatter } from '../formatter';
|
||||
import { formatDateTime } from "flex-tools/misc/formatDateTime"
|
||||
import { relativeTime } from "flex-tools/misc/relativeTime"
|
||||
import { assignObject } from "flex-tools/object/assignObject"
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*/
|
||||
import { toNumber } from "../utils"
|
||||
import { Formatter } from "../formatter"
|
||||
import { IFormatter } from "../formatter"
|
||||
import { toCurrency } from "./currency"
|
||||
import { VoerkaI18nFormatter } from '../types';
|
||||
|
||||
|
@ -16,6 +16,7 @@ import { isFunction } from "flex-tools/typecheck/isFunction"
|
||||
import { isPlainObject } from "flex-tools/typecheck/isPlainObject"
|
||||
import { safeParseJson } from "flex-tools/object/safeParseJson"
|
||||
import { assignObject } from "flex-tools/object/assignObject"
|
||||
import { VoerkaI18nFormatterConfigs } from './types';
|
||||
|
||||
/**
|
||||
使用正则表达式对原始文本内容进行解析匹配后得到的便以处理的数组
|
||||
@ -269,18 +270,23 @@ function parseFormaterParams(strParams: string): any[] {
|
||||
* @param {*} defaultParams 可选默认值
|
||||
* @returns
|
||||
*/
|
||||
export type Formatter = (this: any, value: string, ...args: any[]) => string
|
||||
|
||||
export type VarValueType = string | Error | undefined | null
|
||||
|
||||
export type IFormatter = (this: any, value: VarValueType, args: any[],config:VoerkaI18nFormatterConfigs) => string
|
||||
|
||||
|
||||
export interface FormatterOptions {
|
||||
normalize?: (value: string) => any // 对输入值进行规范化处理,如进行时间格式化时,为了提高更好的兼容性,支持数字时间戳/字符串/Date等,需要对输入值进行处理,如强制类型转换等
|
||||
params?: Record<string, any> | null, // 可选的,声明参数顺序,如果是变参的,则需要传入null
|
||||
configKey?: string // 声明该格式化器在$config中的路径,支持简单的使用.的路径语法
|
||||
}
|
||||
|
||||
export function createFormatter(fn: Formatter, options?: FormatterOptions, defaultParams?: Record<string, any>) {
|
||||
export function createFormatter(fn: IFormatter, options?: FormatterOptions, defaultParams?: Record<string, any>) {
|
||||
let opts = assignObject({
|
||||
normalize: null, // 对输入值进行规范化处理,如进行时间格式化时,为了提高更好的兼容性,支持数字时间戳/字符串/Date等,需要对输入值进行处理,如强制类型转换等
|
||||
params: null, // 可选的,声明参数顺序,如果是变参的,则需要传入null
|
||||
configKey: null // 声明该格式化器在$config中的路径,支持简单的使用.的路径语法
|
||||
normalize: null, // 对输入值进行规范化处理,如进行时间格式化时,为了提高更好的兼容性,支持数字时间戳/字符串/Date等,需要对输入值进行处理,如强制类型转换等
|
||||
params: null, // 可选的,声明参数顺序,如果是变参的,则需要传入null
|
||||
configKey: null // 声明该格式化器在config中的路径,支持简单的使用.的路径语法
|
||||
}, options)
|
||||
|
||||
// 最后一个参数是传入activeFormatterConfig参数
|
||||
@ -289,9 +295,7 @@ export function createFormatter(fn: Formatter, options?: FormatterOptions, defau
|
||||
let finalValue = value
|
||||
// 1. 输入值规范处理,主要是进行类型转换,确保输入的数据类型及相关格式的正确性,提高数据容错性
|
||||
if (isFunction(opts.normalize)) {
|
||||
try {
|
||||
finalValue = opts.normalize(finalValue)
|
||||
} catch { }
|
||||
try {finalValue = opts.normalize(finalValue)} catch { }
|
||||
}
|
||||
// 2. 读取activeFormatterConfig
|
||||
let activeFormatterConfigs = args.length > 0 ? args[args.length - 1] : {}
|
||||
@ -335,11 +339,11 @@ export function createFormatter(fn: Formatter, options?: FormatterOptions, defau
|
||||
* @param {*} options
|
||||
* @param {*} defaultParams
|
||||
*/
|
||||
export const createFlexFormatter = function (fn: Formatter, options: FormatterOptions, defaultParams?: Record<string, any>) {
|
||||
export const createFlexFormatter = function (fn: IFormatter, options: FormatterOptions, defaultParams?: Record<string, any>) {
|
||||
const opts = assignObject({
|
||||
params: {}
|
||||
}, options)
|
||||
const $flexFormatter = Formatter(function (this: any, value: string,args: string[],$config:Record<string,any> ) {
|
||||
const $flexFormatter = Formatter(function (this: any, value: VarValueType,args: string[],$config:Record<string,any> ) {
|
||||
// 2. 从语言配置中读取默认参数
|
||||
let finalParams = (options.params || {}).reduce((r: Record<string, any>, name: string) => {
|
||||
r[name] = $config[name] == undefined ? (defaultParams || {})[name] : $config[name]
|
||||
|
@ -151,6 +151,7 @@ export class VoerkaI18nFormatterRegistry{
|
||||
languages.forEach((lngName:string) => {
|
||||
if(!(lngName in this.#formatters)) this.#formatters[lngName] = {}
|
||||
if(typeof(this.#formatters[lngName])!="function"){
|
||||
if(!this.#formatters[lngName]) this.#formatters[lngName] = {}
|
||||
let lngFormatters = this.#formatters[lngName] as any
|
||||
if (DataTypes.includes(name)) {
|
||||
if(!lngFormatters.$types) lngFormatters.$types = {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { assignObject } from 'flex-tools/object/assignObject';
|
||||
import { VoerkaI18nFormatterConfigs } from '../types';
|
||||
import { toNumber } from "../utils"
|
||||
import { Formatter } from "../formatter"
|
||||
import { IFormatter, VarValueType,Formatter } from "../formatter"
|
||||
|
||||
/**
|
||||
* 字典格式化器
|
||||
@ -12,7 +12,7 @@ import { Formatter } from "../formatter"
|
||||
* @param {...any} args
|
||||
* @returns
|
||||
*/
|
||||
function dict(key:string, values:any) {
|
||||
export function dict(key:string, values:any) {
|
||||
if(key in values){
|
||||
return values[key]
|
||||
}else{
|
||||
@ -39,8 +39,8 @@ function dict(key:string, values:any) {
|
||||
* @paran {String} next 下一步行为,取值true/false,break,skip,默认是break
|
||||
* @param {*} config
|
||||
*/
|
||||
const empty = Formatter(function(value:any,escapeValue:any,next: 'break' | 'ignore',$config:VoerkaI18nFormatterConfigs){
|
||||
let opts = assignObject({escape:"",next:'break',values:[]},$config)
|
||||
export const empty = Formatter(function(value:VarValueType,[escapeValue,next]:[escapeValue:any,next: 'break' | 'ignore'],config:VoerkaI18nFormatterConfigs){
|
||||
let opts = assignObject({escape:"",next:'break',values:[]},config)
|
||||
if(escapeValue!=undefined) opts.escape = escapeValue
|
||||
let emptyValues = [undefined,null]
|
||||
if(Array.isArray(opts.values)) emptyValues.push(...opts.values)
|
||||
@ -72,8 +72,8 @@ const empty = Formatter(function(value:any,escapeValue:any,next: 'break' | 'igno
|
||||
* @param {*} config 格式化器的全局配置参数
|
||||
* @returns
|
||||
*/
|
||||
const error = Formatter(function(value:any,escapeValue:any,next:'break' | 'ignore',$config:VoerkaI18nFormatterConfigs){
|
||||
if(value instanceof Error){
|
||||
export const error = Formatter(function(value:string,escapeValue:any,next:'break' | 'ignore',$config:VoerkaI18nFormatterConfigs){
|
||||
if(typeof(value)=='object' && (value instanceof Error)){
|
||||
try{
|
||||
let opts = assignObject({escape:null,next:'break'},$config)
|
||||
if(escapeValue!=undefined) opts.escape = escapeValue
|
||||
@ -100,8 +100,8 @@ const error = Formatter(function(value:any,escapeValue:any,next:'break' | 'ignor
|
||||
* @param {*} prefix
|
||||
* @returns
|
||||
*/
|
||||
export function prefix(value:any,prefix:string="") {
|
||||
return prefix ? `${prefix}${value}` : value
|
||||
export function prefix(value:string,[prefix]:[prefix:string]) {
|
||||
return prefix ? `${prefix || ''}${value}` : value
|
||||
}
|
||||
/**
|
||||
* 添加后缀
|
||||
@ -109,8 +109,8 @@ export function prefix(value:any,prefix:string="") {
|
||||
* @param {*} suffix
|
||||
* @returns
|
||||
*/
|
||||
export function suffix(value:any,suffix:string="") {
|
||||
return suffix ? `${value}${suffix}` : value
|
||||
export function suffix(value:string,[suffix]:[suffix:string]) {
|
||||
return suffix ? `${value}${suffix || ''}` : value
|
||||
}
|
||||
|
||||
const FILE_SIZE_SECTIONS = [
|
||||
@ -141,7 +141,7 @@ const FILE_SIZE_WHOLE_UNITS = ["Bytes", "Kilobytes", "Megabytes", "Gigabytes", "
|
||||
* @param {*} brief 是否采用简称单位
|
||||
* @param {*} options
|
||||
*/
|
||||
export const filesize= Formatter((value:any,unit:string,brief:boolean=true,$config:VoerkaI18nFormatterConfigs)=>{
|
||||
export const filesize= Formatter((value:string,unit:string,brief:boolean=true,$config:VoerkaI18nFormatterConfigs)=>{
|
||||
let v = toNumber(value)
|
||||
let unitIndex
|
||||
if(unit==undefined || unit=="auto"){
|
||||
@ -163,12 +163,4 @@ const FILE_SIZE_WHOLE_UNITS = ["Bytes", "Kilobytes", "Megabytes", "Gigabytes", "
|
||||
configKey:"fileSize"
|
||||
})
|
||||
|
||||
|
||||
export default {
|
||||
dict,
|
||||
empty,
|
||||
error,
|
||||
prefix,
|
||||
suffix,
|
||||
filesize
|
||||
}
|
||||
|
@ -83,22 +83,6 @@ export function translate(this:VoerkaI18nScope,message:string,...args:any[]):str
|
||||
})
|
||||
}
|
||||
|
||||
// 3. 取得翻译文本模板字符串
|
||||
// if(activeLanguage === scope.defaultLanguage){
|
||||
// // 2.1 从默认语言中取得翻译文本模板字符串
|
||||
// // 如果当前语言就是默认语言,不需要查询加载,只需要做插值变换即可
|
||||
// // 当源文件运用了babel插件后会将原始文本内容转换为msgId
|
||||
// // 如果是msgId则从scope.default中读取,scope.default=默认语言包={<id>:<message>}
|
||||
// if(isMessageId(result)){
|
||||
// result = (scope.default as any)[result] || message
|
||||
// }
|
||||
// }else{
|
||||
// // 2.2 从当前语言包中取得翻译文本模板字符串
|
||||
// // 如果没有启用babel插件将源文本转换为msgId,需要先将文本内容转换为msgId
|
||||
// let msgId = isMessageId(result) ? result : scope.idMap[result]
|
||||
// result = (scope.current as any)[msgId] || result
|
||||
// }
|
||||
|
||||
if(isMessageId(message)){
|
||||
const msgId = scope.idMap[message]
|
||||
result = (scope.current as any)[msgId] || message
|
||||
@ -119,11 +103,7 @@ export function translate(this:VoerkaI18nScope,message:string,...args:any[]):str
|
||||
}
|
||||
}
|
||||
// 进行插值处理
|
||||
if(vars.length==0){
|
||||
return result as string
|
||||
}else{
|
||||
return replaceInterpolatedVars.call(scope,result as string,...vars)
|
||||
}
|
||||
return replaceInterpolatedVars.call(scope,result as string,...vars)
|
||||
}catch(e){
|
||||
return result as any // 出错则返回原始文本
|
||||
}
|
||||
|
@ -75,4 +75,14 @@ export function toBoolean(value:any){
|
||||
|
||||
export function randomId():string{
|
||||
return Date.now().toString() + parseInt(String(Math.random() * 1000))
|
||||
}
|
||||
}
|
||||
// const varRegexp = /\{([^\}]*)\}/gm
|
||||
// /**
|
||||
// * 返回字符串中变量的数量
|
||||
// * @param str
|
||||
// */
|
||||
// export function getVarCount(str:string){
|
||||
// const matches = str.match(varRegexp)
|
||||
// return matches ? matches.length : 0
|
||||
// }
|
||||
|
Loading…
x
Reference in New Issue
Block a user