1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const _ = require("lodash");
|
4 | const eventSplitter = /\s+/;
|
5 | function eventsApi(iteratee, events, name, callback, options) {
|
6 | let i = 0, names;
|
7 | if (name && typeof name === 'object') {
|
8 | if (callback !== void 0 && 'context' in options && options['context'] === void 0) {
|
9 | options['context'] = callback;
|
10 | }
|
11 | for (names = _.keys(name); i < names.length; i++) {
|
12 | events = eventsApi(iteratee, events, names[i], name[names[i]], options);
|
13 | }
|
14 | }
|
15 | else if (name && typeof name === 'string' && eventSplitter.test(name)) {
|
16 | for (names = name.split(eventSplitter); i < names.length; i++) {
|
17 | events = iteratee(events, names[i], callback, options);
|
18 | }
|
19 | }
|
20 | else {
|
21 | events = iteratee(events, name, callback, options);
|
22 | }
|
23 | return events;
|
24 | }
|
25 | function onApi(events, name, callback, options) {
|
26 | if (callback) {
|
27 | const handlers = events[name] || (events[name] = []);
|
28 | const context = options.context, ctx = options.ctx, listening = options.listening, priority = options.priority;
|
29 | if (listening) {
|
30 | listening.count++;
|
31 | }
|
32 | handlers.push({
|
33 | callback: callback,
|
34 | context: context,
|
35 | ctx: context || ctx,
|
36 | listening: listening,
|
37 | priority: priority
|
38 | });
|
39 | handlers.sort((a, b) => b.priority - a.priority);
|
40 | }
|
41 | return events;
|
42 | }
|
43 | function offApi(events, name, callback, options) {
|
44 | if (!events) {
|
45 | return;
|
46 | }
|
47 | let i = 0, listening;
|
48 | const context = options.context, listeners = options.listeners;
|
49 | if (!name && !callback && !context) {
|
50 | const ids = _.keys(listeners);
|
51 | for (; i < ids.length; i++) {
|
52 | listening = listeners[ids[i]];
|
53 | delete listeners[listening.id];
|
54 | delete listening.listeningTo[listening.objId];
|
55 | }
|
56 | return;
|
57 | }
|
58 | const names = name ? [name] : _.keys(events);
|
59 | for (; i < names.length; i++) {
|
60 | name = names[i];
|
61 | const handlers = events[name];
|
62 | if (!handlers) {
|
63 | break;
|
64 | }
|
65 | const remaining = [];
|
66 | for (let j = 0; j < handlers.length; j++) {
|
67 | const handler = handlers[j];
|
68 | if (callback && callback !== handler.callback &&
|
69 | callback !== handler.callback._callback ||
|
70 | context && context !== handler.context) {
|
71 | remaining.push(handler);
|
72 | }
|
73 | else {
|
74 | listening = handler.listening;
|
75 | if (listening && --listening.count === 0) {
|
76 | delete listeners[listening.id];
|
77 | delete listening.listeningTo[listening.objId];
|
78 | }
|
79 | }
|
80 | }
|
81 | if (remaining.length) {
|
82 | events[name] = remaining;
|
83 | }
|
84 | else {
|
85 | delete events[name];
|
86 | }
|
87 | }
|
88 | if (_.size(events)) {
|
89 | return events;
|
90 | }
|
91 | }
|
92 | function onceMap(map, name, callback, offer) {
|
93 | if (callback) {
|
94 | const once = map[name] = _.once(function () {
|
95 | offer(name, once);
|
96 | callback.apply(this, arguments);
|
97 | });
|
98 | once._callback = callback;
|
99 | }
|
100 | return map;
|
101 | }
|
102 | function triggerApi(objEvents, name, callback, args, triggerer = triggerEvents) {
|
103 | if (objEvents) {
|
104 | const events = objEvents[name];
|
105 | let allEvents = objEvents['all'];
|
106 | if (events && allEvents) {
|
107 | allEvents = allEvents.slice();
|
108 | }
|
109 | if (events) {
|
110 | triggerer(events, args);
|
111 | }
|
112 | if (allEvents) {
|
113 | triggerer(allEvents, [name].concat(args));
|
114 | }
|
115 | }
|
116 | return objEvents;
|
117 | }
|
118 | function triggerEvents(events, args) {
|
119 | let ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
|
120 | switch (args.length) {
|
121 | case 0:
|
122 | while (++i < l) {
|
123 | (ev = events[i]).callback.call(ev.ctx);
|
124 | }
|
125 | return;
|
126 | case 1:
|
127 | while (++i < l) {
|
128 | (ev = events[i]).callback.call(ev.ctx, a1);
|
129 | }
|
130 | return;
|
131 | case 2:
|
132 | while (++i < l) {
|
133 | (ev = events[i]).callback.call(ev.ctx, a1, a2);
|
134 | }
|
135 | return;
|
136 | case 3:
|
137 | while (++i < l) {
|
138 | (ev = events[i]).callback.call(ev.ctx, a1, a2, a3);
|
139 | }
|
140 | return;
|
141 | default:
|
142 | while (++i < l) {
|
143 | (ev = events[i]).callback.apply(ev.ctx, args);
|
144 | }
|
145 | return;
|
146 | }
|
147 | }
|
148 | class Event {
|
149 | constructor(name) {
|
150 | this._isPropagationStopped = false;
|
151 | this._isDefaultPrevented = false;
|
152 | this._name = name;
|
153 | }
|
154 | stopPropagation() {
|
155 | this._isPropagationStopped = true;
|
156 | }
|
157 | preventDefault() {
|
158 | this._isDefaultPrevented = true;
|
159 | }
|
160 | get name() {
|
161 | return this._name;
|
162 | }
|
163 | get isPropagationStopped() {
|
164 | return this._isPropagationStopped;
|
165 | }
|
166 | get isDefaultPrevented() {
|
167 | return this._isDefaultPrevented;
|
168 | }
|
169 | }
|
170 | exports.Event = Event;
|
171 | class EventDispatcher {
|
172 | get _listenId() {
|
173 | return this._savedListenId || (this._savedListenId = _.uniqueId('l'));
|
174 | }
|
175 | on(nameOrMap, callback, context, priority) {
|
176 | this.internalOn(nameOrMap, callback, context, priority);
|
177 | return this;
|
178 | }
|
179 | internalOn(name, callback, context, priority = 0, listening) {
|
180 | this._events = eventsApi(onApi, this._events || {}, name, callback, {
|
181 | context: context,
|
182 | ctx: this,
|
183 | listening: listening,
|
184 | priority: priority
|
185 | });
|
186 | if (listening) {
|
187 | const listeners = this._listeners || (this._listeners = {});
|
188 | listeners[listening.id] = listening;
|
189 | }
|
190 | }
|
191 | once(name, callback, context, priority) {
|
192 | const events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
|
193 | return this.on(events, void 0, context, priority);
|
194 | }
|
195 | off(name, callback, context) {
|
196 | if (!this._events) {
|
197 | return this;
|
198 | }
|
199 | this._events = eventsApi(offApi, this._events, name, callback, {
|
200 | context: context,
|
201 | listeners: this._listeners
|
202 | });
|
203 | return this;
|
204 | }
|
205 | listenTo(obj, name, callback, priority) {
|
206 | if (!obj) {
|
207 | return this;
|
208 | }
|
209 | const id = obj._listenId;
|
210 | const listeningTo = this._listeningTo || (this._listeningTo = {});
|
211 | let listening = listeningTo[id];
|
212 | if (!listening) {
|
213 | const thisId = this._listenId;
|
214 | listening = listeningTo[id] = {
|
215 | obj: obj,
|
216 | objId: id,
|
217 | id: thisId,
|
218 | listeningTo: listeningTo,
|
219 | count: 0
|
220 | };
|
221 | }
|
222 | obj.internalOn(name, callback, this, priority, listening);
|
223 | return this;
|
224 | }
|
225 | listenToOnce(obj, name, callback, priority) {
|
226 | const events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
|
227 | return this.listenTo(obj, events, void 0, priority);
|
228 | }
|
229 | stopListening(obj, name, callback) {
|
230 | const listeningTo = this._listeningTo;
|
231 | if (!listeningTo) {
|
232 | return this;
|
233 | }
|
234 | const ids = obj ? [obj._listenId] : _.keys(listeningTo);
|
235 | for (let i = 0; i < ids.length; i++) {
|
236 | const listening = listeningTo[ids[i]];
|
237 | if (!listening) {
|
238 | break;
|
239 | }
|
240 | listening.obj.off(name, callback, this);
|
241 | }
|
242 | if (_.isEmpty(listeningTo)) {
|
243 | this._listeningTo = void 0;
|
244 | }
|
245 | return this;
|
246 | }
|
247 | trigger(name, ...args) {
|
248 | if (!this._events) {
|
249 | return this;
|
250 | }
|
251 | if (name instanceof Event) {
|
252 | triggerApi(this._events, name.name, void 0, [name], (events, args) => {
|
253 | let ev, i = -1, l = events.length;
|
254 | while (++i < l) {
|
255 | if (name.isPropagationStopped) {
|
256 | return;
|
257 | }
|
258 | ev = events[i];
|
259 | ev.callback.apply(ev.ctx, args);
|
260 | }
|
261 | });
|
262 | }
|
263 | else {
|
264 | eventsApi(triggerApi, this._events, name, void 0, args);
|
265 | }
|
266 | return this;
|
267 | }
|
268 | }
|
269 | exports.EventDispatcher = EventDispatcher;
|
270 |
|
\ | No newline at end of file |