# Yahoo! UI Library

### Container 2.2.2

Yahoo! UI Library > container > OverlayManager.js (source view)

    /**
    * OverlayManager is used for maintaining the focus status of multiple Overlays.* @namespace YAHOO.widget
    * @namespace YAHOO.widget
    * @class OverlayManager
    * @constructor
    * @param {Array}	overlays	Optional. A collection of Overlays to register with the manager.
    * @param {Object}	userConfig		The object literal representing the user configuration of the OverlayManager
    */
    YAHOO.widget.OverlayManager = function(userConfig) {
    	this.init(userConfig);
    };

    /**
    * The CSS class representing a focused Overlay
    * @property YAHOO.widget.OverlayManager.CSS_FOCUSED
    * @static
    * @final
    * @type String
    */
    YAHOO.widget.OverlayManager.CSS_FOCUSED = "focused";

    YAHOO.widget.OverlayManager.prototype = {
    	/**
    	* The class's constructor function
    	* @property contructor
    	* @type Function
    	*/
    	constructor : YAHOO.widget.OverlayManager,

    	/**
    	* The array of Overlays that are currently registered
    	* @property overlays
    	* @type YAHOO.widget.Overlay[]
    	*/
    	overlays : null,

    	/**
    	* Initializes the default configuration of the OverlayManager
    	* @method initDefaultConfig
    	*/
    	initDefaultConfig : function() {
    		/**
    		* The collection of registered Overlays in use by the OverlayManager
    		* @config overlays
    		* @type YAHOO.widget.Overlay[]
    		* @default null
    		*/
    		this.cfg.addProperty("overlays", { suppressEvent:true } );

    		/**
    		* The default DOM event that should be used to focus an Overlay
    		* @config focusevent
    		* @type String
    		* @default "mousedown"
    		*/
    		this.cfg.addProperty("focusevent", { value:"mousedown" } );
    	},

    	/**
    	* Initializes the OverlayManager
    	* @method init
    	* @param {YAHOO.widget.Overlay[]}	overlays	Optional. A collection of Overlays to register with the manager.
    	* @param {Object}	userConfig		The object literal representing the user configuration of the OverlayManager
    	*/
    	init : function(userConfig) {
    		/**
    		* The OverlayManager's Config object used for monitoring configuration properties.
    		* @property cfg
    		* @type YAHOO.util.Config
    		*/
    		this.cfg = new YAHOO.util.Config(this);

    		this.initDefaultConfig();

    		if (userConfig) {
    			this.cfg.applyConfig(userConfig, true);
    		}
    		this.cfg.fireQueue();

    		/**
    		* The currently activated Overlay
    		* @property activeOverlay
    		* @private
    		* @type YAHOO.widget.Overlay
    		*/
    		var activeOverlay = null;

    		/**
    		* Returns the currently focused Overlay
    		* @method getActive
    		* @return {YAHOO.widget.Overlay}	The currently focused Overlay
    		*/
    		this.getActive = function() {
    			return activeOverlay;
    		};

    		/**
    		* Focuses the specified Overlay
    		* @method focus
    		* @param {YAHOO.widget.Overlay} overlay	The Overlay to focus
    		* @param {String} overlay	The id of the Overlay to focus
    		*/
    		this.focus = function(overlay) {

    			var o = this.find(overlay);

    			if (o) {

                    if (activeOverlay != o) {

                        if(activeOverlay) {

                            activeOverlay.blur();

                        }

                        activeOverlay = o;

                        YAHOO.util.Dom.addClass(activeOverlay.element, YAHOO.widget.OverlayManager.CSS_FOCUSED);

                        this.overlays.sort(this.compareZIndexDesc);

                        var topZIndex = YAHOO.util.Dom.getStyle(this.overlays[0].element, "zIndex");

                        if (! isNaN(topZIndex) && this.overlays[0] != overlay) {

                            activeOverlay.cfg.setProperty("zIndex", (parseInt(topZIndex, 10) + 2));

                        }

                        this.overlays.sort(this.compareZIndexDesc);

                        o.focusEvent.fire();

                    }

    			}

    		};

    		/**
    		* Removes the specified Overlay from the manager
    		* @method remove
    		* @param {YAHOO.widget.Overlay}	overlay	The Overlay to remove
    		* @param {String} overlay	The id of the Overlay to remove
    		*/
    		this.remove = function(overlay) {
    			var o = this.find(overlay);
    			if (o) {
    				var originalZ = YAHOO.util.Dom.getStyle(o.element, "zIndex");
    				o.cfg.setProperty("zIndex", -1000, true);
    				this.overlays.sort(this.compareZIndexDesc);
    				this.overlays = this.overlays.slice(0, this.overlays.length-1);

                    o.hideEvent.unsubscribe(o.blur);
                    o.destroyEvent.unsubscribe(this._onOverlayDestroy, o);

                    if (o.element) {

            			YAHOO.util.Event.removeListener(o.element, this.cfg.getProperty("focusevent"), this._onOverlayElementFocus);

                    }

    				o.cfg.setProperty("zIndex", originalZ, true);
    				o.cfg.setProperty("manager", null);

                    o.focusEvent.unsubscribeAll();
                    o.blurEvent.unsubscribeAll();

    				o.focusEvent = null;
    				o.blurEvent = null;

    				o.focus = null;
    				o.blur = null;
    			}
    		};

    		/**
    		* Removes focus from all registered Overlays in the manager
    		* @method blurAll
    		*/
    		this.blurAll = function() {
    			for (var o=0;o<this.overlays.length;o++) {
                    this.overlays[o].blur();
    			}
    		};

            this._onOverlayBlur = function(p_sType, p_aArgs) {
                activeOverlay = null;
            };

    		var overlays = this.cfg.getProperty("overlays");

    		if (! this.overlays) {
    			this.overlays = [];
    		}

    		if (overlays) {
    			this.register(overlays);
    			this.overlays.sort(this.compareZIndexDesc);
    		}
    	},

        /**
        * @method _onOverlayElementFocus
        * @description Event handler for the DOM event that is used to focus
        * the Overlay instance as specified by the "focusevent"
        * configuration property.
        * @private
        * @param {Event} p_oEvent Object representing the DOM event object passed
        * back by the event utility (YAHOO.util.Event).
        */
        _onOverlayElementFocus: function(p_oEvent) {

            var oTarget = YAHOO.util.Event.getTarget(p_oEvent),
                oClose = this.close;

            if (
                oClose &&
                (
                    oTarget == oClose ||
                    YAHOO.util.Dom.isAncestor(oClose, oTarget)
                )
            ) {

                this.blur();

            }
            else {

                this.focus();

            }

        },

        /**
        * @method _onOverlayDestroy
        * @description "destroy" event handler for the Overlay.
        * @private
        * @param {String} p_sType String representing the name of the event that
        * was fired.
        * @param {Array} p_aArgs Array of arguments sent when the event was fired.
        * @param {YAHOO.widget.Overlay} p_oOverlay Object representing the menu that
        * fired the event.
        */
        _onOverlayDestroy: function(p_sType, p_aArgs, p_oOverlay) {

            this.remove(p_oOverlay);

        },

    	/**
    	* Registers an Overlay or an array of Overlays with the manager. Upon registration, the Overlay receives functions for focus and blur, along with CustomEvents for each.
    	* @method register
    	* @param {YAHOO.widget.Overlay}	overlay		An Overlay to register with the manager.
    	* @param {YAHOO.widget.Overlay[]}	overlay		An array of Overlays to register with the manager.
    	* @return	{Boolean}	True if any Overlays are registered.
    	*/
    	register : function(overlay) {
    		if (overlay instanceof YAHOO.widget.Overlay) {
    			overlay.cfg.addProperty("manager", { value:this } );

    			overlay.focusEvent = new YAHOO.util.CustomEvent("focus", overlay);
    			overlay.blurEvent = new YAHOO.util.CustomEvent("blur", overlay);

    			var mgr=this;

    			overlay.focus = function() {
    				mgr.focus(this);
    			};

    			overlay.blur = function() {
                    if(mgr.getActive() == this) {
                        YAHOO.util.Dom.removeClass(this.element, YAHOO.widget.OverlayManager.CSS_FOCUSED);
                        this.blurEvent.fire();
    				}
    			};

                overlay.blurEvent.subscribe(mgr._onOverlayBlur);

                overlay.hideEvent.subscribe(overlay.blur);

                overlay.destroyEvent.subscribe(this._onOverlayDestroy, overlay, this);

    			YAHOO.util.Event.addListener(overlay.element, this.cfg.getProperty("focusevent"), this._onOverlayElementFocus, null, overlay);

    			var zIndex = YAHOO.util.Dom.getStyle(overlay.element, "zIndex");
    			if (! isNaN(zIndex)) {
    				overlay.cfg.setProperty("zIndex", parseInt(zIndex, 10));
    			} else {
    				overlay.cfg.setProperty("zIndex", 0);
    			}

    			this.overlays.push(overlay);
    			return true;
    		} else if (overlay instanceof Array) {
    			var regcount = 0;
    			for (var i=0;i<overlay.length;i++) {
    				if (this.register(overlay[i])) {
    					regcount++;
    				}
    			}
    			if (regcount > 0) {
    				return true;
    			}
    		} else {
    			return false;
    		}
    	},

    	/**
    	* Attempts to locate an Overlay by instance or ID.
    	* @method find
    	* @param {YAHOO.widget.Overlay}	overlay		An Overlay to locate within the manager
    	* @param {String}	overlay		An Overlay id to locate within the manager
    	* @return	{YAHOO.widget.Overlay}	The requested Overlay, if found, or null if it cannot be located.
    	*/
    	find : function(overlay) {
    		if (overlay instanceof YAHOO.widget.Overlay) {
    			for (var o=0;o<this.overlays.length;o++) {
    				if (this.overlays[o] == overlay) {
    					return this.overlays[o];
    				}
    			}
    		} else if (typeof overlay == "string") {
    			for (var p=0;p<this.overlays.length;p++) {
    				if (this.overlays[p].id == overlay) {
    					return this.overlays[p];
    				}
    			}
    		}
    		return null;
    	},

    	/**
    	* Used for sorting the manager's Overlays by z-index.
    	* @method compareZIndexDesc
    	* @private
    	* @return {Number}	0, 1, or -1, depending on where the Overlay should fall in the stacking order.
    	*/
    	compareZIndexDesc : function(o1, o2) {
    		var zIndex1 = o1.cfg.getProperty("zIndex");
    		var zIndex2 = o2.cfg.getProperty("zIndex");

    		if (zIndex1 > zIndex2) {
    			return -1;
    		} else if (zIndex1 < zIndex2) {
    			return 1;
    		} else {
    			return 0;
    		}
    	},

    	/**
    	* Shows all Overlays in the manager.
    	* @method showAll
    	*/
    	showAll : function() {
    		for (var o=0;o<this.overlays.length;o++) {
    			this.overlays[o].show();
    		}
    	},

    	/**
    	* Hides all Overlays in the manager.
    	* @method hideAll
    	*/
    	hideAll : function() {
    		for (var o=0;o<this.overlays.length;o++) {
    			this.overlays[o].hide();
    		}
    	},

    	/**
    	* Returns a string representation of the object.
    	* @method toString
    	* @return {String}	The string representation of the OverlayManager
    	*/
    	toString : function() {
    		return "OverlayManager";
    	}

    };

Copyright © 2007 Yahoo! Inc. All rights reserved.