UNPKG

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