From 1eb1334a0ef8e9b0d56104bd0a14ed43bf811881 Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Sun, 30 Dec 2012 01:11:18 -0500 Subject: [PATCH] Updated implementation to be modular. --- README.md | 2 +- index.js | 18 ------ package.json | 2 +- smokesignals.js | 150 +++++++++++++++++++++++--------------------- smokesignals.min.js | 2 +- test.js | 2 +- 6 files changed, 84 insertions(+), 92 deletions(-) delete mode 100644 index.js diff --git a/README.md b/README.md index de00e15..41f70a8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ the functionality that Node's event emitter has.) This library has three goals: 1. Make it easy and intuitive to listen for and initiate events on an object. -2. Be really small. Right now the minified version comes in at 407 bytes (247 +2. Be really small. Right now the minified version comes in at 571 bytes (345 bytes gzipped). 3. Not pollute the global namespace or the objects it modifies with a bunch of crap. I define crap as anything that is not the API. diff --git a/index.js b/index.js deleted file mode 100644 index 04b2de3..0000000 --- a/index.js +++ /dev/null @@ -1,18 +0,0 @@ -var existed = false; -var old; - -if ('smokesignals' in global) { - existed = true; - old = global.smokesignals; -} - -require('./smokesignals'); - -module.exports = smokesignals; - -if (existed) { - global.smokesignals = old; -} -else { - delete global.smokesignals; -} diff --git a/package.json b/package.json index 33eef0c..944147d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ , "email": "benjamin@benjaminthomas.org" } , "keywords": ["events", "emitter", "trigger"] -, "main": "./index.js" +, "main": "./smokesignals.min.js" , "repository": {"type": "git", "url": "git://github.com/bentomas/smokesignals.git"} , "scripts": { "test": "node ./test.js" } } diff --git a/smokesignals.js b/smokesignals.js index e987911..42a1dad 100644 --- a/smokesignals.js +++ b/smokesignals.js @@ -1,82 +1,92 @@ -// in a few cases we've chosen optimizing script length over efficiency of code. -// I think that is the right choice for this library. If you're adding and -// triggering A LOT of events, you might want to use a different library. -smokesignals = { - convert: function(obj, handlers) { - // we store the list of handlers as a local variable inside the scope - // so that we don't have to add random properties to the object we are - // converting. (prefixing variables in the object with an underscore or - // two is an ugly solution) - // we declare the variable in the function definition to use two less - // characters (as opposed to using 'var '). I consider this an inelegant - // solution since smokesignals.convert.length now returns 2 when it is - // really 1, but doing this doesn't otherwise change the functionallity of - // this module, so we'll go with it for now - handlers = {}; +(function (name, global, definition) { + if (typeof module !== 'undefined') { + module.exports = definition(); + } else if (typeof define !== 'undefined' && typeof define.amd === 'object') { + define(definition); + } else { + global[name] = definition(); + } +})('smokesignals', this, function () { + // in a few cases we've chosen optimizing script length over efficiency of code. + // I think that is the right choice for this library. If you're adding and + // triggering A LOT of events, you might want to use a different library. + return { + convert: function(obj, handlers) { + // we store the list of handlers as a local variable inside the scope + // so that we don't have to add random properties to the object we are + // converting. (prefixing variables in the object with an underscore or + // two is an ugly solution) + // we declare the variable in the function definition to use two less + // characters (as opposed to using 'var '). I consider this an inelegant + // solution since smokesignals.convert.length now returns 2 when it is + // really 1, but doing this doesn't otherwise change the functionallity of + // this module, so we'll go with it for now + handlers = {}; - // add a listener - obj.on = function(eventName, handler) { - // either use the existing array or create a new one for this event - // this isn't the most efficient way to do this, but is the shorter - // than other more efficient ways, so we'll go with it for now. - (handlers[eventName] = handlers[eventName] || []) - // add the handler to the array - .push(handler); + // add a listener + obj.on = function(eventName, handler) { + // either use the existing array or create a new one for this event + // this isn't the most efficient way to do this, but is the shorter + // than other more efficient ways, so we'll go with it for now. + (handlers[eventName] = handlers[eventName] || []) + // add the handler to the array + .push(handler); - return obj; - } - - // add a listener that will only be called once - obj.once = function(eventName, handler) { - // create a wrapper listener, that will remove itself after it is called - function wrappedHandler() { - // remove ourself, and then call the real handler with the args - // passed to this wrapper - handler.apply(obj.off(eventName, wrappedHandler), arguments); + return obj; } - // in order to allow that these wrapped handlers can be removed by - // removing the original function, we save a reference to the original - // function - wrappedHandler.h = handler; - // call the regular add listener function with our new wrapper - return obj.on(eventName, wrappedHandler); - } + // add a listener that will only be called once + obj.once = function(eventName, handler) { + // create a wrapper listener, that will remove itself after it is called + function wrappedHandler() { + // remove ourself, and then call the real handler with the args + // passed to this wrapper + handler.apply(obj.off(eventName, wrappedHandler), arguments); + } + // in order to allow that these wrapped handlers can be removed by + // removing the original function, we save a reference to the original + // function + wrappedHandler.h = handler; - // remove a listener - obj.off = function(eventName, handler) { - // loop through all handlers for this eventName, assuming a handler - // was passed in, to see if the handler passed in was any of them so - // we can remove it - // it would be more efficient to stash the length and compare i - // to that, but that is longer so we'll go with this. - for (var list = handlers[eventName], i = 0; handler && list && list[i]; i++) { - // either this item is the handler passed in, or this item is a - // wrapper for the handler passed in. See the 'once' function - list[i] != handler && list[i].h != handler || - // remove it! - list.splice(i--,1); + // call the regular add listener function with our new wrapper + return obj.on(eventName, wrappedHandler); } - // if i is 0 (i.e. falsy), then there are no items in the array for this - // event name (or the array doesn't exist) - if (!i) { - // remove the array for this eventname (if it doesn't exist then - // this isn't really hurting anything) - delete handlers[eventName]; + + // remove a listener + obj.off = function(eventName, handler) { + // loop through all handlers for this eventName, assuming a handler + // was passed in, to see if the handler passed in was any of them so + // we can remove it + // it would be more efficient to stash the length and compare i + // to that, but that is longer so we'll go with this. + for (var list = handlers[eventName], i = 0; handler && list && list[i]; i++) { + // either this item is the handler passed in, or this item is a + // wrapper for the handler passed in. See the 'once' function + list[i] != handler && list[i].h != handler || + // remove it! + list.splice(i--,1); + } + // if i is 0 (i.e. falsy), then there are no items in the array for this + // event name (or the array doesn't exist) + if (!i) { + // remove the array for this eventname (if it doesn't exist then + // this isn't really hurting anything) + delete handlers[eventName]; + } + return obj; } - return obj; - } - obj.emit = function(eventName) { - // loop through all handlers for this event name and call them all - // it would be more efficient to stash the length and compare i - // to that, but that is longer so we'll go with this. - for(var list = handlers[eventName], i = 0; list && list[i];) { - list[i++].apply(obj, list.slice.call(arguments, 1)); + obj.emit = function(eventName) { + // loop through all handlers for this event name and call them all + // it would be more efficient to stash the length and compare i + // to that, but that is longer so we'll go with this. + for(var list = handlers[eventName], i = 0; list && list[i];) { + list[i++].apply(obj, list.slice.call(arguments, 1)); + } + return obj; } + return obj; } - - return obj; } -} +}); diff --git a/smokesignals.min.js b/smokesignals.min.js index 0178f5b..fe3064e 100644 --- a/smokesignals.min.js +++ b/smokesignals.min.js @@ -1 +1 @@ -smokesignals={convert:function(c,e){e={};c.on=function(d,a){(e[d]=e[d]||[]).push(a);return c};c.once=function(d,a){function b(){a.apply(c.off(d,b),arguments)}b.h=a;return c.on(d,b)};c.off=function(d,a){for(var b=e[d],f=0;a&&b&&b[f];f++)b[f]!=a&&b[f].h!=a||b.splice(f--,1);f||delete e[d];return c};c.emit=function(d){for(var a=e[d],b=0;a&&a[b];)a[b++].apply(c,a.slice.call(arguments,1));return c};return c}}; +(function(n,e,t){typeof module!="undefined"?module.exports=t():typeof define!="undefined"&&typeof define.amd=="object"?define(t):e[n]=t()})("smokesignals",this,function(){return{convert:function(n,e){return e={},n.on=function(t,o){return(e[t]=e[t]||[]).push(o),n},n.once=function(e,t){function o(){t.apply(n.off(e,o),arguments)}return o.h=t,n.on(e,o)},n.off=function(t,o){for(var f=e[t],u=0;o&&f&&f[u];u++)f[u]!=o&&f[u].h!=o||f.splice(u--,1);return u||delete e[t],n},n.emit=function(t){for(var o=e[t],f=0;o&&o[f];)o[f++].apply(n,o.slice.call(arguments,1));return n},n}}}) \ No newline at end of file diff --git a/test.js b/test.js index f5e4c28..4ae51ea 100644 --- a/test.js +++ b/test.js @@ -6,7 +6,7 @@ console.log('test do not pollute node globals when requiring'); globalKeys.push(key); } - var smokesignals = require('./index'); + var smokesignals = require('./'); for (var key in global) { assert.ok(globalKeys.indexOf(key) > -1);