2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
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
14 var Dom = YAHOO.util.Dom,
15 Event = YAHOO.util.Event,
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.
27 var Layout = function(el, config) {
28 if (Lang.isObject(el) && !el.tagName) {
32 if (Lang.isString(el)) {
43 attributes: config || {}
46 Layout.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
52 * @property _instances
53 * @description Internal hash table for all layout instances
56 Layout._instances = {};
59 * @method getLayoutById
60 * @description Get's a layout object by the HTML id of the element associated with the Layout object.
61 * @return {Object} The Layout Object
63 Layout.getLayoutById = function(id) {
64 if (Layout._instances[id]) {
65 return Layout._instances[id];
70 YAHOO.extend(Layout, YAHOO.util.Element, {
73 * @description A modified version of the YAHOO.env.ua object
78 b.standardsMode = false;
85 * @description An object literal that contains a list of units in the layout
92 * @description Set to true when the layout is rendered
99 * @description The zIndex to set all LayoutUnits to
106 * @description A collection of the current sizes of all usable LayoutUnits to be used for calculations
112 * @method _setBodySize
113 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
114 * @description Used to set the body size of the layout, sets the height and width of the parent container
116 _setBodySize: function(set) {
118 set = ((set === false) ? false : true);
121 h = Dom.getClientHeight();
122 w = Dom.getClientWidth();
124 h = parseInt(this.getStyle('height'), 10);
125 w = parseInt(this.getStyle('width'), 10);
127 w = this.get('element').clientWidth;
130 h = this.get('element').clientHeight;
133 if (this.get('minWidth')) {
134 if (w < this.get('minWidth')) {
135 w = this.get('minWidth');
138 if (this.get('minHeight')) {
139 if (h < this.get('minHeight')) {
140 h = this.get('minHeight');
150 Dom.setStyle(this._doc, 'height', h + 'px');
151 Dom.setStyle(this._doc, 'width', w + 'px');
153 this._sizes.doc = { h: h, w: w };
159 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
160 * @description Used to set the size and position of the left, right, top and bottom units
162 _setSides: function(set) {
163 var h1 = ((this._units.top) ? this._units.top.get('height') : 0),
164 h2 = ((this._units.bottom) ? this._units.bottom.get('height') : 0),
165 h = this._sizes.doc.h,
166 w = this._sizes.doc.w;
167 set = ((set === false) ? false : true);
170 h: h1, w: ((this._units.top) ? w : 0),
173 this._sizes.bottom = {
174 h: h2, w: ((this._units.bottom) ? w : 0)
177 var newH = (h - (h1 + h2));
180 h: newH, w: ((this._units.left) ? this._units.left.get('width') : 0)
182 this._sizes.right = {
183 h: newH, w: ((this._units.right) ? this._units.right.get('width') : 0),
184 l: ((this._units.right) ? (w - this._units.right.get('width')) : 0),
185 t: ((this._units.top) ? this._sizes.top.h : 0)
188 if (this._units.right && set) {
189 this._units.right.set('top', this._sizes.right.t);
190 if (!this._units.right._collapsing) {
191 this._units.right.set('left', this._sizes.right.l);
193 this._units.right.set('height', this._sizes.right.h, true);
195 if (this._units.left) {
196 this._sizes.left.l = 0;
197 if (this._units.top) {
198 this._sizes.left.t = this._sizes.top.h;
200 this._sizes.left.t = 0;
203 this._units.left.set('top', this._sizes.left.t);
204 this._units.left.set('height', this._sizes.left.h, true);
205 this._units.left.set('left', 0);
208 if (this._units.bottom) {
209 this._sizes.bottom.t = this._sizes.top.h + this._sizes.left.h;
211 this._units.bottom.set('top', this._sizes.bottom.t);
212 this._units.bottom.set('width', this._sizes.bottom.w, true);
215 if (this._units.top) {
217 this._units.top.set('width', this._sizes.top.w, true);
220 this._setCenter(set);
225 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
226 * @description Used to set the size and position of the center unit
228 _setCenter: function(set) {
229 set = ((set === false) ? false : true);
230 var h = this._sizes.left.h;
231 var w = (this._sizes.doc.w - (this._sizes.left.w + this._sizes.right.w));
233 this._units.center.set('height', h, true);
234 this._units.center.set('width', w, true);
235 this._units.center.set('top', this._sizes.top.h);
236 this._units.center.set('left', this._sizes.left.w);
238 this._sizes.center = { h: h, w: w, t: this._sizes.top.h, l: this._sizes.left.w };
242 * @description Get a reference to the internal Layout Unit sizes object used to build the layout wireframe
243 * @return {Object} An object of the layout unit sizes
245 getSizes: function() {
249 * @method getUnitById
250 * @param {String} id The HTML element id of the unit
251 * @description Get the LayoutUnit by it's HTML id
252 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
254 getUnitById: function(id) {
255 return YAHOO.widget.LayoutUnit.getLayoutUnitById(id);
258 * @method getUnitByPosition
259 * @param {String} pos The position of the unit in this layout
260 * @description Get the LayoutUnit by it's position in this layout
261 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
263 getUnitByPosition: function(pos) {
265 pos = pos.toLowerCase();
266 if (this._units[pos]) {
267 return this._units[pos];
275 * @param {Object} unit The LayoutUnit that you want to remove
276 * @description Remove the unit from this layout and resize the layout.
278 removeUnit: function(unit) {
279 delete this._units[unit.get('position')];
284 * @param {Object} cfg The config for the LayoutUnit that you want to add
285 * @description Add a unit to this layout and if the layout is rendered, resize the layout.
286 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
288 addUnit: function(cfg) {
292 if (this._units[cfg.position]) {
299 if (Dom.get(cfg.id)) {
300 element = Dom.get(cfg.id);
306 element = cfg.element;
310 el = document.createElement('div');
311 var id = Dom.generateId();
316 element = document.createElement('div');
318 Dom.addClass(element, 'yui-layout-wrap');
319 if (this.browser.ie && !this.browser.standardsMode) {
321 element.style.zoom = 1;
325 el.insertBefore(element, el.firstChild);
327 el.appendChild(element);
329 this._doc.appendChild(el);
331 var h = false, w = false;
334 h = parseInt(cfg.height, 10);
337 w = parseInt(cfg.width, 10);
340 YAHOO.lang.augmentObject(unitConfig, cfg); // break obj ref
342 unitConfig.parent = this;
343 unitConfig.wrap = element;
344 unitConfig.height = h;
345 unitConfig.width = w;
347 var unit = new YAHOO.widget.LayoutUnit(el, unitConfig);
349 unit.on('heightChange', this.resize, { unit: unit }, this);
350 unit.on('widthChange', this.resize, { unit: unit }, this);
351 unit.on('gutterChange', this.resize, { unit: unit }, this);
352 this._units[cfg.position] = unit;
354 if (this._rendered) {
362 * @method _createUnits
363 * @description Private method to create units from the config that was passed in.
365 _createUnits: function() {
366 var units = this.get('units');
367 for (var i in units) {
368 if (Lang.hasOwnProperty(units, i)) {
369 this.addUnit(units[i]);
375 * @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.
376 * @description Starts the chain of resize routines that will resize all the units.
377 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
379 resize: function(set, info) {
382 * If the event comes from an attribute and the value hasn't changed, don't process it.
385 if (ev && ev.prevValue && ev.newValue) {
386 if (ev.prevValue == ev.newValue) {
389 if (!info.unit.get('animate')) {
396 set = ((set === false) ? false : true);
398 var retVal = this.fireEvent('beforeResize');
399 if (retVal === false) {
402 if (this.browser.ie) {
404 Dom.removeClass(document.documentElement, 'yui-layout');
405 Dom.addClass(document.documentElement, 'yui-layout');
407 this.removeClass('yui-layout');
408 this.addClass('yui-layout');
412 this._setBodySize(set);
414 this.fireEvent('resize', { target: this, sizes: this._sizes, event: ev });
420 * @method _setupBodyElements
421 * @description Sets up the main doc element when using the body as the main element.
423 _setupBodyElements: function() {
424 this._doc = Dom.get('layout-doc');
426 this._doc = document.createElement('div');
427 this._doc.id = 'layout-doc';
428 if (document.body.firstChild) {
429 document.body.insertBefore(this._doc, document.body.firstChild);
431 document.body.appendChild(this._doc);
436 Event.on(window, 'resize', this.resize, this, true);
437 Dom.addClass(this._doc, 'yui-layout-doc');
441 * @method _setupElements
442 * @description Sets up the main doc element when not using the body as the main element.
444 _setupElements: function() {
445 this._doc = this.getElementsByClassName('yui-layout-doc')[0];
447 this._doc = document.createElement('div');
448 this.get('element').appendChild(this._doc);
452 Dom.addClass(this._doc, 'yui-layout-doc');
457 * @description Flag to determine if we are using the body as the root element.
464 * @description Reference to the root element
471 * @description The Layout class' initialization method
473 init: function(p_oElement, p_oAttributes) {
477 Layout.superclass.init.call(this, p_oElement, p_oAttributes);
479 if (this.get('parent')) {
480 this._zIndex = this.get('parent')._zIndex + 10;
487 if (!Lang.isString(id)) {
488 id = Dom.generateId(id);
490 Layout._instances[id] = this;
494 * @description This method starts the render process, applying classnames and creating elements
495 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
499 var el = this.get('element');
500 if (el && el.tagName && (el.tagName.toLowerCase() == 'body')) {
502 Dom.addClass(document.body, 'yui-layout');
503 if (Dom.hasClass(document.body, 'yui-skin-sam')) {
504 //Move the class up so we can have a css chain
505 Dom.addClass(document.documentElement, 'yui-skin-sam');
506 Dom.removeClass(document.body, 'yui-skin-sam');
508 this._setupBodyElements();
510 this._isBody = false;
511 this.addClass('yui-layout');
512 this._setupElements();
515 this._rendered = true;
516 this.fireEvent('render');
523 * @description Stamps the root node with a secure classname for ease of use. Also sets the this.browser.standardsMode variable.
526 if (document.compatMode == 'CSS1Compat') {
527 this.browser.standardsMode = true;
529 if (window.location.href.toLowerCase().indexOf("https") === 0) {
530 Dom.addClass(document.documentElement, 'secure');
531 this.browser.secure = true;
536 * @method initAttributes
537 * @description Processes the config
539 initAttributes: function(attr) {
540 Layout.superclass.initAttributes.call(this, attr);
543 * @description An array of config definitions for the LayoutUnits to add to this layout
546 this.setAttributeConfig('units', {
548 validator: YAHOO.lang.isArray,
549 value: attr.units || []
553 * @attribute minHeight
554 * @description The minimum height in pixels
557 this.setAttributeConfig('minHeight', {
558 value: attr.minHeight || false,
559 validator: YAHOO.lang.isNumber
563 * @attribute minWidth
564 * @description The minimum width in pixels
567 this.setAttributeConfig('minWidth', {
568 value: attr.minWidth || false,
569 validator: YAHOO.lang.isNumber
574 * @description The height in pixels
577 this.setAttributeConfig('height', {
578 value: attr.height || false,
579 validator: YAHOO.lang.isNumber,
580 method: function(h) {
584 this.setStyle('height', h + 'px');
590 * @description The width in pixels
593 this.setAttributeConfig('width', {
594 value: attr.width || false,
595 validator: YAHOO.lang.isNumber,
596 method: function(w) {
600 this.setStyle('width', w + 'px');
606 * @description If this layout is to be used as a child of another Layout instance, this config will bind the resize events together.
607 * @type Object YAHOO.widget.Layout
609 this.setAttributeConfig('parent', {
611 value: attr.parent || false,
612 method: function(p) {
614 p.on('resize', this.resize, this, true);
621 * @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.
623 destroy: function() {
624 var par = this.get('parent');
626 par.removeListener('resize', this.resize, this, true);
628 Event.removeListener(window, 'resize', this.resize, this, true);
630 this.unsubscribeAll();
631 for (var u in this._units) {
632 if (Lang.hasOwnProperty(this._units, u)) {
633 if (this._units[u]) {
634 this._units[u].destroy(true);
639 Event.purgeElement(this.get('element'));
640 this.get('parentNode').removeChild(this.get('element'));
642 delete YAHOO.widget.Layout._instances[this.get('id')];
643 //Brutal Object Destroy
644 for (var i in this) {
645 if (Lang.hasOwnProperty(this, i)) {
657 * @description Returns a string representing the Layout.
660 toString: function() {
662 return 'Layout #' + this.get('id');
669 * @description Fired when this.resize is called
670 * @type YAHOO.util.CustomEvent
674 * @description Fired when the Resize Utility for a Unit fires it's startResize Event.
675 * @type YAHOO.util.CustomEvent
678 * @event beforeResize
679 * @description Fires at the beginning of the resize method. If you return false, the resize is cancelled.
680 * @type YAHOO.util.CustomEvent
684 * @description Fired after the render method completes.
685 * @type YAHOO.util.CustomEvent
688 YAHOO.widget.Layout = Layout;
691 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
692 * @namespace YAHOO.widget
693 * @requires yahoo, dom, element, event, layout
694 * @optional animation, dragdrop, selector
697 var Dom = YAHOO.util.Dom,
698 Sel = YAHOO.util.Selector,
699 Event = YAHOO.util.Event,
705 * @extends YAHOO.util.Element
706 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
707 * @param {String/HTMLElement} el The element to make a unit.
708 * @param {Object} attrs Object liternal containing configuration parameters.
711 var LayoutUnit = function(el, config) {
715 attributes: config || {}
718 LayoutUnit.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
724 * @property _instances
725 * @description Internal hash table for all layout unit instances
728 LayoutUnit._instances = {};
731 * @method getLayoutUnitById
732 * @description Get's a layout unit object by the HTML id of the element associated with the Layout Unit object.
733 * @return {Object} The Layout Object
735 LayoutUnit.getLayoutUnitById = function(id) {
736 if (LayoutUnit._instances[id]) {
737 return LayoutUnit._instances[id];
742 YAHOO.extend(LayoutUnit, YAHOO.util.Element, {
744 * @property STR_CLOSE
745 * @description String used for close button title
748 STR_CLOSE: 'Click to close this pane.',
750 * @property STR_COLLAPSE
751 * @description String used for collapse button title
754 STR_COLLAPSE: 'Click to collapse this pane.',
756 * @property STR_EXPAND
757 * @description String used for expand button title
760 STR_EXPAND: 'Click to expand this pane.',
762 * The class name applied to dynamic tabs while loading.
763 * @property LOADING_CLASSNAME
765 * @default "disabled"
767 LOADING_CLASSNAME: 'loading',
770 * @description A modified version of the YAHOO.env.ua object
777 * @description A collection of the current sizes of the contents of this Layout Unit
784 * @description A reference to the Animation instance used by this LayouUnit
785 * @type YAHOO.util.Anim
791 * @description A reference to the Resize instance used by this LayoutUnit
792 * @type YAHOO.util.Resize
798 * @description A reference to the clip element used when collapsing the unit
805 * @description A simple hash table used to store the gutter to apply to the Unit
811 * @description A reference to the HTML element used for the Header
817 * @description A reference to the HTML element used for the body
823 * @description A reference to the HTML element used for the footer
829 * @property _collapsed
830 * @description Flag to determine if the unit is collapsed or not.
836 * @property _collapsing
837 * @description A flag set while the unit is being collapsed, used so we don't fire events while animating the size
843 * @property _lastWidth
844 * @description A holder for the last known width of the unit
850 * @property _lastHeight
851 * @description A holder for the last known height of the unit
858 * @description A holder for the last known top of the unit
864 * @property _lastLeft
865 * @description A holder for the last known left of the unit
871 * @property _lastScroll
872 * @description A holder for the last known scroll state of the unit
878 * @property _lastCenetrScroll
879 * @description A holder for the last known scroll state of the center unit
882 _lastCenterScroll: null,
885 * @property _lastScrollTop
886 * @description A holder for the last known scrollTop state of the unit
889 _lastScrollTop: null,
892 * @description Resize either the unit or it's clipped state, also updating the box inside
893 * @param {Boolean} force This will force full calculations even when the unit is collapsed
894 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
896 resize: function(force) {
897 var retVal = this.fireEvent('beforeResize');
898 if (retVal === false) {
901 if (!this._collapsing || (force === true)) {
902 var scroll = this.get('scroll');
903 this.set('scroll', false);
906 var hd = this._getBoxSize(this.header),
907 ft = this._getBoxSize(this.footer),
908 box = [this.get('height'), this.get('width')];
910 var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
911 nw = box[1] - (this._gutter.left + this._gutter.right);
913 var wrapH = (nh + (hd[0] + ft[0])),
916 if (this._collapsed && !this._collapsing) {
917 this._setHeight(this._clip, wrapH);
918 this._setWidth(this._clip, wrapW);
919 Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
920 Dom.setStyle(this._clip, 'left', this.get('left') + this._gutter.left + 'px');
921 } else if (!this._collapsed || (this._collapsed && this._collapsing)) {
922 wrapH = this._setHeight(this.get('wrap'), wrapH);
923 wrapW = this._setWidth(this.get('wrap'), wrapW);
924 this._sizes.wrap.h = wrapH;
925 this._sizes.wrap.w = wrapW;
927 Dom.setStyle(this.get('wrap'), 'top', this._gutter.top + 'px');
928 Dom.setStyle(this.get('wrap'), 'left', this._gutter.left + 'px');
930 this._sizes.header.w = this._setWidth(this.header, wrapW);
931 this._sizes.header.h = hd[0];
933 this._sizes.footer.w = this._setWidth(this.footer, wrapW);
934 this._sizes.footer.h = ft[0];
936 Dom.setStyle(this.footer, 'bottom', '0px');
938 this._sizes.body.h = this._setHeight(this.body, (wrapH - (hd[0] + ft[0])));
939 this._sizes.body.w =this._setWidth(this.body, wrapW);
940 Dom.setStyle(this.body, 'top', hd[0] + 'px');
942 this.set('scroll', scroll);
943 this.fireEvent('resize');
951 * @description Sets the width of the element based on the border size of the element.
952 * @param {HTMLElement} el The HTMLElement to have it's width set
953 * @param {Number} w The width that you want it the element set to
954 * @return {Number} The new width, fixed for borders and IE QuirksMode
956 _setWidth: function(el, w) {
958 var b = this._getBorderSizes(el);
959 w = (w - (b[1] + b[3]));
960 w = this._fixQuirks(el, w, 'w');
964 Dom.setStyle(el, 'width', w + 'px');
971 * @description Sets the height of the element based on the border size of the element.
972 * @param {HTMLElement} el The HTMLElement to have it's height set
973 * @param {Number} h The height that you want it the element set to
974 * @return {Number} The new height, fixed for borders and IE QuirksMode
976 _setHeight: function(el, h) {
978 var b = this._getBorderSizes(el);
979 h = (h - (b[0] + b[2]));
980 h = this._fixQuirks(el, h, 'h');
984 Dom.setStyle(el, 'height', h + 'px');
991 * @description Fixes the box calculations for IE in QuirksMode
992 * @param {HTMLElement} el The HTMLElement to set the dimension on
993 * @param {Number} dim The number of the dimension to fix
994 * @param {String} side The dimension (h or w) to fix. Defaults to h
995 * @return {Number} The fixed dimension
997 _fixQuirks: function(el, dim, side) {
1003 if ((this.browser.ie < 8) && !this.browser.standardsMode) {
1004 //Internet Explorer - Quirks Mode
1005 var b = this._getBorderSizes(el),
1006 bp = this._getBorderSizes(el.parentNode);
1007 if ((b[i1] === 0) && (b[i2] === 0)) { //No Borders, check parent
1008 if ((bp[i1] !== 0) && (bp[i2] !== 0)) { //Parent has Borders
1009 dim = (dim - (bp[i1] + bp[i2]));
1012 if ((bp[i1] === 0) && (bp[i2] === 0)) {
1013 dim = (dim + (b[i1] + b[i2]));
1021 * @method _getBoxSize
1022 * @description Get's the elements clientHeight and clientWidth plus the size of the borders
1023 * @param {HTMLElement} el The HTMLElement to get the size of
1024 * @return {Array} An array of height and width
1026 _getBoxSize: function(el) {
1029 if (this.browser.ie && !this.browser.standardsMode) {
1032 var b = this._getBorderSizes(el);
1033 size[0] = el.clientHeight + (b[0] + b[2]);
1034 size[1] = el.clientWidth + (b[1] + b[3]);
1040 * @method _getBorderSizes
1041 * @description Get the CSS border size of the element passed.
1042 * @param {HTMLElement} el The element to get the border size of
1043 * @return {Array} An array of the top, right, bottom, left borders.
1045 _getBorderSizes: function(el) {
1047 el = el || this.get('element');
1048 if (this.browser.ie && !this.browser.standardsMode) {
1051 s[0] = parseInt(Dom.getStyle(el, 'borderTopWidth'), 10);
1052 s[1] = parseInt(Dom.getStyle(el, 'borderRightWidth'), 10);
1053 s[2] = parseInt(Dom.getStyle(el, 'borderBottomWidth'), 10);
1054 s[3] = parseInt(Dom.getStyle(el, 'borderLeftWidth'), 10);
1056 //IE will return NaN on these if they are set to auto, we'll set them to 0
1057 for (var i = 0; i < s.length; i++) {
1066 * @method _createClip
1067 * @description Create the clip element used when the Unit is collapsed
1069 _createClip: function() {
1071 this._clip = document.createElement('div');
1072 this._clip.className = 'yui-layout-clip yui-layout-clip-' + this.get('position');
1073 this._clip.innerHTML = '<div class="collapse"></div>';
1074 var c = this._clip.firstChild;
1075 c.title = this.STR_EXPAND;
1076 Event.on(c, 'click', this.expand, this, true);
1077 this.get('element').parentNode.appendChild(this._clip);
1082 * @method _toggleClip
1083 * @description Toggle th current state of the Clip element and set it's height, width and position
1085 _toggleClip: function() {
1086 if (!this._collapsed) {
1088 var hd = this._getBoxSize(this.header),
1089 ft = this._getBoxSize(this.footer),
1090 box = [this.get('height'), this.get('width')];
1093 var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
1094 nw = box[1] - (this._gutter.left + this._gutter.right),
1095 wrapH = (nh + (hd[0] + ft[0]));
1097 switch (this.get('position')) {
1100 this._setWidth(this._clip, nw);
1101 this._setHeight(this._clip, this.get('collapseSize'));
1102 Dom.setStyle(this._clip, 'left', (this._lastLeft + this._gutter.left) + 'px');
1103 if (this.get('position') == 'bottom') {
1104 Dom.setStyle(this._clip, 'top', ((this._lastTop + this._lastHeight) - (this.get('collapseSize') - this._gutter.top)) + 'px');
1106 Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
1111 this._setWidth(this._clip, this.get('collapseSize'));
1112 this._setHeight(this._clip, wrapH);
1113 Dom.setStyle(this._clip, 'top', (this.get('top') + this._gutter.top) + 'px');
1114 if (this.get('position') == 'right') {
1115 Dom.setStyle(this._clip, 'left', (((this._lastLeft + this._lastWidth) - this.get('collapseSize')) - this._gutter.left) + 'px');
1117 Dom.setStyle(this._clip, 'left', (this.get('left') + this._gutter.left) + 'px');
1122 Dom.setStyle(this._clip, 'display', 'block');
1123 this.setStyle('display', 'none');
1126 Dom.setStyle(this._clip, 'display', 'none');
1131 * @description Get a reference to the internal sizes object for this unit
1132 * @return {Object} An object of the sizes used for calculations
1134 getSizes: function() {
1139 * @description Toggles the Unit, replacing it with a clipped version.
1140 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1142 toggle: function() {
1143 if (this._collapsed) {
1152 * @description Expand the Unit if it is collapsed.
1153 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1155 expand: function() {
1156 if (!this._collapsed) {
1159 var retVal = this.fireEvent('beforeExpand');
1160 if (retVal === false) {
1164 this._collapsing = true;
1165 this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1168 this.setStyle('display', 'none');
1171 switch (this.get('position')) {
1174 this.set('width', this._lastWidth, true);
1175 this.setStyle('width', this._lastWidth + 'px');
1176 this.get('parent').resize(false);
1177 s = this.get('parent').getSizes()[this.get('position')];
1178 this.set('height', s.h, true);
1185 if (this.get('position') == 'left') {
1186 attr.left.from = (left - s.w);
1187 this.setStyle('left', (left - s.w) + 'px');
1192 this.set('height', this._lastHeight, true);
1193 this.setStyle('height', this._lastHeight + 'px');
1194 this.get('parent').resize(false);
1195 s = this.get('parent').getSizes()[this.get('position')];
1196 this.set('width', s.w, true);
1203 if (this.get('position') == 'top') {
1204 this.setStyle('top', (top - s.h) + 'px');
1205 attr.top.from = (top - s.h);
1210 this._anim.attributes = attr;
1211 var exStart = function() {
1212 this.setStyle('display', 'block');
1214 this._anim.onStart.unsubscribe(exStart, this, true);
1216 var expand = function() {
1217 this._collapsing = false;
1218 this.setStyle('zIndex', this.get('parent')._zIndex);
1219 this.set('width', this._lastWidth);
1220 this.set('height', this._lastHeight);
1221 this._collapsed = false;
1223 this.set('scroll', this._lastScroll);
1224 if (this._lastScrollTop > 0) {
1225 this.body.scrollTop = this._lastScrollTop;
1227 this._anim.onComplete.unsubscribe(expand, this, true);
1228 this.fireEvent('expand');
1230 this._anim.onStart.subscribe(exStart, this, true);
1231 this._anim.onComplete.subscribe(expand, this, true);
1232 this._anim.animate();
1235 this._collapsing = false;
1237 this._collapsed = false;
1238 this.setStyle('zIndex', this.get('parent')._zIndex);
1239 this.setStyle('display', 'block');
1240 this.set('width', this._lastWidth);
1241 this.set('height', this._lastHeight);
1243 this.set('scroll', this._lastScroll);
1244 if (this._lastScrollTop > 0) {
1245 this.body.scrollTop = this._lastScrollTop;
1247 this.fireEvent('expand');
1253 * @description Collapse the Unit if it is not collapsed.
1254 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1256 collapse: function() {
1257 if (this._collapsed) {
1260 var retValue = this.fireEvent('beforeCollapse');
1261 if (retValue === false) {
1267 this._collapsing = true;
1268 var w = this.get('width'),
1269 h = this.get('height'),
1271 this._lastWidth = w;
1272 this._lastHeight = h;
1273 this._lastScroll = this.get('scroll');
1274 this._lastScrollTop = this.body.scrollTop;
1275 this.set('scroll', false, true);
1276 this._lastLeft = parseInt(this.get('element').style.left, 10);
1277 this._lastTop = parseInt(this.get('element').style.top, 10);
1278 if (isNaN(this._lastTop)) {
1282 if (isNaN(this._lastLeft)) {
1284 this.set('left', 0);
1286 this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1287 var pos = this.get('position');
1292 this.set('height', (this.get('collapseSize') + (this._gutter.top + this._gutter.bottom)));
1295 to: (this.get('top') - h)
1298 if (pos == 'bottom') {
1299 attr.top.to = (this.get('top') + h);
1304 this.set('width', (this.get('collapseSize') + (this._gutter.left + this._gutter.right)));
1307 to: -(this._lastWidth)
1310 if (pos == 'right') {
1312 to: (this.get('left') + w)
1318 this._anim.attributes = attr;
1319 var collapse = function() {
1320 this._collapsing = false;
1322 this.setStyle('zIndex', this.get('parent')._zIndex);
1323 this._collapsed = true;
1324 this.get('parent').resize();
1325 this._anim.onComplete.unsubscribe(collapse, this, true);
1326 this.fireEvent('collapse');
1328 this._anim.onComplete.subscribe(collapse, this, true);
1329 this._anim.animate();
1331 this._collapsing = false;
1332 this.setStyle('display', 'none');
1334 this.setStyle('zIndex', this.get('parent')._zIndex);
1335 this.get('parent').resize();
1336 this._collapsed = true;
1337 this.fireEvent('collapse');
1343 * @description Close the unit, removing it from the parent Layout.
1344 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
1347 this.setStyle('display', 'none');
1348 this.get('parent').removeUnit(this);
1349 this.fireEvent('close');
1351 this._clip.parentNode.removeChild(this._clip);
1354 return this.get('parent');
1357 * @property loadHandler
1358 * @description Callback method for the YUI Connection Manager used for load the body using AJAX
1362 success: function(o) {
1363 this.body.innerHTML = o.responseText;
1366 failure: function(o) {
1370 * @property dataConnection
1371 * @description YUI Connection Manager handler
1374 dataConnection: null,
1377 * @property _loading
1378 * @description During the loading process this variable will be true
1383 * @method loadContent
1384 * @description Loading the content of the unit using the connection manager
1385 * @return {object} YUI Connection Manager handler
1387 loadContent: function() {
1388 // load dynamic content unless already loading or loaded and caching
1389 if (YAHOO.util.Connect && this.get('dataSrc') && !this._loading && !this.get('dataLoaded')) {
1390 this._loading = true;
1391 Dom.addClass(this.body, this.LOADING_CLASSNAME);
1392 this.dataConnection = YAHOO.util.Connect.asyncRequest(
1393 this.get('loadMethod'),
1394 this.get('dataSrc'),
1396 success: function(o) {
1397 this.loadHandler.success.call(this, o);
1398 this.set('dataLoaded', true);
1399 this.dataConnection = null;
1400 Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1401 this._loading = false;
1402 this.fireEvent('load');
1404 failure: function(o) {
1405 this.loadHandler.failure.call(this, o);
1406 this.dataConnection = null;
1407 Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1408 this._loading = false;
1409 this.fireEvent('loadError', { error: o });
1412 timeout: this.get('dataTimeout')
1415 return this.dataConnection;
1422 * @description The initalization method inherited from Element.
1424 init: function(p_oElement, p_oAttributes) {
1450 LayoutUnit.superclass.init.call(this, p_oElement, p_oAttributes);
1452 this.browser = this.get('parent').browser;
1454 var id = p_oElement;
1455 if (!Lang.isString(id)) {
1456 id = Dom.generateId(id);
1458 LayoutUnit._instances[id] = this;
1460 this.setStyle('position', 'absolute');
1462 this.addClass('yui-layout-unit');
1463 this.addClass('yui-layout-unit-' + this.get('position'));
1466 var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1468 this.header = header;
1470 var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1474 var footer = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1476 this.footer = footer;
1479 this.on('contentChange', this.resize, this, true);
1480 this._lastScrollTop = 0;
1482 this.set('animate', this.get('animate'));
1486 * @method initAttributes
1487 * @description Processes the config
1489 initAttributes: function(attr) {
1490 LayoutUnit.superclass.initAttributes.call(this, attr);
1495 * @description A reference to the wrap element
1498 this.setAttributeConfig('wrap', {
1499 value: attr.wrap || null,
1500 method: function(w) {
1502 var id = Dom.generateId(w);
1503 LayoutUnit._instances[id] = this;
1509 * @description Set this option to true if you want the LayoutUnit to fix the first layer of YUI CSS Grids (margins)
1512 this.setAttributeConfig('grids', {
1513 value: attr.grids || false
1518 * @description The current top positioning of the Unit
1521 this.setAttributeConfig('top', {
1522 value: attr.top || 0,
1523 validator: Lang.isNumber,
1524 method: function(t) {
1525 if (!this._collapsing) {
1526 this.setStyle('top', t + 'px');
1533 * @description The current left position of the Unit
1536 this.setAttributeConfig('left', {
1537 value: attr.left || 0,
1538 validator: Lang.isNumber,
1539 method: function(l) {
1540 if (!this._collapsing) {
1541 this.setStyle('left', l + 'px');
1547 * @attribute minWidth
1548 * @description The minWidth parameter passed to the Resize Utility
1551 this.setAttributeConfig('minWidth', {
1552 value: attr.minWidth || false,
1553 method: function(v) {
1555 this._resize.set('minWidth', v);
1558 validator: YAHOO.lang.isNumber
1562 * @attribute maxWidth
1563 * @description The maxWidth parameter passed to the Resize Utility
1566 this.setAttributeConfig('maxWidth', {
1567 value: attr.maxWidth || false,
1568 method: function(v) {
1570 this._resize.set('maxWidth', v);
1573 validator: YAHOO.lang.isNumber
1577 * @attribute minHeight
1578 * @description The minHeight parameter passed to the Resize Utility
1581 this.setAttributeConfig('minHeight', {
1582 value: attr.minHeight || false,
1583 method: function(v) {
1585 this._resize.set('minHeight', v);
1588 validator: YAHOO.lang.isNumber
1592 * @attribute maxHeight
1593 * @description The maxHeight parameter passed to the Resize Utility
1596 this.setAttributeConfig('maxHeight', {
1597 value: attr.maxHeight || false,
1598 method: function(v) {
1600 this._resize.set('maxHeight', v);
1603 validator: YAHOO.lang.isNumber
1608 * @description The height of the Unit
1611 this.setAttributeConfig('height', {
1613 validator: Lang.isNumber,
1614 method: function(h) {
1615 if (!this._collapsing) {
1619 this.setStyle('height', h + 'px');
1626 * @description The width of the Unit
1629 this.setAttributeConfig('width', {
1631 validator: Lang.isNumber,
1632 method: function(w) {
1633 if (!this._collapsing) {
1637 this.setStyle('width', w + 'px');
1643 * @description The CSS zIndex to give to the unit, so you can have overlapping elements such as menus in a unit.
1646 this.setAttributeConfig('zIndex', {
1647 value: attr.zIndex || false,
1648 method: function(z) {
1649 this.setStyle('zIndex', z);
1653 * @attribute position
1654 * @description The position (top, right, bottom, left or center) of the Unit in the Layout
1657 this.setAttributeConfig('position', {
1658 value: attr.position
1662 * @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)
1665 this.setAttributeConfig('gutter', {
1666 value: attr.gutter || 0,
1667 validator: YAHOO.lang.isString,
1668 method: function(gutter) {
1669 var p = gutter.split(' ');
1671 this._gutter.top = parseInt(p[0], 10);
1673 this._gutter.right = parseInt(p[1], 10);
1675 this._gutter.right = this._gutter.top;
1678 this._gutter.bottom = parseInt(p[2], 10);
1680 this._gutter.bottom = this._gutter.top;
1683 this._gutter.left = parseInt(p[3], 10);
1685 this._gutter.left = this._gutter.right;
1687 this._gutter.left = this._gutter.top;
1694 * @description The parent Layout that we are assigned to
1695 * @type {Object} YAHOO.widget.Layout
1697 this.setAttributeConfig('parent', {
1699 value: attr.parent || false,
1700 method: function(p) {
1702 p.on('resize', this.resize, this, true);
1708 * @attribute collapseSize
1709 * @description The pixel size of the Clip that we will collapse to
1712 this.setAttributeConfig('collapseSize', {
1713 value: attr.collapseSize || 25,
1714 validator: YAHOO.lang.isNumber
1717 * @attribute duration
1718 * @description The duration to give the Animation Utility when animating the opening and closing of Units
1720 this.setAttributeConfig('duration', {
1721 value: attr.duration || 0.5
1725 * @description The Animation Easing to apply to the Animation instance for this unit.
1727 this.setAttributeConfig('easing', {
1728 value: attr.easing || ((YAHOO.util && YAHOO.util.Easing) ? YAHOO.util.Easing.BounceIn : 'false')
1731 * @attribute animate
1732 * @description Use animation to collapse/expand the unit
1735 this.setAttributeConfig('animate', {
1736 value: ((attr.animate === false) ? false : true),
1737 validator: function() {
1739 if (YAHOO.util.Anim) {
1744 method: function(anim) {
1746 this._anim = new YAHOO.util.Anim(this.get('element'), {}, this.get('duration'), this.get('easing'));
1754 * @description The text to use as the Header of the Unit
1756 this.setAttributeConfig('header', {
1757 value: attr.header || false,
1758 method: function(txt) {
1759 if (txt === false) {
1762 Dom.addClass(this.body, 'yui-layout-bd-nohd');
1763 this.header.parentNode.removeChild(this.header);
1768 var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1770 header = this._createHeader();
1772 this.header = header;
1774 var h = this.header.getElementsByTagName('h2')[0];
1776 h = document.createElement('h2');
1777 this.header.appendChild(h);
1781 Dom.removeClass(this.body, 'yui-layout-bd-nohd');
1784 this.fireEvent('contentChange', { target: 'header' });
1789 * @description Use the proxy config setting for the Resize Utility
1792 this.setAttributeConfig('proxy', {
1794 value: ((attr.proxy === false) ? false : true)
1798 * @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.
1800 this.setAttributeConfig('body', {
1801 value: attr.body || false,
1802 method: function(content) {
1804 var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1808 body = document.createElement('div');
1809 body.className = 'yui-layout-bd';
1811 this.get('wrap').appendChild(body);
1815 Dom.addClass(this.body, 'yui-layout-bd-nohd');
1817 Dom.addClass(this.body, 'yui-layout-bd-noft');
1821 if (Lang.isString(content)) {
1822 el = Dom.get(content);
1823 } else if (content && content.tagName) {
1827 var id = Dom.generateId(el);
1828 LayoutUnit._instances[id] = this;
1829 this.body.appendChild(el);
1831 this.body.innerHTML = content;
1836 this.fireEvent('contentChange', { target: 'body' });
1842 * @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.
1844 this.setAttributeConfig('footer', {
1845 value: attr.footer || false,
1846 method: function(content) {
1847 if (content === false) {
1850 Dom.addClass(this.body, 'yui-layout-bd-noft');
1851 this.footer.parentNode.removeChild(this.footer);
1856 var ft = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1858 ft = document.createElement('div');
1859 ft.className = 'yui-layout-ft';
1861 this.get('wrap').appendChild(ft);
1867 if (Lang.isString(content)) {
1868 el = Dom.get(content);
1869 } else if (content && content.tagName) {
1873 this.footer.appendChild(el);
1875 this.footer.innerHTML = content;
1877 Dom.removeClass(this.body, 'yui-layout-bd-noft');
1879 this.fireEvent('contentChange', { target: 'footer' });
1884 * @description Adds a close icon to the unit
1886 this.setAttributeConfig('close', {
1887 value: attr.close || false,
1888 method: function(close) {
1889 //Position Center doesn't get this
1890 if (this.get('position') == 'center') {
1893 if (!this.header && close) {
1894 this._createHeader();
1896 var c = Dom.getElementsByClassName('close', 'div', this.header)[0];
1898 //Force some header text if there isn't any
1899 if (!this.get('header')) {
1900 this.set('header', ' ');
1903 c = document.createElement('div');
1904 c.className = 'close';
1905 this.header.appendChild(c);
1906 Event.on(c, 'click', this.close, this, true);
1908 c.title = this.STR_CLOSE;
1909 } else if (c && c.parentNode) {
1910 Event.purgeElement(c);
1911 c.parentNode.removeChild(c);
1913 this._configs.close.value = close;
1914 this.set('collapse', this.get('collapse')); //Reset so we get the right classnames
1919 * @attribute collapse
1920 * @description Adds a collapse icon to the unit
1922 this.setAttributeConfig('collapse', {
1923 value: attr.collapse || false,
1924 method: function(collapse) {
1925 //Position Center doesn't get this
1926 if (this.get('position') == 'center') {
1929 if (!this.header && collapse) {
1930 this._createHeader();
1932 var c = Dom.getElementsByClassName('collapse', 'div', this.header)[0];
1934 //Force some header text if there isn't any
1935 if (!this.get('header')) {
1936 this.set('header', ' ');
1939 c = document.createElement('div');
1940 this.header.appendChild(c);
1941 Event.on(c, 'click', this.collapse, this, true);
1943 c.title = this.STR_COLLAPSE;
1944 c.className = 'collapse' + ((this.get('close')) ? ' collapse-close' : '');
1945 } else if (c && c.parentNode) {
1946 Event.purgeElement(c);
1947 c.parentNode.removeChild(c);
1953 * @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.
1954 * @type Boolean/Null
1957 this.setAttributeConfig('scroll', {
1958 value: (((attr.scroll === true) || (attr.scroll === false) || (attr.scroll === null)) ? attr.scroll : false),
1959 method: function(scroll) {
1960 if ((scroll === false) && !this._collapsed) { //Removing scroll bar
1962 if (this.body.scrollTop > 0) {
1963 this._lastScrollTop = this.body.scrollTop;
1968 if (scroll === true) {
1969 this.addClass('yui-layout-scroll');
1970 this.removeClass('yui-layout-noscroll');
1971 if (this._lastScrollTop > 0) {
1973 this.body.scrollTop = this._lastScrollTop;
1976 } else if (scroll === false) {
1977 this.removeClass('yui-layout-scroll');
1978 this.addClass('yui-layout-noscroll');
1979 } else if (scroll === null) {
1980 this.removeClass('yui-layout-scroll');
1981 this.removeClass('yui-layout-noscroll');
1987 * @description Config option to pass to the Resize Utility
1989 this.setAttributeConfig('hover', {
1991 value: attr.hover || false,
1992 validator: YAHOO.lang.isBoolean
1995 * @attribute useShim
1996 * @description Config option to pass to the Resize Utility
1998 this.setAttributeConfig('useShim', {
1999 value: attr.useShim || false,
2000 validator: YAHOO.lang.isBoolean,
2001 method: function(u) {
2003 this._resize.set('useShim', u);
2009 * @description Should a Resize instance be added to this unit
2012 this.setAttributeConfig('resize', {
2013 value: attr.resize || false,
2014 validator: function(r) {
2015 if (YAHOO.util && YAHOO.util.Resize) {
2020 method: function(resize) {
2021 if (resize && !this._resize) {
2022 //Position Center doesn't get this
2023 if (this.get('position') == 'center') {
2026 var handle = false; //To catch center
2027 switch (this.get('position')) {
2042 this.setStyle('position', 'absolute'); //Make sure Resize get's a position
2045 this._resize = new YAHOO.util.Resize(this.get('element'), {
2046 proxy: this.get('proxy'),
2047 hover: this.get('hover'),
2051 minWidth: this.get('minWidth'),
2052 maxWidth: this.get('maxWidth'),
2053 minHeight: this.get('minHeight'),
2054 maxHeight: this.get('maxHeight'),
2055 height: this.get('height'),
2056 width: this.get('width'),
2058 useShim: this.get('useShim'),
2062 this._resize._handles[handle].innerHTML = '<div class="yui-layout-resize-knob"></div>';
2064 if (this.get('proxy')) {
2065 var proxy = this._resize.getProxyEl();
2066 proxy.innerHTML = '<div class="yui-layout-handle-' + handle + '"></div>';
2068 this._resize.on('startResize', function(ev) {
2069 this._lastScroll = this.get('scroll');
2070 this.set('scroll', false);
2071 if (this.get('parent')) {
2072 this.get('parent').fireEvent('startResize');
2073 var c = this.get('parent').getUnitByPosition('center');
2074 this._lastCenterScroll = c.get('scroll');
2075 c.addClass(this._resize.CSS_RESIZING);
2076 c.set('scroll', false);
2078 this.fireEvent('startResize');
2080 this._resize.on('resize', function(ev) {
2081 this.set('height', ev.height);
2082 this.set('width', ev.width);
2084 this._resize.on('endResize', function(ev) {
2085 this.set('scroll', this._lastScroll);
2086 if (this.get('parent')) {
2087 var c = this.get('parent').getUnitByPosition('center');
2088 c.set('scroll', this._lastCenterScroll);
2089 c.removeClass(this._resize.CSS_RESIZING);
2092 this.fireEvent('endResize');
2097 this._resize.destroy();
2103 * The unit data source, used for loading content dynamically.
2104 * @attribute dataSrc
2107 this.setAttributeConfig('dataSrc', {
2111 * The method to use for the data request.
2112 * @attribute loadMethod
2116 this.setAttributeConfig('loadMethod', {
2117 value: attr.loadMethod || 'GET',
2118 validator: YAHOO.lang.isString
2121 * Whether or not any data has been loaded from the server.
2122 * @attribute dataLoaded
2125 this.setAttributeConfig('dataLoaded', {
2127 validator: YAHOO.lang.isBoolean,
2131 * Number if milliseconds before aborting and calling failure handler.
2132 * @attribute dataTimeout
2136 this.setAttributeConfig('dataTimeout', {
2137 value: attr.dataTimeout || null,
2138 validator: YAHOO.lang.isNumber
2143 * @method _cleanGrids
2144 * @description This method attempts to clean up the first level of the YUI CSS Grids, YAHOO.util.Selector is required for this operation.
2146 _cleanGrids: function() {
2147 if (this.get('grids')) {
2148 var b = Sel.query('div.yui-b', this.body, true);
2150 Dom.removeClass(b, 'yui-b');
2152 Event.onAvailable('yui-main', function() {
2153 Dom.setStyle(Sel.query('#yui-main'), 'margin-left', '0');
2154 Dom.setStyle(Sel.query('#yui-main'), 'margin-right', '0');
2160 * @method _createHeader
2161 * @description Creates the HTMLElement for the header
2162 * @return {HTMLElement} The new HTMLElement
2164 _createHeader: function() {
2165 var header = document.createElement('div');
2166 header.className = 'yui-layout-hd';
2167 if (this.get('firstChild')) {
2168 this.get('wrap').insertBefore(header, this.get('wrap').firstChild);
2170 this.get('wrap').appendChild(header);
2172 this.header = header;
2177 * @param {Boolean} force Don't report to the parent, because we are being called from the parent.
2178 * @description Removes this unit from the parent and cleans up after itself.
2179 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
2181 destroy: function(force) {
2183 this._resize.destroy();
2185 var par = this.get('parent');
2187 this.setStyle('display', 'none');
2189 this._clip.parentNode.removeChild(this._clip);
2194 par.removeUnit(this);
2198 par.removeListener('resize', this.resize, this, true);
2200 this.unsubscribeAll();
2201 Event.purgeElement(this.get('element'));
2202 this.get('parentNode').removeChild(this.get('element'));
2204 delete YAHOO.widget.LayoutUnit._instances[this.get('id')];
2205 //Brutal Object Destroy
2206 for (var i in this) {
2207 if (Lang.hasOwnProperty(this, i)) {
2217 * @description Returns a string representing the LayoutUnit.
2220 toString: function() {
2222 return 'LayoutUnit #' + this.get('id') + ' (' + this.get('position') + ')';
2224 return 'LayoutUnit';
2228 * @description Fired when this.resize is called
2229 * @type YAHOO.util.CustomEvent
2232 * @event startResize
2233 * @description Fired when the Resize Utility fires it's startResize Event.
2234 * @type YAHOO.util.CustomEvent
2238 * @description Fired when the Resize Utility fires it's endResize Event.
2239 * @type YAHOO.util.CustomEvent
2242 * @event beforeResize
2243 * @description Fired at the beginning of the resize method. If you return false, the resize is cancelled.
2244 * @type YAHOO.util.CustomEvent
2247 * @event contentChange
2248 * @description Fired when the content in the header, body or footer is changed via the API
2249 * @type YAHOO.util.CustomEvent
2253 * @description Fired when the unit is closed
2254 * @type YAHOO.util.CustomEvent
2257 * @event beforeCollapse
2258 * @description Fired before the unit is collapsed. If you return false, the collapse is cancelled.
2259 * @type YAHOO.util.CustomEvent
2263 * @description Fired when the unit is collapsed
2264 * @type YAHOO.util.CustomEvent
2268 * @description Fired when the unit is exanded
2269 * @type YAHOO.util.CustomEvent
2272 * @event beforeExpand
2273 * @description Fired before the unit is exanded. If you return false, the collapse is cancelled.
2274 * @type YAHOO.util.CustomEvent
2278 * @description Fired when data is loaded via the dataSrc config.
2279 * @type YAHOO.util.CustomEvent
2283 * @description Fired when an error occurs loading data via the dataSrc config. Error message is passed as argument to this event.
2284 * @type YAHOO.util.CustomEvent
2288 YAHOO.widget.LayoutUnit = LayoutUnit;
2290 YAHOO.register("layout", YAHOO.widget.Layout, {version: "2.8.0r4", build: "2449"});