This repository has been archived by the owner on Dec 5, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.js
141 lines (117 loc) · 3.48 KB
/
index.js
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
/*! (c) 2017 Andrea Giammarchi (ISC) */
var EventTarget = (function () {
'use strict';
var G = typeof global === typeof null ? global : self;
var findIndex = [].findIndex || function (callback, context) {
var i = this.length;
while (i--) {
if (callback.call(context, this[i])) return i;
}return i;
};
var defineProperty = Object.defineProperty;
// even if not unique each time, the used WeakMap
// is one and one only so it's not required to grant
// uniqueness per each instance. This is enough.
var UID = '__event-target__' + Math.random();
var WeakMap = G.WeakMap || function WeakMap() {
return {
get: function get(obj) {
return obj[UID];
},
set: function set(obj, value) {
defineProperty(obj, UID, {
configurable: true,
value: value
});
}
};
};
var EventTarget = G.EventTarget;
try {
new EventTarget();
} catch (e) {
EventTarget = function () {
// used to relate instances to listeners
var wm = new WeakMap();
// get listeners or relate them once to the instance
var get = function get(self) {
return wm.get(self) || set(self);
};
var set = function set(self) {
var dictionary = new Null();
wm.set(self, dictionary);
return dictionary;
};
// define values as configurable
var define = function define(where, what) {
for (var key in what) {
defineProperty(where, key, {
configurable: true,
value: what[key]
});
}
};
// no need to transpile here, it's a very simple class
function EventTarget() {}
// EventTarget "class" definition
define(EventTarget.prototype, {
addEventListener: addEventListener,
dispatchEvent: dispatchEvent,
removeEventListener: removeEventListener
});
// dispatch event for each listener
function dispatch(info) {
var options = info.options;
if (options && options.once) {
removeEventListener.call(info.target, this.type, info.listener, info.options);
}
if (typeof info.listener === 'function') {
info.listener.call(info.target, this);
} else {
info.listener.handleEvent(this);
}
}
// search for a registered listener
function registered(info) {
return this === info.listener;
}
// public methods
function addEventListener(type, listener, options) {
var secret = get(this);
var listeners = secret[type] || (secret[type] = []);
if (findIndex.call(listeners, registered, listener) < 0) {
listeners.push({ target: this, listener: listener, options: options });
}
}
function dispatchEvent(event) {
var secret = get(this);
var listeners = secret[event.type];
if (listeners) {
define(event, {
currentTarget: this,
target: this
});
listeners.forEach(dispatch, event);
delete event.currentTarget;
delete event.target;
}
return true;
}
// used both as public and private method,
// to avoid method pollution/interception of private listeners
function removeEventListener(type, listener, options) {
var secret = get(this);
var listeners = secret[type];
if (listeners) {
var i = findIndex.call(listeners, registered, listener);
if (-1 < i) listeners.splice(i, 1);
}
}
// private "class"
function Null() {}
Null.prototype = Object.create(null);
return EventTarget;
}();
}
return EventTarget;
}());