PageRenderTime 86ms CodeModel.GetById 19ms app.highlight 56ms RepoModel.GetById 1ms app.codeStats 0ms

/hippo/src/main/webapp/yui/layout/layout-debug.js

http://hdbc.googlecode.com/
JavaScript | 1781 lines | 1103 code | 83 blank | 595 comment | 208 complexity | 3faf7abd41763cde29d7d15e80358885 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2Copyright (c) 2009, Yahoo! Inc. All rights reserved.
   3Code licensed under the BSD License:
   4http://developer.yahoo.net/yui/license.txt
   5version: 2.7.0
   6*/
   7/**
   8 * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
   9 * @namespace YAHOO.widget
  10 * @requires yahoo, dom, element, event
  11 * @module layout
  12 */
  13(function() {
  14    var Dom = YAHOO.util.Dom,
  15        Event = YAHOO.util.Event,
  16        Lang = YAHOO.lang;
  17
  18    /**
  19     * @constructor
  20     * @class Layout
  21     * @extends YAHOO.util.Element
  22     * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
  23     * @param {String/HTMLElement} el The element to make contain a layout.
  24     * @param {Object} attrs Object liternal containing configuration parameters.
  25    */
  26
  27    var Layout = function(el, config) {
  28        YAHOO.log('Creating the Layout Object', 'info', 'Layout');
  29        if (Lang.isObject(el) && !el.tagName) {
  30            config = el;
  31            el = null;
  32        }
  33        if (Lang.isString(el)) {
  34            if (Dom.get(el)) {
  35                el = Dom.get(el);
  36            }
  37        }
  38        if (!el) {
  39            el = document.body;
  40        }
  41
  42        var oConfig = {
  43            element: el,
  44            attributes: config || {}
  45        };
  46
  47        Layout.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
  48    };
  49
  50    /**
  51    * @private
  52    * @static
  53    * @property _instances
  54    * @description Internal hash table for all layout instances
  55    * @type Object
  56    */ 
  57    Layout._instances = {};
  58    /**
  59    * @static
  60    * @method getLayoutById 
  61    * @description Get's a layout object by the HTML id of the element associated with the Layout object.
  62    * @return {Object} The Layout Object
  63    */ 
  64    Layout.getLayoutById = function(id) {
  65        if (Layout._instances[id]) {
  66            return Layout._instances[id];
  67        }
  68        return false;
  69    };
  70
  71    YAHOO.extend(Layout, YAHOO.util.Element, {
  72        /**
  73        * @property browser
  74        * @description A modified version of the YAHOO.env.ua object
  75        * @type Object
  76        */
  77        browser: function() {
  78            var b = YAHOO.env.ua;
  79            b.standardsMode = false;
  80            b.secure = false;
  81            return b;
  82        }(),
  83        /**
  84        * @private
  85        * @property _units
  86        * @description An object literal that contains a list of units in the layout
  87        * @type Object
  88        */
  89        _units: null,
  90        /**
  91        * @private
  92        * @property _rendered
  93        * @description Set to true when the layout is rendered
  94        * @type Boolean
  95        */
  96        _rendered: null,
  97        /**
  98        * @private
  99        * @property _zIndex
 100        * @description The zIndex to set all LayoutUnits to
 101        * @type Number
 102        */
 103        _zIndex: null,
 104        /**
 105        * @private
 106        * @property _sizes
 107        * @description A collection of the current sizes of all usable LayoutUnits to be used for calculations
 108        * @type Object
 109        */
 110        _sizes: null,
 111        /**
 112        * @private
 113        * @method _setBodySize
 114        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
 115        * @description Used to set the body size of the layout, sets the height and width of the parent container
 116        */
 117        _setBodySize: function(set) {
 118            var h = 0, w = 0;
 119            set = ((set === false) ? false : true);
 120
 121            if (this._isBody) {
 122                h = Dom.getClientHeight();
 123                w = Dom.getClientWidth();
 124            } else {
 125                h = parseInt(this.getStyle('height'), 10);
 126                w = parseInt(this.getStyle('width'), 10);
 127                if (isNaN(w)) {
 128                    w = this.get('element').clientWidth;
 129                }
 130                if (isNaN(h)) {
 131                    h = this.get('element').clientHeight;
 132                }
 133            }
 134            if (this.get('minWidth')) {
 135                if (w < this.get('minWidth')) {
 136                    w = this.get('minWidth');
 137                }
 138            }
 139            if (this.get('minHeight')) {
 140                if (h < this.get('minHeight')) {
 141                    h = this.get('minHeight');
 142                }
 143            }
 144            if (set) {
 145                Dom.setStyle(this._doc, 'height', h + 'px');
 146                Dom.setStyle(this._doc, 'width', w + 'px');
 147            }
 148            this._sizes.doc = { h: h, w: w };
 149            YAHOO.log('Setting Body height and width: (' + h + ',' + w + ')', 'info', 'Layout');
 150            this._setSides(set);
 151        },
 152        /**
 153        * @private
 154        * @method _setSides
 155        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
 156        * @description Used to set the size and position of the left, right, top and bottom units
 157        */
 158        _setSides: function(set) {
 159            YAHOO.log('Setting side units', 'info', 'Layout');
 160            var h1 = ((this._units.top) ? this._units.top.get('height') : 0),
 161                h2 = ((this._units.bottom) ? this._units.bottom.get('height') : 0),
 162                h = this._sizes.doc.h,
 163                w = this._sizes.doc.w;
 164            set = ((set === false) ? false : true);
 165
 166            this._sizes.top = {
 167                h: h1, w: ((this._units.top) ? w : 0),
 168                t: 0
 169            };
 170            this._sizes.bottom = {
 171                h: h2, w: ((this._units.bottom) ? w : 0)
 172            };
 173            
 174            var newH = (h - (h1 + h2));
 175
 176            this._sizes.left = {
 177                h: newH, w: ((this._units.left) ? this._units.left.get('width') : 0)
 178            };
 179            this._sizes.right = {
 180                h: newH, w: ((this._units.right) ? this._units.right.get('width') : 0),
 181                l: ((this._units.right) ? (w - this._units.right.get('width')) : 0),
 182                t: ((this._units.top) ? this._sizes.top.h : 0)
 183            };
 184            
 185            if (this._units.right && set) {
 186                this._units.right.set('top', this._sizes.right.t);
 187                if (!this._units.right._collapsing) { 
 188                    this._units.right.set('left', this._sizes.right.l);
 189                }
 190                this._units.right.set('height', this._sizes.right.h, true);
 191            }
 192            if (this._units.left) {
 193                this._sizes.left.l = 0;
 194                if (this._units.top) {
 195                    this._sizes.left.t = this._sizes.top.h;
 196                } else {
 197                    this._sizes.left.t = 0;
 198                }
 199                if (set) {
 200                    this._units.left.set('top', this._sizes.left.t);
 201                    this._units.left.set('height', this._sizes.left.h, true);
 202                    this._units.left.set('left', 0);
 203                }
 204            }
 205            if (this._units.bottom) {
 206                this._sizes.bottom.t = this._sizes.top.h + this._sizes.left.h;
 207                if (set) {
 208                    this._units.bottom.set('top', this._sizes.bottom.t);
 209                    this._units.bottom.set('width', this._sizes.bottom.w, true);
 210                }
 211            }
 212            if (this._units.top) {
 213                if (set) {
 214                    this._units.top.set('width', this._sizes.top.w, true);
 215                }
 216            }
 217            YAHOO.log('Setting sizes: (' + Lang.dump(this._sizes) + ')', 'info', 'Layout');
 218            this._setCenter(set);
 219        },
 220        /**
 221        * @private
 222        * @method _setCenter
 223        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
 224        * @description Used to set the size and position of the center unit
 225        */
 226        _setCenter: function(set) {
 227            set = ((set === false) ? false : true);
 228            var h = this._sizes.left.h;
 229            var w = (this._sizes.doc.w - (this._sizes.left.w + this._sizes.right.w));
 230            if (set) {
 231                this._units.center.set('height', h, true);
 232                this._units.center.set('width', w, true);
 233                this._units.center.set('top', this._sizes.top.h);
 234                this._units.center.set('left', this._sizes.left.w);
 235            }
 236            this._sizes.center = { h: h, w: w, t: this._sizes.top.h, l: this._sizes.left.w };
 237            YAHOO.log('Setting Center size to: (' + h + ', ' + w + ')', 'info', 'Layout');
 238        },
 239        /**
 240        * @method getSizes
 241        * @description Get a reference to the internal Layout Unit sizes object used to build the layout wireframe
 242        * @return {Object} An object of the layout unit sizes
 243        */
 244        getSizes: function() {
 245            return this._sizes;
 246        },
 247        /**
 248        * @method getUnitById
 249        * @param {String} id The HTML element id of the unit
 250        * @description Get the LayoutUnit by it's HTML id
 251        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
 252        */
 253        getUnitById: function(id) {
 254            return YAHOO.widget.LayoutUnit.getLayoutUnitById(id);
 255        },
 256        /**
 257        * @method getUnitByPosition
 258        * @param {String} pos The position of the unit in this layout
 259        * @description Get the LayoutUnit by it's position in this layout
 260        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
 261        */
 262        getUnitByPosition: function(pos) {
 263            if (pos) {
 264                pos = pos.toLowerCase();
 265                if (this._units[pos]) {
 266                    return this._units[pos];
 267                }
 268                return false;
 269            }
 270            return false;
 271        },
 272        /**
 273        * @method removeUnit
 274        * @param {Object} unit The LayoutUnit that you want to remove
 275        * @description Remove the unit from this layout and resize the layout.
 276        */
 277        removeUnit: function(unit) {
 278            delete this._units[unit.get('position')];
 279            this.resize();
 280        },
 281        /**
 282        * @method addUnit
 283        * @param {Object} cfg The config for the LayoutUnit that you want to add
 284        * @description Add a unit to this layout and if the layout is rendered, resize the layout. 
 285        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
 286        */
 287        addUnit: function(cfg) {
 288            if (!cfg.position) {
 289                YAHOO.log('No position property passed', 'error', 'Layout');
 290                return false;
 291            }
 292            if (this._units[cfg.position]) {
 293                YAHOO.log('Position already exists', 'error', 'Layout');
 294                return false;
 295            }
 296            YAHOO.log('Adding Unit at position: ' + cfg.position, 'info', 'Layout');
 297            var element = null,
 298                el = null;
 299
 300            if (cfg.id) {
 301                if (Dom.get(cfg.id)) {
 302                    element = Dom.get(cfg.id);
 303                    delete cfg.id;
 304
 305                }
 306            }
 307            if (cfg.element) {
 308                element = cfg.element;
 309            }
 310
 311            if (!el) {
 312                el = document.createElement('div');
 313                var id = Dom.generateId();
 314                el.id = id;
 315            }
 316
 317            if (!element) {
 318                element = document.createElement('div');
 319            }
 320            Dom.addClass(element, 'yui-layout-wrap');
 321            if (this.browser.ie && !this.browser.standardsMode) {
 322                el.style.zoom = 1;
 323                element.style.zoom = 1;
 324            }
 325
 326            if (el.firstChild) {
 327                el.insertBefore(element, el.firstChild);
 328            } else {
 329                el.appendChild(element);
 330            }
 331            this._doc.appendChild(el);
 332
 333            var h = false, w = false;
 334
 335            if (cfg.height) {
 336                h = parseInt(cfg.height, 10);
 337            }
 338            if (cfg.width) {
 339                w = parseInt(cfg.width, 10);
 340            }
 341            var unitConfig = {};
 342            YAHOO.lang.augmentObject(unitConfig, cfg); // break obj ref
 343
 344            unitConfig.parent = this;
 345            unitConfig.wrap = element;
 346            unitConfig.height = h;
 347            unitConfig.width = w;
 348
 349            var unit = new YAHOO.widget.LayoutUnit(el, unitConfig);
 350
 351            unit.on('heightChange', this.resize, this, true);
 352            unit.on('widthChange', this.resize, this, true);
 353            unit.on('gutterChange', this.resize, this, true);
 354            this._units[cfg.position] = unit;
 355
 356            if (this._rendered) {
 357                this.resize();
 358            }
 359
 360            return unit;
 361        },
 362        /**
 363        * @private
 364        * @method _createUnits
 365        * @description Private method to create units from the config that was passed in.
 366        */
 367        _createUnits: function() {
 368            var units = this.get('units');
 369            for (var i in units) {
 370                if (Lang.hasOwnProperty(units, i)) {
 371                    this.addUnit(units[i]);
 372                }
 373            }
 374        },
 375        /**
 376        * @method resize
 377        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
 378        * @description Starts the chain of resize routines that will resize all the units.
 379        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
 380        */
 381        resize: function(set) {
 382            set = ((set === false) ? false : true);
 383            if (set) {
 384                var retVal = this.fireEvent('beforeResize');
 385                if (retVal === false) {
 386                    set = false;
 387                }
 388                if (this.browser.ie) {
 389                    if (this._isBody) {
 390                        Dom.removeClass(document.documentElement, 'yui-layout');
 391                        Dom.addClass(document.documentElement, 'yui-layout');
 392                    } else {
 393                        this.removeClass('yui-layout');
 394                        this.addClass('yui-layout');
 395                    }
 396                }
 397            }
 398            this._setBodySize(set);
 399            if (set) {
 400                this.fireEvent('resize', { target: this, sizes: this._sizes });
 401            }
 402            return this;
 403        },
 404        /**
 405        * @private
 406        * @method _setupBodyElements
 407        * @description Sets up the main doc element when using the body as the main element.
 408        */
 409        _setupBodyElements: function() {
 410            this._doc = Dom.get('layout-doc');
 411            if (!this._doc) {
 412                this._doc = document.createElement('div');
 413                this._doc.id = 'layout-doc';
 414                if (document.body.firstChild) {
 415                    document.body.insertBefore(this._doc, document.body.firstChild);
 416                } else {
 417                    document.body.appendChild(this._doc);
 418                }
 419            }
 420            this._createUnits();
 421            this._setBodySize();
 422            Event.on(window, 'resize', this.resize, this, true);
 423            Dom.addClass(this._doc, 'yui-layout-doc');
 424        },
 425        /**
 426        * @private
 427        * @method _setupElements
 428        * @description Sets up the main doc element when not using the body as the main element.
 429        */
 430        _setupElements: function() {
 431            this._doc = this.getElementsByClassName('yui-layout-doc')[0];
 432            if (!this._doc) {
 433                this._doc = document.createElement('div');
 434                this.get('element').appendChild(this._doc);
 435            }
 436            this._createUnits();
 437            this._setBodySize();
 438            Dom.addClass(this._doc, 'yui-layout-doc');
 439        },
 440        /**
 441        * @private
 442        * @property _isBody
 443        * @description Flag to determine if we are using the body as the root element.
 444        * @type Boolean
 445        */
 446        _isBody: null,
 447        /**
 448        * @private
 449        * @property _doc
 450        * @description Reference to the root element
 451        * @type HTMLElement
 452        */
 453        _doc: null,
 454        /**
 455        * @private
 456        * @method init
 457        * @description The Layout class' initialization method
 458        */        
 459        init: function(p_oElement, p_oAttributes) {
 460            YAHOO.log('init', 'info', 'Layout');
 461
 462            this._zIndex = 0;
 463
 464            Layout.superclass.init.call(this, p_oElement, p_oAttributes);
 465            
 466            if (this.get('parent')) {
 467                this._zIndex = this.get('parent')._zIndex + 10;
 468            }
 469
 470            this._sizes = {};
 471            this._units = {};
 472
 473            var id = p_oElement;
 474            if (!Lang.isString(id)) {
 475                id = Dom.generateId(id);
 476            }
 477            Layout._instances[id] = this;
 478        },
 479        /**
 480        * @method render
 481        * @description This method starts the render process, applying classnames and creating elements
 482        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
 483        */        
 484        render: function() {
 485            YAHOO.log('Render', 'info', 'Layout');
 486            this._stamp();
 487            var el = this.get('element');
 488            if (el && el.tagName && (el.tagName.toLowerCase() == 'body')) {
 489                this._isBody = true;
 490                Dom.addClass(document.body, 'yui-layout');
 491                if (Dom.hasClass(document.body, 'yui-skin-sam')) {
 492                    //Move the class up so we can have a css chain
 493                    Dom.addClass(document.documentElement, 'yui-skin-sam');
 494                    Dom.removeClass(document.body, 'yui-skin-sam');
 495                }
 496                this._setupBodyElements();
 497            } else {
 498                this._isBody = false;
 499                this.addClass('yui-layout');
 500                this._setupElements();
 501            }
 502            this.resize();
 503            this._rendered = true;
 504            this.fireEvent('render');
 505
 506            return this;
 507        },
 508        /**
 509        * @private
 510        * @method _stamp
 511        * @description Stamps the root node with a secure classname for ease of use. Also sets the this.browser.standardsMode variable.
 512        */        
 513        _stamp: function() {
 514            if (document.compatMode == 'CSS1Compat') {
 515                this.browser.standardsMode = true;
 516            }
 517            if (window.location.href.toLowerCase().indexOf("https") === 0) {
 518                Dom.addClass(document.documentElement, 'secure');
 519                this.browser.secure = true;
 520            }
 521        },
 522        /**
 523        * @private
 524        * @method initAttributes
 525        * @description Processes the config
 526        */        
 527        initAttributes: function(attr) {
 528            Layout.superclass.initAttributes.call(this, attr);
 529            /**
 530            * @attribute units
 531            * @description An array of config definitions for the LayoutUnits to add to this layout
 532            * @type Array
 533            */
 534            this.setAttributeConfig('units', {
 535                writeOnce: true,
 536                validator: YAHOO.lang.isArray,
 537                value: attr.units || []
 538            });
 539
 540            /**
 541            * @attribute minHeight
 542            * @description The minimum height in pixels
 543            * @type Number
 544            */
 545            this.setAttributeConfig('minHeight', {
 546                value: attr.minHeight || false,
 547                validator: YAHOO.lang.isNumber
 548            });
 549
 550            /**
 551            * @attribute minWidth
 552            * @description The minimum width in pixels
 553            * @type Number
 554            */
 555            this.setAttributeConfig('minWidth', {
 556                value: attr.minWidth || false,
 557                validator: YAHOO.lang.isNumber
 558            });
 559
 560            /**
 561            * @attribute height
 562            * @description The height in pixels
 563            * @type Number
 564            */
 565            this.setAttributeConfig('height', {
 566                value: attr.height || false,
 567                validator: YAHOO.lang.isNumber,
 568                method: function(h) {
 569                    this.setStyle('height', h + 'px');
 570                }
 571            });
 572
 573            /**
 574            * @attribute width
 575            * @description The width in pixels
 576            * @type Number
 577            */
 578            this.setAttributeConfig('width', {
 579                value: attr.width || false,
 580                validator: YAHOO.lang.isNumber,
 581                method: function(w) {
 582                    this.setStyle('width', w + 'px');
 583                }
 584            });
 585
 586            /**
 587            * @attribute parent
 588            * @description If this layout is to be used as a child of another Layout instance, this config will bind the resize events together.
 589            * @type Object YAHOO.widget.Layout
 590            */
 591            this.setAttributeConfig('parent', {
 592                writeOnce: true,
 593                value: attr.parent || false,
 594                method: function(p) {
 595                    if (p) {
 596                        p.on('resize', this.resize, this, true);
 597                    }
 598                }
 599            });
 600        },
 601        /**
 602        * @method destroy
 603        * @description Removes this layout from the page and destroys all units that it contains. This will destroy all data inside the layout and it's children.
 604        */
 605        destroy: function() {
 606            var par = this.get('parent');
 607            if (par) {
 608                par.removeListener('resize', this.resize, this, true);
 609            }
 610            Event.removeListener(window, 'resize', this.resize, this, true);
 611
 612            this.unsubscribeAll();
 613            for (var u in this._units) {
 614                if (Lang.hasOwnProperty(this._units, u)) {
 615                    if (this._units[u]) {
 616                        this._units[u].destroy(true);
 617                    }
 618                }
 619            }
 620
 621            Event.purgeElement(this.get('element'));
 622            this.get('parentNode').removeChild(this.get('element'));
 623            
 624            delete YAHOO.widget.Layout._instances[this.get('id')];
 625            //Brutal Object Destroy
 626            for (var i in this) {
 627                if (Lang.hasOwnProperty(this, i)) {
 628                    this[i] = null;
 629                    delete this[i];
 630                }
 631            }
 632            
 633            if (par) {
 634                par.resize();
 635            }
 636        },
 637        /**
 638        * @method toString
 639        * @description Returns a string representing the Layout.
 640        * @return {String}
 641        */        
 642        toString: function() {
 643            if (this.get) {
 644                return 'Layout #' + this.get('id');
 645            }
 646            return 'Layout';
 647        }
 648    });
 649    /**
 650    * @event resize
 651    * @description Fired when this.resize is called
 652    * @type YAHOO.util.CustomEvent
 653    */
 654    /**
 655    * @event startResize
 656    * @description Fired when the Resize Utility for a Unit fires it's startResize Event.
 657    * @type YAHOO.util.CustomEvent
 658    */
 659    /**
 660    * @event beforeResize
 661    * @description Fires at the beginning of the resize method. If you return false, the resize is cancelled.
 662    * @type YAHOO.util.CustomEvent
 663    */
 664    /**
 665    * @event render
 666    * @description Fired after the render method completes.
 667    * @type YAHOO.util.CustomEvent
 668    */
 669
 670    YAHOO.widget.Layout = Layout;
 671})();
 672/**
 673 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
 674 * @namespace YAHOO.widget
 675 * @requires yahoo, dom, element, event, layout
 676 * @optional animation, dragdrop, selector
 677 */
 678(function() {
 679    var Dom = YAHOO.util.Dom,
 680        Sel = YAHOO.util.Selector,
 681        Event = YAHOO.util.Event,
 682        Lang = YAHOO.lang;
 683
 684    /**
 685     * @constructor
 686     * @class LayoutUnit
 687     * @extends YAHOO.util.Element
 688     * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
 689     * @param {String/HTMLElement} el The element to make a unit.
 690     * @param {Object} attrs Object liternal containing configuration parameters.
 691    */
 692
 693    var LayoutUnit = function(el, config) {
 694        
 695        var oConfig = {
 696            element: el,
 697            attributes: config || {}
 698        };
 699
 700        LayoutUnit.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
 701    };
 702
 703    /**
 704    * @private
 705    * @static
 706    * @property _instances
 707    * @description Internal hash table for all layout unit instances
 708    * @type Object
 709    */ 
 710    LayoutUnit._instances = {};
 711    /**
 712    * @static
 713    * @method getLayoutUnitById 
 714    * @description Get's a layout unit object by the HTML id of the element associated with the Layout Unit object.
 715    * @return {Object} The Layout Object
 716    */ 
 717    LayoutUnit.getLayoutUnitById = function(id) {
 718        if (LayoutUnit._instances[id]) {
 719            return LayoutUnit._instances[id];
 720        }
 721        return false;
 722    };
 723
 724    YAHOO.extend(LayoutUnit, YAHOO.util.Element, {
 725        /**
 726        * @property STR_CLOSE
 727        * @description String used for close button title
 728        * @type {String}
 729        */
 730        STR_CLOSE: 'Click to close this pane.',
 731        /**
 732        * @property STR_COLLAPSE
 733        * @description String used for collapse button title
 734        * @type {String}
 735        */
 736        STR_COLLAPSE: 'Click to collapse this pane.',
 737        /**
 738        * @property STR_EXPAND
 739        * @description String used for expand button title
 740        * @type {String}
 741        */
 742        STR_EXPAND: 'Click to expand this pane.',
 743        /**
 744	    * The class name applied to dynamic tabs while loading.
 745	    * @property LOADING_CLASSNAME
 746	    * @type String
 747	    * @default "disabled"
 748	    */
 749	    LOADING_CLASSNAME: 'loading',
 750        /**
 751        * @property browser
 752        * @description A modified version of the YAHOO.env.ua object
 753        * @type Object
 754        */
 755        browser: null,
 756        /**
 757        * @private
 758        * @property _sizes
 759        * @description A collection of the current sizes of the contents of this Layout Unit
 760        * @type Object
 761        */
 762        _sizes: null,
 763        /**
 764        * @private
 765        * @property _anim
 766        * @description A reference to the Animation instance used by this LayouUnit
 767        * @type YAHOO.util.Anim
 768        */
 769        _anim: null,
 770        /**
 771        * @private
 772        * @property _resize
 773        * @description A reference to the Resize instance used by this LayoutUnit
 774        * @type YAHOO.util.Resize
 775        */
 776        _resize: null,
 777        /**
 778        * @private
 779        * @property _clip
 780        * @description A reference to the clip element used when collapsing the unit
 781        * @type HTMLElement
 782        */
 783        _clip: null,
 784        /**
 785        * @private
 786        * @property _gutter
 787        * @description A simple hash table used to store the gutter to apply to the Unit
 788        * @type Object
 789        */
 790        _gutter: null,
 791        /**
 792        * @property header
 793        * @description A reference to the HTML element used for the Header
 794        * @type HTMLELement
 795        */
 796        header: null,
 797        /**
 798        * @property body
 799        * @description A reference to the HTML element used for the body
 800        * @type HTMLElement
 801        */
 802        body: null,
 803        /**
 804        * @property footer
 805        * @description A reference to the HTML element used for the footer
 806        * @type HTMLElement
 807        */
 808        footer: null,
 809        /**
 810        * @private
 811        * @property _collapsed
 812        * @description Flag to determine if the unit is collapsed or not.
 813        * @type Boolean
 814        */
 815        _collapsed: null,
 816        /**
 817        * @private
 818        * @property _collapsing
 819        * @description A flag set while the unit is being collapsed, used so we don't fire events while animating the size
 820        * @type Boolean
 821        */
 822        _collapsing: null,
 823        /**
 824        * @private
 825        * @property _lastWidth
 826        * @description A holder for the last known width of the unit
 827        * @type Number
 828        */
 829        _lastWidth: null,
 830        /**
 831        * @private
 832        * @property _lastHeight
 833        * @description A holder for the last known height of the unit
 834        * @type Number
 835        */
 836        _lastHeight: null,
 837        /**
 838        * @private
 839        * @property _lastTop
 840        * @description A holder for the last known top of the unit
 841        * @type Number
 842        */
 843        _lastTop: null,
 844        /**
 845        * @private
 846        * @property _lastLeft
 847        * @description A holder for the last known left of the unit
 848        * @type Number
 849        */
 850        _lastLeft: null,
 851        /**
 852        * @private
 853        * @property _lastScroll
 854        * @description A holder for the last known scroll state of the unit
 855        * @type Boolean
 856        */
 857        _lastScroll: null,
 858        /**
 859        * @private
 860        * @property _lastCenetrScroll
 861        * @description A holder for the last known scroll state of the center unit
 862        * @type Boolean
 863        */
 864        _lastCenterScroll: null,
 865        /**
 866        * @private
 867        * @property _lastScrollTop
 868        * @description A holder for the last known scrollTop state of the unit
 869        * @type Number
 870        */
 871        _lastScrollTop: null,
 872        /**
 873        * @method resize
 874        * @description Resize either the unit or it's clipped state, also updating the box inside
 875        * @param {Boolean} force This will force full calculations even when the unit is collapsed
 876        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
 877        */
 878        resize: function(force) {
 879            YAHOO.log('Resize', 'info', 'LayoutUnit');
 880            var retVal = this.fireEvent('beforeResize');
 881            if (retVal === false) {
 882                return this;
 883            }
 884            if (!this._collapsing || (force === true)) {
 885                var scroll = this.get('scroll');
 886                this.set('scroll', false);
 887
 888
 889                var hd = this._getBoxSize(this.header),
 890                    ft = this._getBoxSize(this.footer),
 891                    box = [this.get('height'), this.get('width')];
 892
 893                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
 894                    nw = box[1] - (this._gutter.left + this._gutter.right);
 895
 896                var wrapH = (nh + (hd[0] + ft[0])),
 897                    wrapW = nw;
 898
 899                if (this._collapsed && !this._collapsing) {
 900                    this._setHeight(this._clip, wrapH);
 901                    this._setWidth(this._clip, wrapW);
 902                    Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
 903                    Dom.setStyle(this._clip, 'left', this.get('left') + this._gutter.left + 'px');
 904                } else if (!this._collapsed || (this._collapsed && this._collapsing)) {
 905                    wrapH = this._setHeight(this.get('wrap'), wrapH);
 906                    wrapW = this._setWidth(this.get('wrap'), wrapW);
 907                    this._sizes.wrap.h = wrapH;
 908                    this._sizes.wrap.w = wrapW;
 909
 910                    Dom.setStyle(this.get('wrap'), 'top', this._gutter.top + 'px');
 911                    Dom.setStyle(this.get('wrap'), 'left', this._gutter.left + 'px');
 912
 913                    this._sizes.header.w = this._setWidth(this.header, wrapW);
 914                    this._sizes.header.h = hd[0];
 915
 916                    this._sizes.footer.w = this._setWidth(this.footer, wrapW);
 917                    this._sizes.footer.h = ft[0];
 918
 919                    Dom.setStyle(this.footer, 'bottom', '0px');
 920
 921                    this._sizes.body.h = this._setHeight(this.body, (wrapH - (hd[0] + ft[0])));
 922                    this._sizes.body.w =this._setWidth(this.body, wrapW);
 923                    Dom.setStyle(this.body, 'top', hd[0] + 'px');
 924
 925                    this.set('scroll', scroll);
 926                    this.fireEvent('resize');
 927                }
 928            }
 929            return this;
 930        },
 931        /**
 932        * @private
 933        * @method _setWidth
 934        * @description Sets the width of the element based on the border size of the element.
 935        * @param {HTMLElement} el The HTMLElement to have it's width set
 936        * @param {Number} w The width that you want it the element set to
 937        * @return {Number} The new width, fixed for borders and IE QuirksMode
 938        */
 939        _setWidth: function(el, w) {
 940            if (el) {
 941                var b = this._getBorderSizes(el);
 942                w = (w - (b[1] + b[3]));
 943                w = this._fixQuirks(el, w, 'w');
 944                if (w < 0) {
 945                    w = 0;
 946                }
 947                Dom.setStyle(el, 'width', w + 'px');
 948            }
 949            return w;
 950        },
 951        /**
 952        * @private
 953        * @method _setHeight
 954        * @description Sets the height of the element based on the border size of the element.
 955        * @param {HTMLElement} el The HTMLElement to have it's height set
 956        * @param {Number} h The height that you want it the element set to
 957        * @return {Number} The new height, fixed for borders and IE QuirksMode
 958        */
 959        _setHeight: function(el, h) {
 960            if (el) {
 961                var b = this._getBorderSizes(el);
 962                h = (h - (b[0] + b[2]));
 963                h = this._fixQuirks(el, h, 'h');
 964                if (h < 0) {
 965                    h = 0;
 966                }
 967                Dom.setStyle(el, 'height', h + 'px');
 968            }
 969            return h;
 970        },
 971        /**
 972        * @private
 973        * @method _fixQuirks
 974        * @description Fixes the box calculations for IE in QuirksMode
 975        * @param {HTMLElement} el The HTMLElement to set the dimension on
 976        * @param {Number} dim The number of the dimension to fix
 977        * @param {String} side The dimension (h or w) to fix. Defaults to h
 978        * @return {Number} The fixed dimension
 979        */
 980        _fixQuirks: function(el, dim, side) {
 981            var i1 = 0, i2 = 2;
 982            if (side == 'w') {
 983                i1 = 1;
 984                i2 = 3;
 985            }
 986            if (this.browser.ie && !this.browser.standardsMode) {
 987                //Internet Explorer - Quirks Mode
 988                var b = this._getBorderSizes(el),
 989                    bp = this._getBorderSizes(el.parentNode);
 990                if ((b[i1] === 0) && (b[i2] === 0)) { //No Borders, check parent
 991                    if ((bp[i1] !== 0) && (bp[i2] !== 0)) { //Parent has Borders
 992                        dim = (dim - (bp[i1] + bp[i2]));
 993                    }
 994                } else {
 995                    if ((bp[i1] === 0) && (bp[i2] === 0)) {
 996                        dim = (dim + (b[i1] + b[i2]));
 997                    }
 998                }
 999            }
1000            return dim;
1001        },
1002        /**
1003        * @private
1004        * @method _getBoxSize
1005        * @description Get's the elements clientHeight and clientWidth plus the size of the borders
1006        * @param {HTMLElement} el The HTMLElement to get the size of
1007        * @return {Array} An array of height and width
1008        */
1009        _getBoxSize: function(el) {
1010            var size = [0, 0];
1011            if (el) {
1012                if (this.browser.ie && !this.browser.standardsMode) {
1013                    el.style.zoom = 1;
1014                }
1015                var b = this._getBorderSizes(el);
1016                size[0] = el.clientHeight + (b[0] + b[2]);
1017                size[1] = el.clientWidth + (b[1] + b[3]);
1018            }
1019            return size;
1020        },
1021        /**
1022        * @private
1023        * @method _getBorderSizes
1024        * @description Get the CSS border size of the element passed.
1025        * @param {HTMLElement} el The element to get the border size of
1026        * @return {Array} An array of the top, right, bottom, left borders.
1027        */
1028        _getBorderSizes: function(el) {
1029            var s = [];
1030            el = el || this.get('element');
1031            if (this.browser.ie && !this.browser.standardsMode) {
1032                el.style.zoom = 1;
1033            }
1034            s[0] = parseInt(Dom.getStyle(el, 'borderTopWidth'), 10);
1035            s[1] = parseInt(Dom.getStyle(el, 'borderRightWidth'), 10);
1036            s[2] = parseInt(Dom.getStyle(el, 'borderBottomWidth'), 10);
1037            s[3] = parseInt(Dom.getStyle(el, 'borderLeftWidth'), 10);
1038            
1039            //IE will return NaN on these if they are set to auto, we'll set them to 0
1040            for (var i = 0; i < s.length; i++) {
1041                if (isNaN(s[i])) {
1042                    s[i] = 0;
1043                }
1044            }
1045            return s;
1046        },
1047        /**
1048        * @private
1049        * @method _createClip
1050        * @description Create the clip element used when the Unit is collapsed
1051        */
1052        _createClip: function() {
1053            if (!this._clip) {
1054                this._clip = document.createElement('div');
1055                this._clip.className = 'yui-layout-clip yui-layout-clip-' + this.get('position');
1056                this._clip.innerHTML = '<div class="collapse"></div>';
1057                var c = this._clip.firstChild;
1058                c.title = this.STR_EXPAND;
1059                Event.on(c, 'click', this.expand, this, true);
1060                this.get('element').parentNode.appendChild(this._clip);
1061            }
1062        },
1063        /**
1064        * @private
1065        * @method _toggleClip
1066        * @description Toggle th current state of the Clip element and set it's height, width and position
1067        */
1068        _toggleClip: function() {
1069            if (!this._collapsed) {
1070                //show
1071                var hd = this._getBoxSize(this.header),
1072                    ft = this._getBoxSize(this.footer),
1073                    box = [this.get('height'), this.get('width')];
1074
1075
1076                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
1077                    nw = box[1] - (this._gutter.left + this._gutter.right),
1078                    wrapH = (nh + (hd[0] + ft[0]));
1079
1080                switch (this.get('position')) {
1081                    case 'top':
1082                    case 'bottom':
1083                        this._setWidth(this._clip, nw);
1084                        this._setHeight(this._clip, this.get('collapseSize'));
1085                        Dom.setStyle(this._clip, 'left', (this._lastLeft + this._gutter.left) + 'px');
1086                        if (this.get('position') == 'bottom') {
1087                            Dom.setStyle(this._clip, 'top', ((this._lastTop + this._lastHeight) - (this.get('collapseSize') - this._gutter.top)) + 'px');
1088                        } else {
1089                            Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
1090                        }
1091                        break;
1092                    case 'left':
1093                    case 'right':
1094                        this._setWidth(this._clip, this.get('collapseSize'));
1095                        this._setHeight(this._clip, wrapH);
1096                        Dom.setStyle(this._clip, 'top', (this.get('top') + this._gutter.top) + 'px');
1097                        if (this.get('position') == 'right') {
1098                            Dom.setStyle(this._clip, 'left', (((this._lastLeft + this._lastWidth) - this.get('collapseSize')) - this._gutter.left) + 'px');
1099                        } else {
1100                            Dom.setStyle(this._clip, 'left', (this.get('left') + this._gutter.left) + 'px');
1101                        }
1102                        break;
1103                }
1104
1105                Dom.setStyle(this._clip, 'display', 'block');
1106                this.setStyle('display', 'none');
1107            } else {
1108                //Hide
1109                Dom.setStyle(this._clip, 'display', 'none');
1110            }
1111        },
1112        /**
1113        * @method getSizes
1114        * @description Get a reference to the internal sizes object for this unit
1115        * @return {Object} An object of the sizes used for calculations
1116        */
1117        getSizes: function() {
1118            return this._sizes;
1119        },
1120        /**
1121        * @method toggle
1122        * @description Toggles the Unit, replacing it with a clipped version.
1123        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1124        */
1125        toggle: function() {
1126            if (this._collapsed) {
1127                this.expand();
1128            } else {
1129                this.collapse();
1130            }
1131            return this;
1132        },
1133        /**
1134        * @method expand
1135        * @description Expand the Unit if it is collapsed.
1136        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1137        */
1138        expand: function() {
1139            if (!this._collapsed) {
1140                return this;
1141            }
1142            var retVal = this.fireEvent('beforeExpand');
1143            if (retVal === false) {
1144                return this;
1145            }
1146
1147            this._collapsing = true;
1148            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1149
1150            if (this._anim) {
1151                this.setStyle('display', 'none');
1152                var attr = {}, s;
1153
1154                switch (this.get('position')) {
1155                    case 'left':
1156                    case 'right':
1157                        this.set('width', this._lastWidth, true);
1158                        this.setStyle('width', this._lastWidth + 'px');
1159                        this.get('parent').resize(false);
1160                        s = this.get('parent').getSizes()[this.get('position')];
1161                        this.set('height', s.h, true);
1162                        var left = s.l;
1163                        attr = {
1164                            left: {
1165                                to: left
1166                            }
1167                        };
1168                        if (this.get('position') == 'left') {
1169                            attr.left.from = (left - s.w);
1170                            this.setStyle('left', (left - s.w) + 'px');
1171                        }
1172                        break;
1173                    case 'top':
1174                    case 'bottom':
1175                        this.set('height', this._lastHeight, true);
1176                        this.setStyle('height', this._lastHeight + 'px');
1177                        this.get('parent').resize(false);
1178                        s = this.get('parent').getSizes()[this.get('position')];
1179                        this.set('width', s.w, true);
1180                        var top = s.t;
1181                        attr = {
1182                            top: {
1183                                to: top
1184                            }
1185                        };
1186                        if (this.get('position') == 'top') {
1187                            this.setStyle('top',  (top - s.h) + 'px');
1188                            attr.top.from = (top - s.h);
1189                        }
1190                        break;
1191                }
1192
1193                this._anim.attributes = attr;
1194                var exStart = function() {
1195                    this.setStyle('display', 'block');
1196                    this.resize(true);
1197                    this._anim.onStart.unsubscribe(exStart, this, true);
1198                };
1199                var expand = function() {
1200                    this._collapsing = false;
1201                    this.setStyle('zIndex', this.get('parent')._zIndex);
1202                    this.set('width', this._lastWidth);
1203                    this.set('height', this._lastHeight);
1204                    this._collapsed = false;
1205                    this.resize();
1206                    this.set('scroll', this._lastScroll);
1207                    if (this._lastScrollTop > 0) {
1208                        this.body.scrollTop = this._lastScrollTop;
1209                    }
1210                    this._anim.onComplete.unsubscribe(expand, this, true);
1211                    this.fireEvent('expand');
1212                };
1213                this._anim.onStart.subscribe(exStart, this, true);
1214                this._anim.onComplete.subscribe(expand, this, true);
1215                this._anim.animate();
1216                this._toggleClip();
1217            } else {
1218                this._collapsing = false;
1219                this._toggleClip();
1220                this._collapsed = false;
1221                this.setStyle('zIndex', this.get('parent')._zIndex);
1222                this.setStyle('display', 'block');
1223                this.set('width', this._lastWidth);
1224                this.set('height', this._lastHeight);
1225                this.resize();
1226                this.set('scroll', this._lastScroll);
1227                if (this._lastScrollTop > 0) {
1228                    this.body.scrollTop = this._lastScrollTop;
1229                }
1230                this.fireEvent('expand');
1231            }
1232            return this;
1233        },
1234        /**
1235        * @method collapse
1236        * @description Collapse the Unit if it is not collapsed.
1237        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1238        */
1239        collapse: function() {
1240            if (this._collapsed) {
1241                return this;
1242            }
1243            var retValue = this.fireEvent('beforeCollapse');
1244            if (retValue === false) {
1245                return this;
1246            }
1247            if (!this._clip) {
1248                this._createClip();
1249            }
1250            this._collapsing = true;
1251            var w = this.get('width'),
1252                h = this.get('height'),
1253                attr = {};
1254            this._lastWidth = w;
1255            this._lastHeight = h;
1256            this._lastScroll = this.get('scroll');
1257            this._lastScrollTop = this.body.scrollTop;            
1258            this.set('scroll', false, true);
1259            this._lastLeft = parseInt(this.get('element').style.left, 10);
1260            this._lastTop = parseInt(this.get('element').style.top, 10);
1261            if (isNaN(this._lastTop)) {
1262                this._lastTop = 0;
1263                this.set('top', 0);
1264            }
1265            if (isNaN(this._lastLeft)) {
1266                this._lastLeft = 0;
1267                this.set('left', 0);
1268            }
1269            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1270            var pos = this.get('position');
1271
1272            switch (pos) {
1273                case 'top':
1274                case 'bottom':
1275                    this.set('height', (this.get('collapseSize') + (this._gutter.top + this._gutter.bottom)));
1276                    attr = {
1277                        top: {
1278                            to: (this.get('top') - h)
1279                        }
1280                    };
1281                    if (pos == 'bottom') {
1282                        attr.top.to = (this.get('top') + h);
1283                    }
1284                    break;
1285                case 'left':
1286                case 'right':
1287                    this.set('width', (this.get('collapseSize') + (this._gutter.left + this._gutter.right)));
1288                    attr = {
1289                        left: {
1290                            to: -(this._lastWidth)
1291                        }
1292                    };
1293                    if (pos == 'right') {
1294                        attr.left = {
1295                            to: (this.get('left') + w)
1296                        };
1297                    }
1298                    break;
1299            }
1300            if (this._anim) {
1301                this._anim.attributes = attr;
1302                var collapse = function() {
1303                    this._collapsing = false;
1304                    this._toggleClip();
1305                    this.setStyle('zIndex', this.get('parent')._zIndex);
1306                    this._collapsed = true;
1307                    this.get('parent').resize();
1308                    this._anim.onComplete.unsubscribe(collapse, this, true);
1309                    this.fireEvent('collapse');
1310                };
1311                this._anim.onComplete.subscribe(collapse, this, true);
1312                this._anim.animate();
1313            } else {
1314                this._collapsing = false;
1315                this.setStyle('display', 'none');
1316                this._toggleClip();
1317                this.setStyle('zIndex', this.get('parent')._zIndex);
1318                this.get('parent').resize();
1319                this._collapsed = true;
1320                this.fireEvent('collapse');
1321            }
1322            return this;
1323        },
1324        /**
1325        * @method close
1326        * @description Close the unit, removing it from the parent Layout.
1327        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
1328        */
1329        close: function() {
1330            this.setStyle('display', 'none');
1331            this.get('parent').removeUnit(this);
1332            this.fireEvent('close');
1333            if (this._clip) {
1334                this._clip.parentNode.removeChild(this._clip);
1335                this._clip = null;
1336            }
1337            return this.get('parent');
1338        },
1339		/**
1340        * @property loadHandler
1341        * @description Callback method for the YUI Connection Manager used for load the body using AJAX
1342        * @type Object
1343        */
1344		loadHandler: {
1345            success: function(o) {
1346				this.body.innerHTML = o.responseText;
1347				this.resize (true);
1348            },
1349            failure: function(o) {
1350            }
1351        },
1352		/**
1353        * @property dataConnection
1354        * @description YUI Connection Manager handler
1355        * @type Object
1356        */
1357		dataConnection: null,
1358		/**
1359        * @private
1360        * @property _loading
1361     

Large files files are truncated, but you can click here to view the full file