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