PairDrop/public_included_ws_fallback/scripts/localization.js

103 lines
2.8 KiB
JavaScript
Raw Normal View History

2023-07-06 21:29:36 +02:00
class Localization {
constructor() {
Localization.defaultLocale = "en";
Localization.supportedLocales = ["en"];
Localization.translations = {};
const initialLocale = Localization.supportedOrDefault(Localization.browserLocales());
Localization.setLocale(initialLocale)
.then(_ => {
Localization.translatePage();
})
}
static isSupported(locale) {
return Localization.supportedLocales.indexOf(locale) > -1;
}
static supportedOrDefault(locales) {
return locales.find(Localization.isSupported) || Localization.defaultLocale;
}
static browserLocales() {
return navigator.languages.map(locale =>
locale.split("-")[0]
);
}
static async setLocale(newLocale) {
if (newLocale === Localization.locale) return false;
const newTranslations = await Localization.fetchTranslationsFor(newLocale);
if(!newTranslations) return false;
const firstTranslation = !Localization.locale
Localization.locale = newLocale;
Localization.translations = newTranslations;
if (firstTranslation) {
Events.fire("translation-loaded");
}
}
static async fetchTranslationsFor(newLocale) {
const response = await fetch(`lang/${newLocale}.json`)
if (response.redirected === true || response.status !== 200) return false;
return await response.json();
}
static translatePage() {
document
.querySelectorAll("[data-i18n-key]")
.forEach(element => Localization.translateElement(element));
}
static async translateElement(element) {
const key = element.getAttribute("data-i18n-key");
const attrs = element.getAttribute("data-i18n-attrs").split(" ");
for (let i in attrs) {
let attr = attrs[i];
if (attr === "text") {
element.innerText = await Localization.getTranslation(key);
} else {
element.attr = await Localization.getTranslation(key, attr);
}
}
}
static getTranslation(key, attr, data) {
const keys = key.split(".");
let translationCandidates = Localization.translations;
for (let i=0; i<keys.length-1; i++) {
translationCandidates = translationCandidates[keys[i]]
}
let lastKey = keys[keys.length-1];
if (attr) lastKey += "_" + attr;
let translation = translationCandidates[lastKey];
for (key in data) {
translation = translation.replace(`{{${key}}}`, data[key]);
}
return Localization.escapeHTML(translation);
}
static escapeHTML(unsafeText) {
let div = document.createElement('div');
div.innerText = unsafeText;
return div.innerHTML;
}
}