UNPKG

@v4fire/core

Version:
203 lines (155 loc) 4.69 kB
/*! * V4Fire Core * https://github.com/V4Fire/Core * * Released under the MIT license * https://github.com/V4Fire/Core/blob/master/LICENSE */ import extend from 'core/prelude/extend'; import { deprecate } from 'core/functools'; import { locale as defaultLocale } from 'core/prelude/i18n'; import { globalFormatOpts, defaultFormats, formatCache, formatAliases, boolAliases, decPartRgxp } from 'core/prelude/number/const'; import { repeatString } from 'core/prelude/number/helpers'; /** @see [[Number.pad]] */ extend(Number.prototype, 'pad', function pad( this: number, lengthOrOpts: number | NumberPadOptions = 0, opts?: NumberPadOptions ): string { opts = {...Object.isPlainObject(lengthOrOpts) ? lengthOrOpts : opts}; if (opts.length == null) { opts.length = Object.isNumber(lengthOrOpts) ? lengthOrOpts : 0; } const val = Number(this); let str = Math.abs(val).toString(opts.base ?? 10); str = repeatString('0', opts.length - str.replace(decPartRgxp, '').length) + str; if (opts.sign || val < 0) { str = (val < 0 ? '-' : '+') + str; } return str; }); /** @see [[NumberConstructor.pad]] */ extend(Number, 'pad', (value: number | NumberPadOptions, lengthOrOpts: number | NumberPadOptions) => { if (Object.isPlainObject(value)) { const opts = value; return (value) => Number.pad(value, opts); } return value.pad(Object.cast(lengthOrOpts)); }); /** @see [[Number.format]] */ extend(Number.prototype, 'format', function format( this: number, patternOrOpts?: number | string | Intl.NumberFormatOptions, locale: CanUndef<CanArray<string>> = defaultLocale.value ): string { if (patternOrOpts === undefined && !globalFormatOpts.init) { return this.toLocaleString(locale); } if (Object.isPlainObject(patternOrOpts)) { return this.toLocaleString(locale, patternOrOpts); } if (Object.isString(patternOrOpts)) { const pattern = patternOrOpts, cacheKey = [locale, pattern].join(); let formatter = formatCache[cacheKey]; if (formatter == null) { const chunks = pattern.split(';'), opts: Intl.NumberFormatOptions = {}; for (let i = 0; i < chunks.length; i++) { const formatChunk = chunks[i].trim(); let [formatKey, formatParams = null] = formatChunk.split(':'); formatKey = formatKey.trim(); if (formatParams != null) { formatParams = formatParams.trim(); } const alias = formatAliases[formatKey]; if (alias != null) { formatKey = alias; switch (alias) { case 'currency': opts.style = 'currency'; opts.currency = formatParams ?? defaultFormats.currency; break; case 'currencyDisplay': opts.currencyDisplay = formatParams ?? defaultFormats.currencyDisplay; break; case 'percent': opts.style = 'percent'; break; case 'decimal': opts.style = 'decimal'; break; default: throw new TypeError(`Unknown alias "${alias}"`); } } else { if (formatParams == null || formatParams === '') { formatParams = defaultFormats[formatKey]; } if (formatParams != null) { opts[formatKey] = formatParams in boolAliases ? boolAliases[formatParams] : formatParams; } } } formatter = new Intl.NumberFormat(locale, opts); formatCache[cacheKey] = formatter; } return formatter.format(this); } const decimalLength = Number(patternOrOpts); const val = Number(this), str = patternOrOpts != null ? val.toFixed(decimalLength) : val.toString(); const [int, dec = ''] = str.split('.'); let res = ''; for (let i = int.length - 1, j = 0; i >= 0; i--) { if (j === 3) { j = 0; res = globalFormatOpts.thousands + res; } j++; res = int[i] + res; } if (dec.length > 0) { return res + globalFormatOpts.decimal + dec; } return res; }); /** @see [[NumberConstructor.format]] */ extend(Number, 'format', ( value: number | string | Intl.NumberFormatOptions, patternOrOpts?: string | Intl.NumberFormatOptions, locale?: CanArray<string> ) => { if (Object.isString(value) || Object.isPlainObject(value)) { locale = Object.cast(patternOrOpts); patternOrOpts = value; return (value) => Number.format(value, Object.cast(patternOrOpts), locale); } return value.format(Object.cast(patternOrOpts), locale); }); /** @see [[NumberConstructor.getOption]] */ extend(Number, 'getOption', deprecate(function getOption(key: string): string { return globalFormatOpts[key]; })); /** @see [[NumberConstructor.setOption]] */ extend(Number, 'setOption', deprecate(function setOption(key: string, value: string): void { globalFormatOpts.init = true; globalFormatOpts[key] = value; }));