Version 3.18.1
Show:

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;