﻿/**
 * 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/08/13
 *
 * @author Blair Mitchelmore
 * @version 1.1.3
 *
 **/

jQuery.fn.extend({
everyTime:function(interval,label,fn,times,belay){
return this.each(function(){
jQuery.timer.add(this,interval,label,fn,times,belay);
});
},
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:{
'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,belay){
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(times&&times.constructor!=Number){
belay=!!times;
times=0;
}
times=times||0;
belay=belay||false;
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(belay&&this.inProgress)
return;
this.inProgress=true;
if((++counter>times&&times!==0)||fn.call(element,counter)===false)
jQuery.timer.remove(element,label,fn);
this.inProgress=false;
};
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);
});
});
