1 /**
  2  * Event
  3  *
  4  * Event api wrapper
  5  * @todo Add method for triggering events
  6  */
  7 (function (undefined){
  8 
  9 	"use strict";
 10 
 11 	var _add_remove, e, _attach_delegate;
 12 
 13 	_add_remove = function (sel, event, callback, add)
 14 	{
 15 		var i, len;
 16 
 17 		if(sel === undefined)
 18 		{
 19 			return null;
 20 		}
 21 
 22 		// Multiple events? Run recursively!
 23 		if ( ! event.match(/^([\w\-]+)$/))
 24 		{
 25 			event = event.split(" ");
 26 
 27 			len = event.length;
 28 
 29 			for (i = 0; i < len; i++)
 30 			{
 31 				_add_remove(sel, event[i], callback, add);
 32 			}
 33 
 34 			return;
 35 		}
 36 
 37 		// Bind the event
 38 		(add === true)
 39 			? sel.addEventListener(event, callback, false)
 40 			: sel.removeEventListener(event, callback, false);
 41 	};
 42 
 43 	_attach_delegate = function(sel, target, event, callback)
 44 	{
 45 		// attach the listener to the parent object
 46 		_add_remove(sel, event, function(e){
 47 
 48 			var elem, t;
 49 
 50 			// Get the live version of the target selector
 51 			t = $_.$(target, sel);
 52 
 53 			// Check each element to see if it matches the target
 54 			for(elem in t)
 55 			{
 56 				// Fire target callback when event bubbles from target
 57 				if(e.target == t[elem])
 58 				{
 59 					// Trigger the event callback
 60 					callback.call(t[elem], e);
 61 
 62 					// Stop event propegation
 63 					e.stopPropagation();
 64 				}
 65 			}
 66 
 67 		}, true);
 68 	};
 69 
 70 	// --------------------------------------------------------------------------
 71 
 72 	/**
 73 	 * Event Listener module
 74 	 *
 75 	 * @namespace
 76 	 * @name event
 77 	 * @memberOf $_
 78 	 */
 79 	e = {
 80 		/**
 81 		 * Adds an event that returns a callback when triggered on the selected
 82 		 * event and selector
 83 		 *
 84 		 * @memberOf $_.event
 85 		 * @name add
 86 		 * @function
 87 		 * @example Eg. $_("#selector").event.add("click", do_something());
 88 		 * @param string event
 89 		 * @param function callback
 90 		 */
 91 		add: function (event, callback)
 92 		{
 93 			$_.each(function(e){
 94 				_add_remove(e, event, callback, true);
 95 			});
 96 		},
 97 		/**
 98 		 * Removes an event bound the the specified selector, event type, and callback
 99 		 *
100 		 * @memberOf $_.event
101 		 * @name remove
102 		 * @function
103 		 * @example Eg. $_("#selector").event.remove("click", do_something());
104 		 * @param string event
105 		 * @param string callback
106 		 */
107 		remove: function (event, callback)
108 		{
109 			$_.each(function(e){
110 				_add_remove(e, event, callback, false);
111 			});
112 		},
113 		/**
114 		 * Binds a persistent event to the document
115 		 *
116 		 * @memberOf $_.event
117 		 * @name live
118 		 * @function
119 		 * @example Eg. $_.event.live(".button", "click", do_something());
120 		 * @param string target
121 		 * @param string event
122 		 * @param function callback
123 		 */
124 		live: function (target, event, callback)
125 		{
126 			_attach_delegate(document.documentElement, target, event, callback);
127 		},
128 		/**
129 		 * Binds an event to a parent object
130 		 *
131 		 * @memberOf $_.event
132 		 * @name delegate
133 		 * @function
134 		 * @example Eg. $_("#parent").delegate(".button", "click", do_something());
135 		 * @param string target
136 		 * @param string event_type
137 		 * @param function callback
138 		 */
139 		delegate: function (target, event, callback)
140 		{
141 			$_.each(function(e){
142 				_attach_delegate(e, target, event, callback);
143 			});
144 		}
145 	};
146 
147 	$_.ext('event', e);
148 
149 }());