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

Commit 6ed6867

Browse files
zbranieckicaridy
authored andcommitted
Separate out NumberFormatToString (#230)
1 parent 9ad9a12 commit 6ed6867

File tree

1 file changed

+113
-91
lines changed

1 file changed

+113
-91
lines changed

src/11.numberformat.js

+113-91
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ Object.defineProperty(Intl.NumberFormat.prototype, 'formatToParts', {
432432
});
433433

434434
/*
435-
* @spec[stasm/ecma402/number-format-to-parts/spec/numberformat.html]
435+
* @spec[tc39/ecma402/master/spec/numberformat.html]
436436
* @clause[sec-formatnumbertoparts]
437437
*/
438438
function FormatNumberToParts(numberFormat, x) {
@@ -461,7 +461,37 @@ function FormatNumberToParts(numberFormat, x) {
461461
}
462462

463463
/*
464-
* @spec[stasm/ecma402/number-format-to-parts/spec/numberformat.html]
464+
* @spec[tc39/ecma402/master/spec/numberformat.html]
465+
* @clause[sec-formatnumberstring]
466+
*/
467+
function FormatNumberToString(numberFormat, x) {
468+
let internal = getInternalProperties(numberFormat);
469+
let result;
470+
471+
// 1. Assert: numberFormat.[[initializedIntlObject]] is true.
472+
473+
// 2. If the numberFormat.[[minimumSignificantDigits]] and numberFormat.[[maximumSignificantDigits]] are present, then
474+
if (hop.call(internal, '[[minimumSignificantDigits]]') &&
475+
hop.call(internal, '[[maximumSignificantDigits]]')) {
476+
// a. Let result be ToRawPrecision(x, numberFormat.[[minimumSignificantDigits]], numberFormat.[[maximumSignificantDigits]]).
477+
result = ToRawPrecision(x,
478+
internal['[[minimumSignificantDigits]]'],
479+
internal['[[maximumSignificantDigits]]']);
480+
}
481+
// 3. Else,
482+
else {
483+
// a. Let result be ToRawFixed(x, numberFormat.[[minimumIntegerDigits]], numberFormat.[[minimumFractionDigits]], numberFormat.[[maximumFractionDigits]]).
484+
result = ToRawFixed(x,
485+
internal['[[minimumIntegerDigits]]'],
486+
internal['[[minimumFractionDigits]]'],
487+
internal['[[maximumFractionDigits]]']);
488+
}
489+
// 4. Return result.
490+
return result;
491+
}
492+
493+
/*
494+
* @spec[tc39/ecma402/master/spec/numberformat.html]
465495
* @clause[sec-partitionnumberpattern]
466496
*/
467497
function PartitionNumberPattern(numberFormat, x) {
@@ -477,7 +507,7 @@ function PartitionNumberPattern(numberFormat, x) {
477507
if (!isNaN(x) && x < 0) {
478508
// a. Let x be -x.
479509
x = -x;
480-
// a. Let pattern be the value of numberFormat.[[negativePattern]].
510+
// b. Let pattern be the value of numberFormat.[[negativePattern]].
481511
pattern = internal['[[negativePattern]]'];
482512
}
483513
// 2. Else,
@@ -499,18 +529,18 @@ function PartitionNumberPattern(numberFormat, x) {
499529
while (beginIndex > -1 && beginIndex < length) {
500530
// a. Set endIndex to Call(%StringProto_indexOf%, pattern, "}", beginIndex)
501531
endIndex = pattern.indexOf('}', beginIndex);
502-
// a. If endIndex = -1, throw new Error exception.
532+
// b. If endIndex = -1, throw new Error exception.
503533
if (endIndex === -1) throw new Error();
504-
// a. If beginIndex is greater than nextIndex, then:
534+
// c. If beginIndex is greater than nextIndex, then:
505535
if (beginIndex > nextIndex) {
506536
// i. Let literal be a substring of pattern from position nextIndex, inclusive, to position beginIndex, exclusive.
507537
let literal = pattern.substring(nextIndex, beginIndex);
508538
// ii. Add new part record { [[type]]: "literal", [[value]]: literal } as a new element of the list result.
509539
arrPush.call(result, { '[[type]]': 'literal', '[[value]]': literal });
510540
}
511-
// a. Let p be the substring of pattern from position beginIndex, exclusive, to position endIndex, exclusive.
541+
// d. Let p be the substring of pattern from position beginIndex, exclusive, to position endIndex, exclusive.
512542
let p = pattern.substring(beginIndex + 1, endIndex);
513-
// a. If p is equal "number", then:
543+
// e. If p is equal "number", then:
514544
if (p === "number") {
515545
// i. If x is NaN,
516546
if (isNaN(x)) {
@@ -528,21 +558,13 @@ function PartitionNumberPattern(numberFormat, x) {
528558
}
529559
// iii. Else,
530560
else {
531-
// 1. If the value of numberFormat.[[style]] is "percent" and isFinite(x), let x be 100 × x.
532-
if (internal['[[style]]'] === 'percent' && isFinite(x)) x *= 100;
533-
534-
let n;
535-
// 2. If the numberFormat.[[minimumSignificantDigits]] and numberFormat.[[maximumSignificantDigits]] are present, then
536-
if (hop.call(internal, '[[minimumSignificantDigits]]') && hop.call(internal, '[[maximumSignificantDigits]]')) {
537-
// a. Let n be ToRawPrecision(x, numberFormat.[[minimumSignificantDigits]], numberFormat.[[maximumSignificantDigits]]).
538-
n = ToRawPrecision(x, internal['[[minimumSignificantDigits]]'], internal['[[maximumSignificantDigits]]']);
539-
}
540-
// 3. Else,
541-
else {
542-
// a. Let n be ToRawFixed(x, numberFormat.[[minimumIntegerDigits]], numberFormat.[[minimumFractionDigits]], numberFormat.[[maximumFractionDigits]]).
543-
n = ToRawFixed(x, internal['[[minimumIntegerDigits]]'], internal['[[minimumFractionDigits]]'], internal['[[maximumFractionDigits]]']);
544-
}
545-
// 4. If the value of the numberFormat.[[numberingSystem]] matches one of the values in the "Numbering System" column of Table 2 below, then
561+
// 1. If numberFormat.[[style]] is "percent", let x be 100 × x.
562+
if (internal['[[style]]'] === 'percent') x *= 100;
563+
564+
// 2. Let n be FormatNumberToString(numberFormat, x).
565+
let n = FormatNumberToString(numberFormat, x);
566+
567+
// 3. If the numberFormat.[[numberingSystem]] matches one of the values in the "Numbering System" column of Table 3 below, then
546568
if (numSys[nums]) {
547569
// 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.
548570
let digits = numSys[nums];
@@ -551,32 +573,32 @@ function PartitionNumberPattern(numberFormat, x) {
551573
return digits[digit];
552574
});
553575
}
554-
// 5. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
576+
// 4. Else use an implementation dependent algorithm to map n to the appropriate representation of n in the given numbering system.
555577
else n = String(n); // ###TODO###
556578

557579
let integer;
558580
let fraction;
559-
// 6. Let decimalSepIndex be Call(%StringProto_indexOf%, n, ".", 0).
581+
// 5. Let decimalSepIndex be Call(%StringProto_indexOf%, n, ".", 0).
560582
let decimalSepIndex = n.indexOf('.', 0);
561-
// 7. If decimalSepIndex > 0, then:
583+
// 6. If decimalSepIndex > 0, then:
562584
if (decimalSepIndex > 0) {
563585
// a. Let integer be the substring of n from position 0, inclusive, to position decimalSepIndex, exclusive.
564586
integer = n.substring(0, decimalSepIndex);
565-
// a. Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n.
587+
// b. Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n.
566588
fraction = n.substring(decimalSepIndex + 1, decimalSepIndex.length);
567589
}
568-
// 8. Else:
590+
// 7. Else:
569591
else {
570592
// a. Let integer be n.
571593
integer = n;
572-
// a. Let fraction be undefined.
594+
// b. Let fraction be undefined.
573595
fraction = undefined;
574596
}
575-
// 9. If the value of the numberFormat.[[useGrouping]] is true,
597+
// 8. If the value of the numberFormat.[[useGrouping]] is true,
576598
if (internal['[[useGrouping]]'] === true) {
577599
// a. Let groupSepSymbol be the ILND String representing the grouping separator.
578600
let groupSepSymbol = ild.group;
579-
// 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.
601+
// b. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer.
580602
let groups = [];
581603
// ----> implementation:
582604
// Primary group represents the group closest to the decimal
@@ -601,9 +623,9 @@ function PartitionNumberPattern(numberFormat, x) {
601623
} else {
602624
arrPush.call(groups, integer);
603625
}
604-
// a. Assert: The number of elements in groups List is greater than 0.
626+
// c. Assert: The number of elements in groups List is greater than 0.
605627
if (groups.length === 0) throw new Error();
606-
// a. Repeat, while groups List is not empty:
628+
// d. Repeat, while groups List is not empty:
607629
while (groups.length) {
608630
// i. Remove the first element from groups and let integerGroup be the value of that element.
609631
let integerGroup = arrShift.call(groups);
@@ -616,93 +638,93 @@ function PartitionNumberPattern(numberFormat, x) {
616638
}
617639
}
618640
}
619-
// 10. Else,
641+
// 9. Else,
620642
else {
621643
// a. Add new part record { [[type]]: "integer", [[value]]: integer } as a new element of the list result.
622644
arrPush.call(result, { '[[type]]': 'integer', '[[value]]': integer });
623645
}
624-
// 11. If fraction is not undefined, then:
646+
// 10. If fraction is not undefined, then:
625647
if (fraction !== undefined) {
626648
// a. Let decimalSepSymbol be the ILND String representing the decimal separator.
627649
let decimalSepSymbol = ild.decimal;
628-
// a. Add new part record { [[type]]: "decimal", [[value]]: decimalSepSymbol } as a new element of the list result.
650+
// b. Add new part record { [[type]]: "decimal", [[value]]: decimalSepSymbol } as a new element of the list result.
629651
arrPush.call(result, { '[[type]]': 'decimal', '[[value]]': decimalSepSymbol });
630-
// a. Add new part record { [[type]]: "fraction", [[value]]: fraction } as a new element of the list result.
652+
// c. Add new part record { [[type]]: "fraction", [[value]]: fraction } as a new element of the list result.
631653
arrPush.call(result, { '[[type]]': 'fraction', '[[value]]': fraction });
632654
}
633655
}
634656
}
635-
// a. Else if p is equal "plusSign", then:
657+
// f. Else if p is equal "plusSign", then:
636658
else if (p === "plusSign") {
637-
// i. Let plusSignSymbol be the ILND String representing the plus sign.
638-
let plusSignSymbol = ild.plusSign;
639-
// ii. Add new part record { [[type]]: "plusSign", [[value]]: plusSignSymbol } as a new element of the list result.
640-
arrPush.call(result, { '[[type]]': 'plusSign', '[[value]]': plusSignSymbol });
659+
// i. Let plusSignSymbol be the ILND String representing the plus sign.
660+
let plusSignSymbol = ild.plusSign;
661+
// ii. Add new part record { [[type]]: "plusSign", [[value]]: plusSignSymbol } as a new element of the list result.
662+
arrPush.call(result, { '[[type]]': 'plusSign', '[[value]]': plusSignSymbol });
663+
}
664+
// g. Else if p is equal "minusSign", then:
665+
else if (p === "minusSign") {
666+
// i. Let minusSignSymbol be the ILND String representing the minus sign.
667+
let minusSignSymbol = ild.minusSign;
668+
// ii. Add new part record { [[type]]: "minusSign", [[value]]: minusSignSymbol } as a new element of the list result.
669+
arrPush.call(result, { '[[type]]': 'minusSign', '[[value]]': minusSignSymbol });
670+
}
671+
// h. Else if p is equal "percentSign" and numberFormat.[[style]] is "percent", then:
672+
else if (p === "percentSign" && internal['[[style]]'] === "percent") {
673+
// i. Let percentSignSymbol be the ILND String representing the percent sign.
674+
let percentSignSymbol = ild.percentSign;
675+
// ii. Add new part record { [[type]]: "percentSign", [[value]]: percentSignSymbol } as a new element of the list result.
676+
arrPush.call(result, { '[[type]]': 'literal', '[[value]]': percentSignSymbol });
677+
}
678+
// i. Else if p is equal "currency" and numberFormat.[[style]] is "currency", then:
679+
else if (p === "currency" && internal['[[style]]'] === "currency") {
680+
// i. Let currency be the value of numberFormat.[[currency]].
681+
let currency = internal['[[currency]]'];
682+
683+
let cd;
684+
685+
// iii. If numberFormat.[[currencyDisplay]] is "code", then
686+
if (internal['[[currencyDisplay]]'] === "code") {
687+
// 1. Let cd be currency.
688+
cd = currency;
641689
}
642-
// a. Else if p is equal "minusSign", then:
643-
else if (p === "minusSign") {
644-
// i. Let minusSignSymbol be the ILND String representing the minus sign.
645-
let minusSignSymbol = ild.minusSign;
646-
// ii. Add new part record { [[type]]: "minusSign", [[value]]: minusSignSymbol } as a new element of the list result.
647-
arrPush.call(result, { '[[type]]': 'minusSign', '[[value]]': minusSignSymbol });
648-
}
649-
// a. Else if p is equal "percentSign" and numberFormat.[[style]] is "percent", then:
650-
else if (p === "percentSign" && internal['[[style]]'] === "percent") {
651-
// i. Let percentSignSymbol be the ILND String representing the percent sign.
652-
let percentSignSymbol = ild.percentSign;
653-
// ii. Add new part record { [[type]]: "percentSign", [[value]]: percentSignSymbol } as a new element of the list result.
654-
arrPush.call(result, { '[[type]]': 'literal', '[[value]]': percentSignSymbol });
655-
}
656-
// a. Else if p is equal "currency" and numberFormat.[[style]] is "currency", then:
657-
else if (p === "currency" && internal['[[style]]'] === "currency") {
658-
// i. Let currency be the value of numberFormat.[[currency]].
659-
let currency = internal['[[currency]]'];
660-
661-
let cd;
662-
663-
// ii. If numberFormat.[[currencyDisplay]] is "code", then
664-
if (internal['[[currencyDisplay]]'] === "code") {
665-
// 1. Let cd be currency.
666-
cd = currency;
667-
}
668-
// iii. Else if numberFormat.[[currencyDisplay]] is "symbol", then
669-
else if (internal['[[currencyDisplay]]'] === "symbol") {
670-
// 1. Let cd be an ILD string representing currency in short form. If the implementation does not have such a representation of currency, use currency itself.
671-
cd = data.currencies[currency] || currency;
672-
}
673-
// iv. Else if numberFormat.[[currencyDisplay]] is "name", then
674-
else if (internal['[[currencyDisplay]]'] === "name") {
675-
// 1. Let cd be an ILD string representing currency in long form. If the implementation does not have such a representation of currency, then use currency itself.
676-
cd = currency;
677-
}
678-
// v. Add new part record { [[type]]: "currency", [[value]]: cd } as a new element of the list result.
679-
arrPush.call(result, { '[[type]]': 'currency', '[[value]]': cd });
680-
}
681-
// a. Else,
682-
else {
683-
// i. Let literal be the substring of pattern from position beginIndex, inclusive, to position endIndex, inclusive.
684-
let literal = pattern.substring(beginIndex, endIndex);
685-
// ii. Add new part record { [[type]]: "literal", [[value]]: literal } as a new element of the list result.
686-
arrPush.call(result, { '[[type]]': 'literal', '[[value]]': literal });
687-
}
688-
// a. Set nextIndex to endIndex + 1.
690+
// iv. Else if numberFormat.[[currencyDisplay]] is "symbol", then
691+
else if (internal['[[currencyDisplay]]'] === "symbol") {
692+
// 1. Let cd be an ILD string representing currency in short form. If the implementation does not have such a representation of currency, use currency itself.
693+
cd = data.currencies[currency] || currency;
694+
}
695+
// v. Else if numberFormat.[[currencyDisplay]] is "name", then
696+
else if (internal['[[currencyDisplay]]'] === "name") {
697+
// 1. Let cd be an ILD string representing currency in long form. If the implementation does not have such a representation of currency, then use currency itself.
698+
cd = currency;
699+
}
700+
// vi. Add new part record { [[type]]: "currency", [[value]]: cd } as a new element of the list result.
701+
arrPush.call(result, { '[[type]]': 'currency', '[[value]]': cd });
702+
}
703+
// j. Else,
704+
else {
705+
// i. Let literal be the substring of pattern from position beginIndex, inclusive, to position endIndex, inclusive.
706+
let literal = pattern.substring(beginIndex, endIndex);
707+
// ii. Add new part record { [[type]]: "literal", [[value]]: literal } as a new element of the list result.
708+
arrPush.call(result, { '[[type]]': 'literal', '[[value]]': literal });
709+
}
710+
// k. Set nextIndex to endIndex + 1.
689711
nextIndex = endIndex + 1;
690-
// a. Set beginIndex to Call(%StringProto_indexOf%, pattern, "{", nextIndex)
712+
// l. Set beginIndex to Call(%StringProto_indexOf%, pattern, "{", nextIndex)
691713
beginIndex = pattern.indexOf('{', nextIndex);
692714
}
693715
// 9. If nextIndex is less than length, then:
694716
if (nextIndex < length) {
695717
// a. Let literal be the substring of pattern from position nextIndex, inclusive, to position length, exclusive.
696718
let literal = pattern.substring(nextIndex, length);
697-
// a. Add new part record { [[type]]: "literal", [[value]]: literal } as a new element of the list result.
719+
// b. Add new part record { [[type]]: "literal", [[value]]: literal } as a new element of the list result.
698720
arrPush.call(result, { '[[type]]': 'literal', '[[value]]': literal });
699721
}
700722
// 10. Return result.
701723
return result;
702724
}
703725

704726
/*
705-
* @spec[stasm/ecma402/number-format-to-parts/spec/numberformat.html]
727+
* @spec[tc39/ecma402/master/spec/numberformat.html]
706728
* @clause[sec-formatnumber]
707729
*/
708730
export function FormatNumber(numberFormat, x) {

0 commit comments

Comments
 (0)