Skip to content

Commit

Permalink
Merge branch 'release/v1.0.0' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver Caldwell committed Apr 13, 2011
2 parents 13cfaa7 + bd7d463 commit c74e004
Show file tree
Hide file tree
Showing 7 changed files with 358 additions and 9 deletions.
188 changes: 188 additions & 0 deletions EventEmitter.js
@@ -0,0 +1,188 @@
/**
* @preserve EventEmitter v1.0.0
*
* Copyright 2011, Oliver Caldwell (flowdev.co.uk)
* Dual licensed under the MIT or GPL Version 2 licenses.
* https://github.com/Wolfy87/Listen
*/

// Initialise the class
function EventEmitter() {}

// Initialise the storage variables
EventEmitter.prototype._events = {};
EventEmitter.prototype._listeners = [];

// Has to be an array to stop it being moved out of the prototype on change
EventEmitter.prototype._maxListeners = [10];

/**
* Adds a listener for a specified event
*
* @param {String} name Name of the event
* @param {Function} listener Run when the event is emitted
* @param {Boolean} once If true, the listener will only be run once, use EventEmitter.once instead, this is mainly for internal use
*/
EventEmitter.prototype.addListener = function(name, listener, once) {
// Grab the index of the listener
var index = this._listeners.length;

// Emit the newListener event
this.emit('newListener', name, listener);

// Add the listener
this._listeners.push({
listener: listener,
once: (once) ? true : false
});

// Add the event to the events object if required
if(typeof this._events[name] === 'undefined') {
this._events[name] = [];
}

// Add the listeners index to the event
this._events[name].push(index);

// Check if we have exceeded the max listeners
if(this._events[name].length === this._maxListeners[0]) {
// We have, let the developer know
console.log('Maximum number of listeners (' + this._maxListeners[0] + ') reached for the "' + name + '" event!');
}
};

/**
* Adds a listener for a specified event (alias of EventEmitter.addListener)
*
* @param {String} name Name of the event
* @param {Function} listener Run when the event is emitted
* @param {Boolean} once If true, the listener will only be run once, use EventEmitter.once instead, this is mainly for internal use
*/
EventEmitter.prototype.on = EventEmitter.prototype.addListener;

/**
* Adds a listener for a specified event that will only be called once
*
* @param {String} name Name of the event
* @param {Function} listener Run when the event is emitted
*/
EventEmitter.prototype.once = function(name, listener) {
this.addListener(name, listener, true);
};

/**
* Removes a listener for a specified event
*
* @param {String} name Name of the event
* @param {Function} listener Reference to the listener function
*/
EventEmitter.prototype.removeListener = function(name, listener) {
// Initialise any required variables
var i = null,
indexes = null;

// Make sure the event exists
if(this._events[name] instanceof Array) {
// Grab the listeners indexes
indexes = this._events[name];

// Loop through all of the indexes
for(i = 0; i < indexes.length; i++) {
// Check if we have found the listener
if(this._listeners[indexes[i]].listener === listener) {
// It is, remove it and return
indexes.splice(i, 1);
}
}
}
};

/**
* Removes all the listeners for a specified event
*
* @param {String} name Name of the event
*/
EventEmitter.prototype.removeAllListeners = function(name) {
this._events[name] = [];
};


/**
* Sets the max number of listeners before a message is displayed
* If it is set to 0 then there is no limit
*
* @param {Number} n Max number of listeners before a message is displayed
*/
EventEmitter.prototype.setMaxListeners = function(n) {
this._maxListeners[0] = n;
};

/**
* Returns an array of listeners for the specified event
*
* @param {String} name Name of the event
* @param {Boolean} checkOnce Mainly for internal use, but if true, it will check if the once flag is set on the listener and remove it if it is
* @returns {Array} An array of the assigned listeners
*/
EventEmitter.prototype.listeners = function(name, checkOnce) {
// Initialise any required variables
var i = null,
built = [],
l = null;

// Make sure the event exists
if(this._events[name] instanceof Array) {
// Grab the listeners indexes
indexes = this._events[name];

// Loop through all of the indexes
for(i = 0; i < indexes.length; i++) {
// Grab the listener
l = this._listeners[indexes[i]];

// To do, finish this
if(checkOnce) {
if(l.once) {
// Add it to the array
built.push(l.listener);

// Remove the reference
this._events[name].splice(i, 1);
}
else {
// Add it to the array
built.push(l.listener);
}
}
else {
// Add it to the array
built.push(l.listener);
}
}
}

// Return the found listeners
return built;
};

/**
* Emits the specified event with optional arguments
*
* @param {String} name Name of the event to be emitted
* @param {Mixed} An argument to be passed to the listeners, you can have as many of these as you want
*/
EventEmitter.prototype.emit = function(name) {
// Initialise any required variables
var i = null,
args = Array.prototype.slice.call(arguments),
listeners = this.listeners(name, true);

// Splice out the first argument
args.splice(0, 1);

// Loop through the listeners
for(i = 0; i < listeners.length; i++) {
// Call the function
listeners[i].apply(null, args);
}
};
11 changes: 11 additions & 0 deletions EventEmitter.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 113 additions & 2 deletions README.md
@@ -1,3 +1,114 @@
Listen adds the event functionality that NodeJS has to your browser.
**Evented JavaScript for the browser**

So you can register and emit events from what ever objects you choose.
This script adds the EventEmitter class to your browser. It has the same API and functionality as the NodeJS implementation.

So you can listen for and emit events from what ever objects you choose.

It works exactly the same as the NodeJS version so head over to the [NodeJS docs](http://nodejs.org/docs/v0.4.5/api/events.html#events.EventEmitter) for the details.

## Documentation

### Creating an EventEmitter object

This is simple, just include the script and create a new instance of the EventEmitter class like so.

var myEmitter = new EventEmitter();

Now the myEmitter object will have methods such as `emit` and `addListener`.

### Adding a listener

This can be done in a few ways. You can use the `addListener` method or it's alias, the `on` method.

This example uses the `addListener` method but you can swap it for `on` and it will make no difference.

myEmitter.addListener('message', show);

This is assuming you have a function called `show` already defined. It assigns the `show` function to the `message` event.

You can also use the `once` method to add a listener that will only be fired once. The syntax is the same as the previous methods.

You can retrieve an array of listeners for a specified event with the `listeners` method.

This will return an array of all listeners associated with the `message` event.

myEmitter.listeners('message');

### Removing a listener

To remove a listener, use the `removeListener` method with the same arguments as you used to set it.

myEmitter.removeListener('message', show);

You can also remove all listeners for a specified event, like so.

myEmitter.removeAllListeners('message');

### Event limits

There is no hard limit as such, but after a certain amount a message will be posted to the console saying that you have exceeded the limit.

You can still add more, it just helps you to find bugs where it may be looping and adding too many listeners.

The default limit is 10 listeners per event.

It does not restrict functionality at all.

You can change the limit with the `setMaxListeners` method. For instance, this would set the limit to 20.

myEmitter.setMaxListeners(20);

Setting it to 0 will disable this feature.

### Emitting events

To emit an event to all the registered listeners you have to use the `emit` method.

This would emit the `message` event and pass two arguments to the listeners.

myEmitter.emit('message', 'arg1', 'arg2');

You can have as many arguments as you want.

## Author

[Oliver Caldwell](http://flowdev.co.uk/), a 17 year old web developer from Essex, England.

## Licences

### MIT
Copyright (C) 2011 Oliver Caldwell

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

### GPL
Copyright (C) 2011 Oliver Caldwell

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
2 changes: 1 addition & 1 deletion build/validate.js
@@ -1,5 +1,5 @@
// Initialisation
var src = require('fs').readFileSync('listen.js', 'utf8'),
var src = require('fs').readFileSync('EventEmitter.js', 'utf8'),
sys = require('sys'),
jshint = require('./jshint').JSHINT,
i = null,
Expand Down
Empty file removed listen.js
Empty file.
8 changes: 4 additions & 4 deletions makefile
@@ -1,13 +1,13 @@
# Set the default files to be built
default: listen.min.js validate
default: EventEmitter.min.js validate

# Compress listen.js into listen.min.js
listen.min.js: listen.js
# Compress EventEmitter.js into EventEmitter.min.js
EventEmitter.min.js: EventEmitter.js
@@echo 'Compressing...'
@@java -jar build/compiler.jar --js $^ --js_output_file $@
@@echo 'Done!'

# Validate listen.js with jshint
# Validate EventEmitter.js with jshint
validate:
@@echo 'Validating...'
@@node build/validate.js
Expand Down

0 comments on commit c74e004

Please sign in to comment.