Source: polyfill/Intl/NumberFormat.js

  1. // Licensed Materials - Property of IBM
  2. //
  3. // IBM Watson Analytics
  4. //
  5. // (C) Copyright IBM Corp. 2018
  6. //
  7. // US Government Users Restricted Rights - Use, duplication or
  8. // disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. module.exports = ( function( Format )
  10. {
  11. "use strict";
  12. /**
  13. * These classes are NOT a polyfill, and are not meant to be!
  14. * They provide a poor man's fallback for the Intl formatters, for non-compliant environments.
  15. */
  16. var reCurrencyCode = /^[A-Z]{3}$/;
  17. var nbsp = String.fromCharCode( 160 );
  18. /**
  19. * Object that parses an Options object and normalizes it to options.
  20. * @class module:barejs/polyfill/Intl.NumberFormat~NumberFormatOptions
  21. */
  22. function NumberFormatOptions( _options )
  23. {
  24. // MinimumFractionDigits is usually 0
  25. this.minimumFractionDigits = 0;
  26. this.maximumFractionDigits = 3;
  27. this.minimumIntegerDigits = 1;
  28. this.numberingSystem = "latn";
  29. this.useGrouping = true;
  30. switch ( "style" in _options ? _options.style : "decimal" )
  31. {
  32. case "percent":
  33. this.style = "percent";
  34. this.maximumFractionDigits = Math.max( 0, this.minimumFractionDigits );
  35. break;
  36. case "currency":
  37. this.style = "currency";
  38. if ( !_options.currency )
  39. throw new TypeError( "Currency code is required with currency style." );
  40. if ( ( typeof _options.currency !== "string" ) || !reCurrencyCode.test( _options.currency ) )
  41. throw new TypeError( "Invalid currency code:" + _options.currency );
  42. this.currency = _options.currency;
  43. this.currencyDisplay = "code"; // This is all the fallback supports!
  44. this.maximumFractionDigits = Math.max( 2, this.minimumFractionDigits );
  45. break;
  46. case "decimal":
  47. this.style = "decimal";
  48. break;
  49. default:
  50. throw new RangeError( "Value " + _options.style + " out of range for numberformat options property style" );
  51. }
  52. }
  53. /**
  54. * Provides number formatting
  55. * @class module:barejs/polyfill/Intl.NumberFormat
  56. * @extends module:barejs/polyfill/Intl~Format
  57. */
  58. function NumberFormat( _locales, _options )
  59. {
  60. Format.call( this, _locales, new NumberFormatOptions( Object( _options ) ) );
  61. }
  62. NumberFormat.prototype = Object.create( Format.prototype,
  63. /** @lends module:barejs/polyfill/Intl.NumberFormat# */
  64. {
  65. constructor: { writable: true, value: NumberFormat },
  66. format:
  67. {
  68. enumerable: true,
  69. value: function format( _value )
  70. {
  71. if ( _value === null || typeof _value === "undefined" )
  72. return "";
  73. var value = +_value;
  74. var prefix = "";
  75. var suffix = "";
  76. if ( isNaN( value ) )
  77. return "NaN";
  78. switch( this._options.style )
  79. {
  80. case "percent":
  81. value *= 100;
  82. suffix = "%";
  83. break;
  84. case "currency":
  85. prefix = this._options.currency + nbsp;
  86. break;
  87. }
  88. // We're currently ignoring min/max decimal places (which is bad).
  89. return prefix + value.toLocaleString() + suffix;
  90. }
  91. }
  92. } );
  93. return NumberFormat;
  94. }( require( "./Format" ) ) );