642 lines
21 KiB
Plaintext
642 lines
21 KiB
Plaintext
import BaseFormatter from './format'
|
||
import { warn, error, isString, getAllKeys } from './util'
|
||
import { Composer, Interpolate, Link, WarnDefault, LinkedModify, PluralizationRule, StringOrNull, NumberOrNull, Availabilities } from './types'
|
||
|
||
// #ifndef APP
|
||
type Interceptor = any
|
||
// #endif
|
||
export class AvailabilitiesImpl implements Availabilities {
|
||
dateTimeFormat : boolean = false
|
||
numberFormat : boolean = false
|
||
constructor() {
|
||
// #ifndef APP
|
||
const intlDefined = typeof Intl !== 'undefined'
|
||
this.dateTimeFormat = intlDefined && typeof Intl.DateTimeFormat !== 'undefined'
|
||
this.numberFormat = intlDefined && typeof Intl.NumberFormat !== 'undefined'
|
||
// #endif
|
||
}
|
||
}
|
||
|
||
const htmlTagMatcher = /<\/?[\w\s="/.':;#-\/]+>/;
|
||
const linkKeyMatcher = /(?:@(?:\.[a-zA-Z0-9_-]+)?:)(?:[\w\-_|./]+|\([\w\-_:|./]+\)|(?:\{[^}]+?\}))/g;
|
||
const linkKeyPrefixMatcher = /^@(?:\.([a-zA-Z]+))?:/;
|
||
const bracketsMatcher = /[()\{\}\']/g;
|
||
const defaultModifiers : Map<string, LinkedModify> = new Map([
|
||
['upper', (str : string) : string => str.toLocaleUpperCase()],
|
||
['lower', (str : string) : string => str.toLocaleLowerCase()],
|
||
['capitalize', (str : string) : string => `${str.charAt(0).toLocaleUpperCase()}${str.substring(1)}`]
|
||
])
|
||
|
||
const DEFAULT_LOCALE = "en-US"
|
||
const defaultFormatter = new BaseFormatter()
|
||
const availabilities = new AvailabilitiesImpl()
|
||
|
||
function setTabBarItems(tabbar : string[] | null) {
|
||
if (tabbar == null) return
|
||
const pages = getCurrentPages()
|
||
const page = pages.length > 0 ? pages[pages.length - 1]: null;
|
||
// @ts-ignore
|
||
// #ifndef APP-ANDROID
|
||
const isTabBar = page != null //page.$vm.$basePage.openType == 'switchTab'// page != null && page.$page.meta.isTabBar
|
||
// #endif
|
||
// #ifdef APP-ANDROID
|
||
const isTabBar = page != null
|
||
// #endif
|
||
if(!isTabBar) return
|
||
tabbar.forEach((text, index) => {
|
||
uni.setTabBarItem({
|
||
text,
|
||
index,
|
||
// success() {},
|
||
fail(err) {
|
||
warn(err.errMsg)
|
||
}
|
||
} as SetTabBarItemOptions)
|
||
})
|
||
}
|
||
|
||
function getLocaleMap(locale : string, key : string, options : UTSJSONObject, root : Composer | null = null) : Map<string, UTSJSONObject> {
|
||
//'messages'
|
||
const __messages = UTSJSONObject.assign({}, options.getJSON(key) ?? {})
|
||
// #ifdef APP
|
||
let map = new Map<string, UTSJSONObject>()
|
||
__messages.toMap().forEach((value, key) => {
|
||
if (value instanceof UTSJSONObject) {
|
||
map.set(key, value)
|
||
}
|
||
})
|
||
// #endif
|
||
|
||
// #ifndef APP
|
||
let map = __messages.toMap()
|
||
// #endif
|
||
|
||
if (map.size == 0 && root != null) {
|
||
// map = root.messages.value
|
||
if (!map.has(locale)) {
|
||
map.set(locale, {})
|
||
}
|
||
}
|
||
return map
|
||
}
|
||
function getLocaleTabbarMap(locale : string, key : string, options : UTSJSONObject) : Map<string, string[]> {
|
||
const __messages = options.getJSON(key) ?? {}
|
||
let map = new Map<string, string[]>()
|
||
__messages.toMap().forEach((tabbar, key) => {
|
||
if (Array.isArray(tabbar)) {
|
||
map.set(key, tabbar as string[]);
|
||
if (key == locale) {
|
||
setTimeout(()=>{
|
||
setTabBarItems(tabbar as string[])
|
||
},500)
|
||
}
|
||
}
|
||
})
|
||
|
||
return map
|
||
}
|
||
function getModifiers(options : UTSJSONObject) : Map<string, LinkedModify> {
|
||
const __modifiers = (options.getJSON('modifiers') ?? {}).toMap();
|
||
const _modifiers = new Map<string, LinkedModify>()
|
||
__modifiers.forEach((value, key) => {
|
||
if (typeof value == 'function') {
|
||
try {
|
||
_modifiers.set(key, value as LinkedModify)
|
||
} catch (e) {
|
||
error(35, '自定义修饰器函数必须是类型:(str: string) => string')
|
||
}
|
||
}
|
||
})
|
||
return _modifiers
|
||
}
|
||
function getPluralizationRules(options : UTSJSONObject) : Map<string, PluralizationRule> {
|
||
const __pluralizationRules = (options.getJSON('pluralizationRules') ?? {}).toMap()
|
||
const _pluralizationRules = new Map<string, PluralizationRule>()
|
||
__pluralizationRules.forEach((value, key) => {
|
||
if (typeof value == 'function') {
|
||
try {
|
||
_pluralizationRules.set(key, value as PluralizationRule)
|
||
} catch (e) {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
error(35, '自定义复数化规则函数必须是类型: ( choice: number, choicesLength: number) => number')
|
||
}
|
||
}
|
||
}
|
||
})
|
||
return _pluralizationRules
|
||
}
|
||
function getFormatter(options : UTSJSONObject) : BaseFormatter {
|
||
const __formatter = options.get('formatter')
|
||
return __formatter != null && __formatter instanceof BaseFormatter ? __formatter : defaultFormatter;
|
||
}
|
||
|
||
let composerID = 0;
|
||
|
||
|
||
|
||
/**
|
||
* 创建一个Composer实例,用于处理国际化信息。
|
||
* @param {UTSJSONObject} [options={}] - 配置对象,包含语言环境、格式化器等设置。
|
||
* @param {Composer | null} [__root=null] - 根Composer实例,用于继承语言环境等信息。
|
||
* @returns {Composer} 返回一个新的Composer实例。
|
||
*/
|
||
export function createComposer(options : UTSJSONObject = {}, __root : Composer | null = null) : Composer {
|
||
|
||
let _interpolate : Interpolate | null = null;
|
||
let _link : Link | null;
|
||
let _warnDefault : WarnDefault | null = null;
|
||
|
||
const _inheritLocale = options.getBoolean('inheritLocale') ?? true;
|
||
const _formatter = getFormatter(options);
|
||
const _modifiers = getModifiers(options)
|
||
const _pluralizationRules = getPluralizationRules(options)
|
||
|
||
// const flatJson = options.getBoolean('flatJson') ?? false;
|
||
const useRoot = __root != null && _inheritLocale
|
||
|
||
const __locale = ref<string>(
|
||
useRoot
|
||
? __root!.locale.value
|
||
: options.getString('locale') ?? DEFAULT_LOCALE
|
||
)
|
||
const _fallbackLocale = ref<any | null>(
|
||
useRoot
|
||
? __root!.fallbackLocale.value
|
||
: options.get('fallbackLocale')
|
||
)
|
||
|
||
|
||
|
||
|
||
const _messages = ref<Map<string, UTSJSONObject>>(getLocaleMap(__locale.value, 'messages', options, __root))
|
||
const _numberFormats = ref<Map<string, UTSJSONObject>>(getLocaleMap(__locale.value, 'numberFormats', options, __root))
|
||
const _datetimeFormats = ref<Map<string, UTSJSONObject>>(getLocaleMap(__locale.value, 'datetimeFormats', options, __root))
|
||
const _tabBars = ref<Map<string, string[]>>(getLocaleTabbarMap(__locale.value, 'tabBars', options))
|
||
|
||
const _locale = computed<string>({
|
||
set(val : string) {
|
||
__locale.value = val;
|
||
// 设置缓存 只有全局才会缓存
|
||
if (__root == null) {
|
||
uni.setStorageSync('uVueI18nLocale', val)
|
||
}
|
||
// 设置tabbar
|
||
setTabBarItems(_tabBars.value.get(val))
|
||
},
|
||
get() : string {
|
||
return __locale.value
|
||
}
|
||
} as WritableComputedOptions<string>)
|
||
|
||
const fallbackLocale = computed<any>({
|
||
set(val : any) {
|
||
_fallbackLocale.value = val
|
||
},
|
||
get() : any {
|
||
return _fallbackLocale.value ?? false
|
||
}
|
||
} as WritableComputedOptions<any>)
|
||
let availableLocales : string[] = getAllKeys(_messages.value).sort()
|
||
|
||
/**
|
||
* 处理字符串中的链接并返回翻译后的字符串。
|
||
* @param {string} str - 要处理的字符串。
|
||
* @param {StringOrNull} [locale=null] - 指定语言环境。
|
||
* @param {any} values - 用于插值的变量。
|
||
* @param {string[]} visitedLinkStack - 已访问过的链接堆栈。
|
||
* @param {string} interpolateMode - 插值模式。
|
||
* @returns {StringOrNull} 返回处理后的字符串或null。
|
||
*/
|
||
_link = (str : string, locale : StringOrNull, values : any, visitedLinkStack : string[], interpolateMode : string) : StringOrNull => {
|
||
const matches = str.match(linkKeyMatcher)
|
||
let ret : string = str
|
||
if (matches == null) return str
|
||
for (let i = 0; i < matches.length; i++) {
|
||
const link = matches[i]
|
||
const linkKeyPrefixMatches = link!.match(linkKeyPrefixMatcher)
|
||
if (linkKeyPrefixMatches == null) continue;
|
||
const [linkPrefix, formatterName] = linkKeyPrefixMatches
|
||
|
||
// 去掉字符串前面的 @:、@.case: 、括号及大括号
|
||
const linkPlaceholder : string = link.replace(linkPrefix!, '').replace(bracketsMatcher, '')
|
||
if (visitedLinkStack.includes(linkPlaceholder)) {
|
||
warn(`发现循环引用。"${link}"已经在link"已经在${visitedLinkStack.reverse().join(' <- ')}链中访问过`)
|
||
return ret
|
||
}
|
||
if (_interpolate == null || _warnDefault == null) {
|
||
return ret
|
||
}
|
||
visitedLinkStack.push(linkPlaceholder)
|
||
let translated = _interpolate!(linkPlaceholder, locale, values, visitedLinkStack, interpolateMode)
|
||
|
||
translated = _warnDefault!(linkPlaceholder, translated, values, interpolateMode)
|
||
|
||
// 如果有自定义_modifiers 否则使用默认defaultModifiers
|
||
if (_modifiers.size > 0 && formatterName != null && _modifiers.has(formatterName)) {
|
||
} else if (translated != null && formatterName != null && defaultModifiers.has(formatterName)) {
|
||
const modifier = defaultModifiers.get(formatterName) as LinkedModify
|
||
translated = modifier(translated)
|
||
}
|
||
visitedLinkStack.pop()
|
||
|
||
// 将链接替换为已翻译的
|
||
ret = translated == null ? ret : ret.replace(link, translated)
|
||
}
|
||
|
||
return ret
|
||
}
|
||
/**
|
||
* 获取指定语言字符。
|
||
* @param {string} key - 要翻译的键。
|
||
* @param {StringOrNull} [locale=null] - 指定语言环境。
|
||
* @param {any} values - 用于插值的变量。
|
||
* @param {string[]} visitedLinkStack - 已访问过的链接堆栈。
|
||
* @param {string} interpolateMode - 插值模式。
|
||
* @returns {StringOrNull} 返回翻译后的字符串或null。
|
||
*/
|
||
_interpolate = (key : string, locale : StringOrNull, values : any, visitedLinkStack : string[], interpolateMode : string) : StringOrNull => {
|
||
const ___locale = locale ?? _locale.value
|
||
let ret = _messages.value.get(___locale)?.getString(key)
|
||
// console.log(_messages)
|
||
// console.log(key,ret)
|
||
if (fallbackLocale.value != false && ret == null) {
|
||
if (typeof fallbackLocale.value == 'string' && ___locale != fallbackLocale.value) {
|
||
ret = _messages.value.get(fallbackLocale.value as string)?.getString(key) ?? ret
|
||
} else if (Array.isArray(fallbackLocale.value)) {
|
||
const arr = (fallbackLocale.value as string[])
|
||
for (let i = 0; i < arr.length; i++) {
|
||
const _ret = _messages.value.get(arr[i])?.getString(key)
|
||
if (_ret != null) {
|
||
ret = _ret
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 检查翻译后的字符串中是否存在链接
|
||
if (typeof ret == 'string' && (ret!.indexOf('@:') >= 0 || ret!.indexOf('@.') >= 0)) {
|
||
// @ts-ignore
|
||
ret = _link(ret!, locale, values, visitedLinkStack, interpolateMode)
|
||
}
|
||
return ret
|
||
}
|
||
/**
|
||
* 获取指定语言字符并渲染。
|
||
* @param {string} message - 要翻译的字符串。
|
||
* @param {any} values - 用于插值的变量。
|
||
* @param {string} interpolateMode - 插值模式。
|
||
* @returns {string} 返回渲染后的字符串。
|
||
*/
|
||
const _render = (message : string, values : any, interpolateMode : string) : string => {
|
||
const ret = _formatter.interpolate(message, values)
|
||
return interpolateMode == 'string' ? `${ret.join('')}` : JSON.stringify(ret)
|
||
}
|
||
/**
|
||
* 在无法翻译的情况下发出警告并提供默认值。
|
||
* @param {string} key - 要翻译的键。
|
||
* @param {StringOrNull} message - 翻译后的字符串或null。
|
||
* @param {any} values - 用于插值的变量。
|
||
* @param {string} interpolateMode - 插值模式。
|
||
* @returns {StringOrNull} 返回警告信息或默认值。
|
||
*/
|
||
_warnDefault = (key : string, message : StringOrNull, values : any, interpolateMode : string) : StringOrNull => {
|
||
if (message == null) {
|
||
warn(`无法翻译键路径 '${key}'. ` + '使用键路径的值作为默认值.')
|
||
}
|
||
if (message == null) return null
|
||
if (key == message) return key
|
||
return _render(message, values, interpolateMode)
|
||
}
|
||
/**
|
||
* 获取复数形式的选择。
|
||
* @param {string} message - 包含复数选择的字符串。
|
||
* @param {number | null} [choice=null] - 复数形式的选择。
|
||
* @param {string | null} [locale=null] - 指定语言环境。
|
||
* @returns {string} 返回选择后的字符串。
|
||
*/
|
||
const fetchChoice = (message : string, choice ?: number, locale ?: string) : string => {
|
||
if (message == '') return message;
|
||
const choices : Array<string> = message.split('|');
|
||
|
||
// 默认 vue-i18n(旧)getChoiceIndex实现 - 兼容英文
|
||
const defaultImpl = (_choice : NumberOrNull, _choicesLength : number) : number => {
|
||
_choice = Math.abs(_choice ?? 1)
|
||
if (_choicesLength == 2) {
|
||
return _choice != 0
|
||
? _choice > 1
|
||
? 1
|
||
: 0
|
||
: 1
|
||
}
|
||
return _choice != 0 ? Math.min(_choice, 2) : 0
|
||
}
|
||
let index : number;
|
||
if (_pluralizationRules.has(locale ?? _locale.value)) {
|
||
index = _pluralizationRules.get(locale ?? _locale.value)!(choice ?? 1, choices.length)
|
||
} else {
|
||
index = defaultImpl(choice, choices.length)
|
||
}
|
||
|
||
if (choices[index] == '') return message
|
||
return choices[index].trim()
|
||
}
|
||
/**
|
||
* 翻译指定的键。
|
||
* @param {string} key - 要翻译的键。
|
||
* @param {any} [values=null] - 用于插值的变量。
|
||
* @param {string | null} [locale=null] - 指定语言环境。
|
||
* @returns {string} 返回翻译后的字符串。
|
||
*/
|
||
const t = (key : string, values ?: any, locale ?: string) : string => {
|
||
const parsedArgs = values ?? {}
|
||
// #ifndef APP
|
||
if (_warnDefault == null || _interpolate == null) return ''
|
||
// #endif
|
||
const msg = _warnDefault(
|
||
key,
|
||
_interpolate(
|
||
key,
|
||
locale,
|
||
parsedArgs,
|
||
[key],
|
||
'string'),
|
||
parsedArgs,
|
||
'string'
|
||
)
|
||
return msg ?? ''
|
||
}
|
||
|
||
/**
|
||
* 翻译指定的键并获取复数形式的选择。
|
||
* @param {string} key - 要翻译的键。
|
||
* @param {number | null} [choice=null] - 复数形式的选择。
|
||
* @param {any} [values=null] - 用于插值的变量。
|
||
* @param {string | null} [locale=null] - 指定语言环境。
|
||
* @returns {string} 返回翻译后的复数形式选择字符串。
|
||
*/
|
||
const tc = (key : string, choice ?: number, values ?: any, locale ?: string) : string => {
|
||
// 预定义的count和n参数
|
||
const _obj = { 'count': choice, 'n': choice }
|
||
const predefined = values == null
|
||
? _obj
|
||
: values instanceof UTSJSONObject
|
||
? UTSJSONObject.assign(_obj, values as UTSJSONObject)
|
||
: values;
|
||
|
||
return fetchChoice(t(key, predefined, locale), choice, locale)
|
||
}
|
||
/**
|
||
* 格式化日期。
|
||
* @param {any} date - 要格式化的日期。
|
||
* @param {StringOrNull} [key=null] - 日期格式化的键。
|
||
* @param {StringOrNull} [locale=null] - 指定语言环境。
|
||
* @param {UTSJSONObject | null} [options=null] - 日期格式化的选项。
|
||
* @returns {string} 返回格式化后的日期字符串。
|
||
*/
|
||
const d = (date : any, key : StringOrNull, locale : StringOrNull, options : UTSJSONObject | null) : string => {
|
||
if (!availabilities.dateTimeFormat) {
|
||
warn('无法格式化日期值,因为不支持 Intl.DateTimeFormat. ' + `key: ${key}, locale: ${locale}, options: ${options}`)
|
||
return `${date}`
|
||
}
|
||
|
||
// #ifndef APP
|
||
const __locale = locale ?? _locale.value
|
||
if (key == null) {
|
||
// @ts-ignore
|
||
const dtf = options == null ? new Intl.DateTimeFormat(__locale) : new Intl.DateTimeFormat(__locale, options)
|
||
return dtf.format(date)
|
||
}
|
||
const formats = _datetimeFormats.value!.get(__locale)
|
||
let formatter;
|
||
if (formats == null || formats!.getJSON(key) == null) {
|
||
warn(`回退到根号下的日期时间本地化:key '${key}'。`)
|
||
return `${date}`
|
||
}
|
||
const format = formats!.getJSON(key) ?? {}
|
||
if (options != null) {
|
||
// @ts-ignore
|
||
formatter = new Intl.DateTimeFormat(__locale, Object.assign({}, format, options))
|
||
} else {
|
||
// @ts-ignore
|
||
formatter = new Intl.DateTimeFormat(__locale, format)
|
||
}
|
||
return formatter.format(date)
|
||
// #endif
|
||
return `${date}`
|
||
}
|
||
/**
|
||
* 格式化数字。
|
||
* @param {number} number - 要格式化的数字。
|
||
* @param {StringOrNull} [key=null] - 数字格式化的键。
|
||
* @param {StringOrNull} [locale=null] - 指定语言环境。
|
||
* @param {UTSJSONObject | null} [options=null] - 数字格式化的选项。
|
||
* @returns {string} 返回格式化后的数字字符串。
|
||
*/
|
||
const n = (number : number, key : StringOrNull, locale : StringOrNull, options : UTSJSONObject | null) : string => {
|
||
if (!availabilities.numberFormat) {
|
||
warn('无法格式化数字值,因为不支持 Intl.NumberFormat. ' + `key: ${key}, locale: ${locale}, options: ${options}`)
|
||
return number.toString()
|
||
}
|
||
|
||
// #ifndef APP
|
||
const __locale = locale ?? _locale.value
|
||
if (key == null) {
|
||
// @ts-ignore
|
||
const nf = options == null ? new Intl.NumberFormat(__locale) : new Intl.NumberFormat(locale, options)
|
||
return nf.format(number)
|
||
}
|
||
const formats = _numberFormats.value!.get(__locale)
|
||
let formatter;
|
||
if (formats == null || formats!.getJSON(key) == null) {
|
||
warn(`回退到根号下的数字本地化:key '${key}'`)
|
||
return number.toString()
|
||
}
|
||
const format = formats!.getJSON(key)
|
||
if (options != null) {
|
||
// @ts-ignore
|
||
formatter = new Intl.NumberFormat(__locale, Object.assign({}, format, options))
|
||
} else {
|
||
// @ts-ignore
|
||
formatter = new Intl.NumberFormat(__locale, format)
|
||
}
|
||
if (formatter) {
|
||
return formatter.format(number)
|
||
}
|
||
// #endif
|
||
return number.toString()
|
||
}
|
||
/**
|
||
* 设置语言环境的locale信息。
|
||
* @param {string} locale - 语言。
|
||
* @param {UTSJSONObject} message - locale信息。
|
||
*/
|
||
const setLocaleMessage = (locale : string, message : UTSJSONObject) => {
|
||
const map = new Map<string, UTSJSONObject>();
|
||
_messages.value.forEach((value, key) => {
|
||
map.set(key, value)
|
||
})
|
||
map.set(locale, message)
|
||
_messages.value = map
|
||
availableLocales = getAllKeys(map).sort()
|
||
}
|
||
/**
|
||
* 获取语言环境的locale信息。
|
||
* @param {string} locale - 语言。
|
||
* @returns {UTSJSONObject} - locale信息。
|
||
*/
|
||
const getLocaleMessage = (locale : string) : UTSJSONObject => {
|
||
return _messages.value.get(locale) ?? {}
|
||
}
|
||
/**
|
||
* 将语言环境信息locale合并到已注册的语言环境信息中。
|
||
* @param {string} locale - 语言。
|
||
* @param {UTSJSONObject} message - locale信息。
|
||
*/
|
||
const mergeLocaleMessage = (locale : string, message : UTSJSONObject) => {
|
||
const map = new Map<string, UTSJSONObject>();
|
||
_messages.value.forEach((value, key) => {
|
||
if (key == locale) {
|
||
map.set(key, UTSJSONObject.assign({}, value, message))
|
||
} else {
|
||
map.set(key, value)
|
||
}
|
||
})
|
||
_messages.value = map
|
||
availableLocales = getAllKeys(map).sort()
|
||
}
|
||
/**
|
||
* 设置日期时间格式。
|
||
* @param {string} locale - 语言。
|
||
* @param {UTSJSONObject} format - 日期时间格式。
|
||
*/
|
||
const setDateTimeFormat = (locale : string, format : UTSJSONObject) => {
|
||
const map = new Map<string, UTSJSONObject>();
|
||
_datetimeFormats.value.forEach((value, key) => {
|
||
map.set(key, value)
|
||
})
|
||
map.set(locale, format)
|
||
_datetimeFormats.value = map
|
||
}
|
||
/**
|
||
* 获取日期时间格式。
|
||
* @param {string} locale - 语言。
|
||
* @returns {UTSJSONObject} - 日期时间格式。
|
||
*/
|
||
const getDateTimeFormat = (locale : string) : UTSJSONObject => {
|
||
return _datetimeFormats.value.get(locale) ?? {}
|
||
}
|
||
|
||
/**
|
||
* 合并日期时间格式到已注册的日期时间格式中。
|
||
* @param {string} locale - 语言。
|
||
* @param {UTSJSONObject} format - 日期时间格式。
|
||
*/
|
||
const mergeDateTimeFormat = (locale : string, format : UTSJSONObject) => {
|
||
const map = new Map<string, UTSJSONObject>();
|
||
_datetimeFormats.value.forEach((value, key) => {
|
||
if (key == locale) {
|
||
map.set(key, UTSJSONObject.assign({}, value, format))
|
||
} else {
|
||
map.set(key, value)
|
||
}
|
||
})
|
||
_datetimeFormats.value = map
|
||
}
|
||
|
||
/**
|
||
* 设置数字格式。
|
||
* @param {string} locale - 语言。
|
||
* @param {UTSJSONObject} format - 数字格式。
|
||
*/
|
||
const setNumberFormat = (locale : string, format : UTSJSONObject) => {
|
||
const map = new Map<string, UTSJSONObject>();
|
||
_numberFormats.value.forEach((value, key) => {
|
||
map.set(key, value)
|
||
})
|
||
map.set(locale, format)
|
||
_numberFormats.value = map
|
||
}
|
||
/**
|
||
* 获取数字格式。
|
||
* @param {string} locale - 语言。
|
||
* @returns {UTSJSONObject} - 数字格式。
|
||
*/
|
||
const getNumberFormat = (locale : string) : UTSJSONObject => {
|
||
return _numberFormats.value.get(locale) ?? {}
|
||
}
|
||
|
||
/**
|
||
* 合并数字格式到已注册的数字格式中。
|
||
* @param {string} locale - 语言。
|
||
* @param {UTSJSONObject} format - 数字格式。
|
||
*/
|
||
const mergeNumberFormat = (locale : string, format : UTSJSONObject) => {
|
||
const map = new Map<string, UTSJSONObject>();
|
||
_numberFormats.value.forEach((value, key) => {
|
||
if (key == locale) {
|
||
map.set(key, UTSJSONObject.assign({}, value, format))
|
||
} else {
|
||
map.set(key, value)
|
||
}
|
||
})
|
||
_numberFormats.value = map
|
||
}
|
||
/**
|
||
* 设置TabBar。
|
||
* @param {string} locale - 语言。
|
||
* @param {string[]} tabbar - TabBar项目。
|
||
*/
|
||
const setTabBar = (locale : string, tabbar : string[]) => {
|
||
const map = new Map<string, string[]>();
|
||
_tabBars.value.forEach((value, key) => {
|
||
map.set(key, value)
|
||
})
|
||
map.set(locale, tabbar)
|
||
_tabBars.value = map
|
||
}
|
||
/**
|
||
* 获取TabBar。
|
||
* @param {string} locale - 语言。
|
||
* @returns {string[]} - TabBar项目。
|
||
*/
|
||
const getTabBar = (locale : string) : string[] => {
|
||
return _tabBars.value.get(locale) ?? []
|
||
}
|
||
|
||
composerID++;
|
||
const interceptor = {
|
||
complete: (_ : NavigateToComplete) => {
|
||
setTimeout(()=>{
|
||
setTabBarItems(_tabBars.value.get(_locale.value))
|
||
},50)
|
||
}
|
||
} as Interceptor
|
||
if(__root == null) {
|
||
uni.addInterceptor('switchTab', interceptor);
|
||
}
|
||
const composer : Composer = {
|
||
id: composerID,
|
||
locale: _locale,
|
||
fallbackLocale,
|
||
messages: _messages,
|
||
setLocaleMessage,
|
||
getLocaleMessage,
|
||
mergeLocaleMessage,
|
||
setDateTimeFormat,
|
||
getDateTimeFormat,
|
||
mergeDateTimeFormat,
|
||
setNumberFormat,
|
||
getNumberFormat,
|
||
mergeNumberFormat,
|
||
setTabBar,
|
||
getTabBar,
|
||
t,
|
||
tc,
|
||
d,
|
||
n,
|
||
availableLocales,
|
||
availabilities
|
||
}
|
||
|
||
return composer
|
||
} |