diff -r 000000000000 -r 40c8f766c9b8 src/cm/media/js/lib/yui/yui3.0.0/build/event/event-delegate-debug.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui3.0.0/build/event/event-delegate-debug.js Mon Nov 23 15:14:29 2009 +0100 @@ -0,0 +1,370 @@ +/* +Copyright (c) 2009, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 3.0.0 +build: 1549 +*/ +YUI.add('event-delegate', function(Y) { + +/** + * 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; + + +}, '3.0.0' ,{requires:['node-base']});