Files
Wegwichtel/test-support/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

41 lines
1.7 KiB
JavaScript

import fs from 'node:fs/promises';
import path from 'node:path';
import vm from 'node:vm';
const root = path.resolve(import.meta.dirname, '..');
export async function loadI18n(context) {
for (const name of ['texts-de', 'i18n']) {
const filename = path.join(root, `public/js/${name}.js`);
vm.runInNewContext(await fs.readFile(filename, 'utf8'), context, { filename });
}
return context.Wegwichtel.I18n;
}
const escapeText = value => value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
export async function localizedHtml(source) {
const i18n = await loadI18n({});
let result = source.replace(/(<[^>]+\bdata-i18n="([^"]+)"[^>]*>)([^<]*)(<\/)/g,
(_match, opening, key, _text, closing) => opening + escapeText(i18n.t(key)) + closing);
result = result.replace(/<[^>]+>/g, opening => {
let translated = opening;
for (const attribute of ['title', 'aria-label', 'placeholder', 'alt']) {
const key = new RegExp(`data-i18n-${attribute}="([^"]+)"`).exec(opening)?.[1];
if (key) translated = translated.replace(new RegExp(`\\b${attribute}="[^"]*"`), `${attribute}="${escapeText(i18n.t(key)).replaceAll('"', '&quot;')}"`);
}
return translated;
});
return result.replace(/\sdata-i18n(?:-[\w-]+)?="[^"]*"/g, '');
}
export async function readAppFile(relativePath) {
const source = await fs.readFile(path.join(root, relativePath), 'utf8');
if (relativePath === 'public/index.html') return localizedHtml(source);
if (relativePath.startsWith('public/js/')) {
// Static text assertions read the centralized wording; runtime tests use the real class.
return source + '\n' + await fs.readFile(path.join(root, 'public/js/texts-de.js'), 'utf8');
}
return source;
}