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