UNPKG

messageformat

Version:

Intl.MessageFormat / Unicode MessageFormat 2 parser, runtime and polyfill

53 lines (52 loc) 1.95 kB
import { MessageError } from "../errors.js"; import { fallback } from "../functions/fallback.js"; import { BIDI_ISOLATE } from "../message-value.js"; import { MessageFunctionContext } from "./function-context.js"; import { getValueSource, resolveValue } from "./resolve-value.js"; export function resolveFunctionRef(ctx, operand, { name, options }) { const source = getValueSource(operand) ?? `:${name}`; try { const fnInput = operand ? [resolveValue(ctx, operand)] : []; const rf = ctx.functions[name]; if (!rf) { throw new MessageError('unknown-function', `Unknown function :${name}`); } const msgCtx = new MessageFunctionContext(ctx, source, options); const opt = resolveOptions(ctx, options); let res = rf(msgCtx, opt, ...fnInput); if (res === null || (typeof res !== 'object' && typeof res !== 'function') || typeof res.type !== 'string' || typeof res.source !== 'string') { throw new MessageError('bad-function-result', `Function :${name} did not return a MessageValue`); } if (msgCtx.dir) res = { ...res, dir: msgCtx.dir, [BIDI_ISOLATE]: true }; if (msgCtx.id && typeof res.toParts === 'function') { return { ...res, toParts() { const parts = res.toParts(); for (const part of parts) part.id = msgCtx.id; return parts; } }; } return res; } catch (error) { ctx.onError(error); return fallback(source); } } function resolveOptions(ctx, options) { const opt = Object.create(null); if (options) { for (const [name, value] of options) { if (!name.startsWith('u:')) opt[name] = resolveValue(ctx, value); } } return opt; }