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

Commit f493b39

Browse files
committed
better formatting. fix for most of the issues with ToRawFixed. fix for invalid NaN.
1 parent 1401545 commit f493b39

File tree

2 files changed

+109
-111
lines changed

2 files changed

+109
-111
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "intl",
3-
"version": "1.2.1",
3+
"version": "1.2.0",
44
"description": "Polyfill the ECMA-402 Intl API (except collation)",
55
"main": "index.js",
66
"directories": {

src/11.numberformat.js

+108-110
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ function PartitionNumberPattern(numberFormat, x) {
491491
// 8. Repeat while beginIndex is an integer index into pattern:
492492
while (beginIndex > -1 && beginIndex < length) {
493493
// a. Set endIndex to Call(%StringProto_indexOf%, pattern, "}", beginIndex)
494-
endIndex = pattern.indexOf('}');
494+
endIndex = pattern.indexOf('}', beginIndex);
495495
// a. If endIndex = -1, throw new Error exception.
496496
if (endIndex === -1) throw new Error();
497497
// a. If beginIndex is greater than nextIndex, then:
@@ -514,116 +514,116 @@ function PartitionNumberPattern(numberFormat, x) {
514514
}
515515
// ii. Else if isFinite(x) is false,
516516
else if (!isFinite(x)) {
517-
// 1. Let n be an ILD String value indicating infinity.
518-
let n = ild.infinity;
519-
// 2. Add new part record { [[type]]: "infinity", [[value]]: n } as a new element of the list result.
520-
arrPush.call(result, { '[[type]]': 'infinity', '[[value]]': n });
517+
// 1. Let n be an ILD String value indicating infinity.
518+
let n = ild.infinity;
519+
// 2. Add new part record { [[type]]: "infinity", [[value]]: n } as a new element of the list result.
520+
arrPush.call(result, { '[[type]]': 'infinity', '[[value]]': n });
521+
}
522+
// iii. Else,
523+
else {
524+
// 1. If the value of numberFormat.[[style]] is "percent" and isFinite(x), let x be 100 × x.
525+
if (internal['[[style]]'] === 'percent' && isFinite(x)) x *= 100;
526+
527+
let n;
528+
// 2. If the numberFormat.[[minimumSignificantDigits]] and numberFormat.[[maximumSignificantDigits]] are present, then
529+
if (hop.call(internal, '[[minimumSignificantDigits]]') && hop.call(internal, '[[maximumSignificantDigits]]')) {
530+
// a. Let n be ToRawPrecision(x, numberFormat.[[minimumSignificantDigits]], numberFormat.[[maximumSignificantDigits]]).
531+
n = ToRawPrecision(x, internal['[[minimumSignificantDigits]]'], internal['[[maximumSignificantDigits]]']);
521532
}
522-
// iii. Else,
533+
// 3. Else,
523534
else {
524-
// 1. If the value of numberFormat.[[style]] is "percent" and isFinite(x), let x be 100 × x.
525-
if (internal['[[style]]'] === 'percent' && isFinite(x)) x *= 100;
526-
527-
let n;
528-
// 2. If the numberFormat.[[minimumSignificantDigits]] and numberFormat.[[maximumSignificantDigits]] are present, then
529-
if (hop.call(internal, '[[minimumSignificantDigits]]') && hop.call(internal, '[[maximumSignificantDigits]]')) {
530-
// a. Let n be ToRawPrecision(x, numberFormat.[[minimumSignificantDigits]], numberFormat.[[maximumSignificantDigits]]).
531-
n = ToRawPrecision(x, internal['[[minimumSignificantDigits]]'], internal['[[maximumSignificantDigits]]']);
532-
}
533-
// 3. Else,
534-
else {
535-
// a. Let n be ToRawFixed(x, numberFormat.[[minimumIntegerDigits]], numberFormat.[[minimumFractionDigits]], numberFormat.[[maximumFractionDigits]]).
536-
n = ToRawFixed(x, internal['[[minimumIntegerDigits]]'], internal['[[minimumFractionDigits]]'], internal['[[maximumFractionDigits]]']);
537-
}
538-
// 4. If the value of the numberFormat.[[numberingSystem]] matches one of the values in the "Numbering System" column of Table 2 below, then
539-
if (numSys[nums]) {
540-
// a. Let digits be an array whose 10 String valued elements are the UTF-16 string representations of the 10 digits specified in the "Digits" column of the matching row in Table 2.
541-
let digits = numSys[nums];
542-
// a. Replace each digit in n with the value of digits[digit].
543-
n = String(n).replace(/\d/g, (digit) => {
544-
return digits[digit];
545-
});
546-
}
547-
// 5. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
548-
else n = String(n); // ###TODO###
549-
550-
let integer;
551-
let fraction;
552-
// 6. Let decimalSepIndex be Call(%StringProto_indexOf%, n, ".", 0).
553-
let decimalSepIndex = n.indexOf('.', 0);
554-
// 7. If decimalSepIndex > 0, then:
555-
if (decimalSepIndex > 0) {
556-
// a. Let integer be the substring of n from position 0, inclusive, to position decimalSepIndex, exclusive.
557-
integer = n.substring(0, decimalSepIndex - 1);
558-
// a. Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n.
559-
fraction = n.substring(decimalSepIndex + 1, decimalSepIndex.length);
560-
}
561-
// 8. Else:
562-
else {
563-
// a. Let integer be n.
564-
integer = n;
565-
// a. Let fraction be undefined.
566-
fraction = undefined;
567-
}
568-
// 9. If the value of the numberFormat.[[useGrouping]] is true,
569-
if (internal['[[useGrouping]]'] === true) {
570-
// a. Let groupSepSymbol be the ILND String representing the grouping separator.
571-
let groupSepSymbol = ild.group;
572-
// a. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer.
573-
let groups = new List();
574-
// ----> implementation:
575-
// Primary group represents the group closest to the decimal
576-
let pgSize = data.patterns.primaryGroupSize || 3;
577-
// Secondary group is every other group
578-
let sgSize = data.patterns.secondaryGroupSize || pgSize;
579-
// Group only if necessary
580-
if (integer.length > pgSize) {
581-
// Index of the primary grouping separator
582-
let end = integer.length - pgSize;
583-
// Starting index for our loop
584-
let idx = end % sgSize;
585-
let start = integer.slice(0, idx);
586-
if (start.length) arrPush.call(groups, start);
587-
// Loop to separate into secondary grouping digits
588-
while (idx < end) {
589-
arrPush.call(groups, integer.slice(idx, idx + sgSize));
590-
idx += sgSize;
591-
}
592-
// Add the primary grouping digits
593-
arrPush.call(groups, integer.slice(end));
594-
} else {
595-
arrPush.call(groups, integer);
596-
}
597-
// a. Assert: The number of elements in groups List is greater than 0.
598-
if (groups.length === 0) throw new Error();
599-
// a. Repeat, while groups List is not empty:
600-
while (groups.length) {
601-
// i. Remove the first element from groups and let integerGroup be the value of that element.
602-
let integerGroup = arrShift.call(groups);
603-
// ii. Add new part record { [[type]]: "integer", [[value]]: integerGroup } as a new element of the list result.
604-
arrPush.call(result, { '[[type]]': 'integer', '[[value]]': integerGroup });
605-
// iii. If groups List is not empty, then:
606-
if (groups.length) {
607-
// 1. Add new part record { [[type]]: "group", [[value]]: groupSepSymbol } as a new element of the list result.
608-
arrPush.call(result, { '[[type]]': 'group', '[[value]]': groupSepSymbol });
609-
}
610-
}
535+
// a. Let n be ToRawFixed(x, numberFormat.[[minimumIntegerDigits]], numberFormat.[[minimumFractionDigits]], numberFormat.[[maximumFractionDigits]]).
536+
n = ToRawFixed(x, internal['[[minimumIntegerDigits]]'], internal['[[minimumFractionDigits]]'], internal['[[maximumFractionDigits]]']);
537+
}
538+
// 4. If the value of the numberFormat.[[numberingSystem]] matches one of the values in the "Numbering System" column of Table 2 below, then
539+
if (numSys[nums]) {
540+
// a. Let digits be an array whose 10 String valued elements are the UTF-16 string representations of the 10 digits specified in the "Digits" column of the matching row in Table 2.
541+
let digits = numSys[nums];
542+
// a. Replace each digit in n with the value of digits[digit].
543+
n = String(n).replace(/\d/g, (digit) => {
544+
return digits[digit];
545+
});
546+
}
547+
// 5. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
548+
else n = String(n); // ###TODO###
549+
550+
let integer;
551+
let fraction;
552+
// 6. Let decimalSepIndex be Call(%StringProto_indexOf%, n, ".", 0).
553+
let decimalSepIndex = n.indexOf('.', 0);
554+
// 7. If decimalSepIndex > 0, then:
555+
if (decimalSepIndex > 0) {
556+
// a. Let integer be the substring of n from position 0, inclusive, to position decimalSepIndex, exclusive.
557+
integer = n.substring(0, decimalSepIndex);
558+
// a. Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n.
559+
fraction = n.substring(decimalSepIndex + 1, decimalSepIndex.length);
560+
}
561+
// 8. Else:
562+
else {
563+
// a. Let integer be n.
564+
integer = n;
565+
// a. Let fraction be undefined.
566+
fraction = undefined;
567+
}
568+
// 9. If the value of the numberFormat.[[useGrouping]] is true,
569+
if (internal['[[useGrouping]]'] === true) {
570+
// a. Let groupSepSymbol be the ILND String representing the grouping separator.
571+
let groupSepSymbol = ild.group;
572+
// a. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer.
573+
let groups = new List();
574+
// ----> implementation:
575+
// Primary group represents the group closest to the decimal
576+
let pgSize = data.patterns.primaryGroupSize || 3;
577+
// Secondary group is every other group
578+
let sgSize = data.patterns.secondaryGroupSize || pgSize;
579+
// Group only if necessary
580+
if (integer.length > pgSize) {
581+
// Index of the primary grouping separator
582+
let end = integer.length - pgSize;
583+
// Starting index for our loop
584+
let idx = end % sgSize;
585+
let start = integer.slice(0, idx);
586+
if (start.length) arrPush.call(groups, start);
587+
// Loop to separate into secondary grouping digits
588+
while (idx < end) {
589+
arrPush.call(groups, integer.slice(idx, idx + sgSize));
590+
idx += sgSize;
611591
}
612-
// 10. Else,
613-
else {
614-
// a. Add new part record { [[type]]: "integer", [[value]]: integer } as a new element of the list result.
615-
arrPush.call(result, { '[[type]]': 'integer', '[[value]]': integer });
616-
}
617-
// 11. If fraction is not undefined, then:
618-
if (fraction !== undefined) {
619-
// a. Let decimalSepSymbol be the ILND String representing the decimal separator.
620-
let decimalSepSymbol = ild.decimal;
621-
// a. Add new part record { [[type]]: "decimal", [[value]]: decimalSepSymbol } as a new element of the list result.
622-
arrPush.call(result, { '[[type]]': 'decimal', '[[value]]': decimalSepSymbol });
623-
// a. Add new part record { [[type]]: "fraction", [[value]]: fraction } as a new element of the list result.
624-
arrPush.call(result, { '[[type]]': 'fraction', '[[value]]': fraction });
592+
// Add the primary grouping digits
593+
arrPush.call(groups, integer.slice(end));
594+
} else {
595+
arrPush.call(groups, integer);
596+
}
597+
// a. Assert: The number of elements in groups List is greater than 0.
598+
if (groups.length === 0) throw new Error();
599+
// a. Repeat, while groups List is not empty:
600+
while (groups.length) {
601+
// i. Remove the first element from groups and let integerGroup be the value of that element.
602+
let integerGroup = arrShift.call(groups);
603+
// ii. Add new part record { [[type]]: "integer", [[value]]: integerGroup } as a new element of the list result.
604+
arrPush.call(result, { '[[type]]': 'integer', '[[value]]': integerGroup });
605+
// iii. If groups List is not empty, then:
606+
if (groups.length) {
607+
// 1. Add new part record { [[type]]: "group", [[value]]: groupSepSymbol } as a new element of the list result.
608+
arrPush.call(result, { '[[type]]': 'group', '[[value]]': groupSepSymbol });
625609
}
626610
}
611+
}
612+
// 10. Else,
613+
else {
614+
// a. Add new part record { [[type]]: "integer", [[value]]: integer } as a new element of the list result.
615+
arrPush.call(result, { '[[type]]': 'integer', '[[value]]': integer });
616+
}
617+
// 11. If fraction is not undefined, then:
618+
if (fraction !== undefined) {
619+
// a. Let decimalSepSymbol be the ILND String representing the decimal separator.
620+
let decimalSepSymbol = ild.decimal;
621+
// a. Add new part record { [[type]]: "decimal", [[value]]: decimalSepSymbol } as a new element of the list result.
622+
arrPush.call(result, { '[[type]]': 'decimal', '[[value]]': decimalSepSymbol });
623+
// a. Add new part record { [[type]]: "fraction", [[value]]: fraction } as a new element of the list result.
624+
arrPush.call(result, { '[[type]]': 'fraction', '[[value]]': fraction });
625+
}
626+
}
627627
}
628628
// a. Else if p is equal "plusSign", then:
629629
else if (p === "plusSign") {
@@ -704,7 +704,6 @@ export function FormatNumber(numberFormat, x) {
704704
// 2. Let result be an empty String.
705705
let result = '';
706706
// 3. For each part in parts, do:
707-
console.log(parts);
708707
for (let idx in parts) {
709708
let part = parts[idx];
710709
// a. Set result to a String value produced by concatenating result and part.[[value]].
@@ -805,8 +804,7 @@ function ToRawFixed(x, minInteger, minFraction, maxFraction) {
805804
// 1. Let f be maxFraction.
806805
let f = maxFraction;
807806
// 2. Let n be an integer for which the exact mathematical value of n ÷ 10f – x is as close to zero as possible. If there are two such n, pick the larger n.
808-
let p = Math.pow(10, f) * x; // ###TODO: add description for this variable p
809-
let n = p > Math.floor(p) ? Math.round(p) : p + 1;
807+
let n = Math.round(Math.pow(10, f) * x);
810808
// 3. If n = 0, let m be the String "0". Otherwise, let m be the String consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
811809
let m = (n === 0 ? "0" : (n + '').split('.')[0]);
812810

@@ -825,7 +823,7 @@ function ToRawFixed(x, minInteger, minFraction, maxFraction) {
825823
k = f + 1;
826824
}
827825
// a. Let a be the first k–f characters of m, and let b be the remaining f characters of m.
828-
let a = m.slice(0, k - f), b = m.slice(-(k - f));
826+
let a = m.substring(0, k - f), b = m.substring(k - f, m.length);
829827
// a. Let m be the concatenation of the three Strings a, ".", and b.
830828
m = a + "." + b;
831829
// a. Let int be the number of characters in a.

0 commit comments

Comments
 (0)