初始化项目
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 多语言运行时(1.3.9)。
|
||||
*
|
||||
* 纯逻辑实现:语言标签归一化、支持列表匹配、用户偏好与系统语言的协商。
|
||||
* 资源文件仍由 resources/<语言>/element/string.json 提供,本类只决定「用哪个语言」。
|
||||
*
|
||||
* 协商顺序(对应 I18N-001 设计):
|
||||
* 1) 用户显式选择且在支持列表内 → 用它;
|
||||
* 2) 否则取系统语言,按「完全匹配 → 主语言匹配」找支持项;
|
||||
* 3) 都不匹配 → 回退 fallback(中文简体)。
|
||||
*
|
||||
* 标签规范:小写化并用 '-' 分隔,如 zh-Hans-CN、en-US;忽略大小写与下划线差异。
|
||||
*/
|
||||
export class I18nUtil {
|
||||
/** 归一化语言标签:小写、下划线转连字符、去空白。 */
|
||||
static normalize(tag: string): string {
|
||||
return tag.trim().toLowerCase().replace('_', '-');
|
||||
}
|
||||
|
||||
/** 主语言(第一个子标签),如 zh-Hans-CN → zh。 */
|
||||
static primaryOf(tag: string): string {
|
||||
const normalized: string = I18nUtil.normalize(tag);
|
||||
const idx: number = normalized.indexOf('-');
|
||||
return idx < 0 ? normalized : normalized.substring(0, idx);
|
||||
}
|
||||
|
||||
/** 是否在支持列表中(完全匹配,忽略大小写)。 */
|
||||
static isSupported(tag: string, supported: string[]): boolean {
|
||||
const target: string = I18nUtil.normalize(tag);
|
||||
for (let i = 0; i < supported.length; i++) {
|
||||
if (I18nUtil.normalize(supported[i]) === target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 在支持列表中找到与给定标签最匹配的项;找不到返回 undefined。 */
|
||||
static match(tag: string, supported: string[]): string | undefined {
|
||||
const target: string = I18nUtil.normalize(tag);
|
||||
for (let i = 0; i < supported.length; i++) {
|
||||
if (I18nUtil.normalize(supported[i]) === target) {
|
||||
return supported[i];
|
||||
}
|
||||
}
|
||||
const primary: string = I18nUtil.primaryOf(target);
|
||||
for (let i = 0; i < supported.length; i++) {
|
||||
if (I18nUtil.primaryOf(supported[i]) === primary) {
|
||||
return supported[i];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 协商最终语言。
|
||||
* @param systemTag 系统语言,如 zh-Hans-CN
|
||||
* @param userTag 用户偏好(空表示跟随系统)
|
||||
* @param supported 支持列表,顺序即优先级
|
||||
* @param fallback 回退语言
|
||||
*/
|
||||
static negotiate(systemTag: string, userTag: string, supported: string[], fallback: string): string {
|
||||
if (userTag.length > 0) {
|
||||
const byUser: string | undefined = I18nUtil.match(userTag, supported);
|
||||
if (byUser !== undefined) {
|
||||
return byUser;
|
||||
}
|
||||
}
|
||||
if (systemTag.length > 0) {
|
||||
const bySystem: string | undefined = I18nUtil.match(systemTag, supported);
|
||||
if (bySystem !== undefined) {
|
||||
return bySystem;
|
||||
}
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user