const estrategiasInterpolacion = {
'mail': (partes) => {
return `${partes[1]}`
},
'link': (partes) => {
return `${partes[2]}`
},
'linkblank': (partes) => {
return `${partes[2]}`
}
}
function extraerInterpolaciones(texto) {
const interpolaciones = []
const re = /\{\{(.+?)\}\}/g;
let m;
while (m = re.exec(texto)) {
interpolaciones.push(m[1])
}
return interpolaciones
}
/**
* @param {HTMLAreaElement} target
* @param {string} interpolacion
*/
function interpolar(target, interpolacion) {
const partes = interpolacion.split('|')
const tipo = partes[0]
//const attr = target.getAttribute(`i18n_${tipo}`)
if (partes.length > 1) {
return estrategiasInterpolacion[tipo](partes)
}
}
function traducir_pagina() {
const targets = document.querySelectorAll('[i18n]')
const targetAttrs = document.querySelectorAll('[i18nattr]')
targets.forEach(t => traducir(t))
targetAttrs.forEach(t => traducirAtributos(t))
}
/**
*
* @param {HTMLElement} target
* @param {string} i18nkey
*/
function getCategorias(target, i18nkey) {
const categorias = i18nkey.split('|')
if (categorias.length > 1) { return categorias }
let padre = target
while ( padre = padre.parentElement ) {
const attr = padre.getAttribute('i18n')
if (attr && attr.length > 0) {
categorias.unshift(...attr.split('|'))
}
}
return categorias
}
function getTraduccion(path) {
try {
let txt = textos[idioma]
path.forEach(j => txt = txt[j])
if (typeof txt != 'string') { return }
return txt
} finally {}
}
/**
* Un elemento puede tener un atributo i18n con siguientes formatos:
* i18n="ruta|en|locales"
* i18n="modificador:ruta|en|locales"
*
* Donde modificar puede ser:
* · txtnode: solo reemplazará el texto, respetando el resto del html
*
* @param {HTMLElement} target
*/
function traducir(target) {
let i18n = target.getAttribute('i18n')
if (i18n == null) { return }
let mod = 'normal'
if (i18n.includes(':')) {
const modYPath = i18n.split(':')
mod = modYPath[0]
i18n = modYPath[1]
}
if (i18n.length == 0) {
i18n = target.classList.item(0)
}
const path = getCategorias(target, i18n)
if (path[0].length == 0){ return }
try {
let txt = getTraduccion(path)
if (!txt) { return }
const interpolaciones = extraerInterpolaciones(txt)
interpolaciones.forEach(i => {
const res = interpolar(target, i)
txt = txt.replace('{{' + i + '}}', res)
})
if (mod == 'txtnode') {
target.childNodes.forEach(c => {
if (c.nodeType == Node.TEXT_NODE && c.textContent.trim().length != 0) {
c.textContent = ' ' + txt
}
})
} else {
target.innerHTML = txt
}
} finally {}
}
function traducirAtributos(target) {
let attr = target.getAttribute('i18nattr')
if (attr == null) { return }
const atributo = attr.split(':')[0]
const categorias = getCategorias(target, attr.split(':')[1])
const txt = getTraduccion(categorias)
if (!txt) { return }
target.setAttribute(atributo, txt)
}
document.addEventListener('DOMContentLoaded', ()=>{
getIdioma()
traducir_pagina()
})