From 7139716b40ce307e71552dd095d598fb4b8ac0b2 Mon Sep 17 00:00:00 2001 From: Ephi Gabay Date: Thu, 5 Jun 2014 19:17:18 +0300 Subject: [PATCH] Added support for one time binding using the '::' expression. Fix for issue #48 --- angular-moment.js | 37 +++++++++++-------- angular-moment.min.js | 2 +- angular-moment.min.map | 2 +- tests.js | 81 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 16 deletions(-) diff --git a/angular-moment.js b/angular-moment.js index 299611f..f32f9ab 100644 --- a/angular-moment.js +++ b/angular-moment.js @@ -107,6 +107,9 @@ var currentFormat = angularMomentConfig.format; var withoutSuffix = amTimeAgoConfig.withoutSuffix; var preprocess = angularMomentConfig.preprocess; + var modelName = attr.amTimeAgo.replace(/^::/, ''); + var isBindOnce = (attr.amTimeAgo.indexOf('::') === 0); + var unwatchChanges; function cancelTimer() { if (activeTimeout) { @@ -117,19 +120,21 @@ function updateTime(momentInstance) { element.text(momentInstance.fromNow(withoutSuffix)); - var howOld = moment().diff(momentInstance, 'minute'); - var secondsUntilUpdate = 3600; - if (howOld < 1) { - secondsUntilUpdate = 1; - } else if (howOld < 60) { - secondsUntilUpdate = 30; - } else if (howOld < 180) { - secondsUntilUpdate = 300; - } - - activeTimeout = $window.setTimeout(function () { - updateTime(momentInstance); - }, secondsUntilUpdate * 1000); + if(!isBindOnce) { + var howOld = moment().diff(momentInstance, 'minute'); + var secondsUntilUpdate = 3600; + if (howOld < 1) { + secondsUntilUpdate = 1; + } else if (howOld < 60) { + secondsUntilUpdate = 30; + } else if (howOld < 180) { + secondsUntilUpdate = 300; + } + + activeTimeout = $window.setTimeout(function () { + updateTime(momentInstance); + }, secondsUntilUpdate * 1000); + } } function updateMoment() { @@ -139,7 +144,7 @@ } } - scope.$watch(attr.amTimeAgo, function (value) { + unwatchChanges = scope.$watch(modelName, function (value) { if ((typeof value === 'undefined') || (value === null) || (value === '')) { cancelTimer(); if (currentValue) { @@ -151,6 +156,10 @@ currentValue = value; updateMoment(); + + if(value !== undefined && isBindOnce) { + unwatchChanges(); + } }); if (angular.isDefined(attr.amWithoutSuffix)) { diff --git a/angular-moment.min.js b/angular-moment.min.js index 9ee42cc..f8b14c7 100644 --- a/angular-moment.min.js +++ b/angular-moment.min.js @@ -1,2 +1,2 @@ -!function(){"use strict";function a(a,b){return a.module("angularMoment",[]).constant("angularMomentConfig",{preprocess:null,timezone:"",format:null}).constant("moment",b).constant("amTimeAgoConfig",{withoutSuffix:!1}).directive("amTimeAgo",["$window","moment","amMoment","amTimeAgoConfig","angularMomentConfig",function(b,c,d,e,f){return function(g,h,i){function j(){n&&(b.clearTimeout(n),n=null)}function k(a){h.text(a.fromNow(p));var d=c().diff(a,"minute"),e=3600;1>d?e=1:60>d?e=30:180>d&&(e=300),n=b.setTimeout(function(){k(a)},1e3*e)}function l(){j(),m&&k(d.preprocessDate(m,q,o))}var m,n=null,o=f.format,p=e.withoutSuffix,q=f.preprocess;g.$watch(i.amTimeAgo,function(a){return"undefined"==typeof a||null===a||""===a?(j(),void(m&&(h.text(""),m=null))):(m=a,void l())}),a.isDefined(i.amWithoutSuffix)&&g.$watch(i.amWithoutSuffix,function(a){"boolean"==typeof a?(p=a,l()):p=e.withoutSuffix}),i.$observe("amFormat",function(a){"undefined"!=typeof a&&(o=a,l())}),i.$observe("amPreprocess",function(a){q=a,l()}),g.$on("$destroy",function(){j()}),g.$on("amMoment:languageChange",function(){l()})}}]).service("amMoment",["moment","$rootScope","$log","angularMomentConfig",function(b,c,d,e){this.preprocessors={utc:b.utc,unix:b.unix},this.changeLanguage=function(d){var e=b.lang(d);return a.isDefined(d)&&c.$broadcast("amMoment:languageChange"),e},this.preprocessDate=function(c,f,g){return a.isUndefined(f)&&(f=e.preprocess),this.preprocessors[f]?this.preprocessors[f](c,g):(f&&d.warn("angular-moment: Ignoring unsupported value for preprocess: "+f),!isNaN(parseFloat(c))&&isFinite(c)?b(parseInt(c,10)):b(c,g))},this.applyTimezone=function(a){var b=e.timezone;return a&&b&&(a.tz?a=a.tz(b):d.warn("angular-moment: timezone specified but moment.tz() is undefined. Did you forget to include moment-timezone.js?")),a}}]).filter("amCalendar",["moment","amMoment",function(a,b){return function(c,d){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,d);var e=a(c);return e.isValid()?b.applyTimezone(e).calendar():""}}]).filter("amDateFormat",["moment","amMoment",function(a,b){return function(c,d,e){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,e);var f=a(c);return f.isValid()?b.applyTimezone(f).format(d):""}}]).filter("amDurationFormat",["moment",function(a){return function(b,c,d){return"undefined"==typeof b||null===b?"":a.duration(b,c).humanize(d)}}])}"function"==typeof define&&define.amd?define("angular-moment",["angular","moment"],a):a(angular,window.moment)}(); +!function(){"use strict";function a(a,b){return a.module("angularMoment",[]).constant("angularMomentConfig",{preprocess:null,timezone:"",format:null}).constant("moment",b).constant("amTimeAgoConfig",{withoutSuffix:!1}).directive("amTimeAgo",["$window","moment","amMoment","amTimeAgoConfig","angularMomentConfig",function(b,c,d,e,f){return function(g,h,i){function j(){o&&(b.clearTimeout(o),o=null)}function k(a){if(h.text(a.fromNow(q)),!t){var d=c().diff(a,"minute"),e=3600;1>d?e=1:60>d?e=30:180>d&&(e=300),o=b.setTimeout(function(){k(a)},1e3*e)}}function l(){j(),m&&k(d.preprocessDate(m,r,p))}var m,n,o=null,p=f.format,q=e.withoutSuffix,r=f.preprocess,s=i.amTimeAgo.replace(/^::/,""),t=0===i.amTimeAgo.indexOf("::");n=g.$watch(s,function(a){return"undefined"==typeof a||null===a||""===a?(j(),void(m&&(h.text(""),m=null))):(m=a,l(),void(void 0!==a&&t&&n()))}),a.isDefined(i.amWithoutSuffix)&&g.$watch(i.amWithoutSuffix,function(a){"boolean"==typeof a?(q=a,l()):q=e.withoutSuffix}),i.$observe("amFormat",function(a){"undefined"!=typeof a&&(p=a,l())}),i.$observe("amPreprocess",function(a){r=a,l()}),g.$on("$destroy",function(){j()}),g.$on("amMoment:languageChange",function(){l()})}}]).service("amMoment",["moment","$rootScope","$log","angularMomentConfig",function(b,c,d,e){this.preprocessors={utc:b.utc,unix:b.unix},this.changeLanguage=function(d){var e=b.lang(d);return a.isDefined(d)&&c.$broadcast("amMoment:languageChange"),e},this.preprocessDate=function(c,f,g){return a.isUndefined(f)&&(f=e.preprocess),this.preprocessors[f]?this.preprocessors[f](c,g):(f&&d.warn("angular-moment: Ignoring unsupported value for preprocess: "+f),!isNaN(parseFloat(c))&&isFinite(c)?b(parseInt(c,10)):b(c,g))},this.applyTimezone=function(a){var b=e.timezone;return a&&b&&(a.tz?a=a.tz(b):d.warn("angular-moment: timezone specified but moment.tz() is undefined. Did you forget to include moment-timezone.js?")),a}}]).filter("amCalendar",["moment","amMoment",function(a,b){return function(c,d){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,d);var e=a(c);return e.isValid()?b.applyTimezone(e).calendar():""}}]).filter("amDateFormat",["moment","amMoment",function(a,b){return function(c,d,e){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,e);var f=a(c);return f.isValid()?b.applyTimezone(f).format(d):""}}]).filter("amDurationFormat",["moment",function(a){return function(b,c,d){return"undefined"==typeof b||null===b?"":a.duration(b,c).humanize(d)}}])}"function"==typeof define&&define.amd?define("angular-moment",["angular","moment"],a):a(angular,window.moment)}(); //# sourceMappingURL=angular-moment.min.map \ No newline at end of file diff --git a/angular-moment.min.map b/angular-moment.min.map index a9775c5..cbef601 100644 --- a/angular-moment.min.map +++ b/angular-moment.min.map @@ -1 +1 @@ -{"version":3,"file":"angular-moment.min.js","sources":["angular-moment.js"],"names":["angularMoment","angular","moment","module","constant","preprocess","timezone","format","withoutSuffix","directive","$window","amMoment","amTimeAgoConfig","angularMomentConfig","scope","element","attr","cancelTimer","activeTimeout","clearTimeout","updateTime","momentInstance","text","fromNow","howOld","diff","secondsUntilUpdate","setTimeout","updateMoment","currentValue","preprocessDate","currentFormat","$watch","amTimeAgo","value","isDefined","amWithoutSuffix","$observe","newValue","$on","service","$rootScope","$log","this","preprocessors","utc","unix","changeLanguage","lang","result","$broadcast","isUndefined","warn","isNaN","parseFloat","isFinite","parseInt","applyTimezone","aMoment","tz","filter","date","isValid","calendar","suffix","duration","humanize","define","amd","window"],"mappings":"CAIA,WACC,YAEA,SAASA,GAAcC,EAASC,GAS/B,MAAOD,GAAQE,OAAO,oBASpBC,SAAS,uBAWTC,WAAY,KAYZC,SAAU,GAaVC,OAAQ,OAURH,SAAS,SAAUF,GAUnBE,SAAS,mBAUTI,eAAe,IAUfC,UAAU,aAAc,UAAW,SAAU,WAAY,kBAAmB,sBAAuB,SAAUC,EAASR,EAAQS,EAAUC,EAAiBC,GAEzJ,MAAO,UAAUC,EAAOC,EAASC,GAOhC,QAASC,KACJC,IACHR,EAAQS,aAAaD,GACrBA,EAAgB,MAIlB,QAASE,GAAWC,GACnBN,EAAQO,KAAKD,EAAeE,QAAQf,GACpC,IAAIgB,GAAStB,IAASuB,KAAKJ,EAAgB,UACvCK,EAAqB,IACZ,GAATF,EACHE,EAAqB,EACF,GAATF,EACVE,EAAqB,GACF,IAATF,IACVE,EAAqB,KAGtBR,EAAgBR,EAAQiB,WAAW,WAClCP,EAAWC,IACY,IAArBK,GAGJ,QAASE,KACRX,IACIY,GACHT,EAAWT,EAASmB,eAAeD,EAAcxB,EAAY0B,IAjC/D,GACIF,GADAX,EAAgB,KAEhBa,EAAgBlB,EAAoBN,OACpCC,EAAgBI,EAAgBJ,cAChCH,EAAaQ,EAAoBR,UAiCrCS,GAAMkB,OAAOhB,EAAKiB,UAAW,SAAUC,GACtC,MAAsB,mBAAVA,IAAqC,OAAVA,GAA8B,KAAVA,GAC1DjB,SACIY,IACHd,EAAQO,KAAK,IACbO,EAAe,SAKjBA,EAAeK,MACfN,QAGG3B,EAAQkC,UAAUnB,EAAKoB,kBAC1BtB,EAAMkB,OAAOhB,EAAKoB,gBAAiB,SAAUF,GACvB,iBAAVA,IACV1B,EAAgB0B,EAChBN,KAEApB,EAAgBI,EAAgBJ,gBAKnCQ,EAAKqB,SAAS,WAAY,SAAU9B,GACd,mBAAXA,KACTwB,EAAgBxB,EAChBqB,OAIFZ,EAAKqB,SAAS,eAAgB,SAAUC,GACvCjC,EAAaiC,EACbV,MAGDd,EAAMyB,IAAI,WAAY,WACrBtB,MAGDH,EAAMyB,IAAI,0BAA2B,WACpCX,UAUFY,QAAQ,YAAa,SAAU,aAAc,OAAQ,sBAAuB,SAAUtC,EAAQuC,EAAYC,EAAM7B,GAUhH8B,KAAKC,eACJC,IAAK3C,EAAO2C,IACZC,KAAM5C,EAAO4C,MAcdH,KAAKI,eAAiB,SAAUC,GAC/B,GAAIC,GAAS/C,EAAO8C,KAAKA,EAIzB,OAHI/C,GAAQkC,UAAUa,IACrBP,EAAWS,WAAW,2BAEhBD,GAiBRN,KAAKb,eAAiB,SAAUI,EAAO7B,EAAYE,GAIlD,MAHIN,GAAQkD,YAAY9C,KACvBA,EAAaQ,EAAoBR,YAE9BsC,KAAKC,cAAcvC,GACfsC,KAAKC,cAAcvC,GAAY6B,EAAO3B,IAE1CF,GACHqC,EAAKU,KAAK,8DAAgE/C,IAEtEgD,MAAMC,WAAWpB,KAAWqB,SAASrB,GAElChC,EAAOsD,SAAStB,EAAO,KAGxBhC,EAAOgC,EAAO3B,KAetBoC,KAAKc,cAAgB,SAAUC,GAC9B,GAAIpD,GAAWO,EAAoBP,QAQnC,OAPIoD,IAAWpD,IACVoD,EAAQC,GACXD,EAAUA,EAAQC,GAAGrD,GAErBoC,EAAKU,KAAK,mHAGLM,MASRE,OAAO,cAAe,SAAU,WAAY,SAAU1D,EAAQS,GAC9D,MAAO,UAAUuB,EAAO7B,GACvB,GAAqB,mBAAV6B,IAAmC,OAAVA,EACnC,MAAO,EAGRA,GAAQvB,EAASmB,eAAeI,EAAO7B,EACvC,IAAIwD,GAAO3D,EAAOgC,EAClB,OAAK2B,GAAKC,UAIHnD,EAAS8C,cAAcI,GAAME,WAH5B,OAaTH,OAAO,gBAAiB,SAAU,WAAY,SAAU1D,EAAQS,GAChE,MAAO,UAAUuB,EAAO3B,EAAQF,GAC/B,GAAqB,mBAAV6B,IAAmC,OAAVA,EACnC,MAAO,EAGRA,GAAQvB,EAASmB,eAAeI,EAAO7B,EACvC,IAAIwD,GAAO3D,EAAOgC,EAClB,OAAK2B,GAAKC,UAIHnD,EAAS8C,cAAcI,GAAMtD,OAAOA,GAHnC,OAaTqD,OAAO,oBAAqB,SAAU,SAAU1D,GAChD,MAAO,UAAUgC,EAAO3B,EAAQyD,GAC/B,MAAqB,mBAAV9B,IAAmC,OAAVA,EAC5B,GAGDhC,EAAO+D,SAAS/B,EAAO3B,GAAQ2D,SAASF,OAK7B,kBAAXG,SAAyBA,OAAOC,IAC1CD,OAAO,kBAAmB,UAAW,UAAWnE,GAEhDA,EAAcC,QAASoE,OAAOnE"} \ No newline at end of file +{"version":3,"file":"angular-moment.min.js","sources":["angular-moment.js"],"names":["angularMoment","angular","moment","module","constant","preprocess","timezone","format","withoutSuffix","directive","$window","amMoment","amTimeAgoConfig","angularMomentConfig","scope","element","attr","cancelTimer","activeTimeout","clearTimeout","updateTime","momentInstance","text","fromNow","isBindOnce","howOld","diff","secondsUntilUpdate","setTimeout","updateMoment","currentValue","preprocessDate","currentFormat","unwatchChanges","modelName","amTimeAgo","replace","indexOf","$watch","value","undefined","isDefined","amWithoutSuffix","$observe","newValue","$on","service","$rootScope","$log","this","preprocessors","utc","unix","changeLanguage","lang","result","$broadcast","isUndefined","warn","isNaN","parseFloat","isFinite","parseInt","applyTimezone","aMoment","tz","filter","date","isValid","calendar","suffix","duration","humanize","define","amd","window"],"mappings":"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"} \ No newline at end of file diff --git a/tests.js b/tests.js index 1bcc12d..7b1c80d 100644 --- a/tests.js +++ b/tests.js @@ -123,6 +123,87 @@ describe('module angularMoment', function () { }, 50); }); + it('should change the text of the element to "a few seconds ago" when given unix timestamp with one time binding', function () { + $rootScope.testDate = new Date().getTime() / 1000; + var element = angular.element(''); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('a few seconds ago'); + }); + + it('should change the text of the element to "a few seconds ago" when given current time with one time binding', function () { + $rootScope.testDate = new Date(); + var element = angular.element(''); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('a few seconds ago'); + }); + + it('should change the text of the div to "3 minutes ago" when given a date 3 minutes ago with one time binding', function () { + $rootScope.testDate = new Date(new Date().getTime() - 3 * 60 * 1000); + var element = angular.element('
'); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('3 minutes ago'); + }); + + it('should change the text of the div to "2 hours ago" when given a date 2 hours ago with one time binding', function () { + $rootScope.testDate = new Date(new Date().getTime() - 2 * 60 * 60 * 1000); + var element = angular.element('
'); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('2 hours ago'); + }); + + it('should change the text of the div to "one year ago" when given a date one year ago with one time binding', function () { + var today = new Date(); + $rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()); + var element = angular.element('
'); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('a year ago'); + }); + + it('should parse correctly numeric dates as milliseconds since the epoch with one time binding', function () { + $rootScope.testDate = new Date().getTime(); + var element = angular.element('
'); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('a few seconds ago'); + }); + + it('should not update the value if date changes on scope when using one time binding', function () { + var today = new Date(); + $rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()).getTime(); + var element = angular.element('
'); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('a year ago'); + $rootScope.testDate = new Date(); + $rootScope.$digest(); + expect(element.text()).toBe('a year ago'); + }); + + it('should not update the span text as time passes when using one time binding', function (done) { + $rootScope.testDate = new Date(new Date().getTime() - 44000); + var element = angular.element('
'); + element = $compile(element)($rootScope); + $rootScope.$digest(); + expect(element.text()).toBe('a few seconds ago'); + + var waitsInterval = setInterval(function () { + // Wait until $rootScope.date is more than 45 seconds old + if (new Date().getTime() - $rootScope.testDate.getTime() < 45000) { + return; + } + + clearInterval(waitsInterval); + $rootScope.$digest(); + expect(element.text()).toBe('a few seconds ago'); + done(); + }, 50); + }); + it('should handle undefined data', function () { $rootScope.testDate = null; var element = angular.element('
');