feat: DSL 磁力聚合 — 搜索/解析/预览/投递 + cilisousuo 源 + 中英双语 + Docker 部署
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { en2zh, normalizeWs, zh2en } from './i18n-dict'
|
||||
|
||||
export type Locale = 'en' | 'zh'
|
||||
|
||||
const STORAGE_KEY = 'dsl-locale'
|
||||
|
||||
function readInitialLocale(): Locale {
|
||||
if (import.meta.client) {
|
||||
const v = localStorage.getItem(STORAGE_KEY)
|
||||
if (v === 'en' || v === 'zh') return v
|
||||
}
|
||||
return 'en' // 默认英文
|
||||
}
|
||||
|
||||
// 模块级响应式语言状态(默认英文)
|
||||
export const locale = ref<Locale>(readInitialLocale())
|
||||
|
||||
export function setLocale(next: Locale) {
|
||||
locale.value = next
|
||||
if (import.meta.client) {
|
||||
localStorage.setItem(STORAGE_KEY, next)
|
||||
document.documentElement.lang = next === 'zh' ? 'zh-CN' : 'en'
|
||||
translateDocument()
|
||||
}
|
||||
}
|
||||
|
||||
/** 把一段中文(或英文)文本按当前语言翻译;找不到映射时原样返回 */
|
||||
export function translateText(input: string): string {
|
||||
if (!input) return input
|
||||
const key = normalizeWs(input)
|
||||
const map = locale.value === 'zh' ? en2zh : zh2en
|
||||
return map[key] ?? input
|
||||
}
|
||||
|
||||
/** 遍历 root 下的文本节点与常见属性,按当前语言就地翻译 */
|
||||
export function walkAndTranslate(root: Node = document.body) {
|
||||
if (!root || !import.meta.client) return
|
||||
|
||||
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)
|
||||
const fixes: { node: Text; text: string }[] = []
|
||||
let n: Node | null
|
||||
while ((n = walker.nextNode())) {
|
||||
const t = (n as Text).textContent || ''
|
||||
if (!t.trim()) continue
|
||||
const tr = translateText(t)
|
||||
if (tr !== t) fixes.push({ node: n as Text, text: tr })
|
||||
}
|
||||
for (const f of fixes) f.node.textContent = f.text
|
||||
|
||||
// 翻译属性(title / placeholder / alt)
|
||||
if (root instanceof HTMLElement) {
|
||||
root.querySelectorAll<HTMLElement>('*').forEach((el) => {
|
||||
for (const attr of ['title', 'placeholder', 'alt']) {
|
||||
const v = el.getAttribute(attr)
|
||||
if (!v) continue
|
||||
const tr = translateText(v)
|
||||
if (tr !== v) el.setAttribute(attr, tr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function translateDocument() {
|
||||
if (import.meta.client) walkAndTranslate(document.body)
|
||||
}
|
||||
Reference in New Issue
Block a user