Files
Wegwichtel/public/js/i18n.js
T
Florian Zumpe aff88eba1b
Sonarqube Scanner / Prepare environment (push) Successful in 20s
Sonarqube Scanner / Build and test (push) Failing after 36s
Sonarqube Scanner / SonarQube analysis (push) Skipped
Sonarqube Scanner / Deploy to Server (push) Successful in 9s
Internationalization
2026-10-01 09:41:01 +02:00

55 lines
2.1 KiB
JavaScript

globalThis.Wegwichtel ??= {};
(function (ns) {
'use strict';
class WegwichtelI18n {
static #languages = new Map([['de', ns.TextsDe.messages]]);
static #language = 'de';
static get language() { return this.#language; }
static register(language, messages) {
this.#languages.set(language.toLowerCase(), Object.freeze({ ...messages }));
}
static setLanguage(language, root = globalThis.document) {
const requested = String(language).toLowerCase();
const base = requested.split('-')[0];
this.#language = 'de';
if (this.#languages.has(base)) this.#language = base;
if (this.#languages.has(requested)) this.#language = requested;
this.apply(root);
return this.#language;
}
static t(key, variables = {}) {
let value = this.#languages.get(this.#language)?.[key] ?? ns.TextsDe.messages[key];
if (value == null) throw new RangeError(`Missing translation: ${key}`);
if (typeof value === 'object') {
const plural = new Intl.PluralRules(this.#language).select(Number(variables.count));
value = value[plural] ?? value.other;
}
return value.replace(/\{([a-zA-Z0-9_]+)\}/g, (placeholder, name) => {
if (!Object.hasOwn(variables, name)) return placeholder;
return String(variables[name] ?? '');
});
}
static apply(root = globalThis.document) {
if (!root?.querySelectorAll) return;
if (root.documentElement) root.documentElement.lang = this.#language;
for (const element of root.querySelectorAll('[data-i18n]')) {
if (typeof element.getAttribute === 'function') element.textContent = this.t(element.getAttribute('data-i18n'));
}
for (const attribute of ['title', 'aria-label', 'placeholder', 'alt']) {
for (const element of root.querySelectorAll(`[data-i18n-${attribute}]`)) {
if (typeof element.getAttribute === 'function' && typeof element.setAttribute === 'function') element.setAttribute(attribute, this.t(element.getAttribute(`data-i18n-${attribute}`)));
}
}
}
}
ns.I18n = WegwichtelI18n;
WegwichtelI18n.apply();
}(globalThis.Wegwichtel));