UNPKG

5.8 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.IMA_EVENT = undefined;
7
8var _EventBus = require('./EventBus');
9
10var _EventBus2 = _interopRequireDefault(_EventBus);
11
12var _GenericError = require('../error/GenericError');
13
14var _GenericError2 = _interopRequireDefault(_GenericError);
15
16var _Window = require('../window/Window');
17
18var _Window2 = _interopRequireDefault(_Window);
19
20function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
22/**
23 * Global name of IMA.js custom event.
24 *
25 * @const
26 * @type {string}
27 */
28const IMA_EVENT = exports.IMA_EVENT = '$IMA.CustomEvent';
29
30/**
31 * Helper for custom events.
32 *
33 * It offers public methods for firing custom events and two methods for
34 * catching events (e.g. inside view components).
35 */
36// @client-side
37
38class EventBusImpl extends _EventBus2.default {
39 static get $dependencies() {
40 return [_Window2.default];
41 }
42
43 /**
44 * Initializes the custom event helper.
45 *
46 * @param {Window} window The IMA window helper.
47 */
48 constructor(window) {
49 super();
50
51 /**
52 * The IMA window helper.
53 *
54 * @type {Window}
55 */
56 this._window = window;
57
58 /**
59 * Map of listeners provided to the public API of this event bus to a
60 * map of event targets to a map of event names to actual listeners
61 * bound to the native API.
62 *
63 * The "listen all" event listeners are not registered in this map.
64 *
65 * @type {WeakMap<
66 * function(Event),
67 * WeakMap<EventTarget, Map<string, function(Event)>>
68 * >}
69 */
70 this._listeners = new WeakMap();
71
72 /**
73 * Map of event targets to listeners executed on all IMA.js event bus
74 * events.
75 *
76 * @type {WeakMap<EventTarget, WeakSet<function(Event)>>}
77 */
78 this._allEventListeners = new WeakMap();
79 }
80
81 /**
82 * @inheritdoc
83 */
84 fire(eventTarget, eventName, data, options = {}) {
85 var eventInitialization = {};
86 var params = { detail: { eventName, data } };
87 var defaultOptions = { bubbles: true, cancelable: true };
88 Object.assign(eventInitialization, defaultOptions, options, params);
89
90 var event = this._window.createCustomEvent(IMA_EVENT, eventInitialization);
91
92 if (eventTarget && typeof eventTarget.dispatchEvent !== 'undefined') {
93 eventTarget.dispatchEvent(event);
94 } else {
95 throw new _GenericError2.default(`ima.event.EventBusImpl.fire: The EventSource ` + `${eventTarget} is not defined or can not dispatch event ` + `'${eventName}' (data: ${data}).`, { eventTarget, eventName, data, eventInitialization });
96 }
97
98 return this;
99 }
100
101 /**
102 * @inheritdoc
103 */
104 listenAll(eventTarget, listener) {
105 this._window.bindEventListener(eventTarget, IMA_EVENT, listener);
106
107 if (!this._allEventListeners.has(eventTarget)) {
108 this._allEventListeners.set(eventTarget, new WeakSet());
109 }
110 this._allEventListeners.get(eventTarget).add(listener);
111
112 return this;
113 }
114
115 /**
116 * @inheritdoc
117 */
118 listen(eventTarget, eventName, listener) {
119 if (!this._listeners.has(listener)) {
120 this._listeners.set(listener, new WeakMap());
121 }
122
123 var targetToEventName = this._listeners.get(listener);
124 if (!targetToEventName.has(eventTarget)) {
125 targetToEventName.set(eventTarget, new Map());
126 }
127
128 var eventNameToNativeListener = targetToEventName.get(eventTarget);
129 var nativeListener = event => {
130 if (event.detail.eventName === eventName) {
131 listener(event);
132 }
133 };
134 eventNameToNativeListener.set(eventName, nativeListener);
135
136 this._window.bindEventListener(eventTarget, IMA_EVENT, nativeListener);
137
138 return this;
139 }
140
141 /**
142 * @inheritdoc
143 */
144 unlistenAll(eventTarget, listener) {
145 this._window.unbindEventListener(eventTarget, IMA_EVENT, listener);
146
147 var listenerRegistered = this._allEventListeners.has(eventTarget) && this._allEventListeners.get(eventTarget).has(listener);
148 if (listenerRegistered) {
149 this._allEventListeners.get(eventTarget).delete(listener);
150 }
151
152 if ($Debug) {
153 if (!listenerRegistered) {
154 console.warn('The provided listener is not registered on the ' + 'specified event target');
155 }
156 }
157
158 return this;
159 }
160
161 /**
162 * @inheritdoc
163 */
164 unlisten(eventTarget, eventName, listener) {
165 if (!this._listeners.has(listener)) {
166 if ($Debug) {
167 console.warn('The provided listener is not bound to listen for the ' + 'specified event on the specified event target.');
168 }
169
170 return this;
171 }
172
173 var targets = this._listeners.get(listener);
174 if (!targets.has(eventTarget)) {
175 if ($Debug) {
176 console.warn('The provided listener is not bound to listen for the ' + 'specified event on the specified event target.');
177 }
178
179 return this;
180 }
181
182 var eventNameToNativeListener = targets.get(eventTarget);
183 if (!eventNameToNativeListener.has(eventName)) {
184 if ($Debug) {
185 console.warn('The provided listener is not bound to listen for the ' + 'specified event on the specified event target.');
186 }
187
188 return this;
189 }
190
191 var nativeListener = eventNameToNativeListener.get(eventName);
192 this._window.unbindEventListener(eventTarget, IMA_EVENT, nativeListener);
193
194 eventNameToNativeListener.delete(eventName);
195 if (eventNameToNativeListener.size) {
196 return this;
197 }
198
199 targets.delete(eventTarget);
200
201 return this;
202 }
203}
204exports.default = EventBusImpl;
205
206typeof $IMA !== 'undefined' && $IMA !== null && $IMA.Loader && $IMA.Loader.register('ima/event/EventBusImpl', [], function (_export, _context) {
207 'use strict';
208 return {
209 setters: [],
210 execute: function () {
211 _export('IMA_EVENT', exports.IMA_EVENT);
212 _export('default', exports.default);
213 }
214 };
215});