@formatjs/intl-pluralrules
Version:
Polyfill for Intl.PluralRules
32 lines (31 loc) • 1.97 kB
JavaScript
import { CanonicalizeLocaleList, CoerceOptionsToObject, GetOption, SetNumberFormatDigitOptions } from "@formatjs/ecma402-abstract";
import { ResolveLocale } from "@formatjs/intl-localematcher";
export function InitializePluralRules(pl, locales, options, { availableLocales, relevantExtensionKeys, localeData, getDefaultLocale, getInternalSlots }) {
const requestedLocales = CanonicalizeLocaleList(locales);
const opt = Object.create(null);
const opts = CoerceOptionsToObject(options);
const internalSlots = getInternalSlots(pl);
internalSlots.initializedPluralRules = true;
const matcher = GetOption(opts, "localeMatcher", "string", ["best fit", "lookup"], "best fit");
opt.localeMatcher = matcher;
const r = ResolveLocale(availableLocales, requestedLocales, opt, relevantExtensionKeys, localeData, getDefaultLocale);
internalSlots.locale = r.locale;
// ECMA-402 Spec: type option ('cardinal' or 'ordinal')
internalSlots.type = GetOption(opts, "type", "string", ["cardinal", "ordinal"], "cardinal");
// Extension: notation options for compact notation support
// Not in ECMA-402 spec, but mirrors Intl.NumberFormat notation option
// Enables proper plural selection for compact numbers (e.g., "1.2M")
const notation = GetOption(opts, "notation", "string", ["standard", "compact"], "standard");
internalSlots.notation = notation;
if (notation === "compact") {
// Extension: compactDisplay option (mirrors Intl.NumberFormat)
internalSlots.compactDisplay = GetOption(opts, "compactDisplay", "string", ["short", "long"], "short");
// Implementation: Load NumberFormat locale data if available (soft dependency)
// This is needed to calculate compact exponents using ComputeExponentForMagnitude
if (typeof Intl !== "undefined" && Intl.NumberFormat && Intl.NumberFormat.localeData) {
internalSlots.dataLocaleData = Intl.NumberFormat.localeData[r.locale];
}
}
SetNumberFormatDigitOptions(internalSlots, opts, 0, 3, "standard");
return pl;
}