2011-11-28 09:31:26 -05:00
/ * *
2008-07-18 11:34:06 -04:00
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps ( e . g . "4 minutes ago" or "about 1 day ago" ) .
*
2011-11-28 09:31:26 -05:00
* @ name timeago
2013-05-18 18:27:54 -04:00
* @ version 1.2 . 0
2011-11-28 09:31:26 -05:00
* @ requires jQuery v1 . 2.3 +
* @ author Ryan McGeary
* @ license MIT License - http : //www.opensource.org/licenses/mit-license.php
*
2008-07-18 11:34:06 -04:00
* For usage and examples , visit :
* http : //timeago.yarp.com/
*
2013-01-21 10:33:20 -05:00
* Copyright ( c ) 2008 - 2013 , Ryan McGeary ( ryan - [ at ] - mcgeary [ * dot * ] org )
2008-07-18 11:34:06 -04:00
* /
2013-01-24 14:42:01 -05:00
( function ( factory ) {
if ( typeof define === 'function' && define . amd ) {
// AMD. Register as an anonymous module.
define ( [ 'jquery' ] , factory ) ;
} else {
// Browser globals
factory ( jQuery ) ;
}
} ( function ( $ ) {
2008-07-18 11:34:06 -04:00
$ . timeago = function ( timestamp ) {
2011-01-21 09:36:21 -08:00
if ( timestamp instanceof Date ) {
return inWords ( timestamp ) ;
} else if ( typeof timestamp === "string" ) {
return inWords ( $ . timeago . parse ( timestamp ) ) ;
2012-05-16 11:30:02 -04:00
} else if ( typeof timestamp === "number" ) {
return inWords ( new Date ( timestamp ) ) ;
2011-01-21 09:36:21 -08:00
} else {
return inWords ( $ . timeago . datetime ( timestamp ) ) ;
}
2008-07-18 11:34:06 -04:00
} ;
2008-08-19 19:40:43 -04:00
var $t = $ . timeago ;
2008-07-18 11:34:06 -04:00
$ . extend ( $ . timeago , {
settings : {
2008-08-06 07:04:15 -04:00
refreshMillis : 60000 ,
2008-08-19 19:40:43 -04:00
allowFuture : false ,
2013-03-19 20:53:55 -07:00
localeTitle : false ,
2010-10-27 14:29:24 +02:00
cutoff : 0 ,
2008-08-19 19:40:43 -04:00
strings : {
2008-10-13 17:51:52 -04:00
prefixAgo : null ,
prefixFromNow : null ,
2008-10-14 08:45:42 -04:00
suffixAgo : "ago" ,
suffixFromNow : "from now" ,
2008-08-19 19:40:43 -04:00
seconds : "less than a minute" ,
minute : "about a minute" ,
minutes : "%d minutes" ,
hour : "about an hour" ,
hours : "about %d hours" ,
day : "a day" ,
days : "%d days" ,
month : "about a month" ,
months : "%d months" ,
year : "about a year" ,
2010-02-28 14:24:23 -05:00
years : "%d years" ,
2012-03-03 15:15:18 -05:00
wordSeparator : " " ,
2010-02-28 14:24:23 -05:00
numbers : [ ]
2008-08-19 19:40:43 -04:00
}
2008-07-18 11:34:06 -04:00
} ,
inWords : function ( distanceMillis ) {
2008-08-19 19:40:43 -04:00
var $l = this . settings . strings ;
2008-10-13 17:51:52 -04:00
var prefix = $l . prefixAgo ;
2010-02-28 14:00:58 -05:00
var suffix = $l . suffixAgo ;
2008-08-06 07:04:15 -04:00
if ( this . settings . allowFuture ) {
2008-10-13 17:51:52 -04:00
if ( distanceMillis < 0 ) {
prefix = $l . prefixFromNow ;
2010-02-28 14:00:58 -05:00
suffix = $l . suffixFromNow ;
2008-10-13 17:51:52 -04:00
}
2008-08-06 07:04:15 -04:00
}
2011-12-14 09:20:18 -05:00
var seconds = Math . abs ( distanceMillis ) / 1000 ;
2008-07-18 11:34:06 -04:00
var minutes = seconds / 60 ;
var hours = minutes / 60 ;
var days = hours / 24 ;
var years = days / 365 ;
2010-02-28 14:24:23 -05:00
function substitute ( stringOrFunction , number ) {
2010-09-14 21:44:55 -04:00
var string = $ . isFunction ( stringOrFunction ) ? stringOrFunction ( number , distanceMillis ) : stringOrFunction ;
2010-02-28 14:24:23 -05:00
var value = ( $l . numbers && $l . numbers [ number ] ) || number ;
return string . replace ( /%d/i , value ) ;
}
2009-02-14 14:09:53 -05:00
var words = seconds < 45 && substitute ( $l . seconds , Math . round ( seconds ) ) ||
2009-02-18 11:24:57 -05:00
seconds < 90 && substitute ( $l . minute , 1 ) ||
2009-02-14 14:09:53 -05:00
minutes < 45 && substitute ( $l . minutes , Math . round ( minutes ) ) ||
2009-02-18 11:24:57 -05:00
minutes < 90 && substitute ( $l . hour , 1 ) ||
2009-02-14 14:09:53 -05:00
hours < 24 && substitute ( $l . hours , Math . round ( hours ) ) ||
2012-02-27 14:56:47 +01:00
hours < 42 && substitute ( $l . day , 1 ) ||
days < 30 && substitute ( $l . days , Math . round ( days ) ) ||
days < 45 && substitute ( $l . month , 1 ) ||
days < 365 && substitute ( $l . months , Math . round ( days / 30 ) ) ||
years < 1.5 && substitute ( $l . year , 1 ) ||
substitute ( $l . years , Math . round ( years ) ) ;
2008-07-18 11:34:06 -04:00
2012-12-27 11:45:54 -05:00
var separator = $l . wordSeparator || "" ;
if ( $l . wordSeparator === undefined ) { separator = " " ; }
2012-03-12 10:12:45 -04:00
return $ . trim ( [ prefix , words , suffix ] . join ( separator ) ) ;
2008-07-18 11:34:06 -04:00
} ,
parse : function ( iso8601 ) {
2008-07-30 10:24:08 -04:00
var s = $ . trim ( iso8601 ) ;
2012-06-28 23:16:31 +02:00
s = s . replace ( /\.\d+/ , "" ) ; // remove milliseconds
2008-07-18 11:34:06 -04:00
s = s . replace ( /-/ , "/" ) . replace ( /-/ , "/" ) ;
s = s . replace ( /T/ , " " ) . replace ( /Z/ , " UTC" ) ;
2011-01-21 09:32:18 -08:00
s = s . replace ( /([\+\-]\d\d)\:?(\d\d)/ , " $1$2" ) ; // -04:00 -> -0400
2008-07-18 11:34:06 -04:00
return new Date ( s ) ;
2009-08-19 16:32:51 +01:00
} ,
datetime : function ( elem ) {
2012-05-10 11:00:18 +02:00
var iso8601 = $t . isTime ( elem ) ? $ ( elem ) . attr ( "datetime" ) : $ ( elem ) . attr ( "title" ) ;
2009-10-25 20:22:09 -04:00
return $t . parse ( iso8601 ) ;
2012-05-10 11:00:18 +02:00
} ,
isTime : function ( elem ) {
// jQuery's `is()` doesn't play well with HTML5 in IE
return $ ( elem ) . get ( 0 ) . tagName . toLowerCase ( ) === "time" ; // $(elem).is("time");
2008-07-18 11:34:06 -04:00
}
} ) ;
2013-03-06 09:41:52 -05:00
// functions that can be called via $(el).timeago('action')
// init is default when no action is given
// functions are called with context of a single element
var functions = {
init : function ( ) {
var refresh _el = $ . proxy ( refresh , this ) ;
refresh _el ( ) ;
var $s = $t . settings ;
if ( $s . refreshMillis > 0 ) {
setInterval ( refresh _el , $s . refreshMillis ) ;
2013-03-06 13:27:36 +01:00
}
2013-03-06 09:41:52 -05:00
} ,
update : function ( time ) {
$ ( this ) . data ( 'timeago' , { datetime : $t . parse ( time ) } ) ;
refresh . apply ( this ) ;
2013-06-12 19:46:49 +00:00
} ,
updateFromDOM : function ( ) {
$ ( this ) . data ( 'timeago' , { datetime : $t . parse ( $t . isTime ( this ) ? $ ( this ) . attr ( "datetime" ) : $ ( this ) . attr ( "title" ) ) } ) ;
refresh . apply ( this ) ;
2013-03-06 09:41:52 -05:00
}
} ;
2008-07-18 11:34:06 -04:00
2013-03-06 09:41:52 -05:00
$ . fn . timeago = function ( action , options ) {
var fn = action ? functions [ action ] : functions . init ;
if ( ! fn ) {
throw new Error ( "Unknown function name '" + action + "' for timeago" ) ;
}
// each over objects here and call the requested function
this . each ( function ( ) {
fn . call ( this , options ) ;
} ) ;
return this ;
} ;
2008-07-18 11:34:06 -04:00
function refresh ( ) {
2009-10-25 20:22:09 -04:00
var data = prepareData ( this ) ;
2010-10-27 14:29:24 +02:00
var $s = $t . settings ;
2009-10-25 20:22:09 -04:00
if ( ! isNaN ( data . datetime ) ) {
2010-10-27 14:29:24 +02:00
if ( $s . cutoff == 0 || distance ( data . datetime ) < $s . cutoff ) {
$ ( this ) . text ( inWords ( data . datetime ) ) ;
}
2008-07-19 10:36:59 -04:00
}
2008-07-20 17:08:34 -04:00
return this ;
}
2009-10-25 20:22:09 -04:00
function prepareData ( element ) {
element = $ ( element ) ;
2010-02-16 07:49:41 -05:00
if ( ! element . data ( "timeago" ) ) {
2009-10-25 20:22:09 -04:00
element . data ( "timeago" , { datetime : $t . datetime ( element ) } ) ;
var text = $ . trim ( element . text ( ) ) ;
2013-03-19 20:53:55 -07:00
if ( $t . settings . localeTitle ) {
2013-04-01 00:10:53 +03:00
element . attr ( "title" , element . data ( 'timeago' ) . datetime . toLocaleString ( ) ) ;
2013-03-19 20:53:55 -07:00
} else if ( text . length > 0 && ! ( $t . isTime ( element ) && element . attr ( "title" ) ) ) {
2011-01-21 09:36:21 -08:00
element . attr ( "title" , text ) ;
}
2009-10-25 20:22:09 -04:00
}
return element . data ( "timeago" ) ;
}
2008-07-20 17:08:34 -04:00
function inWords ( date ) {
2008-08-19 19:40:43 -04:00
return $t . inWords ( distance ( date ) ) ;
2008-07-18 11:34:06 -04:00
}
function distance ( date ) {
return ( new Date ( ) . getTime ( ) - date . getTime ( ) ) ;
}
2008-08-20 22:34:42 -04:00
// fix for IE6 suckage
2010-01-27 17:30:51 -05:00
document . createElement ( "abbr" ) ;
document . createElement ( "time" ) ;
2013-01-18 22:26:07 -05:00
} ) ) ;