Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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