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