event-target.js (4323B)
1 'use strict'; 2 3 /** 4 * Class representing an event. 5 * 6 * @private 7 */ 8 class Event { 9 /** 10 * Create a new `Event`. 11 * 12 * @param {String} type The name of the event 13 * @param {Object} target A reference to the target to which the event was dispatched 14 */ 15 constructor(type, target) { 16 this.target = target; 17 this.type = type; 18 } 19 } 20 21 /** 22 * Class representing a message event. 23 * 24 * @extends Event 25 * @private 26 */ 27 class MessageEvent extends Event { 28 /** 29 * Create a new `MessageEvent`. 30 * 31 * @param {(String|Buffer|ArrayBuffer|Buffer[])} data The received data 32 * @param {WebSocket} target A reference to the target to which the event was dispatched 33 */ 34 constructor(data, target) { 35 super('message', target); 36 37 this.data = data; 38 } 39 } 40 41 /** 42 * Class representing a close event. 43 * 44 * @extends Event 45 * @private 46 */ 47 class CloseEvent extends Event { 48 /** 49 * Create a new `CloseEvent`. 50 * 51 * @param {Number} code The status code explaining why the connection is being closed 52 * @param {String} reason A human-readable string explaining why the connection is closing 53 * @param {WebSocket} target A reference to the target to which the event was dispatched 54 */ 55 constructor(code, reason, target) { 56 super('close', target); 57 58 this.wasClean = target._closeFrameReceived && target._closeFrameSent; 59 this.reason = reason; 60 this.code = code; 61 } 62 } 63 64 /** 65 * Class representing an open event. 66 * 67 * @extends Event 68 * @private 69 */ 70 class OpenEvent extends Event { 71 /** 72 * Create a new `OpenEvent`. 73 * 74 * @param {WebSocket} target A reference to the target to which the event was dispatched 75 */ 76 constructor(target) { 77 super('open', target); 78 } 79 } 80 81 /** 82 * Class representing an error event. 83 * 84 * @extends Event 85 * @private 86 */ 87 class ErrorEvent extends Event { 88 /** 89 * Create a new `ErrorEvent`. 90 * 91 * @param {Object} error The error that generated this event 92 * @param {WebSocket} target A reference to the target to which the event was dispatched 93 */ 94 constructor(error, target) { 95 super('error', target); 96 97 this.message = error.message; 98 this.error = error; 99 } 100 } 101 102 /** 103 * This provides methods for emulating the `EventTarget` interface. It's not 104 * meant to be used directly. 105 * 106 * @mixin 107 */ 108 const EventTarget = { 109 /** 110 * Register an event listener. 111 * 112 * @param {String} type A string representing the event type to listen for 113 * @param {Function} listener The listener to add 114 * @param {Object} options An options object specifies characteristics about 115 * the event listener 116 * @param {Boolean} options.once A `Boolean`` indicating that the listener 117 * should be invoked at most once after being added. If `true`, the 118 * listener would be automatically removed when invoked. 119 * @public 120 */ 121 addEventListener(type, listener, options) { 122 if (typeof listener !== 'function') return; 123 124 function onMessage(data) { 125 listener.call(this, new MessageEvent(data, this)); 126 } 127 128 function onClose(code, message) { 129 listener.call(this, new CloseEvent(code, message, this)); 130 } 131 132 function onError(error) { 133 listener.call(this, new ErrorEvent(error, this)); 134 } 135 136 function onOpen() { 137 listener.call(this, new OpenEvent(this)); 138 } 139 140 const method = options && options.once ? 'once' : 'on'; 141 142 if (type === 'message') { 143 onMessage._listener = listener; 144 this[method](type, onMessage); 145 } else if (type === 'close') { 146 onClose._listener = listener; 147 this[method](type, onClose); 148 } else if (type === 'error') { 149 onError._listener = listener; 150 this[method](type, onError); 151 } else if (type === 'open') { 152 onOpen._listener = listener; 153 this[method](type, onOpen); 154 } else { 155 this[method](type, listener); 156 } 157 }, 158 159 /** 160 * Remove an event listener. 161 * 162 * @param {String} type A string representing the event type to remove 163 * @param {Function} listener The listener to remove 164 * @public 165 */ 166 removeEventListener(type, listener) { 167 const listeners = this.listeners(type); 168 169 for (let i = 0; i < listeners.length; i++) { 170 if (listeners[i] === listener || listeners[i]._listener === listener) { 171 this.removeListener(type, listeners[i]); 172 } 173 } 174 } 175 }; 176 177 module.exports = EventTarget;