
/**
 * Module Dependencies
 */

var events = require('event');

/**
 * Exports
 */

exports.on = function(name, module, cb) {

  // cb can be passed as
  // the second or third argument
  if (typeof module !== 'string') {
    cb = module;
    module = undefined;
  }

  // if a module is provided
  // pass in a special callback
  // function that checks the
  // module
  if (module) {
    events.prototype.on.call(this, name, function() {
      if (this.event.target.module() === module) {
        cb.apply(this, arguments);
      }
    });
  } else {
    events.prototype.on.call(this, name, cb);
  }

  return this;
};


exports.fire = function(name) {
  var parent = this.parent;

  this.event = this.event || {
    target: this,
    propagate: true,
    stopPropagation: function(){ this.propagate = false; }
  };

  // Trigger event
  events.prototype.fire.apply(this, arguments);

  // Trigger the same event on the parent view
  if (this.event.propagate && parent) {
    parent.event = this.event;
    this.fire.apply(parent, arguments);
  }

  // Remove the event reference
  delete this.event;

  // Allow chaining
  return this;
};

exports.fireStatic = events.prototype.fire;
exports.off = events.prototype.off;

/**
 * Module Dependencies
 */

var events = require('event');

/**
 * Exports
 */

exports.on = function(name, module, cb) {

  // cb can be passed as
  // the second or third argument
  if (typeof module !== 'string') {
    cb = module;
    module = undefined;
  }

  // if a module is provided
  // pass in a special callback
  // function that checks the
  // module
  if (module) {
    events.prototype.on.call(this, name, function() {
      if (this.event.target.module() === module) {
        cb.apply(this, arguments);
      }
    });
  } else {
    events.prototype.on.call(this, name, cb);
  }

  return this;
};


exports.fire = function(name) {
  var parent = this.parent;
  var _event = this.event;
  var event = {
    target: this,
    propagate: true,
    stopPropagation: function(){ this.propagate = false; }
  };

  fireBubble(this, arguments, event);

  // COMPLEX:
  // If an earlier event object was
  // cached, restore the the event
  // back onto the view. If there
  // wasn't an earlier event, make
  // sure the `event` key has been
  // deleted off the view.
  if (_event) this.event = _event;
  else delete this.event;

  // Allow chaining
  return this;
};

function fireBubble(view, args, event) {
  if (!view || !event.propagate) return;

  view.event = event;
  events.prototype.fire.apply(view, args);

  fireBubble(view.parent, args, event);
}



exports.fireStatic = events.prototype.fire;
exports.off = events.prototype.off;
Rework the way the event object is attached and removed from the view object
Rework the way the event object is attached and removed from the view object
