[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/2in3/2.9.0/build/yui2-layout/ -> yui2-layout.js (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1