UNPKG

@formatjs/intl-pluralrules

Version:
130 lines (129 loc) 4.23 kB
import { CanonicalizeLocaleList, SupportedLocales, ToNumber } from "@formatjs/ecma402-abstract"; import "./abstract/GetOperands.js"; import { InitializePluralRules } from "./abstract/InitializePluralRules.js"; import { ResolvePlural } from "./abstract/ResolvePlural.js"; import getInternalSlots from "./get_internal_slots.js"; function validateInstance(instance, method) { if (!(instance instanceof PluralRules)) { throw new TypeError(`Method Intl.PluralRules.prototype.${method} called on incompatible receiver ${String(instance)}`); } } /** * http://ecma-international.org/ecma-402/7.0/index.html#sec-pluralruleselect * @param locale * @param type * @param _n * @param param3 */ function PluralRuleSelect(locale, type, _n, { IntegerDigits, NumberOfFractionDigits, FractionDigits }) { return PluralRules.localeData[locale].fn(NumberOfFractionDigits ? `${IntegerDigits}.${FractionDigits}` : IntegerDigits, type === "ordinal"); } export class PluralRules { constructor(locales, options) { // test262/test/intl402/RelativeTimeFormat/constructor/constructor/newtarget-undefined.js // Cannot use `new.target` bc of IE11 & TS transpiles it to something else const newTarget = this && this instanceof PluralRules ? this.constructor : void 0; if (!newTarget) { throw new TypeError("Intl.PluralRules must be called with 'new'"); } return InitializePluralRules(this, locales, options, { availableLocales: PluralRules.availableLocales, relevantExtensionKeys: PluralRules.relevantExtensionKeys, localeData: PluralRules.localeData, getDefaultLocale: PluralRules.getDefaultLocale, getInternalSlots }); } resolvedOptions() { validateInstance(this, "resolvedOptions"); const opts = Object.create(null); const internalSlots = getInternalSlots(this); opts.locale = internalSlots.locale; opts.type = internalSlots.type; [ "minimumIntegerDigits", "minimumFractionDigits", "maximumFractionDigits", "minimumSignificantDigits", "maximumSignificantDigits" ].forEach((field) => { const val = internalSlots[field]; if (val !== undefined) { opts[field] = val; } }); opts.pluralCategories = [...PluralRules.localeData[opts.locale].categories[opts.type]]; return opts; } select(val) { validateInstance(this, "select"); const n = ToNumber(val); return ResolvePlural(this, n, { getInternalSlots, PluralRuleSelect }); } toString() { return "[object Intl.PluralRules]"; } static supportedLocalesOf(locales, options) { return SupportedLocales(PluralRules.availableLocales, CanonicalizeLocaleList(locales), options); } static __addLocaleData(...data) { for (const { data: d, locale } of data) { PluralRules.localeData[locale] = d; PluralRules.availableLocales.add(locale); if (!PluralRules.__defaultLocale) { PluralRules.__defaultLocale = locale; } } } static localeData = {}; static availableLocales = new Set(); static __defaultLocale = ""; static getDefaultLocale() { return PluralRules.__defaultLocale; } static relevantExtensionKeys = []; static polyfilled = true; } try { // IE11 does not have Symbol if (typeof Symbol !== "undefined") { Object.defineProperty(PluralRules.prototype, Symbol.toStringTag, { value: "Intl.PluralRules", writable: false, enumerable: false, configurable: true }); } try { // https://github.com/tc39/test262/blob/master/test/intl402/PluralRules/length.js Object.defineProperty(PluralRules, "length", { value: 0, writable: false, enumerable: false, configurable: true }); } catch {} // https://github.com/tc39/test262/blob/master/test/intl402/RelativeTimeFormat/constructor/length.js Object.defineProperty(PluralRules.prototype.constructor, "length", { value: 0, writable: false, enumerable: false, configurable: true }); // https://github.com/tc39/test262/blob/master/test/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/length.js Object.defineProperty(PluralRules.supportedLocalesOf, "length", { value: 1, writable: false, enumerable: false, configurable: true }); Object.defineProperty(PluralRules, "name", { value: "PluralRules", writable: false, enumerable: false, configurable: true }); } catch {}