jsface.pointcut.js
function wrap(fn, before, after, advisor) {
    var ignoredKeys = { prototype: 1 };

    function wrapper() {
      var _before = wrapper[BEFORE],
          bLen    = _before.length,
          _after  = wrapper[AFTER],
          aLen    = _after.length,
          _fn     = wrapper[ORIGIN],
          ret, r;

      // Invoke before, if it returns { $skip: true } then skip fn() and after() and returns $data
      while (bLen--) {
        r = _before[bLen].apply(this, arguments);
        if (mapOrNil(r) && r.$skip === true) {
          return r.$data;
        }
      }

      // Invoke fn, save return value
      ret = _fn.apply(this, arguments);

      while (aLen--) {
        r = _after[aLen].apply(this, arguments);
        if (mapOrNil(r) && r.$skip === true) {
          return ret;
        }
      }
      return ret;
    }

    // wrapper exists? reuse it
    if (fn[WRAPPER] === fn) {
      fn[BEFORE].push(before);
      fn[AFTER].push(after);
      fn[ADVISOR].push(advisor);
      return fn;
    }

    // create a reusable wrapper structure
    extend(wrapper, fn, 0, true);
    if (classOrNil(fn)) {
      wrapper.prototype = fn.prototype;

      // this destroys the origin of wrapper[ORIGIN], in theory, prototype.constructor should point
      // to the class constructor itself, but it's no harm to not let that happen
      // wrapper.prototype.constructor = wrapper;
    }

    wrapper[BEFORE]  = [ before ];
    wrapper[AFTER]   = [ after ];
    wrapper[ORIGIN]  = fn;
    wrapper[ADVISOR] = [ advisor ];
    wrapper[WRAPPER] = wrapper;
    wrapper.$super   = fn.$super;
    wrapper.$superp  = fn.$superp;
    return wrapper;
  }
function wrap(fn, before, after, advisor) {
    var ignoredKeys = { prototype: 1 };

    function wrapper() {
      var _before = wrapper[BEFORE],
          bLen    = _before.length,
          _after  = wrapper[AFTER],
          aLen    = _after.length,
          _fn     = wrapper[ORIGIN],
          ret, r;

      // Invoke before, if it returns { $skip: true } then skip fn() and after() and returns $data
      while (bLen--) {
        r = _before[bLen].apply(this, arguments);
        if (mapOrNil(r) && r.$skip === true) {
          return r.$data;
        }
      }

      // Invoke fn, save return value
      ret = _fn.apply(this, arguments);

      while (aLen--) {
        r = _after[aLen].apply(this, arguments);
        if (mapOrNil(r) && r.$skip === true) {
          return ret;
        }
      }
      return ret;
    }

    // wrapper exists? reuse it
    if (fn[WRAPPER] === fn) {
      fn[BEFORE].push(before);
      fn[AFTER].push(after);
      fn[ADVISOR].push(advisor);
      return fn;
    }

    // create a reusable wrapper structure
    extend(wrapper, fn, 0, true);
    if (classOrNil(fn)) {
      wrapper.prototype = fn.prototype;

      // this destroys the origin of wrapper[ORIGIN], in theory, prototype.constructor should point
      // to the class constructor itself, but it's no harm to not let that happen
      // wrapper.prototype.constructor = wrapper;
    }

    wrapper[BEFORE]  = [ before ];
    wrapper[AFTER]   = [ after ];
    wrapper[ORIGIN]  = fn;
    wrapper[ADVISOR] = [ advisor ];
    wrapper[WRAPPER] = wrapper;
    wrapper.$super   = fn.$super;
    wrapper.$superp  = fn.$superp;
    return wrapper;
  }
function wrap ( fn , before , after , advisor ) { var ignoredKeys = { prototype : 1 } ; function wrapper ( ) { var _before = wrapper [ BEFORE ] , bLen = _before . length , _after = wrapper [ AFTER ] , aLen = _after . length , _fn = wrapper [ ORIGIN ] , ret , r ; // Invoke before, if it returns { $skip: true } then skip fn() and after() and returns $data while ( bLen -- ) { r = _before [ bLen ] . apply ( this , arguments ) ; if ( mapOrNil ( r ) && r . $skip === true ) { return r . $data ; } } // Invoke fn, save return value ret = _fn . apply ( this , arguments ) ; while ( aLen -- ) { r = _after [ aLen ] . apply ( this , arguments ) ; if ( mapOrNil ( r ) && r . $skip === true ) { return ret ; } } return ret ; } // wrapper exists? reuse it if ( fn [ WRAPPER ] === fn ) { fn [ BEFORE ] . push ( before ) ; fn [ AFTER ] . push ( after ) ; fn [ ADVISOR ] . push ( advisor ) ; return fn ; } // create a reusable wrapper structure extend ( wrapper , fn , 0 , true ) ; if ( classOrNil ( fn ) ) { wrapper . prototype = fn . prototype ; // this destroys the origin of wrapper[ORIGIN], in theory, prototype.constructor should point // to the class constructor itself, but it's no harm to not let that happen // wrapper.prototype.constructor = wrapper; } wrapper [ BEFORE ] = [ before ] ; wrapper [ AFTER ] = [ after ] ; wrapper [ ORIGIN ] = fn ; wrapper [ ADVISOR ] = [ advisor ] ; wrapper [ WRAPPER ] = wrapper ; wrapper . $super = fn . $super ; wrapper . $superp = fn . $superp ; return wrapper ; }
Wrap a function with before & after.
Wrap a function with before & after .