diff options
Diffstat (limited to 'ikiwiki/relativedate.js')
-rw-r--r-- | ikiwiki/relativedate.js | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/ikiwiki/relativedate.js b/ikiwiki/relativedate.js new file mode 100644 index 00000000000..2a270d627ab --- /dev/null +++ b/ikiwiki/relativedate.js @@ -0,0 +1,75 @@ +// Causes html elements in the 'relativedate' class to be displayed +// as relative dates. The date is parsed from the title attribute, or from +// the element content. + +var dateElements; + +hook("onload", getDates); + +function getDates() { + dateElements = getElementsByClass('relativedate'); + for (var i = 0; i < dateElements.length; i++) { + var elt = dateElements[i]; + var title = elt.attributes.title; + var d = new Date(title ? title.value : elt.innerHTML); + if (! isNaN(d)) { + dateElements[i].date=d; + elt.title=elt.innerHTML; + } + } + + showDates(); +} + +function showDates() { + for (var i = 0; i < dateElements.length; i++) { + var elt = dateElements[i]; + var d = elt.date; + if (! isNaN(d)) { + elt.innerHTML=relativeDate(d); + } + } + setTimeout(showDates,30000); // keep updating every 30s +} + +var timeUnits = [ + { unit: 'year', seconds: 60 * 60 * 24 * 364 }, + { unit: 'month', seconds: 60 * 60 * 24 * 30 }, + { unit: 'day', seconds: 60 * 60 * 24 }, + { unit: 'hour', seconds: 60 * 60 }, + { unit: 'minute', seconds: 60 }, +]; + +function relativeDate(date) { + var now = new Date(); + var offset = date.getTime() - now.getTime(); + var seconds = Math.round(Math.abs(offset) / 1000); + + // hack to avoid reading just in the future if there is a minor + // amount of clock slip + if (offset >= 0 && seconds < 30 * 60 * 60) { + return "just now"; + } + + var ret = ""; + var shown = 0; + for (i = 0; i < timeUnits.length; i++) { + if (seconds >= timeUnits[i].seconds) { + var num = Math.floor(seconds / timeUnits[i].seconds); + seconds -= num * timeUnits[i].seconds; + if (ret) + ret += "and "; + ret += num + " " + timeUnits[i].unit + (num > 1 ? "s" : "") + " "; + + if (++shown == 2) + break; + } + else if (shown) + break; + } + + if (! ret) + ret = "less than a minute " + + return ret + (offset < 0 ? "ago" : "from now"); +} |