
Subclassing errors is problematic since Error returns a new instance. All of the patching which we do than prevent proper application of source maps. PR Close #14160
165 lines
5.6 KiB
TypeScript
165 lines
5.6 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {Inject, LOCALE_ID, Pipe, PipeTransform, Type} from '@angular/core';
|
|
|
|
import {NumberWrapper} from '../facade/lang';
|
|
|
|
import {NumberFormatStyle, NumberFormatter} from './intl';
|
|
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
|
|
|
|
const _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
|
|
|
|
function formatNumber(
|
|
pipe: Type<any>, locale: string, value: number | string, style: NumberFormatStyle,
|
|
digits: string, currency: string = null, currencyAsSymbol: boolean = false): string {
|
|
if (value == null) return null;
|
|
|
|
// Convert strings to numbers
|
|
value = typeof value === 'string' && NumberWrapper.isNumeric(value) ? +value : value;
|
|
if (typeof value !== 'number') {
|
|
throw invalidPipeArgumentError(pipe, value);
|
|
}
|
|
|
|
let minInt: number;
|
|
let minFraction: number;
|
|
let maxFraction: number;
|
|
if (style !== NumberFormatStyle.Currency) {
|
|
// rely on Intl default for currency
|
|
minInt = 1;
|
|
minFraction = 0;
|
|
maxFraction = 3;
|
|
}
|
|
|
|
if (digits) {
|
|
const parts = digits.match(_NUMBER_FORMAT_REGEXP);
|
|
if (parts === null) {
|
|
throw new Error(`${digits} is not a valid digit info for number pipes`);
|
|
}
|
|
if (parts[1] != null) { // min integer digits
|
|
minInt = NumberWrapper.parseIntAutoRadix(parts[1]);
|
|
}
|
|
if (parts[3] != null) { // min fraction digits
|
|
minFraction = NumberWrapper.parseIntAutoRadix(parts[3]);
|
|
}
|
|
if (parts[5] != null) { // max fraction digits
|
|
maxFraction = NumberWrapper.parseIntAutoRadix(parts[5]);
|
|
}
|
|
}
|
|
|
|
return NumberFormatter.format(value as number, locale, style, {
|
|
minimumIntegerDigits: minInt,
|
|
minimumFractionDigits: minFraction,
|
|
maximumFractionDigits: maxFraction,
|
|
currency: currency,
|
|
currencyAsSymbol: currencyAsSymbol,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @ngModule CommonModule
|
|
* @whatItDoes Formats a number according to locale rules.
|
|
* @howToUse `number_expression | number[:digitInfo]`
|
|
*
|
|
* Formats a number as text. Group sizing and separator and other locale-specific
|
|
* configurations are based on the active locale.
|
|
*
|
|
* where `expression` is a number:
|
|
* - `digitInfo` is a `string` which has a following format: <br>
|
|
* <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>
|
|
* - `minIntegerDigits` is the minimum number of integer digits to use. Defaults to `1`.
|
|
* - `minFractionDigits` is the minimum number of digits after fraction. Defaults to `0`.
|
|
* - `maxFractionDigits` is the maximum number of digits after fraction. Defaults to `3`.
|
|
*
|
|
* For more information on the acceptable range for each of these numbers and other
|
|
* details see your native internationalization library.
|
|
*
|
|
* WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
|
|
* and may require a polyfill. See {@linkDocs guide/browser-support} for details.
|
|
*
|
|
* ### Example
|
|
*
|
|
* {@example common/pipes/ts/number_pipe.ts region='NumberPipe'}
|
|
*
|
|
* @stable
|
|
*/
|
|
@Pipe({name: 'number'})
|
|
export class DecimalPipe implements PipeTransform {
|
|
constructor(@Inject(LOCALE_ID) private _locale: string) {}
|
|
|
|
transform(value: any, digits: string = null): string {
|
|
return formatNumber(DecimalPipe, this._locale, value, NumberFormatStyle.Decimal, digits);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ngModule CommonModule
|
|
* @whatItDoes Formats a number as a percentage according to locale rules.
|
|
* @howToUse `number_expression | percent[:digitInfo]`
|
|
*
|
|
* @description
|
|
*
|
|
* Formats a number as percentage.
|
|
*
|
|
* - `digitInfo` See {@link DecimalPipe} for detailed description.
|
|
*
|
|
* WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
|
|
* and may require a polyfill. See {@linkDocs guide/browser-support} for details.
|
|
*
|
|
* ### Example
|
|
*
|
|
* {@example common/pipes/ts/number_pipe.ts region='PercentPipe'}
|
|
*
|
|
* @stable
|
|
*/
|
|
@Pipe({name: 'percent'})
|
|
export class PercentPipe implements PipeTransform {
|
|
constructor(@Inject(LOCALE_ID) private _locale: string) {}
|
|
|
|
transform(value: any, digits: string = null): string {
|
|
return formatNumber(PercentPipe, this._locale, value, NumberFormatStyle.Percent, digits);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ngModule CommonModule
|
|
* @whatItDoes Formats a number as currency using locale rules.
|
|
* @howToUse `number_expression | currency[:currencyCode[:symbolDisplay[:digitInfo]]]`
|
|
* @description
|
|
*
|
|
* Use `currency` to format a number as currency.
|
|
*
|
|
* - `currencyCode` is the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code, such
|
|
* as `USD` for the US dollar and `EUR` for the euro.
|
|
* - `symbolDisplay` is a boolean indicating whether to use the currency symbol or code.
|
|
* - `true`: use symbol (e.g. `$`).
|
|
* - `false`(default): use code (e.g. `USD`).
|
|
* - `digitInfo` See {@link DecimalPipe} for detailed description.
|
|
*
|
|
* WARNING: this pipe uses the Internationalization API which is not yet available in all browsers
|
|
* and may require a polyfill. See {@linkDocs guide/browser-support} for details.
|
|
*
|
|
* ### Example
|
|
*
|
|
* {@example common/pipes/ts/number_pipe.ts region='CurrencyPipe'}
|
|
*
|
|
* @stable
|
|
*/
|
|
@Pipe({name: 'currency'})
|
|
export class CurrencyPipe implements PipeTransform {
|
|
constructor(@Inject(LOCALE_ID) private _locale: string) {}
|
|
|
|
transform(
|
|
value: any, currencyCode: string = 'USD', symbolDisplay: boolean = false,
|
|
digits: string = null): string {
|
|
return formatNumber(
|
|
CurrencyPipe, this._locale, value, NumberFormatStyle.Currency, digits, currencyCode,
|
|
symbolDisplay);
|
|
}
|
|
}
|