modifier.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
  2. function round(x, precision) {
  3. const y = +x + precision / 2;
  4. return y - (y % +precision);
  5. }
  6. function getNumberFormatMultiplier({ scale, unit }) {
  7. let mult = typeof scale === 'number' && scale >= 0 ? scale : 1;
  8. if (unit && unit.style === 'percent')
  9. mult *= 0.01;
  10. return mult;
  11. }
  12. /**
  13. * Determine a modifier for the input value to account for any `scale`,
  14. * `percent`, and `precision-increment` tokens in the skeleton.
  15. *
  16. * @internal
  17. * @remarks
  18. * With ICU NumberFormatter, the `percent` skeleton would style `25` as "25%".
  19. * To achieve the same with `Intl.NumberFormat`, the input value must be `0.25`.
  20. */
  21. export function getNumberFormatModifier(skeleton) {
  22. const mult = getNumberFormatMultiplier(skeleton);
  23. const { precision } = skeleton;
  24. if (precision && precision.style === 'precision-increment') {
  25. return (n) => round(n, precision.increment) * mult;
  26. }
  27. else {
  28. return (n) => n * mult;
  29. }
  30. }
  31. /**
  32. * Returns a string of JavaScript source that evaluates to a modifier for the
  33. * input value to account for any `scale`, `percent`, and `precision-increment`
  34. * tokens in the skeleton.
  35. *
  36. * @internal
  37. * @remarks
  38. * With ICU NumberFormatter, the `percent` skeleton would style `25` as "25%".
  39. * To achieve the same with `Intl.NumberFormat`, the input value must be `0.25`.
  40. */
  41. export function getNumberFormatModifierSource(skeleton) {
  42. const mult = getNumberFormatMultiplier(skeleton);
  43. const { precision } = skeleton;
  44. if (precision && precision.style === 'precision-increment') {
  45. // see round() above for source
  46. const setX = `+n + ${precision.increment / 2}`;
  47. let res = `x - (x % +${precision.increment})`;
  48. if (mult !== 1)
  49. res = `(${res}) * ${mult}`;
  50. return `function(n) { var x = ${setX}; return ${res}; }`;
  51. }
  52. return mult !== 1 ? `function(n) { return n * ${mult}; }` : null;
  53. }