Skip to content

Commit 553b241

Browse files
author
Dustin Brown
committed
Initial rewrite after fork
1 parent f8e0d9b commit 553b241

File tree

4 files changed

+251
-2
lines changed

4 files changed

+251
-2
lines changed

LICENSE

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
This code is free. You can redistribute it and/or modify it in any
2+
way that you see fit so long as if you redistribute it with any changes, you
3+
don't call it the same thing.
4+
5+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11+
THE SOFTWARE.

README.md

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,103 @@
1-
# telegraph
2-
A minimalistic javascript event emitter based on smokesignals.js
1+
Telegraph
2+
=============
3+
4+
A minimal event emitter for browsers, forked from Benjamin Thomas' [smokesignals.js][1].
5+
6+
This library has three goals:
7+
8+
1. Make it easy and intuitive to listen for and initiate events on an object.
9+
2. Be as small as possible. Right now the minified version comes in at 514 bytes.
10+
3. Capability for handlers to cancel the event process.
11+
12+
There are many other [wonderful libraries that do similar things][2], but none
13+
of them worked exactly how I wanted them to work or met all the goals above.
14+
15+
Installing
16+
----------
17+
18+
Just download `telegraph.js` and put it in a place you can access from your webpage.
19+
20+
Loading
21+
-------
22+
23+
Just include the Telegraph script:
24+
25+
<script src="telegraph.js"></script>
26+
27+
Using
28+
-----
29+
30+
Make any object an event emitter:
31+
32+
var jill = {};
33+
telegraph(jill);
34+
35+
// or...
36+
var jill = telegraph();
37+
38+
Or if you prefer constructors:
39+
40+
function Person() {
41+
telegraph(this);
42+
}
43+
var jill = new Person();
44+
45+
Now you can listen for events:
46+
47+
function listener(name) {
48+
window.alert('Hello ' + name + '!');
49+
}
50+
jill.on('say hello', listener);
51+
52+
And emit events:
53+
54+
jill.emit('say hello', 'Jack');
55+
// alerts: "Hello Jack!"
56+
// returns: true
57+
58+
And remove a listener:
59+
60+
jill.off('say hello', listener);
61+
62+
Or if you only want to listen for an event once:
63+
64+
jill.once('another event', function() {
65+
window.alert("I'll only be called once!");
66+
});
67+
jill.emit('another event');
68+
69+
Or remove all listeners for an event:
70+
71+
jill.off('say hello');
72+
73+
Or if you want to remove ALL listeners:
74+
75+
// just call off() with no parameters
76+
jill.off();
77+
78+
// or reconvert the object...
79+
telegraph(jill);
80+
81+
Or if you want to cancel the event chain:
82+
83+
// just return false from a handler
84+
jill.on('event', function() { return false; });
85+
jill.on('event', function() { console.log('event!'); });
86+
87+
// emit now returns false, and 'event!' is not printed
88+
jill.emit('event');
89+
90+
That's it! One global object (`telegraph`) and when used it adds 4 methods to
91+
your objects (`on`, `once`, `off` and `emit`).
92+
93+
By the way, all methods, except for `emit`, are chainable:
94+
95+
var jill = smokesignals.convert({})
96+
.on('event one', function() { ... })
97+
.on('event two', function() { ... })
98+
.once('event three', function() { ... })
99+
.off ('event one')
100+
;
101+
102+
[1]: https://bitbucket.org/bentomas/smokesignals.js
103+
[2]: http://microjs.com/#events

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name":"telegraph-events",
3+
"description":"Minimal event emitter forked from smokesignals.js",
4+
"version":"1.0.0",
5+
"author":"Dustin Brown <dubrowgn.com> (https://dubrowgn.com)",
6+
"bugs":{
7+
"url":"https://github.com/dubrowgn/telegraph/issues",
8+
9+
},
10+
"keywords":[
11+
"events",
12+
"emitter",
13+
"trigger"
14+
],
15+
"repository":{
16+
"type":"git",
17+
"url":"git://github.com/dubrowgn/telegraph.git"
18+
},
19+
"scripts":{
20+
"build":"echo FIXME",
21+
"test":"node ./test.js"
22+
}
23+
}

telegraph.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* Converts the passed object, or a new object, into an event emitter
3+
* @param {object} obj The object to convert
4+
* @returns {object} The passed object for chaining
5+
*/
6+
telegraph = function (obj) {
7+
'use strict';
8+
9+
obj = obj || {};
10+
11+
// we store the list of handlers as a local variable inside the scope so
12+
// that we don't have to add random properties to the object we are
13+
// wrapping. (prefixing variables in the object with an underscore or two is
14+
// an ugly solution)
15+
var handlers = {};
16+
17+
/**
18+
* Add a listener
19+
* @param {string} eventName The name of the event
20+
* @param {function} handler The handler function for the event
21+
* @returns {object} This object for chaining
22+
*/
23+
obj.on = function (eventName, handler, front) {
24+
// either use the existing array or create a new one for this event
25+
(handlers[eventName] = handlers[eventName] || [])
26+
// add the handler to the array
27+
[front ? 'unshift' : 'push'](handler);
28+
29+
return obj;
30+
};
31+
32+
/**
33+
* Add a listener that will only be called once
34+
* @param {string} eventName The name of the event
35+
* @param {function} handler The handler function for the event
36+
* @returns {object} This object for chaining
37+
*/
38+
obj.once = function (eventName, handler, front) {
39+
// create a wrapper listener, that will remove itself after it is called
40+
function wrappedHandler() {
41+
// remove ourself, and then call the real handler with the args
42+
// passed to this wrapper
43+
handler.apply(obj.off(eventName, wrappedHandler), arguments);
44+
}
45+
46+
// in order to allow that these wrapped handlers can be removed by
47+
// removing the original function, we save a reference to the original
48+
// function
49+
wrappedHandler.h = handler;
50+
51+
// call the regular add listener function with our new wrapper
52+
return obj.on(eventName, wrappedHandler, front);
53+
};
54+
55+
/**
56+
* Remove a listener. Remove all listeners for eventName if handler is
57+
* omitted. Remove all listeners for all event names if eventName is also
58+
* omitted.
59+
* @param {string} eventName The name of the event
60+
* @param {function} handler The handler function for the event
61+
* @returns {object} This object for chaining
62+
*/
63+
obj.off = function (eventName, handler) {
64+
// if no eventName, clear all event handlers for all events
65+
if (eventName === undefined) {
66+
handlers = {};
67+
return obj;
68+
} // if
69+
70+
// loop through all handlers for this eventName to see if the handler
71+
// passed in was any of them so we can remove it
72+
// if no handler, clear all handlers for the event instead
73+
var list = handler ? handlers[eventName] || [] : [];
74+
for (var i = 0; i < list.length; i++) {
75+
// either this item is the handler passed in, or this item is a
76+
// wrapper for the handler passed in. See the 'once' function
77+
if (list[i] === handler || list[i].h === handler)
78+
list.splice(i--, 1);
79+
} // for( i )
80+
81+
// cleanup if no events for the eventName
82+
if (!list.length) {
83+
// remove the array for this eventname (if it doesn't exist then
84+
// this isn't really hurting anything)
85+
delete handlers[eventName];
86+
} // if
87+
88+
return obj;
89+
};
90+
91+
/**
92+
* Dispatches the named event, calling all registered handler functions. If
93+
* any handler returns false, the event subsequent handlers are not called
94+
* and false is returned; Otherwise, all handlers are called and true is
95+
* returned.
96+
* @param {string} eventName The name of the event to dispatch
97+
* @returns {boolean} False if any handler returns false, true otherwise.
98+
*/
99+
obj.emit = function (eventName) {
100+
// loop through all handlers for this event name and call them all
101+
// arguments is "array-like", so call slice() from list instead
102+
// handlers can return false to cancel event
103+
var list = handlers[eventName] || [];
104+
var args = list.slice.call(arguments, 1);
105+
for (var i = 0; i < list.length; ++i) {
106+
if (list[i].apply(obj, args) === false)
107+
return false;
108+
} // for( i )
109+
110+
return true;
111+
};
112+
113+
return obj;
114+
} // telegraph( )

0 commit comments

Comments
 (0)