1/* 2* jQuery-Simple-Timer 3* 4* Creates a countdown timer. 5* 6* Example: 7* $('.timer').startTimer(); 8* 9*/ 10 11(function (factory) { 12 // Using as a CommonJS module 13 if(typeof module === "object" && typeof module.exports === "object") { 14 // jQuery must be provided as argument when used 15 // as a CommonJS module. 16 // 17 // For example: 18 // let $ = require("jquery"); 19 // require("jquery-simple-timer")($); 20 module.exports = function(jq) { 21 factory(jq, window, document); 22 } 23 } else { 24 // Using as script tag 25 // 26 // For example: 27 // <script src="jquery.simple.timer.js"></script> 28 factory(jQuery, window, document); 29 } 30}(function($, window, document, undefined) { 31 32 // Polyfill new JS features for older browser 33 Number.isFinite = Number.isFinite || function(value) { 34 return typeof value === 'number' && isFinite(value); 35 } 36 37 var timer; 38 39 var Timer = function(targetElement){ 40 this._options = {}; 41 this.targetElement = targetElement; 42 return this; 43 }; 44 45 Timer.start = function(userOptions, targetElement){ 46 timer = new Timer(targetElement); 47 mergeOptions(timer, userOptions); 48 return timer.start(userOptions); 49 }; 50 51 // Writes to `this._options` object so that other 52 // functions can access it without having to 53 // pass this object as argument multiple times. 54 function mergeOptions(timer, opts) { 55 opts = opts || {}; 56 57 // Element that will be created for hours, minutes, and seconds. 58 timer._options.elementContainer = opts.elementContainer || 'div'; 59 60 var classNames = opts.classNames || {}; 61 62 timer._options.classNameSeconds = classNames.seconds || 'jst-seconds' 63 , timer._options.classNameMinutes = classNames.minutes || 'jst-minutes' 64 , timer._options.classNameHours = classNames.hours || 'jst-hours' 65 , timer._options.classNameClearDiv = classNames.clearDiv || 'jst-clearDiv' 66 , timer._options.classNameTimeout = classNames.timeout || 'jst-timeout'; 67 } 68 69 Timer.prototype.start = function(options) { 70 71 var that = this; 72 73 var createSubElements = function(timerBoxElement){ 74 var seconds = document.createElement(that._options.elementContainer); 75 seconds.className = that._options.classNameSeconds; 76 77 var minutes = document.createElement(that._options.elementContainer); 78 minutes.className = that._options.classNameMinutes; 79 80 var hours = document.createElement(that._options.elementContainer); 81 hours.className = that._options.classNameHours; 82 83 var clearElement = document.createElement(that._options.elementContainer); 84 clearElement.className = that._options.classNameClearDiv; 85 86 return timerBoxElement. 87 append(hours). 88 append(minutes). 89 append(seconds). 90 append(clearElement); 91 }; 92 93 this.targetElement.each(function(_index, timerBox) { 94 var that = this; 95 var timerBoxElement = $(timerBox); 96 var cssClassSnapshot = timerBoxElement.attr('class'); 97 98 timerBoxElement.on('complete', function() { 99 clearInterval(timerBoxElement.intervalId); 100 }); 101 102 timerBoxElement.on('complete', function() { 103 timerBoxElement.onComplete(timerBoxElement); 104 }); 105 106 timerBoxElement.on('complete', function(){ 107 timerBoxElement.addClass(that._options.classNameTimeout); 108 }); 109 110 timerBoxElement.on('complete', function(){ 111 if(options && options.loop === true) { 112 timer.resetTimer(timerBoxElement, options, cssClassSnapshot); 113 } 114 }); 115 116 timerBoxElement.on('pause', function() { 117 clearInterval(timerBoxElement.intervalId); 118 timerBoxElement.paused = true; 119 }); 120 121 timerBoxElement.on('resume', function() { 122 timerBoxElement.paused = false; 123 const secondsLeft = timerBoxElement.data('timeLeft'); 124 const onComplete = timerBoxElement.onComplete; 125 that.startCountdown(timerBoxElement, { secondsLeft, onComplete }); 126 }); 127 128 createSubElements(timerBoxElement); 129 return this.startCountdown(timerBoxElement, options); 130 }.bind(this)); 131 }; 132 133 /** 134 * Resets timer and add css class 'loop' to indicate the timer is in a loop.
135 * $timerBox {jQuery object} - The timer element 136 * options {object} - The options for the timer 137 * css - The original css of the element 138 */ 139 Timer.prototype.resetTimer = function($timerBox, options, css) { 140 var interval = 0; 141 if(options.loopInterval) { 142 interval = parseInt(options.loopInterval, 10) * 1000; 143 } 144 setTimeout(function() { 145 $timerBox.trigger('reset'); 146 $timerBox.attr('class', css + ' loop'); 147 timer.startCountdown($timerBox, options); 148 }, interval); 149 } 150 151 Timer.prototype.fetchSecondsLeft = function(element){ 152 var secondsLeft = element.data('seconds-left'); 153 var minutesLeft = element.data('minutes-left'); 154 155 if(Number.isFinite(secondsLeft)){ 156 return parseInt(secondsLeft, 10); 157 } else if(Number.isFinite(minutesLeft)) { 158 return parseFloat(minutesLeft) * 60; 159 }else { 160 throw 'Missing time data'; 161 } 162 }; 163 164 Timer.prototype.startCountdown = function(element, options) { 165 options = options || {}; 166 167 var intervalId = null; 168 var defaultComplete = function(){ 169 clearInterval(intervalId); 170 return this.clearTimer(element); 171 }.bind(this); 172 173 element.onComplete = options.onComplete || defaultComplete; 174 element.allowPause = options.allowPause || false; 175 if(element.allowPause){ 176 element.on('click', function() { 177 if(element.paused){ 178 element.trigger('resume'); 179 }else{ 180 element.trigger('pause'); 181 } 182 }); 183 } 184 185 var secondsLeft = options.secondsLeft || this.fetchSecondsLeft(element); 186 187 var refreshRate = options.refreshRate || 1000; 188 var endTime = secondsLeft + this.currentTime(); 189 var timeLeft = endTime - this.currentTime(); 190 191 this.setFinalValue(this.formatTimeLeft(timeLeft), element); 192 193 intervalId = setInterval((function() { 194 timeLeft = endTime - this.currentTime(); 195 // When timer has been idle and only resumed past timeout, 196 // then we immediatelly complete the timer. 197 if(timeLeft < 0 ){ 198 timeLeft = 0; 199 } 200 element.data('timeLeft', timeLeft); 201 this.setFinalValue(this.formatTimeLeft(timeLeft), element); 202 }.bind(this)), refreshRate); 203 204 element.intervalId = intervalId; 205 }; 206 207 Timer.prototype.clearTimer = function(element){ 208 element.find('.jst-seconds').text('00'); 209 element.find('.jst-minutes').text('00:'); 210 element.find('.jst-hours').text('00:'); 211 }; 212 213 Timer.prototype.currentTime = function() { 214 return Math.round((new Date()).getTime() / 1000); 215 }; 216 217 Timer.prototype.formatTimeLeft = function(timeLeft) { 218 219 var lpad = function(n, width) { 220 width = width || 2; 221 n = n + ''; 222 223 var padded = null; 224 225 if (n.length >= width) { 226 padded = n; 227 } else { 228 padded = Array(width - n.length + 1).join(0) + n; 229 } 230 231 return padded; 232 }; 233 234 var hours = Math.floor(timeLeft / 3600); 235 timeLeft -= hours * 3600; 236 237 var minutes = Math.floor(timeLeft / 60); 238 timeLeft -= minutes * 60; 239 240 var seconds = parseInt(timeLeft % 60, 10); 241 242 if (+hours === 0 && +minutes === 0 && +seconds === 0) { 243 return []; 244 } else { 245 return [lpad(hours), lpad(minutes), lpad(seconds)]; 246 } 247 }; 248 249 Timer.prototype.setFinalValue = function(finalValues, element) { 250 251 if(finalValues.length === 0){ 252 this.clearTimer(element); 253 element.trigger('complete'); 254 return false; 255 } 256 257 element.find('.' + this._options.classNameSeconds).text(finalValues.pop()); 258 element.find('.' + this._options.classNameMinutes).text(finalValues.pop() + ':'); 259 element.find('.' + this._options.classNameHours).text(finalValues.pop() + ':'); 260 }; 261 262 263 $.fn.startTimer = function(options) { 264 this.TimerObject = Timer; 265 Timer.start(options, this); 266 return this; 267 }; 268 269}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.