-
-
Save mudge/5830382 to your computer and use it in GitHub Desktop.
/* Polyfill indexOf. */ | |
var indexOf; | |
if (typeof Array.prototype.indexOf === 'function') { | |
indexOf = function (haystack, needle) { | |
return haystack.indexOf(needle); | |
}; | |
} else { | |
indexOf = function (haystack, needle) { | |
var i = 0, length = haystack.length, idx = -1, found = false; | |
while (i < length && !found) { | |
if (haystack[i] === needle) { | |
idx = i; | |
found = true; | |
} | |
i++; | |
} | |
return idx; | |
}; | |
}; | |
/* Polyfill EventEmitter. */ | |
var EventEmitter = function () { | |
this.events = {}; | |
}; | |
EventEmitter.prototype.on = function (event, listener) { | |
if (typeof this.events[event] !== 'object') { | |
this.events[event] = []; | |
} | |
this.events[event].push(listener); | |
}; | |
EventEmitter.prototype.removeListener = function (event, listener) { | |
var idx; | |
if (typeof this.events[event] === 'object') { | |
idx = indexOf(this.events[event], listener); | |
if (idx > -1) { | |
this.events[event].splice(idx, 1); | |
} | |
} | |
}; | |
EventEmitter.prototype.emit = function (event) { | |
var i, listeners, length, args = [].slice.call(arguments, 1); | |
if (typeof this.events[event] === 'object') { | |
listeners = this.events[event].slice(); | |
length = listeners.length; | |
for (i = 0; i < length; i++) { | |
listeners[i].apply(this, args); | |
} | |
} | |
}; | |
EventEmitter.prototype.once = function (event, listener) { | |
this.on(event, function g () { | |
this.removeListener(event, g); | |
listener.apply(this, arguments); | |
}); | |
}; |
You can add simple overrides by returning true or false to stop propagation, e.g. return true to stop all other events before it.
// hooks.js
// inspired by gmod lua !
// it is useful to prevent circular dependencies and or import hell
export class hooks {
static register(name, f) {
if (!hooks[name])
hooks[name] = [];
hooks[name].push(f);
return f;
}
static unregister(name, f) {
hooks[name] = hooks[name].filter(e => e != f);
}
static call(name, x) {
if (!hooks[name])
return;
for (let i = hooks[name].length; i--;)
if (hooks[name][i](x))
return;
}
}
export default hooks;
Hello, this is actually amazing. What license do you release this under?
This was extracted from my Promise library Pacta and, as such, is released under the BSD 3-clause license.
@undecidedapollo and @coldsilk:
There seems to be a problem with the once/removeListener function. When the event is emitted and the listener is called, it calls remove. The remove function splices the array stored at this.event[eventString] while the emit function is doing a forEach on the same array. This splice modifies the array while it is being iterated against, and causes the forEach to skip the next listener.
It has been a while since I wrote this but I believe this is why emit
takes a shallow copy of the list of listeners on line 55 using slice
so that the loop is unaffected by removeListener
modifying the underlying events.
In a nutshell...