c9-core/plugins/c9.nodeapi/timeago.js

132 wiersze
4.5 KiB
JavaScript

define(function(require, exports, module) {
function timeago(timestamp) {
if (timestamp instanceof Date) {
return inWords(timestamp);
} else if (typeof timestamp === "string") {
return inWords(parse(timestamp));
} else if (typeof timestamp === "number") {
return inWords(new Date(timestamp));
} else {
return timeagoElement(timestamp);
}
}
var settings = {
refreshMillis: 60000,
allowFuture: false,
strings: {
prefixAgo: null,
prefixFromNow: null,
suffixAgo: "ago",
suffixFromNow: "from now",
seconds: "less than a minute",
minute: "about a minute",
minutes: "%d minutes",
hour: "about an hour",
hours: "about %d hours",
day: "a day",
days: "%d days",
month: "about a month",
months: "%d months",
year: "about a year",
years: "%d years",
wordSeparator: " ",
numbers: []
}
};
function distanceInWords(distanceMillis) {
var $l = settings.strings;
var prefix = $l.prefixAgo;
var suffix = $l.suffixAgo;
if (settings.allowFuture) {
if (distanceMillis < 0) {
prefix = $l.prefixFromNow;
suffix = $l.suffixFromNow;
}
}
var seconds = Math.abs(distanceMillis) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
var years = days / 365;
function substitute(stringOrFunction, number) {
var string = typeof stringOrFunction === "function" ? stringOrFunction(number, distanceMillis) : stringOrFunction;
var value = ($l.numbers && $l.numbers[number]) || number;
return string.replace(/%d/i, value);
}
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
seconds < 90 && substitute($l.minute, 1) ||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
minutes < 90 && substitute($l.hour, 1) ||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
hours < 42 && substitute($l.day, 1) ||
days < 30 && substitute($l.days, Math.round(days)) ||
days < 45 && substitute($l.month, 1) ||
days < 365 && substitute($l.months, Math.round(days / 30)) ||
years < 1.5 && substitute($l.year, 1) ||
substitute($l.years, Math.round(years));
var separator = $l.wordSeparator || "";
if ($l.wordSeparator === undefined) { separator = " "; }
return [prefix, words, suffix].filter(function(s) { return s; })
.map(function(s) { return s.trim(); })
.join(separator);
}
function parse(iso8601) {
var s = iso8601.trim();
s = s.replace(/\.\d+/, ""); // remove milliseconds
s = s.replace(/-/, "/").replace(/-/, "/");
s = s.replace(/T/, " ").replace(/Z/, " UTC");
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/, " $1$2"); // -04:00 -> -0400
return new Date(s);
}
function datetime(elem) {
var iso8601 = isTime(elem) ? elem.getAttribute("datetime") : elem.getAttribute("title");
return parse(iso8601);
}
function isTime(elem) {
return elem.tagName.toLowerCase() === "time";
}
function timeagoElement(elem) {
refresh(elem);
if (settings.refreshMillis > 0)
setInterval(refresh.bind(null, elem), settings.refreshMillis);
}
function refresh(elem) {
var datetime = prepareDateTime(elem);
if (!isNaN(datetime))
elem.textContent = inWords(datetime);
}
function prepareDateTime(elem) {
var timeagoAttr = elem.getAttribute("timeago");
if (timeagoAttr)
return new Date(timeagoAttr);
var data = datetime(elem);
elem.setAttribute("timeago", data);
var text = elem.textContent.trim();
if (text.length > 0 && !(isTime(elem) && elem.title))
elem.title = text;
return data;
}
function inWords(date) {
return distanceInWords(distance(date));
}
function distance(date) {
return (new Date().getTime() - date.getTime());
}
// fix for IE6 suckage
document.createElement("abbr");
document.createElement("time");
module.exports = timeago;
});