1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 * PluralRules internal properties.
8 * 9.1 Internal slots of Service Constructors
9 * 16.2.3 Properties of the Intl.PluralRules Constructor, Internal slots
11 * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6
13 var pluralRulesInternalProperties = {
14 localeData: pluralRulesLocaleData,
15 relevantExtensionKeys: [],
18 function pluralRulesLocaleData() {
19 // PluralRules don't support any extension keys.
24 * 16.1.2 InitializePluralRules ( pluralRules, locales, options )
26 * Compute an internal properties object from |lazyPluralRulesData|.
28 * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6
30 function resolvePluralRulesInternals(lazyPluralRulesData) {
31 assert(IsObject(lazyPluralRulesData), "lazy data not an object?");
33 var internalProps = std_Object_create(null);
35 var PluralRules = pluralRulesInternalProperties;
37 // Compute effective locale.
40 var localeData = PluralRules.localeData;
43 var r = ResolveLocale(
45 lazyPluralRulesData.requestedLocales,
46 lazyPluralRulesData.opt,
47 PluralRules.relevantExtensionKeys,
52 internalProps.locale = r.locale;
55 internalProps.type = lazyPluralRulesData.type;
57 // Step 8. SetNumberFormatDigitOptions, step 6.
58 internalProps.minimumIntegerDigits = lazyPluralRulesData.minimumIntegerDigits;
60 // Step 8. SetNumberFormatDigitOptions, step 14.
61 internalProps.roundingIncrement = lazyPluralRulesData.roundingIncrement;
63 // Step 8. SetNumberFormatDigitOptions, step 15.
64 internalProps.roundingMode = lazyPluralRulesData.roundingMode;
66 // Step 8. SetNumberFormatDigitOptions, step 16.
67 internalProps.trailingZeroDisplay = lazyPluralRulesData.trailingZeroDisplay;
69 // Step 8. SetNumberFormatDigitOptions, steps 25-26.
70 if ("minimumFractionDigits" in lazyPluralRulesData) {
72 "maximumFractionDigits" in lazyPluralRulesData,
73 "min/max frac digits mismatch"
75 internalProps.minimumFractionDigits =
76 lazyPluralRulesData.minimumFractionDigits;
77 internalProps.maximumFractionDigits =
78 lazyPluralRulesData.maximumFractionDigits;
81 // Step 8. SetNumberFormatDigitOptions, steps 24 and 26.
82 if ("minimumSignificantDigits" in lazyPluralRulesData) {
84 "maximumSignificantDigits" in lazyPluralRulesData,
85 "min/max sig digits mismatch"
87 internalProps.minimumSignificantDigits =
88 lazyPluralRulesData.minimumSignificantDigits;
89 internalProps.maximumSignificantDigits =
90 lazyPluralRulesData.maximumSignificantDigits;
93 // Step 8. SetNumberFormatDigitOptions, steps 26-30.
94 internalProps.roundingPriority = lazyPluralRulesData.roundingPriority;
96 // `pluralCategories` is lazily computed on first access.
97 internalProps.pluralCategories = null;
103 * Returns an object containing the PluralRules internal properties of |obj|.
105 function getPluralRulesInternals(obj) {
106 assert(IsObject(obj), "getPluralRulesInternals called with non-object");
108 intl_GuardToPluralRules(obj) !== null,
109 "getPluralRulesInternals called with non-PluralRules"
112 var internals = getIntlObjectInternals(obj);
114 internals.type === "PluralRules",
115 "bad type escaped getIntlObjectInternals"
118 var internalProps = maybeInternalProperties(internals);
120 return internalProps;
123 internalProps = resolvePluralRulesInternals(internals.lazyData);
124 setInternalProperties(internals, internalProps);
125 return internalProps;
129 * 16.1.2 InitializePluralRules ( pluralRules, locales, options )
131 * Initializes an object as a PluralRules.
133 * This method is complicated a moderate bit by its implementing initialization
134 * as a *lazy* concept. Everything that must happen now, does -- but we defer
135 * all the work we can until the object is actually used as a PluralRules.
136 * This later work occurs in |resolvePluralRulesInternals|; steps not noted
139 * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6
141 function InitializePluralRules(pluralRules, locales, options) {
142 assert(IsObject(pluralRules), "InitializePluralRules called with non-object");
144 intl_GuardToPluralRules(pluralRules) !== null,
145 "InitializePluralRules called with non-PluralRules"
148 // Lazy PluralRules data has the following structure:
151 // requestedLocales: List of locales,
152 // type: "cardinal" / "ordinal",
154 // opt: // opt object computer in InitializePluralRules
156 // localeMatcher: "lookup" / "best fit",
159 // minimumIntegerDigits: integer ∈ [1, 21],
161 // // optional, mutually exclusive with the significant-digits option
162 // minimumFractionDigits: integer ∈ [0, 100],
163 // maximumFractionDigits: integer ∈ [0, 100],
165 // // optional, mutually exclusive with the fraction-digits option
166 // minimumSignificantDigits: integer ∈ [1, 21],
167 // maximumSignificantDigits: integer ∈ [1, 21],
169 // roundingPriority: "auto" / "lessPrecision" / "morePrecision",
171 // trailingZeroDisplay: "auto" / "stripIfInteger",
173 // roundingIncrement: integer ∈ (1, 2, 5,
175 // 100, 200, 250, 500,
176 // 1000, 2000, 2500, 5000),
178 // roundingMode: "ceil" / "floor" / "expand" / "trunc" /
179 // "halfCeil" / "halfFloor" / "halfExpand" / "halfTrunc" / "halfEven",
182 // Note that lazy data is only installed as a final step of initialization,
183 // so every PluralRules lazy data object has *all* these properties, never a
185 var lazyPluralRulesData = std_Object_create(null);
188 var requestedLocales = CanonicalizeLocaleList(locales);
189 lazyPluralRulesData.requestedLocales = requestedLocales;
191 // Step 2. (Inlined call to CoerceOptionsToObject.)
192 if (options === undefined) {
193 options = std_Object_create(null);
195 options = ToObject(options);
199 var opt = new_Record();
200 lazyPluralRulesData.opt = opt;
203 var matcher = GetOption(
207 ["lookup", "best fit"],
210 opt.localeMatcher = matcher;
213 var type = GetOption(
217 ["cardinal", "ordinal"],
220 lazyPluralRulesData.type = type;
223 SetNumberFormatDigitOptions(lazyPluralRulesData, options, 0, 3, "standard");
227 // We've done everything that must be done now: mark the lazy data as fully
228 // computed and install it.
229 initializeIntlObject(pluralRules, "PluralRules", lazyPluralRulesData);
233 * 16.2.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] )
235 * Returns the subset of the given locale list for which this locale list has a
236 * matching (possibly fallback) locale. Locales appear in the same order in the
237 * returned list as in the input list.
239 * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6
241 function Intl_PluralRules_supportedLocalesOf(locales /*, options*/) {
242 var options = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
245 var availableLocales = "PluralRules";
248 var requestedLocales = CanonicalizeLocaleList(locales);
251 return SupportedLocales(availableLocales, requestedLocales, options);
255 * 16.3.3 Intl.PluralRules.prototype.select ( value )
257 * Returns a String value representing the plural category matching
258 * the number passed as value according to the
259 * effective locale and the formatting options of this PluralRules.
261 * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6
263 function Intl_PluralRules_select(value) {
265 var pluralRules = this;
269 !IsObject(pluralRules) ||
270 (pluralRules = intl_GuardToPluralRules(pluralRules)) === null
273 intl_CallPluralRulesMethodIfWrapped,
276 "Intl_PluralRules_select"
281 var n = ToNumber(value);
283 // Ensure the PluralRules internals are resolved.
284 getPluralRulesInternals(pluralRules);
287 return intl_SelectPluralRule(pluralRules, n);
291 * 16.3.4 Intl.PluralRules.prototype.selectRange ( start, end )
293 * Returns a String value representing the plural category matching the input
294 * number range according to the effective locale and the formatting options
295 * of this PluralRules.
297 * ES2024 Intl draft rev 74ca7099f103d143431b2ea422ae640c6f43e3e6
299 function Intl_PluralRules_selectRange(start, end) {
301 var pluralRules = this;
305 !IsObject(pluralRules) ||
306 (pluralRules = intl_GuardToPluralRules(pluralRules)) === null
309 intl_CallPluralRulesMethodIfWrapped,
313 "Intl_PluralRules_selectRange"
318 if (start === undefined || end === undefined) {
320 JSMSG_UNDEFINED_NUMBER,
321 start === undefined ? "start" : "end",
328 var x = ToNumber(start);
331 var y = ToNumber(end);
334 return intl_SelectPluralRuleRange(pluralRules, x, y);
338 * 16.3.5 Intl.PluralRules.prototype.resolvedOptions ( )
340 * Returns the resolved options for a PluralRules object.
342 * ES2024 Intl draft rev a1db4567870dbe505121a4255f1210338757190a
344 function Intl_PluralRules_resolvedOptions() {
346 var pluralRules = this;
350 !IsObject(pluralRules) ||
351 (pluralRules = intl_GuardToPluralRules(pluralRules)) === null
354 intl_CallPluralRulesMethodIfWrapped,
356 "Intl_PluralRules_resolvedOptions"
360 var internals = getPluralRulesInternals(pluralRules);
363 var internalsPluralCategories = internals.pluralCategories;
364 if (internalsPluralCategories === null) {
365 internalsPluralCategories = intl_GetPluralCategories(pluralRules);
366 internals.pluralCategories = internalsPluralCategories;
370 var pluralCategories = [];
371 for (var i = 0; i < internalsPluralCategories.length; i++) {
372 DefineDataProperty(pluralCategories, i, internalsPluralCategories[i]);
377 locale: internals.locale,
378 type: internals.type,
379 minimumIntegerDigits: internals.minimumIntegerDigits,
382 // Min/Max fraction digits are either both present or not present at all.
384 hasOwn("minimumFractionDigits", internals) ===
385 hasOwn("maximumFractionDigits", internals),
386 "minimumFractionDigits is present iff maximumFractionDigits is present"
389 if (hasOwn("minimumFractionDigits", internals)) {
392 "minimumFractionDigits",
393 internals.minimumFractionDigits
397 "maximumFractionDigits",
398 internals.maximumFractionDigits
402 // Min/Max significant digits are either both present or not present at all.
404 hasOwn("minimumSignificantDigits", internals) ===
405 hasOwn("maximumSignificantDigits", internals),
406 "minimumSignificantDigits is present iff maximumSignificantDigits is present"
409 if (hasOwn("minimumSignificantDigits", internals)) {
412 "minimumSignificantDigits",
413 internals.minimumSignificantDigits
417 "maximumSignificantDigits",
418 internals.maximumSignificantDigits
422 DefineDataProperty(result, "pluralCategories", pluralCategories);
423 DefineDataProperty(result, "roundingIncrement", internals.roundingIncrement);
424 DefineDataProperty(result, "roundingMode", internals.roundingMode);
425 DefineDataProperty(result, "roundingPriority", internals.roundingPriority);
428 "trailingZeroDisplay",
429 internals.trailingZeroDisplay