﻿/**

* jQuery.timers - Timer abstractions for jQuery

* Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)

* Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).

* Date: 2009/10/16

*

* @author Blair Mitchelmore

* @version 1.2

*

**/

jQuery.fn.extend({

everyTime: function(interval, label, fn, times) {

return this.each(function() {

jQuery.timer.add(this, interval, label, fn, times);

});

},

oneTime: function(interval, label, fn) {

return this.each(function() {

jQuery.timer.add(this, interval, label, fn, 1);

});

},

stopTime: function(label, fn) {

return this.each(function() {

jQuery.timer.remove(this, label, fn);

});

}

});

jQuery.extend({

timer: {

global: [],

guid: 1,

dataKey: "jQuery.timer",

regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,

powers: {

// Yeah this is major overkill...

'ms': 1,

'cs': 10,

'ds': 100,

's': 1000,

'das': 10000,

'hs': 100000,

'ks': 1000000

},

timeParse: function(value) {

if (value == undefined || value == null)

return null;

var result = this.regex.exec(jQuery.trim(value.toString()));

if (result[2]) {

var num = parseFloat(result[1]);

var mult = this.powers[result[2]] || 1;

return num * mult;

} else {

return value;

}

},

add: function(element, interval, label, fn, times) {

var counter = 0;

if (jQuery.isFunction(label)) {

if (!times) 

times = fn;

fn = label;

label = interval;

}

interval = jQuery.timer.timeParse(interval);

if (typeof interval != 'number' || isNaN(interval) || interval < 0)

return;

if (typeof times != 'number' || isNaN(times) || times < 0) 

times = 0;

times = times || 0;

var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {});

if (!timers[label])

timers[label] = {};

fn.timerID = fn.timerID || this.guid++;

var handler = function() {

if ((++counter > times && times !== 0) || fn.call(element, counter) === false)

jQuery.timer.remove(element, label, fn);

};

handler.timerID = fn.timerID;

if (!timers[label][fn.timerID])

timers[label][fn.timerID] = window.setInterval(handler,interval);

this.global.push( element );

},

remove: function(element, label, fn) {

var timers = jQuery.data(element, this.dataKey), ret;

if ( timers ) {

if (!label) {

for ( label in timers )

this.remove(element, label, fn);

} else if ( timers[label] ) {

if ( fn ) {

if ( fn.timerID ) {

window.clearInterval(timers[label][fn.timerID]);

delete timers[label][fn.timerID];

}

} else {

for ( var fn in timers[label] ) {

window.clearInterval(timers[label][fn]);

delete timers[label][fn];

}

}

for ( ret in timers[label] ) break;

if ( !ret ) {

ret = null;

delete timers[label];

}

}

for ( ret in timers ) break;

if ( !ret ) 

jQuery.removeData(element, this.dataKey);

}

}

}

});

jQuery(window).bind("unload", function() {

jQuery.each(jQuery.timer.global, function(index, item) {

jQuery.timer.remove(item);

});

});
