forked from unconed/mathbox
-
Notifications
You must be signed in to change notification settings - Fork 7
/
binder.js
123 lines (94 loc) · 3.03 KB
/
binder.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
// Recycled from threestrap
module.exports = self = {
bind: function (context, globals) {
return function (key, object) {
// Prepare object
if (!object.__binds) {
object.__binds = [];
}
// Set base target
var fallback = context;
if (_.isArray(key)) {
fallback = key[0];
key = key[1];
}
// Match key
var match = /^([^.:]*(?:\.[^.:]+)*)?(?:\:(.*))?$/.exec(key);
var path = match[1].split(/\./g);
var name = path.pop();
var dest = match[2] || name;
// Whitelisted objects
var selector = path.shift();
var target = {
'this': object,
}[selector] || globals[selector] || context[selector] || fallback;
// Look up keys
while (target && (key = path.shift())) { target = target[key] };
// Attach event handler at last level
if (target && (target.on || target.addEventListener)) {
var callback = function (event) {
object[dest] && object[dest](event, context);
};
// Polyfill for both styles of event listener adders
self._polyfill(target, [ 'addEventListener', 'on' ], function (method) {
target[method](name, callback);
});
// Store bind for removal later
var bind = { target: target, name: name, callback: callback };
object.__binds.push(bind);
// Return callback
return callback;
}
else {
throw "Cannot bind '" + key + "' in " + this.__name;
}
};
},
unbind: function () {
return function (object) {
// Remove all binds belonging to object
if (object.__binds) {
object.__binds.forEach(function (bind) {
// Polyfill for both styles of event listener removers
self._polyfill(bind.target, [ 'removeEventListener', 'off' ], function (method) {
bind.target[method](bind.name, bind.callback);
});
}.bind(this));
object.__binds = [];
}
}
},
apply: function ( object ) {
THREE.EventDispatcher.prototype.apply(object);
object.trigger = self._trigger;
object.triggerOnce = self._triggerOnce;
object.on = object.addEventListener;
object.off = object.removeEventListener;
object.dispatchEvent = object.trigger;
},
////
_triggerOnce: function (event) {
this.trigger(event);
if (this._listeners) {
delete this._listeners[event.type]
}
},
_trigger: function (event) {
if (this._listeners === undefined) return;
var type = event.type;
var listeners = this._listeners[type];
if (listeners !== undefined) {
listeners = listeners.slice()
var length = listeners.length;
event.target = this;
for (var i = 0; i < length; i++) {
// add original target as parameter for convenience
listeners[i].call(this, event, this);
}
}
},
_polyfill: function (object, methods, callback) {
methods.map(function (method) { return object.method });
if (methods.length) callback(methods[0]);
},
};