Skip to content
This repository was archived by the owner on Apr 14, 2021. It is now read-only.

Commit a0c3b3e

Browse files
zbranieckicaridy
authored andcommitted
Intl.Pluralrules (#262)
* Import pluralrules data * Attach pluralrules file * Make the algorithm work * Implement GetOperands & PluralRuleSelection using make-plural.js * make things work * Import pluralrules data * Attach pluralrules file * Make the algorithm work * make things work * remove hardcoded data * Update to the spec * formatting and comments * Fix make-plural import path * Fix linter complaints and typos * Use plurals locales and let make-plurals format the number
1 parent 5ef821f commit a0c3b3e

File tree

4 files changed

+338
-85
lines changed

4 files changed

+338
-85
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"grunt-curl": "^2.2.0",
4343
"grunt-zip": "^0.17.1",
4444
"jshint": "^2.9.3",
45+
"make-plural": "^4.0.1",
4546
"mkdirp": "^0.5.1",
4647
"object.assign": "^4.0.4",
4748
"rimraf": "^2.5.4",

src/11.numberformat.js

+103-85
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,64 @@ defineProperty(Intl.NumberFormat, 'prototype', {
6666
writable: false
6767
});
6868

69+
/*
70+
* @spec[tc39/ecma402/master/spec/numberformat.html]
71+
* @clause[sec-setnumberformatdigitoptions]
72+
*/
73+
export function /*11.1.1 */SetNumberFormatDigitOptions (intlObj, options, mnfdDefault) {
74+
// 1. Assert: Type(intlObj) is Object and intlObj.[[initializedIntlObject]] is true.
75+
76+
// 2. Assert: Type(options) is Object.
77+
78+
// 3. Assert: type(mnfdDefault) is Number.
79+
80+
// 4. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21, 1).
81+
let mnid = GetNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
82+
83+
// 5. Let mnfd be ? GetNumberOption(options, "minimumFractionDigits", 0, 20, mnfdDefault).
84+
let mnfd = GetNumberOption(options, 'minimumFractionDigits', 0, 20, mnfdDefault);
85+
86+
// 6. Let mxfd be ? GetNumberOption(options, "maximumFractionDigits", mnfd, 20).
87+
let mxfd = GetNumberOption(options, 'maximumFractionDigits', mnfd, 20);
88+
89+
// 7. Let mnsd be ? Get(options, "minimumSignificantDigits").
90+
let mnsd = options.minimumSignificantDigits;
91+
92+
// 8. Let mxsd be ? Get(options, "maximumSignificantDigits").
93+
let mxsd = options.maximumSignificantDigits;
94+
95+
// 9. Set intlObj.[[minimumIntegerDigits]] to mnid.
96+
intlObj['[[minimumIntegerDigits]]'] = mnid;
97+
98+
// 10. Set intlObj.[[minimumFractionDigits]] to mnfd.
99+
intlObj['[[minimumFractionDigits]]'] = mnfd;
100+
101+
// 11. Set intlObj.[[maximumFractionDigits]] to mxfd.
102+
intlObj['[[maximumFractionDigits]]'] = mxfd;
103+
104+
// 12. If mnsd is not undefined or mxsd is not undefined, then
105+
if (mnsd !== undefined || mxsd !== undefined) {
106+
// a. Let mnsd be ? GetNumberOption(options, "minimumSignificantDigits", 1, 21, 1).
107+
mnsd = GetNumberOption(options, "minimumSignificantDigits", 1, 21, 1);
108+
109+
// b. Let mxsd be ? GetNumberOption(options, "maximumSignificantDigits", mnsd, 21, 21).
110+
mxsd = GetNumberOption(options, "maximumSignificantDigits", mnsd, 21, 21);
111+
112+
// c. Set intlObj.[[minimumSignificantDigits]] to mnsd.
113+
intlObj['[[minimumSignificantDigits]]'] = mnsd;
114+
115+
// d. Set intlObj.[[maximumSignificantDigits]] to mxsd.
116+
intlObj['[[maximumSignificantDigits]]'] = mxsd;
117+
}
118+
119+
}
120+
69121
/**
70122
* The abstract operation InitializeNumberFormat accepts the arguments
71123
* numberFormat (which must be an object), locales, and options. It initializes
72124
* numberFormat as a NumberFormat object.
73125
*/
74-
export function /*11.1.1.1 */InitializeNumberFormat (numberFormat, locales, options) {
126+
export function /*11.1.2 */InitializeNumberFormat (numberFormat, locales, options) {
75127
// This will be a internal properties object if we're not already initialized
76128
let internal = getInternalProperties(numberFormat);
77129

@@ -123,13 +175,11 @@ export function /*11.1.1.1 */InitializeNumberFormat (numberFormat, locales, opti
123175
// 8. Set opt.[[localeMatcher]] to matcher.
124176
opt['[[localeMatcher]]'] = matcher;
125177

126-
// 9. Let NumberFormat be the standard built-in object that is the initial value
127-
// of Intl.NumberFormat.
128-
// 10. Let localeData be the value of the [[localeData]] internal property of
178+
// 9. Let localeData be the value of the [[localeData]] internal property of
129179
// NumberFormat.
130180
let localeData = internals.NumberFormat['[[localeData]]'];
131181

132-
// 11. Let r be the result of calling the ResolveLocale abstract operation
182+
// 10. Let r be the result of calling the ResolveLocale abstract operation
133183
// (defined in 9.2.5) with the [[availableLocales]] internal property of
134184
// NumberFormat, requestedLocales, opt, the [[relevantExtensionKeys]]
135185
// internal property of NumberFormat, and localeData.
@@ -138,45 +188,45 @@ export function /*11.1.1.1 */InitializeNumberFormat (numberFormat, locales, opti
138188
opt, internals.NumberFormat['[[relevantExtensionKeys]]'], localeData
139189
);
140190

141-
// 12. Set the [[locale]] internal property of numberFormat to the value of
191+
// 11. Set the [[locale]] internal property of numberFormat to the value of
142192
// r.[[locale]].
143193
internal['[[locale]]'] = r['[[locale]]'];
144194

145-
// 13. Set the [[numberingSystem]] internal property of numberFormat to the value
195+
// 12. Set the [[numberingSystem]] internal property of numberFormat to the value
146196
// of r.[[nu]].
147197
internal['[[numberingSystem]]'] = r['[[nu]]'];
148198

149199
// The specification doesn't tell us to do this, but it's helpful later on
150200
internal['[[dataLocale]]'] = r['[[dataLocale]]'];
151201

152-
// 14. Let dataLocale be the value of r.[[dataLocale]].
202+
// 13. Let dataLocale be the value of r.[[dataLocale]].
153203
let dataLocale = r['[[dataLocale]]'];
154204

155-
// 15. Let s be the result of calling the GetOption abstract operation with the
205+
// 14. Let s be the result of calling the GetOption abstract operation with the
156206
// arguments options, "style", "string", a List containing the three String
157207
// values "decimal", "percent", and "currency", and "decimal".
158208
let s = GetOption(options, 'style', 'string', new List('decimal', 'percent', 'currency'), 'decimal');
159209

160-
// 16. Set the [[style]] internal property of numberFormat to s.
210+
// 15. Set the [[style]] internal property of numberFormat to s.
161211
internal['[[style]]'] = s;
162212

163-
// 17. Let c be the result of calling the GetOption abstract operation with the
213+
// 16. Let c be the result of calling the GetOption abstract operation with the
164214
// arguments options, "currency", "string", undefined, and undefined.
165215
let c = GetOption(options, 'currency', 'string');
166216

167-
// 18. If c is not undefined and the result of calling the
217+
// 17. If c is not undefined and the result of calling the
168218
// IsWellFormedCurrencyCode abstract operation (defined in 6.3.1) with
169219
// argument c is false, then throw a RangeError exception.
170220
if (c !== undefined && !IsWellFormedCurrencyCode(c))
171221
throw new RangeError("'" + c + "' is not a valid currency code");
172222

173-
// 19. If s is "currency" and c is undefined, throw a TypeError exception.
223+
// 18. If s is "currency" and c is undefined, throw a TypeError exception.
174224
if (s === 'currency' && c === undefined)
175225
throw new TypeError('Currency code is required when style is currency');
176226

177227
let cDigits;
178228

179-
// 20. If s is "currency", then
229+
// 19. If s is "currency", then
180230
if (s === 'currency') {
181231
// a. Let c be the result of converting c to upper case as specified in 6.1.
182232
c = c.toUpperCase();
@@ -189,109 +239,77 @@ export function /*11.1.1.1 */InitializeNumberFormat (numberFormat, locales, opti
189239
cDigits = CurrencyDigits(c);
190240
}
191241

192-
// 21. Let cd be the result of calling the GetOption abstract operation with the
242+
// 20. Let cd be the result of calling the GetOption abstract operation with the
193243
// arguments options, "currencyDisplay", "string", a List containing the
194244
// three String values "code", "symbol", and "name", and "symbol".
195245
let cd = GetOption(options, 'currencyDisplay', 'string', new List('code', 'symbol', 'name'), 'symbol');
196246

197-
// 22. If s is "currency", then set the [[currencyDisplay]] internal property of
247+
// 21. If s is "currency", then set the [[currencyDisplay]] internal property of
198248
// numberFormat to cd.
199249
if (s === 'currency')
200250
internal['[[currencyDisplay]]'] = cd;
201251

202-
// 23. Let mnid be the result of calling the GetNumberOption abstract operation
203-
// (defined in 9.2.10) with arguments options, "minimumIntegerDigits", 1, 21,
204-
// and 1.
205-
let mnid = GetNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
206-
207-
// 24. Set the [[minimumIntegerDigits]] internal property of numberFormat to mnid.
208-
internal['[[minimumIntegerDigits]]'] = mnid;
209-
210-
// 25. If s is "currency", then let mnfdDefault be cDigits; else let mnfdDefault
211-
// be 0.
212-
let mnfdDefault = s === 'currency' ? cDigits : 0;
213-
214-
// 26. Let mnfd be the result of calling the GetNumberOption abstract operation
215-
// with arguments options, "minimumFractionDigits", 0, 20, and mnfdDefault.
216-
let mnfd = GetNumberOption(options, 'minimumFractionDigits', 0, 20, mnfdDefault);
217-
218-
// 27. Set the [[minimumFractionDigits]] internal property of numberFormat to mnfd.
219-
internal['[[minimumFractionDigits]]'] = mnfd;
220-
221-
// 28. If s is "currency", then let mxfdDefault be max(mnfd, cDigits); else if s
222-
// is "percent", then let mxfdDefault be max(mnfd, 0); else let mxfdDefault
223-
// be max(mnfd, 3).
224-
let mxfdDefault = s === 'currency' ? Math.max(mnfd, cDigits)
225-
: (s === 'percent' ? Math.max(mnfd, 0) : Math.max(mnfd, 3));
226-
227-
// 29. Let mxfd be the result of calling the GetNumberOption abstract operation
228-
// with arguments options, "maximumFractionDigits", mnfd, 20, and mxfdDefault.
229-
let mxfd = GetNumberOption(options, 'maximumFractionDigits', mnfd, 20, mxfdDefault);
230-
231-
// 30. Set the [[maximumFractionDigits]] internal property of numberFormat to mxfd.
232-
internal['[[maximumFractionDigits]]'] = mxfd;
233-
234-
// 31. Let mnsd be the result of calling the [[Get]] internal method of options
235-
// with argument "minimumSignificantDigits".
236-
let mnsd = options.minimumSignificantDigits;
237-
238-
// 32. Let mxsd be the result of calling the [[Get]] internal method of options
239-
// with argument "maximumSignificantDigits".
240-
let mxsd = options.maximumSignificantDigits;
241-
242-
// 33. If mnsd is not undefined or mxsd is not undefined, then:
243-
if (mnsd !== undefined || mxsd !== undefined) {
244-
// a. Let mnsd be the result of calling the GetNumberOption abstract
245-
// operation with arguments options, "minimumSignificantDigits", 1, 21,
246-
// and 1.
247-
mnsd = GetNumberOption(options, 'minimumSignificantDigits', 1, 21, 1);
248-
249-
// b. Let mxsd be the result of calling the GetNumberOption abstract
250-
// operation with arguments options, "maximumSignificantDigits", mnsd,
251-
// 21, and 21.
252-
mxsd = GetNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
253-
254-
// c. Set the [[minimumSignificantDigits]] internal property of numberFormat
255-
// to mnsd, and the [[maximumSignificantDigits]] internal property of
256-
// numberFormat to mxsd.
257-
internal['[[minimumSignificantDigits]]'] = mnsd;
258-
internal['[[maximumSignificantDigits]]'] = mxsd;
252+
// 22. If s is "currency", then
253+
// a. Let mnfdDefault be cDigits.
254+
// 23. Else,
255+
// a. Let mnfdDefault be 0.
256+
let mnfdDefault = s === "currency" ? cDigits : 0;
257+
258+
// 24. Perform ? SetNumberFormatDigitOptions(numberFormat, options, mnfdDefault).
259+
SetNumberFormatDigitOptions(internal, options, mnfdDefault);
260+
261+
// 25. If numberFormat.[[maximumFractionDigits]] is undefined, then
262+
if (internal['[[maximumFractionDigits]]'] === undefined) {
263+
// a. If s is "currency", then
264+
if (s === 'currency') {
265+
// i. Set numberFormat.[[maximumFractionDigits]] to max(numberFormat.[[minimumFractionDigits]], cDigits).
266+
internal['[[maximumFractionDigits]]'] = Math.max(internal['[[minimumFractionDigits]]'], cDigits);
267+
// b. Else if s is "percent", then
268+
} else if (s === 'percent') {
269+
// i. Set numberFormat.[[maximumFractionDigits]] to max(numberFormat.[[minimumFractionDigits]], 0).
270+
internal['[[maximumFractionDigits]]'] = Math.max(internal['[[minimumFractionDigits]]'], 0);
271+
// c. Else,
272+
} else {
273+
// i. Set numberFormat.[[maximumFractionDigits]] to max(numberFormat.[[minimumFractionDigits]], 3).
274+
internal['[[maximumFractionDigits]]'] = Math.max(internal['[[minimumFractionDigits]]'], 3);
275+
}
259276
}
260-
// 34. Let g be the result of calling the GetOption abstract operation with the
277+
278+
// 26. Let g be the result of calling the GetOption abstract operation with the
261279
// arguments options, "useGrouping", "boolean", undefined, and true.
262280
let g = GetOption(options, 'useGrouping', 'boolean', undefined, true);
263281

264-
// 35. Set the [[useGrouping]] internal property of numberFormat to g.
282+
// 27. Set the [[useGrouping]] internal property of numberFormat to g.
265283
internal['[[useGrouping]]'] = g;
266284

267-
// 36. Let dataLocaleData be the result of calling the [[Get]] internal method of
285+
// 28. Let dataLocaleData be the result of calling the [[Get]] internal method of
268286
// localeData with argument dataLocale.
269287
let dataLocaleData = localeData[dataLocale];
270288

271-
// 37. Let patterns be the result of calling the [[Get]] internal method of
289+
// 29. Let patterns be the result of calling the [[Get]] internal method of
272290
// dataLocaleData with argument "patterns".
273291
let patterns = dataLocaleData.patterns;
274292

275-
// 38. Assert: patterns is an object (see 11.2.3)
293+
// 30. Assert: patterns is an object (see 11.2.3)
276294

277-
// 39. Let stylePatterns be the result of calling the [[Get]] internal method of
295+
// 31. Let stylePatterns be the result of calling the [[Get]] internal method of
278296
// patterns with argument s.
279297
let stylePatterns = patterns[s];
280298

281-
// 40. Set the [[positivePattern]] internal property of numberFormat to the
299+
// 32. Set the [[positivePattern]] internal property of numberFormat to the
282300
// result of calling the [[Get]] internal method of stylePatterns with the
283301
// argument "positivePattern".
284302
internal['[[positivePattern]]'] = stylePatterns.positivePattern;
285303

286-
// 41. Set the [[negativePattern]] internal property of numberFormat to the
304+
// 33. Set the [[negativePattern]] internal property of numberFormat to the
287305
// result of calling the [[Get]] internal method of stylePatterns with the
288306
// argument "negativePattern".
289307
internal['[[negativePattern]]'] = stylePatterns.negativePattern;
290308

291-
// 42. Set the [[boundFormat]] internal property of numberFormat to undefined.
309+
// 34. Set the [[boundFormat]] internal property of numberFormat to undefined.
292310
internal['[[boundFormat]]'] = undefined;
293311

294-
// 43. Set the [[initializedNumberFormat]] internal property of numberFormat to
312+
// 35. Set the [[initializedNumberFormat]] internal property of numberFormat to
295313
// true.
296314
internal['[[initializedNumberFormat]]'] = true;
297315

@@ -302,7 +320,7 @@ export function /*11.1.1.1 */InitializeNumberFormat (numberFormat, locales, opti
302320
// Restore the RegExp properties
303321
regexpRestore();
304322

305-
// Return the newly initialised object
323+
// 36. Return the newly initialised object
306324
return numberFormat;
307325
}
308326

@@ -464,7 +482,7 @@ function FormatNumberToParts(numberFormat, x) {
464482
* @spec[tc39/ecma402/master/spec/numberformat.html]
465483
* @clause[sec-formatnumberstring]
466484
*/
467-
function FormatNumberToString(numberFormat, x) {
485+
export function FormatNumberToString(numberFormat, x) {
468486
let internal = getInternalProperties(numberFormat);
469487
let result;
470488

0 commit comments

Comments
 (0)