'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 Add a global event handler (self, callback) -> Ox.Event Add a catch-all event handler (self, event, callback) -> Ox.Event Add an event handler for a single event (self, {event: callback, ...}) -> Ox.Event Add 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.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 an event handler that fires once (self, callback) -> Ox.Event Add a catch-all event handler (self, event, callback) -> Ox.Event Add an event handler for a single event (self, {event: callback, ...}) -> Ox.Event Add 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 Trigger an event (self, event, data) -> Ox.Event Trigger an event with event data (self, {event: data, ...}) -> Ox.Event Trigger multiple events with event data 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, i) { handler.once && handlers.splice(i, 1); handler.callback.call(element, data || {}, event); }); }); eventHandlers.forEach(function(callback) { callback.call(element, data || {}, event, element); }); }); } return that; }; /*@ .unbind Removes an event handler () -> Ox.Event Remove all global event handlers (callback) -> Ox.Event Remove a global event handler (self) -> Ox.Event Remove all event handlers (self, callback) -> Ox.Event Unbind a specific catch-all event handler (self, event) -> Ox.Event Unbind all event handlers for a single event (self, event, callback) -> Ox.Event Unbind a specific event handler for a single event (self, {event: callback, ...}) -> Ox.Event Unbind 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) { 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; }());