UNPKG

@formatjs/ecma402-abstract

Version:

A collection of implementation for ECMAScript abstract operations

51 lines (50 loc) 1.69 kB
import "../types/number.js"; const PART_TYPES_TO_COLLAPSE = new Set([ "unit", "exponentMinusSign", "minusSign", "plusSign", "percentSign", "exponentSeparator", "percent", "percentSign", "currency", "literal" ]); /** * https://tc39.es/ecma402/#sec-collapsenumberrange * LDML: https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#collapsing-number-ranges */ export function CollapseNumberRange(numberFormat, result, { getInternalSlots }) { const internalSlots = getInternalSlots(numberFormat); const symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]; const rangeSignRegex = new RegExp(`s?[${symbols.rangeSign}]s?`); const rangeSignIndex = result.findIndex((r) => r.type === "literal" && rangeSignRegex.test(r.value)); let prefixSignParts = []; for (let i = rangeSignIndex - 1; i >= 0; i--) { if (!PART_TYPES_TO_COLLAPSE.has(result[i].type)) { break; } prefixSignParts.unshift(result[i]); } // Don't collapse if it's a single code point if (Array.from(prefixSignParts.map((p) => p.value).join("")).length > 1) { const newResult = Array.from(result); newResult.splice(rangeSignIndex - prefixSignParts.length, prefixSignParts.length); return newResult; } let suffixSignParts = []; for (let i = rangeSignIndex + 1; i < result.length; i++) { if (!PART_TYPES_TO_COLLAPSE.has(result[i].type)) { break; } suffixSignParts.push(result[i]); } // Don't collapse if it's a single code point if (Array.from(suffixSignParts.map((p) => p.value).join("")).length > 1) { const newResult = Array.from(result); newResult.splice(rangeSignIndex + 1, suffixSignParts.length); return newResult; } return result; }