API Docs for: 1.0.0
Show:

File: src/gallery-popup/js/popup.js

/**********************************************************************
 * Widgets for showing a temporary, "popup" overlay.
 *
 * @module gallery-popup
 * @main gallery-popup
 */

var visible_popup;

/**
 * <p>Popup provides an overlay which opens on a definable set of events,
 * closes on ESC or clicks outside the popup, and which can block the
 * overlay from closing based on a definable set of events which take
 * precendence over the default close events.</p>
 *
 * @class Popup
 * @extends Overlay
 * @uses WidgetAutohide
 * @constructor
 */
Y.Popup = Y.Base.create('popup', Y.Overlay, [Y.WidgetAutohide],
{
	initializer: function(config)
	{
		this.appendHideOn({ eventName: 'clickoutside' });

		Y.after(this._attachUIHandlesPopup, this, 'bindUI');

		if (this.get('reparentToBody'))
		{
			Y.after(function()
			{
				Y.one('body').append(this.get('boundingBox'));
			},
			this, 'renderUI');
		}

		this.after('showOnChange', this._resetUIHandlesPopup);
		this.after('stayOpenOnChange', this._resetUIHandlesPopup);

		this.on('visibleChange', function(e)
		{
			if (e.newVal)
			{
				if (visible_popup && visible_popup != this)
				{
					visible_popup.hide();
				}
				visible_popup = this;
			}
			else if (visible_popup == this)
			{
				visible_popup = null;
			}
		});
	},

	destructor: function()
	{
		this._detachUIHandlesPopup();
	},

	/**
	 * Add an additional event which should hide the popup.
	 * 
	 * @method appendHideOn
	 * @chainable
	 * @param o {Object} The event description (node, eventName, keyCode)
	 */
	appendHideOn: function(o)
	{
		var hide = this.get('hideOn');
		hide.push(o);
		this.set('hideOn', hide);
		return this;
	},

	_resetUIHandlesPopup: function()
	{
		this._detachUIHandlesPopup();
		this._attachUIHandlesPopup();
	},

	_attachUIHandlesPopup: function()
	{
		this._uiHandlesPopup = [].concat(

			Y.map(this.get('showOn'), function(o)
			{
				this._attachUIEventPopup(o, this.show);
			},
			this),

			Y.map(this.get('stayOpenOn'), function(o)
			{
				this._attachUIEventPopup(o, this._blockUIEventPopup);
			},
			this));
	},

	_attachUIEventPopup: function(o, f)
	{
		if (o.keyCode)
		{
			return Y.one(o.node).on(o.eventName, Y.bind(f, this), o.keyCode);
		}
		else
		{
			return Y.one(o.node).on(o.eventName, f, this);
		}
	},

	_detachUIHandlesPopup: function()
	{
		if (this._uiHandlesPopup)
		{
			Y.Array.invoke(this._uiHandlesPopup, 'detach');
			this._uiHandlesPopup = null;
		}
	},

	_blockUIEventPopup: function(e)
	{
		if (this.get('visible'))
		{
			e.halt();
		}
	}
},
{
	ATTRS:
	{
		/**
		 * List of { node, eventName, keyCode } describing the events that
		 * should trigger showing the popup.  `node` and `eventName` are
		 * required.
		 *
		 * @attribute showOn
		 * @type {Array}
		 */
		showOn:
		{
			validator: Y.Lang.isArray,
			value:     []
		},

		/**
		 * List of { node, eventName, keyCode } describing the events that
		 * should keep the popup open.  These block hideOn from being
		 * triggered.  `node` and `eventName` are required.
		 *
		 * @attribute stayOpenOn
		 * @type {Array}
		 */
		stayOpenOn:
		{
			validator: Y.Lang.isArray,
			value:     []
		},

		/**
		 * Set to `true` to reparent the popup to the body element.
		 *
		 * @attribute reparentToBody
		 * @type {Boolean}
		 * @default false
		 * @writeonce
		 */
		reparentToBody:
		{
			validator: Y.Lang.isBoolean,
			writeOnce: true,
			value:     false
		}
	}
});