(function(window, setTimeout_, clearTimeout_, setInterval_, clearInterval_, expose) {
/**
* Timeout
*
* @param fn A function to run, or string to be eval()d
* @param delay The delay (in ms) for the Timeout
* @access Depends on expose
*/
var Timeout = function(fn, delay) {
Timeout.queue.push(this);
this.id = Timeout.queue.indexOf(this);
this.fn = fn;
this.delay = delay;
this.start();
return this;
};
Timeout.queue = [];
Timeout.prototype.active = false;
Timeout.prototype.cancelled = 0;
Timeout.prototype.complete = 0;
Timeout.prototype.delay = 0;
Timeout.prototype.fn = function() {};
Timeout.prototype.id = null;
Timeout.prototype.timeout = null;
Timeout.prototype.start =
Timeout.prototype.restart = function() {
if (!this.active) {
this.active = true;
// create a closure for the current timeout object
this.timeout = setTimeout_((function(timeout) {
return function() {
// only run if we're active
if (timeout.active) {
timeout.run();
timeout.timeout = null;
}
else {
// clean up
timeout.stop();
}
timeout.active = false;
// clear space
Timeout.queue[timeout.id] = null;
}
})(this), this.delay);
}
return this;
};
Timeout.prototype.cancel =
Timeout.prototype.clear =
Timeout.prototype.stop = function(execute) {
clearTimeout_(this.timeout);
this.timeout = null;
if (execute) {
this.run();
}
this.cancelled++;
this.active = false;
// free up the space in the array, but don't remove it!
Timeout.queue[this.id] = null;
return this;
};
Timeout.prototype.run = function() {
if (typeof this.fn == 'function') {
this.fn(this);
}
else if (typeof this.fn == 'string') {
eval(this.fn);
}
this.complete++;
return this;
};
/**
* Interval
*
* @param fn A function to run, or string to be eval()d
* @param delay The delay (in ms) for the Interval
* @access Depends on expose
*/
var Interval = function(fn, delay) {
Interval.queue.push(this);
this.id = Interval.queue.indexOf(this);
this.fn = fn;
this.delay = delay;
this.start();
return this;
};
Interval.queue = [];
Interval.prototype.active = false;
Interval.prototype.cancelled = 0;
Interval.prototype.complete = 0;
Interval.prototype.delay = 0;
Interval.prototype.fn = function() {};
Interval.prototype.id = null;
Interval.prototype.interval = null;
Interval.prototype.start =
Interval.prototype.restart = function() {
if (!this.active) {
this.active = true;
this.interval = setInterval_((function(interval) {
return function() {
if (interval.active) {
interval.run();
}
else {
interval.stop();
}
}
})(this), this.delay);
}
return this;
};
Interval.prototype.cancel =
Interval.prototype.clear =
Interval.prototype.stop = function(execute) {
clearInterval_(this.interval);
this.interval = null;
if (execute) {
this.run();
}
this.cancelled++;
this.active = false;
Interval.queue[this.id] = null;
return this;
};
Interval.prototype.run = function() {
if (typeof this.fn == 'function') {
this.fn(this);
}
else if (typeof this.fn == 'string') {
eval(this.fn);
}
this.complete++;
return this;
}
/**
* Replacements for the standard timeout/interval functions
*/
window.setTimeout = function(fn, delay) {
return new Timeout(fn, delay);
};
window.clearTimeout = function(id, execute) {
if ((id in Timeout.queue) && Timeout.queue[id].active) {
Timeout.queue[id].stop(!!execute);
return true;
}
return false;
};
window.setInterval = function(fn, delay) {
return new Interval(fn, delay);
};
window.clearInterval = function(id, execute) {
if ((id in Interval.queue) && Interval.queue[id].active) {
Interval.queue[id].stop(!!execute);
return true;
}
return false;
};
if (expose) {
window.Timeout = Timeout;
window.Interval = Interval;
}
return;
})(window, window.setTimeout, window.clearTimeout, window.setInterval, window.clearInterval, false);
|