Show:
                            /**
                             * A widget-level extension that provides ability to hide widget when
                             * certain events occur.
                             *
                             * @module widget-autohide
                             * @author eferraiuolo, tilomitra
                             * @since 3.4.0
                             */
                            
                            
                            var WIDGET_AUTOHIDE    = 'widgetAutohide',
                                AUTOHIDE            = 'autohide',
                                CLICK_OUTSIDE     = 'clickoutside',
                                FOCUS_OUTSIDE     = 'focusoutside',
                                DOCUMENT            = 'document',
                                KEY                 = 'key',
                                PRESS_ESCAPE         = 'esc',
                                BIND_UI             = 'bindUI',
                                SYNC_UI             = "syncUI",
                                RENDERED            = "rendered",
                                BOUNDING_BOX        = "boundingBox",
                                VISIBLE             = "visible",
                                CHANGE              = 'Change',
                            
                                getCN               = Y.ClassNameManager.getClassName;
                            
                            /**
                             * The WidgetAutohide class provides the hideOn attribute which can
                             * be used to hide the widget when certain events occur.
                             *
                             * @class WidgetAutohide
                             * @param {Object} config User configuration object
                             */
                            function WidgetAutohide(config) {
                                Y.after(this._bindUIAutohide, this, BIND_UI);
                                Y.after(this._syncUIAutohide, this, SYNC_UI);
                            
                            
                                if (this.get(RENDERED)) {
                                    this._bindUIAutohide();
                                    this._syncUIAutohide();
                                }
                            
                            }
                            
                            /**
                            * Static property used to define the default attribute
                            * configuration introduced by WidgetAutohide.
                            *
                            * @property ATTRS
                            * @static
                            * @type Object
                            */
                            WidgetAutohide.ATTRS = {
                            
                            
                                /**
                                 * @attribute hideOn
                                 * @type array
                                 *
                                 * @description An array of objects corresponding to the nodes, events, and keycodes to hide the widget on.
                                 * The implementer can supply an array of objects, with each object having the following properties:
                                 * <p>eventName: (string, required): The eventName to listen to.</p>
                                 * <p>node: (Y.Node, optional): The Y.Node that will fire the event (defaults to the boundingBox of the widget)</p>
                                 * <p>keyCode: (string, optional): If listening for key events, specify the keyCode</p>
                                 * <p>By default, this attribute consists of one object which will cause the widget to hide if the
                                 * escape key is pressed.</p>
                                 */
                                hideOn: {
                                    validator: Y.Lang.isArray,
                                    valueFn  : function() {
                                        return [
                                            {
                                                node: Y.one(DOCUMENT),
                                                eventName: KEY,
                                                keyCode: PRESS_ESCAPE
                                            }
                                        ];
                                    }
                                }
                            };
                            
                            WidgetAutohide.prototype = {
                                // *** Instance Members *** //
                            
                                    _uiHandlesAutohide : null,
                            
                                    // *** Lifecycle Methods *** //
                            
                                    destructor : function () {
                            
                                        this._detachUIHandlesAutohide();
                                    },
                            
                                    /**
                                     * Binds event listeners to the widget.
                                     * <p>
                                     * This method in invoked after bindUI is invoked for the Widget class
                                     * using YUI's aop infrastructure.
                                     * </p>
                                     * @method _bindUIAutohide
                                     * @protected
                                     */
                                    _bindUIAutohide : function () {
                            
                                        this.after(VISIBLE+CHANGE, this._afterHostVisibleChangeAutohide);
                                        this.after("hideOnChange", this._afterHideOnChange);
                                    },
                            
                                    /**
                                     * Syncs up the widget based on its current state. In particular, removes event listeners if
                                     * widget is not visible, and attaches them otherwise.
                                     * <p>
                                     * This method in invoked after syncUI is invoked for the Widget class
                                     * using YUI's aop infrastructure.
                                     * </p>
                                     * @method _syncUIAutohide
                                     * @protected
                                     */
                                    _syncUIAutohide : function () {
                            
                                        this._uiSetHostVisibleAutohide(this.get(VISIBLE));
                                    },
                            
                                    // *** Private Methods *** //
                            
                                    /**
                                     * Removes event listeners if widget is not visible, and attaches them otherwise.
                                     *
                                     * @method _uiSetHostVisibleAutohide
                                     * @protected
                                     */
                                    _uiSetHostVisibleAutohide : function (visible) {
                            
                                        if (visible) {
                                            //this._attachUIHandlesAutohide();
                                            Y.later(1, this, '_attachUIHandlesAutohide');
                                        } else {
                                            this._detachUIHandlesAutohide();
                                        }
                                    },
                            
                                    /**
                                     * Iterates through all objects in the hideOn attribute and creates event listeners.
                                     *
                                     * @method _attachUIHandlesAutohide
                                     * @protected
                                     */
                                    _attachUIHandlesAutohide : function () {
                            
                                        if (this._uiHandlesAutohide) { return; }
                            
                                        var bb = this.get(BOUNDING_BOX),
                                            hide = Y.bind(this.hide,this),
                                            uiHandles = [],
                                            self = this,
                                            hideOn = this.get('hideOn'),
                                            i = 0,
                                            o = {node: undefined, ev: undefined, keyCode: undefined};
                            
                                            //push all events on which the widget should be hidden
                                            for (; i < hideOn.length; i++) {
                            
                                                o.node = hideOn[i].node;
                                                o.ev = hideOn[i].eventName;
                                                o.keyCode = hideOn[i].keyCode;
                            
                                                //no keycode or node defined
                                                if (!o.node && !o.keyCode && o.ev) {
                                                    uiHandles.push(bb.on(o.ev, hide));
                                                }
                            
                                                //node defined, no keycode (not a keypress)
                                                else if (o.node && !o.keyCode && o.ev) {
                                                    uiHandles.push(o.node.on(o.ev, hide));
                                                }
                            
                                                //node defined, keycode defined, event defined (its a key press)
                                                else if (o.node && o.keyCode && o.ev) {
                                                    uiHandles.push(o.node.on(o.ev, hide, o.keyCode));
                                                }
                            
                                                else {
                                                    Y.log('The event with name "'+o.ev+'" could not be attached.');
                                                }
                            
                                            }
                            
                                        this._uiHandlesAutohide = uiHandles;
                                    },
                            
                                    /**
                                     * Detaches all event listeners created by this extension
                                     *
                                     * @method _detachUIHandlesAutohide
                                     * @protected
                                     */
                                    _detachUIHandlesAutohide : function () {
                            
                                        Y.each(this._uiHandlesAutohide, function(h){
                                            h.detach();
                                        });
                                        this._uiHandlesAutohide = null;
                                    },
                            
                                    /**
                                     * Default function called when the visibility of the widget changes. Determines
                                     * whether to attach or detach event listeners based on the visibility of the widget.
                                     *
                                     * @method _afterHostVisibleChangeAutohide
                                     * @protected
                                     */
                                    _afterHostVisibleChangeAutohide : function (e) {
                            
                                        this._uiSetHostVisibleAutohide(e.newVal);
                                    },
                            
                                    /**
                                     * Default function called when hideOn Attribute is changed. Remove existing listeners and create new listeners.
                                     *
                                     * @method _afterHideOnChange
                                     * @protected
                                     */
                                    _afterHideOnChange : function(e) {
                                        this._detachUIHandlesAutohide();
                            
                                        if (this.get(VISIBLE)) {
                                            this._attachUIHandlesAutohide();
                                        }
                                    }
                            };
                            
                            Y.WidgetAutohide = WidgetAutohide;