Allows to create custom events based on other custom events.
(function(){
[Element, Window, Document].invoke('implement', {hasEvent: function(event){
var events = this.retrieve('events'),
list = (events && events[event]) ? events[event].values : null;
if (list){
for (var i = list.length; i--;) if (i in list){
return true;
}
}
return false;
}});
var wrap = function(custom, method, extended, name){
method = custom[method];
extended = custom[extended];
return function(fn, customName){
if (!customName) customName = name;
if (extended && !this.hasEvent(customName)) extended.call(this, fn, customName);
if (method) method.call(this, fn, customName);
};
};
var inherit = function(custom, base, method, name){
return function(fn, customName){
base[method].call(this, fn, customName || name);
custom[method].call(this, fn, customName || name);
};
};
var events = Element.Events;
Element.defineCustomEvent = function(name, custom){
var base = events[custom.base];
custom.onAdd = wrap(custom, 'onAdd', 'onSetup', name);
custom.onRemove = wrap(custom, 'onRemove', 'onTeardown', name);
events[name] = base ? Object.append({}, custom, {
base: base.base,
condition: function(event){
return (!base.condition || base.condition.call(this, event)) &&
(!custom.condition || custom.condition.call(this, event));
},
onAdd: inherit(custom, base, 'onAdd', name),
onRemove: inherit(custom, base, 'onRemove', name)
}) : custom;
return this;
};
var loop = function(name){
var method = 'on' + name.capitalize();
Element[name + 'CustomEvents'] = function(){
Object.each(events, function(event, name){
if (event[method]) event[method].call(event, name);
});
};
return loop;
};
loop('enable')('disable');
})();