"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.UNITS = void 0; var _LocaleDataStore = require("./LocaleDataStore"); var _resolveLocale = _interopRequireDefault(require("./resolveLocale")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // Valid time units. var UNITS = ["second", "minute", "hour", "day", "week", "month", "quarter", "year"]; // Valid values for the `numeric` option. exports.UNITS = UNITS; var NUMERIC_VALUES = ["auto", "always"]; // Valid values for the `style` option. var STYLE_VALUES = ["long", "short", "narrow"]; /** * Polyfill for `Intl.RelativeTimeFormat` proposal. * https://github.com/tc39/proposal-intl-relative-time * https://github.com/tc39/proposal-intl-relative-time/issues/55 */ var RelativeTimeFormat = /*#__PURE__*/ function () { /** * @param {(string|string[])} [locales] - Preferred locales (or locale). * @param {Object} [options] - Formatting options. * @param {string} [options.style="long"] - One of: "long", "short", "narrow". * @param {string} [options.numeric="always"] - (Version >= 2) One of: "always", "auto". * @param {string} [options.localeMatcher="lookup"] - One of: "lookup", "best fit". Currently only "lookup" is supported. */ function RelativeTimeFormat() { var locales = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck(this, RelativeTimeFormat); _defineProperty(this, "numeric", "always"); _defineProperty(this, "style", "long"); _defineProperty(this, "localeMatcher", "lookup"); var numeric = options.numeric, style = options.style, localeMatcher = options.localeMatcher; // Set `numeric` option. if (numeric) { if (NUMERIC_VALUES.indexOf(numeric) < 0) { throw new RangeError("Invalid \"numeric\" option: ".concat(numeric)); } this.numeric = numeric; } // Set `style` option. if (style) { if (STYLE_VALUES.indexOf(style) < 0) { throw new RangeError("Invalid \"style\" option: ".concat(style)); } this.style = style; } // Set `localeMatcher` option. if (localeMatcher) { this.localeMatcher = localeMatcher; } // Set `locale`. // Convert `locales` to an array. if (typeof locales === 'string') { locales = [locales]; } // Add default locale. locales.push((0, _LocaleDataStore.getDefaultLocale)()); // Choose the most appropriate locale. this.locale = RelativeTimeFormat.supportedLocalesOf(locales, { localeMatcher: this.localeMatcher })[0]; if (!this.locale) { throw new TypeError("No supported locale was found"); } this.locale = (0, _resolveLocale.default)(this.locale, { localeMatcher: this.localeMatcher }); // Use `Intl.NumberFormat` for formatting numbers (when available). if (typeof Intl !== 'undefined' && Intl.NumberFormat) { this.numberFormat = new Intl.NumberFormat(this.locale); } } /** * Formats time `value` in `units` (either in past or in future). * @param {number} value - Time interval value. * @param {string} unit - Time interval measurement unit. * @return {string} * @throws {RangeError} If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter". * @example * // Returns "2 days ago" * rtf.format(-2, "day") * // Returns "in 5 minutes" * rtf.format(5, "minute") */ _createClass(RelativeTimeFormat, [{ key: "format", value: function format(value, unit) { return this.getRule(value, unit).replace('{0}', this.formatNumber(Math.abs(value))); } /** * Formats time `value` in `units` (either in past or in future). * @param {number} value - Time interval value. * @param {string} unit - Time interval measurement unit. * @return {Object[]} The parts (`{ type, value }`). * @throws {RangeError} If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter". * @example * // Version 1. * // Returns [ * // { type: "literal", value: "in " }, * // { type: "day", value: "100" }, * // { type: "literal", value: " days" } * // ] * rtf.formatToParts(100, "day") * // * // Version 2. * // Returns [ * // { type: "literal", value: "in " }, * // { type: "integer", value: "100", unit: "day" }, * // { type: "literal", value: " days" } * // ] * rtf.formatToParts(100, "day") */ }, { key: "formatToParts", value: function formatToParts(value, unit) { var rule = this.getRule(value, unit); var valueIndex = rule.indexOf("{0}"); // "yesterday"/"today"/"tomorrow". if (valueIndex < 0) { return [{ type: "literal", value: rule }]; } var parts = []; if (valueIndex > 0) { parts.push({ type: "literal", value: rule.slice(0, valueIndex) }); } parts.push({ unit: unit, type: "integer", value: this.formatNumber(Math.abs(value)) }); if (valueIndex + "{0}".length < rule.length - 1) { parts.push({ type: "literal", value: rule.slice(valueIndex + "{0}".length) }); } return parts; } /** * Returns formatting rule for `value` in `units` (either in past or in future). * @param {number} value - Time interval value. * @param {string} unit - Time interval measurement unit. * @return {string} * @throws {RangeError} If unit is not one of "second", "minute", "hour", "day", "week", "month", "quarter". * @example * // Returns "{0} days ago" * getRule(-2, "day") */ }, { key: "getRule", value: function getRule(value, unit) { if (UNITS.indexOf(unit) < 0) { throw new RangeError("Unknown time unit: ".concat(unit, ".")); } // Get locale-specific time interval formatting rules // of a given `style` for the given value of measurement `unit`. // // E.g.: // // ```json // { // "past": { // "one": "a second ago", // "other": "{0} seconds ago" // }, // "future": { // "one": "in a second", // "other": "in {0} seconds" // } // } // ``` // var unitRules = (0, _LocaleDataStore.getLocaleData)(this.locale)[this.style][unit]; // Special case for "yesterday"/"today"/"tomorrow". if (this.numeric === "auto") { // "yesterday", "the day before yesterday", etc. if (value === -2 || value === -1) { var message = unitRules["previous".concat(value === -1 ? '' : '-' + Math.abs(value))]; if (message) { return message; } } // "tomorrow", "the day after tomorrow", etc. else if (value === 1 || value === 2) { var _message = unitRules["next".concat(value === 1 ? '' : '-' + Math.abs(value))]; if (_message) { return _message; } } // "today" else if (value === 0) { if (unitRules.current) { return unitRules.current; } } } // Choose either "past" or "future" based on time `value` sign. // If there's only "other" then it's being collapsed. // (the resulting bundle size optimization technique) var quantifierRules = unitRules[value <= 0 ? "past" : "future"]; // Bundle size optimization technique. if (typeof quantifierRules === "string") { return quantifierRules; } // Quantify `value`. var quantify = (0, _LocaleDataStore.getLocaleData)(this.locale).quantify; var quantifier = quantify && quantify(Math.abs(value)); // There seems to be no such locale in CLDR // for which `quantify` is missing // and still `past` and `future` messages // contain something other than "other". /* istanbul ignore next */ quantifier = quantifier || 'other'; // "other" rule is supposed to be always present. // If only "other" rule is present then "rules" is not an object and is a string. return quantifierRules[quantifier] || quantifierRules.other; } /** * Formats a number into a string. * Uses `Intl.NumberFormat` when available. * @param {number} number * @return {string} */ }, { key: "formatNumber", value: function formatNumber(number) { return this.numberFormat ? this.numberFormat.format(number) : String(number); } /** * Returns a new object with properties reflecting the locale and date and time formatting options computed during initialization of this DateTimeFormat object. * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/resolvedOptions * @return {Object} */ }, { key: "resolvedOptions", value: function resolvedOptions() { return { locale: this.locale, style: this.style, numeric: this.numeric }; } }]); return RelativeTimeFormat; }(); /** * Returns an array containing those of the provided locales * that are supported in collation without having to fall back * to the runtime's default locale. * @param {(string|string[])} locale - A string with a BCP 47 language tag, or an array of such strings. For the general form of the locales argument, see the Intl page. * @param {Object} [options] - An object that may have the following property: * @param {string} [options.localeMatcher="lookup"] - The locale matching algorithm to use. Possible values are "lookup" and "best fit". Currently only "lookup" is supported. * @return {string[]} An array of strings representing a subset of the given locale tags that are supported in collation without having to fall back to the runtime's default locale. * @example * var locales = ['ban', 'id-u-co-pinyin', 'es-PY'] * var options = { localeMatcher: 'lookup' } * // Returns ["id", "es-PY"] * Intl.RelativeTimeFormat.supportedLocalesOf(locales, options) */ exports.default = RelativeTimeFormat; RelativeTimeFormat.supportedLocalesOf = function (locales) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; // Convert `locales` to an array. if (typeof locales === 'string') { locales = [locales]; } return locales.filter(function (locale) { return (0, _resolveLocale.default)(locale, options); }); }; /** * Adds locale data for a specific locale. * @param {Object} localeData */ RelativeTimeFormat.addLocale = _LocaleDataStore.addLocaleData; /** * Sets default locale. * @param {string} locale */ RelativeTimeFormat.setDefaultLocale = _LocaleDataStore.setDefaultLocale; /** * Gets default locale. * @return {string} locale */ RelativeTimeFormat.getDefaultLocale = _LocaleDataStore.getDefaultLocale; /** * Extracts language from an IETF BCP 47 language tag. * @param {string} languageTag - IETF BCP 47 language tag. * @return {string} * @example * // Returns "he" * getLanguageFromLanguageTag("he-IL-u-ca-hebrew-tz-jeruslm") * // Returns "ar" * getLanguageFromLanguageTag("ar-u-nu-latn") */ // export function getLanguageFromLanguageTag(languageTag) { // const hyphenIndex = languageTag.indexOf('-') // if (hyphenIndex > 0) { // return languageTag.slice(0, hyphenIndex) // } // return languageTag // } //# sourceMappingURL=RelativeTimeFormat.js.map