Skip to content

Commit ab88610

Browse files
committed
Merge pullrequest #5 - Thanks @elisehuard
2 parents 955e36f + 9c36a25 commit ab88610

File tree

1 file changed

+185
-164
lines changed

1 file changed

+185
-164
lines changed

src/jquery.counter.js

Lines changed: 185 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -10,189 +10,210 @@
1010
else definition(context['$']);
1111
}(this, function ($) {
1212

13-
$.fn.counter = function(options) {
13+
var methods = {
14+
init: function(options) {
1415

15-
options = options || {};
16+
options = options || {};
1617

17-
var checkStop = function(data) {
18-
var stop = 0;
19-
var current = 0;
20-
$.each(data.parts, function(i, part) {
21-
stop += (stop * part.limit) + part.stop;
22-
current += (current * part.limit) + part.value;
23-
});
24-
return data.down ? stop >= current : stop <= current;
25-
};
18+
var checkStop = function(data) {
19+
var stop = 0;
20+
var current = 0;
21+
$.each(data.parts, function(i, part) {
22+
stop += (stop * part.limit) + part.stop;
23+
current += (current * part.limit) + part.value;
24+
});
25+
return data.down ? stop >= current : stop <= current;
26+
};
2627

27-
var tick = function() {
28-
var e = $(this);
29-
var data = e.data('counter');
30-
var i = data.parts.length - 1;
31-
while(i >= 0 ) {
32-
var part = data.parts[i];
33-
part.value += data.down ? -1 : 1;
34-
if (data.down && part.value < 0) {
35-
part.value = part.limit;
36-
} else if (!data.down && part.value > part.limit) {
37-
part.value = 0;
38-
} else {
39-
break;
28+
var tick = function() {
29+
var e = $(this);
30+
var data = e.data('counter');
31+
var i = data.parts.length - 1;
32+
while(i >= 0 ) {
33+
var part = data.parts[i];
34+
part.value += data.down ? -1 : 1;
35+
if (data.down && part.value < 0) {
36+
part.value = part.limit;
37+
} else if (!data.down && part.value > part.limit) {
38+
part.value = 0;
39+
} else {
40+
break;
41+
}
42+
i--;
4043
}
41-
i--;
42-
}
43-
refresh(e, i);
44-
if (checkStop(data)) {
45-
clearInterval(data.intervalId);
46-
e.trigger("counterStop");
47-
}
48-
};
44+
refresh(e, i);
45+
if (checkStop(data)) {
46+
clearInterval(data.intervalId);
47+
e.trigger("counterStop");
48+
}
49+
};
4950

50-
var refresh = function(e, to) {
51-
var data = e.data('counter');
52-
var i = data.parts.length - 1;
53-
while (i >= to) {
54-
var part = data.parts[i];
55-
var digits = part.value + '';
56-
while (digits.length < part.padding) {
57-
digits = '0' + digits;
51+
var refresh = function(e, to) {
52+
var data = e.data('counter');
53+
var i = data.parts.length - 1;
54+
while (i >= to) {
55+
var part = data.parts[i];
56+
var digits = part.value + '';
57+
while (digits.length < part.padding) {
58+
digits = '0' + digits;
59+
}
60+
$.each(split(digits, ''), function(j, digit) {
61+
animate(e, i, j, digit);
62+
});
63+
i--;
5864
}
59-
$.each(split(digits, ''), function(j, digit) {
60-
animate(e, i, j, digit);
61-
});
62-
i--;
63-
}
64-
};
65+
};
6566

66-
var animate = function(e, ipart, idigit, digit) {
67-
var edigit = $($(e.children('span.part').get(ipart)).find('span.digit').get(idigit));
68-
edigit.attr('class', 'digit digit' + digit + ' digit' + edigit.text() + digit).text(digit);
69-
};
67+
var animate = function(e, ipart, idigit, digit) {
68+
var edigit = $($(e.children('span.part').get(ipart)).find('span.digit').get(idigit));
69+
edigit.attr('class', 'digit digit' + digit + ' digit' + edigit.text() + digit).text(digit);
70+
};
7071

71-
//from http://blog.stevenlevithan.com/archives/cross-browser-split
72-
var split = function(undef) {
72+
//from http://blog.stevenlevithan.com/archives/cross-browser-split
73+
var split = function(undef) {
7374

74-
var nativeSplit = String.prototype.split,
75-
compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group
76-
self;
75+
var nativeSplit = String.prototype.split,
76+
compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group
77+
self;
7778

78-
self = function (str, separator, limit) {
79-
// If `separator` is not a regex, use `nativeSplit`
80-
if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
81-
return nativeSplit.call(str, separator, limit);
82-
}
83-
var output = [],
84-
flags = (separator.ignoreCase ? "i" : "") +
85-
(separator.multiline ? "m" : "") +
86-
(separator.extended ? "x" : "") + // Proposed for ES6
87-
(separator.sticky ? "y" : ""), // Firefox 3+
88-
lastLastIndex = 0,
89-
// Make `global` and avoid `lastIndex` issues by working with a copy
90-
separator = new RegExp(separator.source, flags + "g"),
91-
separator2, match, lastIndex, lastLength;
92-
str += ""; // Type-convert
93-
if (!compliantExecNpcg) {
94-
// Doesn't need flags gy, but they don't hurt
95-
separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
96-
}
97-
/* Values for `limit`, per the spec:
98-
* If undefined: 4294967295 // Math.pow(2, 32) - 1
99-
* If 0, Infinity, or NaN: 0
100-
* If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
101-
* If negative number: 4294967296 - Math.floor(Math.abs(limit))
102-
* If other: Type-convert, then use the above rules
103-
*/
104-
limit = limit === undef ?
105-
-1 >>> 0 : // Math.pow(2, 32) - 1
106-
limit >>> 0; // ToUint32(limit)
107-
while (match = separator.exec(str)) {
108-
// `separator.lastIndex` is not reliable cross-browser
109-
lastIndex = match.index + match[0].length;
110-
if (lastIndex > lastLastIndex) {
111-
output.push(str.slice(lastLastIndex, match.index));
112-
// Fix browsers whose `exec` methods don't consistently return `undefined` for
113-
// nonparticipating capturing groups
114-
if (!compliantExecNpcg && match.length > 1) {
115-
match[0].replace(separator2, function () {
116-
for (var i = 1; i < arguments.length - 2; i++) {
117-
if (arguments[i] === undef) {
118-
match[i] = undef;
79+
self = function (str, separator, limit) {
80+
// If `separator` is not a regex, use `nativeSplit`
81+
if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
82+
return nativeSplit.call(str, separator, limit);
83+
}
84+
var output = [],
85+
flags = (separator.ignoreCase ? "i" : "") +
86+
(separator.multiline ? "m" : "") +
87+
(separator.extended ? "x" : "") + // Proposed for ES6
88+
(separator.sticky ? "y" : ""), // Firefox 3+
89+
lastLastIndex = 0,
90+
// Make `global` and avoid `lastIndex` issues by working with a copy
91+
separator = new RegExp(separator.source, flags + "g"),
92+
separator2, match, lastIndex, lastLength;
93+
str += ""; // Type-convert
94+
if (!compliantExecNpcg) {
95+
// Doesn't need flags gy, but they don't hurt
96+
separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
97+
}
98+
/* Values for `limit`, per the spec:
99+
* If undefined: 4294967295 // Math.pow(2, 32) - 1
100+
* If 0, Infinity, or NaN: 0
101+
* If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
102+
* If negative number: 4294967296 - Math.floor(Math.abs(limit))
103+
* If other: Type-convert, then use the above rules
104+
*/
105+
limit = limit === undef ?
106+
-1 >>> 0 : // Math.pow(2, 32) - 1
107+
limit >>> 0; // ToUint32(limit)
108+
while (match = separator.exec(str)) {
109+
// `separator.lastIndex` is not reliable cross-browser
110+
lastIndex = match.index + match[0].length;
111+
if (lastIndex > lastLastIndex) {
112+
output.push(str.slice(lastLastIndex, match.index));
113+
// Fix browsers whose `exec` methods don't consistently return `undefined` for
114+
// nonparticipating capturing groups
115+
if (!compliantExecNpcg && match.length > 1) {
116+
match[0].replace(separator2, function () {
117+
for (var i = 1; i < arguments.length - 2; i++) {
118+
if (arguments[i] === undef) {
119+
match[i] = undef;
120+
}
119121
}
120-
}
121-
});
122+
});
123+
}
124+
if (match.length > 1 && match.index < str.length) {
125+
Array.prototype.push.apply(output, match.slice(1));
126+
}
127+
lastLength = match[0].length;
128+
lastLastIndex = lastIndex;
129+
if (output.length >= limit) {
130+
break;
131+
}
122132
}
123-
if (match.length > 1 && match.index < str.length) {
124-
Array.prototype.push.apply(output, match.slice(1));
133+
if (separator.lastIndex === match.index) {
134+
separator.lastIndex++; // Avoid an infinite loop
125135
}
126-
lastLength = match[0].length;
127-
lastLastIndex = lastIndex;
128-
if (output.length >= limit) {
129-
break;
130-
}
131-
}
132-
if (separator.lastIndex === match.index) {
133-
separator.lastIndex++; // Avoid an infinite loop
134136
}
135-
}
136-
if (lastLastIndex === str.length) {
137-
if (lastLength || !separator.test("")) {
138-
output.push("");
137+
if (lastLastIndex === str.length) {
138+
if (lastLength || !separator.test("")) {
139+
output.push("");
140+
}
141+
} else {
142+
output.push(str.slice(lastLastIndex));
139143
}
140-
} else {
141-
output.push(str.slice(lastLastIndex));
142-
}
143-
return output.length > limit ? output.slice(0, limit) : output;
144-
};
145-
146-
return self;
147-
148-
}();
144+
return output.length > limit ? output.slice(0, limit) : output;
145+
};
146+
147+
return self;
148+
149+
}();
149150

150-
return this.each(function() {
151-
var e = $(this);
152-
var data = e.data('counter') || {};
153-
data.interval = parseInt(options.interval || e.attr('data-interval') || '1000', 10);
154-
data.down = ( options.direction || e.attr('data-direction') || 'down') == 'down';
155-
data.parts = [];
156-
var initial = split(options.initial || e.text(), /([^0-9]+)/);
157-
//WARN: Use attr() no data()
158-
var format = split(options.format || e.attr('data-format') || "23:59:59", /([^0-9]+)/);
159-
var stop = options.stop || e.attr('data-stop');
160-
if (stop) {
161-
stop = split(stop, /([^0-9]+)/);
162-
}
163-
e.html('');
164-
$.each(format, function(index, value) {
165-
if (/^\d+$/.test(value)) {
166-
var part = {};
167-
part.index = index;
168-
part.padding = (value + '').length;
169-
part.limit = parseInt(value, 10);
170-
part.value = parseInt(initial[initial.length - format.length + index] || 0, 10);
171-
part.value = part.value > part.limit ? part.limit : part.value;
172-
part.stop = parseInt(stop ? stop[stop.length - format.length + index] : (data.down ? 0 : part.limit), 10);
173-
part.stop = part.stop > part.limit ? part.limit : part.stop;
174-
part.stop = part.stop < 0 ? 0 : part.stop;
175-
var epart = $('<span>').addClass('part').addClass('part' + index);
176-
var digits = part.value + '';
177-
while (digits.length < part.padding) {
178-
digits = '0' + digits;
179-
}
180-
for(var i=0; i < digits.length; i++) {
181-
epart.append($('<span>').addClass('digit digit' + digits.charAt(i)).text(digits.charAt(i)));
151+
return this.each(function() {
152+
var e = $(this);
153+
var data = e.data('counter') || {};
154+
data.interval = parseInt(options.interval || e.attr('data-interval') || '1000', 10);
155+
data.down = ( options.direction || e.attr('data-direction') || 'down') == 'down';
156+
data.parts = [];
157+
var initial = split(options.initial || e.text(), /([^0-9]+)/);
158+
//WARN: Use attr() no data()
159+
var format = split(options.format || e.attr('data-format') || "23:59:59", /([^0-9]+)/);
160+
var stop = options.stop || e.attr('data-stop');
161+
if (stop) {
162+
stop = split(stop, /([^0-9]+)/);
163+
}
164+
e.html('');
165+
$.each(format, function(index, value) {
166+
if (/^\d+$/.test(value)) {
167+
var part = {};
168+
part.index = index;
169+
part.padding = (value + '').length;
170+
part.limit = parseInt(value, 10);
171+
part.value = parseInt(initial[initial.length - format.length + index] || 0, 10);
172+
part.value = part.value > part.limit ? part.limit : part.value;
173+
part.stop = parseInt(stop ? stop[stop.length - format.length + index] : (data.down ? 0 : part.limit), 10);
174+
part.stop = part.stop > part.limit ? part.limit : part.stop;
175+
part.stop = part.stop < 0 ? 0 : part.stop;
176+
var epart = $('<span>').addClass('part').addClass('part' + index);
177+
var digits = part.value + '';
178+
while (digits.length < part.padding) {
179+
digits = '0' + digits;
180+
}
181+
for(var i=0; i < digits.length; i++) {
182+
epart.append($('<span>').addClass('digit digit' + digits.charAt(i)).text(digits.charAt(i)));
183+
}
184+
e.append(epart);
185+
data.parts.push(part);
186+
} else {
187+
e.append($('<span>').addClass('separator').addClass('separator' + index).text(value));
182188
}
183-
e.append(epart);
184-
data.parts.push(part);
189+
});
190+
if (!checkStop(data)) {
191+
data.intervalId = setInterval($.proxy(tick, this), data.interval);
185192
} else {
186-
e.append($('<span>').addClass('separator').addClass('separator' + index).text(value));
193+
e.trigger("counterStop");
187194
}
195+
e.data('counter', data);
196+
return this;
188197
});
189-
if (!checkStop(data)) {
190-
data.intervalId = setInterval($.proxy(tick, this), data.interval);
191-
} else {
192-
e.trigger("counterStop");
193-
}
194-
e.data('counter', data);
195-
return this;
196-
});
198+
},
199+
stop: function() {
200+
var e = $(this);
201+
var data = e.data('counter');
202+
clearInterval(data.intervalId);
203+
e.trigger("counterStop");
204+
return this;
205+
}
206+
}
207+
208+
$.fn.counter = function(method) {
209+
// Method calling logic
210+
if ( methods[method] ) {
211+
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
212+
} else if ( typeof method === 'object' || ! method ) {
213+
return methods.init.apply( this, arguments );
214+
} else {
215+
$.error( 'Method ' + method + ' does not exist on jQuery.counter' );
216+
}
197217
};
218+
198219
}));

0 commit comments

Comments
 (0)