UNPKG

8.38 kBJavaScriptView Raw
1(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.EventEmitter = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2'use strict';
3
4var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
5
6function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7
8var DEFAULT_VALUES = {
9 emitDelay: 10,
10 strictMode: false
11};
12
13/**
14 * @typedef {object} EventEmitterListenerFunc
15 * @property {boolean} once
16 * @property {function} fn
17 */
18
19/**
20 * @class EventEmitter
21 *
22 * @private
23 * @property {Object.<string, EventEmitterListenerFunc[]>} _listeners
24 * @property {string[]} events
25 */
26
27var EventEmitter = function () {
28
29 /**
30 * @constructor
31 * @param {{}} [opts]
32 * @param {number} [opts.emitDelay = 10] - Number in ms. Specifies whether emit will be sync or async. By default - 10ms. If 0 - fires sync
33 * @param {boolean} [opts.strictMode = false] - is true, Emitter throws error on emit error with no listeners
34 */
35
36 function EventEmitter() {
37 var opts = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_VALUES : arguments[0];
38
39 _classCallCheck(this, EventEmitter);
40
41 var emitDelay = void 0,
42 strictMode = void 0;
43
44 if (opts.hasOwnProperty('emitDelay')) {
45 emitDelay = opts.emitDelay;
46 } else {
47 emitDelay = DEFAULT_VALUES.emitDelay;
48 }
49 this._emitDelay = emitDelay;
50
51 if (opts.hasOwnProperty('strictMode')) {
52 strictMode = opts.strictMode;
53 } else {
54 strictMode = DEFAULT_VALUES.strictMode;
55 }
56 this._strictMode = strictMode;
57
58 this._listeners = {};
59 this.events = [];
60 }
61
62 /**
63 * @protected
64 * @param {string} type
65 * @param {function} listener
66 * @param {boolean} [once = false]
67 */
68
69
70 _createClass(EventEmitter, [{
71 key: '_addListenner',
72 value: function _addListenner(type, listener, once) {
73 if (typeof listener !== 'function') {
74 throw TypeError('listener must be a function');
75 }
76
77 if (this.events.indexOf(type) === -1) {
78 this._listeners[type] = [{
79 once: once,
80 fn: listener
81 }];
82 this.events.push(type);
83 } else {
84 this._listeners[type].push({
85 once: once,
86 fn: listener
87 });
88 }
89 }
90
91 /**
92 * Subscribes on event type specified function
93 * @param {string} type
94 * @param {function} listener
95 */
96
97 }, {
98 key: 'on',
99 value: function on(type, listener) {
100 this._addListenner(type, listener, false);
101 }
102
103 /**
104 * Subscribes on event type specified function to fire only once
105 * @param {string} type
106 * @param {function} listener
107 */
108
109 }, {
110 key: 'once',
111 value: function once(type, listener) {
112 this._addListenner(type, listener, true);
113 }
114
115 /**
116 * Removes event with specified type. If specified listenerFunc - deletes only one listener of specified type
117 * @param {string} eventType
118 * @param {function} [listenerFunc]
119 */
120
121 }, {
122 key: 'off',
123 value: function off(eventType, listenerFunc) {
124 var _this = this;
125
126 var typeIndex = this.events.indexOf(eventType);
127 var hasType = eventType && typeIndex !== -1;
128
129 if (hasType) {
130 if (!listenerFunc) {
131 delete this._listeners[eventType];
132 this.events.splice(typeIndex, 1);
133 } else {
134 (function () {
135 var removedEvents = [];
136 var typeListeners = _this._listeners[eventType];
137
138 typeListeners.forEach(
139 /**
140 * @param {EventEmitterListenerFunc} fn
141 * @param {number} idx
142 */
143 function (fn, idx) {
144 if (fn.fn === listenerFunc) {
145 removedEvents.unshift(idx);
146 }
147 });
148
149 removedEvents.forEach(function (idx) {
150 typeListeners.splice(idx, 1);
151 });
152
153 if (!typeListeners.length) {
154 _this.events.splice(typeIndex, 1);
155 delete _this._listeners[eventType];
156 }
157 })();
158 }
159 }
160 }
161
162 /**
163 * Applies arguments to specified event type
164 * @param {string} eventType
165 * @param {*[]} eventArguments
166 * @protected
167 */
168
169 }, {
170 key: '_applyEvents',
171 value: function _applyEvents(eventType, eventArguments) {
172 var typeListeners = this._listeners[eventType];
173
174 if (!typeListeners || !typeListeners.length) {
175 if (this._strictMode) {
176 throw 'No listeners specified for event: ' + eventType;
177 } else {
178 return;
179 }
180 }
181
182 var removableListeners = [];
183 typeListeners.forEach(function (eeListener, idx) {
184 eeListener.fn.apply(null, eventArguments);
185 if (eeListener.once) {
186 removableListeners.unshift(idx);
187 }
188 });
189
190 removableListeners.forEach(function (idx) {
191 typeListeners.splice(idx, 1);
192 });
193 }
194
195 /**
196 * Emits event with specified type and params.
197 * @param {string} type
198 * @param eventArgs
199 */
200
201 }, {
202 key: 'emit',
203 value: function emit(type) {
204 var _this2 = this;
205
206 for (var _len = arguments.length, eventArgs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
207 eventArgs[_key - 1] = arguments[_key];
208 }
209
210 if (this._emitDelay) {
211 setTimeout(function () {
212 _this2._applyEvents.call(_this2, type, eventArgs);
213 }, this._emitDelay);
214 } else {
215 this._applyEvents(type, eventArgs);
216 }
217 }
218
219 /**
220 * Emits event with specified type and params synchronously.
221 * @param {string} type
222 * @param eventArgs
223 */
224
225 }, {
226 key: 'emitSync',
227 value: function emitSync(type) {
228 for (var _len2 = arguments.length, eventArgs = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
229 eventArgs[_key2 - 1] = arguments[_key2];
230 }
231
232 this._applyEvents(type, eventArgs);
233 }
234 }]);
235
236 return EventEmitter;
237}();
238
239module.exports = EventEmitter;
240
241},{}]},{},[1])(1)
242});
\No newline at end of file