Skip to content

Commit

Permalink
[minor] Move the EventTarget methods to lib/EventTarget.js
Browse files Browse the repository at this point in the history
  • Loading branch information
lpinca committed Dec 4, 2016
1 parent 8e1b092 commit c16d595
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 147 deletions.
158 changes: 158 additions & 0 deletions lib/EventTarget.js
@@ -0,0 +1,158 @@
'use strict';

/**
* Class representing an event.
*
* @private
*/
class Event {
/**
* Create a new `Event`.
*
* @param {String} type The name of the event
* @param {Object} target A reference to the target to which the event was dispatched
*/
constructor (type, target) {
this.target = target;
this.type = type;
}
}

/**
* Class representing a message event.
*
* @extends Event
* @private
*/
class MessageEvent extends Event {
/**
* Create a new `MessageEvent`.
*
* @param {(String|Buffer|ArrayBuffer)} data The received data
* @param {Boolean} isBinary Specifies if `data` is binary
* @param {WebSocket} target A reference to the target to which the event was dispatched
*/
constructor (data, isBinary, target) {
super('message', target);

this.binary = isBinary; // non-standard.
this.data = data;
}
}

/**
* Class representing a close event.
*
* @extends Event
* @private
*/
class CloseEvent extends Event {
/**
* Create a new `CloseEvent`.
*
* @param {Number} code The status code explaining why the connection is being closed
* @param {String} reason A human-readable string explaining why the connection is closing
* @param {WebSocket} target A reference to the target to which the event was dispatched
*/
constructor (code, reason, target) {
super('close', target);

this.wasClean = code === undefined || code === 1000;
this.reason = reason;
this.target = target;
this.type = 'close';
this.code = code;
}
}

/**
* Class representing an open event.
*
* @extends Event
* @private
*/
class OpenEvent extends Event {
/**
* Create a new `OpenEvent`.
*
* @param {WebSocket} target A reference to the target to which the event was dispatched
*/
constructor (target) {
super('open', target);
}
}

/**
* This provides methods for emulating the `EventTarget` interface. It's not
* meant to be used directly.
*
* @mixin
*/
const EventTarget = {
/**
* Register an event listener.
*
* @param {String} method A string representing the event type to listen for
* @param {Function} listener The listener to add
* @public
*/
addEventListener (method, listener) {
if (typeof listener !== 'function') return;

function onMessage (data, flags) {
if (flags.binary && this.binaryType === 'arraybuffer') {
data = new Uint8Array(data).buffer;
}
listener.call(this, new MessageEvent(data, !!flags.binary, this));
}

function onClose (code, message) {
listener.call(this, new CloseEvent(code, message, this));
}

function onError (event) {
event.type = 'error';
event.target = this;
listener.call(this, event);
}

function onOpen () {
listener.call(this, new OpenEvent(this));
}

if (method === 'message') {
onMessage._listener = listener;
this.on(method, onMessage);
} else if (method === 'close') {
onClose._listener = listener;
this.on(method, onClose);
} else if (method === 'error') {
onError._listener = listener;
this.on(method, onError);
} else if (method === 'open') {
onOpen._listener = listener;
this.on(method, onOpen);
} else {
this.on(method, listener);
}
},

/**
* Remove an event listener.
*
* @param {String} method A string representing the event type to remove
* @param {Function} listener The listener to remove
* @public
*/
removeEventListener (method, listener) {
const listeners = this.listeners(method);

for (var i = 0; i < listeners.length; i++) {
if (listeners[i]._listener === listener) {
this.removeListener(method, listeners[i]);
}
}
}
};

module.exports = EventTarget;

0 comments on commit c16d595

Please sign in to comment.