oxjs/source/Ox.UI/js/Core/Event.js
2012-06-30 11:24:03 +02:00

178 lines
6.1 KiB
JavaScript

'use strict';
/*@
Ox.Event <o> Used internally for events
@*/
Ox.Event = (function() {
var eventHandlers = [],
that = {};
function log(data, event, self) {
var element = this,
handlers = self.eventHandlers ? self.eventHandlers[event] : [];
if (!Ox.contains([
'mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick',
'dragstart', 'drag', 'dragenter', 'dragleave', 'dragpause', 'dragend',
'draganddropstart', 'draganddrop', 'draganddropenter', 'draganddropleave', 'draganddropend',
'playing', 'position', 'progress'
], event)) {
try {
data = JSON.stringify(data)
} catch(e) {}
Ox.print(
'EVENT',
element.oxid,
'"' + element[0].className.split(' ').filter(function(className) {
return /^Ox/.test(className);
}).map(function(className) {
return className.replace(/^Ox/, '');
}).join(' ') + '"',
event,
data,
handlers.length,
handlers.map(function(handler) {
return handler.toString().split('\n').shift();
})
);
}
}
/*@
.bind <f> Adds an event handler
(callback) -> <o> Ox.Event
(self, callback) -> <o> Ox.Event
(self, event, callback) -> <o> Ox.Event
(self, {event: callback, ...}) -> <o> Ox.Event
self <o> The element's shared private object
callback <f> Callback function
data <o> Event data
event <s> Event name
element <o> Element
event <s> Event name
Event names can be namespaced, like `'click.foo'`
*/
that.bind = function() {
var args = Ox.toArray(arguments), once, self;
if (args.length == 1) {
eventHandlers.push(args[0])
} else {
self = args.shift();
once = Ox.isBoolean(Ox.last(args)) ? args.pop() : false;
args = Ox.isFunction(args[0]) ? {'*': args[0]} : Ox.makeObject(args);
if (Ox.len(args) && !self.eventHandlers) {
self.eventHandlers = {};
}
Ox.forEach(args, function(handler, event) {
handler.once = once;
self.eventHandlers[event] = (
self.eventHandlers[event] || []
).concat(handler);
});
}
return that;
};
/*@
.bindOnce <f> Adds an event handler that fires once
(self, callback) -> <o> Ox.Event
(self, event, callback) -> <o> Ox.Event
(self, {event: callback, ...}) -> <o> Ox.Event
self <o> The element's shared private object
callback <f> Callback function
data <o> Event data
event <s> Event name
element <o> Element
event <s> Event name
Event names can be namespaced, like `'click.foo'`
*/
that.bindOnce = function() {
return that.bind.apply(null, Ox.slice(arguments).concat(true));
};
/*@
.log <f> Turns event logging on or off
(enabled) -> <o> Ox.Event
enabled <b> Enables (`true`) or disables (`false`) event logging
*/
that.log = function(enabled) {
that[enabled ? 'bind' : 'unbind'](log);
return that;
};
/*@
.trigger <f> Triggers an event
(self, event) -> <o> Ox.Event
(self, event, data) -> <o> Ox.Event
(self, {event: data, ...}) -> Ox.Event
self <o> The element's shared private object
event <s> Event name
data <o> Event data
*/
that.trigger = function(self) {
var element = this;
if (self.eventHandlers) {
Ox.forEach(Ox.makeObject(
Ox.slice(arguments, 1)
), function(data, event) {
var triggered = event.split('.');
triggered.map(function(v, i) {
return triggered.slice(0, i + 1).join('.');
}).concat('*').forEach(function(triggered) {
var handlers = self.eventHandlers[triggered];
handlers && handlers.forEach(function(handler) {
handler.once && that.unbind(self, triggered, handler);
handler.call(element, data || {}, event);
});
});
eventHandlers.forEach(function(handler) {
handler.call(element, data || {}, event, element);
});
});
}
return that;
};
/*@
.unbind <f> Removes an event handler
(callback) -> <o> Ox.Event
(self) -> <o> Ox.Event
(self, callback) -> <o> Ox.Event
(self, event) -> <o> Ox.Event
(self, event, callback) -> <o> Ox.Event
(self, {event: callback, ...}) -> <o> Ox.Event
self <o> The element's shared private object
callback <f> Callback function
event <s> Event name
*/
that.unbind = function() {
var args = Ox.slice(arguments), self;
if (Ox.isFunction(args[0])) {
eventHandlers.forEach(function(handler) {
handler === args[0] && eventHandlers.splice(i, 1);
});
} else if ((self = args.shift()).eventHandlers) {
if (args.length == 0) {
delete self.eventHandlers;
} else {
if (Ox.isFunction(args[0])) {
args = {'*': args[0]};
}
Ox.forEach(Ox.makeObject(args), function(unbind, event) {
if (Ox.isUndefined(unbind)) {
delete self.eventHandlers[event];
} else {
self.eventHandlers[event].forEach(function(handler, i) {
handler === unbind && self.eventHandlers[event].splice(i, 1);
});
}
});
}
}
return that;
};
return that;
}());