Show:
                            /**
                             * Adds bubbling and delegation support to DOM events focus and blur.
                             *
                             * @module event
                             * @submodule event-focus
                             */
                            var Event    = Y.Event,
                            
                                YLang    = Y.Lang,
                            
                                isString = YLang.isString,
                            
                                arrayIndex = Y.Array.indexOf,
                            
                                useActivate = (function() {
                            
                                    // Changing the structure of this test, so that it doesn't use inline JS in HTML,
                                    // which throws an exception in Win8 packaged apps, due to additional security restrictions:
                                    // http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences
                            
                                    var supported = false,
                                        doc = Y.config.doc,
                                        p;
                            
                                    if (doc) {
                            
                                        p = doc.createElement("p");
                                        p.setAttribute("onbeforeactivate", ";");
                            
                                        // onbeforeactivate is a function in IE8+.
                                        // onbeforeactivate is a string in IE6,7 (unfortunate, otherwise we could have just checked for function below).
                                        // onbeforeactivate is a function in IE10, in a Win8 App environment (no exception running the test).
                            
                                        // onbeforeactivate is undefined in Webkit/Gecko.
                                        // onbeforeactivate is a function in Webkit/Gecko if it's a supported event (e.g. onclick).
                            
                                        supported = (p.onbeforeactivate !== undefined);
                                    }
                            
                                    return supported;
                                }());
                            
                            function define(type, proxy, directEvent) {
                                var nodeDataKey = '_' + type + 'Notifiers';
                            
                                Y.Event.define(type, {
                            
                                    _useActivate : useActivate,
                            
                                    _attach: function (el, notifier, delegate) {
                                        if (Y.DOM.isWindow(el)) {
                                            return Event._attach([type, function (e) {
                                                notifier.fire(e);
                                            }, el]);
                                        } else {
                                            return Event._attach(
                                                [proxy, this._proxy, el, this, notifier, delegate],
                                                { capture: true });
                                        }
                                    },
                            
                                    _proxy: function (e, notifier, delegate) {
                                        var target        = e.target,
                                            currentTarget = e.currentTarget,
                                            notifiers     = target.getData(nodeDataKey),
                                            yuid          = Y.stamp(currentTarget._node),
                                            defer         = (useActivate || target !== currentTarget),
                                            directSub;
                            
                                        notifier.currentTarget = (delegate) ? target : currentTarget;
                                        notifier.container     = (delegate) ? currentTarget : null;
                            
                                        // Maintain a list to handle subscriptions from nested
                                        // containers div#a>div#b>input #a.on(focus..) #b.on(focus..),
                                        // use one focus or blur subscription that fires notifiers from
                                        // #b then #a to emulate bubble sequence.
                                        if (!notifiers) {
                                            notifiers = {};
                                            target.setData(nodeDataKey, notifiers);
                            
                                            // only subscribe to the element's focus if the target is
                                            // not the current target (
                                            if (defer) {
                                                directSub = Event._attach(
                                                    [directEvent, this._notify, target._node]).sub;
                                                directSub.once = true;
                                            }
                                        } else {
                                            // In old IE, defer is always true.  In capture-phase browsers,
                                            // The delegate subscriptions will be encountered first, which
                                            // will establish the notifiers data and direct subscription
                                            // on the node.  If there is also a direct subscription to the
                                            // node's focus/blur, it should not call _notify because the
                                            // direct subscription from the delegate sub(s) exists, which
                                            // will call _notify.  So this avoids _notify being called
                                            // twice, unnecessarily.
                                            defer = true;
                                        }
                            
                                        if (!notifiers[yuid]) {
                                            notifiers[yuid] = [];
                                        }
                            
                                        notifiers[yuid].push(notifier);
                            
                                        if (!defer) {
                                            this._notify(e);
                                        }
                                    },
                            
                                    _notify: function (e, container) {
                                        var currentTarget = e.currentTarget,
                                            notifierData  = currentTarget.getData(nodeDataKey),
                                            axisNodes     = currentTarget.ancestors(),
                                            doc           = currentTarget.get('ownerDocument'),
                                            delegates     = [],
                                                            // Used to escape loops when there are no more
                                                            // notifiers to consider
                                            count         = notifierData ?
                                                                Y.Object.keys(notifierData).length :
                                                                0,
                                            target, notifiers, notifier, yuid, match, tmp, i, len, sub, ret;
                            
                                        // clear the notifications list (mainly for delegation)
                                        currentTarget.clearData(nodeDataKey);
                            
                                        // Order the delegate subs by their placement in the parent axis
                                        axisNodes.push(currentTarget);
                                        // document.get('ownerDocument') returns null
                                        // which we'll use to prevent having duplicate Nodes in the list
                                        if (doc) {
                                            axisNodes.unshift(doc);
                                        }
                            
                                        // ancestors() returns the Nodes from top to bottom
                                        axisNodes._nodes.reverse();
                            
                                        if (count) {
                                            // Store the count for step 2
                                            tmp = count;
                                            axisNodes.some(function (node) {
                                                var yuid      = Y.stamp(node),
                                                    notifiers = notifierData[yuid],
                                                    i, len;
                            
                                                if (notifiers) {
                                                    count--;
                                                    for (i = 0, len = notifiers.length; i < len; ++i) {
                                                        if (notifiers[i].handle.sub.filter) {
                                                            delegates.push(notifiers[i]);
                                                        }
                                                    }
                                                }
                            
                                                return !count;
                                            });
                                            count = tmp;
                                        }
                            
                                        // Walk up the parent axis, notifying direct subscriptions and
                                        // testing delegate filters.
                                        while (count && (target = axisNodes.shift())) {
                                            yuid = Y.stamp(target);
                            
                                            notifiers = notifierData[yuid];
                            
                                            if (notifiers) {
                                                for (i = 0, len = notifiers.length; i < len; ++i) {
                                                    notifier = notifiers[i];
                                                    sub      = notifier.handle.sub;
                                                    match    = true;
                            
                                                    e.currentTarget = target;
                            
                                                    if (sub.filter) {
                                                        match = sub.filter.apply(target,
                                                            [target, e].concat(sub.args || []));
                            
                                                        // No longer necessary to test against this
                                                        // delegate subscription for the nodes along
                                                        // the parent axis.
                                                        delegates.splice(
                                                            arrayIndex(delegates, notifier), 1);
                                                    }
                            
                                                    if (match) {
                                                        // undefined for direct subs
                                                        e.container = notifier.container;
                                                        ret = notifier.fire(e);
                                                    }
                            
                                                    if (ret === false || e.stopped === 2) {
                                                        break;
                                                    }
                                                }
                            
                                                delete notifiers[yuid];
                                                count--;
                                            }
                            
                                            if (e.stopped !== 2) {
                                                // delegates come after subs targeting this specific node
                                                // because they would not normally report until they'd
                                                // bubbled to the container node.
                                                for (i = 0, len = delegates.length; i < len; ++i) {
                                                    notifier = delegates[i];
                                                    sub = notifier.handle.sub;
                            
                                                    if (sub.filter.apply(target,
                                                        [target, e].concat(sub.args || []))) {
                            
                                                        e.container = notifier.container;
                                                        e.currentTarget = target;
                                                        ret = notifier.fire(e);
                                                    }
                            
                                                    if (ret === false || e.stopped === 2 ||
                                                        // If e.stopPropagation() is called, notify any
                                                        // delegate subs from the same container, but break
                                                        // once the container changes. This emulates
                                                        // delegate() behavior for events like 'click' which
                                                        // won't notify delegates higher up the parent axis.
                                                        (e.stopped && delegates[i+1] &&
                                                         delegates[i+1].container !== notifier.container)) {
                                                        break;
                                                    }
                                                }
                                            }
                            
                                            if (e.stopped) {
                                                break;
                                            }
                                        }
                                    },
                            
                                    on: function (node, sub, notifier) {
                                        sub.handle = this._attach(node._node, notifier);
                                    },
                            
                                    detach: function (node, sub) {
                                        sub.handle.detach();
                                    },
                            
                                    delegate: function (node, sub, notifier, filter) {
                                        if (isString(filter)) {
                                            sub.filter = function (target) {
                                                return Y.Selector.test(target._node, filter,
                                                    node === target ? null : node._node);
                                            };
                                        }
                            
                                        sub.handle = this._attach(node._node, notifier, true);
                                    },
                            
                                    detachDelegate: function (node, sub) {
                                        sub.handle.detach();
                                    }
                                }, true);
                            }
                            
                            // For IE, we need to defer to focusin rather than focus because
                            // `el.focus(); doSomething();` executes el.onbeforeactivate, el.onactivate,
                            // el.onfocusin, doSomething, then el.onfocus.  All others support capture
                            // phase focus, which executes before doSomething.  To guarantee consistent
                            // behavior for this use case, IE's direct subscriptions are made against
                            // focusin so subscribers will be notified before js following el.focus() is
                            // executed.
                            if (useActivate) {
                                //     name     capture phase       direct subscription
                                define("focus", "beforeactivate",   "focusin");
                                define("blur",  "beforedeactivate", "focusout");
                            } else {
                                define("focus", "focus", "focus");
                                define("blur",  "blur",  "blur");
                            }