Comparing version 2.1.2 to 3.0.0
470
emmett.js
@@ -13,4 +13,40 @@ (function() { | ||
/** | ||
* Incremental id used to order event handlers. | ||
*/ | ||
var __order = 0; | ||
/** | ||
* A simple helper to shallowly merge two objects. The second one will "win" | ||
* over the first one. | ||
* | ||
* @param {object} o1 First target object. | ||
* @param {object} o2 Second target object. | ||
* @return {object} Returns the merged object. | ||
*/ | ||
function shallowMerge(o1, o2) { | ||
var o = {}, | ||
k; | ||
for (k in o1) o[k] = o1[k]; | ||
for (k in o2) o[k] = o2[k]; | ||
return o; | ||
} | ||
/** | ||
* Is the given variable a plain JavaScript object? | ||
* | ||
* @param {mixed} v Target. | ||
* @return {boolean} The boolean result. | ||
*/ | ||
function isPlainObject(v) { | ||
return v && | ||
typeof v === 'object' && | ||
!Array.isArray(v) && | ||
!(v instanceof Function) && | ||
!(v instanceof RegExp); | ||
} | ||
/** | ||
* The emitter's constructor. It initializes the handlers-per-events store and | ||
@@ -26,5 +62,26 @@ * the global handlers store. | ||
this._enabled = true; | ||
this._children = []; | ||
// Dirty trick that will set the necessary properties to the emitter | ||
this.unbindAll(); | ||
}; | ||
/** | ||
* This method unbinds every handlers attached to every or any events. So, | ||
* these functions will no more be executed when the related events are | ||
* emitted. If the functions were not bound to the events, nothing will | ||
* happen, and no error will be thrown. | ||
* | ||
* Usage: | ||
* ****** | ||
* > myEmitter.unbindAll(); | ||
* | ||
* @return {Emitter} Returns this. | ||
*/ | ||
Emitter.prototype.unbindAll = function() { | ||
this._handlers = {}; | ||
this._handlersAll = []; | ||
this._handlersComplex = []; | ||
return this; | ||
}; | ||
@@ -109,61 +166,57 @@ | ||
eArray, | ||
handlersList, | ||
bindingObject; | ||
// Variant 1 and 2: | ||
if (typeof b === 'function') { | ||
eArray = typeof a === 'string' ? | ||
[a] : | ||
a; | ||
// Variant 3 | ||
if (isPlainObject(a)) { | ||
for (event in a) | ||
this.on(event, a[event], b); | ||
return this; | ||
} | ||
for (i = 0, l = eArray.length; i !== l; i += 1) { | ||
event = eArray[i]; | ||
// Variant 1, 2 and 4 | ||
if (typeof a === 'function') { | ||
c = b; | ||
b = a; | ||
a = null; | ||
} | ||
// Check that event is not '': | ||
if (!event) | ||
continue; | ||
eArray = [].concat(a); | ||
for (i = 0, l = eArray.length; i < l; i++) { | ||
event = eArray[i]; | ||
bindingObject = { | ||
order: __order++, | ||
fn: b | ||
}; | ||
// Defining the list in which the handler should be inserted | ||
if (typeof event === 'string') { | ||
if (!this._handlers[event]) | ||
this._handlers[event] = []; | ||
bindingObject = { | ||
handler: b | ||
}; | ||
for (k in c || {}) | ||
if (__allowedOptions[k]) | ||
bindingObject[k] = c[k]; | ||
else | ||
throw new Error( | ||
'The option "' + k + '" is not recognized by Emmett.' | ||
); | ||
this._handlers[event].push(bindingObject); | ||
handlersList = this._handlers[event]; | ||
} | ||
else if (event instanceof RegExp) { | ||
handlersList = this._handlersComplex; | ||
bindingObject.pattern = event; | ||
} | ||
else if (event === null) { | ||
handlersList = this._handlersAll; | ||
} | ||
else { | ||
throw Error('Emitter.on: invalid event.'); | ||
} | ||
// Variant 3: | ||
} else if (a && typeof a === 'object' && !Array.isArray(a)) | ||
for (event in a) | ||
Emitter.prototype.on.call(this, event, a[event], b); | ||
// Variant 4: | ||
else if (typeof a === 'function') { | ||
bindingObject = { | ||
handler: a | ||
}; | ||
// Appending needed properties | ||
for (k in c || {}) | ||
if (__allowedOptions[k]) | ||
bindingObject[k] = c[k]; | ||
else | ||
throw new Error( | ||
'The option "' + k + '" is not recognized by Emmett.' | ||
); | ||
this._handlersAll.push(bindingObject); | ||
if (bindingObject.once) | ||
bindingObject.parent = handlersList; | ||
handlersList.push(bindingObject); | ||
} | ||
// No matching variant: | ||
else | ||
throw new Error('Wrong arguments.'); | ||
return this; | ||
@@ -179,25 +232,12 @@ }; | ||
*/ | ||
Emitter.prototype.once = function(a, b, c) { | ||
// Variant 1 and 2: | ||
if (typeof b === 'function') { | ||
c = c || {}; | ||
c.once = true; | ||
this.on(a, b, c); | ||
Emitter.prototype.once = function() { | ||
var args = Array.prototype.slice.call(arguments), | ||
li = args.length - 1; | ||
// Variants 3 and 4: | ||
} else if ( | ||
// Variant 3: | ||
(a && typeof a === 'object' && !Array.isArray(a)) || | ||
// Variant 4: | ||
(typeof a === 'function') | ||
) { | ||
b = b || {}; | ||
b.once = true; | ||
this.on(a, b); | ||
if (isPlainObject(args[li]) && args.length > 1) | ||
args[li] = shallowMerge(args[li], {once: true}); | ||
else | ||
args.push({once: true}); | ||
// No matching variant: | ||
} else | ||
throw new Error('Wrong arguments.'); | ||
return this; | ||
return this.on.apply(this, args); | ||
}; | ||
@@ -244,4 +284,25 @@ | ||
* @return {Emitter} Returns this. | ||
* | ||
* Variant 5: | ||
* ********** | ||
* > myEmitter.off(event); | ||
* | ||
* @param {string} event The event we should unbind. | ||
* @return {Emitter} Returns this. | ||
*/ | ||
Emitter.prototype.off = function(events, handler) { | ||
function filter(target, fn) { | ||
target = target || []; | ||
var a = [], | ||
l, | ||
i; | ||
for (i = 0, l = target.length; i < l; i++) | ||
if (target[i].fn !== fn) | ||
a.push(target[i]); | ||
return a; | ||
} | ||
Emitter.prototype.off = function(events, fn) { | ||
var i, | ||
@@ -253,39 +314,38 @@ n, | ||
a, | ||
event, | ||
eArray = typeof events === 'string' ? | ||
[events] : | ||
events; | ||
event; | ||
if (arguments.length === 1 && typeof eArray === 'function') { | ||
handler = arguments[0]; | ||
// Variant 4: | ||
if (arguments.length === 1 && typeof events === 'function') { | ||
fn = arguments[0]; | ||
// Handlers bound to events: | ||
for (k in this._handlers) { | ||
a = []; | ||
for (i = 0, n = this._handlers[k].length; i !== n; i += 1) | ||
if (this._handlers[k][i].handler !== handler) | ||
a.push(this._handlers[k][i]); | ||
this._handlers[k] = a; | ||
this._handlers[k] = filter(this._handlers[k], fn); | ||
if (this._handlers[k].length === 0) | ||
delete this._handlers[k]; | ||
} | ||
a = []; | ||
for (i = 0, n = this._handlersAll.length; i !== n; i += 1) | ||
if (this._handlersAll[i].handler !== handler) | ||
a.push(this._handlersAll[i]); | ||
this._handlersAll = a; | ||
// Generic Handlers | ||
this._handlersAll = filter(this._handlersAll, fn); | ||
// Complex handlers | ||
this._handlersComplex = filter(this._handlersComplex, fn); | ||
} | ||
// Variant 5 | ||
else if (arguments.length === 1 && typeof events === 'string') { | ||
delete this._handlers[events]; | ||
} | ||
// Variant 1 and 2: | ||
else if (arguments.length === 2) { | ||
for (i = 0, n = eArray.length; i !== n; i += 1) { | ||
var eArray = [].concat(events); | ||
for (i = 0, n = eArray.length; i < n; i++) { | ||
event = eArray[i]; | ||
if (this._handlers[event]) { | ||
a = []; | ||
for (j = 0, m = this._handlers[event].length; j !== m; j += 1) | ||
if (this._handlers[event][j].handler !== handler) | ||
a.push(this._handlers[event][j]); | ||
this._handlers[event] = a; | ||
} | ||
this._handlers[event] = filter(this._handlers[event], fn); | ||
if (this._handlers[event] && this._handlers[event].length === 0) | ||
if ((this._handlers[event] || []).length === 0) | ||
delete this._handlers[event]; | ||
@@ -295,29 +355,47 @@ } | ||
// Variant 3 | ||
else if (isPlainObject(events)) { | ||
for (k in events) | ||
this.off(k, events[k]); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* This method unbinds every handlers attached to every or any events. So, | ||
* these functions will no more be executed when the related events are | ||
* emitted. If the functions were not bound to the events, nothing will | ||
* happen, and no error will be thrown. | ||
* This method retrieve the listeners attached to a particular event. | ||
* | ||
* Usage: | ||
* ****** | ||
* > myEmitter.unbindAll(); | ||
* | ||
* @return {Emitter} Returns this. | ||
* @param {?string} Name of the event. | ||
* @return {array} Array of handler functions. | ||
*/ | ||
Emitter.prototype.unbindAll = function() { | ||
var k; | ||
Emitter.prototype.listeners = function(event) { | ||
var handlers = this._handlersAll || [], | ||
complex = false, | ||
h, | ||
i, | ||
l; | ||
this._handlersAll = []; | ||
for (k in this._handlers) | ||
delete this._handlers[k]; | ||
if (!event) | ||
throw Error('Emitter.listeners: no event provided.'); | ||
return this; | ||
handlers = handlers.concat(this._handlers[event] || []); | ||
for (i = 0, l = this._handlersComplex.length; i < l; i++) { | ||
h = this._handlersComplex[i]; | ||
if (~event.search(h.pattern)) { | ||
complex = true; | ||
handlers.push(h); | ||
} | ||
} | ||
// If we have any complex handlers, we need to sort | ||
if (this._handlersAll.length || complex) | ||
return handlers.sort(function(a, b) { | ||
return a.order - b.order; | ||
}); | ||
else | ||
return handlers.slice(0); | ||
}; | ||
/** | ||
@@ -333,2 +411,3 @@ * This method emits the specified event(s), and executes every handlers bound | ||
* > myEmitter.emit(['myEvent1', 'myEvent2'], myData); | ||
* > myEmitter.emit({myEvent1: myData1, myEvent2: myData2}); | ||
* | ||
@@ -340,70 +419,48 @@ * @param {string|array} events The event(s) to emit. | ||
Emitter.prototype.emit = function(events, data) { | ||
var i, | ||
n, | ||
j, | ||
m, | ||
z, | ||
a, | ||
event, | ||
child, | ||
handlers, | ||
eventName, | ||
self = this, | ||
eArray = typeof events === 'string' ? | ||
[events] : | ||
events; | ||
// Check that the emitter is enabled: | ||
// Short exit if the emitter is disabled | ||
if (!this._enabled) | ||
return this; | ||
data = data === undefined ? {} : data; | ||
// Object variant | ||
if (isPlainObject(events)) { | ||
for (i = 0, n = eArray.length; i !== n; i += 1) { | ||
eventName = eArray[i]; | ||
handlers = (this._handlers[eventName] || []).concat(this._handlersAll); | ||
for (var k in events) | ||
this.emit(k, events[k]); | ||
if (handlers.length) { | ||
return this; | ||
} | ||
var eArray = [].concat(events), | ||
onces = [], | ||
event, | ||
handlers, | ||
handler, | ||
i, | ||
j, | ||
l, | ||
m; | ||
for (i = 0, l = eArray.length; i < l; i++) { | ||
handlers = this.listeners(eArray[i]); | ||
for (j = 0, m = handlers.length; j < m; j++) { | ||
handler = handlers[j]; | ||
event = { | ||
type: eventName, | ||
data: data || {}, | ||
type: eArray[i], | ||
target: this | ||
}; | ||
a = []; | ||
for (j = 0, m = handlers.length; j !== m; j += 1) { | ||
if (arguments.length > 1) | ||
event.data = data; | ||
// We have to verify that the handler still exists in the array, | ||
// as it might have been mutated already | ||
if ( | ||
( | ||
this._handlers[eventName] && | ||
this._handlers[eventName].indexOf(handlers[j]) >= 0 | ||
) || | ||
this._handlersAll.indexOf(handlers[j]) >= 0 | ||
) { | ||
handlers[j].handler.call( | ||
'scope' in handlers[j] ? handlers[j].scope : this, | ||
event | ||
); | ||
handler.fn.call('scope' in handler ? handler.scope : this, event); | ||
// Since the listener callback can mutate the _handlers, | ||
// we register the handlers we want to remove, not the ones | ||
// we want to keep | ||
if (handlers[j].once) | ||
a.push(handlers[j]); | ||
} | ||
} | ||
// Go through handlers to remove | ||
for (z = 0; z < a.length; z++) { | ||
this._handlers[eventName].splice(a.indexOf(a[z]), 1); | ||
} | ||
if (handler.once) | ||
onces.push(handler); | ||
} | ||
} | ||
// Events propagation: | ||
for (i = 0, n = this._children.length; i !== n; i += 1) { | ||
child = this._children[i]; | ||
child.emit.apply(child, arguments); | ||
// Cleaning onces | ||
for (j = onces.length - 1; j >= 0; j--) | ||
onces[j].parent.splice(onces[j].parent.indexOf(onces[j]), 1); | ||
} | ||
@@ -416,80 +473,6 @@ | ||
/** | ||
* This method creates a new instance of Emitter and binds it as a child. Here | ||
* is what children do: | ||
* - When the parent emits an event, the children will emit the same later | ||
* - When a child is killed, it is automatically unreferenced from the parent | ||
* - When the parent is killed, all children will be killed as well | ||
* | ||
* @return {Emitter} Returns the fresh new child. | ||
* This method will unbind all listeners and make it impossible to ever | ||
* rebind any listener to any event. | ||
*/ | ||
Emitter.prototype.child = function() { | ||
var self = this, | ||
child = new Emitter(); | ||
child.on('emmett:kill', function() { | ||
if (self._children) | ||
for (var i = 0, l = self._children.length; i < l; i++) | ||
if (self._children[i] === child) { | ||
self._children.splice(i, 1); | ||
break; | ||
} | ||
}); | ||
this._children.push(child); | ||
return child; | ||
}; | ||
/** | ||
* This returns an array of handler functions corresponding to the given | ||
* event or every handler functions if an event were not to be given. | ||
* | ||
* @param {?string} event Name of the event. | ||
* @return {Emitter} Returns this. | ||
*/ | ||
function mapHandlers(a) { | ||
var i, l, h = []; | ||
for (i = 0, l = a.length; i < l; i++) | ||
h.push(a[i].handler); | ||
return h; | ||
} | ||
Emitter.prototype.listeners = function(event) { | ||
var handlers = [], | ||
k, | ||
i, | ||
l; | ||
// If no event is passed, we return every handlers | ||
if (!event) { | ||
handlers = mapHandlers(this._handlersAll); | ||
for (k in this._handlers) | ||
handlers = handlers.concat(mapHandlers(this._handlers[k])); | ||
// Retrieving handlers per children | ||
for (i = 0, l = this._children.length; i < l; i++) | ||
handlers = handlers.concat(this._children[i].listeners()); | ||
} | ||
// Else we only retrieve the needed handlers | ||
else { | ||
handlers = mapHandlers(this._handlers[event]); | ||
// Retrieving handlers per children | ||
for (i = 0, l = this._children.length; i < l; i++) | ||
handlers = handlers.concat(this._children[i].listeners(event)); | ||
} | ||
return handlers; | ||
}; | ||
/** | ||
* This method will first dispatch a "emmett:kill" event, and then unbinds all | ||
* listeners and make it impossible to ever rebind any listener to any event. | ||
*/ | ||
Emitter.prototype.kill = function() { | ||
this.emit('emmett:kill'); | ||
@@ -499,9 +482,4 @@ this.unbindAll(); | ||
this._handlersAll = null; | ||
this._handlersComplex = null; | ||
this._enabled = false; | ||
if (this._children) | ||
for (var i = 0, l = this._children.length; i < l; i++) | ||
this._children[i].kill(); | ||
this._children = null; | ||
}; | ||
@@ -538,3 +516,3 @@ | ||
*/ | ||
Emitter.version = '2.1.2'; | ||
Emitter.version = '3.0.0'; | ||
@@ -541,0 +519,0 @@ |
/** | ||
* emmett - A custom events emitter for Node.js and the browser | ||
* @version v2.1.2 | ||
* emmett - A custom event emitter for Node.js and the browser. | ||
* @version v3.0.0 | ||
* @link https://github.com/jacomyal/emmett | ||
* @license MIT | ||
*/ | ||
(function(){"use strict";function e(e){var t,n,r=[];for(t=0,n=e.length;n>t;t++)r.push(e[t].handler);return r}var t={once:"boolean",scope:"object"},n=function(){this._enabled=!0,this._children=[],this._handlers={},this._handlersAll=[]};n.prototype.on=function(e,r,i){var h,s,l,o,d,a;if("function"==typeof r){for(d="string"==typeof e?[e]:e,h=0,s=d.length;h!==s;h+=1)if(o=d[h]){this._handlers[o]||(this._handlers[o]=[]),a={handler:r};for(l in i||{}){if(!t[l])throw new Error('The option "'+l+'" is not recognized by Emmett.');a[l]=i[l]}this._handlers[o].push(a)}}else if(e&&"object"==typeof e&&!Array.isArray(e))for(o in e)n.prototype.on.call(this,o,e[o],r);else{if("function"!=typeof e)throw new Error("Wrong arguments.");a={handler:e};for(l in i||{}){if(!t[l])throw new Error('The option "'+l+'" is not recognized by Emmett.');a[l]=i[l]}this._handlersAll.push(a)}return this},n.prototype.once=function(e,t,n){if("function"==typeof t)n=n||{},n.once=!0,this.on(e,t,n);else{if((!e||"object"!=typeof e||Array.isArray(e))&&"function"!=typeof e)throw new Error("Wrong arguments.");t=t||{},t.once=!0,this.on(e,t)}return this},n.prototype.off=function(e,t){var n,r,i,h,s,l,o,d="string"==typeof e?[e]:e;if(1===arguments.length&&"function"==typeof d){t=arguments[0];for(s in this._handlers){for(l=[],n=0,r=this._handlers[s].length;n!==r;n+=1)this._handlers[s][n].handler!==t&&l.push(this._handlers[s][n]);this._handlers[s]=l}for(l=[],n=0,r=this._handlersAll.length;n!==r;n+=1)this._handlersAll[n].handler!==t&&l.push(this._handlersAll[n]);this._handlersAll=l}else if(2===arguments.length)for(n=0,r=d.length;n!==r;n+=1){if(o=d[n],this._handlers[o]){for(l=[],i=0,h=this._handlers[o].length;i!==h;i+=1)this._handlers[o][i].handler!==t&&l.push(this._handlers[o][i]);this._handlers[o]=l}this._handlers[o]&&0===this._handlers[o].length&&delete this._handlers[o]}return this},n.prototype.unbindAll=function(){var e;this._handlersAll=[];for(e in this._handlers)delete this._handlers[e];return this},n.prototype.emit=function(e,t){var n,r,i,h,s,l,o,d,a,f,c="string"==typeof e?[e]:e;if(!this._enabled)return this;for(t=void 0===t?{}:t,n=0,r=c.length;n!==r;n+=1)if(f=c[n],a=(this._handlers[f]||[]).concat(this._handlersAll),a.length){for(o={type:f,data:t||{},target:this},l=[],i=0,h=a.length;i!==h;i+=1)(this._handlers[f]&&this._handlers[f].indexOf(a[i])>=0||this._handlersAll.indexOf(a[i])>=0)&&(a[i].handler.call("scope"in a[i]?a[i].scope:this,o),a[i].once&&l.push(a[i]));for(s=0;s<l.length;s++)this._handlers[f].splice(l.indexOf(l[s]),1)}for(n=0,r=this._children.length;n!==r;n+=1)d=this._children[n],d.emit.apply(d,arguments);return this},n.prototype.child=function(){var e=this,t=new n;return t.on("emmett:kill",function(){if(e._children)for(var n=0,r=e._children.length;r>n;n++)if(e._children[n]===t){e._children.splice(n,1);break}}),this._children.push(t),t},n.prototype.listeners=function(t){var n,r,i,h=[];if(t)for(h=e(this._handlers[t]),r=0,i=this._children.length;i>r;r++)h=h.concat(this._children[r].listeners(t));else{h=e(this._handlersAll);for(n in this._handlers)h=h.concat(e(this._handlers[n]));for(r=0,i=this._children.length;i>r;r++)h=h.concat(this._children[r].listeners())}return h},n.prototype.kill=function(){if(this.emit("emmett:kill"),this.unbindAll(),this._handlers=null,this._handlersAll=null,this._enabled=!1,this._children)for(var e=0,t=this._children.length;t>e;e++)this._children[e].kill();this._children=null},n.prototype.disable=function(){return this._enabled=!1,this},n.prototype.enable=function(){return this._enabled=!0,this},n.version="2.1.2","undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=n),exports.Emitter=n):"function"==typeof define&&define.amd?define("emmett",[],function(){return n}):this.Emitter=n}).call(this); | ||
(function(){"use strict";function e(e,t){var n,r={};for(n in e)r[n]=e[n];for(n in t)r[n]=t[n];return r}function t(e){return!(!e||"object"!=typeof e||Array.isArray(e)||e instanceof Function||e instanceof RegExp)}function n(e,t){e=e||[];var n,r,s=[];for(r=0,n=e.length;n>r;r++)e[r].fn!==t&&s.push(e[r]);return s}var r={once:"boolean",scope:"object"},s=0,i=function(){this._enabled=!0,this.unbindAll()};i.prototype.unbindAll=function(){return this._handlers={},this._handlersAll=[],this._handlersComplex=[],this},i.prototype.on=function(e,n,i){var l,o,h,a,f,d,u;if(t(e)){for(a in e)this.on(a,e[a],n);return this}for("function"==typeof e&&(i=n,n=e,e=null),f=[].concat(e),l=0,o=f.length;o>l;l++){if(a=f[l],u={order:s++,fn:n},"string"==typeof a)this._handlers[a]||(this._handlers[a]=[]),d=this._handlers[a];else if(a instanceof RegExp)d=this._handlersComplex,u.pattern=a;else{if(null!==a)throw Error("Emitter.on: invalid event.");d=this._handlersAll}for(h in i||{})r[h]&&(u[h]=i[h]);u.once&&(u.parent=d),d.push(u)}return this},i.prototype.once=function(){var n=Array.prototype.slice.call(arguments),r=n.length-1;return t(n[r])&&n.length>1?n[r]=e(n[r],{once:!0}):n.push({once:!0}),this.on.apply(this,n)},i.prototype.off=function(e,r){var s,i,l,o;if(1===arguments.length&&"function"==typeof e){r=arguments[0];for(l in this._handlers)this._handlers[l]=n(this._handlers[l],r),0===this._handlers[l].length&&delete this._handlers[l];this._handlersAll=n(this._handlersAll,r),this._handlersComplex=n(this._handlersComplex,r)}else if(1===arguments.length&&"string"==typeof e)delete this._handlers[e];else if(2===arguments.length){var h=[].concat(e);for(s=0,i=h.length;i>s;s++)o=h[s],this._handlers[o]=n(this._handlers[o],r),0===(this._handlers[o]||[]).length&&delete this._handlers[o]}else if(t(e))for(l in e)this.off(l,e[l]);return this},i.prototype.listeners=function(e){var t,n,r,s=this._handlersAll||[],i=!1;if(!e)throw Error("Emitter.listeners: no event provided.");for(s=s.concat(this._handlers[e]||[]),n=0,r=this._handlersComplex.length;r>n;n++)t=this._handlersComplex[n],~e.search(t.pattern)&&(i=!0,s.push(t));return this._handlersAll.length||i?s.sort(function(e,t){return e.order-t.order}):s.slice(0)},i.prototype.emit=function(e,n){if(!this._enabled)return this;if(t(e)){for(var r in e)this.emit(r,e[r]);return this}var s,i,l,o,h,a,f,d=[].concat(e),u=[];for(o=0,a=d.length;a>o;o++){for(i=this.listeners(d[o]),h=0,f=i.length;f>h;h++)l=i[h],s={type:d[o],target:this},arguments.length>1&&(s.data=n),l.fn.call("scope"in l?l.scope:this,s),l.once&&u.push(l);for(h=u.length-1;h>=0;h--)u[h].parent.splice(u[h].parent.indexOf(u[h]),1)}return this},i.prototype.kill=function(){this.unbindAll(),this._handlers=null,this._handlersAll=null,this._handlersComplex=null,this._enabled=!1},i.prototype.disable=function(){return this._enabled=!1,this},i.prototype.enable=function(){return this._enabled=!0,this},i.version="3.0.0","undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=i),exports.Emitter=i):"function"==typeof define&&define.amd?define("emmett",[],function(){return i}):this.Emitter=i}).call(this); |
{ | ||
"name": "emmett", | ||
"version": "2.1.2", | ||
"description": "A custom events emitter for Node.js and the browser", | ||
"version": "3.0.0", | ||
"description": "A custom event emitter for Node.js and the browser.", | ||
"main": "emmett.js", | ||
@@ -15,5 +15,15 @@ "scripts": { | ||
"keywords": [ | ||
"events" | ||
"events", | ||
"emitter" | ||
], | ||
"author": "Alexis Jacomy", | ||
"contributors": [ | ||
{ | ||
"name": "jacomyal", | ||
"url": "https://github.com/jacomyal" | ||
}, | ||
{ | ||
"name": "yomguithereal", | ||
"url": "https://github.com/Yomguithereal" | ||
} | ||
], | ||
"license": "MIT", | ||
@@ -20,0 +30,0 @@ "bugs": { |
190
README.md
@@ -1,20 +0,184 @@ | ||
# Emmett - a custom events emitter for Node.js and the browser | ||
**version: 2.1.2** | ||
# Emmett | ||
## Description | ||
A custom event emitter for Node.js and the browser. | ||
**Emmett** is a custom events emitter for Node.js and the browser. It has initially been developed as domino.emitter, to deal with communication in domino.js, a JavaScript cascading controller for rich internet applications. | ||
Its aim is to provide its user with a lot of event emitting sugar while remaining lightweight and fast. | ||
I invite you to read [emmett's code](./emmett.js) to know more about how it works. To see examples, you can check the unit tests in [test/emmett.test.js](./test/emmett.test.js). | ||
## Installation | ||
Finally, if you see bugs or features that would improve the library, feel free to report them on the related [Github issues page](https://github.com/jacomyal/emmett/issues). | ||
You can install **Emmett** through npm: | ||
## Install | ||
```bash | ||
npm install --save emmett | ||
``` | ||
First, you can install emmett from NPM: `npm install --save emmett`, or directly save locally the [`emmett.min.js`](./emmett.min.js) minified file. | ||
Or you can just drop the [`emmett.min.js`](./emmett.min.js) file in your project (will work with many popular module systems). | ||
Also, you can install the development version: | ||
1. Clone the repository: `git clone http://github.com/jacomyal/emmett` | ||
2. Install dependencies: `npm install` | ||
3. Check the unit tests: `npm test` | ||
4. Get a minified version (`./emmett.min.js`): `npm build` | ||
## Usage | ||
### Creating an emitter | ||
```js | ||
var Emitter = require('emmett'); | ||
var emitter = new Emitter(); | ||
``` | ||
### Extending the emitter | ||
*Node.js* | ||
```js | ||
var util = require('util'), | ||
Emitter = require('emmett'); | ||
function MyObject() { | ||
Emitter.call(this); | ||
} | ||
helpers.inherits(MyObject, Emitter); | ||
``` | ||
*ES6 class* | ||
```js | ||
import Emitter from 'emmett'; | ||
class MyObject extends Emitter { | ||
/* ... */ | ||
} | ||
``` | ||
### Listening to events | ||
```js | ||
// Basic | ||
emitter.on('eventName', callback); | ||
// Once | ||
emitter.once('eventName', callback); | ||
// Matching event names with a regex | ||
emitter.on(/^event/, callback); | ||
// Options | ||
emitter.on('eventName', callback, {scope: customScope, once: true}); | ||
// Polymorphisms | ||
emitter.on(['event1', 'event2'], callback); | ||
emitter.on({ | ||
event1: callback1, | ||
event2: callback2 | ||
}); | ||
// Listening to every events | ||
emitter.on(callback); | ||
``` | ||
## Event data | ||
Events are objects having the following keys: | ||
* **data**: the data attached to the event. | ||
* **type**: the event type. | ||
* **target**: the event emitter. | ||
```js | ||
emitter.on('myEvent', function(e) { | ||
console.log(e.data); | ||
}); | ||
emitter.emit('myEvent', 'Hello World!'); | ||
// Will print "Hello World!" in the console | ||
``` | ||
## Removing listeners | ||
```js | ||
// Basic | ||
emitter.off('eventName', callback); | ||
// Removing every listeners attached to the given event | ||
emitter.off('eventName'); | ||
// Removing the callback from any event | ||
emitter.off(callback); | ||
// Polymorphisms | ||
emitter.off(['event1', 'event2'], callback); | ||
emitter.off({ | ||
event1: callback1, | ||
event2: callback2 | ||
}); | ||
// Removing every listeners | ||
emitter.unbindAll(); | ||
``` | ||
## Emitting | ||
```js | ||
// Basic | ||
emitter.emit('eventName'); | ||
// With data | ||
emitter.emit('eventName', {hello: 'world'}); | ||
// Polymorphisms | ||
emitter.emit(['event1', 'event2']); | ||
emitter.emit(['event1', 'event2'], {hello: 'world'}); | ||
emitter.emit({ | ||
event1: 'hey', | ||
event2: 'ho' | ||
}); | ||
``` | ||
## Retrieving listeners | ||
```js | ||
// Return every matching handlers for a given event name | ||
emitter.listeners('eventName'); | ||
``` | ||
## Disabling an emitter | ||
While disabled, emitting events won't produce nothing. | ||
```js | ||
emitter.disable(); | ||
emitter.enable(); | ||
``` | ||
## Killing an emitter | ||
Killing an emitter will remove all its listeners and make it inoperant in the future. | ||
```js | ||
emitter.kill(); | ||
``` | ||
## Contribution | ||
Do not hesitate to contribute to the library. Be sure to add and pass any relevant unit test before submitting any code. | ||
```bash | ||
# Installing the dev version | ||
git clone http://github.com/jacomyal/emmett | ||
cd emmett | ||
# Installing dependencies | ||
npm install | ||
# Running unit tests | ||
npm test | ||
# Build a minified version | ||
npm build | ||
# Lint the code | ||
gulp lint | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21466
185
448
2