~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/static/javascript/yui/build/widget/widget-position-ext-debug.js

[rs=thumper] merge loggerhead trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.net/yui/license.txt
 
5
version: 3.0.0pr2
 
6
*/
 
7
YUI.add('widget-position-ext', function(Y) {
 
8
 
 
9
/**
 
10
 * Provides extended/advanced XY positioning support for Widgets, through an extension.
 
11
 *
 
12
 * It builds on top of the widget-position module, to provide alignmentment and centering support.
 
13
 * Future releases aim to add constrained and fixed positioning support.
 
14
 *
 
15
 * @module widget-position-ext
 
16
 */
 
17
        var L = Y.Lang,
 
18
            ALIGN = "align",
 
19
 
 
20
            BINDUI = "bindUI",
 
21
            SYNCUI = "syncUI",
 
22
 
 
23
            OFFSET_WIDTH = "offsetWidth",
 
24
            OFFSET_HEIGHT = "offsetHeight",
 
25
            VIEWPORT_REGION = "viewportRegion",
 
26
            REGION = "region",
 
27
 
 
28
            AlignChange = "alignChange";
 
29
 
 
30
        /**
 
31
         * Widget extension, which can be used to add extended XY positioning support to the base Widget class,
 
32
         * through the <a href="Base.html#method_build">Base.build</a> method.
 
33
         *
 
34
         * @class WidgetPositionExt
 
35
         * @param {Object} User configuration object
 
36
         */
 
37
        function PositionExt(config) {
 
38
            Y.after(this._syncUIPosExtras, this, SYNCUI);
 
39
            Y.after(this._bindUIPosExtras, this, BINDUI);
 
40
        }
 
41
 
 
42
        /**
 
43
         * Static property used to define the default attribute 
 
44
         * configuration introduced by WidgetPositionExt.
 
45
         * 
 
46
         * @property WidgetPositionExt.ATTRS
 
47
         * @type Object
 
48
         * @static
 
49
         */
 
50
        PositionExt.ATTRS = {
 
51
 
 
52
            /**
 
53
             * @attribute align
 
54
             * @type Object
 
55
             * @default null
 
56
             * @desciption The align attribute is used to align a reference point on the widget, with the refernce point on another node, or the viewport. 
 
57
             * The object which align expects has the following properties:
 
58
             * <dl>
 
59
             *       <dt>node</dt>
 
60
             *       <dd>
 
61
             *         The node to which the Widget is to be aligned. If set to null, or not provided, the Widget is aligned to the viewport
 
62
             *       </dd>
 
63
             *       <dt>points</dt>
 
64
             *       <dd>
 
65
             *         <p>
 
66
             *         A two element array, defining the two points on the Widget and node/viewport which are to be aligned. The first element is the point on the Widget, and the second element is the point on the node/viewport.
 
67
             *         Supported alignment points are defined as static properties on <code>WidgetPositionExt</code>.
 
68
             *         </p>
 
69
             *         <p>
 
70
             *         e.g. <code>[WidgetPositionExt.TR, WidgetPositionExt.TL]</code> aligns the Top-Right corner of the Widget with the
 
71
             *         Top-Left corner of the node/viewport, and <code>[WidgetPositionExt.CC, WidgetPositionExt.TC]</code> aligns the Center of the 
 
72
             *         Widget with the Top-Center edge of the node/viewport.
 
73
             *         </p>
 
74
             *       </dd>
 
75
             *   </dl>
 
76
             */
 
77
            align: {
 
78
                value:null
 
79
            },
 
80
 
 
81
            /**
 
82
             * @attribute centered
 
83
             * @type {boolean | node} 
 
84
             * @default false
 
85
             * @description A convenience attribute, which can be used as a shortcut for the align attribute.
 
86
             * If set to true, the Widget is centered in the viewport. If set to a node reference or valid selector string,
 
87
             * the Widget will be centered within the node. If set the false, no center positioning is applied.
 
88
             */
 
89
            centered: {
 
90
                set: function(val) {
 
91
                    return this._setAlignCenter(val);
 
92
                },
 
93
                value:false
 
94
            }
 
95
        };
 
96
 
 
97
        /**
 
98
         * Constant used to specify the top-left corner for alignment
 
99
         * 
 
100
         * @property WidgetPositionExt.TL
 
101
         * @type String
 
102
         * @static
 
103
         * @value "tl"
 
104
         */
 
105
        PositionExt.TL = "tl";
 
106
        /**
 
107
         * Constant used to specify the top-right corner for alignment
 
108
         * 
 
109
         * @property WidgetPositionExt.TR
 
110
         * @type String
 
111
         * @static
 
112
         * @value "tr"
 
113
         */
 
114
        PositionExt.TR = "tr";
 
115
        /**
 
116
         * Constant used to specify the bottom-left corner for alignment
 
117
         * 
 
118
         * @property WidgetPositionExt.BL
 
119
         * @type String
 
120
         * @static
 
121
         * @value "bl"
 
122
         */
 
123
        PositionExt.BL = "bl";
 
124
        /**
 
125
         * Constant used to specify the bottom-right corner for alignment
 
126
         * 
 
127
         * @property WidgetPositionExt.BR
 
128
         * @type String
 
129
         * @static
 
130
         * @value "br"
 
131
         */
 
132
        PositionExt.BR = "br";
 
133
        /**
 
134
         * Constant used to specify the top edge-center point for alignment
 
135
         * 
 
136
         * @property WidgetPositionExt.TC
 
137
         * @type String
 
138
         * @static
 
139
         * @value "tc"
 
140
         */
 
141
        PositionExt.TC = "tc";
 
142
        /**
 
143
         * Constant used to specify the right edge, center point for alignment
 
144
         * 
 
145
         * @property WidgetPositionExt.RC
 
146
         * @type String
 
147
         * @static
 
148
         * @value "rc"
 
149
         */
 
150
        PositionExt.RC = "rc";
 
151
        /**
 
152
         * Constant used to specify the bottom edge, center point for alignment
 
153
         * 
 
154
         * @property WidgetPositionExt.BC
 
155
         * @type String
 
156
         * @static
 
157
         * @value "bc"
 
158
         */
 
159
        PositionExt.BC = "bc";
 
160
        /**
 
161
         * Constant used to specify the left edge, center point for alignment
 
162
         * 
 
163
         * @property WidgetPositionExt.LC
 
164
         * @type String
 
165
         * @static
 
166
         * @value "lc"
 
167
         */
 
168
        PositionExt.LC = "lc";
 
169
        /**
 
170
         * Constant used to specify the center of widget/node/viewport for alignment
 
171
         * 
 
172
         * @property WidgetPositionExt.CC
 
173
         * @type String
 
174
         * @static
 
175
         * @value "cc"
 
176
         */
 
177
        PositionExt.CC = "cc";
 
178
 
 
179
        PositionExt.prototype = {
 
180
 
 
181
            /**
 
182
             * Synchronizes the UI to match the Widgets extended positioning state.
 
183
             * This method in invoked after syncUI is invoked for the Widget class
 
184
             * using YUI's aop infrastructure.
 
185
             *
 
186
             * @method _syncUIPosExtras
 
187
             * @protected
 
188
             */
 
189
            _syncUIPosExtras : function() {
 
190
                var align = this.get(ALIGN);
 
191
                if (align) {
 
192
                    this._uiSetAlign(align.node, align.points);
 
193
                }
 
194
            },
 
195
 
 
196
            /**
 
197
             * Binds event listeners responsible for updating the UI state in response to 
 
198
             * Widget extended positioning related state changes.
 
199
             * <p>
 
200
             * This method is invoked after bindUI is invoked for the Widget class
 
201
             * using YUI's aop infrastructure.
 
202
             * </p>
 
203
             * @method _bindUIStack
 
204
             * @protected
 
205
             */
 
206
            _bindUIPosExtras : function() {
 
207
                this.after(AlignChange, this._afterAlignChange);
 
208
            },
 
209
 
 
210
            /**
 
211
             * Default setter for center attribute changes. Sets up the appropriate value, and passes 
 
212
             * it through the to the align attribute.
 
213
             *
 
214
             * @method _setAlignCenter
 
215
             * @protected
 
216
             * @param {boolean | node} The attribute value being set. 
 
217
             * @return {Number} The attribute value being set.
 
218
             */
 
219
            _setAlignCenter : function(val) {
 
220
                if (val) {
 
221
                    this.set(ALIGN, {
 
222
                        node: val === true ? null : val,
 
223
                        points: [PositionExt.CC, PositionExt.CC]
 
224
                    });
 
225
                }
 
226
                return val;
 
227
            },
 
228
 
 
229
            /**
 
230
             * Default attribute change listener for the align attribute, responsible
 
231
             * for updating the UI, in response to attribute changes.
 
232
             * 
 
233
             * @method _afterAlignChange
 
234
             * @protected
 
235
             * @param {Event.Facade} e The event facade for the attribute change
 
236
             */
 
237
            _afterAlignChange : function(e) {
 
238
                if (e.newVal) {
 
239
                    this._uiSetAlign(e.newVal.node, e.newVal.points);
 
240
                }
 
241
            },
 
242
 
 
243
            /**
 
244
             * Updates the UI to reflect the align value passed in (see the align attribute documentation, for the object stucture expected)
 
245
             * @method _uiSetAlign
 
246
             * @protected
 
247
             * @param {Node | null} The node to align to, or null to indicate the viewport
 
248
             */
 
249
            _uiSetAlign: function (node, points) {
 
250
 
 
251
                if (!L.isArray(points) || points.length != 2) {
 
252
                    Y.fail("align: Invalid Points Arguments");
 
253
                    return;
 
254
                }
 
255
 
 
256
                var nodeRegion, widgetPoint, nodePoint, xy;
 
257
 
 
258
                if (!node) {
 
259
                    nodeRegion = this._posNode.get(VIEWPORT_REGION);
 
260
                } else {
 
261
                    node = Y.Node.get(node);
 
262
                    if (node) {
 
263
                        nodeRegion = node.get(REGION);
 
264
                    }
 
265
                }
 
266
 
 
267
                if (nodeRegion) {
 
268
 
 
269
                    // TODO: ViewportRegion doesn't have width/height - Workaround until normalized in Node/Dom
 
270
                    nodeRegion.width = nodeRegion.width || nodeRegion.right - nodeRegion.left;
 
271
                    nodeRegion.height = nodeRegion.height || nodeRegion.bottom - nodeRegion.top;
 
272
 
 
273
                    widgetPoint = points[0];
 
274
                    nodePoint = points[1];
 
275
 
 
276
                    // TODO: Optimize KWeight - Would lookup table help?
 
277
                    switch (nodePoint) {
 
278
                        case PositionExt.TL:
 
279
                            xy = [nodeRegion.left, nodeRegion.top];
 
280
                            break;
 
281
                        case PositionExt.TR:
 
282
                            xy = [nodeRegion.right, nodeRegion.top];
 
283
                            break;
 
284
                        case PositionExt.BL:
 
285
                            xy = [nodeRegion.left, nodeRegion.bottom];
 
286
                            break;
 
287
                        case PositionExt.BR:
 
288
                            xy = [nodeRegion.right, nodeRegion.bottom];
 
289
                            break;
 
290
                        case PositionExt.TC:
 
291
                            xy = [nodeRegion.left + Math.floor(nodeRegion.width/2), nodeRegion.top];
 
292
                            break;
 
293
                        case PositionExt.BC:
 
294
                            xy = [nodeRegion.left + Math.floor(nodeRegion.width/2), nodeRegion.bottom];
 
295
                            break;
 
296
                        case PositionExt.LC:
 
297
                            xy = [nodeRegion.left, nodeRegion.top + Math.floor(nodeRegion.height/2)];
 
298
                            break;
 
299
                        case PositionExt.RC:
 
300
                            xy = [nodeRegion.right, nodeRegion.top + Math.floor(nodeRegion.height/2), widgetPoint];
 
301
                            break;
 
302
                        case PositionExt.CC:
 
303
                            xy = [nodeRegion.left + Math.floor(nodeRegion.width/2), nodeRegion.top + Math.floor(nodeRegion.height/2), widgetPoint];
 
304
                            break;
 
305
                        default:
 
306
                            Y.log("align: Invalid Points Arguments", "info", "widget-position-extras");
 
307
                            break;
 
308
                    }
 
309
 
 
310
                    if (xy) {
 
311
                        this._doAlign(widgetPoint, xy[0], xy[1]);
 
312
                    }
 
313
                }
 
314
            },
 
315
 
 
316
            /**
 
317
             * Helper method, used to align the given point on the widget, with the XY page co-ordinates provided.
 
318
             *
 
319
             * @method _doAlign
 
320
             * @private
 
321
             * @param {String} widgetPoint Supported point constant (e.g. WidgetPositionExt.TL)
 
322
             * @param {Number} x X page co-ordinate to align to
 
323
             * @param {Number} y Y page co-ordinate to align to
 
324
             */
 
325
            _doAlign : function(widgetPoint, x, y) {
 
326
                var widgetNode = this._posNode,
 
327
                    xy;
 
328
 
 
329
                switch (widgetPoint) {
 
330
                    case PositionExt.TL:
 
331
                        xy = [x, y];
 
332
                        break;
 
333
                    case PositionExt.TR:
 
334
                        xy = [x - widgetNode.get(OFFSET_WIDTH), y];
 
335
                        break;
 
336
                    case PositionExt.BL:
 
337
                        xy = [x, y - widgetNode.get(OFFSET_HEIGHT)];
 
338
                        break;
 
339
                    case PositionExt.BR:
 
340
                        xy = [x - widgetNode.get(OFFSET_WIDTH), y - widgetNode.get(OFFSET_HEIGHT)];
 
341
                        break;
 
342
                    case PositionExt.TC:
 
343
                        xy = [x - (widgetNode.get(OFFSET_WIDTH)/2), y];
 
344
                        break;
 
345
                    case PositionExt.BC:
 
346
                        xy = [x - (widgetNode.get(OFFSET_WIDTH)/2), y - widgetNode.get(OFFSET_HEIGHT)];
 
347
                        break;
 
348
                    case PositionExt.LC:
 
349
                        xy = [x, y - (widgetNode.get(OFFSET_HEIGHT)/2)];
 
350
                        break;
 
351
                    case PositionExt.RC:
 
352
                        xy = [(x - widgetNode.get(OFFSET_WIDTH)), y - (widgetNode.get(OFFSET_HEIGHT)/2)];
 
353
                        break;
 
354
                    case PositionExt.CC:
 
355
                        xy = [x - (widgetNode.get(OFFSET_WIDTH)/2), y - (widgetNode.get(OFFSET_HEIGHT)/2)];
 
356
                        break;
 
357
                    default:
 
358
                        Y.log("align: Invalid Points Argument", "info", "widget-position-extras");
 
359
                        break;
 
360
                }
 
361
 
 
362
                if (xy) {
 
363
                    this.move(xy);
 
364
                }
 
365
            },
 
366
 
 
367
            /**
 
368
             * Aligns the Widget to the provided node (or viewport) using the provided
 
369
             * points. The method can be invoked directly, however it will result in 
 
370
             * the align attribute being out of sync with current position of the of Widget.
 
371
             * 
 
372
             * @method align
 
373
             * @param {Node | String | null} node A reference (or selector string) for the Node which with the Widget is to be aligned.
 
374
             * If null is passed in, the Widget will be aligned with the viewport.
 
375
             * @param {Array[2]} points A two element array, specifying the points on the Widget and node/viewport which need to be aligned. 
 
376
             * The first entry is the point on the Widget, and the second entry is the point on the node/viewport which need to align.
 
377
             * Valid point references are defined as static constants on the WidgetPositionExt class. 
 
378
             * 
 
379
             * e.g. [WidgetPositionExt.TL, WidgetPositionExt.TR] will align the top-left corner of the Widget with the top-right corner of the node/viewport.
 
380
             */
 
381
            align: function (node, points) {
 
382
                this.set(ALIGN, {node: node, points:points});
 
383
            },
 
384
 
 
385
            /**
 
386
             * Centers the container in the viewport, or if a node is passed in,
 
387
             * the node.
 
388
             *
 
389
             * @method centered
 
390
             * @param {Node | String} node Optional. A node reference or selector string defining the node 
 
391
             * inside which the Widget is to be centered. If not passed in, the Widget will be centered in the 
 
392
             * viewport.
 
393
             */
 
394
            centered: function (node) {
 
395
                this.align(node, [PositionExt.CC, PositionExt.CC]);
 
396
            }
 
397
        };
 
398
 
 
399
        Y.WidgetPositionExt = PositionExt;
 
400
 
 
401
 
 
402
 
 
403
}, '3.0.0pr2' ,{requires:['widget', 'widget-position']});