src/third_party/mozjs/extract/js/src/builtin/intl/NumberFormat.js
/**
 * Initializes an object as a NumberFormat.
 *
 * This method is complicated a moderate bit by its implementing initialization
 * as a *lazy* concept.  Everything that must happen now, does -- but we defer
 * all the work we can until the object is actually used as a NumberFormat.
 * This later work occurs in |resolveNumberFormatInternals|; steps not noted
 * here occur there.
 *
 * Spec: ECMAScript Internationalization API Specification, 11.1.2.
 */
Initializes an object as a NumberFormat.
This method is complicated a moderate bit by its implementing initialization
as a *lazy* concept.  Everything that must happen now, does -- but we defer
all the work we can until the object is actually used as a NumberFormat.
This later work occurs in |resolveNumberFormatInternals|; steps not noted
here occur there.

ECMAScript Internationalization API Specification, 11.1.2.
Initializes an object as a NumberFormat . This method is complicated a moderate bit by its implementing initialization as a * lazy * concept . Everything that must happen now does -- but we defer all the work we can until the object is actually used as a NumberFormat . This later work occurs in |resolveNumberFormatInternals| ; steps not noted here occur there . ECMAScript Internationalization API Specification 11 . 1 . 2 .
function InitializeNumberFormat(numberFormat, thisValue, locales, options) {
    assert(IsObject(numberFormat), "InitializeNumberFormat called with non-object");
    assert(intl_GuardToNumberFormat(numberFormat) !== null,
           "InitializeNumberFormat called with non-NumberFormat");
       {
         requestedLocales: List of locales,
         style: "decimal" / "percent" / "currency" / "unit",
          fields present only if style === "currency":
         currency: a well-formed currency code (IsWellFormedCurrencyCode),
         currencyDisplay: "code" / "symbol" / "narrowSymbol" / "name",
         currencySign: "standard" / "accounting",
          fields present only if style === "unit":
         unit: a well-formed unit identifier (IsWellFormedUnitIdentifier),
         unitDisplay: "short" / "narrow" / "long",
         opt:  opt object computed in InitializeNumberFormat
           {
             localeMatcher: "lookup" / "best fit",
             nu: string matching a Unicode extension type,  optional
           }
         minimumIntegerDigits: integer ∈ [1, 21],
          optional, mutually exclusive with the significant-digits option
         minimumFractionDigits: integer ∈ [0, 20],
         maximumFractionDigits: integer ∈ [0, 20],
          optional, mutually exclusive with the fraction-digits option
         minimumSignificantDigits: integer ∈ [1, 21],
         maximumSignificantDigits: integer ∈ [1, 21],
         useGrouping: true / false,
         notation: "standard" / "scientific" / "engineering" / "compact",
          optional, if notation is "compact"
         compactDisplay: "short" / "long",
         signDisplay: "auto" / "never" / "always" / "exceptZero",
       }
     Note that lazy data is only installed as a final step of initialization,
     so every NumberFormat lazy data object has *all* these properties, never a
     subset of them.
    var lazyNumberFormatData = std_Object_create(null);
     Step 1.
    var requestedLocales = CanonicalizeLocaleList(locales);
    lazyNumberFormatData.requestedLocales = requestedLocales;
     Steps 2-3.
     If we ever need more speed here at startup, we should try to detect the
     case where |options === undefined| and then directly use the default
     value for each option.  For now, just keep it simple.
    if (options === undefined)
        options = std_Object_create(null);
    else
        options = ToObject(options);
     Compute options that impact interpretation of locale.
     Step 4.
    var opt = new_Record();
    lazyNumberFormatData.opt = opt;
     Steps 5-6.
    var matcher = GetOption(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit");
    opt.localeMatcher = matcher;
    var numberingSystem = GetOption(options, "numberingSystem", "string", undefined, undefined);
    if (numberingSystem !== undefined) {
        numberingSystem = intl_ValidateAndCanonicalizeUnicodeExtensionType(numberingSystem,
                                                                           "numberingSystem",
                                                                           "nu");
    }
    opt.nu = numberingSystem;
     Compute formatting options.
     Step 12.
    var style = GetOption(options, "style", "string", ["decimal", "percent", "currency", "unit"],
                          "decimal");
    lazyNumberFormatData.style = style;
     Steps 14-17.
    var currency = GetOption(options, "currency", "string", undefined, undefined);
     Per the Intl.NumberFormat Unified API Proposal, this check should only
     happen for |style === "currency"|, which seems inconsistent, given that
     we normally validate all options when present, even the ones which are
     unused.
     TODO: File issue at <https:github.com/tc39/proposal-unified-intl-numberformat>.
    if (currency !== undefined && !IsWellFormedCurrencyCode(currency))
        ThrowRangeError(JSMSG_INVALID_CURRENCY_CODE, currency);
    var cDigits;
    if (style === "currency") {
        if (currency === undefined)
            ThrowTypeError(JSMSG_UNDEFINED_CURRENCY);
         Steps 19.a-c.
        currency = toASCIIUpperCase(currency);
        lazyNumberFormatData.currency = currency;
        cDigits = CurrencyDigits(currency);
    }
     Step 18.
    var currencyDisplay = GetOption(options, "currencyDisplay", "string",
                                    ["code", "symbol", "narrowSymbol", "name"], "symbol");
    if (style === "currency")
        lazyNumberFormatData.currencyDisplay = currencyDisplay;
     Intl.NumberFormat Unified API Proposal
    var currencySign = GetOption(options, "currencySign", "string", ["standard", "accounting"],
                                 "standard");
    if (style === "currency")
        lazyNumberFormatData.currencySign = currencySign;
     Intl.NumberFormat Unified API Proposal
    var unit = GetOption(options, "unit", "string", undefined, undefined);
     Aligned with |currency| check from above, see note about spec issue there.
    if (unit !== undefined && !IsWellFormedUnitIdentifier(unit))
        ThrowRangeError(JSMSG_INVALID_UNIT_IDENTIFIER, unit);
    var unitDisplay = GetOption(options, "unitDisplay", "string",
                                ["short", "narrow", "long"], "short");
    if (style === "unit") {
        if (unit === undefined)
            ThrowTypeError(JSMSG_UNDEFINED_UNIT);
        lazyNumberFormatData.unit = unit;
        lazyNumberFormatData.unitDisplay = unitDisplay;
    }
     Steps 20-21.
    var mnfdDefault, mxfdDefault;
    if (style === "currency") {
        mnfdDefault = cDigits;
        mxfdDefault = cDigits;
    } else {
        mnfdDefault = 0;
        mxfdDefault = style === "percent" ? 0 : 3;
    }
     Intl.NumberFormat Unified API Proposal
    var notation = GetOption(options, "notation", "string",
                             ["standard", "scientific", "engineering", "compact"], "standard");
    lazyNumberFormatData.notation = notation;
     Step 22.
    SetNumberFormatDigitOptions(lazyNumberFormatData, options, mnfdDefault, mxfdDefault, notation);
     Intl.NumberFormat Unified API Proposal
    var compactDisplay = GetOption(options, "compactDisplay", "string",
                                   ["short", "long"], "short");
    if (notation === "compact")
        lazyNumberFormatData.compactDisplay = compactDisplay;
     Steps 23.
    var useGrouping = GetOption(options, "useGrouping", "boolean", undefined, true);
    lazyNumberFormatData.useGrouping = useGrouping;
     Intl.NumberFormat Unified API Proposal
    var signDisplay = GetOption(options, "signDisplay", "string",
                                ["auto", "never", "always", "exceptZero"], "auto");
    lazyNumberFormatData.signDisplay = signDisplay;
     Step 31.
     We've done everything that must be done now: mark the lazy data as fully
     computed and install it.
    initializeIntlObject(numberFormat, "NumberFormat", lazyNumberFormatData);
     11.2.1, steps 4-5.
    if (numberFormat !== thisValue &&
        callFunction(std_Object_isPrototypeOf, GetBuiltinPrototype("NumberFormat"), thisValue))
    {
        DefineDataProperty(thisValue, intlFallbackSymbol(), numberFormat,
                           ATTR_NONENUMERABLE | ATTR_NONCONFIGURABLE | ATTR_NONWRITABLE);
        return thisValue;
    }
     11.2.1, step 6.
    return numberFormat;
}
function InitializeNumberFormat ( numberFormat , thisValue , locales , options ) { assert ( IsObject ( numberFormat ) , "InitializeNumberFormat called with non-object" ) ; assert ( intl_GuardToNumberFormat ( numberFormat ) !== null , "InitializeNumberFormat called with non-NumberFormat" ) ; var lazyNumberFormatData = std_Object_create ( null ) ; var requestedLocales = CanonicalizeLocaleList ( locales ) ; lazyNumberFormatData . requestedLocales = requestedLocales ; if ( options === undefined ) options = std_Object_create ( null ) ; else options = ToObject ( options ) ; var opt = new_Record ( ) ; lazyNumberFormatData . opt = opt ; var matcher = GetOption ( options , "localeMatcher" , "string" , [ "lookup" , "best fit" ] , "best fit" ) ; opt . localeMatcher = matcher ; var numberingSystem = GetOption ( options , "numberingSystem" , "string" , undefined , undefined ) ; if ( numberingSystem !== undefined ) { numberingSystem = intl_ValidateAndCanonicalizeUnicodeExtensionType ( numberingSystem , "numberingSystem" , "nu" ) ; } opt . nu = numberingSystem ; var style = GetOption ( options , "style" , "string" , [ "decimal" , "percent" , "currency" , "unit" ] , "decimal" ) ; lazyNumberFormatData . style = style ; var currency = GetOption ( options , "currency" , "string" , undefined , undefined ) ; if ( currency !== undefined && ! IsWellFormedCurrencyCode ( currency ) ) ThrowRangeError ( JSMSG_INVALID_CURRENCY_CODE , currency ) ; var cDigits ; if ( style === "currency" ) { if ( currency === undefined ) ThrowTypeError ( JSMSG_UNDEFINED_CURRENCY ) ; currency = toASCIIUpperCase ( currency ) ; lazyNumberFormatData . currency = currency ; cDigits = CurrencyDigits ( currency ) ; } var currencyDisplay = GetOption ( options , "currencyDisplay" , "string" , [ "code" , "symbol" , "narrowSymbol" , "name" ] , "symbol" ) ; if ( style === "currency" ) lazyNumberFormatData . currencyDisplay = currencyDisplay ; var currencySign = GetOption ( options , "currencySign" , "string" , [ "standard" , "accounting" ] , "standard" ) ; if ( style === "currency" ) lazyNumberFormatData . currencySign = currencySign ; var unit = GetOption ( options , "unit" , "string" , undefined , undefined ) ; if ( unit !== undefined && ! IsWellFormedUnitIdentifier ( unit ) ) ThrowRangeError ( JSMSG_INVALID_UNIT_IDENTIFIER , unit ) ; var unitDisplay = GetOption ( options , "unitDisplay" , "string" , [ "short" , "narrow" , "long" ] , "short" ) ; if ( style === "unit" ) { if ( unit === undefined ) ThrowTypeError ( JSMSG_UNDEFINED_UNIT ) ; lazyNumberFormatData . unit = unit ; lazyNumberFormatData . unitDisplay = unitDisplay ; } var mnfdDefault , mxfdDefault ; if ( style === "currency" ) { mnfdDefault = cDigits ; mxfdDefault = cDigits ; } else { mnfdDefault = 0 ; mxfdDefault = style === "percent" ? 0 : 3 ; } var notation = GetOption ( options , "notation" , "string" , [ "standard" , "scientific" , "engineering" , "compact" ] , "standard" ) ; lazyNumberFormatData . notation = notation ; SetNumberFormatDigitOptions ( lazyNumberFormatData , options , mnfdDefault , mxfdDefault , notation ) ; var compactDisplay = GetOption ( options , "compactDisplay" , "string" , [ "short" , "long" ] , "short" ) ; if ( notation === "compact" ) lazyNumberFormatData . compactDisplay = compactDisplay ; var useGrouping = GetOption ( options , "useGrouping" , "boolean" , undefined , true ) ; lazyNumberFormatData . useGrouping = useGrouping ; var signDisplay = GetOption ( options , "signDisplay" , "string" , [ "auto" , "never" , "always" , "exceptZero" ] , "auto" ) ; lazyNumberFormatData . signDisplay = signDisplay ; initializeIntlObject ( numberFormat , "NumberFormat" , lazyNumberFormatData ) ; if ( numberFormat !== thisValue && callFunction ( std_Object_isPrototypeOf , GetBuiltinPrototype ( "NumberFormat" ) , thisValue ) ) { DefineDataProperty ( thisValue , intlFallbackSymbol ( ) , numberFormat , ATTR_NONENUMERABLE | ATTR_NONCONFIGURABLE | ATTR_NONWRITABLE ) ; return thisValue ; } return numberFormat ; }
Initializes an object as a NumberFormat.
Initializes an object as a NumberFormat .
// Lazy NumberFormat data has the following structure: // //   { //     requestedLocales: List of locales, //     style: "decimal" / "percent" / "currency" / "unit", // //     // fields present only if style === "currency": //     currency: a well-formed currency code (IsWellFormedCurrencyCode), //     currencyDisplay: "code" / "symbol" / "narrowSymbol" / "name", //     currencySign: "standard" / "accounting", // //     // fields present only if style === "unit": //     unit: a well-formed unit identifier (IsWellFormedUnitIdentifier), //     unitDisplay: "short" / "narrow" / "long", // //     opt: // opt object computed in InitializeNumberFormat //       { //         localeMatcher: "lookup" / "best fit", // //         nu: string matching a Unicode extension type, // optional //       } // //     minimumIntegerDigits: integer ∈ [1, 21], // //     // optional, mutually exclusive with the significant-digits option //     minimumFractionDigits: integer ∈ [0, 20], //     maximumFractionDigits: integer ∈ [0, 20], // //     // optional, mutually exclusive with the fraction-digits option //     minimumSignificantDigits: integer ∈ [1, 21], //     maximumSignificantDigits: integer ∈ [1, 21], // //     useGrouping: true / false, // //     notation: "standard" / "scientific" / "engineering" / "compact", // //     // optional, if notation is "compact" //     compactDisplay: "short" / "long", // //     signDisplay: "auto" / "never" / "always" / "exceptZero", //   } // // Note that lazy data is only installed as a final step of initialization, // so every NumberFormat lazy data object has *all* these properties, never a // subset of them. // Step 1. // Steps 2-3. // // If we ever need more speed here at startup, we should try to detect the // case where |options === undefined| and then directly use the default // value for each option.  For now, just keep it simple. // Compute options that impact interpretation of locale. // Step 4. // Steps 5-6. // Compute formatting options. // Step 12. // Steps 14-17. // Per the Intl.NumberFormat Unified API Proposal, this check should only // happen for |style === "currency"|, which seems inconsistent, given that // we normally validate all options when present, even the ones which are // unused. // TODO: File issue at <https://github.com/tc39/proposal-unified-intl-numberformat>. // Steps 19.a-c. // Step 18. // Intl.NumberFormat Unified API Proposal // Intl.NumberFormat Unified API Proposal // Aligned with |currency| check from above, see note about spec issue there. // Steps 20-21. // Intl.NumberFormat Unified API Proposal // Step 22. // Intl.NumberFormat Unified API Proposal // Steps 23. // Intl.NumberFormat Unified API Proposal // Step 31. // // We've done everything that must be done now: mark the lazy data as fully // computed and install it. // 11.2.1, steps 4-5. // 11.2.1, step 6.