#

API Docs for: 3.10.3
Show: Inherited Protected Private Deprecated

# File: node/js/align-plugin.js

        /**
         * Provides advanced positioning support for Node via a Plugin
         * for centering and alignment.
         * @module align-plugin
         */

        var OFFSET_WIDTH = 'offsetWidth',
            OFFSET_HEIGHT = 'offsetHeight',
            undefined = undefined;

        /**
         * Node plugin which can be used to align a node with another node,
         * region, or the viewport.
         *
         * @class Plugin.Align
         * @param {Object} User configuration object
         */
        function Align(config) {
            if (config.host) {
                this._host = config.host;
            }
        }

        Align.prototype = {
            /**
             * Aligns node with a point on another node or region.
             * Possible alignment points are:
             * <dl>
             *      <dt>tl</dt>
             *      <dd>top left</dd>
             *      <dt>tr</dt>
             *      <dd>top right</dd>
             *      <dt>bl</dt>
             *      <dd>bottom left</dd>
             *      <dt>br</dt>
             *      <dd>bottom right</dd>
             *      <dt>tc</dt>
             *      <dd>top center</dd>
             *      <dt>bc</dt>
             *      <dd>bottom center</dd>
             *      <dt>rc</dt>
             *      <dd>right center</dd>
             *      <dt>lc</dt>
             *      <dd>left center</dd>
             *      <dt>cc</dt>
             *      <dd>center center</dd>
             * </dl>
             * @method to
             * @param region {String || Node || HTMLElement || Object} The node or
             * region to align with. Defaults to the viewport region.
             * @param regionPoint {String} The point of the region to align with.
             * @param point {String} The point of the node aligned to the region.
             * @param resize {Boolean} Whether or not the node should re-align when
             * the window is resized. Defaults to false.
             */
            to: function(region, regionPoint, point, syncOnResize) {
                // cache original args for syncing
                this._syncArgs = Y.Array(arguments);

                if (region.top === undefined) {
                    region = Y.one(region).get('region');
                }

                if (region) {
                    var xy = [region.left, region.top],
                        offxy = [region.width, region.height],
                        points = Align.points,
                        node = this._host,
                        NULL = null,
                        size = node.getAttrs([OFFSET_HEIGHT, OFFSET_WIDTH]),
                        nodeoff = [0 - size[OFFSET_WIDTH], 0 - size[OFFSET_HEIGHT]], // reverse offsets
                        regionFn0 = regionPoint ? points[regionPoint.charAt(0)]: NULL,
                        regionFn1 = (regionPoint && regionPoint !== 'cc') ? points[regionPoint.charAt(1)] : NULL,
                        nodeFn0 = point ? points[point.charAt(0)] : NULL,
                        nodeFn1 = (point && point !== 'cc') ? points[point.charAt(1)] : NULL;

                    if (regionFn0) {
                        xy = regionFn0(xy, offxy, regionPoint);
                    }
                    if (regionFn1) {
                        xy = regionFn1(xy, offxy, regionPoint);
                    }

                    if (nodeFn0) {
                        xy = nodeFn0(xy, nodeoff, point);
                    }
                    if (nodeFn1) {
                        xy = nodeFn1(xy, nodeoff, point);
                    }

                    if (xy && node) {
                        node.setXY(xy);
                    }

                    this._resize(syncOnResize);

                }
                return this;
            },

            sync: function() {
                this.to.apply(this, this._syncArgs);
                return this;
            },

            _resize: function(add) {
                var handle = this._handle;
                if (add && !handle) {
                    this._handle = Y.on('resize', this._onresize, window, this);
                } else if (!add && handle) {
                    handle.detach();
                }

            },

            _onresize: function() {
                var self = this;
                setTimeout(function() { // for performance
                    self.sync();
                });
            },

            /**
             * Aligns the center of a node to the center of another node or region.
             * @method center
             * @param region {Node || HTMLElement || Object} optional The node or
             * region to align with. Defaults to the viewport region.
             * the window is resized. If centering to viewport, this defaults
             * to true, otherwise default is false.
             */
            center: function(region, resize) {
                this.to(region, 'cc', 'cc', resize);
                return this;
            },

            /**
             * Removes the resize handler, if any. This is called automatically
             * when unplugged from the host node.
             * @method destroy
             */
            destroy: function() {
                var handle = this._handle;
                if (handle) {
                    handle.detach();
                }
            }
        };

        Align.points = {
            't': function(xy, off) {
                return xy;
            },

            'r': function(xy, off) {
                return [xy[0] + off[0], xy[1]];
            },

            'b': function(xy, off) {
                return [xy[0], xy[1] + off[1]];
            },

            'l': function(xy, off) {
                return xy;
            },

            'c': function(xy, off, point) {
                var axis = (point[0] === 't' || point[0] === 'b') ?  0 : 1,
                    ret, val;

                if (point === 'cc') {
                    ret = [xy[0] + off[0] / 2, xy[1] + off[1] / 2];
                } else {
                    val = xy[axis] + off[axis] / 2;
                    ret = (axis) ? [xy[0], val] : [val, xy[1]];
                }

                 return ret;
            }
        };

        Align.NAME = 'Align';
        Align.NS = 'align';

        Align.prototype.constructor = Align;

        Y.namespace('Plugin');
        Y.Plugin.Align = Align;