32 lines
1.5 KiB
JavaScript
32 lines
1.5 KiB
JavaScript
|
|
// Strings, loaded once from the flat dictionary scripts/build-locale.mjs
|
||
|
|
// generates from locales/en-US/main.ftl. No Fluent parser ships here — the
|
||
|
|
// build step already resolved the source file's syntax down to plain
|
||
|
|
// `{ $var }` placeholders, which is all this needs to substitute.
|
||
|
|
|
||
|
|
let messages = null;
|
||
|
|
|
||
|
|
export async function loadLocale() {
|
||
|
|
const response = await fetch("locales/en-US.json");
|
||
|
|
messages = await response.json();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Falls back to the id itself on a miss, so a typo'd or forgotten call
|
||
|
|
// shows up as visibly wrong text in the UI rather than disappearing.
|
||
|
|
export function t(id, args = {}) {
|
||
|
|
const value = messages?.[id];
|
||
|
|
if (value === undefined) return id;
|
||
|
|
return value.replace(/\{\s*\$(\w+)\s*\}/g, (_, name) => args[name] ?? "");
|
||
|
|
}
|
||
|
|
|
||
|
|
// index.html's static markup keeps its literal English text and gains
|
||
|
|
// data-l10n-* attributes alongside it, so the page still reads correctly
|
||
|
|
// even if this runs late — this pass just overwrites it from the same
|
||
|
|
// English source, proving the wiring for whenever a second locale exists.
|
||
|
|
export function applyStaticLocale(root = document) {
|
||
|
|
for (const el of root.querySelectorAll("[data-l10n-id]")) el.textContent = t(el.dataset.l10nId);
|
||
|
|
for (const el of root.querySelectorAll("[data-l10n-placeholder]")) el.placeholder = t(el.dataset.l10nPlaceholder);
|
||
|
|
for (const el of root.querySelectorAll("[data-l10n-title]")) el.title = t(el.dataset.l10nTitle);
|
||
|
|
for (const el of root.querySelectorAll("[data-l10n-aria-label]"))
|
||
|
|
el.setAttribute("aria-label", t(el.dataset.l10nAriaLabel));
|
||
|
|
}
|