(function (moduleFactory) {
if (typeof exports === "object") {
module.exports = moduleFactory(require("lodash"), require("moment"));
} else if (typeof define === "function" && define.amd) {
define(["lodash", "moment"], moduleFactory);
} else if (typeof window !== 'undefined' && window != null && window.moment) {
window.HandlebarsMoment = moduleFactory;
// moduleFactory(_, moment);
}
}(function (_, moment) {
/**
* @module handlebars%moment
* @description Helpers providing [Moment.js](http://momentjs.com) functionality
*
* var Handlebars = require("handlebars");
* var MomentHelper = require("handlebars.moment");
* MomentHelper.registerHelpers(Handlebars);
*
* @returns {object} MomentHelper instance
*/
var MomentHelpers = function (Handlebars) {
var momentFormatMap = {
dates: "date",
months: "month",
years: "year",
isoweekday: "isoWeekday",
dayofyear: "dayOfYear",
isoweek: "isoWeek",
isoweeks: "isoWeek",
weekyear: "weekYear",
isoweekyear: "isoWeekYear",
zoneabbr: "zoneAbbr",
zonename: "zoneName",
tostring: "toString",
string: "toString",
str: "toString",
valueof: "valueOf",
value: "valueOf",
val: "valueOf",
fromnow: "fromNow",
daysinmonth: "daysInMonth",
todate: "toDate",
toarray: "toArray",
array: "toArray",
tojson: "toJSON",
json: "toJSON",
toisostring: "toISOString",
isostring: "toISOString"
};
var weekdayMap = {
L: "dddd",
S: "ddd",
XS: "dd"
};
/**
* @template moment
* @block helper
* @param {string|date} [0] Date string|object
* @param {string} [1] Date format / Moment method
* @param {*} [2] Moment method params
* @param {*} [3] Moment method params 1
* @param {*} [4] Moment method params 2
* @param {string|date} [date] Alternative date
* @param {string} [format] Alternative format
* @param {string} [input] Format to use to parse date
* @param {string} [lang] Specific locale to use
* @param {number|string} [type] Type of weekday (L|S|XS|number)
* @param {boolean} [suffix]
* @param {boolean} [utc]
* @param {boolean} [local]
* @param {string} [from]
* @param {string} [unixfrom]
* @param {string} [max]
* @param {string} [min]
* @param {string} [unixmax]
* @param {string} [unixmin]
* @param {string} [startOf]
* @param {string} [endOf]
* @param {number|string} [add]
* @param {number|string} [subtract]
* @param {number} [addparam] Value to use if add is number
* @param {number} [subtractparam] Value to use if subtract is number
* @param {number} [amount] Value to use if add|subtract are strings
* @param {string} [diff]
* @param {string} [unixdiff]
* @param {string} [unitdiff] Value for Moment method params 1 if diff
* @param {boolean} [nosuffix] Value for Moment method params 2 if diff
*
* @description Outputs a date
*
* Current date
*
* {{moment}}
*
* Specific date
*
* {{moment d}}
* {{moment date=d}}
*
* Date format
*
* {{moment d "YY, MMM dd"}}
* {{moment date=d format="DD/MM/YYYY"}}
* {{moment d unix=true}}
*
* Date input parsing
*
* {{moment dinput input="DD-YYYY-MM"}}
*
* Date timezone
*
* {{moment dstr utc=true}}
* {{moment dstr local=true}}
*
* Date units
*
* {{moment d "millisecond"}}
* {{moment d "second"}}
* {{moment d "minute"}}
* {{moment d "hour"}}
* {{moment d "date"}}
* {{moment d "day"}}
* {{moment d "weekday"}}
* {{moment d "weekday" type="s"}}
* {{moment d "weekday" type="xs"}}
* {{moment d "weekday" type="number"}}
* {{moment d "isoweekday"}}
* {{moment d "dayofyear"}}
* {{moment d "week"}}
* {{moment d "isoweek"}}
* {{moment d "month"}}
* {{moment d "year"}}
* {{moment d "weekyear"}}
* {{moment d "isoweekyear"}}
*
* Date manipulation
*
* {{moment d add="days" amount="7"}}
* {{moment d add="365" addparam="d"}}
* {{moment d subtract="days" amount="7"}}
* {{moment d subtract="365" subtractparam="d"}}
*
* Start and end of years
*
* {{moment d startof="year"}}
* {{moment d endof="year"}}
*
* Date max/min
*
* {{moment d max=dmax}}
* {{moment d min=dmin}}
*
* Date from now and specific dates
*
* {{moment d "fromNow"}}
* {{moment d "from" dfrom}}
*
* Difference between dates
*
* {{moment d diff=ddiff}}
*
* Date as calendar time
*
* {{moment d "calendar"}}
*
* Date as strings
*
* {{moment d "str"}}
* {{moment d "val"}}
* {{moment d "unix"}}
*
* Moment utils
*
* {{moment d "daysinmonth"}}
* {{moment d "todate"}}
* {{moment d "array"}}
* {{moment d "isostring"}}
*
* Helper parameters map to those of Moment.js unless noted
*/
Handlebars.registerHelper("moment", function() {
var args = Array.prototype.slice.call(arguments),
options = args.pop(),
date = args.shift(),
format = args.shift(),
formatParams = args.shift(),
formatParams1 = args.shift(),
formatParams2 = args.shift();
if (options.hash && options.hash.params) {
options.hash = _.extend({}, options.hash.params, options.hash);
delete options.hash.params;
}
var params = options.hash;
if (!date) {
date = params.date;
}
function marshallDate (date, unix) {
if (typeof date === "string" && date.match(/^\d+(\.\d+){0,1}$/)) {
date = +date;
}
if (unix && typeof date === "number") {
date = date * 1000;
}
return date;
}
date = marshallDate(date, params.unix);
var max = marshallDate(params.max, params.unixmax);
var min = marshallDate(params.min, params.unixmin);
if (!format) {
format = params.format || params.fn;
}
if (momentFormatMap[format]) {
format = momentFormatMap[format];
}
if (format === "weekday") {
params.type = params.type ? params.type.toUpperCase() : null;
if (params.type !== "NUMBER") {
if (weekdayMap[params.type]) {
format = weekdayMap[params.type];
} else {
format = weekdayMap.L;
}
}
}
var ofMethod = "start";
var ofType = params.startOf || params.startof;
if (!ofType) {
ofType = params.endOf || params.endof;
if (ofType) {
ofMethod = "end";
}
}
/*if (!formatParams) {
formatParams = params.formatparams || params.fnparams;
if (formatParams === undefined) {
if (params.suffix !== undefined) {
formatParams = params.suffix;
}
}
}*/
var momentObj;
if (moment.isMoment(date)) {
momentObj = date.clone();
} else {
var momentFn = params.utc ? moment.utc : moment;
momentObj = momentFn(date, params.input);
}
if (params.lang) {
momentObj.lang(params.lang);
}
if (max) {
momentObj = moment.max(moment(max), momentObj);
}
if (min) {
momentObj = moment.min(moment(min), momentObj);
}
if (ofType) {
momentObj = momentObj[ofMethod + "Of"](ofType);
}
if (params.nosuffix === undefined && params.suffix !== undefined) {
params.nosuffix = !params.suffix;
}
if (params.from) {
format = "from";
formatParams = marshallDate(params.from, params.unixfrom);
}
if (format === "fromNow") {
if (formatParams === undefined) {
formatParams = params.nosuffix;
}
}
if (format === "from") {
if (formatParams1 === undefined) {
formatParams1 = params.nosuffix;
}
}
if (params.diff) {
format = "diff";
formatParams = marshallDate(params.diff, params.unixdiff);
}
if (format === "diff") {
if (formatParams1 === undefined) {
formatParams1 = params.unitdiff;
}
if (formatParams2 === undefined) {
formatParams2 = params.nosuffix;
}
}
function manipulateMoment (method) {
var arg = params[method];
if (arg) {
var argParam = params[method + "param"];
if (argParam === undefined) {
argParam = params.amount;
}
var args = arg;
if (argParam) {
var addNum = +arg;
args = {};
if (isNaN(addNum)) {
args[arg] = +argParam;
} else {
args[argParam] = addNum;
}
}
momentObj[method](args);
}
}
manipulateMoment("add");
manipulateMoment("subtract");
if (params.local) {
momentObj.local();
} else if (params.utc) {
momentObj.utc();
}
var momentOutput = momentObj[format] ? momentObj[format](formatParams, formatParams1, formatParams2) : momentObj.format(format);
return momentOutput;
});
var durationMethodMap = {
asmilliseconds: "asMilliseconds",
asseconds: "asSeconds",
asminutes: "asMinutes",
ashours: "asHours",
asdays: "asDays",
asweeks: "asWeeks",
asmonths: "asMonths",
asyears: "asYears"
};
var durationGetArray = [
"ms",
"s",
"m",
"h",
"d",
"w",
"M",
"y"
];
var durationGetMap = {};
for (var i in durationGetArray) {
durationGetMap[durationGetArray[i]] = true;
}
/**
* @template duration
* @block helper
* @param {string} [duration] Length of duration
* @param {string} [input] Unit of duration
* @param {number} [add]
* @param {number} [subtract]
* @param {number} [addunit|addparam]
* @param {number} [subtractunit|subtractparam]
* @param {string} [as] Sets duration method to as
* @param {string} [get] Sets duration method to get
* @param {string} [humanize] Sets duration method to humanize
* @param {boolean} [suffix=false]
*
* @description Outputs a duration
*
* Duration - implictly in milliseconds
*
* {{duration d}}
*
* Duration with explicit input date unit type
*
* {{duration d input="s"}}
*
* Amount of date units in duration
*
* {{duration d "seconds"}}
* {{duration d "minutes"}}
* {{duration d "years"}}
* {{duration d get="seconds"}}
* {{duration d "s"}}
*
* Duration as date units
*
* {{duration d "asseconds"}}
* {{duration d "asminutes"}}
* {{duration d "asyears"}}
* {{duration d as="seconds"}}
*
* Humanize duration output
*
* {{duration d "humanize"}}
* {{duration d "humanize" true}}
* {{duration d suffix=true}}
*
* Manipulate durations
*
* {{duration d add=damount as="milliseconds"}}
* {{duration d subtract=damount as="seconds"}}
* {{duration d subtract=damount as="days"}}
*/
Handlebars.registerHelper("duration", function() {
var args = Array.prototype.slice.call(arguments),
options = args.pop(),
duration = args.shift(),
method = args.shift(),
methodArg = args.shift();
if (options.hash && options.hash.params) {
options.hash = _.extend({}, options.hash.params, options.hash);
delete options.hash.params;
}
var params = options.hash;
if (!duration) {
duration = params.duration;
}
if (typeof duration === "string" && duration.match(/^\d+$/)) {
duration = +duration;
}
var durationObj = moment.duration(duration, params.input);
function manipulateDuration (method) {
var arg = params[method];
if (arg) {
if (!isNaN(+arg)) {
arg = +arg;
}
var argParam = params[method + "unit"];
if (argParam === undefined) {
argParam = params[method + "param"];
}
durationObj[method](arg, argParam);
}
}
manipulateDuration("add");
manipulateDuration("subtract");
if (!method) {
method = params.method;
}
if (durationGetMap[method]) {
methodArg = method;
method = "get";
}
if (durationMethodMap[method]) {
method = durationMethodMap[method];
}
if (params.as) {
method = "as";
methodArg = params.as;
} else if (params.get) {
method = "get";
methodArg = params.get;
}
if (!durationObj[method]) {
method = "humanize";
}
if (method === "humanize") {
if (methodArg === undefined) {
methodArg = params.suffix;
}
}
return durationObj[method](methodArg);
});
};
var external = {
/**
* @method registerHelpers
* @static
* @param {object} hbars Handlebars instance
* @description Register MomentHelper helpers with Handlebars
*
* - {@link template:moment}
* - {@link template:duration}
*/
registerHelpers: function (hbars) {
MomentHelpers(hbars);
}
};
return external;
}));