From: Maggie Pint Date: Wed, 11 May 2016 04:16:03 +0000 (-0500) Subject: make moment calendar extensible with ad-hoc options X-Git-Tag: 2.14.0~25^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c0f40b21d230c2ce550c1e25c89bc11bfd6a2e5;p=thirdparty%2Fmoment.git make moment calendar extensible with ad-hoc options --- diff --git a/src/lib/locale/calendar.js b/src/lib/locale/calendar.js index e9cad6d18..f12214b86 100644 --- a/src/lib/locale/calendar.js +++ b/src/lib/locale/calendar.js @@ -10,6 +10,6 @@ export var defaultCalendar = { import isFunction from '../utils/is-function'; export function calendar (key, mom, now) { - var output = this._calendar[key]; + var output = this._calendar[key] || this._calendar['sameElse']; return isFunction(output) ? output.call(mom, now) : output; } diff --git a/src/lib/moment/calendar.js b/src/lib/moment/calendar.js index 4f4a9a72f..4b5725c58 100644 --- a/src/lib/moment/calendar.js +++ b/src/lib/moment/calendar.js @@ -1,19 +1,24 @@ import { createLocal } from '../create/local'; import { cloneWithOffset } from '../units/offset'; import isFunction from '../utils/is-function'; +import { hooks } from '../utils/hooks'; -export function calendar (time, formats) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're local/utc/offset or not. - var now = time || createLocal(), - sod = cloneWithOffset(now, this).startOf('day'), - diff = this.diff(sod, 'days', true), - format = diff < -6 ? 'sameElse' : +export function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; +} + +export function calendar (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); diff --git a/src/lib/moment/prototype.js b/src/lib/moment/prototype.js index 817889090..0fa829381 100644 --- a/src/lib/moment/prototype.js +++ b/src/lib/moment/prototype.js @@ -3,7 +3,7 @@ import { Moment } from './constructor'; var proto = Moment.prototype; import { add, subtract } from './add-subtract'; -import { calendar } from './calendar'; +import { calendar, getCalendarFormat } from './calendar'; import { clone } from './clone'; import { isBefore, isBetween, isSame, isAfter, isSameOrAfter, isSameOrBefore } from './compare'; import { diff } from './diff'; @@ -20,6 +20,7 @@ import { creationData } from './creation-data'; proto.add = add; proto.calendar = calendar; +proto.calendarFormat = getCalendarFormat; proto.clone = clone; proto.diff = diff; proto.endOf = endOf; diff --git a/src/moment.js b/src/moment.js index 6d330956b..74df19809 100644 --- a/src/moment.js +++ b/src/moment.js @@ -21,6 +21,10 @@ import { createInZone as parseZone } from './lib/moment/moment'; +import { + getCalendarFormat +} from './lib/moment/calendar'; + import { defineLocale, updateLocale, @@ -72,6 +76,7 @@ moment.weekdaysShort = weekdaysShort; moment.normalizeUnits = normalizeUnits; moment.relativeTimeRounding = relativeTimeRounding; moment.relativeTimeThreshold = relativeTimeThreshold; +moment.calendarFormat = getCalendarFormat; moment.prototype = fn; export default moment; diff --git a/src/test/moment/calendar.js b/src/test/moment/calendar.js index b7cffaa2b..36af6848f 100644 --- a/src/test/moment/calendar.js +++ b/src/test/moment/calendar.js @@ -14,4 +14,44 @@ test('passing a function', function (assert) { }), '1:00PM', 'should equate'); }); +test('extending calendar options', function (assert) { + var calendarFormat = moment.calendarFormat; + moment.calendarFormat = function (myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + var nextMonth = now.clone().add(1, 'month'); + + var retVal = diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : + (myMoment.month() === now.month() && myMoment.year() === now.year()) ? 'thisMonth' : + (nextMonth.month() === myMoment.month() && nextMonth.year() === myMoment.year()) ? 'nextMonth' : 'sameElse'; + return retVal; + }; + + moment.updateLocale('en', { + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + thisMonth : '[This month on the] Do', + nextMonth : '[Next month on the] Do', + sameElse : 'L' + } + }); + var a = moment('2016-01-01').add(28, 'days'); + var b = moment('2016-01-01').add(1, 'month'); + try { + assert.equal(a.calendar('2016-01-01'), 'This month on the 29th', 'Ad hoc calendar format for this month'); + assert.equal(b.calendar('2016-01-01'), 'Next month on the 1st', 'Ad hoc calendar format for next month'); + assert.equal(a.locale('fr').calendar('2016-01-01'), a.locale('fr').format('L'), 'French falls back to default because thisMonth is not defined in that locale'); + } finally { + moment.calendarFormat = calendarFormat; + moment.updateLocale('en', null); + } +});