angular-timeago
Advanced tools
Comparing version 0.1.12 to 0.2.0
@@ -27,3 +27,3 @@ { | ||
}, | ||
"version": "0.1.12" | ||
"version": "0.2.0" | ||
} |
/** | ||
* Angular directive/filter/service for formatting date so that it displays how long ago the given time was compared to now. | ||
* @version v0.1.11 - 2015-05-22 | ||
* @version v0.2.0 - 2015-07-24 | ||
* @link https://github.com/yaru22/angular-timeago | ||
@@ -15,9 +15,9 @@ * @author Brian Park <yaru22@gmail.com> | ||
return { | ||
scope: { | ||
fromTime: '@', | ||
format: '@' | ||
}, | ||
restrict: 'EA', | ||
link: function (scope, elem, attrs) { | ||
var fromTime; | ||
// Track the fromTime attribute | ||
attrs.$observe('fromTime', function (value) { | ||
fromTime = timeAgo.parse(value); | ||
}); | ||
link: function (scope, elem) { | ||
var fromTime = timeAgo.parse(scope.fromTime); | ||
// Track changes to time difference | ||
@@ -27,3 +27,3 @@ scope.$watch(function () { | ||
}, function (value) { | ||
angular.element(elem).text(timeAgo.inWords(value)); | ||
angular.element(elem).text(timeAgo.inWords(value, fromTime, scope.format)); | ||
}); | ||
@@ -51,205 +51,244 @@ } | ||
} | ||
]).factory('timeAgo', function () { | ||
var service = {}; | ||
service.settings = { | ||
refreshMillis: 60000, | ||
allowFuture: false, | ||
strings: { | ||
'it_IT': { | ||
prefixAgo: null, | ||
prefixFromNow: null, | ||
suffixAgo: 'fa', | ||
suffixFromNow: 'da ora', | ||
seconds: 'meno di un minuto', | ||
minute: 'circa un minuto', | ||
minutes: '%d minuti', | ||
hour: 'circa un\' ora', | ||
hours: 'circa %d ore', | ||
day: 'un giorno', | ||
days: '%d giorni', | ||
month: 'circa un mese', | ||
months: '%d mesi', | ||
year: 'circa un anno', | ||
years: '%d anni', | ||
numbers: [] | ||
}, | ||
'en_US': { | ||
prefixAgo: null, | ||
prefixFromNow: null, | ||
suffixAgo: 'ago', | ||
suffixFromNow: 'from now', | ||
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', | ||
years: '%d years', | ||
numbers: [] | ||
}, | ||
'de_DE': { | ||
prefixAgo: 'vor', | ||
prefixFromNow: null, | ||
suffixAgo: null, | ||
suffixFromNow: 'from now', | ||
seconds: 'weniger als einer Minute', | ||
minute: 'ca. einer Minute', | ||
minutes: '%d Minuten', | ||
hour: 'ca. einer Stunde', | ||
hours: 'ca. %d Stunden', | ||
day: 'einem Tag', | ||
days: '%d Tagen', | ||
month: 'ca. einem Monat', | ||
months: '%d Monaten', | ||
year: 'ca. einem Jahr', | ||
years: '%d Jahren', | ||
numbers: [] | ||
}, | ||
'he_IL': { | ||
prefixAgo: null, | ||
prefixFromNow: null, | ||
suffixAgo: '\u05dc\u05e4\u05e0\u05d9', | ||
suffixFromNow: '\u05de\u05e2\u05db\u05e9\u05d9\u05d5', | ||
seconds: '\u05e4\u05d7\u05d5\u05ea \u05de\u05d3\u05e7\u05d4', | ||
minute: '\u05db\u05d3\u05e7\u05d4', | ||
minutes: '%d \u05d3\u05e7\u05d5\u05ea', | ||
hour: '\u05db\u05e9\u05e2\u05d4', | ||
hours: '\u05db %d \u05e9\u05e2\u05d5\u05ea', | ||
day: '\u05d9\u05d5\u05dd', | ||
days: '%d \u05d9\u05de\u05d9\u05dd', | ||
month: '\u05db\u05d7\u05d5\u05d3\u05e9', | ||
months: '%d \u05d7\u05d5\u05d3\u05e9\u05d9\u05dd', | ||
year: '\u05db\u05e9\u05e0\u05d4', | ||
years: '%d \u05e9\u05e0\u05d9\u05dd', | ||
numbers: [] | ||
}, | ||
'pt_BR': { | ||
prefixAgo: null, | ||
prefixFromNow: 'daqui a', | ||
suffixAgo: 'atr\xe1s', | ||
suffixFromNow: null, | ||
seconds: 'menos de um minuto', | ||
minute: 'cerca de um minuto', | ||
minutes: '%d minutos', | ||
hour: 'cerca de uma hora', | ||
hours: 'cerca de %d horas', | ||
day: 'um dia', | ||
days: '%d dias', | ||
month: 'cerca de um m\xeas', | ||
months: '%d meses', | ||
year: 'cerca de um ano', | ||
years: '%d anos', | ||
numbers: [] | ||
}, | ||
'fr_FR': { | ||
prefixAgo: 'il y a', | ||
prefixFromNow: null, | ||
suffixAgo: null, | ||
suffixFromNow: 'from now', | ||
seconds: 'moins d\'une minute', | ||
minute: 'environ une minute', | ||
minutes: '%d minutes', | ||
hour: 'environ une heure', | ||
hours: 'environ %d heures', | ||
day: 'un jour', | ||
days: '%d jours', | ||
month: 'environ un mois', | ||
months: '%d mois', | ||
year: 'environ un an', | ||
years: '%d ans', | ||
numbers: [] | ||
}, | ||
'es_LA': { | ||
prefixAgo: 'hace', | ||
prefixFromNow: null, | ||
suffixAgo: null, | ||
suffixFromNow: 'apartir de ahora', | ||
seconds: 'menos de un minuto', | ||
minute: 'un minuto', | ||
minutes: '%d minutos', | ||
hour: 'una hora', | ||
hours: '%d horas', | ||
day: 'un dia', | ||
days: '%d dias', | ||
month: 'un mes', | ||
months: '%d meses', | ||
year: 'un a\xf1o', | ||
years: '%d a\xf1os', | ||
numbers: [] | ||
]).factory('timeAgo', [ | ||
'$filter', | ||
function ($filter) { | ||
var service = {}; | ||
service.settings = { | ||
refreshMillis: 60000, | ||
allowFuture: false, | ||
overrideLang: null, | ||
fullDateAfterSeconds: null, | ||
strings: { | ||
'it_IT': { | ||
prefixAgo: null, | ||
prefixFromNow: null, | ||
suffixAgo: 'fa', | ||
suffixFromNow: 'da ora', | ||
seconds: 'meno di un minuto', | ||
minute: 'circa un minuto', | ||
minutes: '%d minuti', | ||
hour: 'circa un\' ora', | ||
hours: 'circa %d ore', | ||
day: 'un giorno', | ||
days: '%d giorni', | ||
month: 'circa un mese', | ||
months: '%d mesi', | ||
year: 'circa un anno', | ||
years: '%d anni', | ||
numbers: [] | ||
}, | ||
'en_US': { | ||
prefixAgo: null, | ||
prefixFromNow: null, | ||
suffixAgo: 'ago', | ||
suffixFromNow: 'from now', | ||
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', | ||
years: '%d years', | ||
numbers: [] | ||
}, | ||
'de_DE': { | ||
prefixAgo: 'vor', | ||
prefixFromNow: null, | ||
suffixAgo: null, | ||
suffixFromNow: 'from now', | ||
seconds: 'weniger als einer Minute', | ||
minute: 'ca. einer Minute', | ||
minutes: '%d Minuten', | ||
hour: 'ca. einer Stunde', | ||
hours: 'ca. %d Stunden', | ||
day: 'einem Tag', | ||
days: '%d Tagen', | ||
month: 'ca. einem Monat', | ||
months: '%d Monaten', | ||
year: 'ca. einem Jahr', | ||
years: '%d Jahren', | ||
numbers: [] | ||
}, | ||
'he_IL': { | ||
prefixAgo: null, | ||
prefixFromNow: null, | ||
suffixAgo: '\u05dc\u05e4\u05e0\u05d9', | ||
suffixFromNow: '\u05de\u05e2\u05db\u05e9\u05d9\u05d5', | ||
seconds: '\u05e4\u05d7\u05d5\u05ea \u05de\u05d3\u05e7\u05d4', | ||
minute: '\u05db\u05d3\u05e7\u05d4', | ||
minutes: '%d \u05d3\u05e7\u05d5\u05ea', | ||
hour: '\u05db\u05e9\u05e2\u05d4', | ||
hours: '\u05db %d \u05e9\u05e2\u05d5\u05ea', | ||
day: '\u05d9\u05d5\u05dd', | ||
days: '%d \u05d9\u05de\u05d9\u05dd', | ||
month: '\u05db\u05d7\u05d5\u05d3\u05e9', | ||
months: '%d \u05d7\u05d5\u05d3\u05e9\u05d9\u05dd', | ||
year: '\u05db\u05e9\u05e0\u05d4', | ||
years: '%d \u05e9\u05e0\u05d9\u05dd', | ||
numbers: [] | ||
}, | ||
'pt_BR': { | ||
prefixAgo: null, | ||
prefixFromNow: 'daqui a', | ||
suffixAgo: 'atr\xe1s', | ||
suffixFromNow: null, | ||
seconds: 'menos de um minuto', | ||
minute: 'cerca de um minuto', | ||
minutes: '%d minutos', | ||
hour: 'cerca de uma hora', | ||
hours: 'cerca de %d horas', | ||
day: 'um dia', | ||
days: '%d dias', | ||
month: 'cerca de um m\xeas', | ||
months: '%d meses', | ||
year: 'cerca de um ano', | ||
years: '%d anos', | ||
numbers: [] | ||
}, | ||
'fr_FR': { | ||
prefixAgo: 'il y a', | ||
prefixFromNow: null, | ||
suffixAgo: null, | ||
suffixFromNow: 'from now', | ||
seconds: 'moins d\'une minute', | ||
minute: 'environ une minute', | ||
minutes: '%d minutes', | ||
hour: 'environ une heure', | ||
hours: 'environ %d heures', | ||
day: 'un jour', | ||
days: '%d jours', | ||
month: 'environ un mois', | ||
months: '%d mois', | ||
year: 'environ un an', | ||
years: '%d ans', | ||
numbers: [] | ||
}, | ||
'es_LA': { | ||
prefixAgo: 'hace', | ||
prefixFromNow: null, | ||
suffixAgo: null, | ||
suffixFromNow: 'apartir de ahora', | ||
seconds: 'menos de un minuto', | ||
minute: 'un minuto', | ||
minutes: '%d minutos', | ||
hour: 'una hora', | ||
hours: '%d horas', | ||
day: 'un dia', | ||
days: '%d dias', | ||
month: 'un mes', | ||
months: '%d meses', | ||
year: 'un a\xf1o', | ||
years: '%d a\xf1os', | ||
numbers: [] | ||
}, | ||
'nl_NL': { | ||
prefixAgo: null, | ||
prefixFromNow: 'over', | ||
suffixAgo: 'geleden', | ||
suffixFromNow: 'vanaf nu', | ||
seconds: 'een paar seconden', | ||
minute: 'ongeveer een minuut', | ||
minutes: '%d minuten', | ||
hour: 'een uur', | ||
hours: '%d uur', | ||
day: 'een dag', | ||
days: '%d dagen', | ||
month: 'een maand', | ||
months: '%d maanden', | ||
year: 'een jaar', | ||
years: '%d jaar', | ||
numbers: [] | ||
} | ||
} | ||
} | ||
}; | ||
service.inWords = function (distanceMillis) { | ||
var lang = document.documentElement.lang; | ||
var $l = service.settings.strings[lang]; | ||
if (typeof $l === 'undefined') { | ||
$l = service.settings.strings['en_US']; | ||
} | ||
var prefix = $l.prefixAgo; | ||
var suffix = $l.suffixAgo; | ||
if (service.settings.allowFuture) { | ||
if (distanceMillis < 0) { | ||
prefix = $l.prefixFromNow; | ||
suffix = $l.suffixFromNow; | ||
}; | ||
service.inWords = function (distanceMillis, fromTime, format, timezone) { | ||
var fullDateAfterSeconds = parseInt(service.settings.fullDateAfterSeconds, 10); | ||
if (!isNaN(fullDateAfterSeconds) && (distanceMillis >= 0 && fullDateAfterSeconds * 1000 <= distanceMillis || fullDateAfterSeconds * 1000 >= distanceMillis)) { | ||
if (format) { | ||
return $filter('date')(fromTime, format, timezone); | ||
} | ||
return fromTime; | ||
} | ||
} | ||
var seconds = Math.abs(distanceMillis) / 1000; | ||
var minutes = seconds / 60; | ||
var hours = minutes / 60; | ||
var days = hours / 24; | ||
var years = days / 365; | ||
function substitute(stringOrFunction, number) { | ||
var string = angular.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; | ||
var value = $l.numbers && $l.numbers[number] || number; | ||
return string.replace(/%d/i, value); | ||
} | ||
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || seconds < 90 && substitute($l.minute, 1) || minutes < 45 && substitute($l.minutes, Math.round(minutes)) || minutes < 90 && substitute($l.hour, 1) || hours < 24 && substitute($l.hours, Math.round(hours)) || 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)); | ||
var separator = $l.wordSeparator === undefined ? ' ' : $l.wordSeparator; | ||
if (lang === 'he_IL') { | ||
return [ | ||
prefix, | ||
suffix, | ||
words | ||
].join(separator).trim(); | ||
} else { | ||
return [ | ||
prefix, | ||
words, | ||
suffix | ||
].join(separator).trim(); | ||
} | ||
}; | ||
service.parse = function (input) { | ||
if (input instanceof Date) { | ||
return input; | ||
} else if (angular.isNumber(input)) { | ||
return new Date(input); | ||
} else if (/^\d+$/.test(input)) { | ||
return new Date(parseInt(input, 10)); | ||
} else { | ||
var s = (input || '').trim(); | ||
s = s.replace(/\.\d+/, ''); | ||
// remove milliseconds | ||
s = s.replace(/-/, '/').replace(/-/, '/'); | ||
s = s.replace(/T/, ' ').replace(/Z/, ' UTC'); | ||
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/, ' $1$2'); | ||
// -04:00 -> -0400 | ||
return new Date(s); | ||
} | ||
}; | ||
return service; | ||
}).filter('timeAgo', [ | ||
var overrideLang = service.settings.overrideLang; | ||
var documentLang = document.documentElement.lang; | ||
var sstrings = service.settings.strings; | ||
var lang, $l; | ||
if (typeof sstrings[overrideLang] !== 'undefined') { | ||
lang = overrideLang; | ||
$l = sstrings[overrideLang]; | ||
} else if (typeof sstrings[documentLang] !== 'undefined') { | ||
lang = documentLang; | ||
$l = sstrings[documentLang]; | ||
} else { | ||
lang = 'en_US'; | ||
$l = sstrings[lang]; | ||
} | ||
var prefix = $l.prefixAgo; | ||
var suffix = $l.suffixAgo; | ||
if (service.settings.allowFuture) { | ||
if (distanceMillis < 0) { | ||
prefix = $l.prefixFromNow; | ||
suffix = $l.suffixFromNow; | ||
} | ||
} | ||
var seconds = Math.abs(distanceMillis) / 1000; | ||
var minutes = seconds / 60; | ||
var hours = minutes / 60; | ||
var days = hours / 24; | ||
var years = days / 365; | ||
function substitute(stringOrFunction, number) { | ||
var string = angular.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; | ||
var value = $l.numbers && $l.numbers[number] || number; | ||
return string.replace(/%d/i, value); | ||
} | ||
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || seconds < 90 && substitute($l.minute, 1) || minutes < 45 && substitute($l.minutes, Math.round(minutes)) || minutes < 90 && substitute($l.hour, 1) || hours < 24 && substitute($l.hours, Math.round(hours)) || 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)); | ||
var separator = $l.wordSeparator === undefined ? ' ' : $l.wordSeparator; | ||
if (lang === 'he_IL') { | ||
return [ | ||
prefix, | ||
suffix, | ||
words | ||
].join(separator).trim(); | ||
} else { | ||
return [ | ||
prefix, | ||
words, | ||
suffix | ||
].join(separator).trim(); | ||
} | ||
}; | ||
service.parse = function (input) { | ||
if (input instanceof Date) { | ||
return input; | ||
} else if (angular.isNumber(input)) { | ||
return new Date(input); | ||
} else if (/^\d+$/.test(input)) { | ||
return new Date(parseInt(input, 10)); | ||
} else { | ||
var s = (input || '').trim(); | ||
s = s.replace(/\.\d+/, ''); | ||
// remove milliseconds | ||
s = s.replace(/-/, '/').replace(/-/, '/'); | ||
s = s.replace(/T/, ' ').replace(/Z/, ' UTC'); | ||
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/, ' $1$2'); | ||
// -04:00 -> -0400 | ||
return new Date(s); | ||
} | ||
}; | ||
return service; | ||
} | ||
]).filter('timeAgo', [ | ||
'nowTime', | ||
'timeAgo', | ||
function (nowTime, timeAgo) { | ||
return function (value) { | ||
return function (value, format, timezone) { | ||
var fromTime = timeAgo.parse(value); | ||
var diff = nowTime() - fromTime; | ||
return timeAgo.inWords(diff); | ||
return timeAgo.inWords(diff, fromTime, format, timezone); | ||
}; | ||
} | ||
]); |
@@ -8,6 +8,10 @@ /* globals angular */ | ||
app.controller('demoController', function ($scope, nowTime) { | ||
app.controller('demoController', function ($scope, timeAgo, nowTime) { | ||
//timeAgo.settings.fullDateAfterSeconds = 60 * 60 * 24; | ||
//timeAgo.settings.overrideLang = 'es_LA'; | ||
$scope.pageLoadTime = (new Date()).toISOString(); | ||
$scope.nowTime = nowTime; | ||
$scope.nowTimeAsDateObject = new Date() | ||
$scope.nowTimeAsDateObject = new Date(); | ||
}); |
@@ -8,3 +8,3 @@ { | ||
"description": "Angular directive/filter/service for formatting date so that it displays how long ago the given time was compared to now.", | ||
"version": "0.1.12", | ||
"version": "0.2.0", | ||
"license": "MIT", | ||
@@ -11,0 +11,0 @@ "homepage": "https://github.com/yaru22/angular-timeago", |
# angular-timeago [![Analytics](https://ga-beacon.appspot.com/UA-2694988-7/angular-timeago/readme?pixel)](https://github.com/yaru22/angular-timeago) | ||
Angular directive/filter/service for formatting date so that it displays how long ago the given time was compared to now. | ||
## Disclaimer | ||
##<a name="disclaimer"/> Disclaimer | ||
This project is based off of [a thread](https://groups.google.com/forum/#!topic/angular/o7vl4tsg53w) on Angular Google Groups. The person who started the thread, [@lrlopez](https://github.com/lrlopez), gave me permission to start a repo using the code he wrote initially. Thanks to [@lrlopez](https://github.com/lrlopez) and other contributors in the thread. | ||
## Demo | ||
##<a name="demo"/> Demo | ||
Check out the demo [here](http://www.brianpark.ca/projects/angular_timeago/demo/). | ||
## Usage | ||
##<a name="usage"/> Usage | ||
**Install via Bower** | ||
@@ -21,10 +21,68 @@ ``` | ||
``` | ||
**Filter** | ||
###<a name="filter"/> Filter | ||
####<a name="filter-basic"/>Basic Filter | ||
``` | ||
{{myDate | timeAgo}} | ||
``` | ||
Displays time ago since `myDate`. `myDate` can be time in **milliseconds since January 1st 1970** (see [MDN Date.prototype.getTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime)) or an **ISO 8601** string (see [MDN Date.prototype.toISOString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)) | ||
Displays time ago since `myDate`. `myDate` can be time in **milliseconds since January 1st 1970** (see [MDN Date.prototype.getTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime)) or an **ISO 8601** string (see [MDN Date.prototype.toISOString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)) | ||
**Language support** | ||
angular-timeago currently supports: `en_US`, `de_DE`, `he_IL`, `pt_BR`. If you want more languages: feel free to contribute! | ||
####<a name="filter-format"/>Filter using [Angular `date` format](https://docs.angularjs.org/api/ng/filter/date) | ||
``` | ||
{{myDate | timeAgo:'MM/dd/yyyy'}} | ||
``` | ||
The format filter will only take effect if you've configured the service to display the full date after a certain number of seconds using the [fullDateAfterSeconds](#config-fulldate) setting. In this scenario, it will use the Angular `date` filter with this format string. | ||
###<a name="directive"/>Directive | ||
####<a name="directive-basic"/>Basic Directive | ||
```html | ||
<p>You were born <time-ago from-time='{{ birthDate }}'></time-ago></p> | ||
``` | ||
####<a name="directive-format"/>Directive using [Angular `date` format](https://docs.angularjs.org/api/ng/filter/date) | ||
```html | ||
<p>You were born <time-ago from-time='{{ birthDate }}' format='MM/dd/yyyy'></time-ago></p> | ||
``` | ||
###<a name="config"/>Configuration Settings | ||
timeAgo has several configurable settings to tweak the default behavior. | ||
```javascript | ||
angular.controller('appCtrl', function (timeAgo) { | ||
timeAgo.settings.<setting> = <value>; | ||
}); | ||
``` | ||
####<a name="config-future"/>`allowFuture` | ||
Default: `false` | ||
```javascript | ||
timeAgo.settings.allowFuture = true; | ||
``` | ||
This will allow timeAgo to format dates in the future as well. e.g. "2 hours from now" | ||
####<a name="config-override"/>`overrideLang` | ||
Default: `null` | ||
```html | ||
<html lang='en_US'> | ||
... | ||
``` | ||
```javascript | ||
// even though the page's setting is 'en_US', timeAgo filtered | ||
// dates will render in 'es_LA' | ||
timeAgo.settings.overrideLang = 'es_LA'; | ||
``` | ||
See [Language Support](#lang) for languages this library supports. | ||
####<a name="config-fulldate"/>`fullDateAfterSeconds` | ||
Default: `null` | ||
```javascript | ||
// After 24 hours, display the date normally. | ||
var oneDay = 60*60*24; | ||
timeAgo.settings.fullDateAfterSeconds = oneDay; | ||
``` | ||
This configures `timeAgo` to use it's own filters (`about a minute ago`, `about 4 hours ago`, etc) until `fullDateAfterSeconds` seconds have passed, and then it will display the date as normal. This is useful when combined with a [date format filter](#filter-format). | ||
###<a name="lang"/>Language support | ||
angular-timeago currently supports the following languages: | ||
`en_US`, `de_DE`, `he_IL`, `pt_BR`, `it_IT`, `fr_FR`, `es_LA`, `nl_NL` | ||
If you want more languages: feel free to contribute! | ||
The language is determined by the string in `document.documentElement.lang` which you can set in your HTML markup: | ||
@@ -38,8 +96,16 @@ ``` | ||
``` | ||
Or configure the service to override the default language: | ||
```javascript | ||
app.controller('appCtrl', function (timeAgo) { | ||
timeAgo.settings.overrideLanguage = 'es_LA'; | ||
}); | ||
``` | ||
You can also add additional or alter existing languages at runtime by extending the service: | ||
```javascript | ||
app.controller('appCtrl', function (timeAgo) { | ||
timeAgo.settings.strings.en_US = { | ||
// appropriate keys here | ||
}; | ||
}); | ||
``` | ||
timeAgo.settings.strings.en_US = { | ||
// appropriate keys here | ||
}; | ||
``` | ||
For more details refer to the [source code](https://github.com/yaru22/angular-timeago/blob/master/src/timeAgo.js#L47). | ||
@@ -59,2 +125,2 @@ | ||
``` | ||
grunt test | ||
@@ -8,11 +8,10 @@ /* global angular */ | ||
return { | ||
scope : { | ||
fromTime : '@', | ||
format : '@' | ||
}, | ||
restrict: 'EA', | ||
link: function(scope, elem, attrs) { | ||
var fromTime; | ||
link: function(scope, elem) { | ||
var fromTime = timeAgo.parse(scope.fromTime); | ||
// Track the fromTime attribute | ||
attrs.$observe('fromTime', function (value) { | ||
fromTime = timeAgo.parse(value); | ||
}); | ||
// Track changes to time difference | ||
@@ -22,3 +21,3 @@ scope.$watch(function () { | ||
}, function(value) { | ||
angular.element(elem).text(timeAgo.inWords(value)); | ||
angular.element(elem).text(timeAgo.inWords(value, fromTime, scope.format)); | ||
}); | ||
@@ -41,3 +40,3 @@ } | ||
}; | ||
}]).factory('timeAgo', function () { | ||
}]).factory('timeAgo', ['$filter', function ($filter) { | ||
var service = {}; | ||
@@ -48,2 +47,4 @@ | ||
allowFuture: false, | ||
overrideLang : null, | ||
fullDateAfterSeconds : null, | ||
strings: { | ||
@@ -197,8 +198,32 @@ 'it_IT': { | ||
service.inWords = function (distanceMillis) { | ||
var lang = document.documentElement.lang; | ||
var $l = service.settings.strings[lang]; | ||
if (typeof $l === 'undefined') { | ||
$l = service.settings.strings['en_US']; | ||
service.inWords = function (distanceMillis, fromTime, format, timezone) { | ||
var fullDateAfterSeconds = parseInt(service.settings.fullDateAfterSeconds, 10); | ||
if (!isNaN(fullDateAfterSeconds) && | ||
( (distanceMillis >= 0 && (fullDateAfterSeconds * 1000) <= distanceMillis) || | ||
(fullDateAfterSeconds * 1000) >= distanceMillis)) | ||
{ | ||
if (format) { | ||
return $filter('date')(fromTime, format, timezone); | ||
} | ||
return fromTime; | ||
} | ||
var overrideLang = service.settings.overrideLang; | ||
var documentLang = document.documentElement.lang; | ||
var sstrings = service.settings.strings; | ||
var lang, $l; | ||
if (typeof sstrings[overrideLang] !== 'undefined') { | ||
lang = overrideLang; | ||
$l = sstrings[overrideLang]; | ||
} else if (typeof sstrings[documentLang] !== 'undefined') { | ||
lang = documentLang; | ||
$l = sstrings[documentLang]; | ||
} else { | ||
lang = 'en_US'; | ||
$l = sstrings[lang]; | ||
} | ||
var prefix = $l.prefixAgo; | ||
@@ -264,8 +289,8 @@ var suffix = $l.suffixAgo; | ||
return service; | ||
}).filter('timeAgo', ['nowTime', 'timeAgo', function (nowTime, timeAgo) { | ||
return function (value) { | ||
}]).filter('timeAgo', ['nowTime', 'timeAgo', function (nowTime, timeAgo) { | ||
return function (value, format, timezone) { | ||
var fromTime = timeAgo.parse(value); | ||
var diff = nowTime() - fromTime; | ||
return timeAgo.inWords(diff); | ||
return timeAgo.inWords(diff, fromTime, format, timezone); | ||
}; | ||
}]); |
@@ -5,3 +5,3 @@ 'use strict'; | ||
var deltaMs = 200; | ||
var deltaMs = 300; | ||
@@ -16,2 +16,6 @@ beforeEach(function () { | ||
it('time ago filter', function () { | ||
expect(element(by.css('.filter-example')).getText()).toMatch(/^(Filter Example\nYou opened this demo page )(less than|about)( a minute ago)$/); | ||
}); | ||
it('loading time', function () { | ||
@@ -30,3 +34,3 @@ var testStartTime = Date.now(); | ||
var pageNowMs = parseInt(pageNowTimeText.replace('Current time: ', '')); | ||
expect(Math.abs(pageNowMs - Date.now()) < deltaMs).toBe(true) | ||
expect(Math.abs(pageNowMs - Date.now()) < deltaMs).toBe(true); | ||
}) | ||
@@ -33,0 +37,0 @@ }); |
@@ -7,3 +7,3 @@ /* jshint ignore:start */ | ||
describe('timeAgo', function () { | ||
var elm, scope, filter, ngDateFilter; | ||
var elm, scope, filter, ngDateFilter, timeAgo; | ||
@@ -13,5 +13,6 @@ // load the code | ||
beforeEach(inject(function ($rootScope, $compile, timeAgoFilter, dateFilter) { | ||
beforeEach(inject(function ($rootScope, $compile, timeAgoFilter, dateFilter, _timeAgo_) { | ||
filter = timeAgoFilter; | ||
ngDateFilter = dateFilter; | ||
timeAgo = _timeAgo_; | ||
})); | ||
@@ -28,4 +29,23 @@ | ||
expect(filter(nowDate)).to.equal(filter(nowDateString)); | ||
}); | ||
}) | ||
it('settings.overrideLang works', function () { | ||
timeAgo.settings.overrideLang = 'es_LA'; | ||
var strs = timeAgo.settings.strings['es_LA']; | ||
var nowDate = new Date(); | ||
expect(filter(nowDate)).to.equal([strs.prefixAgo, strs.seconds, strs.suffixAgo].join(' ').trim()); | ||
}); | ||
it('settings.fullDateAfterSeconds works', function() { | ||
// force it to display the full date always | ||
timeAgo.settings.fullDateAfterSeconds = 0; | ||
var nowDate = new Date(); | ||
var ngDateString = ngDateFilter(nowDate, 'yyyy-MM-dd HH:mm'); | ||
var taDateString = filter(nowDate, 'yyyy-MM-dd HH:mm'); | ||
expect(ngDateString).to.equal(taDateString); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
780912
22
19965
124