- 
            
      
        
      
    Star
      
          
          (207)
      
  
You must be signed in to star a gist 
- 
              
      
        
      
    Fork
      
          
          (37)
      
  
You must be signed in to fork a gist 
- 
      
- 
        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...