PluginProbe
Cooked – Recipe Management / 1.11.4
Cooked – Recipe Management v1.11.4
1.16.1 1.16.0 1.15.0 trunk 1.10.0 1.11.0 1.11.1 1.11.2 1.11.3 1.11.4 1.12.0 1.13.0 1.14.0 1.7.10 1.7.11 1.7.12 1.7.13 1.7.15.1 1.7.15.3 1.7.15.4 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 All 37 releases
cooked / assets / js / timer / jquery.simple.timer.js

jquery.simple.timer.js in Cooked – Recipe Management 1.11.4, at assets/js/timer/jquery.simple.timer.js

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