UNPKG

angular-l10n

Version:

An Angular library to translate messages, dates and numbers

306 lines 11.4 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Injectable } from '@angular/core'; import { LocaleService } from './locale.service'; import { IntlAPI } from './intl-api'; import { formatDigitsAliases } from '../models/intl-formatter'; import { Logger } from '../models/logger'; /** * @record */ export function ILocaleValidation() { } if (false) { /** * @param {?} s * @param {?=} digits * @param {?=} defaultLocale * @return {?} */ ILocaleValidation.prototype.parseNumber = function (s, digits, defaultLocale) { }; } /** * Provides the methods for locale validation. */ var LocaleValidation = /** @class */ (function () { function LocaleValidation(locale) { this.locale = locale; } /** * Converts a string to a number according to default locale. * If the string cannot be converted to a number, returns NaN. * @param s The string to be parsed * @param digits An alias of the format. Default is '1.0-3' * @param defaultLocale The default locale to use. Default is the current locale */ /** * Converts a string to a number according to default locale. * If the string cannot be converted to a number, returns NaN. * @param {?} s The string to be parsed * @param {?=} digits An alias of the format. Default is '1.0-3' * @param {?=} defaultLocale The default locale to use. Default is the current locale * @return {?} */ LocaleValidation.prototype.parseNumber = /** * Converts a string to a number according to default locale. * If the string cannot be converted to a number, returns NaN. * @param {?} s The string to be parsed * @param {?=} digits An alias of the format. Default is '1.0-3' * @param {?=} defaultLocale The default locale to use. Default is the current locale * @return {?} */ function (s, digits, defaultLocale) { if (s == "" || s == null) return null; // Replaces whitespace metacharacters. s = s.replace(/\s/g, ' '); this.decimalCode = this.getDecimalCode(defaultLocale); this.numberCodes = this.getNumberCodes(defaultLocale); if (!this.validateNumber(s, digits)) return NaN; /** @type {?} */ var value = ""; /** @type {?} */ var characters = s.split(""); for (var _i = 0, characters_1 = characters; _i < characters_1.length; _i++) { var char = characters_1[_i]; /** @type {?} */ var charCode = this.toUnicode(char); /** @type {?} */ var index = this.numberCodes.indexOf(charCode); if (index != -1) { value += index; } else if (charCode == this.decimalCode.minusSign) { value += "-"; } else if (charCode == this.decimalCode.decimalSeparator) { value += "."; } else if (charCode == this.decimalCode.thousandSeparator) { continue; } else { return NaN; } } return parseFloat(value); }; /** * @param {?} s * @param {?=} digits * @return {?} */ LocaleValidation.prototype.validateNumber = /** * @param {?} s * @param {?=} digits * @return {?} */ function (s, digits) { /** @type {?} */ var options = {}; if (digits) { /** @type {?} */ var digitsOptions = formatDigitsAliases(digits); if (digitsOptions != null) { options = digitsOptions; } else { Logger.log('LocaleValidation', 'invalidNumberFormatAlias'); } } /** @type {?} */ var minInt = options.minimumIntegerDigits !== undefined ? options.minimumIntegerDigits : 1; /** @type {?} */ var minFraction = options.minimumFractionDigits !== undefined ? options.minimumFractionDigits : 0; /** @type {?} */ var maxFraction = options.maximumFractionDigits !== undefined ? options.maximumFractionDigits : 3; /** @type {?} */ var minusSign = this.decimalCode.minusSign; /** @type {?} */ var zero = this.numberCodes[0]; /** @type {?} */ var decimalSeparator = this.decimalCode.decimalSeparator; /** @type {?} */ var thousandSeparator = this.decimalCode.thousandSeparator; /** @type {?} */ var nine = this.numberCodes[9]; // Pattern for 1.0-2 digits: /^-?[0-9]{1,}(\.[0-9]{0,2})?$/ // Unicode pattern = "^\u002d?[\u0030-\u0039]{1,}(\\u002e[\u0030-\u0039]{0,2})?$" // Complete Pattern with thousand separator: // /^-?([0-9]{1,}|(?=(?:\,*[0-9]){1,}(\.|$))(?!0(?!\.|[0-9]))[0-9]{1,3}(\,[0-9]{3})*)(\.[0-9]{0,2})?$/ // where: // (?=(?:\,*[0-9]){1,}(\.|$)) => Positive Lookahead to count the integer digits // (?!0(?!\.|[0-9])) => Negative Lookahead to avoid 0,1111.00 // [0-9]{1,3}(\,[0-9]{3})* => Allows thousand separator /** @type {?} */ var d = "[" + zero + "-" + nine + "]"; /** @type {?} */ var n = "{" + minInt + ",}"; /** @type {?} */ var nm = "{" + minFraction + "," + maxFraction + "}"; /** @type {?} */ var plainPattern = "" + d + n; // tslint:disable-next-line /** @type {?} */ var thousandPattern = "(?=(?:\\" + thousandSeparator + "*" + d + ")" + n + "(\\" + decimalSeparator + "|$))(?!" + zero + "(?!\\" + decimalSeparator + "|" + d + "))" + d + "{1,3}(\\" + thousandSeparator + d + "{3})*"; /** @type {?} */ var pattern = "^" + minusSign + "?(" + plainPattern + "|" + thousandPattern + ")"; if (minFraction > 0 && maxFraction > 0) { // Decimal separator is mandatory. pattern += "\\" + decimalSeparator + d + nm + "$"; } else if (minFraction == 0 && maxFraction > 0) { // Decimal separator is optional. pattern += "(\\" + decimalSeparator + d + nm + ")?$"; } else { // Integer number. pattern += "$"; } pattern = this.toChar(pattern); /** @type {?} */ var NUMBER_REGEXP = new RegExp(pattern); return NUMBER_REGEXP.test(s); }; /** * @param {?=} defaultLocale * @return {?} */ LocaleValidation.prototype.getDecimalCode = /** * @param {?=} defaultLocale * @return {?} */ function (defaultLocale) { /** @type {?} */ var decimalCode = { minusSign: this.toUnicode("-"), decimalSeparator: this.toUnicode("."), thousandSeparator: this.toUnicode(",") }; if (IntlAPI.hasNumberFormat()) { /** @type {?} */ var value = -1000.9; // Reference value. /** @type {?} */ var localeValue = this.locale.formatDecimal(value, '1.1-1', defaultLocale); /** @type {?} */ var unicodeChars = []; for (var i = 0; i < localeValue.length; i++) { /** @type {?} */ var unicodeChar = this.toUnicode(localeValue.charAt(i)); // Replaces NO-BREAK SPACE unicodeChar = unicodeChar.replace("\\u202F", "\\u0020"); unicodeChar = unicodeChar.replace("\\u00A0", "\\u0020"); unicodeChars.push(unicodeChar); } /** @type {?} */ var thousandSeparator = localeValue.length >= 8 ? true : false; // Expected positions. // Right to left: // checks Unicode characters 'RIGHT-TO-LEFT MARK' (U+200F) & 'Arabic Letter Mark' (U+061C), // or the reverse order. // Left to right: // checks Unicode character 'LEFT-TO-RIGHT MARK' (U+200E). /** @type {?} */ var positions = void 0; if (unicodeChars[0] == "\\u200F" || unicodeChars[0] == "\\u061C") { positions = thousandSeparator ? [1, 7, 3] : [1, 6]; } else if (unicodeChars[0] == this.toUnicode(this.locale.formatDecimal(1, '1.0-0', defaultLocale))) { positions = thousandSeparator ? [7, 5, 1] : [6, 4]; } else if (unicodeChars[0] == "\\u200E") { positions = thousandSeparator ? [1, 7, 3] : [1, 6]; } else { positions = thousandSeparator ? [0, 6, 2] : [0, 5]; } decimalCode = { minusSign: unicodeChars[positions[0]], decimalSeparator: unicodeChars[positions[1]], thousandSeparator: thousandSeparator ? unicodeChars[positions[2]] : "" }; } return decimalCode; }; /** * @param {?=} defaultLocale * @return {?} */ LocaleValidation.prototype.getNumberCodes = /** * @param {?=} defaultLocale * @return {?} */ function (defaultLocale) { /** @type {?} */ var numberCodes = []; for (var num = 0; num <= 9; num++) { numberCodes.push(this.toUnicode(num.toString())); } if (IntlAPI.hasNumberFormat()) { for (var num = 0; num <= 9; num++) { numberCodes[num] = this.toUnicode(this.locale.formatDecimal(num, '1.0-0', defaultLocale)); } } return numberCodes; }; /** * @param {?} pattern * @return {?} */ LocaleValidation.prototype.toChar = /** * @param {?} pattern * @return {?} */ function (pattern) { return pattern.replace(/\\u[\dA-F]{4}/gi, function (match) { return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16)); }); }; /** * @param {?} c * @return {?} */ LocaleValidation.prototype.toUnicode = /** * @param {?} c * @return {?} */ function (c) { return "\\u" + this.toHex(c.charCodeAt(0)); }; /** * @param {?} value * @return {?} */ LocaleValidation.prototype.toHex = /** * @param {?} value * @return {?} */ function (value) { /** @type {?} */ var hex = value.toString(16).toUpperCase(); // With padding. hex = "0000".substr(0, 4 - hex.length) + hex; return hex; }; LocaleValidation.decorators = [ { type: Injectable } ]; /** @nocollapse */ LocaleValidation.ctorParameters = function () { return [ { type: LocaleService } ]; }; return LocaleValidation; }()); export { LocaleValidation }; if (false) { /** @type {?} */ LocaleValidation.prototype.decimalCode; /** @type {?} */ LocaleValidation.prototype.numberCodes; /** @type {?} */ LocaleValidation.prototype.locale; } //# sourceMappingURL=locale-validation.js.map