Last active
October 8, 2015 06:39
-
-
Save brendanmoore/3293598 to your computer and use it in GitHub Desktop.
first draft namespaced event emitter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This is NOT DOM events (click, mouseover, touchend, etc...) | |
* This is custom events, which can be bound to anything. | |
*/ | |
var ee = function(){}; | |
//bind function to event | |
ee.prototype.on = function(key, fn){ | |
//if not function, bail | |
if(typeof fn !== 'function'){ return false; } | |
this._e[key] = this._e[key] || []; | |
this._e[key].push(fn); | |
return true; | |
}; | |
//like on but only once. | |
ee.prototype.once = function(key, fn){ | |
if(typeof fn !== 'function'){ return false; } | |
var k = key, g = fn, self = this, f = function(){ | |
g.apply(this, Array.prototype.slice.call(arguments)); | |
self.off(k, f); | |
}; | |
return self.on(key, f); | |
}; | |
//unbind function(s) from event/namespace | |
ee.prototype.off = function(key, fn){ | |
var ns, ev, t, filter, regex; | |
if(!!~e.indexOf(":")){ | |
//namespaced, only unbind in namespace | |
t = e.split(":"); | |
ev = t.shift(); | |
ns = t.join(":"); | |
}else{ | |
ev = e; | |
ns = ""; | |
} | |
var self = this; | |
function splice(k,f){ | |
if(void(0) == f){ | |
return self._e[k].length = 0; //truncate! | |
} | |
//splice | |
if(!!~self._e[k].indexOf(f)){ | |
self._e[k].splice(self._e[k].indexOf(f), 1); | |
} | |
} | |
if(ev !== "" && ns !== ""){ | |
//full event.namespace | |
this._e[key] || return; //no namespace/event combo. | |
return splice(key, fn); | |
} | |
if(ev === ""){ | |
//any event with correct ns | |
regex = new RegExp("/"+key.replace(":","\\.")+"$/"); | |
} | |
if(ns === ""){ | |
//any event with the namespace | |
regex = new RegExp("/^"+key.replace(":","\\.")+"/"); | |
} | |
//should find a mixin for this | |
Object.keys(this._e).forEach(function(v,i){ | |
if(regex.test(v)){ | |
splice(v, fn); | |
} | |
}); | |
}; | |
//emit an event with extra data | |
ee.prototype.emit = function(e /*, args... */){ | |
var args = Array.prototype.slice.call(arguments), regex, self = this; | |
e = args.shift(); | |
//the regex that matches the events, is must start with `e`, so all namespaces will match | |
regex = new RegExp("/^"+e.replace(":","\\.")+"/"); | |
Object.keys(this._e).forEach(function(v,i){ | |
if(regex.test(v)){ | |
//call all functions. | |
self._e[v].forEach(function(vv,ii){ | |
vv.apply(this, args); | |
}); | |
} | |
}); | |
} | |
//now to add a function to make an emitter from an object. | |
function mixin(object){ | |
object || object = {}; //so it can be called without args | |
object.on = object.bind = ee.prototype.on; | |
object.off = object.unbind = ee.prototype.off; | |
object.once = ee.prototype.once; | |
object.emit = object.trigger = ee.prototype.emit; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Changed . to :