@formatjs/intl-listformat
Version:
Formats JS list in a i18n-safe way
215 lines (214 loc) • 9.53 kB
JavaScript
;
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
}