layout-debug.js 86 KB

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