forked from paperjs/paper.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCallback.js
More file actions
140 lines (133 loc) · 3.97 KB
/
Copy pathCallback.js
File metadata and controls
140 lines (133 loc) · 3.97 KB
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
/*
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
* http://lehni.org/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
/**
* @name Callback
* @namespace
* @private
*/
var Callback = {
attach: function(type, func) {
// If an object literal is passed, attach all callbacks defined in it
if (typeof type !== 'string') {
Base.each(type, function(value, key) {
this.attach(key, value);
}, this);
return;
}
var entry = this._eventTypes[type];
if (entry) {
var handlers = this._handlers = this._handlers || {};
handlers = handlers[type] = handlers[type] || [];
if (handlers.indexOf(func) == -1) { // Not added yet, add it now
handlers.push(func);
// See if this is the first handler that we're attaching, and
// call install if defined.
if (entry.install && handlers.length == 1)
entry.install.call(this, type);
}
}
},
detach: function(type, func) {
// If an object literal is passed, detach all callbacks defined in it
if (typeof type !== 'string') {
Base.each(type, function(value, key) {
this.detach(key, value);
}, this);
return;
}
var entry = this._eventTypes[type],
handlers = this._handlers && this._handlers[type],
index;
if (entry && handlers) {
// See if this is the last handler that we're detaching (or if we
// are detaching all handlers), and call uninstall if defined.
if (!func || (index = handlers.indexOf(func)) != -1
&& handlers.length == 1) {
if (entry.uninstall)
entry.uninstall.call(this, type);
delete this._handlers[type];
} else if (index != -1) {
// Just remove this one handler
handlers.splice(index, 1);
}
}
},
once: function(type, func) {
this.attach(type, function() {
func.apply(this, arguments);
this.detach(type, func);
});
},
fire: function(type, event) {
// Returns true if fired, false otherwise
var handlers = this._handlers && this._handlers[type];
if (!handlers)
return false;
var args = [].slice.call(arguments, 1);
Base.each(handlers, function(func) {
// When the handler function returns false, prevent the default
// behaviour of the event by calling stop() on it
if (func.apply(this, args) === false && event && event.stop)
event.stop();
}, this);
return true;
},
responds: function(type) {
return !!(this._handlers && this._handlers[type]);
},
// Install jQuery-style aliases to our event handler methods
on: '#attach',
off: '#detach',
trigger: '#fire',
statics: {
// Override inject() so that sub-classes automatically add the accessors
// for the event handler functions (e.g. #onMouseDown) for each property
inject: function inject(/* src, ... */) {
for (var i = 0, l = arguments.length; i < l; i++) {
var src = arguments[i],
events = src._events;
if (events) {
// events can either be an object literal or an array of
// strings describing the on*-names.
// We need to map lowercased event types to the event
// entries represented by these on*-names in _events.
var types = {};
Base.each(events, function(entry, key) {
var isString = typeof entry === 'string',
name = isString ? entry : key,
part = Base.capitalize(name),
type = name.substring(2).toLowerCase();
// Map the event type name to the event entry.
types[type] = isString ? {} : entry;
// Create getters and setters for the property
// with the on*-name name:
name = '_' + name;
src['get' + part] = function() {
return this[name];
};
src['set' + part] = function(func) {
if (func) {
this.attach(type, func);
} else if (this[name]) {
this.detach(type, this[name]);
}
this[name] = func;
};
});
src._eventTypes = types;
}
inject.base.call(this, src);
}
return this;
}
}
};