[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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', ' '); 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', ' '); 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"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |