2011-11-11 12:29:28 -05:00
|
|
|
/*
|
2013-01-28 21:03:27 -05:00
|
|
|
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
2011-11-11 12:29:28 -05:00
|
|
|
* http://paperjs.org/
|
|
|
|
*
|
2014-01-03 19:47:16 -05:00
|
|
|
* Copyright (c) 2011 - 2014, Juerg Lehni & Jonathan Puckey
|
|
|
|
* http://scratchdisk.com/ & http://jonathanpuckey.com/
|
2011-11-11 12:29:28 -05:00
|
|
|
*
|
|
|
|
* Distributed under the MIT license. See LICENSE file for details.
|
|
|
|
*
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2012-11-06 16:34:46 -05:00
|
|
|
/**
|
2014-10-08 08:13:08 -04:00
|
|
|
* @name Emitter
|
2012-11-06 16:34:46 -05:00
|
|
|
* @namespace
|
2013-05-06 23:56:58 -04:00
|
|
|
* @private
|
2012-11-06 16:34:46 -05:00
|
|
|
*/
|
2014-10-08 08:13:08 -04:00
|
|
|
var Emitter = {
|
2014-10-08 08:57:56 -04:00
|
|
|
on: function(type, func) {
|
2014-08-16 13:24:54 -04:00
|
|
|
// If an object literal is passed, attach all callbacks defined in it
|
|
|
|
if (typeof type !== 'string') {
|
|
|
|
Base.each(type, function(value, key) {
|
2014-10-08 08:57:56 -04:00
|
|
|
this.on(key, value);
|
2014-08-16 13:24:54 -04:00
|
|
|
}, this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var entry = this._eventTypes[type];
|
|
|
|
if (entry) {
|
2014-10-08 08:57:56 -04:00
|
|
|
var handlers = this._callbacks = this._callbacks || {};
|
2014-08-16 13:24:54 -04:00
|
|
|
handlers = handlers[type] = handlers[type] || [];
|
2014-10-08 08:57:56 -04:00
|
|
|
if (handlers.indexOf(func) === -1) { // Not added yet, add it now
|
2014-08-16 13:24:54 -04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2011-11-11 12:29:28 -05:00
|
|
|
|
2014-10-08 08:57:56 -04:00
|
|
|
off: function(type, func) {
|
2014-08-16 13:24:54 -04:00
|
|
|
// If an object literal is passed, detach all callbacks defined in it
|
|
|
|
if (typeof type !== 'string') {
|
|
|
|
Base.each(type, function(value, key) {
|
2014-10-08 08:57:56 -04:00
|
|
|
this.off(key, value);
|
2014-08-16 13:24:54 -04:00
|
|
|
}, this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var entry = this._eventTypes[type],
|
2014-10-08 08:57:56 -04:00
|
|
|
handlers = this._callbacks && this._callbacks[type],
|
2014-08-16 13:24:54 -04:00
|
|
|
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.
|
2014-10-08 08:57:56 -04:00
|
|
|
if (!func || (index = handlers.indexOf(func)) !== -1
|
|
|
|
&& handlers.length === 1) {
|
2014-08-16 13:24:54 -04:00
|
|
|
if (entry.uninstall)
|
|
|
|
entry.uninstall.call(this, type);
|
2014-10-08 08:57:56 -04:00
|
|
|
delete this._callbacks[type];
|
|
|
|
} else if (index !== -1) {
|
2014-08-16 13:24:54 -04:00
|
|
|
// Just remove this one handler
|
|
|
|
handlers.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2011-11-11 12:29:28 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
once: function(type, func) {
|
2014-10-08 08:57:56 -04:00
|
|
|
this.on(type, function() {
|
2014-08-16 13:24:54 -04:00
|
|
|
func.apply(this, arguments);
|
2014-10-08 08:57:56 -04:00
|
|
|
this.off(type, func);
|
2014-08-16 13:24:54 -04:00
|
|
|
});
|
|
|
|
},
|
2013-05-06 23:57:08 -04:00
|
|
|
|
2014-10-08 08:57:56 -04:00
|
|
|
emit: function(type, event) {
|
2014-08-16 13:24:54 -04:00
|
|
|
// Returns true if fired, false otherwise
|
2014-10-08 08:57:56 -04:00
|
|
|
var handlers = this._callbacks && this._callbacks[type];
|
2014-08-16 13:24:54 -04:00
|
|
|
if (!handlers)
|
|
|
|
return false;
|
2014-10-08 10:36:22 -04:00
|
|
|
var args = [].slice.call(arguments, 1);
|
2014-08-16 13:24:54 -04:00
|
|
|
for (var i = 0, l = handlers.length; i < l; i++) {
|
|
|
|
// When the handler function returns false, prevent the default
|
|
|
|
// behaviour and stop propagation of the event by calling stop()
|
2014-10-08 10:36:22 -04:00
|
|
|
if (handlers[i].apply(this, args) === false
|
2014-08-16 13:24:54 -04:00
|
|
|
&& event && event.stop) {
|
|
|
|
event.stop();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
},
|
2011-11-11 12:29:28 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
responds: function(type) {
|
2014-10-08 08:57:56 -04:00
|
|
|
return !!(this._callbacks && this._callbacks[type]);
|
2014-08-16 13:24:54 -04:00
|
|
|
},
|
2011-11-11 13:49:31 -05:00
|
|
|
|
2014-10-08 08:57:56 -04:00
|
|
|
// Keep deprecated methods around from previous Callback interface.
|
|
|
|
attach: '#on',
|
|
|
|
detach: '#off',
|
|
|
|
fire: '#emit',
|
2013-05-06 23:56:58 -04:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
_installEvents: function(install) {
|
2014-10-08 08:57:56 -04:00
|
|
|
var handlers = this._callbacks,
|
2014-08-16 13:24:54 -04:00
|
|
|
key = install ? 'install' : 'uninstall';
|
|
|
|
for (var type in handlers) {
|
|
|
|
if (handlers[type].length > 0) {
|
|
|
|
var entry = this._eventTypes[type],
|
|
|
|
func = entry[key];
|
|
|
|
if (func)
|
|
|
|
func.call(this, type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2013-12-08 14:40:30 -05:00
|
|
|
|
2014-08-16 13:24:54 -04:00
|
|
|
statics: {
|
|
|
|
// Override inject() so that sub-classes automatically add the accessors
|
|
|
|
// for the event handler functions (e.g. #onMouseDown) for each property
|
2014-10-21 17:52:53 -04:00
|
|
|
// NOTE: This needs to be defined in the first injection scope, as for
|
|
|
|
// simplicity, we don't loop through all of them here.
|
|
|
|
inject: function inject(src) {
|
|
|
|
var 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) {
|
|
|
|
// Detach the previous event, if there was one.
|
|
|
|
var prev = this[name];
|
|
|
|
if (prev)
|
|
|
|
this.off(type, prev);
|
|
|
|
if (func)
|
|
|
|
this.on(type, func);
|
|
|
|
this[name] = func;
|
|
|
|
};
|
|
|
|
});
|
|
|
|
src._eventTypes = types;
|
2014-08-16 13:24:54 -04:00
|
|
|
}
|
2014-10-21 17:52:53 -04:00
|
|
|
return inject.base.apply(this, arguments);
|
2014-08-16 13:24:54 -04:00
|
|
|
}
|
|
|
|
}
|
2011-11-11 12:29:28 -05:00
|
|
|
};
|