1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/* global varienEvents */
/* eslint-disable strict */
define([
'Magento_Ui/js/modal/alert',
'prototype'
], function (alert) {
// from http://www.someelement.com/2007/03/eventpublisher-custom-events-la-pubsub.html
window.varienEvents = Class.create();
varienEvents.prototype = {
/**
* Initialize.
*/
initialize: function () {
this.arrEvents = {};
this.eventPrefix = '';
},
/**
* Attaches a {handler} function to the publisher's {eventName} event for execution upon the event firing
* @param {String} eventName
* @param {Function} handler
* @param {Boolean} [asynchFlag] - Defaults to false if omitted.
* Indicates whether to execute {handler} asynchronously (true) or not (false).
*/
attachEventHandler: function (eventName, handler) {
var asynchVar, handlerObj;
if (typeof handler == 'undefined' || handler == null) {
return;
}
eventName += this.eventPrefix;
// using an event cache array to track all handlers for proper cleanup
if (this.arrEvents[eventName] == null) {
this.arrEvents[eventName] = [];
}
//create a custom object containing the handler method and the asynch flag
asynchVar = arguments.length > 2 ? arguments[2] : false;
handlerObj = {
method: handler,
asynch: asynchVar
};
this.arrEvents[eventName].push(handlerObj);
},
/**
* Removes a single handler from a specific event
* @param {String} eventName - The event name to clear the handler from
* @param {Function} handler - A reference to the handler function to un-register from the event
*/
removeEventHandler: function (eventName, handler) {
eventName += this.eventPrefix;
if (this.arrEvents[eventName] != null) {
this.arrEvents[eventName] = this.arrEvents[eventName].reject(function (obj) {
return obj.method == handler; //eslint-disable-line eqeqeq
});
}
},
/**
* Removes all handlers from a single event
* @param {String} eventName - The event name to clear handlers from
*/
clearEventHandlers: function (eventName) {
eventName += this.eventPrefix;
this.arrEvents[eventName] = null;
},
/**
* Removes all handlers from ALL events
*/
clearAllEventHandlers: function () {
this.arrEvents = {};
},
/**
* Collect and modify value of arg synchronously in succession and return its new value.
* In order to use, call attachEventHandler and add function handlers with eventName.
* Then call fireEventReducer with eventName and any argument to have its value accumulatively modified.
* Event handlers will be applied to argument in order of first attached to last attached.
* @param {String} eventName
* @param {*} arg
*/
fireEventReducer: function (eventName, arg) {
var evtName = eventName + this.eventPrefix,
result = arg,
len,
i;
if (!this.arrEvents[evtName]) {
return result;
}
len = this.arrEvents[evtName].length; //optimization
for (i = 0; i < len; i++) {
/* eslint-disable max-depth */
try {
result = this.arrEvents[evtName][i].method(result);
} catch (e) {
if (this.id) {
alert({
content: 'error: error in ' + this.id + '.fireEventReducer():\n\nevent name: ' +
eventName + '\n\nerror message: ' + e.message
});
} else {
alert({
content: 'error: error in [unknown object].fireEventReducer():\n\nevent name: ' +
eventName + '\n\nerror message: ' + e.message
});
}
}
/* eslint-disable max-depth */
}
return result;
},
/**
* Fires the event {eventName}, resulting in all registered handlers to be executed.
* It also collects and returns results of all non-asynchronous handlers
* @param {String} eventName - The name of the event to fire
* @param {Object} [args] - Any object, will be passed into the handler function as the only argument
* @return {Array}
*/
fireEvent: function (eventName) {
var evtName = eventName + this.eventPrefix,
results = [],
result, len, i, eventArgs, method, eventHandler;
if (this.arrEvents[evtName] != null) {
len = this.arrEvents[evtName].length; //optimization
for (i = 0; i < len; i++) {
/* eslint-disable max-depth */
try {
if (arguments.length > 1) {
if (this.arrEvents[evtName][i].asynch) {
eventArgs = arguments[1];
method = this.arrEvents[evtName][i].method.bind(this);
setTimeout(function () { //eslint-disable-line no-loop-func
method(eventArgs);
}, 10);
} else {
result = this.arrEvents[evtName][i].method(arguments[1]);
}
} else {
if (this.arrEvents[evtName][i].asynch) { //eslint-disable-line no-lonely-if
eventHandler = this.arrEvents[evtName][i].method;
setTimeout(eventHandler, 1);
} else if (
this.arrEvents &&
this.arrEvents[evtName] &&
this.arrEvents[evtName][i] &&
this.arrEvents[evtName][i].method
) {
result = this.arrEvents[evtName][i].method();
}
}
results.push(result);
}
catch (e) {
if (this.id) {
alert({
content: 'error: error in ' + this.id + '.fireEvent():\n\nevent name: ' +
eventName + '\n\nerror message: ' + e.message
});
} else {
alert({
content: 'error: error in [unknown object].fireEvent():\n\nevent name: ' +
eventName + '\n\nerror message: ' + e.message
});
}
}
/* eslint-enable max-depth */
}
}
return results;
}
};
window.varienGlobalEvents = new varienEvents(); //jscs:ignore requireCapitalizedConstructors
return window.varienGlobalEvents;
});