/** * @ignore * function utilities of lang * @author yiminghe@gmail.com * */ (function (S, undefined) { // ios Function.prototype.bind === undefined function bindFn(r, fn, obj) { var slice = [].slice, args = slice.call(arguments, 3), fNOP = function () { }, bound = function () { var inArgs = slice.call(arguments); return fn.apply( this instanceof fNOP ? this : obj, (r ? inArgs.concat(args) : args.concat(inArgs)) ); }; fNOP.prototype = fn.prototype; bound.prototype = new fNOP(); return bound; } S.mix(S, { /** * empty function * @member KISSY */ 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 KISSY * @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 KISSY * @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 KISSY */ later: function (fn, when, periodic, context, data) { when = when || 0; var m = fn, d = S.makeArray(data), f, r; if (typeof fn == 'string') { m = context[fn]; } if (!m) { S.error('method undefined'); } 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 KISSY */ throttle: function (fn, ms, context) { ms = ms || 150; if (ms === -1) { return (function () { fn.apply(context || this, arguments); }); } var last = S.now(); return (function () { var now = S.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 KISSY */ 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 = S.later(fn, ms, 0, context || this, arguments); } f.stop = function () { if (bufferTimer) { bufferTimer.cancel(); bufferTimer = 0; } }; return f; } }); })(KISSY);