~ubuntu-branches/ubuntu/natty/otrs2/natty-updates

« back to all changes in this revision

Viewing changes to var/httpd/htdocs/yui/2.7.0/build/layout/layout-debug.js

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2010-08-09 19:43:44 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20100809194344-absef1ut5mfj3qhv
Tags: 2.4.7+dfsg1-1
* Strip out yui from the source in the dfsg version.
  Closes: #591196
* Depend on libjs-yui and link to this package, instead of using the embedded
  yui version. This changes make the flash ticket statistics unuseable!
  Closes: #592146

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3
 
Code licensed under the BSD License:
4
 
http://developer.yahoo.net/yui/license.txt
5
 
version: 2.7.0
6
 
*/
7
 
/**
8
 
 * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
9
 
 * @namespace YAHOO.widget
10
 
 * @requires yahoo, dom, element, event
11
 
 * @module layout
12
 
 */
13
 
(function() {
14
 
    var Dom = YAHOO.util.Dom,
15
 
        Event = YAHOO.util.Event,
16
 
        Lang = YAHOO.lang;
17
 
 
18
 
    /**
19
 
     * @constructor
20
 
     * @class Layout
21
 
     * @extends YAHOO.util.Element
22
 
     * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
23
 
     * @param {String/HTMLElement} el The element to make contain a layout.
24
 
     * @param {Object} attrs Object liternal containing configuration parameters.
25
 
    */
26
 
 
27
 
    var Layout = function(el, config) {
28
 
        YAHOO.log('Creating the Layout Object', 'info', 'Layout');
29
 
        if (Lang.isObject(el) && !el.tagName) {
30
 
            config = el;
31
 
            el = null;
32
 
        }
33
 
        if (Lang.isString(el)) {
34
 
            if (Dom.get(el)) {
35
 
                el = Dom.get(el);
36
 
            }
37
 
        }
38
 
        if (!el) {
39
 
            el = document.body;
40
 
        }
41
 
 
42
 
        var oConfig = {
43
 
            element: el,
44
 
            attributes: config || {}
45
 
        };
46
 
 
47
 
        Layout.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
48
 
    };
49
 
 
50
 
    /**
51
 
    * @private
52
 
    * @static
53
 
    * @property _instances
54
 
    * @description Internal hash table for all layout instances
55
 
    * @type Object
56
 
    */ 
57
 
    Layout._instances = {};
58
 
    /**
59
 
    * @static
60
 
    * @method getLayoutById 
61
 
    * @description Get's a layout object by the HTML id of the element associated with the Layout object.
62
 
    * @return {Object} The Layout Object
63
 
    */ 
64
 
    Layout.getLayoutById = function(id) {
65
 
        if (Layout._instances[id]) {
66
 
            return Layout._instances[id];
67
 
        }
68
 
        return false;
69
 
    };
70
 
 
71
 
    YAHOO.extend(Layout, YAHOO.util.Element, {
72
 
        /**
73
 
        * @property browser
74
 
        * @description A modified version of the YAHOO.env.ua object
75
 
        * @type Object
76
 
        */
77
 
        browser: function() {
78
 
            var b = YAHOO.env.ua;
79
 
            b.standardsMode = false;
80
 
            b.secure = false;
81
 
            return b;
82
 
        }(),
83
 
        /**
84
 
        * @private
85
 
        * @property _units
86
 
        * @description An object literal that contains a list of units in the layout
87
 
        * @type Object
88
 
        */
89
 
        _units: null,
90
 
        /**
91
 
        * @private
92
 
        * @property _rendered
93
 
        * @description Set to true when the layout is rendered
94
 
        * @type Boolean
95
 
        */
96
 
        _rendered: null,
97
 
        /**
98
 
        * @private
99
 
        * @property _zIndex
100
 
        * @description The zIndex to set all LayoutUnits to
101
 
        * @type Number
102
 
        */
103
 
        _zIndex: null,
104
 
        /**
105
 
        * @private
106
 
        * @property _sizes
107
 
        * @description A collection of the current sizes of all usable LayoutUnits to be used for calculations
108
 
        * @type Object
109
 
        */
110
 
        _sizes: null,
111
 
        /**
112
 
        * @private
113
 
        * @method _setBodySize
114
 
        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
115
 
        * @description Used to set the body size of the layout, sets the height and width of the parent container
116
 
        */
117
 
        _setBodySize: function(set) {
118
 
            var h = 0, w = 0;
119
 
            set = ((set === false) ? false : true);
120
 
 
121
 
            if (this._isBody) {
122
 
                h = Dom.getClientHeight();
123
 
                w = Dom.getClientWidth();
124
 
            } else {
125
 
                h = parseInt(this.getStyle('height'), 10);
126
 
                w = parseInt(this.getStyle('width'), 10);
127
 
                if (isNaN(w)) {
128
 
                    w = this.get('element').clientWidth;
129
 
                }
130
 
                if (isNaN(h)) {
131
 
                    h = this.get('element').clientHeight;
132
 
                }
133
 
            }
134
 
            if (this.get('minWidth')) {
135
 
                if (w < this.get('minWidth')) {
136
 
                    w = this.get('minWidth');
137
 
                }
138
 
            }
139
 
            if (this.get('minHeight')) {
140
 
                if (h < this.get('minHeight')) {
141
 
                    h = this.get('minHeight');
142
 
                }
143
 
            }
144
 
            if (set) {
145
 
                Dom.setStyle(this._doc, 'height', h + 'px');
146
 
                Dom.setStyle(this._doc, 'width', w + 'px');
147
 
            }
148
 
            this._sizes.doc = { h: h, w: w };
149
 
            YAHOO.log('Setting Body height and width: (' + h + ',' + w + ')', 'info', 'Layout');
150
 
            this._setSides(set);
151
 
        },
152
 
        /**
153
 
        * @private
154
 
        * @method _setSides
155
 
        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
156
 
        * @description Used to set the size and position of the left, right, top and bottom units
157
 
        */
158
 
        _setSides: function(set) {
159
 
            YAHOO.log('Setting side units', 'info', 'Layout');
160
 
            var h1 = ((this._units.top) ? this._units.top.get('height') : 0),
161
 
                h2 = ((this._units.bottom) ? this._units.bottom.get('height') : 0),
162
 
                h = this._sizes.doc.h,
163
 
                w = this._sizes.doc.w;
164
 
            set = ((set === false) ? false : true);
165
 
 
166
 
            this._sizes.top = {
167
 
                h: h1, w: ((this._units.top) ? w : 0),
168
 
                t: 0
169
 
            };
170
 
            this._sizes.bottom = {
171
 
                h: h2, w: ((this._units.bottom) ? w : 0)
172
 
            };
173
 
            
174
 
            var newH = (h - (h1 + h2));
175
 
 
176
 
            this._sizes.left = {
177
 
                h: newH, w: ((this._units.left) ? this._units.left.get('width') : 0)
178
 
            };
179
 
            this._sizes.right = {
180
 
                h: newH, w: ((this._units.right) ? this._units.right.get('width') : 0),
181
 
                l: ((this._units.right) ? (w - this._units.right.get('width')) : 0),
182
 
                t: ((this._units.top) ? this._sizes.top.h : 0)
183
 
            };
184
 
            
185
 
            if (this._units.right && set) {
186
 
                this._units.right.set('top', this._sizes.right.t);
187
 
                if (!this._units.right._collapsing) { 
188
 
                    this._units.right.set('left', this._sizes.right.l);
189
 
                }
190
 
                this._units.right.set('height', this._sizes.right.h, true);
191
 
            }
192
 
            if (this._units.left) {
193
 
                this._sizes.left.l = 0;
194
 
                if (this._units.top) {
195
 
                    this._sizes.left.t = this._sizes.top.h;
196
 
                } else {
197
 
                    this._sizes.left.t = 0;
198
 
                }
199
 
                if (set) {
200
 
                    this._units.left.set('top', this._sizes.left.t);
201
 
                    this._units.left.set('height', this._sizes.left.h, true);
202
 
                    this._units.left.set('left', 0);
203
 
                }
204
 
            }
205
 
            if (this._units.bottom) {
206
 
                this._sizes.bottom.t = this._sizes.top.h + this._sizes.left.h;
207
 
                if (set) {
208
 
                    this._units.bottom.set('top', this._sizes.bottom.t);
209
 
                    this._units.bottom.set('width', this._sizes.bottom.w, true);
210
 
                }
211
 
            }
212
 
            if (this._units.top) {
213
 
                if (set) {
214
 
                    this._units.top.set('width', this._sizes.top.w, true);
215
 
                }
216
 
            }
217
 
            YAHOO.log('Setting sizes: (' + Lang.dump(this._sizes) + ')', 'info', 'Layout');
218
 
            this._setCenter(set);
219
 
        },
220
 
        /**
221
 
        * @private
222
 
        * @method _setCenter
223
 
        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
224
 
        * @description Used to set the size and position of the center unit
225
 
        */
226
 
        _setCenter: function(set) {
227
 
            set = ((set === false) ? false : true);
228
 
            var h = this._sizes.left.h;
229
 
            var w = (this._sizes.doc.w - (this._sizes.left.w + this._sizes.right.w));
230
 
            if (set) {
231
 
                this._units.center.set('height', h, true);
232
 
                this._units.center.set('width', w, true);
233
 
                this._units.center.set('top', this._sizes.top.h);
234
 
                this._units.center.set('left', this._sizes.left.w);
235
 
            }
236
 
            this._sizes.center = { h: h, w: w, t: this._sizes.top.h, l: this._sizes.left.w };
237
 
            YAHOO.log('Setting Center size to: (' + h + ', ' + w + ')', 'info', 'Layout');
238
 
        },
239
 
        /**
240
 
        * @method getSizes
241
 
        * @description Get a reference to the internal Layout Unit sizes object used to build the layout wireframe
242
 
        * @return {Object} An object of the layout unit sizes
243
 
        */
244
 
        getSizes: function() {
245
 
            return this._sizes;
246
 
        },
247
 
        /**
248
 
        * @method getUnitById
249
 
        * @param {String} id The HTML element id of the unit
250
 
        * @description Get the LayoutUnit by it's HTML id
251
 
        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
252
 
        */
253
 
        getUnitById: function(id) {
254
 
            return YAHOO.widget.LayoutUnit.getLayoutUnitById(id);
255
 
        },
256
 
        /**
257
 
        * @method getUnitByPosition
258
 
        * @param {String} pos The position of the unit in this layout
259
 
        * @description Get the LayoutUnit by it's position in this layout
260
 
        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
261
 
        */
262
 
        getUnitByPosition: function(pos) {
263
 
            if (pos) {
264
 
                pos = pos.toLowerCase();
265
 
                if (this._units[pos]) {
266
 
                    return this._units[pos];
267
 
                }
268
 
                return false;
269
 
            }
270
 
            return false;
271
 
        },
272
 
        /**
273
 
        * @method removeUnit
274
 
        * @param {Object} unit The LayoutUnit that you want to remove
275
 
        * @description Remove the unit from this layout and resize the layout.
276
 
        */
277
 
        removeUnit: function(unit) {
278
 
            delete this._units[unit.get('position')];
279
 
            this.resize();
280
 
        },
281
 
        /**
282
 
        * @method addUnit
283
 
        * @param {Object} cfg The config for the LayoutUnit that you want to add
284
 
        * @description Add a unit to this layout and if the layout is rendered, resize the layout. 
285
 
        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
286
 
        */
287
 
        addUnit: function(cfg) {
288
 
            if (!cfg.position) {
289
 
                YAHOO.log('No position property passed', 'error', 'Layout');
290
 
                return false;
291
 
            }
292
 
            if (this._units[cfg.position]) {
293
 
                YAHOO.log('Position already exists', 'error', 'Layout');
294
 
                return false;
295
 
            }
296
 
            YAHOO.log('Adding Unit at position: ' + cfg.position, 'info', 'Layout');
297
 
            var element = null,
298
 
                el = null;
299
 
 
300
 
            if (cfg.id) {
301
 
                if (Dom.get(cfg.id)) {
302
 
                    element = Dom.get(cfg.id);
303
 
                    delete cfg.id;
304
 
 
305
 
                }
306
 
            }
307
 
            if (cfg.element) {
308
 
                element = cfg.element;
309
 
            }
310
 
 
311
 
            if (!el) {
312
 
                el = document.createElement('div');
313
 
                var id = Dom.generateId();
314
 
                el.id = id;
315
 
            }
316
 
 
317
 
            if (!element) {
318
 
                element = document.createElement('div');
319
 
            }
320
 
            Dom.addClass(element, 'yui-layout-wrap');
321
 
            if (this.browser.ie && !this.browser.standardsMode) {
322
 
                el.style.zoom = 1;
323
 
                element.style.zoom = 1;
324
 
            }
325
 
 
326
 
            if (el.firstChild) {
327
 
                el.insertBefore(element, el.firstChild);
328
 
            } else {
329
 
                el.appendChild(element);
330
 
            }
331
 
            this._doc.appendChild(el);
332
 
 
333
 
            var h = false, w = false;
334
 
 
335
 
            if (cfg.height) {
336
 
                h = parseInt(cfg.height, 10);
337
 
            }
338
 
            if (cfg.width) {
339
 
                w = parseInt(cfg.width, 10);
340
 
            }
341
 
            var unitConfig = {};
342
 
            YAHOO.lang.augmentObject(unitConfig, cfg); // break obj ref
343
 
 
344
 
            unitConfig.parent = this;
345
 
            unitConfig.wrap = element;
346
 
            unitConfig.height = h;
347
 
            unitConfig.width = w;
348
 
 
349
 
            var unit = new YAHOO.widget.LayoutUnit(el, unitConfig);
350
 
 
351
 
            unit.on('heightChange', this.resize, this, true);
352
 
            unit.on('widthChange', this.resize, this, true);
353
 
            unit.on('gutterChange', this.resize, this, true);
354
 
            this._units[cfg.position] = unit;
355
 
 
356
 
            if (this._rendered) {
357
 
                this.resize();
358
 
            }
359
 
 
360
 
            return unit;
361
 
        },
362
 
        /**
363
 
        * @private
364
 
        * @method _createUnits
365
 
        * @description Private method to create units from the config that was passed in.
366
 
        */
367
 
        _createUnits: function() {
368
 
            var units = this.get('units');
369
 
            for (var i in units) {
370
 
                if (Lang.hasOwnProperty(units, i)) {
371
 
                    this.addUnit(units[i]);
372
 
                }
373
 
            }
374
 
        },
375
 
        /**
376
 
        * @method resize
377
 
        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
378
 
        * @description Starts the chain of resize routines that will resize all the units.
379
 
        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
380
 
        */
381
 
        resize: function(set) {
382
 
            set = ((set === false) ? false : true);
383
 
            if (set) {
384
 
                var retVal = this.fireEvent('beforeResize');
385
 
                if (retVal === false) {
386
 
                    set = false;
387
 
                }
388
 
                if (this.browser.ie) {
389
 
                    if (this._isBody) {
390
 
                        Dom.removeClass(document.documentElement, 'yui-layout');
391
 
                        Dom.addClass(document.documentElement, 'yui-layout');
392
 
                    } else {
393
 
                        this.removeClass('yui-layout');
394
 
                        this.addClass('yui-layout');
395
 
                    }
396
 
                }
397
 
            }
398
 
            this._setBodySize(set);
399
 
            if (set) {
400
 
                this.fireEvent('resize', { target: this, sizes: this._sizes });
401
 
            }
402
 
            return this;
403
 
        },
404
 
        /**
405
 
        * @private
406
 
        * @method _setupBodyElements
407
 
        * @description Sets up the main doc element when using the body as the main element.
408
 
        */
409
 
        _setupBodyElements: function() {
410
 
            this._doc = Dom.get('layout-doc');
411
 
            if (!this._doc) {
412
 
                this._doc = document.createElement('div');
413
 
                this._doc.id = 'layout-doc';
414
 
                if (document.body.firstChild) {
415
 
                    document.body.insertBefore(this._doc, document.body.firstChild);
416
 
                } else {
417
 
                    document.body.appendChild(this._doc);
418
 
                }
419
 
            }
420
 
            this._createUnits();
421
 
            this._setBodySize();
422
 
            Event.on(window, 'resize', this.resize, this, true);
423
 
            Dom.addClass(this._doc, 'yui-layout-doc');
424
 
        },
425
 
        /**
426
 
        * @private
427
 
        * @method _setupElements
428
 
        * @description Sets up the main doc element when not using the body as the main element.
429
 
        */
430
 
        _setupElements: function() {
431
 
            this._doc = this.getElementsByClassName('yui-layout-doc')[0];
432
 
            if (!this._doc) {
433
 
                this._doc = document.createElement('div');
434
 
                this.get('element').appendChild(this._doc);
435
 
            }
436
 
            this._createUnits();
437
 
            this._setBodySize();
438
 
            Dom.addClass(this._doc, 'yui-layout-doc');
439
 
        },
440
 
        /**
441
 
        * @private
442
 
        * @property _isBody
443
 
        * @description Flag to determine if we are using the body as the root element.
444
 
        * @type Boolean
445
 
        */
446
 
        _isBody: null,
447
 
        /**
448
 
        * @private
449
 
        * @property _doc
450
 
        * @description Reference to the root element
451
 
        * @type HTMLElement
452
 
        */
453
 
        _doc: null,
454
 
        /**
455
 
        * @private
456
 
        * @method init
457
 
        * @description The Layout class' initialization method
458
 
        */        
459
 
        init: function(p_oElement, p_oAttributes) {
460
 
            YAHOO.log('init', 'info', 'Layout');
461
 
 
462
 
            this._zIndex = 0;
463
 
 
464
 
            Layout.superclass.init.call(this, p_oElement, p_oAttributes);
465
 
            
466
 
            if (this.get('parent')) {
467
 
                this._zIndex = this.get('parent')._zIndex + 10;
468
 
            }
469
 
 
470
 
            this._sizes = {};
471
 
            this._units = {};
472
 
 
473
 
            var id = p_oElement;
474
 
            if (!Lang.isString(id)) {
475
 
                id = Dom.generateId(id);
476
 
            }
477
 
            Layout._instances[id] = this;
478
 
        },
479
 
        /**
480
 
        * @method render
481
 
        * @description This method starts the render process, applying classnames and creating elements
482
 
        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
483
 
        */        
484
 
        render: function() {
485
 
            YAHOO.log('Render', 'info', 'Layout');
486
 
            this._stamp();
487
 
            var el = this.get('element');
488
 
            if (el && el.tagName && (el.tagName.toLowerCase() == 'body')) {
489
 
                this._isBody = true;
490
 
                Dom.addClass(document.body, 'yui-layout');
491
 
                if (Dom.hasClass(document.body, 'yui-skin-sam')) {
492
 
                    //Move the class up so we can have a css chain
493
 
                    Dom.addClass(document.documentElement, 'yui-skin-sam');
494
 
                    Dom.removeClass(document.body, 'yui-skin-sam');
495
 
                }
496
 
                this._setupBodyElements();
497
 
            } else {
498
 
                this._isBody = false;
499
 
                this.addClass('yui-layout');
500
 
                this._setupElements();
501
 
            }
502
 
            this.resize();
503
 
            this._rendered = true;
504
 
            this.fireEvent('render');
505
 
 
506
 
            return this;
507
 
        },
508
 
        /**
509
 
        * @private
510
 
        * @method _stamp
511
 
        * @description Stamps the root node with a secure classname for ease of use. Also sets the this.browser.standardsMode variable.
512
 
        */        
513
 
        _stamp: function() {
514
 
            if (document.compatMode == 'CSS1Compat') {
515
 
                this.browser.standardsMode = true;
516
 
            }
517
 
            if (window.location.href.toLowerCase().indexOf("https") === 0) {
518
 
                Dom.addClass(document.documentElement, 'secure');
519
 
                this.browser.secure = true;
520
 
            }
521
 
        },
522
 
        /**
523
 
        * @private
524
 
        * @method initAttributes
525
 
        * @description Processes the config
526
 
        */        
527
 
        initAttributes: function(attr) {
528
 
            Layout.superclass.initAttributes.call(this, attr);
529
 
            /**
530
 
            * @attribute units
531
 
            * @description An array of config definitions for the LayoutUnits to add to this layout
532
 
            * @type Array
533
 
            */
534
 
            this.setAttributeConfig('units', {
535
 
                writeOnce: true,
536
 
                validator: YAHOO.lang.isArray,
537
 
                value: attr.units || []
538
 
            });
539
 
 
540
 
            /**
541
 
            * @attribute minHeight
542
 
            * @description The minimum height in pixels
543
 
            * @type Number
544
 
            */
545
 
            this.setAttributeConfig('minHeight', {
546
 
                value: attr.minHeight || false,
547
 
                validator: YAHOO.lang.isNumber
548
 
            });
549
 
 
550
 
            /**
551
 
            * @attribute minWidth
552
 
            * @description The minimum width in pixels
553
 
            * @type Number
554
 
            */
555
 
            this.setAttributeConfig('minWidth', {
556
 
                value: attr.minWidth || false,
557
 
                validator: YAHOO.lang.isNumber
558
 
            });
559
 
 
560
 
            /**
561
 
            * @attribute height
562
 
            * @description The height in pixels
563
 
            * @type Number
564
 
            */
565
 
            this.setAttributeConfig('height', {
566
 
                value: attr.height || false,
567
 
                validator: YAHOO.lang.isNumber,
568
 
                method: function(h) {
569
 
                    this.setStyle('height', h + 'px');
570
 
                }
571
 
            });
572
 
 
573
 
            /**
574
 
            * @attribute width
575
 
            * @description The width in pixels
576
 
            * @type Number
577
 
            */
578
 
            this.setAttributeConfig('width', {
579
 
                value: attr.width || false,
580
 
                validator: YAHOO.lang.isNumber,
581
 
                method: function(w) {
582
 
                    this.setStyle('width', w + 'px');
583
 
                }
584
 
            });
585
 
 
586
 
            /**
587
 
            * @attribute parent
588
 
            * @description If this layout is to be used as a child of another Layout instance, this config will bind the resize events together.
589
 
            * @type Object YAHOO.widget.Layout
590
 
            */
591
 
            this.setAttributeConfig('parent', {
592
 
                writeOnce: true,
593
 
                value: attr.parent || false,
594
 
                method: function(p) {
595
 
                    if (p) {
596
 
                        p.on('resize', this.resize, this, true);
597
 
                    }
598
 
                }
599
 
            });
600
 
        },
601
 
        /**
602
 
        * @method destroy
603
 
        * @description Removes this layout from the page and destroys all units that it contains. This will destroy all data inside the layout and it's children.
604
 
        */
605
 
        destroy: function() {
606
 
            var par = this.get('parent');
607
 
            if (par) {
608
 
                par.removeListener('resize', this.resize, this, true);
609
 
            }
610
 
            Event.removeListener(window, 'resize', this.resize, this, true);
611
 
 
612
 
            this.unsubscribeAll();
613
 
            for (var u in this._units) {
614
 
                if (Lang.hasOwnProperty(this._units, u)) {
615
 
                    if (this._units[u]) {
616
 
                        this._units[u].destroy(true);
617
 
                    }
618
 
                }
619
 
            }
620
 
 
621
 
            Event.purgeElement(this.get('element'));
622
 
            this.get('parentNode').removeChild(this.get('element'));
623
 
            
624
 
            delete YAHOO.widget.Layout._instances[this.get('id')];
625
 
            //Brutal Object Destroy
626
 
            for (var i in this) {
627
 
                if (Lang.hasOwnProperty(this, i)) {
628
 
                    this[i] = null;
629
 
                    delete this[i];
630
 
                }
631
 
            }
632
 
            
633
 
            if (par) {
634
 
                par.resize();
635
 
            }
636
 
        },
637
 
        /**
638
 
        * @method toString
639
 
        * @description Returns a string representing the Layout.
640
 
        * @return {String}
641
 
        */        
642
 
        toString: function() {
643
 
            if (this.get) {
644
 
                return 'Layout #' + this.get('id');
645
 
            }
646
 
            return 'Layout';
647
 
        }
648
 
    });
649
 
    /**
650
 
    * @event resize
651
 
    * @description Fired when this.resize is called
652
 
    * @type YAHOO.util.CustomEvent
653
 
    */
654
 
    /**
655
 
    * @event startResize
656
 
    * @description Fired when the Resize Utility for a Unit fires it's startResize Event.
657
 
    * @type YAHOO.util.CustomEvent
658
 
    */
659
 
    /**
660
 
    * @event beforeResize
661
 
    * @description Fires at the beginning of the resize method. If you return false, the resize is cancelled.
662
 
    * @type YAHOO.util.CustomEvent
663
 
    */
664
 
    /**
665
 
    * @event render
666
 
    * @description Fired after the render method completes.
667
 
    * @type YAHOO.util.CustomEvent
668
 
    */
669
 
 
670
 
    YAHOO.widget.Layout = Layout;
671
 
})();
672
 
/**
673
 
 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
674
 
 * @namespace YAHOO.widget
675
 
 * @requires yahoo, dom, element, event, layout
676
 
 * @optional animation, dragdrop, selector
677
 
 */
678
 
(function() {
679
 
    var Dom = YAHOO.util.Dom,
680
 
        Sel = YAHOO.util.Selector,
681
 
        Event = YAHOO.util.Event,
682
 
        Lang = YAHOO.lang;
683
 
 
684
 
    /**
685
 
     * @constructor
686
 
     * @class LayoutUnit
687
 
     * @extends YAHOO.util.Element
688
 
     * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
689
 
     * @param {String/HTMLElement} el The element to make a unit.
690
 
     * @param {Object} attrs Object liternal containing configuration parameters.
691
 
    */
692
 
 
693
 
    var LayoutUnit = function(el, config) {
694
 
        
695
 
        var oConfig = {
696
 
            element: el,
697
 
            attributes: config || {}
698
 
        };
699
 
 
700
 
        LayoutUnit.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
701
 
    };
702
 
 
703
 
    /**
704
 
    * @private
705
 
    * @static
706
 
    * @property _instances
707
 
    * @description Internal hash table for all layout unit instances
708
 
    * @type Object
709
 
    */ 
710
 
    LayoutUnit._instances = {};
711
 
    /**
712
 
    * @static
713
 
    * @method getLayoutUnitById 
714
 
    * @description Get's a layout unit object by the HTML id of the element associated with the Layout Unit object.
715
 
    * @return {Object} The Layout Object
716
 
    */ 
717
 
    LayoutUnit.getLayoutUnitById = function(id) {
718
 
        if (LayoutUnit._instances[id]) {
719
 
            return LayoutUnit._instances[id];
720
 
        }
721
 
        return false;
722
 
    };
723
 
 
724
 
    YAHOO.extend(LayoutUnit, YAHOO.util.Element, {
725
 
        /**
726
 
        * @property STR_CLOSE
727
 
        * @description String used for close button title
728
 
        * @type {String}
729
 
        */
730
 
        STR_CLOSE: 'Click to close this pane.',
731
 
        /**
732
 
        * @property STR_COLLAPSE
733
 
        * @description String used for collapse button title
734
 
        * @type {String}
735
 
        */
736
 
        STR_COLLAPSE: 'Click to collapse this pane.',
737
 
        /**
738
 
        * @property STR_EXPAND
739
 
        * @description String used for expand button title
740
 
        * @type {String}
741
 
        */
742
 
        STR_EXPAND: 'Click to expand this pane.',
743
 
        /**
744
 
            * The class name applied to dynamic tabs while loading.
745
 
            * @property LOADING_CLASSNAME
746
 
            * @type String
747
 
            * @default "disabled"
748
 
            */
749
 
            LOADING_CLASSNAME: 'loading',
750
 
        /**
751
 
        * @property browser
752
 
        * @description A modified version of the YAHOO.env.ua object
753
 
        * @type Object
754
 
        */
755
 
        browser: null,
756
 
        /**
757
 
        * @private
758
 
        * @property _sizes
759
 
        * @description A collection of the current sizes of the contents of this Layout Unit
760
 
        * @type Object
761
 
        */
762
 
        _sizes: null,
763
 
        /**
764
 
        * @private
765
 
        * @property _anim
766
 
        * @description A reference to the Animation instance used by this LayouUnit
767
 
        * @type YAHOO.util.Anim
768
 
        */
769
 
        _anim: null,
770
 
        /**
771
 
        * @private
772
 
        * @property _resize
773
 
        * @description A reference to the Resize instance used by this LayoutUnit
774
 
        * @type YAHOO.util.Resize
775
 
        */
776
 
        _resize: null,
777
 
        /**
778
 
        * @private
779
 
        * @property _clip
780
 
        * @description A reference to the clip element used when collapsing the unit
781
 
        * @type HTMLElement
782
 
        */
783
 
        _clip: null,
784
 
        /**
785
 
        * @private
786
 
        * @property _gutter
787
 
        * @description A simple hash table used to store the gutter to apply to the Unit
788
 
        * @type Object
789
 
        */
790
 
        _gutter: null,
791
 
        /**
792
 
        * @property header
793
 
        * @description A reference to the HTML element used for the Header
794
 
        * @type HTMLELement
795
 
        */
796
 
        header: null,
797
 
        /**
798
 
        * @property body
799
 
        * @description A reference to the HTML element used for the body
800
 
        * @type HTMLElement
801
 
        */
802
 
        body: null,
803
 
        /**
804
 
        * @property footer
805
 
        * @description A reference to the HTML element used for the footer
806
 
        * @type HTMLElement
807
 
        */
808
 
        footer: null,
809
 
        /**
810
 
        * @private
811
 
        * @property _collapsed
812
 
        * @description Flag to determine if the unit is collapsed or not.
813
 
        * @type Boolean
814
 
        */
815
 
        _collapsed: null,
816
 
        /**
817
 
        * @private
818
 
        * @property _collapsing
819
 
        * @description A flag set while the unit is being collapsed, used so we don't fire events while animating the size
820
 
        * @type Boolean
821
 
        */
822
 
        _collapsing: null,
823
 
        /**
824
 
        * @private
825
 
        * @property _lastWidth
826
 
        * @description A holder for the last known width of the unit
827
 
        * @type Number
828
 
        */
829
 
        _lastWidth: null,
830
 
        /**
831
 
        * @private
832
 
        * @property _lastHeight
833
 
        * @description A holder for the last known height of the unit
834
 
        * @type Number
835
 
        */
836
 
        _lastHeight: null,
837
 
        /**
838
 
        * @private
839
 
        * @property _lastTop
840
 
        * @description A holder for the last known top of the unit
841
 
        * @type Number
842
 
        */
843
 
        _lastTop: null,
844
 
        /**
845
 
        * @private
846
 
        * @property _lastLeft
847
 
        * @description A holder for the last known left of the unit
848
 
        * @type Number
849
 
        */
850
 
        _lastLeft: null,
851
 
        /**
852
 
        * @private
853
 
        * @property _lastScroll
854
 
        * @description A holder for the last known scroll state of the unit
855
 
        * @type Boolean
856
 
        */
857
 
        _lastScroll: null,
858
 
        /**
859
 
        * @private
860
 
        * @property _lastCenetrScroll
861
 
        * @description A holder for the last known scroll state of the center unit
862
 
        * @type Boolean
863
 
        */
864
 
        _lastCenterScroll: null,
865
 
        /**
866
 
        * @private
867
 
        * @property _lastScrollTop
868
 
        * @description A holder for the last known scrollTop state of the unit
869
 
        * @type Number
870
 
        */
871
 
        _lastScrollTop: null,
872
 
        /**
873
 
        * @method resize
874
 
        * @description Resize either the unit or it's clipped state, also updating the box inside
875
 
        * @param {Boolean} force This will force full calculations even when the unit is collapsed
876
 
        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
877
 
        */
878
 
        resize: function(force) {
879
 
            YAHOO.log('Resize', 'info', 'LayoutUnit');
880
 
            var retVal = this.fireEvent('beforeResize');
881
 
            if (retVal === false) {
882
 
                return this;
883
 
            }
884
 
            if (!this._collapsing || (force === true)) {
885
 
                var scroll = this.get('scroll');
886
 
                this.set('scroll', false);
887
 
 
888
 
 
889
 
                var hd = this._getBoxSize(this.header),
890
 
                    ft = this._getBoxSize(this.footer),
891
 
                    box = [this.get('height'), this.get('width')];
892
 
 
893
 
                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
894
 
                    nw = box[1] - (this._gutter.left + this._gutter.right);
895
 
 
896
 
                var wrapH = (nh + (hd[0] + ft[0])),
897
 
                    wrapW = nw;
898
 
 
899
 
                if (this._collapsed && !this._collapsing) {
900
 
                    this._setHeight(this._clip, wrapH);
901
 
                    this._setWidth(this._clip, wrapW);
902
 
                    Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
903
 
                    Dom.setStyle(this._clip, 'left', this.get('left') + this._gutter.left + 'px');
904
 
                } else if (!this._collapsed || (this._collapsed && this._collapsing)) {
905
 
                    wrapH = this._setHeight(this.get('wrap'), wrapH);
906
 
                    wrapW = this._setWidth(this.get('wrap'), wrapW);
907
 
                    this._sizes.wrap.h = wrapH;
908
 
                    this._sizes.wrap.w = wrapW;
909
 
 
910
 
                    Dom.setStyle(this.get('wrap'), 'top', this._gutter.top + 'px');
911
 
                    Dom.setStyle(this.get('wrap'), 'left', this._gutter.left + 'px');
912
 
 
913
 
                    this._sizes.header.w = this._setWidth(this.header, wrapW);
914
 
                    this._sizes.header.h = hd[0];
915
 
 
916
 
                    this._sizes.footer.w = this._setWidth(this.footer, wrapW);
917
 
                    this._sizes.footer.h = ft[0];
918
 
 
919
 
                    Dom.setStyle(this.footer, 'bottom', '0px');
920
 
 
921
 
                    this._sizes.body.h = this._setHeight(this.body, (wrapH - (hd[0] + ft[0])));
922
 
                    this._sizes.body.w =this._setWidth(this.body, wrapW);
923
 
                    Dom.setStyle(this.body, 'top', hd[0] + 'px');
924
 
 
925
 
                    this.set('scroll', scroll);
926
 
                    this.fireEvent('resize');
927
 
                }
928
 
            }
929
 
            return this;
930
 
        },
931
 
        /**
932
 
        * @private
933
 
        * @method _setWidth
934
 
        * @description Sets the width of the element based on the border size of the element.
935
 
        * @param {HTMLElement} el The HTMLElement to have it's width set
936
 
        * @param {Number} w The width that you want it the element set to
937
 
        * @return {Number} The new width, fixed for borders and IE QuirksMode
938
 
        */
939
 
        _setWidth: function(el, w) {
940
 
            if (el) {
941
 
                var b = this._getBorderSizes(el);
942
 
                w = (w - (b[1] + b[3]));
943
 
                w = this._fixQuirks(el, w, 'w');
944
 
                if (w < 0) {
945
 
                    w = 0;
946
 
                }
947
 
                Dom.setStyle(el, 'width', w + 'px');
948
 
            }
949
 
            return w;
950
 
        },
951
 
        /**
952
 
        * @private
953
 
        * @method _setHeight
954
 
        * @description Sets the height of the element based on the border size of the element.
955
 
        * @param {HTMLElement} el The HTMLElement to have it's height set
956
 
        * @param {Number} h The height that you want it the element set to
957
 
        * @return {Number} The new height, fixed for borders and IE QuirksMode
958
 
        */
959
 
        _setHeight: function(el, h) {
960
 
            if (el) {
961
 
                var b = this._getBorderSizes(el);
962
 
                h = (h - (b[0] + b[2]));
963
 
                h = this._fixQuirks(el, h, 'h');
964
 
                if (h < 0) {
965
 
                    h = 0;
966
 
                }
967
 
                Dom.setStyle(el, 'height', h + 'px');
968
 
            }
969
 
            return h;
970
 
        },
971
 
        /**
972
 
        * @private
973
 
        * @method _fixQuirks
974
 
        * @description Fixes the box calculations for IE in QuirksMode
975
 
        * @param {HTMLElement} el The HTMLElement to set the dimension on
976
 
        * @param {Number} dim The number of the dimension to fix
977
 
        * @param {String} side The dimension (h or w) to fix. Defaults to h
978
 
        * @return {Number} The fixed dimension
979
 
        */
980
 
        _fixQuirks: function(el, dim, side) {
981
 
            var i1 = 0, i2 = 2;
982
 
            if (side == 'w') {
983
 
                i1 = 1;
984
 
                i2 = 3;
985
 
            }
986
 
            if (this.browser.ie && !this.browser.standardsMode) {
987
 
                //Internet Explorer - Quirks Mode
988
 
                var b = this._getBorderSizes(el),
989
 
                    bp = this._getBorderSizes(el.parentNode);
990
 
                if ((b[i1] === 0) && (b[i2] === 0)) { //No Borders, check parent
991
 
                    if ((bp[i1] !== 0) && (bp[i2] !== 0)) { //Parent has Borders
992
 
                        dim = (dim - (bp[i1] + bp[i2]));
993
 
                    }
994
 
                } else {
995
 
                    if ((bp[i1] === 0) && (bp[i2] === 0)) {
996
 
                        dim = (dim + (b[i1] + b[i2]));
997
 
                    }
998
 
                }
999
 
            }
1000
 
            return dim;
1001
 
        },
1002
 
        /**
1003
 
        * @private
1004
 
        * @method _getBoxSize
1005
 
        * @description Get's the elements clientHeight and clientWidth plus the size of the borders
1006
 
        * @param {HTMLElement} el The HTMLElement to get the size of
1007
 
        * @return {Array} An array of height and width
1008
 
        */
1009
 
        _getBoxSize: function(el) {
1010
 
            var size = [0, 0];
1011
 
            if (el) {
1012
 
                if (this.browser.ie && !this.browser.standardsMode) {
1013
 
                    el.style.zoom = 1;
1014
 
                }
1015
 
                var b = this._getBorderSizes(el);
1016
 
                size[0] = el.clientHeight + (b[0] + b[2]);
1017
 
                size[1] = el.clientWidth + (b[1] + b[3]);
1018
 
            }
1019
 
            return size;
1020
 
        },
1021
 
        /**
1022
 
        * @private
1023
 
        * @method _getBorderSizes
1024
 
        * @description Get the CSS border size of the element passed.
1025
 
        * @param {HTMLElement} el The element to get the border size of
1026
 
        * @return {Array} An array of the top, right, bottom, left borders.
1027
 
        */
1028
 
        _getBorderSizes: function(el) {
1029
 
            var s = [];
1030
 
            el = el || this.get('element');
1031
 
            if (this.browser.ie && !this.browser.standardsMode) {
1032
 
                el.style.zoom = 1;
1033
 
            }
1034
 
            s[0] = parseInt(Dom.getStyle(el, 'borderTopWidth'), 10);
1035
 
            s[1] = parseInt(Dom.getStyle(el, 'borderRightWidth'), 10);
1036
 
            s[2] = parseInt(Dom.getStyle(el, 'borderBottomWidth'), 10);
1037
 
            s[3] = parseInt(Dom.getStyle(el, 'borderLeftWidth'), 10);
1038
 
            
1039
 
            //IE will return NaN on these if they are set to auto, we'll set them to 0
1040
 
            for (var i = 0; i < s.length; i++) {
1041
 
                if (isNaN(s[i])) {
1042
 
                    s[i] = 0;
1043
 
                }
1044
 
            }
1045
 
            return s;
1046
 
        },
1047
 
        /**
1048
 
        * @private
1049
 
        * @method _createClip
1050
 
        * @description Create the clip element used when the Unit is collapsed
1051
 
        */
1052
 
        _createClip: function() {
1053
 
            if (!this._clip) {
1054
 
                this._clip = document.createElement('div');
1055
 
                this._clip.className = 'yui-layout-clip yui-layout-clip-' + this.get('position');
1056
 
                this._clip.innerHTML = '<div class="collapse"></div>';
1057
 
                var c = this._clip.firstChild;
1058
 
                c.title = this.STR_EXPAND;
1059
 
                Event.on(c, 'click', this.expand, this, true);
1060
 
                this.get('element').parentNode.appendChild(this._clip);
1061
 
            }
1062
 
        },
1063
 
        /**
1064
 
        * @private
1065
 
        * @method _toggleClip
1066
 
        * @description Toggle th current state of the Clip element and set it's height, width and position
1067
 
        */
1068
 
        _toggleClip: function() {
1069
 
            if (!this._collapsed) {
1070
 
                //show
1071
 
                var hd = this._getBoxSize(this.header),
1072
 
                    ft = this._getBoxSize(this.footer),
1073
 
                    box = [this.get('height'), this.get('width')];
1074
 
 
1075
 
 
1076
 
                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
1077
 
                    nw = box[1] - (this._gutter.left + this._gutter.right),
1078
 
                    wrapH = (nh + (hd[0] + ft[0]));
1079
 
 
1080
 
                switch (this.get('position')) {
1081
 
                    case 'top':
1082
 
                    case 'bottom':
1083
 
                        this._setWidth(this._clip, nw);
1084
 
                        this._setHeight(this._clip, this.get('collapseSize'));
1085
 
                        Dom.setStyle(this._clip, 'left', (this._lastLeft + this._gutter.left) + 'px');
1086
 
                        if (this.get('position') == 'bottom') {
1087
 
                            Dom.setStyle(this._clip, 'top', ((this._lastTop + this._lastHeight) - (this.get('collapseSize') - this._gutter.top)) + 'px');
1088
 
                        } else {
1089
 
                            Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
1090
 
                        }
1091
 
                        break;
1092
 
                    case 'left':
1093
 
                    case 'right':
1094
 
                        this._setWidth(this._clip, this.get('collapseSize'));
1095
 
                        this._setHeight(this._clip, wrapH);
1096
 
                        Dom.setStyle(this._clip, 'top', (this.get('top') + this._gutter.top) + 'px');
1097
 
                        if (this.get('position') == 'right') {
1098
 
                            Dom.setStyle(this._clip, 'left', (((this._lastLeft + this._lastWidth) - this.get('collapseSize')) - this._gutter.left) + 'px');
1099
 
                        } else {
1100
 
                            Dom.setStyle(this._clip, 'left', (this.get('left') + this._gutter.left) + 'px');
1101
 
                        }
1102
 
                        break;
1103
 
                }
1104
 
 
1105
 
                Dom.setStyle(this._clip, 'display', 'block');
1106
 
                this.setStyle('display', 'none');
1107
 
            } else {
1108
 
                //Hide
1109
 
                Dom.setStyle(this._clip, 'display', 'none');
1110
 
            }
1111
 
        },
1112
 
        /**
1113
 
        * @method getSizes
1114
 
        * @description Get a reference to the internal sizes object for this unit
1115
 
        * @return {Object} An object of the sizes used for calculations
1116
 
        */
1117
 
        getSizes: function() {
1118
 
            return this._sizes;
1119
 
        },
1120
 
        /**
1121
 
        * @method toggle
1122
 
        * @description Toggles the Unit, replacing it with a clipped version.
1123
 
        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1124
 
        */
1125
 
        toggle: function() {
1126
 
            if (this._collapsed) {
1127
 
                this.expand();
1128
 
            } else {
1129
 
                this.collapse();
1130
 
            }
1131
 
            return this;
1132
 
        },
1133
 
        /**
1134
 
        * @method expand
1135
 
        * @description Expand the Unit if it is collapsed.
1136
 
        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1137
 
        */
1138
 
        expand: function() {
1139
 
            if (!this._collapsed) {
1140
 
                return this;
1141
 
            }
1142
 
            var retVal = this.fireEvent('beforeExpand');
1143
 
            if (retVal === false) {
1144
 
                return this;
1145
 
            }
1146
 
 
1147
 
            this._collapsing = true;
1148
 
            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1149
 
 
1150
 
            if (this._anim) {
1151
 
                this.setStyle('display', 'none');
1152
 
                var attr = {}, s;
1153
 
 
1154
 
                switch (this.get('position')) {
1155
 
                    case 'left':
1156
 
                    case 'right':
1157
 
                        this.set('width', this._lastWidth, true);
1158
 
                        this.setStyle('width', this._lastWidth + 'px');
1159
 
                        this.get('parent').resize(false);
1160
 
                        s = this.get('parent').getSizes()[this.get('position')];
1161
 
                        this.set('height', s.h, true);
1162
 
                        var left = s.l;
1163
 
                        attr = {
1164
 
                            left: {
1165
 
                                to: left
1166
 
                            }
1167
 
                        };
1168
 
                        if (this.get('position') == 'left') {
1169
 
                            attr.left.from = (left - s.w);
1170
 
                            this.setStyle('left', (left - s.w) + 'px');
1171
 
                        }
1172
 
                        break;
1173
 
                    case 'top':
1174
 
                    case 'bottom':
1175
 
                        this.set('height', this._lastHeight, true);
1176
 
                        this.setStyle('height', this._lastHeight + 'px');
1177
 
                        this.get('parent').resize(false);
1178
 
                        s = this.get('parent').getSizes()[this.get('position')];
1179
 
                        this.set('width', s.w, true);
1180
 
                        var top = s.t;
1181
 
                        attr = {
1182
 
                            top: {
1183
 
                                to: top
1184
 
                            }
1185
 
                        };
1186
 
                        if (this.get('position') == 'top') {
1187
 
                            this.setStyle('top',  (top - s.h) + 'px');
1188
 
                            attr.top.from = (top - s.h);
1189
 
                        }
1190
 
                        break;
1191
 
                }
1192
 
 
1193
 
                this._anim.attributes = attr;
1194
 
                var exStart = function() {
1195
 
                    this.setStyle('display', 'block');
1196
 
                    this.resize(true);
1197
 
                    this._anim.onStart.unsubscribe(exStart, this, true);
1198
 
                };
1199
 
                var expand = function() {
1200
 
                    this._collapsing = false;
1201
 
                    this.setStyle('zIndex', this.get('parent')._zIndex);
1202
 
                    this.set('width', this._lastWidth);
1203
 
                    this.set('height', this._lastHeight);
1204
 
                    this._collapsed = false;
1205
 
                    this.resize();
1206
 
                    this.set('scroll', this._lastScroll);
1207
 
                    if (this._lastScrollTop > 0) {
1208
 
                        this.body.scrollTop = this._lastScrollTop;
1209
 
                    }
1210
 
                    this._anim.onComplete.unsubscribe(expand, this, true);
1211
 
                    this.fireEvent('expand');
1212
 
                };
1213
 
                this._anim.onStart.subscribe(exStart, this, true);
1214
 
                this._anim.onComplete.subscribe(expand, this, true);
1215
 
                this._anim.animate();
1216
 
                this._toggleClip();
1217
 
            } else {
1218
 
                this._collapsing = false;
1219
 
                this._toggleClip();
1220
 
                this._collapsed = false;
1221
 
                this.setStyle('zIndex', this.get('parent')._zIndex);
1222
 
                this.setStyle('display', 'block');
1223
 
                this.set('width', this._lastWidth);
1224
 
                this.set('height', this._lastHeight);
1225
 
                this.resize();
1226
 
                this.set('scroll', this._lastScroll);
1227
 
                if (this._lastScrollTop > 0) {
1228
 
                    this.body.scrollTop = this._lastScrollTop;
1229
 
                }
1230
 
                this.fireEvent('expand');
1231
 
            }
1232
 
            return this;
1233
 
        },
1234
 
        /**
1235
 
        * @method collapse
1236
 
        * @description Collapse the Unit if it is not collapsed.
1237
 
        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1238
 
        */
1239
 
        collapse: function() {
1240
 
            if (this._collapsed) {
1241
 
                return this;
1242
 
            }
1243
 
            var retValue = this.fireEvent('beforeCollapse');
1244
 
            if (retValue === false) {
1245
 
                return this;
1246
 
            }
1247
 
            if (!this._clip) {
1248
 
                this._createClip();
1249
 
            }
1250
 
            this._collapsing = true;
1251
 
            var w = this.get('width'),
1252
 
                h = this.get('height'),
1253
 
                attr = {};
1254
 
            this._lastWidth = w;
1255
 
            this._lastHeight = h;
1256
 
            this._lastScroll = this.get('scroll');
1257
 
            this._lastScrollTop = this.body.scrollTop;            
1258
 
            this.set('scroll', false, true);
1259
 
            this._lastLeft = parseInt(this.get('element').style.left, 10);
1260
 
            this._lastTop = parseInt(this.get('element').style.top, 10);
1261
 
            if (isNaN(this._lastTop)) {
1262
 
                this._lastTop = 0;
1263
 
                this.set('top', 0);
1264
 
            }
1265
 
            if (isNaN(this._lastLeft)) {
1266
 
                this._lastLeft = 0;
1267
 
                this.set('left', 0);
1268
 
            }
1269
 
            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1270
 
            var pos = this.get('position');
1271
 
 
1272
 
            switch (pos) {
1273
 
                case 'top':
1274
 
                case 'bottom':
1275
 
                    this.set('height', (this.get('collapseSize') + (this._gutter.top + this._gutter.bottom)));
1276
 
                    attr = {
1277
 
                        top: {
1278
 
                            to: (this.get('top') - h)
1279
 
                        }
1280
 
                    };
1281
 
                    if (pos == 'bottom') {
1282
 
                        attr.top.to = (this.get('top') + h);
1283
 
                    }
1284
 
                    break;
1285
 
                case 'left':
1286
 
                case 'right':
1287
 
                    this.set('width', (this.get('collapseSize') + (this._gutter.left + this._gutter.right)));
1288
 
                    attr = {
1289
 
                        left: {
1290
 
                            to: -(this._lastWidth)
1291
 
                        }
1292
 
                    };
1293
 
                    if (pos == 'right') {
1294
 
                        attr.left = {
1295
 
                            to: (this.get('left') + w)
1296
 
                        };
1297
 
                    }
1298
 
                    break;
1299
 
            }
1300
 
            if (this._anim) {
1301
 
                this._anim.attributes = attr;
1302
 
                var collapse = function() {
1303
 
                    this._collapsing = false;
1304
 
                    this._toggleClip();
1305
 
                    this.setStyle('zIndex', this.get('parent')._zIndex);
1306
 
                    this._collapsed = true;
1307
 
                    this.get('parent').resize();
1308
 
                    this._anim.onComplete.unsubscribe(collapse, this, true);
1309
 
                    this.fireEvent('collapse');
1310
 
                };
1311
 
                this._anim.onComplete.subscribe(collapse, this, true);
1312
 
                this._anim.animate();
1313
 
            } else {
1314
 
                this._collapsing = false;
1315
 
                this.setStyle('display', 'none');
1316
 
                this._toggleClip();
1317
 
                this.setStyle('zIndex', this.get('parent')._zIndex);
1318
 
                this.get('parent').resize();
1319
 
                this._collapsed = true;
1320
 
                this.fireEvent('collapse');
1321
 
            }
1322
 
            return this;
1323
 
        },
1324
 
        /**
1325
 
        * @method close
1326
 
        * @description Close the unit, removing it from the parent Layout.
1327
 
        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
1328
 
        */
1329
 
        close: function() {
1330
 
            this.setStyle('display', 'none');
1331
 
            this.get('parent').removeUnit(this);
1332
 
            this.fireEvent('close');
1333
 
            if (this._clip) {
1334
 
                this._clip.parentNode.removeChild(this._clip);
1335
 
                this._clip = null;
1336
 
            }
1337
 
            return this.get('parent');
1338
 
        },
1339
 
                /**
1340
 
        * @property loadHandler
1341
 
        * @description Callback method for the YUI Connection Manager used for load the body using AJAX
1342
 
        * @type Object
1343
 
        */
1344
 
                loadHandler: {
1345
 
            success: function(o) {
1346
 
                                this.body.innerHTML = o.responseText;
1347
 
                                this.resize (true);
1348
 
            },
1349
 
            failure: function(o) {
1350
 
            }
1351
 
        },
1352
 
                /**
1353
 
        * @property dataConnection
1354
 
        * @description YUI Connection Manager handler
1355
 
        * @type Object
1356
 
        */
1357
 
                dataConnection: null,
1358
 
                /**
1359
 
        * @private
1360
 
        * @property _loading
1361
 
        * @description During the loading process this variable will be true
1362
 
        * @type Number
1363
 
        */
1364
 
        _loading: false,
1365
 
                /**
1366
 
        * @method loadContent
1367
 
        * @description Loading the content of the unit using the connection manager
1368
 
        * @return {object} YUI Connection Manager handler
1369
 
        */
1370
 
        loadContent: function() {
1371
 
                        // load dynamic content unless already loading or loaded and caching
1372
 
                        if (YAHOO.util.Connect && this.get('dataSrc') && !this._loading && !this.get('dataLoaded')) {
1373
 
                        this._loading = true; 
1374
 
                        Dom.addClass(this.body, this.LOADING_CLASSNAME);
1375
 
                                this.dataConnection = YAHOO.util.Connect.asyncRequest(
1376
 
                            this.get('loadMethod'),
1377
 
                            this.get('dataSrc'), 
1378
 
                            {
1379
 
                                success: function(o) {
1380
 
                                    this.loadHandler.success.call(this, o);
1381
 
                                    this.set('dataLoaded', true);
1382
 
                                    this.dataConnection = null;
1383
 
                                    Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1384
 
                                                        this._loading = false;
1385
 
                                                        this.fireEvent('load');
1386
 
                                },
1387
 
                                failure: function(o) {
1388
 
                                    this.loadHandler.failure.call(this, o);
1389
 
                                    this.dataConnection = null;
1390
 
                                    Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1391
 
                                    this._loading = false;
1392
 
                                                        this.fireEvent('loadError', { error: o });
1393
 
                                },
1394
 
                                scope: this,
1395
 
                                timeout: this.get('dataTimeout')
1396
 
                            }
1397
 
                        );
1398
 
                                return this.dataConnection;
1399
 
                }
1400
 
                        return false;
1401
 
        },
1402
 
        /**
1403
 
        * @private
1404
 
        * @method init
1405
 
        * @description The initalization method inherited from Element.
1406
 
        */
1407
 
        init: function(p_oElement, p_oAttributes) {
1408
 
            YAHOO.log('init', 'info', 'LayoutUnit');
1409
 
            this._gutter = {
1410
 
                left: 0,
1411
 
                right: 0,
1412
 
                top: 0,
1413
 
                bottom: 0
1414
 
            };
1415
 
            this._sizes = {
1416
 
                wrap: {
1417
 
                    h: 0,
1418
 
                    w: 0
1419
 
                },
1420
 
                header: {
1421
 
                    h: 0,
1422
 
                    w: 0
1423
 
                },
1424
 
                body: {
1425
 
                    h: 0,
1426
 
                    w: 0
1427
 
                },
1428
 
                footer: {
1429
 
                    h: 0,
1430
 
                    w: 0
1431
 
                }
1432
 
            };
1433
 
            
1434
 
            LayoutUnit.superclass.init.call(this, p_oElement, p_oAttributes);
1435
 
 
1436
 
            this.browser = this.get('parent').browser;
1437
 
            
1438
 
            var id = p_oElement;
1439
 
            if (!Lang.isString(id)) {
1440
 
                id = Dom.generateId(id);
1441
 
            }
1442
 
            LayoutUnit._instances[id] = this;
1443
 
 
1444
 
            this.setStyle('position', 'absolute');
1445
 
 
1446
 
            this.addClass('yui-layout-unit');
1447
 
            this.addClass('yui-layout-unit-' + this.get('position'));
1448
 
 
1449
 
 
1450
 
            var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1451
 
            if (header) {
1452
 
                this.header = header;
1453
 
            }
1454
 
            var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1455
 
            if (body) {
1456
 
                this.body = body;
1457
 
            }
1458
 
            var footer = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1459
 
            if (footer) {
1460
 
                this.footer = footer;
1461
 
            }
1462
 
 
1463
 
            this.on('contentChange', this.resize, this, true);
1464
 
            this._lastScrollTop = 0;
1465
 
 
1466
 
            this.set('animate', this.get('animate'));
1467
 
        },
1468
 
        /**
1469
 
        * @private
1470
 
        * @method initAttributes
1471
 
        * @description Processes the config
1472
 
        */        
1473
 
        initAttributes: function(attr) {
1474
 
            LayoutUnit.superclass.initAttributes.call(this, attr);
1475
 
 
1476
 
            /**
1477
 
            * @private
1478
 
            * @attribute wrap
1479
 
            * @description A reference to the wrap element
1480
 
            * @type HTMLElement
1481
 
            */
1482
 
            this.setAttributeConfig('wrap', {
1483
 
                value: attr.wrap || null,
1484
 
                method: function(w) {
1485
 
                    if (w) {
1486
 
                        var id = Dom.generateId(w);
1487
 
                        LayoutUnit._instances[id] = this;
1488
 
                    }
1489
 
                }
1490
 
            });
1491
 
            /**
1492
 
            * @attribute grids
1493
 
            * @description Set this option to true if you want the LayoutUnit to fix the first layer of YUI CSS Grids (margins)
1494
 
            * @type Boolean
1495
 
            */
1496
 
            this.setAttributeConfig('grids', {
1497
 
                value: attr.grids || false
1498
 
            });
1499
 
            /**
1500
 
            * @private
1501
 
            * @attribute top
1502
 
            * @description The current top positioning of the Unit
1503
 
            * @type Number
1504
 
            */
1505
 
            this.setAttributeConfig('top', {
1506
 
                value: attr.top || 0,
1507
 
                validator: Lang.isNumber,
1508
 
                method: function(t) {
1509
 
                    if (!this._collapsing) {
1510
 
                        this.setStyle('top', t + 'px');
1511
 
                    }
1512
 
                }
1513
 
            });
1514
 
            /**
1515
 
            * @private
1516
 
            * @attribute left
1517
 
            * @description The current left position of the Unit
1518
 
            * @type Number
1519
 
            */
1520
 
            this.setAttributeConfig('left', {
1521
 
                value: attr.left || 0,
1522
 
                validator: Lang.isNumber,
1523
 
                method: function(l) {
1524
 
                    if (!this._collapsing) {
1525
 
                        this.setStyle('left', l + 'px');
1526
 
                    }
1527
 
                }
1528
 
            });
1529
 
 
1530
 
            /**
1531
 
            * @attribute minWidth
1532
 
            * @description The minWidth parameter passed to the Resize Utility
1533
 
            * @type Number
1534
 
            */
1535
 
            this.setAttributeConfig('minWidth', {
1536
 
                value: attr.minWidth || false,
1537
 
                validator: YAHOO.lang.isNumber
1538
 
            });
1539
 
 
1540
 
            /**
1541
 
            * @attribute maxWidth
1542
 
            * @description The maxWidth parameter passed to the Resize Utility
1543
 
            * @type Number
1544
 
            */
1545
 
            this.setAttributeConfig('maxWidth', {
1546
 
                value: attr.maxWidth || false,
1547
 
                validator: YAHOO.lang.isNumber
1548
 
            });
1549
 
 
1550
 
            /**
1551
 
            * @attribute minHeight
1552
 
            * @description The minHeight parameter passed to the Resize Utility
1553
 
            * @type Number
1554
 
            */
1555
 
            this.setAttributeConfig('minHeight', {
1556
 
                value: attr.minHeight || false,
1557
 
                validator: YAHOO.lang.isNumber
1558
 
            });
1559
 
 
1560
 
            /**
1561
 
            * @attribute maxHeight
1562
 
            * @description The maxHeight parameter passed to the Resize Utility
1563
 
            * @type Number
1564
 
            */
1565
 
            this.setAttributeConfig('maxHeight', {
1566
 
                value: attr.maxHeight || false,
1567
 
                validator: YAHOO.lang.isNumber
1568
 
            });
1569
 
 
1570
 
            /**
1571
 
            * @attribute height
1572
 
            * @description The height of the Unit
1573
 
            * @type Number
1574
 
            */
1575
 
            this.setAttributeConfig('height', {
1576
 
                value: attr.height,
1577
 
                validator: Lang.isNumber,
1578
 
                method: function(h) {
1579
 
                    if (!this._collapsing) {
1580
 
                        if (h < 0) {
1581
 
                            h = 0;
1582
 
                        }
1583
 
                        this.setStyle('height', h + 'px');
1584
 
                    }
1585
 
                }
1586
 
            });
1587
 
 
1588
 
            /**
1589
 
            * @attribute width
1590
 
            * @description The width of the Unit
1591
 
            * @type Number
1592
 
            */
1593
 
            this.setAttributeConfig('width', {
1594
 
                value: attr.width,
1595
 
                validator: Lang.isNumber,
1596
 
                method: function(w) {
1597
 
                    if (!this._collapsing) {
1598
 
                        if (w < 0) {
1599
 
                            w = 0;
1600
 
                        }
1601
 
                        this.setStyle('width', w + 'px');
1602
 
                    }
1603
 
                }
1604
 
            });
1605
 
            /**
1606
 
            * @attribute zIndex
1607
 
            * @description The CSS zIndex to give to the unit, so you can have overlapping elements such as menus in a unit.
1608
 
            * @type {Number}
1609
 
            */
1610
 
            this.setAttributeConfig('zIndex', {
1611
 
                value: attr.zIndex || false,
1612
 
                method: function(z) {
1613
 
                    this.setStyle('zIndex', z);
1614
 
                }
1615
 
            });
1616
 
            /**
1617
 
            * @attribute position
1618
 
            * @description The position (top, right, bottom, left or center) of the Unit in the Layout
1619
 
            * @type {String}
1620
 
            */
1621
 
            this.setAttributeConfig('position', {
1622
 
                value: attr.position
1623
 
            });
1624
 
            /**
1625
 
            * @attribute gutter
1626
 
            * @description The gutter that we should apply to the parent Layout around this Unit. Supports standard CSS markup: (2 4 0 5) or (2) or (2 5)
1627
 
            * @type String
1628
 
            */
1629
 
            this.setAttributeConfig('gutter', {
1630
 
                value: attr.gutter || 0,
1631
 
                validator: YAHOO.lang.isString,
1632
 
                method: function(gutter) {
1633
 
                    var p = gutter.split(' ');
1634
 
                    if (p.length) {
1635
 
                        this._gutter.top = parseInt(p[0], 10);
1636
 
                        if (p[1]) {
1637
 
                            this._gutter.right = parseInt(p[1], 10);
1638
 
                        } else {
1639
 
                            this._gutter.right = this._gutter.top;
1640
 
                        }
1641
 
                        if (p[2]) {
1642
 
                            this._gutter.bottom = parseInt(p[2], 10);
1643
 
                        } else {
1644
 
                            this._gutter.bottom = this._gutter.top;
1645
 
                        }
1646
 
                        if (p[3]) {
1647
 
                            this._gutter.left = parseInt(p[3], 10);
1648
 
                        } else if (p[1]) {
1649
 
                            this._gutter.left = this._gutter.right;
1650
 
                        } else {
1651
 
                            this._gutter.left = this._gutter.top;
1652
 
                        }
1653
 
                    }
1654
 
                }
1655
 
            });
1656
 
            /**
1657
 
            * @attribute parent
1658
 
            * @description The parent Layout that we are assigned to
1659
 
            * @type {Object} YAHOO.widget.Layout
1660
 
            */
1661
 
            this.setAttributeConfig('parent', {
1662
 
                writeOnce: true,
1663
 
                value: attr.parent || false,
1664
 
                method: function(p) {
1665
 
                    if (p) {
1666
 
                        p.on('resize', this.resize, this, true);
1667
 
                    }
1668
 
 
1669
 
                }
1670
 
            });
1671
 
            /**
1672
 
            * @attribute collapseSize
1673
 
            * @description The pixel size of the Clip that we will collapse to
1674
 
            * @type Number
1675
 
            */
1676
 
            this.setAttributeConfig('collapseSize', {
1677
 
                value: attr.collapseSize || 25,
1678
 
                validator: YAHOO.lang.isNumber
1679
 
            });
1680
 
            /**
1681
 
            * @attribute duration
1682
 
            * @description The duration to give the Animation Utility when animating the opening and closing of Units
1683
 
            */
1684
 
            this.setAttributeConfig('duration', {
1685
 
                value: attr.duration || 0.5
1686
 
            });
1687
 
            /**
1688
 
            * @attribute easing
1689
 
            * @description The Animation Easing to apply to the Animation instance for this unit.
1690
 
            */
1691
 
            this.setAttributeConfig('easing', {
1692
 
                value: attr.easing || ((YAHOO.util && YAHOO.util.Easing) ? YAHOO.util.Easing.BounceIn : 'false')
1693
 
            });
1694
 
            /**
1695
 
            * @attribute animate
1696
 
            * @description Use animation to collapse/expand the unit
1697
 
            * @type Boolean
1698
 
            */
1699
 
            this.setAttributeConfig('animate', {
1700
 
                value: ((attr.animate === false) ? false : true),
1701
 
                validator: function() {
1702
 
                    var anim = false;
1703
 
                    if (YAHOO.util.Anim) {
1704
 
                        anim = true;
1705
 
                    }
1706
 
                    return anim;
1707
 
                },
1708
 
                method: function(anim) {
1709
 
                    if (anim) {
1710
 
                        this._anim = new YAHOO.util.Anim(this.get('element'), {}, this.get('duration'), this.get('easing'));
1711
 
                    } else {
1712
 
                        this._anim = false;
1713
 
                    }
1714
 
                }
1715
 
            });
1716
 
            /**
1717
 
            * @attribute header
1718
 
            * @description The text to use as the Header of the Unit
1719
 
            */
1720
 
            this.setAttributeConfig('header', {
1721
 
                value: attr.header || false,
1722
 
                method: function(txt) {
1723
 
                    if (txt === false) {
1724
 
                        //Remove the footer
1725
 
                        if (this.header) {
1726
 
                            Dom.addClass(this.body, 'yui-layout-bd-nohd');
1727
 
                            this.header.parentNode.removeChild(this.header);
1728
 
                            this.header = null;
1729
 
                        }
1730
 
                    } else {
1731
 
                        if (!this.header) {
1732
 
                            var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1733
 
                            if (!header) {
1734
 
                                header = this._createHeader();
1735
 
                            }
1736
 
                            this.header = header;
1737
 
                        }
1738
 
                        var h = this.header.getElementsByTagName('h2')[0];
1739
 
                        if (!h) {
1740
 
                            h = document.createElement('h2');
1741
 
                            this.header.appendChild(h);
1742
 
                        }
1743
 
                        h.innerHTML = txt;
1744
 
                        if (this.body) {
1745
 
                            Dom.removeClass(this.body, 'yui-layout-bd-nohd');
1746
 
                        }
1747
 
                    }
1748
 
                    this.fireEvent('contentChange', { target: 'header' });
1749
 
                }
1750
 
            });
1751
 
            /**
1752
 
            * @attribute proxy
1753
 
            * @description Use the proxy config setting for the Resize Utility
1754
 
            * @type Boolean
1755
 
            */
1756
 
            this.setAttributeConfig('proxy', {
1757
 
                writeOnce: true,
1758
 
                value: ((attr.proxy === false) ? false : true)
1759
 
            });
1760
 
            /**
1761
 
            * @attribute body
1762
 
            * @description The content for the body. If we find an element in the page with an id that matches the passed option we will move that element into the body of this unit.
1763
 
            */
1764
 
            this.setAttributeConfig('body', {
1765
 
                value: attr.body || false,
1766
 
                method: function(content) {
1767
 
                    if (!this.body) {
1768
 
                        var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1769
 
                        if (body) {
1770
 
                            this.body = body;
1771
 
                        } else {
1772
 
                            body = document.createElement('div');
1773
 
                            body.className = 'yui-layout-bd';
1774
 
                            this.body = body;
1775
 
                            this.get('wrap').appendChild(body);
1776
 
                        }
1777
 
                    }
1778
 
                    if (!this.header) {
1779
 
                        Dom.addClass(this.body, 'yui-layout-bd-nohd');
1780
 
                    }
1781
 
                    Dom.addClass(this.body, 'yui-layout-bd-noft');
1782
 
 
1783
 
 
1784
 
                    var el = null;
1785
 
                    if (Lang.isString(content)) {
1786
 
                        el = Dom.get(content);
1787
 
                    } else if (content && content.tagName) {
1788
 
                        el = content;
1789
 
                    }
1790
 
                    if (el) {
1791
 
                        var id = Dom.generateId(el);
1792
 
                        LayoutUnit._instances[id] = this;
1793
 
                        this.body.appendChild(el);
1794
 
                    } else {
1795
 
                        this.body.innerHTML = content;
1796
 
                    }
1797
 
 
1798
 
                    this._cleanGrids();
1799
 
 
1800
 
                    this.fireEvent('contentChange', { target: 'body' });
1801
 
                }
1802
 
            });
1803
 
 
1804
 
            /**
1805
 
            * @attribute footer
1806
 
            * @description The content for the footer. If we find an element in the page with an id that matches the passed option we will move that element into the footer of this unit.
1807
 
            */
1808
 
            this.setAttributeConfig('footer', {
1809
 
                value: attr.footer || false,
1810
 
                method: function(content) {
1811
 
                    if (content === false) {
1812
 
                        //Remove the footer
1813
 
                        if (this.footer) {
1814
 
                            Dom.addClass(this.body, 'yui-layout-bd-noft');
1815
 
                            this.footer.parentNode.removeChild(this.footer);
1816
 
                            this.footer = null;
1817
 
                        }
1818
 
                    } else {
1819
 
                        if (!this.footer) {
1820
 
                            var ft = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1821
 
                            if (!ft) {
1822
 
                                ft = document.createElement('div');
1823
 
                                ft.className = 'yui-layout-ft';
1824
 
                                this.footer = ft;
1825
 
                                this.get('wrap').appendChild(ft);
1826
 
                            } else {
1827
 
                                this.footer = ft;
1828
 
                            }
1829
 
                        }
1830
 
                        var el = null;
1831
 
                        if (Lang.isString(content)) {
1832
 
                            el = Dom.get(content);
1833
 
                        } else if (content && content.tagName) {
1834
 
                            el = content;
1835
 
                        }
1836
 
                        if (el) {
1837
 
                            this.footer.appendChild(el);
1838
 
                        } else {
1839
 
                            this.footer.innerHTML = content;
1840
 
                        }
1841
 
                        Dom.removeClass(this.body, 'yui-layout-bd-noft');
1842
 
                    }
1843
 
                    this.fireEvent('contentChange', { target: 'footer' });
1844
 
                }
1845
 
            });
1846
 
            /**
1847
 
            * @attribute close
1848
 
            * @description Adds a close icon to the unit
1849
 
            */
1850
 
            this.setAttributeConfig('close', {
1851
 
                value: attr.close || false,
1852
 
                method: function(close) {
1853
 
                    //Position Center doesn't get this
1854
 
                    if (this.get('position') == 'center') {
1855
 
                        YAHOO.log('Position center unit cannot have close', 'error', 'LayoutUnit');
1856
 
                        return false;
1857
 
                    }
1858
 
                    if (!this.header) {
1859
 
                        this._createHeader();
1860
 
                    }
1861
 
                    var c = Dom.getElementsByClassName('close', 'div', this.header)[0];
1862
 
                    if (close) {
1863
 
                        //Force some header text if there isn't any
1864
 
                        if (!this.get('header')) {
1865
 
                            this.set('header', '&nbsp;');
1866
 
                        }
1867
 
                        if (!c) {
1868
 
                            c = document.createElement('div');
1869
 
                            c.className = 'close';
1870
 
                            this.header.appendChild(c);
1871
 
                            Event.on(c, 'click', this.close, this, true);
1872
 
                        }
1873
 
                        c.title = this.STR_CLOSE;
1874
 
                    } else if (c) {
1875
 
                        Event.purgeElement(c);
1876
 
                        c.parentNode.removeChild(c);
1877
 
                    }
1878
 
                    this._configs.close.value = close;
1879
 
                    this.set('collapse', this.get('collapse')); //Reset so we get the right classnames
1880
 
                }
1881
 
            });
1882
 
 
1883
 
            /**
1884
 
            * @attribute collapse
1885
 
            * @description Adds a collapse icon to the unit
1886
 
            */
1887
 
            this.setAttributeConfig('collapse', {
1888
 
                value: attr.collapse || false,
1889
 
                method: function(collapse) {
1890
 
                    //Position Center doesn't get this
1891
 
                    if (this.get('position') == 'center') {
1892
 
                        YAHOO.log('Position center unit cannot have collapse', 'error', 'LayoutUnit');
1893
 
                        return false;
1894
 
                    }
1895
 
                    if (!this.header) {
1896
 
                        this._createHeader();
1897
 
                    }
1898
 
                    var c = Dom.getElementsByClassName('collapse', 'div', this.header)[0];
1899
 
                    if (collapse) {
1900
 
                        //Force some header text if there isn't any
1901
 
                        if (!this.get('header')) {
1902
 
                            this.set('header', '&nbsp;');
1903
 
                        }
1904
 
                        if (!c) {
1905
 
                            c = document.createElement('div');
1906
 
                            this.header.appendChild(c);
1907
 
                            Event.on(c, 'click', this.collapse, this, true);
1908
 
                        }
1909
 
                        c.title = this.STR_COLLAPSE;
1910
 
                        c.className = 'collapse' + ((this.get('close')) ? ' collapse-close' : '');
1911
 
                    } else if (c) {
1912
 
                        Event.purgeElement(c);
1913
 
                        c.parentNode.removeChild(c);
1914
 
                    }
1915
 
                }
1916
 
            });
1917
 
            /**
1918
 
            * @attribute scroll
1919
 
            * @description Adds a class to the unit to allow for overflow: auto (yui-layout-scroll), default is overflow: hidden (yui-layout-noscroll). If true scroll bars will be placed on the element when the content exceeds the given area, false will put overflow hidden to hide the content. Passing null will render the content as usual overflow.
1920
 
            * @type Boolean/Null
1921
 
            */
1922
 
 
1923
 
            this.setAttributeConfig('scroll', {
1924
 
                value: (((attr.scroll === true) || (attr.scroll === false) || (attr.scroll === null)) ? attr.scroll : false),
1925
 
                method: function(scroll) {
1926
 
                    if ((scroll === false) && !this._collapsed) { //Removing scroll bar
1927
 
                        if (this.body) {
1928
 
                            if (this.body.scrollTop > 0) {
1929
 
                                this._lastScrollTop = this.body.scrollTop;
1930
 
                            }
1931
 
                        }
1932
 
                    }
1933
 
                    
1934
 
                    if (scroll === true) {
1935
 
                        this.addClass('yui-layout-scroll');
1936
 
                        this.removeClass('yui-layout-noscroll');
1937
 
                        if (this._lastScrollTop > 0) {
1938
 
                            if (this.body) {
1939
 
                                this.body.scrollTop = this._lastScrollTop;
1940
 
                            }
1941
 
                        }
1942
 
                    } else if (scroll === false) {
1943
 
                        this.removeClass('yui-layout-scroll');
1944
 
                        this.addClass('yui-layout-noscroll');
1945
 
                    } else if (scroll === null) {
1946
 
                        this.removeClass('yui-layout-scroll');
1947
 
                        this.removeClass('yui-layout-noscroll');
1948
 
                    }
1949
 
                }
1950
 
            });
1951
 
            /**
1952
 
            * @attribute hover
1953
 
            * @description Config option to pass to the Resize Utility
1954
 
            */
1955
 
            this.setAttributeConfig('hover', {
1956
 
                writeOnce: true,
1957
 
                value: attr.hover || false,
1958
 
                validator: YAHOO.lang.isBoolean
1959
 
            });
1960
 
            /**
1961
 
            * @attribute useShim
1962
 
            * @description Config option to pass to the Resize Utility
1963
 
            */
1964
 
            this.setAttributeConfig('useShim', {
1965
 
                value: attr.useShim || false,
1966
 
                validator: YAHOO.lang.isBoolean,
1967
 
                method: function(u) {
1968
 
                    if (this._resize) {
1969
 
                        this._resize.set('useShim', u);
1970
 
                    }
1971
 
                }
1972
 
            });
1973
 
            /**
1974
 
            * @attribute resize
1975
 
            * @description Should a Resize instance be added to this unit
1976
 
            */
1977
 
 
1978
 
            this.setAttributeConfig('resize', {
1979
 
                value: attr.resize || false,
1980
 
                validator: function(r) {
1981
 
                    if (YAHOO.util && YAHOO.util.Resize) {
1982
 
                        return true;
1983
 
                    }
1984
 
                    return false;
1985
 
                },
1986
 
                method: function(resize) {
1987
 
                    if (resize && !this._resize) {
1988
 
                        //Position Center doesn't get this
1989
 
                        if (this.get('position') == 'center') {
1990
 
                            YAHOO.log('Position center unit cannot have resize', 'error', 'LayoutUnit');
1991
 
                            return false;
1992
 
                        }
1993
 
                        var handle = false; //To catch center
1994
 
                        switch (this.get('position')) {
1995
 
                            case 'top':
1996
 
                                handle = 'b';
1997
 
                                break;
1998
 
                            case 'bottom':
1999
 
                                handle = 't';
2000
 
                                break;
2001
 
                            case 'right':
2002
 
                                handle = 'l';
2003
 
                                break;
2004
 
                            case 'left':
2005
 
                                handle = 'r';
2006
 
                                break;
2007
 
                        }
2008
 
 
2009
 
                        this.setStyle('position', 'absolute'); //Make sure Resize get's a position
2010
 
                        
2011
 
                        if (handle) {
2012
 
                            this._resize = new YAHOO.util.Resize(this.get('element'), {
2013
 
                                proxy: this.get('proxy'),
2014
 
                                hover: this.get('hover'),
2015
 
                                status: false,
2016
 
                                autoRatio: false,
2017
 
                                handles: [handle],
2018
 
                                minWidth: this.get('minWidth'),
2019
 
                                maxWidth: this.get('maxWidth'),
2020
 
                                minHeight: this.get('minHeight'),
2021
 
                                maxHeight: this.get('maxHeight'),
2022
 
                                height: this.get('height'),
2023
 
                                width: this.get('width'),
2024
 
                                setSize: false,
2025
 
                                useShim: this.get('useShim'),
2026
 
                                wrap: false
2027
 
                            });
2028
 
                            
2029
 
                            this._resize._handles[handle].innerHTML = '<div class="yui-layout-resize-knob"></div>';
2030
 
 
2031
 
                            if (this.get('proxy')) {
2032
 
                                var proxy = this._resize.getProxyEl();
2033
 
                                proxy.innerHTML = '<div class="yui-layout-handle-' + handle + '"></div>';
2034
 
                            }
2035
 
                            this._resize.on('startResize', function(ev) {
2036
 
                                this._lastScroll = this.get('scroll');
2037
 
                                this.set('scroll', false);
2038
 
                                if (this.get('parent')) {
2039
 
                                    this.get('parent').fireEvent('startResize');
2040
 
                                    var c = this.get('parent').getUnitByPosition('center');
2041
 
                                    this._lastCenterScroll = c.get('scroll');
2042
 
                                    c.addClass(this._resize.CSS_RESIZING);
2043
 
                                    c.set('scroll', false);
2044
 
                                }
2045
 
                                this.fireEvent('startResize');
2046
 
                            }, this, true);
2047
 
                            this._resize.on('resize', function(ev) {
2048
 
                                this.set('height', ev.height);
2049
 
                                this.set('width', ev.width);
2050
 
                            }, this, true);
2051
 
                            this._resize.on('endResize', function(ev) {
2052
 
                                this.set('scroll', this._lastScroll);
2053
 
                                if (this.get('parent')) {
2054
 
                                    var c = this.get('parent').getUnitByPosition('center');
2055
 
                                    c.set('scroll', this._lastCenterScroll);
2056
 
                                    c.removeClass(this._resize.CSS_RESIZING);
2057
 
                                }
2058
 
                                this.resize();
2059
 
                                this.fireEvent('endResize');
2060
 
                            }, this, true);
2061
 
                        }
2062
 
                    } else {
2063
 
                        if (this._resize) {
2064
 
                            this._resize.destroy();
2065
 
                        }
2066
 
                    }
2067
 
                }
2068
 
            });
2069
 
                        /**
2070
 
                 * The unit data source, used for loading content dynamically.
2071
 
                 * @attribute dataSrc
2072
 
                 * @type String
2073
 
                 */
2074
 
                this.setAttributeConfig('dataSrc', {
2075
 
                    value: attr.dataSrc
2076
 
                });
2077
 
                /**
2078
 
                 * The method to use for the data request.
2079
 
                 * @attribute loadMethod
2080
 
                 * @type String
2081
 
                 * @default "GET"
2082
 
                 */
2083
 
                this.setAttributeConfig('loadMethod', {
2084
 
                    value: attr.loadMethod || 'GET',
2085
 
                    validator: YAHOO.lang.isString
2086
 
                });     
2087
 
                /**
2088
 
                 * Whether or not any data has been loaded from the server.
2089
 
                 * @attribute dataLoaded
2090
 
                 * @type Boolean
2091
 
                 */        
2092
 
                this.setAttributeConfig('dataLoaded', {
2093
 
                    value: false,
2094
 
                    validator: YAHOO.lang.isBoolean,
2095
 
                    writeOnce: true
2096
 
                });
2097
 
                /**
2098
 
                 * Number if milliseconds before aborting and calling failure handler.
2099
 
                 * @attribute dataTimeout
2100
 
                 * @type Number
2101
 
                 * @default null
2102
 
                 */
2103
 
                this.setAttributeConfig('dataTimeout', {
2104
 
                    value: attr.dataTimeout || null,
2105
 
                    validator: YAHOO.lang.isNumber
2106
 
                });
2107
 
        },
2108
 
        /**
2109
 
        * @private
2110
 
        * @method _cleanGrids
2111
 
        * @description This method attempts to clean up the first level of the YUI CSS Grids, YAHOO.util.Selector is required for this operation.
2112
 
        */
2113
 
        _cleanGrids: function() {
2114
 
            if (this.get('grids')) {
2115
 
                var b = Sel.query('div.yui-b', this.body, true);
2116
 
                if (b) {
2117
 
                    Dom.removeClass(b, 'yui-b');
2118
 
                }
2119
 
                Event.onAvailable('yui-main', function() {
2120
 
                    Dom.setStyle(Sel.query('#yui-main'), 'margin-left', '0');
2121
 
                    Dom.setStyle(Sel.query('#yui-main'), 'margin-right', '0');
2122
 
                });
2123
 
            }
2124
 
        },
2125
 
        /**
2126
 
        * @private
2127
 
        * @method _createHeader
2128
 
        * @description Creates the HTMLElement for the header
2129
 
        * @return {HTMLElement} The new HTMLElement
2130
 
        */
2131
 
        _createHeader: function() {
2132
 
            var header = document.createElement('div');
2133
 
            header.className = 'yui-layout-hd';
2134
 
            if (this.get('firstChild')) {
2135
 
                this.get('wrap').insertBefore(header, this.get('wrap').firstChild);
2136
 
            } else {
2137
 
                this.get('wrap').appendChild(header);
2138
 
            }
2139
 
            this.header = header;
2140
 
            return header;
2141
 
        },
2142
 
        /**
2143
 
        * @method destroy
2144
 
        * @param {Boolean} force Don't report to the parent, because we are being called from the parent.
2145
 
        * @description Removes this unit from the parent and cleans up after itself.
2146
 
        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
2147
 
        */
2148
 
        destroy: function(force) {
2149
 
            if (this._resize) {
2150
 
                this._resize.destroy();
2151
 
            }
2152
 
            var par = this.get('parent');
2153
 
 
2154
 
            this.setStyle('display', 'none');
2155
 
            if (this._clip) {
2156
 
                this._clip.parentNode.removeChild(this._clip);
2157
 
                this._clip = null;
2158
 
            }
2159
 
 
2160
 
            if (!force) {
2161
 
                par.removeUnit(this);
2162
 
            }
2163
 
            
2164
 
            if (par) {
2165
 
                par.removeListener('resize', this.resize, this, true);
2166
 
            }
2167
 
            this.unsubscribeAll();
2168
 
            Event.purgeElement(this.get('element'));
2169
 
            this.get('parentNode').removeChild(this.get('element'));
2170
 
 
2171
 
            delete YAHOO.widget.LayoutUnit._instances[this.get('id')];
2172
 
            //Brutal Object Destroy
2173
 
            for (var i in this) {
2174
 
                if (Lang.hasOwnProperty(this, i)) {
2175
 
                    this[i] = null;
2176
 
                    delete this[i];
2177
 
                }
2178
 
            }
2179
 
        
2180
 
            return par;
2181
 
        },
2182
 
        /**
2183
 
        * @method toString
2184
 
        * @description Returns a string representing the LayoutUnit.
2185
 
        * @return {String}
2186
 
        */        
2187
 
        toString: function() {
2188
 
            if (this.get) {
2189
 
                return 'LayoutUnit #' + this.get('id') + ' (' + this.get('position') + ')';
2190
 
            }
2191
 
            return 'LayoutUnit';
2192
 
        }
2193
 
    /**
2194
 
    * @event resize
2195
 
    * @description Fired when this.resize is called
2196
 
    * @type YAHOO.util.CustomEvent
2197
 
    */
2198
 
    /**
2199
 
    * @event startResize
2200
 
    * @description Fired when the Resize Utility fires it's startResize Event.
2201
 
    * @type YAHOO.util.CustomEvent
2202
 
    */
2203
 
    /**
2204
 
    * @event endResize
2205
 
    * @description Fired when the Resize Utility fires it's endResize Event.
2206
 
    * @type YAHOO.util.CustomEvent
2207
 
    */
2208
 
    /**
2209
 
    * @event beforeResize
2210
 
    * @description Fired at the beginning of the resize method. If you return false, the resize is cancelled.
2211
 
    * @type YAHOO.util.CustomEvent
2212
 
    */
2213
 
    /**
2214
 
    * @event contentChange
2215
 
    * @description Fired when the content in the header, body or footer is changed via the API
2216
 
    * @type YAHOO.util.CustomEvent
2217
 
    */
2218
 
    /**
2219
 
    * @event close
2220
 
    * @description Fired when the unit is closed
2221
 
    * @type YAHOO.util.CustomEvent
2222
 
    */
2223
 
    /**
2224
 
    * @event beforeCollapse
2225
 
    * @description Fired before the unit is collapsed. If you return false, the collapse is cancelled.
2226
 
    * @type YAHOO.util.CustomEvent
2227
 
    */
2228
 
    /**
2229
 
    * @event collapse
2230
 
    * @description Fired when the unit is collapsed
2231
 
    * @type YAHOO.util.CustomEvent
2232
 
    */
2233
 
    /**
2234
 
    * @event expand
2235
 
    * @description Fired when the unit is exanded
2236
 
    * @type YAHOO.util.CustomEvent
2237
 
    */
2238
 
    /**
2239
 
    * @event beforeExpand
2240
 
    * @description Fired before the unit is exanded. If you return false, the collapse is cancelled.
2241
 
    * @type YAHOO.util.CustomEvent
2242
 
    */
2243
 
    /**
2244
 
    * @event load
2245
 
    * @description Fired when data is loaded via the dataSrc config.
2246
 
    * @type YAHOO.util.CustomEvent
2247
 
    */
2248
 
    /**
2249
 
    * @event loadError
2250
 
    * @description Fired when an error occurs loading data via the dataSrc config. Error message is passed as argument to this event.
2251
 
    * @type YAHOO.util.CustomEvent
2252
 
    */
2253
 
    });
2254
 
 
2255
 
    YAHOO.widget.LayoutUnit = LayoutUnit;
2256
 
})();
2257
 
YAHOO.register("layout", YAHOO.widget.Layout, {version: "2.7.0", build: "1799"});