1/* 2 * timeago: a jQuery plugin, version: 0.9.1 (2010-08-30) 3 * @requires jQuery v1.2.3 or later 4 * 5 * Timeago is a jQuery plugin that makes it easy to support automatically 6 * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago"). 7 * 8 * For usage and examples, visit: 9 * http://timeago.yarp.com/ 10 * 11 * Licensed under the MIT: 12 * http://www.opensource.org/licenses/mit-license.php 13 * 14 * Copyright (c) 2008-2010, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org) 15 */ 16(function($) { 17 $.timeago = function(timestamp) { 18 if (timestamp instanceof Date) return inWords(timestamp); 19 else if (typeof timestamp == "string") return inWords($.timeago.parse(timestamp)); 20 else return inWords($.timeago.datetime(timestamp)); 21 }; 22 var $t = $.timeago; 23 24 $.extend($.timeago, { 25 settings: { 26 refreshMillis: 60000, 27 allowFuture: false, 28 strings: { 29 prefixAgo: null, 30 prefixFromNow: null, 31 suffixAgo: "ago", 32 suffixFromNow: "from now", 33 seconds: "%d seconds", // Local modification. 34 minute: "about a minute", 35 minutes: "%d minutes", 36 hour: "about an hour", 37 hours: "about %d hours", 38 day: "a day", 39 days: "%d days", 40 month: "about a month", 41 months: "%d months", 42 year: "about a year", 43 years: "%d years", 44 numbers: [] 45 } 46 }, 47 inWords: function(distanceMillis) { 48 var $l = this.settings.strings; 49 var prefix = $l.prefixAgo; 50 var suffix = $l.suffixAgo; 51 if (this.settings.allowFuture) { 52 if (distanceMillis < 0) { 53 prefix = $l.prefixFromNow; 54 suffix = $l.suffixFromNow; 55 } 56 distanceMillis = Math.abs(distanceMillis); 57 } 58 59 var seconds = distanceMillis / 1000; 60 var minutes = seconds / 60; 61 var hours = minutes / 60; 62 var days = hours / 24; 63 var years = days / 365; 64 65 function substitute(stringOrFunction, number) { 66 var string = $.isFunction(stringOrFunction) ? stringOrFunction(number) : stringOrFunction; 67 var value = ($l.numbers && $l.numbers[number]) || number; 68 return string.replace(/%d/i, value); 69 } 70 71 var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || 72 seconds < 90 && substitute($l.minute, 1) || 73 minutes < 45 && substitute($l.minutes, Math.round(minutes)) || 74 minutes < 90 && substitute($l.hour, 1) || 75 hours < 24 && substitute($l.hours, Math.round(hours)) || 76 hours < 48 && substitute($l.day, 1) || 77 days < 30 && substitute($l.days, Math.floor(days)) || 78 days < 60 && substitute($l.month, 1) || 79 days < 365 && substitute($l.months, Math.floor(days / 30)) || 80 years < 2 && substitute($l.year, 1) || 81 substitute($l.years, Math.floor(years)); 82 83 return $.trim([prefix, words, suffix].join(" ")); 84 }, 85 parse: function(iso8601) { 86 var s = $.trim(iso8601); 87 s = s.replace(/\.\d\d\d+/,""); // remove milliseconds 88 s = s.replace(/-/,"/").replace(/-/,"/"); 89 s = s.replace(/T/," ").replace(/Z/," UTC"); 90 s = s.replace(/([\+-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 91 return new Date(s); 92 }, 93 datetime: function(elem) { 94 // jQuery's `is()` doesn't play well with HTML5 in IE 95 var isTime = $(elem).get(0).tagName.toLowerCase() == "time"; // $(elem).is("time"); 96 var iso8601 = isTime ? $(elem).attr("datetime") : $(elem).attr("title"); 97 return $t.parse(iso8601); 98 } 99 }); 100 101 $.fn.timeago = function() { 102 var self = this; 103 self.each(refresh); 104 105 var $s = $t.settings; 106 if ($s.refreshMillis > 0) { 107 setInterval(function() { self.each(refresh); }, $s.refreshMillis); 108 } 109 return self; 110 }; 111 112 function refresh() { 113 var data = prepareData(this); 114 if (!isNaN(data.datetime)) { 115 $(this).text(inWords(data.datetime)); 116 } 117 return this; 118 } 119 120 function prepareData(element) { 121 element = $(element); 122 if (!element.data("timeago")) { 123 element.data("timeago", { datetime: $t.datetime(element) }); 124 var text = $.trim(element.text()); 125 if (text.length > 0) element.attr("title", text); 126 } 127 return element.data("timeago"); 128 } 129 130 function inWords(date) { 131 return $t.inWords(distance(date)); 132 } 133 134 function distance(date) { 135 return (new Date().getTime() - date.getTime()); 136 } 137 138 // fix for IE6 suckage 139 document.createElement("abbr"); 140 document.createElement("time"); 141})(jQuery); 142