modulex-util
Version:
common utilities from modulex
176 lines (158 loc) • 5.44 kB
JavaScript
/**
* @ignore
* function utilities of lang
* @author yiminghe@gmail.com
*/
var util = require('./base');
// ios Function.prototype.bind === undefine
function bindFn(r, fn, obj) {
function FNOP() {
}
var slice = [].slice,
args = slice.call(arguments, 3),
bound = function () {
var inArgs = slice.call(arguments);
return fn.apply(
this instanceof FNOP ? this :
// fix: y.x=util.bind(fn);
obj || this,
(r ? inArgs.concat(args) : args.concat(inArgs))
);
};
FNOP.prototype = fn.prototype;
bound.prototype = new FNOP();
return bound;
}
util.mix(util, {
/**
* empty function
* @member util
*/
noop: function () {
},
/**
* Creates a new function that, when called, itself calls this function in the context of the provided this value,
* with a given sequence of arguments preceding any provided when the new function was called.
* refer: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
* @param {Function} fn internal called function
* @param {Object} obj context in which fn runs
* @param {*...} var_args extra arguments
* @member util
* @return {Function} new function with context and arguments
*/
bind: bindFn(0, bindFn, null, 0),
/**
* Creates a new function that, when called, itself calls this function in the context of the provided this value,
* with a given sequence of arguments preceding any provided when the new function was called.
* refer: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
* @param {Function} fn internal called function
* @param {Object} obj context in which fn runs
* @param {*...} var_args extra arguments
* @member util
* @return {Function} new function with context and arguments
*/
rbind: bindFn(0, bindFn, null, 1),
/**
* Executes the supplied function in the context of the supplied
* object 'when' milliseconds later. Executes the function a
* single time unless periodic is set to true.
*
* @param fn {Function|String} the function to execute or the name of the method in
* the 'o' object to execute.
*
* @param [when=0] {Number} the number of milliseconds to wait until the fn is executed.
*
* @param {Boolean} [periodic] if true, executes continuously at supplied interval
* until canceled.
*
* @param {Object} [context] the context object.
*
* @param [data] that is provided to the function. This accepts either a single
* item or an array. If an array is provided, the function is executed with
* one parameter for each array item. If you need to pass a single array
* parameter, it needs to be wrapped in an array.
*
* @return {Object} a timer object. Call the cancel() method on this object to stop
* the timer.
*
* @member util
*/
later: function (fn, when, periodic, context, data) {
when = when || 0;
var m = fn,
d = util.makeArray(data),
f,
r;
if (typeof fn === 'string') {
m = context[fn];
}
f = function () {
m.apply(context, d);
};
r = (periodic) ? setInterval(f, when) : setTimeout(f, when);
return {
id: r,
interval: periodic,
cancel: function () {
if (this.interval) {
clearInterval(r);
} else {
clearTimeout(r);
}
}
};
},
/**
* Throttles a call to a method based on the time between calls.
* @param {Function} fn The function call to throttle.
* @param {Object} [context] context fn to run
* @param {Number} [ms] The number of milliseconds to throttle the method call.
* Passing a -1 will disable the throttle. Defaults to 150.
* @return {Function} Returns a wrapped function that calls fn throttled.
* @member util
*/
throttle: function (fn, ms, context) {
ms = ms || 150;
if (ms === -1) {
return function () {
fn.apply(context || this, arguments);
};
}
var last = util.now();
return function () {
var now = util.now();
if (now - last > ms) {
last = now;
fn.apply(context || this, arguments);
}
};
},
/**
* buffers a call between a fixed time
* @param {Function} fn
* @param {Number} ms
* @param {Object} [context]
* @return {Function} Returns a wrapped function that calls fn buffered.
* @member util
*/
buffer: function (fn, ms, context) {
ms = ms || 150;
if (ms === -1) {
return function () {
fn.apply(context || this, arguments);
};
}
var bufferTimer = null;
function f() {
f.stop();
bufferTimer = util.later(fn, ms, 0, context || this, arguments);
}
f.stop = function () {
if (bufferTimer) {
bufferTimer.cancel();
bufferTimer = 0;
}
};
return f;
}
});