mirror of https://github.com/layui/layui
refactor(i18n): laydate 国际化方案迁移至 i18n.$t (#2745)
parent
e2ea3ee8de
commit
d21eabd680
18
src/layui.js
18
src/layui.js
|
@ -55,12 +55,25 @@
|
|||
// 异常提示
|
||||
var error = function(msg, type) {
|
||||
type = type || 'log';
|
||||
msg = 'Layui message: ' + msg;
|
||||
msg = '[Layui warn]: ' + msg;
|
||||
|
||||
if (window.console) {
|
||||
console[type] ? console[type](msg) : console.log(msg);
|
||||
}
|
||||
};
|
||||
var warned = Object.create(null);
|
||||
|
||||
var errorOnce = function (msg, type) {
|
||||
if(warned._size && warned._size > 100){
|
||||
warned = Object.create(null);
|
||||
warned._size = 0;
|
||||
}
|
||||
if (!warned[msg]) {
|
||||
warned[msg] = true;
|
||||
warned._size = (warned._size || 0) + 1;
|
||||
error(msg, type)
|
||||
}
|
||||
}
|
||||
|
||||
// 内置模块
|
||||
var builtinModules = config.builtin = {
|
||||
|
@ -715,7 +728,8 @@
|
|||
// 提示
|
||||
Class.prototype.hint = function() {
|
||||
return {
|
||||
error: error
|
||||
error: error,
|
||||
errorOnce: errorOnce
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -262,27 +262,46 @@ layui.define('lay', function(exports) {
|
|||
return value
|
||||
}
|
||||
|
||||
var resolveValue = memoize(function(path, obj, defaultValue){
|
||||
var pathParts = path.split(':');
|
||||
var locale = pathParts[0];
|
||||
|
||||
path = pathParts[1];
|
||||
|
||||
var value = get(obj, path, defaultValue);
|
||||
|
||||
if (layui.cache.debug) {
|
||||
var isFallback = defaultValue === value || value === path;
|
||||
var isNotFound = !value || isFallback;
|
||||
if (isNotFound) {
|
||||
hint.errorOnce("Not found '" + path + "' key in '" + locale + "' locale messages.", 'warn');
|
||||
}
|
||||
if (isFallback) {
|
||||
hint.errorOnce("Fallback to default message for key: '" + path + "'", 'warn');
|
||||
}
|
||||
}
|
||||
|
||||
return value || path;
|
||||
});
|
||||
|
||||
var i18n = {
|
||||
config: config,
|
||||
set: function(options) {
|
||||
lay.extend(config, options);
|
||||
getCachedValueForKeyPath.cleanup();
|
||||
resolveValue.cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
var getCachedValueForKeyPath = memoize(function(key, obj){
|
||||
return get(obj, key, key);
|
||||
});
|
||||
|
||||
/**
|
||||
* 根据给定的键从国际化消息中获取翻译后的内容
|
||||
* 未文档化的私有方法,仅限内部使用
|
||||
*
|
||||
* @internal
|
||||
* @param {string} key 要翻译的键
|
||||
* @param {any[]} [args] 可选的占位符替换参数:
|
||||
* @param {string} keypath 要翻译的键路径
|
||||
* @param {Record<string, any> | any[]} [parameters] 可选的占位符替换参数:
|
||||
* - 对象形式:用于替换 `{key}` 形式的占位符;
|
||||
* - 数组形式:用于替换 `{0}`, `{1}` 等占位符;
|
||||
* @param {{locale: string, default: string}} [options] 翻译选项
|
||||
* @returns {string} 翻译后的文本
|
||||
*
|
||||
* @example 使用对象替换命名占位符
|
||||
|
@ -297,27 +316,24 @@ layui.define('lay', function(exports) {
|
|||
* }
|
||||
* i18n.$t('message.hello', ['Hello'])
|
||||
*/
|
||||
i18n.translation = function(key) {
|
||||
var options = config;
|
||||
var args = arguments;
|
||||
var i18nMessages = options.messages[options.locale];
|
||||
i18n.translation = function(keypath, parameters, options) {
|
||||
var locale = (options && options.locale) || config.locale;
|
||||
var i18nMessages = config.messages[locale];
|
||||
var namespace = locale + ':';
|
||||
var fallbackMessage = options && options.default;
|
||||
|
||||
if (!i18nMessages) {
|
||||
hint.error('Locale "' + options.locale + '" not found. Please add i18n messages for this locale first.', 'warn');
|
||||
return key;
|
||||
hint.errorOnce("Locale '" + locale + "' not found. Please add i18n messages for this locale first.", 'error');
|
||||
}
|
||||
|
||||
var result = getCachedValueForKeyPath(key, i18nMessages);
|
||||
|
||||
var result = resolveValue(namespace + keypath, i18nMessages, fallbackMessage);
|
||||
|
||||
// 替换占位符
|
||||
if (typeof result === 'string' && args.length > 1) {
|
||||
var opts = args[1];
|
||||
if (typeof result === 'string' && parameters) {
|
||||
// 第二个参数为对象或数组,替换占位符 {key} 或 {0}, {1}...
|
||||
if (opts !== null && typeof opts === 'object') {
|
||||
result = result.replace(OBJECT_REPLACE_REGEX, function(match, key) {
|
||||
return opts[key] !== undefined ? opts[key] : match;
|
||||
});
|
||||
}
|
||||
result = result.replace(OBJECT_REPLACE_REGEX, function(match, key) {
|
||||
return parameters[key] !== undefined ? parameters[key] : match;
|
||||
});
|
||||
}
|
||||
|
||||
return escape(result);
|
||||
|
|
|
@ -111,6 +111,9 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
// 初始化属性
|
||||
options = lay.extend(that.config, lay.options(elem[0])); // 继承节点上的属性
|
||||
|
||||
// 更新 i18n 消息对象
|
||||
that.i18nMessages = that.getI18nMessages();
|
||||
|
||||
// 若重复执行 render,则视为 reload 处理
|
||||
if(elem[0] && elem.attr(MOD_ID)){
|
||||
var newThat = thisModule.getThis(elem.attr(MOD_ID));
|
||||
|
@ -163,7 +166,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
showBottom: true, // 是否显示底部栏
|
||||
isPreview: true, // 是否显示值预览
|
||||
btns: ['clear', 'now', 'confirm'], // 右下角显示的按钮,会按照数组顺序排列
|
||||
// 为实现 lang 选项就近生效,去除此处的默认值,原型 lang() 方法中有兜底值
|
||||
// 为实现 lang 选项就近生效,去除此处的默认值,$t 设置了英文回退值
|
||||
lang: '', // 语言,只支持 cn/en,即中文和英文
|
||||
theme: 'default', // 主题
|
||||
position: null, // 控件定位方式定位, 默认absolute,支持:fixed/absolute/static
|
||||
|
@ -177,51 +180,84 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
shade: 0
|
||||
};
|
||||
|
||||
// 多语言
|
||||
Class.prototype.lang = function() {
|
||||
Class.prototype.getI18nMessages = function () {
|
||||
var that = this;
|
||||
var options = that.config;
|
||||
var locale = i18n.config.locale.replace(/^\s+|\s+$/g, '');
|
||||
var i18nMessages = i18n.config.messages[locale];
|
||||
var laydateMessages = {
|
||||
// 保留原版 en
|
||||
en: {
|
||||
month: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
weeks: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
|
||||
time: ['Hour', 'Minute', 'Second'],
|
||||
selectDate: 'Select Date',
|
||||
selectTime: 'Select Time',
|
||||
startTime: 'Start Time',
|
||||
endTime: 'End Time',
|
||||
tools: {
|
||||
confirm: 'Confirm',
|
||||
clear: 'Clear',
|
||||
now: 'Now',
|
||||
reset: 'Reset'
|
||||
},
|
||||
timeout: 'End time cannot be less than start Time\nPlease re-select',
|
||||
invalidDate: 'Invalid date',
|
||||
formatError: ['The date format error\nMust be followed:\n', '\nIt has been reset'],
|
||||
preview: 'The selected result'
|
||||
}
|
||||
};
|
||||
|
||||
// 同步 message
|
||||
if (i18nMessages) {
|
||||
laydateMessages[locale] = i18nMessages.laydate;
|
||||
}
|
||||
var locale = i18n.config.locale;
|
||||
|
||||
// 纠正旧版「简体中文」语言码
|
||||
if (options.lang === 'cn') {
|
||||
options.lang = zhCN;
|
||||
} else if (!options.lang) { // 若未传 lang 选项,则取 locale
|
||||
options.lang = locale;
|
||||
}else if(!options.lang){
|
||||
options.lang = i18n.config.locale;
|
||||
}
|
||||
locale = options.lang;
|
||||
|
||||
// 获取当前语言的 laydate 消息
|
||||
// 若无消息数据,则取上述内置 en,确保组件正常显示。注:此非默认值逻辑,默认值已由 i18n 统一控制
|
||||
return laydateMessages[options.lang] || laydateMessages['en'];;
|
||||
};
|
||||
return {
|
||||
month: i18n.$t('laydate.month', null, {
|
||||
locale: locale,
|
||||
default: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||
}),
|
||||
weeks: i18n.$t('laydate.weeks', null, {
|
||||
locale: locale,
|
||||
default: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
|
||||
}),
|
||||
time: i18n.$t('laydate.time', null, {
|
||||
locale: locale,
|
||||
default: ['Hour', 'Minute', 'Second']
|
||||
}),
|
||||
selectDate: i18n.$t('laydate.selectDate', null, {
|
||||
locale: locale,
|
||||
default: 'Select Date'
|
||||
}),
|
||||
selectTime: i18n.$t('laydate.selectTime', null, {
|
||||
locale: locale,
|
||||
default: 'Select Time'
|
||||
}),
|
||||
startTime: i18n.$t('laydate.startTime', null, {
|
||||
locale: locale,
|
||||
default: 'Start Time'
|
||||
}),
|
||||
endTime: i18n.$t('laydate.endTime', null, {
|
||||
locale: locale,
|
||||
default: 'End Time'
|
||||
}),
|
||||
tools: {
|
||||
confirm: i18n.$t('laydate.tools.confirm', null, {
|
||||
locale: locale,
|
||||
default: 'Confirm'
|
||||
}),
|
||||
clear: i18n.$t('laydate.tools.clear', null, {
|
||||
locale: locale,
|
||||
default: 'Clear'
|
||||
}),
|
||||
now: i18n.$t('laydate.tools.now', null, {
|
||||
locale: locale,
|
||||
default: 'Now'
|
||||
}),
|
||||
reset: i18n.$t('laydate.tools.reset', null, {
|
||||
locale: locale,
|
||||
default: 'Reset'
|
||||
})
|
||||
},
|
||||
timeout: i18n.$t('laydate.timeout', null, {
|
||||
locale: locale,
|
||||
default: 'End time cannot be less than start Time\nPlease re-select'
|
||||
}),
|
||||
invalidDate: i18n.$t('laydate.invalidDate', null, {
|
||||
locale: locale,
|
||||
default: 'Invalid date'
|
||||
}),
|
||||
formatError: i18n.$t('laydate.formatError', null, {
|
||||
locale: locale,
|
||||
default: ['The date format error\nMust be followed:\n', '\nIt has been reset']
|
||||
}),
|
||||
preview: i18n.$t('laydate.preview', null, {
|
||||
locale: locale,
|
||||
default: 'The selected result'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 仅简体中文生效,不做国际化
|
||||
Class.prototype.markerOfChineseFestivals = {
|
||||
|
@ -317,7 +353,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
// 设置了一周的开始是周几,此处做一个控制
|
||||
if (options.weekStart) {
|
||||
if (!/^[0-6]$/.test(options.weekStart)) {
|
||||
var lang = that.lang();
|
||||
var lang = that.i18nMessages;
|
||||
options.weekStart = lang.weeks.indexOf(options.weekStart);
|
||||
if (options.weekStart === -1) options.weekStart = 0;
|
||||
}
|
||||
|
@ -434,7 +470,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
Class.prototype.render = function(){
|
||||
var that = this
|
||||
,options = that.config
|
||||
,lang = that.lang()
|
||||
,lang = that.i18nMessages
|
||||
,isStatic = options.position === 'static'
|
||||
|
||||
//主面板
|
||||
|
@ -830,7 +866,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
var that = this
|
||||
,thisDate = new Date()
|
||||
,options = that.config
|
||||
,lang = that.lang()
|
||||
,lang = that.i18nMessages
|
||||
,dateTime = options.dateTime = options.dateTime || that.systemDate()
|
||||
,thisMaxDate, error
|
||||
|
||||
|
@ -1431,7 +1467,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
,options = that.config
|
||||
,dateTime = value || that.thisDateTime(index)
|
||||
,thisDate = new Date(), startWeek, prevMaxDate, thisMaxDate
|
||||
,lang = that.lang()
|
||||
,lang = that.i18nMessages
|
||||
|
||||
,isAlone = options.type !== 'date' && options.type !== 'datetime'
|
||||
,tds = lay(that.table[index]).find('td')
|
||||
|
@ -1577,7 +1613,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
var that = this
|
||||
,options = that.config
|
||||
,dateTime = that.rangeLinked ? options.dateTime : [options.dateTime, that.endDate][index]
|
||||
,lang = that.lang()
|
||||
,lang = that.i18nMessages
|
||||
,isAlone = options.range && options.type !== 'date' && options.type !== 'datetime' //独立范围选择器
|
||||
|
||||
,ul = lay.elem('ul', {
|
||||
|
@ -1900,7 +1936,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
Class.prototype.setBtnStatus = function(tips, start, end){
|
||||
var that = this
|
||||
,options = that.config
|
||||
,lang = that.lang()
|
||||
,lang = that.i18nMessages
|
||||
,isOut
|
||||
,elemBtn = lay(that.footer).find(ELEM_CONFIRM)
|
||||
,timeParams = options.type === 'datetime' || options.type === 'time' ? ['hours', 'minutes', 'seconds'] : undefined;
|
||||
|
@ -2307,7 +2343,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
Class.prototype.tool = function(btn, type){
|
||||
var that = this
|
||||
,options = that.config
|
||||
,lang = that.lang()
|
||||
,lang = that.i18nMessages
|
||||
,dateTime = options.dateTime
|
||||
,isStatic = options.position === 'static'
|
||||
,active = {
|
||||
|
@ -2316,13 +2352,13 @@ layui.define(['lay', 'i18n'], function(exports) {
|
|||
if(lay(btn).hasClass(DISABLED)) return;
|
||||
that.list('time', 0);
|
||||
options.range && that.list('time', 1);
|
||||
lay(btn).attr('lay-type', 'date').html(that.lang().selectDate);
|
||||
lay(btn).attr('lay-type', 'date').html(that.i18nMessages.selectDate);
|
||||
}
|
||||
|
||||
//选择日期
|
||||
,date: function(){
|
||||
that.closeList();
|
||||
lay(btn).attr('lay-type', 'datetime').html(that.lang().selectTime);
|
||||
lay(btn).attr('lay-type', 'datetime').html(that.i18nMessages.selectTime);
|
||||
}
|
||||
|
||||
//清空、重置
|
||||
|
|
Loading…
Reference in New Issue