i18n 国际化基础插件
简介
i18n(Internationalization)是 NitaiPage 项目中的一个核心插件,提供页面内容的实时翻译功能。该插件通过 IndexedDB 存储翻译字典,并使用 MutationObserver 监听 DOM 变化,实现动态内容的实时翻译。
功能说明
实时翻译
- 支持翻译 HTML 属性(placeholder、title)
- 通过监听 DOM 变化,实时翻译用户页面中的文本
- 支持跳过特定元素(
translate="none")及其所有子元素
字典
- 从 IndexedDB 读取和保存翻译字典
- 字典格式:
'原文': '译文' - 字典为空时不启用翻译
- 翻译时按照原文长度从长到短开始翻译
API
addTranslationEntries(entries)
用于批量添加翻译到字典
参数:
entries(Object) - 翻译条目对象,格式为{ '原文': '译文', ... }
返回值:
Promise<boolean>- 添加成功返回 true,失败返回 false
示例:
javascript
const success = await window.i18n.addTranslationEntries({
'@yourPluginTextPart:a-part-of-the-plugin-text1': '你好',
'@yourPluginTextPart:a-part-of-the-plugin-text2': '世界',
'@yourPluginTextPart:a-part-of-the-plugin-text3': '设置',
'@yourPluginTextPart:a-part-of-the-plugin-text4': '保存'
});
if (success) {
console.log('翻译条目添加成功');
}注意事项
空值或非字符串会被跳过- 每个原文都作为独立的 key 存储到 IndexedDB
- 至少成功一个 key 才会返回 true
- 为了避免与其它插件的 key 冲突,建议在 key 前添加插件名称前缀(如
@yourPluginTextPart:)
字典存储
翻译字典存储在 IndexedDB 中:
- 数据库名:
translate - 存储名:
entries - 存储结构:
key:原文,value:译文
translate (数据库)
└── entries (存储空间)
├── '原文1': '译文1'
├── '原文2': '译文2'
└── ...用户设置
自动安装翻译插件开关
开启后在安装新的插件时,自动安装对应的翻译
工作流
检测浏览器语言
- 读取
navigator.languages或navigator.language,返回的第一个有效的语言代码 - 默认回退到
en-US
- 读取
检查已安装语言
- 从 localStorage 读取
installedTranslationLang - 如果未安装或使用的是基础配置,则尝试安装
- 从 localStorage 读取
安装翻译插件
- 获取全局翻译插件:
https://nfdb.nitai.us.kg/translateGlobal-{langCode}.js - 解析翻译字典
- 存储字典到 IndexedDB
- 标记已安装语言
- 获取全局翻译插件:
回退
- 如果翻译插件不存在或下载失败
- 获取全局翻译插件:
https://nfdb.nitai.us.kg/translateGlobal-en-US.js - 如果翻译插件还是不存在或下载失败
- 加载本地
basicLanguageSetting.json作为回退 - 将基础配置保存到 IndexedDB
- 标记为使用基础配置(
basic)
示例
制作翻译插件
javascript
// ==Npplication==
// @name ...
// @id ...
// @version 1.0.0
// @type translate
// @translates language
// @updateUrl https://...
// @description 设置全局...
// @author ...
// @icon ...
// @setting false
// ==/Npplication==
// localStorage.setItem('autoInstallTranslationGlobal', 'language'); //仅全局翻译插件需要设置,如果你是为其它插件制作翻译插件,请删除这一行
// 添加字典
$(function () {
const translateEntries = {...};
if (typeof window !== 'undefined' && window.i18n && window.i18n.addTranslationEntries) {
window.i18n.addTranslationEntries(translateEntriesGlobal);
}
});