[7588] | 1 | /* |
---|
| 2 | * timeago: a jQuery plugin, version: 0.9.3 (2011-01-21) |
---|
| 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-2011, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org) |
---|
| 15 | */ |
---|
| 16 | |
---|
| 17 | (function($) { |
---|
| 18 | $.timeago = function(timestamp) { |
---|
| 19 | if (timestamp instanceof Date) { |
---|
| 20 | return inWords(timestamp); |
---|
| 21 | } else if (typeof timestamp === "string") { |
---|
| 22 | return inWords($.timeago.parse(timestamp)); |
---|
| 23 | } else { |
---|
| 24 | return inWords($.timeago.datetime(timestamp)); |
---|
| 25 | } |
---|
| 26 | }; |
---|
| 27 | var $t = $.timeago; |
---|
| 28 | |
---|
| 29 | $.extend($.timeago, { |
---|
| 30 | settings: { |
---|
| 31 | refreshMillis: 60000, |
---|
| 32 | allowFuture: false, |
---|
| 33 | strings: { |
---|
| 34 | prefixAgo: null, |
---|
| 35 | prefixFromNow: null, |
---|
| 36 | suffixAgo: "ago", |
---|
| 37 | suffixFromNow: "from now", |
---|
| 38 | seconds: "less than a minute", |
---|
| 39 | minute: "about a minute", |
---|
| 40 | minutes: "%d minutes", |
---|
| 41 | hour: "about an hour", |
---|
| 42 | hours: "about %d hours", |
---|
| 43 | day: "a day", |
---|
| 44 | days: "%d days", |
---|
| 45 | month: "about a month", |
---|
| 46 | months: "%d months", |
---|
| 47 | year: "about a year", |
---|
| 48 | years: "%d years", |
---|
| 49 | numbers: [] |
---|
| 50 | } |
---|
| 51 | }, |
---|
| 52 | inWords: function(distanceMillis) { |
---|
| 53 | var $l = this.settings.strings; |
---|
| 54 | var prefix = $l.prefixAgo; |
---|
| 55 | var suffix = $l.suffixAgo; |
---|
| 56 | if (this.settings.allowFuture) { |
---|
| 57 | if (distanceMillis < 0) { |
---|
| 58 | prefix = $l.prefixFromNow; |
---|
| 59 | suffix = $l.suffixFromNow; |
---|
| 60 | } |
---|
| 61 | distanceMillis = Math.abs(distanceMillis); |
---|
| 62 | } |
---|
| 63 | |
---|
| 64 | var seconds = distanceMillis / 1000; |
---|
| 65 | var minutes = seconds / 60; |
---|
| 66 | var hours = minutes / 60; |
---|
| 67 | var days = hours / 24; |
---|
| 68 | var years = days / 365; |
---|
| 69 | |
---|
| 70 | function substitute(stringOrFunction, number) { |
---|
| 71 | var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; |
---|
| 72 | var value = ($l.numbers && $l.numbers[number]) || number; |
---|
| 73 | return string.replace(/%d/i, value); |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || |
---|
| 77 | seconds < 90 && substitute($l.minute, 1) || |
---|
| 78 | minutes < 45 && substitute($l.minutes, Math.round(minutes)) || |
---|
| 79 | minutes < 90 && substitute($l.hour, 1) || |
---|
| 80 | hours < 24 && substitute($l.hours, Math.round(hours)) || |
---|
| 81 | hours < 48 && substitute($l.day, 1) || |
---|
| 82 | days < 30 && substitute($l.days, Math.floor(days)) || |
---|
| 83 | days < 60 && substitute($l.month, 1) || |
---|
| 84 | days < 365 && substitute($l.months, Math.floor(days / 30)) || |
---|
| 85 | years < 2 && substitute($l.year, 1) || |
---|
| 86 | substitute($l.years, Math.floor(years)); |
---|
| 87 | |
---|
| 88 | return $.trim([prefix, words, suffix].join(" ")); |
---|
| 89 | }, |
---|
| 90 | parse: function(iso8601) { |
---|
| 91 | var s = $.trim(iso8601); |
---|
| 92 | s = s.replace(/\.\d\d\d+/,""); // remove milliseconds |
---|
| 93 | s = s.replace(/-/g,"/"); |
---|
| 94 | s = s.replace(/(\d)T(\d)/,"$1 $2").replace(/(\d)Z/,"$1 UTC"); |
---|
| 95 | s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 |
---|
| 96 | return new Date(s); |
---|
| 97 | }, |
---|
| 98 | datetime: function(elem) { |
---|
| 99 | // jQuery's `is()` doesn't play well with HTML5 in IE |
---|
| 100 | var isTime = $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); |
---|
| 101 | |
---|
| 102 | var iso8601 = null; |
---|
| 103 | |
---|
| 104 | if( isTime ) |
---|
| 105 | { |
---|
| 106 | iso8601 = $(elem).attr("datetime"); |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | if( !iso8601 ) |
---|
| 110 | { |
---|
| 111 | iso8601 = $(elem).attr("title"); |
---|
| 112 | } |
---|
| 113 | |
---|
| 114 | if( !iso8601 ) |
---|
| 115 | { |
---|
| 116 | iso8601 = $(elem).text(); |
---|
| 117 | } |
---|
| 118 | |
---|
| 119 | return $t.parse(iso8601); |
---|
| 120 | } |
---|
| 121 | }); |
---|
| 122 | |
---|
| 123 | $.fn.timeago = function() { |
---|
| 124 | var self = this; |
---|
| 125 | self.each(refresh); |
---|
| 126 | |
---|
| 127 | var $s = $t.settings; |
---|
| 128 | if ($s.refreshMillis > 0) { |
---|
| 129 | setInterval(function() { self.each(refresh); }, $s.refreshMillis); |
---|
| 130 | } |
---|
| 131 | return self; |
---|
| 132 | }; |
---|
| 133 | |
---|
| 134 | function refresh() { |
---|
| 135 | var data = prepareData(this); |
---|
| 136 | if (!isNaN(data.datetime)) { |
---|
| 137 | $(this).text(inWords(data.datetime)); |
---|
| 138 | } |
---|
| 139 | return this; |
---|
| 140 | } |
---|
| 141 | |
---|
| 142 | function prepareData(element) { |
---|
| 143 | element = $(element); |
---|
| 144 | if (!element.data("timeago")) { |
---|
| 145 | element.data("timeago", { datetime: $t.datetime(element) }); |
---|
| 146 | var text = $.trim(element.text()); |
---|
| 147 | if (text.length > 0) { |
---|
| 148 | element.attr("title", text); |
---|
| 149 | } |
---|
| 150 | } |
---|
| 151 | return element.data("timeago"); |
---|
| 152 | } |
---|
| 153 | |
---|
| 154 | function inWords(date) { |
---|
| 155 | return $t.inWords(distance(date)); |
---|
| 156 | } |
---|
| 157 | |
---|
| 158 | function distance(date) { |
---|
| 159 | return (new Date().getTime() - date.getTime()); |
---|
| 160 | } |
---|
| 161 | |
---|
| 162 | // fix for IE6 suckage |
---|
| 163 | document.createElement("abbr"); |
---|
| 164 | document.createElement("time"); |
---|
| 165 | }(jQuery)); |
---|