UNPKG

@formatjs/intl-listformat

Version:

Formats JS list in a i18n-safe way

215 lines (214 loc) 9.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var ecma402_abstract_1 = require("@formatjs/ecma402-abstract"); var intl_localematcher_1 = require("@formatjs/intl-localematcher"); function validateInstance(instance, method) { if (!(instance instanceof ListFormat)) { throw new TypeError("Method Intl.ListFormat.prototype.".concat(method, " called on incompatible receiver ").concat(String(instance))); } } /** * https://tc39.es/proposal-intl-list-format/#sec-createstringlistfromiterable * @param list list */ function stringListFromIterable(list) { if (list === undefined) { return []; } var result = []; for (var _i = 0, list_1 = list; _i < list_1.length; _i++) { var el = list_1[_i]; if (typeof el !== 'string') { throw new TypeError("array list[".concat(list.indexOf(el), "] is not type String")); } result.push(el); } return result; } function createPartsFromList(internalSlotMap, lf, list) { var size = list.length; if (size === 0) { return []; } if (size === 2) { var pattern = (0, ecma402_abstract_1.getInternalSlot)(internalSlotMap, lf, 'templatePair'); var first = { type: 'element', value: list[0] }; var second = { type: 'element', value: list[1] }; return deconstructPattern(pattern, { '0': first, '1': second }); } var last = { type: 'element', value: list[size - 1], }; var parts = last; var i = size - 2; while (i >= 0) { var pattern = void 0; if (i === 0) { pattern = (0, ecma402_abstract_1.getInternalSlot)(internalSlotMap, lf, 'templateStart'); } else if (i < size - 2) { pattern = (0, ecma402_abstract_1.getInternalSlot)(internalSlotMap, lf, 'templateMiddle'); } else { pattern = (0, ecma402_abstract_1.getInternalSlot)(internalSlotMap, lf, 'templateEnd'); } var head = { type: 'element', value: list[i] }; parts = deconstructPattern(pattern, { '0': head, '1': parts }); i--; } return parts; } function deconstructPattern(pattern, placeables) { var patternParts = (0, ecma402_abstract_1.PartitionPattern)(pattern); var result = []; for (var _i = 0, patternParts_1 = patternParts; _i < patternParts_1.length; _i++) { var patternPart = patternParts_1[_i]; var part = patternPart.type; if ((0, ecma402_abstract_1.isLiteralPart)(patternPart)) { result.push({ type: 'literal', value: patternPart.value, }); } else { (0, ecma402_abstract_1.invariant)(part in placeables, "".concat(part, " is missing from placables")); var subst = placeables[part]; if (Array.isArray(subst)) { result.push.apply(result, subst); } else { result.push(subst); } } } return result; } var ListFormat = /** @class */ (function () { function ListFormat(locales, options) { // test262/test/intl402/ListFormat/constructor/constructor/newtarget-undefined.js // Cannot use `new.target` bc of IE11 & TS transpiles it to something else var newTarget = this && this instanceof ListFormat ? this.constructor : void 0; if (!newTarget) { throw new TypeError("Intl.ListFormat must be called with 'new'"); } (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'initializedListFormat', true); var requestedLocales = (0, ecma402_abstract_1.CanonicalizeLocaleList)(locales); var opt = Object.create(null); var opts = (0, ecma402_abstract_1.GetOptionsObject)(options); var matcher = (0, ecma402_abstract_1.GetOption)(opts, 'localeMatcher', 'string', ['best fit', 'lookup'], 'best fit'); opt.localeMatcher = matcher; var localeData = ListFormat.localeData; var r = (0, intl_localematcher_1.ResolveLocale)(ListFormat.availableLocales, requestedLocales, opt, ListFormat.relevantExtensionKeys, localeData, ListFormat.getDefaultLocale); (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'locale', r.locale); var type = (0, ecma402_abstract_1.GetOption)(opts, 'type', 'string', ['conjunction', 'disjunction', 'unit'], 'conjunction'); (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'type', type); var style = (0, ecma402_abstract_1.GetOption)(opts, 'style', 'string', ['long', 'short', 'narrow'], 'long'); (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'style', style); var dataLocale = r.dataLocale; var dataLocaleData = localeData[dataLocale]; (0, ecma402_abstract_1.invariant)(!!dataLocaleData, "Missing locale data for ".concat(dataLocale)); var dataLocaleTypes = dataLocaleData[type]; var templates = dataLocaleTypes[style]; (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'templatePair', templates.pair); (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'templateStart', templates.start); (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'templateMiddle', templates.middle); (0, ecma402_abstract_1.setInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'templateEnd', templates.end); } ListFormat.prototype.format = function (elements) { validateInstance(this, 'format'); var result = ''; var parts = createPartsFromList(ListFormat.__INTERNAL_SLOT_MAP__, this, stringListFromIterable(elements)); if (!Array.isArray(parts)) { return parts.value; } for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { var p = parts_1[_i]; result += p.value; } return result; }; ListFormat.prototype.formatToParts = function (elements) { validateInstance(this, 'format'); var parts = createPartsFromList(ListFormat.__INTERNAL_SLOT_MAP__, this, stringListFromIterable(elements)); if (!Array.isArray(parts)) { return [parts]; } var result = []; for (var _i = 0, parts_2 = parts; _i < parts_2.length; _i++) { var part = parts_2[_i]; result.push(tslib_1.__assign({}, part)); } return result; }; ListFormat.prototype.resolvedOptions = function () { validateInstance(this, 'resolvedOptions'); return { locale: (0, ecma402_abstract_1.getInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'locale'), type: (0, ecma402_abstract_1.getInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'type'), style: (0, ecma402_abstract_1.getInternalSlot)(ListFormat.__INTERNAL_SLOT_MAP__, this, 'style'), }; }; ListFormat.supportedLocalesOf = function (locales, options) { // test262/test/intl402/ListFormat/constructor/supportedLocalesOf/result-type.js return (0, ecma402_abstract_1.SupportedLocales)(ListFormat.availableLocales, (0, ecma402_abstract_1.CanonicalizeLocaleList)(locales), options); }; ListFormat.__addLocaleData = function () { var data = []; for (var _i = 0; _i < arguments.length; _i++) { data[_i] = arguments[_i]; } for (var _a = 0, data_1 = data; _a < data_1.length; _a++) { var _b = data_1[_a], d = _b.data, locale = _b.locale; var minimizedLocale = new Intl.Locale(locale) .minimize() .toString(); ListFormat.localeData[locale] = ListFormat.localeData[minimizedLocale] = d; ListFormat.availableLocales.add(minimizedLocale); ListFormat.availableLocales.add(locale); if (!ListFormat.__defaultLocale) { ListFormat.__defaultLocale = minimizedLocale; } } }; ListFormat.getDefaultLocale = function () { return ListFormat.__defaultLocale; }; ListFormat.localeData = {}; ListFormat.availableLocales = new Set(); ListFormat.__defaultLocale = ''; ListFormat.relevantExtensionKeys = []; ListFormat.polyfilled = true; ListFormat.__INTERNAL_SLOT_MAP__ = new WeakMap(); return ListFormat; }()); exports.default = ListFormat; try { // IE11 does not have Symbol if (typeof Symbol !== 'undefined') { Object.defineProperty(ListFormat.prototype, Symbol.toStringTag, { value: 'Intl.ListFormat', writable: false, enumerable: false, configurable: true, }); } // https://github.com/tc39/test262/blob/master/test/intl402/ListFormat/constructor/length.js Object.defineProperty(ListFormat.prototype.constructor, 'length', { value: 0, writable: false, enumerable: false, configurable: true, }); // https://github.com/tc39/test262/blob/master/test/intl402/ListFormat/constructor/supportedLocalesOf/length.js Object.defineProperty(ListFormat.supportedLocalesOf, 'length', { value: 1, writable: false, enumerable: false, configurable: true, }); } catch (e) { // Meta fix so we're test262-compliant, not important }