1 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
2 |
|
3 | function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
4 |
|
5 | function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
6 |
|
7 | function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
8 |
|
9 | function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
10 |
|
11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
12 |
|
13 | 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); } }
|
14 |
|
15 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
16 |
|
17 | import RelativeTimeFormatPolyfill from 'relative-time-format';
|
18 | import Cache from './cache';
|
19 | import chooseLocale from './locale';
|
20 | import getStep from './steps/getStep';
|
21 | import getStepDenominator from './steps/getStepDenominator';
|
22 | import getTimeToNextUpdate from './steps/getTimeToNextUpdate';
|
23 | import { addLocaleData, getLocaleData } from './LocaleDataStore';
|
24 | import defaultStyle from './style/roundMinute';
|
25 | import getStyleByName from './style/getStyleByName';
|
26 | import { getRoundFunction } from './round';
|
27 |
|
28 | var UNITS = ['now',
|
29 | 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'];
|
30 |
|
31 | var TimeAgo =
|
32 |
|
33 | function () {
|
34 | |
35 |
|
36 |
|
37 |
|
38 | function TimeAgo() {
|
39 | var locales = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
40 |
|
41 | var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
42 | polyfill = _ref.polyfill;
|
43 |
|
44 | _classCallCheck(this, TimeAgo);
|
45 |
|
46 |
|
47 | if (typeof locales === 'string') {
|
48 | locales = [locales];
|
49 | }
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | this.locale = chooseLocale(locales.concat(TimeAgo.getDefaultLocale()), getLocaleData);
|
55 |
|
56 | if (typeof Intl !== 'undefined') {
|
57 |
|
58 | if (Intl.NumberFormat) {
|
59 | this.numberFormat = new Intl.NumberFormat(this.locale);
|
60 | }
|
61 | }
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | if (polyfill === false) {
|
68 | this.IntlRelativeTimeFormat = Intl.RelativeTimeFormat;
|
69 | this.IntlPluralRules = Intl.PluralRules;
|
70 | } else {
|
71 | this.IntlRelativeTimeFormat = RelativeTimeFormatPolyfill;
|
72 | this.IntlPluralRules = RelativeTimeFormatPolyfill.PluralRules;
|
73 | }
|
74 |
|
75 |
|
76 | this.relativeTimeFormatCache = new Cache();
|
77 |
|
78 | this.pluralRulesCache = new Cache();
|
79 | }
|
80 | |
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | _createClass(TimeAgo, [{
|
100 | key: "format",
|
101 | value: function format(input, style, options) {
|
102 | if (!options) {
|
103 | if (style && !isStyle(style)) {
|
104 | options = style;
|
105 | style = undefined;
|
106 | } else {
|
107 | options = {};
|
108 | }
|
109 | }
|
110 |
|
111 | if (!style) {
|
112 | style = defaultStyle;
|
113 | }
|
114 |
|
115 | if (typeof style === 'string') {
|
116 | style = getStyleByName(style);
|
117 | }
|
118 |
|
119 | var timestamp = getTimestamp(input);
|
120 |
|
121 |
|
122 | var _this$getLabels = this.getLabels(style.flavour || style.labels),
|
123 | labels = _this$getLabels.labels,
|
124 | labelsType = _this$getLabels.labelsType;
|
125 |
|
126 | var now;
|
127 |
|
128 |
|
129 |
|
130 |
|
131 | if (style.now !== undefined) {
|
132 | now = style.now;
|
133 | }
|
134 |
|
135 |
|
136 | if (now === undefined && options.now !== undefined) {
|
137 | now = options.now;
|
138 | }
|
139 |
|
140 | if (now === undefined) {
|
141 | now = Date.now();
|
142 | }
|
143 |
|
144 |
|
145 | var secondsPassed = (now - timestamp) / 1000;
|
146 |
|
147 | var future = options.future || secondsPassed < 0;
|
148 | var nowLabel = getNowLabel(labels, getLocaleData(this.locale).now, getLocaleData(this.locale).long, future);
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 | if (style.custom) {
|
162 | var custom = style.custom({
|
163 | now: now,
|
164 | date: new Date(timestamp),
|
165 | time: timestamp,
|
166 | elapsed: secondsPassed,
|
167 | locale: this.locale
|
168 | });
|
169 |
|
170 | if (custom !== undefined) {
|
171 |
|
172 |
|
173 | return custom;
|
174 | }
|
175 | }
|
176 |
|
177 |
|
178 | var units = getTimeIntervalMeasurementUnits(
|
179 |
|
180 | style.units, labels, nowLabel);
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 | var round = options.round || style.round;
|
187 |
|
188 |
|
189 | var _getStep = getStep(
|
190 |
|
191 |
|
192 | style.gradation || style.steps || defaultStyle.steps, secondsPassed, {
|
193 | now: now,
|
194 | units: units,
|
195 | round: round,
|
196 | future: future,
|
197 | getNextStep: true
|
198 | }),
|
199 | _getStep2 = _slicedToArray(_getStep, 3),
|
200 | prevStep = _getStep2[0],
|
201 | step = _getStep2[1],
|
202 | nextStep = _getStep2[2];
|
203 |
|
204 | var formattedDate = this.formatDateForStep(timestamp, step, secondsPassed, {
|
205 | labels: labels,
|
206 | labelsType: labelsType,
|
207 | nowLabel: nowLabel,
|
208 | now: now,
|
209 | future: future,
|
210 | round: round
|
211 | }) || '';
|
212 |
|
213 | if (options.getTimeToNextUpdate) {
|
214 | var timeToNextUpdate = getTimeToNextUpdate(timestamp, step, {
|
215 | nextStep: nextStep,
|
216 | prevStep: prevStep,
|
217 | now: now,
|
218 | future: future,
|
219 | round: round
|
220 | });
|
221 | return [formattedDate, timeToNextUpdate];
|
222 | }
|
223 |
|
224 | return formattedDate;
|
225 | }
|
226 | }, {
|
227 | key: "formatDateForStep",
|
228 | value: function formatDateForStep(timestamp, step, secondsPassed, _ref2) {
|
229 | var _this = this;
|
230 |
|
231 | var labels = _ref2.labels,
|
232 | labelsType = _ref2.labelsType,
|
233 | nowLabel = _ref2.nowLabel,
|
234 | now = _ref2.now,
|
235 | future = _ref2.future,
|
236 | round = _ref2.round;
|
237 |
|
238 |
|
239 | if (!step) {
|
240 | return;
|
241 | }
|
242 |
|
243 | if (step.format) {
|
244 | return step.format(timestamp, this.locale, {
|
245 | formatAs: function formatAs(unit, value) {
|
246 |
|
247 | return _this.formatValue(value, unit, {
|
248 | labels: labels,
|
249 | future: future
|
250 | });
|
251 | },
|
252 | now: now,
|
253 | future: future
|
254 | });
|
255 | }
|
256 |
|
257 |
|
258 | var unit = step.unit || step.formatAs;
|
259 |
|
260 | if (!unit) {
|
261 | throw new Error("[javascript-time-ago] Each step must define either `formatAs` or `format()`. Step: ".concat(JSON.stringify(step)));
|
262 | }
|
263 |
|
264 |
|
265 |
|
266 | if (unit === 'now') {
|
267 | return nowLabel;
|
268 | }
|
269 |
|
270 |
|
271 | var amount = Math.abs(secondsPassed) / getStepDenominator(step);
|
272 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 | if (step.granularity) {
|
284 |
|
285 | amount = getRoundFunction(round)(amount / step.granularity) * step.granularity;
|
286 | }
|
287 |
|
288 | var valueForFormatting = -1 * Math.sign(secondsPassed) * getRoundFunction(round)(amount);
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 | if (valueForFormatting === 0) {
|
296 | if (future) {
|
297 | valueForFormatting = 0;
|
298 | } else {
|
299 | valueForFormatting = -0;
|
300 | }
|
301 | }
|
302 |
|
303 | switch (labelsType) {
|
304 | case 'long':
|
305 | case 'short':
|
306 | case 'narrow':
|
307 |
|
308 | return this.getFormatter(labelsType).format(valueForFormatting, unit);
|
309 |
|
310 | default:
|
311 |
|
312 |
|
313 | return this.formatValue(valueForFormatting, unit, {
|
314 | labels: labels,
|
315 | future: future
|
316 | });
|
317 | }
|
318 | }
|
319 | |
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 |
|
328 | }, {
|
329 | key: "formatValue",
|
330 | value: function formatValue(value, unit, _ref3) {
|
331 | var labels = _ref3.labels,
|
332 | future = _ref3.future;
|
333 | return this.getFormattingRule(labels, unit, value, {
|
334 | future: future
|
335 | }).replace('{0}', this.formatNumber(Math.abs(value)));
|
336 | }
|
337 | |
338 |
|
339 |
|
340 |
|
341 |
|
342 |
|
343 |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 | }, {
|
350 | key: "getFormattingRule",
|
351 | value: function getFormattingRule(formattingRules, unit, value, _ref4) {
|
352 | var future = _ref4.future;
|
353 |
|
354 |
|
355 | var locale = this.locale;
|
356 | formattingRules = formattingRules[unit];
|
357 |
|
358 |
|
359 |
|
360 |
|
361 | if (typeof formattingRules === 'string') {
|
362 | return formattingRules;
|
363 | }
|
364 |
|
365 |
|
366 |
|
367 |
|
368 | var pastOrFuture = value === 0 ? future ? 'future' : 'past' : value < 0 ? 'past' : 'future';
|
369 | var quantifierRules = formattingRules[pastOrFuture] || formattingRules;
|
370 |
|
371 | if (typeof quantifierRules === 'string') {
|
372 | return quantifierRules;
|
373 | }
|
374 |
|
375 |
|
376 | var quantifier = this.getPluralRules().select(Math.abs(value));
|
377 |
|
378 |
|
379 | return quantifierRules[quantifier] || quantifierRules.other;
|
380 | }
|
381 | |
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 | }, {
|
389 | key: "formatNumber",
|
390 | value: function formatNumber(number) {
|
391 | return this.numberFormat ? this.numberFormat.format(number) : String(number);
|
392 | }
|
393 | |
394 |
|
395 |
|
396 |
|
397 |
|
398 |
|
399 | }, {
|
400 | key: "getFormatter",
|
401 | value: function getFormatter(labelsType) {
|
402 |
|
403 |
|
404 | return this.relativeTimeFormatCache.get(this.locale, labelsType) || this.relativeTimeFormatCache.put(this.locale, labelsType, new this.IntlRelativeTimeFormat(this.locale, {
|
405 | style: labelsType
|
406 | }));
|
407 | }
|
408 | |
409 |
|
410 |
|
411 |
|
412 |
|
413 | }, {
|
414 | key: "getPluralRules",
|
415 | value: function getPluralRules() {
|
416 |
|
417 |
|
418 | return this.pluralRulesCache.get(this.locale) || this.pluralRulesCache.put(this.locale, new this.IntlPluralRules(this.locale));
|
419 | }
|
420 | |
421 |
|
422 |
|
423 |
|
424 |
|
425 |
|
426 |
|
427 |
|
428 |
|
429 |
|
430 | }, {
|
431 | key: "getLabels",
|
432 | value: function getLabels() {
|
433 | var labelsType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
434 |
|
435 |
|
436 | if (typeof labelsType === 'string') {
|
437 | labelsType = [labelsType];
|
438 | }
|
439 |
|
440 |
|
441 | labelsType = labelsType.map(function (labelsType) {
|
442 | switch (labelsType) {
|
443 | case 'tiny':
|
444 | case 'mini-time':
|
445 | return 'mini';
|
446 |
|
447 | default:
|
448 | return labelsType;
|
449 | }
|
450 | });
|
451 |
|
452 |
|
453 | labelsType = labelsType.concat('long');
|
454 |
|
455 | var localeData = getLocaleData(this.locale);
|
456 |
|
457 | for (var _iterator = labelsType, _isArray = Array.isArray(_iterator), _i2 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
458 | var _ref5;
|
459 |
|
460 | if (_isArray) {
|
461 | if (_i2 >= _iterator.length) break;
|
462 | _ref5 = _iterator[_i2++];
|
463 | } else {
|
464 | _i2 = _iterator.next();
|
465 | if (_i2.done) break;
|
466 | _ref5 = _i2.value;
|
467 | }
|
468 |
|
469 | var _labelsType = _ref5;
|
470 |
|
471 | if (localeData[_labelsType]) {
|
472 | return {
|
473 | labelsType: _labelsType,
|
474 | labels: localeData[_labelsType]
|
475 | };
|
476 | }
|
477 | }
|
478 | }
|
479 | }]);
|
480 |
|
481 | return TimeAgo;
|
482 | }();
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 | export { TimeAgo as default };
|
489 | var defaultLocale = 'en';
|
490 |
|
491 |
|
492 |
|
493 |
|
494 |
|
495 | TimeAgo.getDefaultLocale = function () {
|
496 | return defaultLocale;
|
497 | };
|
498 |
|
499 |
|
500 |
|
501 |
|
502 |
|
503 |
|
504 | TimeAgo.setDefaultLocale = function (locale) {
|
505 | return defaultLocale = locale;
|
506 | };
|
507 |
|
508 |
|
509 |
|
510 |
|
511 |
|
512 |
|
513 | TimeAgo.addDefaultLocale = function (localeData) {
|
514 | if (defaultLocaleHasBeenSpecified) {
|
515 | return console.error('[javascript-time-ago] `TimeAgo.addDefaultLocale()` can only be called once. To add other locales, use `TimeAgo.addLocale()`.');
|
516 | }
|
517 |
|
518 | defaultLocaleHasBeenSpecified = true;
|
519 | TimeAgo.setDefaultLocale(localeData.locale);
|
520 | TimeAgo.addLocale(localeData);
|
521 | };
|
522 |
|
523 | var defaultLocaleHasBeenSpecified;
|
524 |
|
525 |
|
526 |
|
527 |
|
528 |
|
529 | TimeAgo.addLocale = function (localeData) {
|
530 | addLocaleData(localeData);
|
531 | RelativeTimeFormatPolyfill.addLocale(localeData);
|
532 | };
|
533 |
|
534 |
|
535 |
|
536 |
|
537 |
|
538 |
|
539 |
|
540 |
|
541 | TimeAgo.locale = TimeAgo.addLocale;
|
542 |
|
543 |
|
544 |
|
545 |
|
546 |
|
547 |
|
548 |
|
549 | TimeAgo.addLabels = function (locale, name, labels) {
|
550 | var localeData = getLocaleData(locale);
|
551 |
|
552 | if (!localeData) {
|
553 | addLocaleData({
|
554 | locale: locale
|
555 | });
|
556 | localeData = getLocaleData(locale);
|
557 | }
|
558 |
|
559 | localeData[name] = labels;
|
560 | };
|
561 |
|
562 |
|
563 | function getTimestamp(input) {
|
564 | if (input.constructor === Date || isMockedDate(input)) {
|
565 | return input.getTime();
|
566 | }
|
567 |
|
568 | if (typeof input === 'number') {
|
569 | return input;
|
570 | }
|
571 |
|
572 |
|
573 |
|
574 |
|
575 | throw new Error("Unsupported relative time formatter input: ".concat(_typeof(input), ", ").concat(input));
|
576 | }
|
577 |
|
578 |
|
579 |
|
580 | function isMockedDate(object) {
|
581 | return _typeof(object) === 'object' && typeof object.getTime === 'function';
|
582 | }
|
583 |
|
584 |
|
585 | function getTimeIntervalMeasurementUnits(allowedUnits, labels, nowLabel) {
|
586 |
|
587 |
|
588 | var units = Object.keys(labels);
|
589 |
|
590 |
|
591 |
|
592 |
|
593 | if (nowLabel) {
|
594 | units.push('now');
|
595 | }
|
596 |
|
597 |
|
598 |
|
599 | if (allowedUnits) {
|
600 | units = allowedUnits.filter(function (unit) {
|
601 | return unit === 'now' || units.indexOf(unit) >= 0;
|
602 | });
|
603 | }
|
604 |
|
605 | return units;
|
606 | }
|
607 |
|
608 | function getNowLabel(labels, nowLabels, longLabels, future) {
|
609 | var nowLabel = labels.now || nowLabels && nowLabels.now;
|
610 |
|
611 | if (nowLabel) {
|
612 |
|
613 | if (typeof nowLabel === 'string') {
|
614 | return nowLabel;
|
615 | }
|
616 |
|
617 |
|
618 |
|
619 |
|
620 |
|
621 |
|
622 | if (future) {
|
623 | return nowLabel.future;
|
624 | } else {
|
625 | return nowLabel.past;
|
626 | }
|
627 | }
|
628 |
|
629 |
|
630 | if (longLabels && longLabels.second && longLabels.second.current) {
|
631 | return longLabels.second.current;
|
632 | }
|
633 | }
|
634 |
|
635 | var OBJECT_CONSTRUCTOR = {}.constructor;
|
636 |
|
637 | function isObject(object) {
|
638 | return _typeof(object) !== undefined && object !== null && object.constructor === OBJECT_CONSTRUCTOR;
|
639 | }
|
640 |
|
641 | function isStyle(variable) {
|
642 | return typeof variable === 'string' || isStyleObject(variable);
|
643 | }
|
644 |
|
645 | export function isStyleObject(object) {
|
646 | return isObject(object) && (Array.isArray(object.steps) ||
|
647 | Array.isArray(object.gradation) ||
|
648 | Array.isArray(object.flavour) || typeof object.flavour === 'string' || Array.isArray(object.labels) || typeof object.labels === 'string' ||
|
649 | Array.isArray(object.units) ||
|
650 | typeof object.custom === 'function');
|
651 | }
|
652 |
|
\ | No newline at end of file |