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) {
|
var error = function(msg, type) {
|
||||||
type = type || 'log';
|
type = type || 'log';
|
||||||
msg = 'Layui message: ' + msg;
|
msg = '[Layui warn]: ' + msg;
|
||||||
|
|
||||||
if (window.console) {
|
if (window.console) {
|
||||||
console[type] ? console[type](msg) : console.log(msg);
|
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 = {
|
var builtinModules = config.builtin = {
|
||||||
|
@ -715,7 +728,8 @@
|
||||||
// 提示
|
// 提示
|
||||||
Class.prototype.hint = function() {
|
Class.prototype.hint = function() {
|
||||||
return {
|
return {
|
||||||
error: error
|
error: error,
|
||||||
|
errorOnce: errorOnce
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -262,27 +262,46 @@ layui.define('lay', function(exports) {
|
||||||
return value
|
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 = {
|
var i18n = {
|
||||||
config: config,
|
config: config,
|
||||||
set: function(options) {
|
set: function(options) {
|
||||||
lay.extend(config, options);
|
lay.extend(config, options);
|
||||||
getCachedValueForKeyPath.cleanup();
|
resolveValue.cleanup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var getCachedValueForKeyPath = memoize(function(key, obj){
|
|
||||||
return get(obj, key, key);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据给定的键从国际化消息中获取翻译后的内容
|
* 根据给定的键从国际化消息中获取翻译后的内容
|
||||||
* 未文档化的私有方法,仅限内部使用
|
* 未文档化的私有方法,仅限内部使用
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
* @param {string} key 要翻译的键
|
* @param {string} keypath 要翻译的键路径
|
||||||
* @param {any[]} [args] 可选的占位符替换参数:
|
* @param {Record<string, any> | any[]} [parameters] 可选的占位符替换参数:
|
||||||
* - 对象形式:用于替换 `{key}` 形式的占位符;
|
* - 对象形式:用于替换 `{key}` 形式的占位符;
|
||||||
* - 数组形式:用于替换 `{0}`, `{1}` 等占位符;
|
* - 数组形式:用于替换 `{0}`, `{1}` 等占位符;
|
||||||
|
* @param {{locale: string, default: string}} [options] 翻译选项
|
||||||
* @returns {string} 翻译后的文本
|
* @returns {string} 翻译后的文本
|
||||||
*
|
*
|
||||||
* @example 使用对象替换命名占位符
|
* @example 使用对象替换命名占位符
|
||||||
|
@ -297,27 +316,24 @@ layui.define('lay', function(exports) {
|
||||||
* }
|
* }
|
||||||
* i18n.$t('message.hello', ['Hello'])
|
* i18n.$t('message.hello', ['Hello'])
|
||||||
*/
|
*/
|
||||||
i18n.translation = function(key) {
|
i18n.translation = function(keypath, parameters, options) {
|
||||||
var options = config;
|
var locale = (options && options.locale) || config.locale;
|
||||||
var args = arguments;
|
var i18nMessages = config.messages[locale];
|
||||||
var i18nMessages = options.messages[options.locale];
|
var namespace = locale + ':';
|
||||||
|
var fallbackMessage = options && options.default;
|
||||||
|
|
||||||
if (!i18nMessages) {
|
if (!i18nMessages) {
|
||||||
hint.error('Locale "' + options.locale + '" not found. Please add i18n messages for this locale first.', 'warn');
|
hint.errorOnce("Locale '" + locale + "' not found. Please add i18n messages for this locale first.", 'error');
|
||||||
return key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = getCachedValueForKeyPath(key, i18nMessages);
|
var result = resolveValue(namespace + keypath, i18nMessages, fallbackMessage);
|
||||||
|
|
||||||
// 替换占位符
|
// 替换占位符
|
||||||
if (typeof result === 'string' && args.length > 1) {
|
if (typeof result === 'string' && parameters) {
|
||||||
var opts = args[1];
|
|
||||||
// 第二个参数为对象或数组,替换占位符 {key} 或 {0}, {1}...
|
// 第二个参数为对象或数组,替换占位符 {key} 或 {0}, {1}...
|
||||||
if (opts !== null && typeof opts === 'object') {
|
result = result.replace(OBJECT_REPLACE_REGEX, function(match, key) {
|
||||||
result = result.replace(OBJECT_REPLACE_REGEX, function(match, key) {
|
return parameters[key] !== undefined ? parameters[key] : match;
|
||||||
return opts[key] !== undefined ? opts[key] : match;
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return escape(result);
|
return escape(result);
|
||||||
|
|
|
@ -111,6 +111,9 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
// 初始化属性
|
// 初始化属性
|
||||||
options = lay.extend(that.config, lay.options(elem[0])); // 继承节点上的属性
|
options = lay.extend(that.config, lay.options(elem[0])); // 继承节点上的属性
|
||||||
|
|
||||||
|
// 更新 i18n 消息对象
|
||||||
|
that.i18nMessages = that.getI18nMessages();
|
||||||
|
|
||||||
// 若重复执行 render,则视为 reload 处理
|
// 若重复执行 render,则视为 reload 处理
|
||||||
if(elem[0] && elem.attr(MOD_ID)){
|
if(elem[0] && elem.attr(MOD_ID)){
|
||||||
var newThat = thisModule.getThis(elem.attr(MOD_ID));
|
var newThat = thisModule.getThis(elem.attr(MOD_ID));
|
||||||
|
@ -163,7 +166,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
showBottom: true, // 是否显示底部栏
|
showBottom: true, // 是否显示底部栏
|
||||||
isPreview: true, // 是否显示值预览
|
isPreview: true, // 是否显示值预览
|
||||||
btns: ['clear', 'now', 'confirm'], // 右下角显示的按钮,会按照数组顺序排列
|
btns: ['clear', 'now', 'confirm'], // 右下角显示的按钮,会按照数组顺序排列
|
||||||
// 为实现 lang 选项就近生效,去除此处的默认值,原型 lang() 方法中有兜底值
|
// 为实现 lang 选项就近生效,去除此处的默认值,$t 设置了英文回退值
|
||||||
lang: '', // 语言,只支持 cn/en,即中文和英文
|
lang: '', // 语言,只支持 cn/en,即中文和英文
|
||||||
theme: 'default', // 主题
|
theme: 'default', // 主题
|
||||||
position: null, // 控件定位方式定位, 默认absolute,支持:fixed/absolute/static
|
position: null, // 控件定位方式定位, 默认absolute,支持:fixed/absolute/static
|
||||||
|
@ -177,51 +180,84 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
shade: 0
|
shade: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// 多语言
|
Class.prototype.getI18nMessages = function () {
|
||||||
Class.prototype.lang = function() {
|
|
||||||
var that = this;
|
var that = this;
|
||||||
var options = that.config;
|
var options = that.config;
|
||||||
var locale = i18n.config.locale.replace(/^\s+|\s+$/g, '');
|
var locale = i18n.config.locale;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 纠正旧版「简体中文」语言码
|
// 纠正旧版「简体中文」语言码
|
||||||
if (options.lang === 'cn') {
|
if (options.lang === 'cn') {
|
||||||
options.lang = zhCN;
|
options.lang = zhCN;
|
||||||
} else if (!options.lang) { // 若未传 lang 选项,则取 locale
|
}else if(!options.lang){
|
||||||
options.lang = locale;
|
options.lang = i18n.config.locale;
|
||||||
}
|
}
|
||||||
|
locale = options.lang;
|
||||||
|
|
||||||
// 获取当前语言的 laydate 消息
|
return {
|
||||||
// 若无消息数据,则取上述内置 en,确保组件正常显示。注:此非默认值逻辑,默认值已由 i18n 统一控制
|
month: i18n.$t('laydate.month', null, {
|
||||||
return laydateMessages[options.lang] || laydateMessages['en'];;
|
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 = {
|
Class.prototype.markerOfChineseFestivals = {
|
||||||
|
@ -317,7 +353,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
// 设置了一周的开始是周几,此处做一个控制
|
// 设置了一周的开始是周几,此处做一个控制
|
||||||
if (options.weekStart) {
|
if (options.weekStart) {
|
||||||
if (!/^[0-6]$/.test(options.weekStart)) {
|
if (!/^[0-6]$/.test(options.weekStart)) {
|
||||||
var lang = that.lang();
|
var lang = that.i18nMessages;
|
||||||
options.weekStart = lang.weeks.indexOf(options.weekStart);
|
options.weekStart = lang.weeks.indexOf(options.weekStart);
|
||||||
if (options.weekStart === -1) options.weekStart = 0;
|
if (options.weekStart === -1) options.weekStart = 0;
|
||||||
}
|
}
|
||||||
|
@ -434,7 +470,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
Class.prototype.render = function(){
|
Class.prototype.render = function(){
|
||||||
var that = this
|
var that = this
|
||||||
,options = that.config
|
,options = that.config
|
||||||
,lang = that.lang()
|
,lang = that.i18nMessages
|
||||||
,isStatic = options.position === 'static'
|
,isStatic = options.position === 'static'
|
||||||
|
|
||||||
//主面板
|
//主面板
|
||||||
|
@ -830,7 +866,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
var that = this
|
var that = this
|
||||||
,thisDate = new Date()
|
,thisDate = new Date()
|
||||||
,options = that.config
|
,options = that.config
|
||||||
,lang = that.lang()
|
,lang = that.i18nMessages
|
||||||
,dateTime = options.dateTime = options.dateTime || that.systemDate()
|
,dateTime = options.dateTime = options.dateTime || that.systemDate()
|
||||||
,thisMaxDate, error
|
,thisMaxDate, error
|
||||||
|
|
||||||
|
@ -1431,7 +1467,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
,options = that.config
|
,options = that.config
|
||||||
,dateTime = value || that.thisDateTime(index)
|
,dateTime = value || that.thisDateTime(index)
|
||||||
,thisDate = new Date(), startWeek, prevMaxDate, thisMaxDate
|
,thisDate = new Date(), startWeek, prevMaxDate, thisMaxDate
|
||||||
,lang = that.lang()
|
,lang = that.i18nMessages
|
||||||
|
|
||||||
,isAlone = options.type !== 'date' && options.type !== 'datetime'
|
,isAlone = options.type !== 'date' && options.type !== 'datetime'
|
||||||
,tds = lay(that.table[index]).find('td')
|
,tds = lay(that.table[index]).find('td')
|
||||||
|
@ -1577,7 +1613,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
var that = this
|
var that = this
|
||||||
,options = that.config
|
,options = that.config
|
||||||
,dateTime = that.rangeLinked ? options.dateTime : [options.dateTime, that.endDate][index]
|
,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' //独立范围选择器
|
,isAlone = options.range && options.type !== 'date' && options.type !== 'datetime' //独立范围选择器
|
||||||
|
|
||||||
,ul = lay.elem('ul', {
|
,ul = lay.elem('ul', {
|
||||||
|
@ -1900,7 +1936,7 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
Class.prototype.setBtnStatus = function(tips, start, end){
|
Class.prototype.setBtnStatus = function(tips, start, end){
|
||||||
var that = this
|
var that = this
|
||||||
,options = that.config
|
,options = that.config
|
||||||
,lang = that.lang()
|
,lang = that.i18nMessages
|
||||||
,isOut
|
,isOut
|
||||||
,elemBtn = lay(that.footer).find(ELEM_CONFIRM)
|
,elemBtn = lay(that.footer).find(ELEM_CONFIRM)
|
||||||
,timeParams = options.type === 'datetime' || options.type === 'time' ? ['hours', 'minutes', 'seconds'] : undefined;
|
,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){
|
Class.prototype.tool = function(btn, type){
|
||||||
var that = this
|
var that = this
|
||||||
,options = that.config
|
,options = that.config
|
||||||
,lang = that.lang()
|
,lang = that.i18nMessages
|
||||||
,dateTime = options.dateTime
|
,dateTime = options.dateTime
|
||||||
,isStatic = options.position === 'static'
|
,isStatic = options.position === 'static'
|
||||||
,active = {
|
,active = {
|
||||||
|
@ -2316,13 +2352,13 @@ layui.define(['lay', 'i18n'], function(exports) {
|
||||||
if(lay(btn).hasClass(DISABLED)) return;
|
if(lay(btn).hasClass(DISABLED)) return;
|
||||||
that.list('time', 0);
|
that.list('time', 0);
|
||||||
options.range && that.list('time', 1);
|
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(){
|
,date: function(){
|
||||||
that.closeList();
|
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