From 9b7c862dd6fdf9f918c7228a07dc9a5ff17d0ac9 Mon Sep 17 00:00:00 2001 From: mohitYogi <20014551+mohitYogi@users.noreply.github.com> Date: Wed, 31 Jul 2019 20:36:57 +0530 Subject: [PATCH 1/4] Updated timer to support continuous run (#1) (#92) * Updated timer to support continuous run (#1) * Updated intervalHandler to support continuous run intervalHandler is updated in order to support continuous timer run, even after duration is completed * Flag for single call to callback Flag for single call to callback when timer completes in continuous run. * Update utils.js * support continuous Timer run 1. Added stopTimerOnDuration in config to run timer continuously. 2. Updated intervalHandler to support continuous run 3. Added Flag isCallbackCalled to stop multiple calls to callback after reaching the duration in continuous run. * Updates after review. 1. Removed stopTimerOnDuration flag (repeat flag do the same.) 2. Removed isCallbackCalled flag, as suggested after commit review. * Update after Review Removed flag isCallbackCalled. (Not required). * Updates after review 1. Removed stopTimerOnDuration flag (repeat flag do the same.) 2. Removed isCallbackCalled flag, as suggested after commit review. * Updates after Review 1. Removed stopTimerOnDuration flag (repeat flag do the same.) 2. Removed isCallbackCalled flag, as suggested after commit review. * Patch version New rule for checking timer duration completed. * Update timer.jquery.js * Semicolon & Comment update Added missing semi colon. Updated Comment. * Removed & Updated Comment --- dist/timer.jquery.js | 10 ++++++---- dist/timer.jquery.min.js | 2 +- package.json | 2 +- src/Timer.js | 1 + src/utils.js | 10 ++++++---- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/dist/timer.jquery.js b/dist/timer.jquery.js index b8c2c8b..068431e 100644 --- a/dist/timer.jquery.js +++ b/dist/timer.jquery.js @@ -62,7 +62,7 @@ function getDefaultConfig() { repeat: false, // This will repeat callback every n times duration is elapsed countdown: false, // If true, this will render the timer as a countdown (must have duration) format: null, // This sets the format in which the time will be printed - updateFrequency: 500 // How often should timer display update + updateFrequency: 500, // How often should timer display update }; } @@ -250,15 +250,16 @@ function intervalHandler(timerInstance) { } timerInstance.render(); + if (!timerInstance.config.duration) { return; } // If the timer was called with a duration parameter, - // run the callback if duration is complete + // run the callback if duration is complete or total seconds is more than duration // and remove the duration if `repeat` is not requested if (timerInstance.totalSeconds > 0 && - timerInstance.totalSeconds % timerInstance.config.duration === 0) { + (timerInstance.totalSeconds % timerInstance.config.duration === 0 || timerInstance.totalSeconds > timerInstance.config.duration )) { if (timerInstance.config.callback) { timerInstance.config.callback(); } @@ -293,6 +294,7 @@ function Timer(element, config) { this.originalConfig = $.extend({}, config); this.totalSeconds = 0; this.intervalId = null; + // A HTML element will have the html() method in jQuery to inject content, this.html = 'html'; if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') { @@ -423,4 +425,4 @@ $.fn.timer = function(options) { } }); }; -} (jQuery)); \ No newline at end of file +} (jQuery)); diff --git a/dist/timer.jquery.min.js b/dist/timer.jquery.min.js index db5f275..1e53ab4 100644 --- a/dist/timer.jquery.min.js +++ b/dist/timer.jquery.min.js @@ -1 +1 @@ -!function(a){function b(a){var b;return a=a||0,b=Math.floor(a/60),{days:a>=n.DAYINSECONDS?Math.floor(a/n.DAYINSECONDS):0,hours:a>=3600?Math.floor(a%n.DAYINSECONDS/3600):0,totalMinutes:b,minutes:a>=60?Math.floor(a%3600/60):b,seconds:a%60,totalSeconds:a}}function c(a){return((a=parseInt(a,10))<10&&"0")+a}function d(){return{seconds:0,editable:!1,duration:null,callback:function(){console.log("Time up!")},repeat:!1,countdown:!1,format:null,updateFrequency:500}}function e(){return Math.round((Date.now?Date.now():(new Date).getTime())/1e3)}function f(a){var d=b(a);if(d.days)return d.days+":"+c(d.hours)+":"+c(d.minutes)+":"+c(d.seconds);if(d.hours)return d.hours+":"+c(d.minutes)+":"+c(d.seconds);return d.minutes?d.minutes+":"+c(d.seconds)+" min":d.seconds+" sec"}function g(a,d){for(var e=b(a),f=[{identifier:"%d",value:e.days},{identifier:"%h",value:e.hours},{identifier:"%m",value:e.minutes},{identifier:"%s",value:e.seconds},{identifier:"%g",value:e.totalMinutes},{identifier:"%t",value:e.totalSeconds},{identifier:"%D",value:c(e.days)},{identifier:"%H",value:c(e.hours)},{identifier:"%M",value:c(e.minutes)},{identifier:"%S",value:c(e.seconds)},{identifier:"%G",value:c(e.totalMinutes)},{identifier:"%T",value:c(e.totalSeconds)}],g=0;g0?c=Number(a.replace(/\ssec/g,"")):a.indexOf("min")>0?(a=a.replace(/\smin/g,""),b=a.split(":"),c=Number(60*b[0])+Number(b[1])):a.match(/\d{1,2}:\d{2}:\d{2}:\d{2}/)?(b=a.split(":"),c=Number(b[0]*n.DAYINSECONDS)+Number(3600*b[1])+Number(60*b[2])+Number(b[3])):a.match(/\d{1,2}:\d{2}:\d{2}/)&&(b=a.split(":"),c=Number(3600*b[0])+Number(60*b[1])+Number(b[2])),c}function j(b,c){b.state=c,a(b.element).data("state",c)}function k(b){a(b.element).on("focus",function(){b.pause()}),a(b.element).on("blur",function(){b.totalSeconds=i(a(b.element)[b.html]()),b.resume()})}function l(b){if(b.totalSeconds=e()-b.startTime,b.config.countdown)return b.totalSeconds=b.config.duration-b.totalSeconds,0===b.totalSeconds&&(clearInterval(b.intervalId),j(b,n.TIMER_STOPPED),b.config.callback(),a(b.element).data("seconds")),void b.render();b.render(),b.config.duration&&b.totalSeconds>0&&b.totalSeconds%b.config.duration==0&&(b.config.callback&&b.config.callback(),b.config.repeat||(clearInterval(b.intervalId),j(b,n.TIMER_STOPPED),b.config.duration=null))}function m(b,c){if(this.element=b,this.originalConfig=a.extend({},c),this.totalSeconds=0,this.intervalId=null,this.html="html","INPUT"!==b.tagName&&"TEXTAREA"!==b.tagName||(this.html="val"),this.config=o.getDefaultConfig(),c.duration&&(c.duration=o.durationTimeToSeconds(c.duration)),"string"!=typeof c&&(this.config=a.extend(this.config,c)),this.config.seconds&&(this.totalSeconds=this.config.seconds),this.config.editable&&o.makeEditable(this),this.startTime=o.unixSeconds()-this.totalSeconds,this.config.duration&&this.config.repeat&&this.config.updateFrequency<1e3&&(this.config.updateFrequency=1e3),this.config.countdown){if(!this.config.duration)throw new Error("Countdown option set without duration!");if(this.config.editable)throw new Error("Cannot set editable on a countdown timer!");this.config.startTime=o.unixSeconds()-this.config.duration,this.totalSeconds=this.config.duration}}var n={PLUGIN_NAME:"timer",TIMER_RUNNING:"running",TIMER_PAUSED:"paused",TIMER_REMOVED:"removed",DAYINSECONDS:86400},o={getDefaultConfig:d,unixSeconds:e,secondsToPrettyTime:f,secondsToFormattedTime:g,durationTimeToSeconds:h,prettyTimeToSeconds:i,setState:j,makeEditable:k,intervalHandler:l};m.prototype.start=function(){this.state!==n.TIMER_RUNNING&&(o.setState(this,n.TIMER_RUNNING),this.render(),this.intervalId=setInterval(o.intervalHandler.bind(null,this),this.config.updateFrequency))},m.prototype.pause=function(){this.state===n.TIMER_RUNNING&&(o.setState(this,n.TIMER_PAUSED),clearInterval(this.intervalId))},m.prototype.resume=function(){this.state===n.TIMER_PAUSED&&(o.setState(this,n.TIMER_RUNNING),this.config.countdown?this.startTime=o.unixSeconds()-this.config.duration+this.totalSeconds:this.startTime=o.unixSeconds()-this.totalSeconds,this.intervalId=setInterval(o.intervalHandler.bind(null,this),this.config.updateFrequency))},m.prototype.remove=function(){clearInterval(this.intervalId),o.setState(this,n.TIMER_REMOVED),a(this.element).data(n.PLUGIN_NAME,null),a(this.element).data("seconds",null)},m.prototype.reset=function(){var b=this.originalConfig;this.remove(),a(this.element).timer(b)},m.prototype.render=function(){this.config.format?a(this.element)[this.html](o.secondsToFormattedTime(this.totalSeconds,this.config.format)):a(this.element)[this.html](o.secondsToPrettyTime(this.totalSeconds)),a(this.element).data("seconds",this.totalSeconds)},a.fn.timer=function(b){return b=b||"start",this.each(function(){a.data(this,n.PLUGIN_NAME)instanceof m||a.data(this,n.PLUGIN_NAME,new m(this,b));var c=a.data(this,n.PLUGIN_NAME);"string"==typeof b?"function"==typeof c[b]&&c[b]():c.start()})}}(jQuery); \ No newline at end of file +!function(n){var a={PLUGIN_NAME:"timer",TIMER_RUNNING:"running",TIMER_PAUSED:"paused",TIMER_REMOVED:"removed",DAYINSECONDS:86400};function s(t){var e;return t=t||0,e=Math.floor(t/60),{days:t>=a.DAYINSECONDS?Math.floor(t/a.DAYINSECONDS):0,hours:3600<=t?Math.floor(t%a.DAYINSECONDS/3600):0,totalMinutes:e,minutes:60<=t?Math.floor(t%3600/60):e,seconds:t%60,totalSeconds:t}}function r(t){return((t=parseInt(t,10))<10&&"0")+t}function e(){return Math.round((Date.now?Date.now():(new Date).getTime())/1e3)}function i(t){var e,n;return 0t.config.duration)&&(t.config.callback&&t.config.callback(),t.config.repeat||(clearInterval(t.intervalId),o(t,a.TIMER_STOPPED),t.config.duration=null))}};function c(t,e){if(this.element=t,this.originalConfig=n.extend({},e),this.totalSeconds=0,this.intervalId=null,this.html="html","INPUT"!==t.tagName&&"TEXTAREA"!==t.tagName||(this.html="val"),this.config=d.getDefaultConfig(),e.duration&&(e.duration=d.durationTimeToSeconds(e.duration)),"string"!=typeof e&&(this.config=n.extend(this.config,e)),this.config.seconds&&(this.totalSeconds=this.config.seconds),this.config.editable&&d.makeEditable(this),this.startTime=d.unixSeconds()-this.totalSeconds,this.config.duration&&this.config.repeat&&this.config.updateFrequency<1e3&&(this.config.updateFrequency=1e3),this.config.countdown){if(!this.config.duration)throw new Error("Countdown option set without duration!");if(this.config.editable)throw new Error("Cannot set editable on a countdown timer!");this.config.startTime=d.unixSeconds()-this.config.duration,this.totalSeconds=this.config.duration}}c.prototype.start=function(){this.state!==a.TIMER_RUNNING&&(d.setState(this,a.TIMER_RUNNING),this.render(),this.intervalId=setInterval(d.intervalHandler.bind(null,this),this.config.updateFrequency))},c.prototype.pause=function(){this.state===a.TIMER_RUNNING&&(d.setState(this,a.TIMER_PAUSED),clearInterval(this.intervalId))},c.prototype.resume=function(){this.state===a.TIMER_PAUSED&&(d.setState(this,a.TIMER_RUNNING),this.config.countdown?this.startTime=d.unixSeconds()-this.config.duration+this.totalSeconds:this.startTime=d.unixSeconds()-this.totalSeconds,this.intervalId=setInterval(d.intervalHandler.bind(null,this),this.config.updateFrequency))},c.prototype.remove=function(){clearInterval(this.intervalId),d.setState(this,a.TIMER_REMOVED),n(this.element).data(a.PLUGIN_NAME,null),n(this.element).data("seconds",null)},c.prototype.reset=function(){var t=this.originalConfig;this.remove(),n(this.element).timer(t)},c.prototype.render=function(){this.config.format?n(this.element)[this.html](d.secondsToFormattedTime(this.totalSeconds,this.config.format)):n(this.element)[this.html](d.secondsToPrettyTime(this.totalSeconds)),n(this.element).data("seconds",this.totalSeconds)},n.fn.timer=function(e){return e=e||"start",this.each(function(){n.data(this,a.PLUGIN_NAME)instanceof c||n.data(this,a.PLUGIN_NAME,new c(this,e));var t=n.data(this,a.PLUGIN_NAME);"string"==typeof e?"function"==typeof t[e]&&t[e]():t.start()})}}(jQuery); diff --git a/package.json b/package.json index 14c764d..bf4a8d4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "timer.jquery", "description": "Start/Stop/Resume/Remove a pretty timer inside any HTML element.", "author": "Walmik Deshpande", - "version": "0.9.0", + "version": "0.9.1", "repository": { "type": "git", "url": "git://github.com/walmik/timer.jquery.git" diff --git a/src/Timer.js b/src/Timer.js index bf31aa3..680e1c9 100644 --- a/src/Timer.js +++ b/src/Timer.js @@ -8,6 +8,7 @@ function Timer(element, config) { this.originalConfig = $.extend({}, config); this.totalSeconds = 0; this.intervalId = null; + // A HTML element will have the html() method in jQuery to inject content, this.html = 'html'; if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') { diff --git a/src/utils.js b/src/utils.js index 04c64f3..4cb8279 100644 --- a/src/utils.js +++ b/src/utils.js @@ -52,7 +52,7 @@ function getDefaultConfig() { repeat: false, // This will repeat callback every n times duration is elapsed countdown: false, // If true, this will render the timer as a countdown (must have duration) format: null, // This sets the format in which the time will be printed - updateFrequency: 500 // How often should timer display update + updateFrequency: 500, // How often should timer display update }; } @@ -227,7 +227,7 @@ function intervalHandler(timerInstance) { if (timerInstance.config.countdown) { timerInstance.totalSeconds = timerInstance.config.duration - timerInstance.totalSeconds; - + if (timerInstance.totalSeconds === 0) { clearInterval(timerInstance.intervalId); setState(timerInstance, Constants.TIMER_STOPPED); @@ -240,15 +240,17 @@ function intervalHandler(timerInstance) { } timerInstance.render(); + if (!timerInstance.config.duration) { return; } // If the timer was called with a duration parameter, - // run the callback if duration is complete + // run the callback if duration is complete or total seconds is more than duration // and remove the duration if `repeat` is not requested + if (timerInstance.totalSeconds > 0 && - timerInstance.totalSeconds % timerInstance.config.duration === 0) { + (timerInstance.totalSeconds % timerInstance.config.duration === 0 || timerInstance.totalSeconds > timerInstance.config.duration )) { if (timerInstance.config.callback) { timerInstance.config.callback(); } From 8147b4b605dc39d8704db4243aef1c3e311ccf02 Mon Sep 17 00:00:00 2001 From: Alan Date: Fri, 10 Jul 2020 10:12:37 -0400 Subject: [PATCH 2/4] Update README.md (#99) Let's not send people to an ad-infested abandoned domain name :) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 864df77..86721b8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [Demo & Instructions][demo] | [Download][min] -[demo]: http://jquerytimer.com/ +[demo]: https://walmik.github.io/timer.jquery/ [min]: https://raw.githubusercontent.com/walmik/timer.jquery/master/dist/timer.jquery.min.js ## Getting started From 2d9582c9e8d97c256850899ccad8cb24a361d38a Mon Sep 17 00:00:00 2001 From: Alan Date: Wed, 12 May 2021 13:54:41 -0400 Subject: [PATCH 3/4] Update constants.js (#100) --- src/constants.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/constants.js b/src/constants.js index 64f1472..c94f6de 100644 --- a/src/constants.js +++ b/src/constants.js @@ -2,6 +2,7 @@ var Constants = { PLUGIN_NAME: 'timer', TIMER_RUNNING: 'running', TIMER_PAUSED: 'paused', + TIMER_STOPPED: 'stopped', TIMER_REMOVED: 'removed', DAYINSECONDS: 86400 }; From 372e68f9b38e5d92a33653d944b34a2f0749eba8 Mon Sep 17 00:00:00 2001 From: Rafael Cossovan Date: Sun, 15 Dec 2024 16:50:54 -0300 Subject: [PATCH 4/4] Fix callback execution order for regressive countdowns (#105) * Fix callback execution order for regressive countdowns. The timer must reach 0 first, then execute the callback. * Bump version number. * Fix broken build (jscs). * Publish 0.9.2 release. --- dist/timer.jquery.js | 31 ++++++++++++++++++------------- dist/timer.jquery.min.js | 2 +- package.json | 10 +++++----- src/Timer.js | 2 +- src/utils.js | 15 ++++++++------- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/dist/timer.jquery.js b/dist/timer.jquery.js index 068431e..efdb776 100644 --- a/dist/timer.jquery.js +++ b/dist/timer.jquery.js @@ -1,13 +1,14 @@ -/*! timer.jquery 0.7.1 2017-09-27*/ -(function($) { +/*! timer.jquery 0.9.2 2024-12-13*/ +(function($) { var Constants = { PLUGIN_NAME: 'timer', TIMER_RUNNING: 'running', TIMER_PAUSED: 'paused', + TIMER_STOPPED: 'stopped', TIMER_REMOVED: 'removed', DAYINSECONDS: 86400 }; - + /* global Constants:true */ /** * Private @@ -62,7 +63,7 @@ function getDefaultConfig() { repeat: false, // This will repeat callback every n times duration is elapsed countdown: false, // If true, this will render the timer as a countdown (must have duration) format: null, // This sets the format in which the time will be printed - updateFrequency: 500, // How often should timer display update + updateFrequency: 500 // How often should timer display update }; } @@ -238,19 +239,19 @@ function intervalHandler(timerInstance) { if (timerInstance.config.countdown) { timerInstance.totalSeconds = timerInstance.config.duration - timerInstance.totalSeconds; + timerInstance.render(); + if (timerInstance.totalSeconds === 0) { clearInterval(timerInstance.intervalId); setState(timerInstance, Constants.TIMER_STOPPED); timerInstance.config.callback(); $(timerInstance.element).data('seconds'); } - - timerInstance.render(); return; } timerInstance.render(); - + if (!timerInstance.config.duration) { return; } @@ -258,8 +259,10 @@ function intervalHandler(timerInstance) { // If the timer was called with a duration parameter, // run the callback if duration is complete or total seconds is more than duration // and remove the duration if `repeat` is not requested + if (timerInstance.totalSeconds > 0 && - (timerInstance.totalSeconds % timerInstance.config.duration === 0 || timerInstance.totalSeconds > timerInstance.config.duration )) { + (timerInstance.totalSeconds % timerInstance.config.duration === 0 || + timerInstance.totalSeconds > timerInstance.config.duration )) { if (timerInstance.config.callback) { timerInstance.config.callback(); } @@ -283,7 +286,7 @@ var utils = { makeEditable: makeEditable, intervalHandler: intervalHandler }; - + /** * Timer function to initiate a timer on the provided element with the given config. * @param {Object} element HTML node as passed by jQuery @@ -294,7 +297,7 @@ function Timer(element, config) { this.originalConfig = $.extend({}, config); this.totalSeconds = 0; this.intervalId = null; - + // A HTML element will have the html() method in jQuery to inject content, this.html = 'html'; if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') { @@ -346,7 +349,9 @@ function Timer(element, config) { Timer.prototype.start = function() { if (this.state !== Constants.TIMER_RUNNING) { utils.setState(this, Constants.TIMER_RUNNING); - this.render(); + if (this.config.hidden !== true) { + this.render(); + } this.intervalId = setInterval(utils.intervalHandler.bind(null, this), this.config.updateFrequency); } }; @@ -391,7 +396,7 @@ Timer.prototype.render = function() { } $(this.element).data('seconds', this.totalSeconds); }; - + /* global $:true */ $.fn.timer = function(options) { options = options || 'start'; @@ -425,4 +430,4 @@ $.fn.timer = function(options) { } }); }; -} (jQuery)); +} (jQuery)); \ No newline at end of file diff --git a/dist/timer.jquery.min.js b/dist/timer.jquery.min.js index 1e53ab4..37bc970 100644 --- a/dist/timer.jquery.min.js +++ b/dist/timer.jquery.min.js @@ -1 +1 @@ -!function(n){var a={PLUGIN_NAME:"timer",TIMER_RUNNING:"running",TIMER_PAUSED:"paused",TIMER_REMOVED:"removed",DAYINSECONDS:86400};function s(t){var e;return t=t||0,e=Math.floor(t/60),{days:t>=a.DAYINSECONDS?Math.floor(t/a.DAYINSECONDS):0,hours:3600<=t?Math.floor(t%a.DAYINSECONDS/3600):0,totalMinutes:e,minutes:60<=t?Math.floor(t%3600/60):e,seconds:t%60,totalSeconds:t}}function r(t){return((t=parseInt(t,10))<10&&"0")+t}function e(){return Math.round((Date.now?Date.now():(new Date).getTime())/1e3)}function i(t){var e,n;return 0t.config.duration)&&(t.config.callback&&t.config.callback(),t.config.repeat||(clearInterval(t.intervalId),o(t,a.TIMER_STOPPED),t.config.duration=null))}};function c(t,e){if(this.element=t,this.originalConfig=n.extend({},e),this.totalSeconds=0,this.intervalId=null,this.html="html","INPUT"!==t.tagName&&"TEXTAREA"!==t.tagName||(this.html="val"),this.config=d.getDefaultConfig(),e.duration&&(e.duration=d.durationTimeToSeconds(e.duration)),"string"!=typeof e&&(this.config=n.extend(this.config,e)),this.config.seconds&&(this.totalSeconds=this.config.seconds),this.config.editable&&d.makeEditable(this),this.startTime=d.unixSeconds()-this.totalSeconds,this.config.duration&&this.config.repeat&&this.config.updateFrequency<1e3&&(this.config.updateFrequency=1e3),this.config.countdown){if(!this.config.duration)throw new Error("Countdown option set without duration!");if(this.config.editable)throw new Error("Cannot set editable on a countdown timer!");this.config.startTime=d.unixSeconds()-this.config.duration,this.totalSeconds=this.config.duration}}c.prototype.start=function(){this.state!==a.TIMER_RUNNING&&(d.setState(this,a.TIMER_RUNNING),this.render(),this.intervalId=setInterval(d.intervalHandler.bind(null,this),this.config.updateFrequency))},c.prototype.pause=function(){this.state===a.TIMER_RUNNING&&(d.setState(this,a.TIMER_PAUSED),clearInterval(this.intervalId))},c.prototype.resume=function(){this.state===a.TIMER_PAUSED&&(d.setState(this,a.TIMER_RUNNING),this.config.countdown?this.startTime=d.unixSeconds()-this.config.duration+this.totalSeconds:this.startTime=d.unixSeconds()-this.totalSeconds,this.intervalId=setInterval(d.intervalHandler.bind(null,this),this.config.updateFrequency))},c.prototype.remove=function(){clearInterval(this.intervalId),d.setState(this,a.TIMER_REMOVED),n(this.element).data(a.PLUGIN_NAME,null),n(this.element).data("seconds",null)},c.prototype.reset=function(){var t=this.originalConfig;this.remove(),n(this.element).timer(t)},c.prototype.render=function(){this.config.format?n(this.element)[this.html](d.secondsToFormattedTime(this.totalSeconds,this.config.format)):n(this.element)[this.html](d.secondsToPrettyTime(this.totalSeconds)),n(this.element).data("seconds",this.totalSeconds)},n.fn.timer=function(e){return e=e||"start",this.each(function(){n.data(this,a.PLUGIN_NAME)instanceof c||n.data(this,a.PLUGIN_NAME,new c(this,e));var t=n.data(this,a.PLUGIN_NAME);"string"==typeof e?"function"==typeof t[e]&&t[e]():t.start()})}}(jQuery); +!function(a){function b(a){var b;return a=a||0,b=Math.floor(a/60),{days:a>=n.DAYINSECONDS?Math.floor(a/n.DAYINSECONDS):0,hours:a>=3600?Math.floor(a%n.DAYINSECONDS/3600):0,totalMinutes:b,minutes:a>=60?Math.floor(a%3600/60):b,seconds:a%60,totalSeconds:a}}function c(a){return((a=parseInt(a,10))<10&&"0")+a}function d(){return{seconds:0,editable:!1,duration:null,callback:function(){console.log("Time up!")},repeat:!1,countdown:!1,format:null,updateFrequency:500}}function e(){return Math.round((Date.now?Date.now():(new Date).getTime())/1e3)}function f(a){var d=b(a);if(d.days)return d.days+":"+c(d.hours)+":"+c(d.minutes)+":"+c(d.seconds);if(d.hours)return d.hours+":"+c(d.minutes)+":"+c(d.seconds);return d.minutes?d.minutes+":"+c(d.seconds)+" min":d.seconds+" sec"}function g(a,d){for(var e=b(a),f=[{identifier:"%d",value:e.days},{identifier:"%h",value:e.hours},{identifier:"%m",value:e.minutes},{identifier:"%s",value:e.seconds},{identifier:"%g",value:e.totalMinutes},{identifier:"%t",value:e.totalSeconds},{identifier:"%D",value:c(e.days)},{identifier:"%H",value:c(e.hours)},{identifier:"%M",value:c(e.minutes)},{identifier:"%S",value:c(e.seconds)},{identifier:"%G",value:c(e.totalMinutes)},{identifier:"%T",value:c(e.totalSeconds)}],g=0;g0?c=Number(a.replace(/\ssec/g,"")):a.indexOf("min")>0?(a=a.replace(/\smin/g,""),b=a.split(":"),c=Number(60*b[0])+Number(b[1])):a.match(/\d{1,2}:\d{2}:\d{2}:\d{2}/)?(b=a.split(":"),c=Number(b[0]*n.DAYINSECONDS)+Number(3600*b[1])+Number(60*b[2])+Number(b[3])):a.match(/\d{1,2}:\d{2}:\d{2}/)&&(b=a.split(":"),c=Number(3600*b[0])+Number(60*b[1])+Number(b[2])),c}function j(b,c){b.state=c,a(b.element).data("state",c)}function k(b){a(b.element).on("focus",function(){b.pause()}),a(b.element).on("blur",function(){b.totalSeconds=i(a(b.element)[b.html]()),b.resume()})}function l(b){if(b.totalSeconds=e()-b.startTime,b.config.countdown)return b.totalSeconds=b.config.duration-b.totalSeconds,b.render(),void(0===b.totalSeconds&&(clearInterval(b.intervalId),j(b,n.TIMER_STOPPED),b.config.callback(),a(b.element).data("seconds")));b.render(),b.config.duration&&b.totalSeconds>0&&(b.totalSeconds%b.config.duration==0||b.totalSeconds>b.config.duration)&&(b.config.callback&&b.config.callback(),b.config.repeat||(clearInterval(b.intervalId),j(b,n.TIMER_STOPPED),b.config.duration=null))}function m(b,c){if(this.element=b,this.originalConfig=a.extend({},c),this.totalSeconds=0,this.intervalId=null,this.html="html","INPUT"!==b.tagName&&"TEXTAREA"!==b.tagName||(this.html="val"),this.config=o.getDefaultConfig(),c.duration&&(c.duration=o.durationTimeToSeconds(c.duration)),"string"!=typeof c&&(this.config=a.extend(this.config,c)),this.config.seconds&&(this.totalSeconds=this.config.seconds),this.config.editable&&o.makeEditable(this),this.startTime=o.unixSeconds()-this.totalSeconds,this.config.duration&&this.config.repeat&&this.config.updateFrequency<1e3&&(this.config.updateFrequency=1e3),this.config.countdown){if(!this.config.duration)throw new Error("Countdown option set without duration!");if(this.config.editable)throw new Error("Cannot set editable on a countdown timer!");this.config.startTime=o.unixSeconds()-this.config.duration,this.totalSeconds=this.config.duration}}var n={PLUGIN_NAME:"timer",TIMER_RUNNING:"running",TIMER_PAUSED:"paused",TIMER_STOPPED:"stopped",TIMER_REMOVED:"removed",DAYINSECONDS:86400},o={getDefaultConfig:d,unixSeconds:e,secondsToPrettyTime:f,secondsToFormattedTime:g,durationTimeToSeconds:h,prettyTimeToSeconds:i,setState:j,makeEditable:k,intervalHandler:l};m.prototype.start=function(){this.state!==n.TIMER_RUNNING&&(o.setState(this,n.TIMER_RUNNING),!0!==this.config.hidden&&this.render(),this.intervalId=setInterval(o.intervalHandler.bind(null,this),this.config.updateFrequency))},m.prototype.pause=function(){this.state===n.TIMER_RUNNING&&(o.setState(this,n.TIMER_PAUSED),clearInterval(this.intervalId))},m.prototype.resume=function(){this.state===n.TIMER_PAUSED&&(o.setState(this,n.TIMER_RUNNING),this.config.countdown?this.startTime=o.unixSeconds()-this.config.duration+this.totalSeconds:this.startTime=o.unixSeconds()-this.totalSeconds,this.intervalId=setInterval(o.intervalHandler.bind(null,this),this.config.updateFrequency))},m.prototype.remove=function(){clearInterval(this.intervalId),o.setState(this,n.TIMER_REMOVED),a(this.element).data(n.PLUGIN_NAME,null),a(this.element).data("seconds",null)},m.prototype.reset=function(){var b=this.originalConfig;this.remove(),a(this.element).timer(b)},m.prototype.render=function(){this.config.format?a(this.element)[this.html](o.secondsToFormattedTime(this.totalSeconds,this.config.format)):a(this.element)[this.html](o.secondsToPrettyTime(this.totalSeconds)),a(this.element).data("seconds",this.totalSeconds)},a.fn.timer=function(b){return b=b||"start",this.each(function(){a.data(this,n.PLUGIN_NAME)instanceof m||a.data(this,n.PLUGIN_NAME,new m(this,b));var c=a.data(this,n.PLUGIN_NAME);"string"==typeof b?"function"==typeof c[b]&&c[b]():c.start()})}}(jQuery); \ No newline at end of file diff --git a/package.json b/package.json index bf4a8d4..685d83d 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,16 @@ "name": "timer.jquery", "description": "Start/Stop/Resume/Remove a pretty timer inside any HTML element.", "author": "Walmik Deshpande", - "version": "0.9.1", + "version": "0.9.2", "repository": { "type": "git", "url": "git://github.com/walmik/timer.jquery.git" }, "scripts": { - "test": "./node_modules/.bin/tape ./test/utils-test.js", - "build": "./node_modules/.bin/grunt", - "watch": "./node_modules/.bin/grunt watch", - "karma": "./node_modules/.bin/karma start" + "test": "npx tape ./test/utils-test.js", + "build": "npx grunt", + "watch": "npx grunt watch", + "karma": "npx karma start" }, "engines": { "node": "> 0.10.0" diff --git a/src/Timer.js b/src/Timer.js index 680e1c9..20418c6 100644 --- a/src/Timer.js +++ b/src/Timer.js @@ -8,7 +8,7 @@ function Timer(element, config) { this.originalConfig = $.extend({}, config); this.totalSeconds = 0; this.intervalId = null; - + // A HTML element will have the html() method in jQuery to inject content, this.html = 'html'; if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') { diff --git a/src/utils.js b/src/utils.js index 4cb8279..9d6fbc2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -52,7 +52,7 @@ function getDefaultConfig() { repeat: false, // This will repeat callback every n times duration is elapsed countdown: false, // If true, this will render the timer as a countdown (must have duration) format: null, // This sets the format in which the time will be printed - updateFrequency: 500, // How often should timer display update + updateFrequency: 500 // How often should timer display update }; } @@ -227,20 +227,20 @@ function intervalHandler(timerInstance) { if (timerInstance.config.countdown) { timerInstance.totalSeconds = timerInstance.config.duration - timerInstance.totalSeconds; - + + timerInstance.render(); + if (timerInstance.totalSeconds === 0) { clearInterval(timerInstance.intervalId); setState(timerInstance, Constants.TIMER_STOPPED); timerInstance.config.callback(); $(timerInstance.element).data('seconds'); } - - timerInstance.render(); return; } timerInstance.render(); - + if (!timerInstance.config.duration) { return; } @@ -248,9 +248,10 @@ function intervalHandler(timerInstance) { // If the timer was called with a duration parameter, // run the callback if duration is complete or total seconds is more than duration // and remove the duration if `repeat` is not requested - + if (timerInstance.totalSeconds > 0 && - (timerInstance.totalSeconds % timerInstance.config.duration === 0 || timerInstance.totalSeconds > timerInstance.config.duration )) { + (timerInstance.totalSeconds % timerInstance.config.duration === 0 || + timerInstance.totalSeconds > timerInstance.config.duration )) { if (timerInstance.config.callback) { timerInstance.config.callback(); }