diff -r 000000000000 -r 40c8f766c9b8 src/cm/media/js/lib/yui/yui3.0.0/api/delegate.js.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui3.0.0/api/delegate.js.html Mon Nov 23 15:14:29 2009 +0100 @@ -0,0 +1,504 @@ + + + + + API: event delegate.js (YUI Library) + + + + + + + + + + +
+
+

Yahoo! UI Library

+

event  3.0.0

+ Yahoo! UI Library + > event + + > delegate.js (source view) +
+
+ Search: +
+   +
+
+
+
+ +
+
+
+
+
+ Filters + + + +
+
+ +
+ +
/**
+ * Adds event delegation support to the library.
+ * 
+ * @module event
+ * @submodule event-delegate
+ */
+
+var Event = Y.Event,
+	Lang = Y.Lang,
+
+	delegates = {},
+	
+	specialTypes = {
+		mouseenter: "mouseover",
+		mouseleave: "mouseout"
+	},
+
+	resolveTextNode = function(n) {
+	    try {
+	        if (n && 3 == n.nodeType) {
+	            return n.parentNode;
+	        }
+	    } catch(e) { }
+	    return n;
+	},
+
+    delegateHandler = function(delegateKey, e, el) {
+
+        var target = resolveTextNode((e.target || e.srcElement)), 
+            tests  = delegates[delegateKey],
+            spec, 
+			ename,
+			matched,
+			fn,
+			ev;
+
+
+		var getMatch = function(el, selector, container) {
+			
+			var returnVal;
+			
+			if (!el || el === container) {
+				returnVal = false;
+			}
+			else {
+				returnVal = Y.Selector.test(el, selector) ? el: getMatch(el.parentNode, selector, container);
+			}
+			
+			return returnVal;
+			
+		};
+
+
+        for (spec in tests) {
+
+            if (tests.hasOwnProperty(spec)) {
+
+                ename  = tests[spec];
+				fn	= tests.fn;
+				matched = null;
+
+
+				if (Y.Selector.test(target, spec, el)) {
+					matched = target;
+				}
+				else if (Y.Selector.test(target, ((spec.replace(/,/gi, " *,")) + " *"), el)) {
+						
+					//	The target is a descendant of an element matching 
+					//	the selector, so crawl up to find the ancestor that 
+					//	matches the selector
+					
+					matched = getMatch(target, spec, el);
+					
+				}
+
+
+				if (matched) {
+
+                    if (!ev) {
+                        ev = new Y.DOMEventFacade(e, el);
+                        ev.container = ev.currentTarget;
+                    }
+
+                    ev.currentTarget = Y.Node.get(matched);
+
+					Y.publish(ename, {
+			               contextFn: function() {
+			                   return ev.currentTarget;
+			               }
+			           });
+
+					if (fn) {
+						fn(ev, ename);
+					}
+					else {
+                    	Y.fire(ename, ev);								
+					}
+					
+				}
+
+            }
+        }
+
+    },
+
+	attach = function (type, key, element) {
+
+		var focusMethods = {
+				focus: Event._attachFocus,
+				blur: Event._attachBlur
+			},
+
+			attachFn = focusMethods[type],
+
+			args = [type, 
+			function (e) {
+	            delegateHandler(key, (e || window.event), element);
+			}, 
+			element];
+
+
+		if (attachFn) {
+			return attachFn(args, { capture: true, facade: false });
+		}
+		else {
+			return Event._attach(args, { facade: false });
+		}
+		
+	},
+
+    sanitize = Y.cached(function(str) {
+        return str.replace(/[|,:]/g, '~');
+    });
+
+/**
+ * Sets up event delegation on a container element.  The delegated event
+ * will use a supplied selector to test if the target or one of the
+ * descendants of the target match it.  The supplied callback function 
+ * will only be executed if a match was encountered, and, in fact, 
+ * will be executed for each element that matches if you supply an 
+ * ambiguous selector.
+ *
+ * The event object for the delegated event is supplied to the callback
+ * function.  It is modified slightly in order to support all properties
+ * that may be needed for event delegation.  'currentTarget' is set to
+ * the element that matched the delegation specifcation.  'container' is
+ * set to the element that the listener is bound to (this normally would
+ * be the 'currentTarget').
+ *
+ * @event delegate
+ * @param type {string} 'delegate'
+ * @param fn {function} the callback function to execute.  This function
+ * will be provided the event object for the delegated event.
+ * @param el {string|node} the element that is the delegation container
+ * @param delegateType {string} the event type to delegate
+ * @param spec {string} a selector that must match the target of the
+ * event.
+ * @param context optional argument that specifies what 'this' refers to.
+ * @param args* 0..n additional arguments to pass on to the callback function.
+ * These arguments will be added after the event object.
+ * @return {EventHandle} the detach handle
+ * @for YUI
+ * @deprecated use Y.delegate
+ */
+Y.Env.evt.plugins.delegate = {
+
+    on: function(type, fn, el, delegateType, spec) {
+
+        Y.log('delegate event is deprecated, use Y.delegate()', 'warn', 'deprecated');
+
+		var args = Y.Array(arguments, 0, true);
+		
+		args.splice(3, 1);
+		
+		args[0] = delegateType;
+
+		return Y.delegate.apply(Y, args);
+
+    }
+
+};
+
+
+/**
+ * Sets up event delegation on a container element.  The delegated event
+ * will use a supplied selector to test if the target or one of the
+ * descendants of the target match it.  The supplied callback function 
+ * will only be executed if a match was encountered, and, in fact, 
+ * will be executed for each element that matches if you supply an 
+ * ambiguous selector.
+ *
+ * The event object for the delegated event is supplied to the callback
+ * function.  It is modified slightly in order to support all properties
+ * that may be needed for event delegation.  'currentTarget' is set to
+ * the element that matched the delegation specifcation.  'container' is
+ * set to the element that the listener is bound to (this normally would
+ * be the 'currentTarget').
+ *
+ * @method delegate
+ * @param type {string} the event type to delegate
+ * @param fn {function} the callback function to execute.  This function
+ * will be provided the event object for the delegated event.
+ * @param el {string|node} the element that is the delegation container
+ * @param spec {string} a selector that must match the target of the
+ * event.
+ * @param context optional argument that specifies what 'this' refers to.
+ * @param args* 0..n additional arguments to pass on to the callback function.
+ * These arguments will be added after the event object.
+ * @return {EventHandle} the detach handle
+ * @for YUI
+ */
+Event.delegate = function (type, fn, el, spec) {
+
+    if (!spec) {
+        Y.log('delegate: no spec, nothing to do', 'warn', 'event');
+        return false;
+    }
+
+
+    var args = Y.Array(arguments, 0, true),	    
+		element = el,	// HTML element serving as the delegation container
+		availHandle;	
+
+
+	if (Lang.isString(el)) {
+		
+		//	Y.Selector.query returns an array of matches unless specified 
+		//	to return just the first match.  Since the primary use case for
+		//	event delegation is to use a single event handler on a container,
+		//	Y.delegate doesn't currently support being able to bind a 
+		//	single listener to multiple containers.
+		
+		element = Y.Selector.query(el, null, true);
+		
+		if (!element) { // Not found, check using onAvailable
+
+			availHandle = Event.onAvailable(el, function() {
+
+				availHandle.handle = Event.delegate.apply(Event, args);
+
+            }, Event, true, false);
+
+            return availHandle;
+			
+		}
+		
+	}
+
+
+	element = Y.Node.getDOMNode(element);
+
+
+	var	guid = Y.stamp(element),
+            
+        // The Custom Event for the delegation spec
+        ename = 'delegate:' + guid + type + sanitize(spec),
+
+        // The key to the listener for the event type and container
+        delegateKey = type + guid,
+
+		delegate = delegates[delegateKey],
+
+		domEventHandle,
+		
+		ceHandle,
+		
+		listeners;
+	
+
+    if (!delegate) {
+
+		delegate = {};
+
+		if (specialTypes[type]) {
+			
+			if (!Event._fireMouseEnter) {
+				Y.log("Delegating a " + type + " event requires the event-mouseenter submodule.", "error", "Event");
+				return false;				
+			}
+			
+			type = specialTypes[type];
+			delegate.fn = Event._fireMouseEnter;
+			
+		}
+
+		//	Create the DOM Event wrapper that will fire the Custom Event
+
+		domEventHandle = attach(type, delegateKey, element);
+
+
+		//	Hook into the _delete method for the Custom Event wrapper of this
+		//	DOM Event in order to clean up the 'delegates' map and unsubscribe
+		//	the associated Custom Event listeners fired by this DOM event
+		//	listener if/when the user calls "purgeElement" OR removes all 
+		//	listeners of the Custom Event.
+		
+		Y.after(function (sub) {
+
+			if (domEventHandle.sub == sub) {
+
+				//	Delete this event from the map of known delegates
+				delete delegates[delegateKey];
+
+				Y.log("DOM event listener associated with the " + ename + " Custom Event removed.  Removing all " + ename + " listeners.", "info", "Event");
+
+				//	Unsubscribe all listeners of the Custom Event fired 
+				//	by this DOM event.
+				Y.detachAll(ename);
+				
+			}
+
+		}, domEventHandle.evt, "_delete");
+			
+		delegate.handle = domEventHandle;
+
+        delegates[delegateKey] = delegate;
+
+    }
+
+
+	listeners = delegate.listeners;
+
+	delegate.listeners = listeners ? (listeners + 1) : 1;
+    delegate[spec] = ename;
+
+
+    args[0] = ename;
+
+    // Remove element, delegation spec
+    args.splice(2, 2);
+        
+
+    // Subscribe to the Custom Event for the delegation spec
+
+	ceHandle = Y.on.apply(Y, args);
+
+
+	//	Hook into the detach method of the handle in order to clean up the 
+	//	'delegates' map and remove the associated DOM event handler 
+	//	responsible for firing this Custom Event if all listener for this 
+	//	event have been removed.
+
+	Y.after(function () {
+			
+		delegate.listeners = (delegate.listeners - 1);
+		
+		if (delegate.listeners === 0) {
+			Y.log("No more listeners for the " + ename + " Custom Event.  Removing its associated DOM event listener.", "info", "Event");
+			delegate.handle.detach();
+		}
+
+	}, ceHandle, "detach");
+
+    return ceHandle;
+	
+};
+
+Y.delegate = Event.delegate;
+
+ +
+
+
+ +
+
+
+ Copyright © 2009 Yahoo! Inc. All rights reserved. +
+
+ + +