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 @@ + + +
+ +/**
+ * 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;
+