MDL-32843 import YUI 3.5.1
[moodle.git] / lib / yui / 3.5.1 / build / align-plugin / align-plugin.js
blob08c4178f79e0ee81a8b1570c8f53c22bcb5b8a6d
1 /*
2 YUI 3.5.1 (build 22)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('align-plugin', function(Y) {
9     /**
10      * Provides advanced positioning support for Node via a Plugin
11      * for centering and alignment. 
12      * @module align-plugin
13      */
15     var OFFSET_WIDTH = 'offsetWidth',
16         OFFSET_HEIGHT = 'offsetHeight',
17         undefined = undefined;
19     /**
20      * Node plugin which can be used to align a node with another node,
21      * region, or the viewport.
22      *
23      * @class Plugin.Align
24      * @param {Object} User configuration object
25      */
26     function Align(config) {
27         if (config.host) {
28             this._host = config.host;
29         }
30     }
31         
32     Align.prototype = {
33         /**
34          * Aligns node with a point on another node or region.
35          * Possible alignment points are:
36          * <dl>
37          *      <dt>tl</dt>
38          *      <dd>top left</dd>
39          *      <dt>tr</dt>
40          *      <dd>top right</dd>
41          *      <dt>bl</dt>
42          *      <dd>bottom left</dd>
43          *      <dt>br</dt>
44          *      <dd>bottom right</dd>
45          *      <dt>tc</dt>
46          *      <dd>top center</dd>
47          *      <dt>bc</dt>
48          *      <dd>bottom center</dd>
49          *      <dt>rc</dt>
50          *      <dd>right center</dd>
51          *      <dt>lc</dt>
52          *      <dd>left center</dd>
53          *      <dt>cc</dt>
54          *      <dd>center center</dd>
55          * </dl>
56          * @method to 
57          * @param region {String || Node || HTMLElement || Object} The node or
58          * region to align with. Defaults to the viewport region.
59          * @param regionPoint {String} The point of the region to align with.
60          * @param point {String} The point of the node aligned to the region. 
61          * @param resize {Boolean} Whether or not the node should re-align when
62          * the window is resized. Defaults to false.
63          */
64         to: function(region, regionPoint, point, syncOnResize) {
65             // cache original args for syncing
66             this._syncArgs = Y.Array(arguments);
68             if (region.top === undefined) {
69                 region = Y.one(region).get('region');
70             }
72             if (region) {
73                 var xy = [region.left, region.top],
74                     offxy = [region.width, region.height],
75                     points = Align.points,
76                     node = this._host,
77                     NULL = null,
78                     size = node.getAttrs([OFFSET_HEIGHT, OFFSET_WIDTH]),
79                     nodeoff = [0 - size[OFFSET_WIDTH], 0 - size[OFFSET_HEIGHT]], // reverse offsets
80                     regionFn0 = regionPoint ? points[regionPoint.charAt(0)]: NULL,
81                     regionFn1 = (regionPoint && regionPoint !== 'cc') ? points[regionPoint.charAt(1)] : NULL,
82                     nodeFn0 = point ? points[point.charAt(0)] : NULL,
83                     nodeFn1 = (point && point !== 'cc') ? points[point.charAt(1)] : NULL;
85                 if (regionFn0) {
86                     xy = regionFn0(xy, offxy, regionPoint);
87                 }
88                 if (regionFn1) {
89                     xy = regionFn1(xy, offxy, regionPoint);
90                 }
92                 if (nodeFn0) {
93                     xy = nodeFn0(xy, nodeoff, point);
94                 }
95                 if (nodeFn1) {
96                     xy = nodeFn1(xy, nodeoff, point);
97                 }
99                 if (xy && node) {
100                     node.setXY(xy);
101                 }
102                 
103                 this._resize(syncOnResize);
105             }
106             return this;
107         },
109         sync: function() {
110             this.to.apply(this, this._syncArgs);
111             return this;
112         },
114         _resize: function(add) {
115             var handle = this._handle;
116             if (add && !handle) {
117                 this._handle = Y.on('resize', this._onresize, window, this);
118             } else if (!add && handle) {
119                 handle.detach();
120             }
122         },
124         _onresize: function() {
125             var self = this;
126             setTimeout(function() { // for performance
127                 self.sync();
128             });
129         },
130     
131         /**
132          * Aligns the center of a node to the center of another node or region.
133          * @method center 
134          * @param region {Node || HTMLElement || Object} optional The node or
135          * region to align with. Defaults to the viewport region.
136          * the window is resized. If centering to viewport, this defaults
137          * to true, otherwise default is false.
138          */
139         center: function(region, resize) {
140             this.to(region, 'cc', 'cc', resize); 
141             return this;
142         },
144         /**
145          * Removes the resize handler, if any. This is called automatically
146          * when unplugged from the host node.
147          * @method destroy 
148          */
149         destroy: function() {
150             var handle = this._handle;
151             if (handle) {
152                 handle.detach();
153             }
154         }
155     };
157     Align.points = {
158         't': function(xy, off) {
159             return xy;
160         },
162         'r': function(xy, off) {
163             return [xy[0] + off[0], xy[1]];
164         },
166         'b': function(xy, off) {
167             return [xy[0], xy[1] + off[1]];
168         },
170         'l': function(xy, off) {
171             return xy;
172         },
174         'c': function(xy, off, point) {
175             var axis = (point[0] === 't' || point[0] === 'b') ?  0 : 1,
176                 ret, val;
178             if (point === 'cc') {
179                 ret = [xy[0] + off[0] / 2, xy[1] + off[1] / 2];
180             } else {
181                 val = xy[axis] + off[axis] / 2;
182                 ret = (axis) ? [xy[0], val] : [val, xy[1]];
183             }
185              return ret;
186         }
187     };
189     Align.NAME = 'Align';
190     Align.NS = 'align';
192     Align.prototype.constructor = Align;
194     Y.namespace('Plugin');
195     Y.Plugin.Align = Align;
199 }, '3.5.1' ,{requires:['node-pluginhost', 'node-screen']});