'use strict'; /*@ Ox.Event 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 Adds event handler(s) (callback) -> Ox.Event Adds a global event handler (self, callback) -> Ox.Event Adds a catch-all handler (self, event, callback) -> Ox.Event Adds a handler for a single event (self, {event: callback, ...}) -> Ox.Event Adds handlers for multiple events self The element's shared private object callback Callback function data Event data event Event name element Element event 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(callback, event) { self.eventHandlers[event] = ( self.eventHandlers[event] || [] ).concat({callback: callback, once: once}); }); } return that; }; /*@ .bindOnce Adds event handler(s) that run(s) only once (self, callback) -> Ox.Event Adds a catch-all handler (self, event, callback) -> Ox.Event Adds an event handler for a single event (self, {event: callback, ...}) -> Ox.Event Adds event handlers for multiple events self The element's shared private object callback Callback function data Event data event Event name element Element event Event name Event names can be namespaced, like `'click.foo'` */ that.bindOnce = function() { return that.bind.apply(null, Ox.slice(arguments).concat(true)); }; /*@ .log Turns event logging on or off (enabled) -> Ox.Event enabled Enables (`true`) or disables (`false`) event logging */ that.log = function(enabled) { that[enabled ? 'bind' : 'unbind'](log); return that; }; /*@ .trigger Triggers an event (self, event) -> Ox.Event Triggers an event (self, event, data) -> Ox.Event Triggers an event with data (self, {event: data, ...}) -> Ox.Event Triggers multiple events with data self The element's shared private object event Event name data Event data */ that.trigger = function(self) { var args = arguments, element = this; self.eventHandlers && setTimeout(function() { Ox.forEach(Ox.makeObject(Ox.slice(args, 1)), function(data, event) { var triggered = event.split('.'); eventHandlers.forEach(function(callback) { callback.call(element, data || {}, event, element); }); 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, i) { handler.once && handlers.splice(i, 1); handler.callback.call(element, data || {}, event); }); }); }); }); return that; }; /*@ .unbind Removes an event handler () -> Ox.Event Removes all global handlers (callback) -> Ox.Event Removes a global handler (self) -> Ox.Event Removes all handlers (self, callback) -> Ox.Event Removes a specific catch-all handler (self, event) -> Ox.Event Remove all handlers for a single event (self, event, callback) -> Ox.Event Removes a specific handler for a single event (self, {event: callback, ...}) -> Ox.Event Removes specific event handlers for multiple events self The element's shared private object callback Callback function event Event name */ that.unbind = function() { var args = Ox.slice(arguments), self; if (args.length == 0) { eventHandlers = []; } else if (Ox.isFunction(args[0])) { eventHandlers.forEach(function(handler, i) { 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(callback, event) { if (Ox.isUndefined(callback)) { delete self.eventHandlers[event]; } else { self.eventHandlers[event].forEach(function(handler, i) { if (handler.callback === callback) { self.eventHandlers[event].splice(i, 1); } }); } }); } } return that; }; return that; }());