Add Handlebars helpers

This commit is contained in:
Oliver-Akins 2024-12-21 23:46:26 -07:00
parent 06c5320786
commit edd4e49f62
4 changed files with 87 additions and 0 deletions

View file

@ -0,0 +1,11 @@
import { handlebarsLocalizer, localizer } from "../utils/Localizer.mjs";
import { options } from "./options.mjs";
export default {
// #region Complex
"rc-i18n": handlebarsLocalizer,
"rc-options": options,
// #region Simple
"rc-empty-state": (v) => v ?? localizer(`RipCrypt.common.empty`),
};

View file

@ -0,0 +1,36 @@
import { localizer } from "../utils/Localizer.mjs";
/**
* @typedef {object} Option
* @property {string} [label]
* @property {string|number} value
* @property {boolean} [disabled]
*/
/**
* @param {string | number} selected
* @param {Array<Option | string>} opts
* @param {any} meta
*/
export function options(selected, opts, meta) {
const { localize = false } = meta;
selected = Handlebars.escapeExpression(selected);
const htmlOptions = [];
for (let opt of opts) {
if (typeof opt === `string`) {
opt = { label: opt, value: opt };
};
opt.value = Handlebars.escapeExpression(opt.value);
htmlOptions.push(
`<option
value=${opt.value}
${selected === opt.value ? `selected` : ``}
${opt.disabled ? `disabled` : ``}
>
${localize ? localizer(opt.label) : opt.label}
</option>`,
);
};
};

View file

@ -0,0 +1,37 @@
import { localizerConfig } from "../config.mjs";
export function handlebarsLocalizer(key, ...args) {
let data = args[0];
if (args.length === 1) { data = args[0].hash };
if (key instanceof Handlebars.SafeString) { key = key.toString() };
const localized = localizer(key, data);
return localized;
};
export function localizer(key, args = {}, depth = 0) {
/** @type {string} */
let localized = game.i18n.format(key, args);
const subkeys = localized.matchAll(localizerConfig.subKeyPattern);
// Short-cut to help prevent infinite recursion
if (depth > localizerConfig.maxDepth) {
return localized;
};
/*
Helps prevent recursion on the same key so that we aren't doing excess work.
*/
const localizedSubkeys = new Map();
for (const match of subkeys) {
const subkey = match.groups.key;
if (localizedSubkeys.has(subkey)) { continue };
localizedSubkeys.set(subkey, localizer(subkey, args, depth + 1));
};
return localized.replace(
localizerConfig.subKeyPattern,
(_fullMatch, subkey) => {
return localizedSubkeys.get(subkey);
},
);
};