276 lines
7.2 KiB
JavaScript
276 lines
7.2 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = extractRelativeTimeMessages;
|
|
|
|
var _RelativeTimeFormat = require("../RelativeTimeFormat");
|
|
|
|
// import { isEqual } from 'lodash'
|
|
// Detects short and narrow flavours of labels (yr., mo., etc).
|
|
// E.g. there are "month", "month-short", "month-narrow".
|
|
// More on "narrow" vs "short":
|
|
// http://cldr.unicode.org/translation/plurals#TOC-Narrow-and-Short-Forms
|
|
var short = /-short$/;
|
|
var narrow = /-narrow$/; // Converts locale data from CLDR format to this library's format.
|
|
//
|
|
// CLDR locale data example:
|
|
//
|
|
// ```json
|
|
// {
|
|
// "main": {
|
|
// "en-US-POSIX": {
|
|
// "identity": {
|
|
// "language": "en",
|
|
// ...
|
|
// },
|
|
// "dates": {
|
|
// "fields": {
|
|
// "year": {
|
|
// "displayName": "year",
|
|
// "relative-type--1": "last year",
|
|
// "relative-type-0": "this year",
|
|
// "relative-type-1": "next year",
|
|
// "relativeTime-type-future": {
|
|
// "relativeTimePattern-count-one": "in {0} year",
|
|
// "relativeTimePattern-count-other": "in {0} years"
|
|
// },
|
|
// "relativeTime-type-past": {
|
|
// "relativeTimePattern-count-one": "{0} year ago",
|
|
// "relativeTimePattern-count-other": "{0} years ago"
|
|
// }
|
|
// },
|
|
// ...
|
|
// ```
|
|
//
|
|
// Parsed locale data example:
|
|
//
|
|
// ```json
|
|
// {
|
|
// "long":
|
|
// {
|
|
// ...
|
|
// "second": [
|
|
// {
|
|
// "one": "a second ago",
|
|
// "other": "{0} seconds ago"
|
|
// },
|
|
// {
|
|
// "one": "in a second",
|
|
// "other": "in {0} seconds"
|
|
// }
|
|
// ],
|
|
// ...
|
|
// },
|
|
// "short":
|
|
// {
|
|
// ...
|
|
// },
|
|
// ...
|
|
// }
|
|
// ```
|
|
|
|
function extractRelativeTimeMessages(localeData) {
|
|
// Extract `locale` from CLDR locale data.
|
|
var locale = Object.keys(localeData.main)[0];
|
|
var timeUnitsFormattingRules = localeData.main[locale].dates.fields;
|
|
return Object.keys(timeUnitsFormattingRules).filter(function (unit) {
|
|
// Take only the generic time measurement units
|
|
// (skip exotic ones like "fri" on "thu").
|
|
return _RelativeTimeFormat.UNITS.indexOf(parseUnit(unit).unit) >= 0;
|
|
}).reduce(function (localeData, _unit) {
|
|
var _parseUnit = parseUnit(_unit),
|
|
unit = _parseUnit.unit,
|
|
type = _parseUnit.type;
|
|
|
|
return setUnitRules(localeData, type, unit, extractTimeUnitFormattingRules(timeUnitsFormattingRules[_unit]));
|
|
}, {});
|
|
}
|
|
/**
|
|
* Parses CLDR time unit formatting rules.
|
|
* @param {object} - CLDR time unit formatting rules.
|
|
* @return {(object|string)}
|
|
*/
|
|
|
|
|
|
function extractTimeUnitFormattingRules(rulesCLDR) {
|
|
var rules = {}; // "relative" values aren't suitable for "ago" or "in a" cases,
|
|
// because "1 year ago" != "last year" (too vague for Jan 30th)
|
|
// and "in 0.49 years" != "this year" (it could be Nov 30th).
|
|
// Still including them here for `Intl.RelativeTimeFormat` polyfill.
|
|
// "yesterday".
|
|
//
|
|
// "the day before yesterday".
|
|
// For example, in German it's "Vorgestern".
|
|
//
|
|
// etc.
|
|
//
|
|
|
|
var previousIndex = 1;
|
|
|
|
while (rulesCLDR["relative-type--".concat(previousIndex)]) {
|
|
rules["previous".concat(previousIndex === 1 ? '' : '-' + previousIndex)] = rulesCLDR["relative-type--".concat(previousIndex)];
|
|
previousIndex++;
|
|
} // "today"
|
|
|
|
/* istanbul ignore else */
|
|
|
|
|
|
if (rulesCLDR['relative-type-0']) {
|
|
rules.current = rulesCLDR['relative-type-0'];
|
|
} // "tomorrow".
|
|
//
|
|
// "the day after tomorrow".
|
|
// For example, in German it's "Übermorgen".
|
|
//
|
|
// etc.
|
|
//
|
|
|
|
|
|
var nextIndex = 1;
|
|
|
|
while (rulesCLDR["relative-type-".concat(nextIndex)]) {
|
|
rules["next".concat(nextIndex === 1 ? '' : '-' + nextIndex)] = rulesCLDR["relative-type-".concat(nextIndex)];
|
|
nextIndex++;
|
|
} // Formatting past times.
|
|
//
|
|
// E.g.:
|
|
//
|
|
// "relativeTime-type-past":
|
|
// {
|
|
// "relativeTimePattern-count-one": "{0} mo. ago",
|
|
// "relativeTimePattern-count-other": "{0} mo. ago"
|
|
// }
|
|
//
|
|
|
|
/* istanbul ignore else */
|
|
|
|
|
|
if (rulesCLDR['relativeTime-type-past']) {
|
|
var past = rulesCLDR['relativeTime-type-past'];
|
|
rules.past = {}; // Populate all quantifiers ("one", "other", etc).
|
|
|
|
var _arr = Object.keys(past);
|
|
|
|
for (var _i = 0; _i < _arr.length; _i++) {
|
|
var quantifier = _arr[_i];
|
|
rules.past[quantifier.replace('relativeTimePattern-count-', '')] = past[quantifier];
|
|
} // Delete all duplicates of "other" rule.
|
|
|
|
|
|
var _arr2 = Object.keys(rules.past);
|
|
|
|
for (var _i2 = 0; _i2 < _arr2.length; _i2++) {
|
|
var _quantifier = _arr2[_i2];
|
|
|
|
if (_quantifier !== 'other' && rules.past[_quantifier] === rules.past.other) {
|
|
delete rules.past[_quantifier];
|
|
}
|
|
} // If only "other" rule is present then "rules" is not an object and is a string.
|
|
|
|
|
|
if (Object.keys(rules.past).length === 1) {
|
|
rules.past = rules.past.other;
|
|
}
|
|
} // Formatting future times.
|
|
//
|
|
// E.g.:
|
|
//
|
|
// "relativeTime-type-future":
|
|
// {
|
|
// "relativeTimePattern-count-one": "in {0} mo.",
|
|
// "relativeTimePattern-count-other": "in {0} mo."
|
|
// }
|
|
//
|
|
|
|
/* istanbul ignore else */
|
|
|
|
|
|
if (rulesCLDR['relativeTime-type-future']) {
|
|
var future = rulesCLDR['relativeTime-type-future'];
|
|
rules.future = {}; // Populate all quantifiers ("one", "other", etc).
|
|
|
|
var _arr3 = Object.keys(future);
|
|
|
|
for (var _i3 = 0; _i3 < _arr3.length; _i3++) {
|
|
var _quantifier2 = _arr3[_i3];
|
|
rules.future[_quantifier2.replace('relativeTimePattern-count-', '')] = future[_quantifier2];
|
|
} // Delete all duplicates of "other" rule.
|
|
|
|
|
|
var _arr4 = Object.keys(rules.future);
|
|
|
|
for (var _i4 = 0; _i4 < _arr4.length; _i4++) {
|
|
var _quantifier3 = _arr4[_i4];
|
|
|
|
if (_quantifier3 !== 'other' && rules.future[_quantifier3] === rules.future.other) {
|
|
delete rules.future[_quantifier3];
|
|
}
|
|
} // If only "other" rule is present then "rules" is not an object and is a string.
|
|
|
|
|
|
if (Object.keys(rules.future).length === 1) {
|
|
rules.future = rules.future.other;
|
|
}
|
|
} // // If `.past` === `.future` then replace them with `.other`.
|
|
// // (only eligible for "tiny" and "*-time" locale data which is not part of CLDR)
|
|
// if (isEqual(rules.past, rules.future)) {
|
|
// rules.other = rules.past
|
|
// delete rules.future
|
|
// }
|
|
// // If only "other" rule is defined for a time unit
|
|
// // then make "rules" a string rather than an object.
|
|
// if (Object.keys(rules).length === 1) {
|
|
// rules = rules.other
|
|
// }
|
|
|
|
|
|
return rules;
|
|
}
|
|
/**
|
|
* Sets time unit formatting rules in locale data.
|
|
* @param {object} localeData
|
|
* @param {string} type
|
|
* @param {string} unit
|
|
* @param {object} rules
|
|
* @return {object} Locale data.
|
|
*/
|
|
|
|
|
|
function setUnitRules(localeData, type, unit, rules) {
|
|
if (!localeData[type]) {
|
|
localeData[type] = {};
|
|
}
|
|
|
|
localeData[type][unit] = rules;
|
|
return localeData;
|
|
}
|
|
/**
|
|
* Parses CLDR time unit into `unit` and `type`.
|
|
* @param {string} CLDR_unit
|
|
* @return {object} `{ type, unit }`.
|
|
*/
|
|
|
|
|
|
function parseUnit(unit) {
|
|
if (narrow.test(unit)) {
|
|
return {
|
|
type: 'narrow',
|
|
unit: unit.replace(narrow, '')
|
|
};
|
|
}
|
|
|
|
if (short.test(unit)) {
|
|
return {
|
|
type: 'short',
|
|
unit: unit.replace(short, '')
|
|
};
|
|
}
|
|
|
|
return {
|
|
type: 'long',
|
|
unit: unit
|
|
};
|
|
}
|
|
//# sourceMappingURL=extractRelativeTimeMessages.js.map
|