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