'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 an event handler (callback) -> Ox.Event (self, callback) -> Ox.Event (self, event, callback) -> Ox.Event (self, {event: callback, ...}) -> Ox.Event 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(handler, event) { handler.once = once; self.eventHandlers[event] = ( self.eventHandlers[event] || [] ).concat(handler); }); } return that; }; /*@ .bindOnce Adds an event handler that fires once (self, callback) -> Ox.Event (self, event, callback) -> Ox.Event (self, {event: callback, ...}) -> Ox.Event 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 (self, event, data) -> Ox.Event (self, {event: data, ...}) -> Ox.Event self The element's shared private object event Event name data 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 Removes an event handler (callback) -> Ox.Event (self) -> Ox.Event (self, callback) -> Ox.Event (self, event) -> Ox.Event (self, event, callback) -> Ox.Event (self, {event: callback, ...}) -> Ox.Event self The element's shared private object callback Callback function event 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; }());