vendor: 7,133 bytes, lines 1-223
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 1.4.3 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-2015, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org) 15 */ 16 17(function (factory) { 18 if (typeof define === 'function' && define.amd) { 19 // AMD. Register as an anonymous module. 20 define(['jquery'], factory); 21 } else if (typeof module === 'object' && typeof module.exports === 'object') { 22 factory(require('jquery')); 23 } else { 24 // Browser globals 25 factory(jQuery); 26 } 27}(function ($) { 28 $.timeago = function(timestamp) { 29 if (timestamp instanceof Date) { 30 return inWords(timestamp); 31 } else if (typeof timestamp === "string") { 32 return inWords($.timeago.parse(timestamp)); 33 } else if (typeof timestamp === "number") { 34 return inWords(new Date(timestamp)); 35 } else { 36 return inWords($.timeago.datetime(timestamp)); 37 } 38 }; 39 var $t = $.timeago; 40 41 $.extend($.timeago, { 42 settings: { 43 refreshMillis: 60000, 44 allowPast: true, 45 allowFuture: false, 46 localeTitle: false, 47 cutoff: 0, 48 strings: { 49 prefixAgo: null, 50 prefixFromNow: null, 51 suffixAgo: "ago", 52 suffixFromNow: "from now", 53 inPast: 'any moment now', 54 seconds: "less than a minute", 55 minute: "about a minute", 56 minutes: "%d minutes", 57 hour: "about an hour", 58 hours: "about %d hours", 59 day: "a day", 60 days: "%d days", 61 month: "about a month", 62 months: "%d months", 63 year: "about a year", 64 years: "%d years", 65 wordSeparator: " ", 66 numbers: [] 67 } 68 }, 69 70 inWords: function(distanceMillis) { 71 if(!this.settings.allowPast && ! this.settings.allowFuture) { 72 throw 'timeago allowPast and allowFuture settings can not both be set to false.'; 73 } 74 75 var $l = this.settings.strings; 76 var prefix = $l.prefixAgo; 77 var suffix = $l.suffixAgo; 78 if (this.settings.allowFuture) { 79 if (distanceMillis < 0) { 80 prefix = $l.prefixFromNow; 81 suffix = $l.suffixFromNow; 82 } 83 } 84 85 if(!this.settings.allowPast && distanceMillis >= 0) { 86 return this.settings.strings.inPast; 87 } 88 89 var seconds = Math.abs(distanceMillis) / 1000; 90 var minutes = seconds / 60; 91 var hours = minutes / 60; 92 var days = hours / 24; 93 var years = days / 365; 94 95 function substitute(stringOrFunction, number) { 96 var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; 97 var value = ($l.numbers && $l.numbers[number]) || number; 98 return string.replace(/%d/i, value); 99 } 100 101 var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || 102 seconds < 90 && substitute($l.minute, 1) || 103 minutes < 45 && substitute($l.minutes, Math.round(minutes)) || 104 minutes < 90 && substitute($l.hour, 1) || 105 hours < 24 && substitute($l.hours, Math.round(hours)) || 106 hours < 42 && substitute($l.day, 1) || 107 days < 30 && substitute($l.days, Math.round(days)) || 108 days < 45 && substitute($l.month, 1) || 109 days < 365 && substitute($l.months, Math.round(days / 30)) || 110 years < 1.5 && substitute($l.year, 1) || 111 substitute($l.years, Math.round(years)); 112 113 var separator = $l.wordSeparator || ""; 114 if ($l.wordSeparator === undefined) { separator = " "; } 115 return $.trim([prefix, words, suffix].join(separator)); 116 }, 117 118 parse: function(iso8601) { 119 var s = $.trim(iso8601); 120 s = s.replace(/\.\d+/,""); // remove milliseconds 121 s = s.replace(/-/,"/").replace(/-/,"/"); 122 s = s.replace(/T/," ").replace(/Z/," UTC"); 123 s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 124 s = s.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900 125 return new Date(s); 126 }, 127 datetime: function(elem) { 128 var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title"); 129 return $t.parse(iso8601); 130 }, 131 isTime: function(elem) { 132 // jQuery's `is()` doesn't play well with HTML5 in IE 133 return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); 134 } 135 }); 136 137 // functions that can be called via $(el).timeago('action') 138 // init is default when no action is given 139 // functions are called with context of a single element 140 var functions = { 141 init: function(){ 142 var refresh_el = $.proxy(refresh, this); 143 refresh_el(); 144 var $s = $t.settings; 145 if ($s.refreshMillis > 0) { 146 this._timeagoInterval = setInterval(refresh_el, $s.refreshMillis); 147 } 148 }, 149 update: function(time){ 150 var parsedTime = $t.parse(time); 151 $(this).data('timeago', { datetime: parsedTime }); 152 if($t.settings.localeTitle) $(this).attr("title", parsedTime.toLocaleString()); 153 refresh.apply(this); 154 }, 155 updateFromDOM: function(){ 156 $(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) }); 157 refresh.apply(this); 158 }, 159 dispose: function () { 160 if (this._timeagoInterval) { 161 window.clearInterval(this._timeagoInterval); 162 this._timeagoInterval = null; 163 } 164 } 165 }; 166 167 $.fn.timeago = function(action, options) { 168 var fn = action ? functions[action] : functions.init; 169 if(!fn){ 170 throw new Error("Unknown function name '"+ action +"' for timeago"); 171 } 172 // each over objects here and call the requested function 173 this.each(function(){ 174 fn.call(this, options); 175 }); 176 return this; 177 }; 178 179 function refresh() { 180 //check if it's still visible 181 if(!$.contains(document.documentElement,this)){ 182 //stop if it has been removed 183 $(this).timeago("dispose"); 184 return this; 185 } 186 187 var data = prepareData(this); 188 var $s = $t.settings; 189 190 if (!isNaN(data.datetime)) { 191 if ( $s.cutoff == 0 || Math.abs(distance(data.datetime)) < $s.cutoff) { 192 $(this).text(inWords(data.datetime)); 193 } 194 } 195 return this; 196 } 197 198 function prepareData(element) { 199 element = $(element); 200 if (!element.data("timeago")) { 201 element.data("timeago", { datetime: $t.datetime(element) }); 202 var text = $.trim(element.text()); 203 if ($t.settings.localeTitle) { 204 element.attr("title", element.data('timeago').datetime.toLocaleString()); 205 } else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) { 206 element.attr("title", text); 207 } 208 } 209 return element.data("timeago"); 210 } 211 212 function inWords(date) { 213 return $t.inWords(distance(date)); 214 } 215 216 function distance(date) { 217 return (new Date().getTime() - date.getTime()); 218 } 219 220 // fix for IE6 suckage 221 document.createElement("abbr"); 222 document.createElement("time"); 223}));
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.