Dashboard sipadu mbip
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

widget-stdmod-debug.js 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /*
  2. Copyright (c) 2010, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 3.4.0
  6. build: nightly
  7. */
  8. YUI.add('widget-stdmod', function(Y) {
  9. /**
  10. * Provides standard module support for Widgets through an extension.
  11. *
  12. * @module widget-stdmod
  13. */
  14. var L = Y.Lang,
  15. Node = Y.Node,
  16. UA = Y.UA,
  17. Widget = Y.Widget,
  18. EMPTY = "",
  19. HD = "hd",
  20. BD = "bd",
  21. FT = "ft",
  22. HEADER = "header",
  23. BODY = "body",
  24. FOOTER = "footer",
  25. FILL_HEIGHT = "fillHeight",
  26. STDMOD = "stdmod",
  27. NODE_SUFFIX = "Node",
  28. CONTENT_SUFFIX = "Content",
  29. FIRST_CHILD = "firstChild",
  30. CHILD_NODES = "childNodes",
  31. OWNER_DOCUMENT = "ownerDocument",
  32. CONTENT_BOX = "contentBox",
  33. HEIGHT = "height",
  34. OFFSET_HEIGHT = "offsetHeight",
  35. AUTO = "auto",
  36. HeaderChange = "headerContentChange",
  37. BodyChange = "bodyContentChange",
  38. FooterChange = "footerContentChange",
  39. FillHeightChange = "fillHeightChange",
  40. HeightChange = "heightChange",
  41. ContentUpdate = "contentUpdate",
  42. RENDERUI = "renderUI",
  43. BINDUI = "bindUI",
  44. SYNCUI = "syncUI",
  45. APPLY_PARSED_CONFIG = "_applyParsedConfig",
  46. UI = Y.Widget.UI_SRC;
  47. /**
  48. * Widget extension, which can be used to add Standard Module support to the
  49. * base Widget class, through the <a href="Base.html#method_build">Base.build</a>
  50. * method.
  51. * <p>
  52. * The extension adds header, body and footer sections to the Widget's content box and
  53. * provides the corresponding methods and attributes to modify the contents of these sections.
  54. * </p>
  55. * @class WidgetStdMod
  56. * @param {Object} The user configuration object
  57. */
  58. function StdMod(config) {
  59. this._stdModNode = this.get(CONTENT_BOX);
  60. Y.before(this._renderUIStdMod, this, RENDERUI);
  61. Y.before(this._bindUIStdMod, this, BINDUI);
  62. Y.before(this._syncUIStdMod, this, SYNCUI);
  63. }
  64. /**
  65. * Constant used to refer the the standard module header, in methods which expect a section specifier
  66. *
  67. * @property HEADER
  68. * @static
  69. * @type String
  70. */
  71. StdMod.HEADER = HEADER;
  72. /**
  73. * Constant used to refer the the standard module body, in methods which expect a section specifier
  74. *
  75. * @property BODY
  76. * @static
  77. * @type String
  78. */
  79. StdMod.BODY = BODY;
  80. /**
  81. * Constant used to refer the the standard module footer, in methods which expect a section specifier
  82. *
  83. * @property FOOTER
  84. * @static
  85. * @type String
  86. */
  87. StdMod.FOOTER = FOOTER;
  88. /**
  89. * Constant used to specify insertion position, when adding content to sections of the standard module in
  90. * methods which expect a "where" argument.
  91. * <p>
  92. * Inserts new content <em>before</em> the sections existing content.
  93. * </p>
  94. * @property AFTER
  95. * @static
  96. * @type String
  97. */
  98. StdMod.AFTER = "after";
  99. /**
  100. * Constant used to specify insertion position, when adding content to sections of the standard module in
  101. * methods which expect a "where" argument.
  102. * <p>
  103. * Inserts new content <em>before</em> the sections existing content.
  104. * </p>
  105. * @property BEFORE
  106. * @static
  107. * @type String
  108. */
  109. StdMod.BEFORE = "before";
  110. /**
  111. * Constant used to specify insertion position, when adding content to sections of the standard module in
  112. * methods which expect a "where" argument.
  113. * <p>
  114. * <em>Replaces</em> the sections existing content, with new content.
  115. * </p>
  116. * @property REPLACE
  117. * @static
  118. * @type String
  119. */
  120. StdMod.REPLACE = "replace";
  121. var STD_HEADER = StdMod.HEADER,
  122. STD_BODY = StdMod.BODY,
  123. STD_FOOTER = StdMod.FOOTER,
  124. HEADER_CONTENT = STD_HEADER + CONTENT_SUFFIX,
  125. FOOTER_CONTENT = STD_FOOTER + CONTENT_SUFFIX,
  126. BODY_CONTENT = STD_BODY + CONTENT_SUFFIX;
  127. /**
  128. * Static property used to define the default attribute
  129. * configuration introduced by WidgetStdMod.
  130. *
  131. * @property ATTRS
  132. * @type Object
  133. * @static
  134. */
  135. StdMod.ATTRS = {
  136. /**
  137. * @attribute headerContent
  138. * @type {String | Node}
  139. * @default undefined
  140. * @description The content to be added to the header section. This will replace any existing content
  141. * in the header. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method.
  142. */
  143. headerContent: {
  144. value:null
  145. },
  146. /**
  147. * @attribute footerContent
  148. * @type {String | Node}
  149. * @default undefined
  150. * @description The content to be added to the footer section. This will replace any existing content
  151. * in the footer. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method.
  152. */
  153. footerContent: {
  154. value:null
  155. },
  156. /**
  157. * @attribute bodyContent
  158. * @type {String | Node}
  159. * @default undefined
  160. * @description The content to be added to the body section. This will replace any existing content
  161. * in the body. If you want to append, or insert new content, use the <a href="#method_setStdModContent">setStdModContent</a> method.
  162. */
  163. bodyContent: {
  164. value:null
  165. },
  166. /**
  167. * @attribute fillHeight
  168. * @type {String}
  169. * @default WidgetStdMod.BODY
  170. * @description The section (WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER) which should be resized to fill the height of the standard module, when a
  171. * height is set on the Widget. If a height is not set on the widget, then all sections are sized based on
  172. * their content.
  173. */
  174. fillHeight: {
  175. value: StdMod.BODY,
  176. validator: function(val) {
  177. return this._validateFillHeight(val);
  178. }
  179. }
  180. };
  181. /**
  182. * The HTML parsing rules for the WidgetStdMod class.
  183. *
  184. * @property HTML_PARSER
  185. * @static
  186. * @type Object
  187. */
  188. StdMod.HTML_PARSER = {
  189. headerContent: function(contentBox) {
  190. return this._parseStdModHTML(STD_HEADER);
  191. },
  192. bodyContent: function(contentBox) {
  193. return this._parseStdModHTML(STD_BODY);
  194. },
  195. footerContent : function(contentBox) {
  196. return this._parseStdModHTML(STD_FOOTER);
  197. }
  198. };
  199. /**
  200. * Static hash of default class names used for the header,
  201. * body and footer sections of the standard module, keyed by
  202. * the section identifier (WidgetStdMod.STD_HEADER, WidgetStdMod.STD_BODY, WidgetStdMod.STD_FOOTER)
  203. *
  204. * @property SECTION_CLASS_NAMES
  205. * @static
  206. * @type Object
  207. */
  208. StdMod.SECTION_CLASS_NAMES = {
  209. header: Widget.getClassName(HD),
  210. body: Widget.getClassName(BD),
  211. footer: Widget.getClassName(FT)
  212. };
  213. /**
  214. * The template HTML strings for each of the standard module sections. Section entries are keyed by the section constants,
  215. * WidgetStdMod.HEADER, WidgetStdMod.BODY, WidgetStdMod.FOOTER, and contain the HTML to be added for each section.
  216. * e.g.
  217. * <pre>
  218. * {
  219. * header : '&lt;div class="yui-widget-hd"&gt;&lt;/div&gt;',
  220. * body : '&lt;div class="yui-widget-bd"&gt;&lt;/div&gt;',
  221. * footer : '&lt;div class="yui-widget-ft"&gt;&lt;/div&gt;'
  222. * }
  223. * </pre>
  224. * @property TEMPLATES
  225. * @type Object
  226. * @static
  227. */
  228. StdMod.TEMPLATES = {
  229. header : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_HEADER] + '"></div>',
  230. body : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_BODY] + '"></div>',
  231. footer : '<div class="' + StdMod.SECTION_CLASS_NAMES[STD_FOOTER] + '"></div>'
  232. };
  233. StdMod.prototype = {
  234. /**
  235. * Synchronizes the UI to match the Widgets standard module state.
  236. * <p>
  237. * This method is invoked after syncUI is invoked for the Widget class
  238. * using YUI's aop infrastructure.
  239. * </p>
  240. * @method _syncUIStdMod
  241. * @protected
  242. */
  243. _syncUIStdMod : function() {
  244. var stdModParsed = this._stdModParsed;
  245. if (!stdModParsed || !stdModParsed[HEADER_CONTENT]) {
  246. this._uiSetStdMod(STD_HEADER, this.get(HEADER_CONTENT));
  247. }
  248. if (!stdModParsed || !stdModParsed[BODY_CONTENT]) {
  249. this._uiSetStdMod(STD_BODY, this.get(BODY_CONTENT));
  250. }
  251. if (!stdModParsed || !stdModParsed[FOOTER_CONTENT]) {
  252. this._uiSetStdMod(STD_FOOTER, this.get(FOOTER_CONTENT));
  253. }
  254. this._uiSetFillHeight(this.get(FILL_HEIGHT));
  255. },
  256. /**
  257. * Creates/Initializes the DOM for standard module support.
  258. * <p>
  259. * This method is invoked after renderUI is invoked for the Widget class
  260. * using YUI's aop infrastructure.
  261. * </p>
  262. * @method _renderUIStdMod
  263. * @protected
  264. */
  265. _renderUIStdMod : function() {
  266. this._stdModNode.addClass(Widget.getClassName(STDMOD));
  267. this._renderStdModSections();
  268. //This normally goes in bindUI but in order to allow setStdModContent() to work before renderUI
  269. //stage, these listeners should be set up at the earliest possible time.
  270. this.after(HeaderChange, this._afterHeaderChange);
  271. this.after(BodyChange, this._afterBodyChange);
  272. this.after(FooterChange, this._afterFooterChange);
  273. },
  274. _renderStdModSections : function() {
  275. if (L.isValue(this.get(HEADER_CONTENT))) { this._renderStdMod(STD_HEADER); }
  276. if (L.isValue(this.get(BODY_CONTENT))) { this._renderStdMod(STD_BODY); }
  277. if (L.isValue(this.get(FOOTER_CONTENT))) { this._renderStdMod(STD_FOOTER); }
  278. },
  279. /**
  280. * Binds event listeners responsible for updating the UI state in response to
  281. * Widget standard module related state changes.
  282. * <p>
  283. * This method is invoked after bindUI is invoked for the Widget class
  284. * using YUI's aop infrastructure.
  285. * </p>
  286. * @method _bindUIStdMod
  287. * @protected
  288. */
  289. _bindUIStdMod : function() {
  290. // this.after(HeaderChange, this._afterHeaderChange);
  291. // this.after(BodyChange, this._afterBodyChange);
  292. // this.after(FooterChange, this._afterFooterChange);
  293. this.after(FillHeightChange, this._afterFillHeightChange);
  294. this.after(HeightChange, this._fillHeight);
  295. this.after(ContentUpdate, this._fillHeight);
  296. },
  297. /**
  298. * Default attribute change listener for the headerContent attribute, responsible
  299. * for updating the UI, in response to attribute changes.
  300. *
  301. * @method _afterHeaderChange
  302. * @protected
  303. * @param {EventFacade} e The event facade for the attribute change
  304. */
  305. _afterHeaderChange : function(e) {
  306. if (e.src !== UI) {
  307. this._uiSetStdMod(STD_HEADER, e.newVal, e.stdModPosition);
  308. }
  309. },
  310. /**
  311. * Default attribute change listener for the bodyContent attribute, responsible
  312. * for updating the UI, in response to attribute changes.
  313. *
  314. * @method _afterBodyChange
  315. * @protected
  316. * @param {EventFacade} e The event facade for the attribute change
  317. */
  318. _afterBodyChange : function(e) {
  319. if (e.src !== UI) {
  320. this._uiSetStdMod(STD_BODY, e.newVal, e.stdModPosition);
  321. }
  322. },
  323. /**
  324. * Default attribute change listener for the footerContent attribute, responsible
  325. * for updating the UI, in response to attribute changes.
  326. *
  327. * @method _afterFooterChange
  328. * @protected
  329. * @param {EventFacade} e The event facade for the attribute change
  330. */
  331. _afterFooterChange : function(e) {
  332. if (e.src !== UI) {
  333. this._uiSetStdMod(STD_FOOTER, e.newVal, e.stdModPosition);
  334. }
  335. },
  336. /**
  337. * Default attribute change listener for the fillHeight attribute, responsible
  338. * for updating the UI, in response to attribute changes.
  339. *
  340. * @method _afterFillHeightChange
  341. * @protected
  342. * @param {EventFacade} e The event facade for the attribute change
  343. */
  344. _afterFillHeightChange: function (e) {
  345. this._uiSetFillHeight(e.newVal);
  346. },
  347. /**
  348. * Default validator for the fillHeight attribute. Verifies that the
  349. * value set is a valid section specifier - one of WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER,
  350. * or a falsey value if fillHeight is to be disabled.
  351. *
  352. * @method _validateFillHeight
  353. * @protected
  354. * @param {String} val The section which should be setup to fill height, or false/null to disable fillHeight
  355. * @return true if valid, false if not
  356. */
  357. _validateFillHeight : function(val) {
  358. return !val || val == StdMod.BODY || val == StdMod.HEADER || val == StdMod.FOOTER;
  359. },
  360. /**
  361. * Updates the rendered UI, to resize the provided section so that the standard module fills out
  362. * the specified widget height. Note: This method does not check whether or not a height is set
  363. * on the Widget.
  364. *
  365. * @method _uiSetFillHeight
  366. * @protected
  367. * @param {String} fillSection A valid section specifier - one of WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER
  368. */
  369. _uiSetFillHeight : function(fillSection) {
  370. var fillNode = this.getStdModNode(fillSection);
  371. var currNode = this._currFillNode;
  372. if (currNode && fillNode !== currNode){
  373. currNode.setStyle(HEIGHT, EMPTY);
  374. }
  375. if (fillNode) {
  376. this._currFillNode = fillNode;
  377. }
  378. this._fillHeight();
  379. },
  380. /**
  381. * Updates the rendered UI, to resize the current section specified by the fillHeight attribute, so
  382. * that the standard module fills out the Widget height. If a height has not been set on Widget,
  383. * the section is not resized (height is set to "auto").
  384. *
  385. * @method _fillHeight
  386. * @private
  387. */
  388. _fillHeight : function() {
  389. if (this.get(FILL_HEIGHT)) {
  390. var height = this.get(HEIGHT);
  391. if (height != EMPTY && height != AUTO) {
  392. this.fillHeight(this._currFillNode);
  393. }
  394. }
  395. },
  396. /**
  397. * Updates the rendered UI, adding the provided content (either an HTML string, or node reference),
  398. * to the specified section. The content is either added before, after or replaces existing content
  399. * in the section, based on the value of the <code>where</code> argument.
  400. *
  401. * @method _uiSetStdMod
  402. * @protected
  403. *
  404. * @param {String} section The section to be updated. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  405. * @param {String | Node} content The new content (either as an HTML string, or Node reference) to add to the section
  406. * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE.
  407. * If not provided, the content will replace existing content in the section.
  408. */
  409. _uiSetStdMod : function(section, content, where) {
  410. // Using isValue, so that "" is valid content
  411. if (L.isValue(content)) {
  412. var node = this.getStdModNode(section) || this._renderStdMod(section);
  413. this._addStdModContent(node, content, where);
  414. this.set(section + CONTENT_SUFFIX, this._getStdModContent(section), {src:UI});
  415. } else {
  416. this._eraseStdMod(section);
  417. }
  418. this.fire(ContentUpdate);
  419. },
  420. /**
  421. * Creates the DOM node for the given section, and inserts it into the correct location in the contentBox.
  422. *
  423. * @method _renderStdMod
  424. * @protected
  425. * @param {String} section The section to create/render. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  426. * @return {Node} A reference to the added section node
  427. */
  428. _renderStdMod : function(section) {
  429. var contentBox = this.get(CONTENT_BOX),
  430. sectionNode = this._findStdModSection(section);
  431. if (!sectionNode) {
  432. sectionNode = this._getStdModTemplate(section);
  433. }
  434. this._insertStdModSection(contentBox, section, sectionNode);
  435. this[section + NODE_SUFFIX] = sectionNode;
  436. return this[section + NODE_SUFFIX];
  437. },
  438. /**
  439. * Removes the DOM node for the given section.
  440. *
  441. * @method _eraseStdMod
  442. * @protected
  443. * @param {String} section The section to remove. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  444. */
  445. _eraseStdMod : function(section) {
  446. var sectionNode = this.getStdModNode(section);
  447. if (sectionNode) {
  448. sectionNode.remove(true);
  449. delete this[section + NODE_SUFFIX];
  450. }
  451. },
  452. /**
  453. * Helper method to insert the Node for the given section into the correct location in the contentBox.
  454. *
  455. * @method _insertStdModSection
  456. * @private
  457. * @param {Node} contentBox A reference to the Widgets content box.
  458. * @param {String} section The section to create/render. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  459. * @param {Node} sectionNode The Node for the section.
  460. */
  461. _insertStdModSection : function(contentBox, section, sectionNode) {
  462. var fc = contentBox.get(FIRST_CHILD);
  463. if (section === STD_FOOTER || !fc) {
  464. contentBox.appendChild(sectionNode);
  465. } else {
  466. if (section === STD_HEADER) {
  467. contentBox.insertBefore(sectionNode, fc);
  468. } else {
  469. var footer = this[STD_FOOTER + NODE_SUFFIX];
  470. if (footer) {
  471. contentBox.insertBefore(sectionNode, footer);
  472. } else {
  473. contentBox.appendChild(sectionNode);
  474. }
  475. }
  476. }
  477. },
  478. /**
  479. * Gets a new Node reference for the given standard module section, by cloning
  480. * the stored template node.
  481. *
  482. * @method _getStdModTemplate
  483. * @protected
  484. * @param {String} section The section to create a new node for. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  485. * @return {Node} The new Node instance for the section
  486. */
  487. _getStdModTemplate : function(section) {
  488. return Node.create(StdMod.TEMPLATES[section], this._stdModNode.get(OWNER_DOCUMENT));
  489. },
  490. /**
  491. * Helper method to add content to a StdMod section node.
  492. * The content is added either before, after or replaces the existing node content
  493. * based on the value of the <code>where</code> argument.
  494. *
  495. * @method _addStdModContent
  496. * @private
  497. *
  498. * @param {Node} node The section Node to be updated.
  499. * @param {Node|NodeList|String} children The new content Node, NodeList or String to be added to section Node provided.
  500. * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE.
  501. * If not provided, the content will replace existing content in the Node.
  502. */
  503. _addStdModContent : function(node, children, where) {
  504. // StdMod where to Node where
  505. switch (where) {
  506. case StdMod.BEFORE: // 0 is before fistChild
  507. where = 0;
  508. break;
  509. case StdMod.AFTER: // undefined is appendChild
  510. where = undefined;
  511. break;
  512. default: // replace is replace, not specified is replace
  513. where = StdMod.REPLACE;
  514. }
  515. node.insert(children, where);
  516. },
  517. /**
  518. * Helper method to obtain the precise height of the node provided, including padding and border.
  519. * The height could be a sub-pixel value for certain browsers, such as Firefox 3.
  520. *
  521. * @method _getPreciseHeight
  522. * @private
  523. * @param {Node} node The node for which the precise height is required.
  524. * @return {Number} The height of the Node including borders and padding, possibly a float.
  525. */
  526. _getPreciseHeight : function(node) {
  527. var height = (node) ? node.get(OFFSET_HEIGHT) : 0,
  528. getBCR = "getBoundingClientRect";
  529. if (node && node.hasMethod(getBCR)) {
  530. var preciseRegion = node.invoke(getBCR);
  531. if (preciseRegion) {
  532. height = preciseRegion.bottom - preciseRegion.top;
  533. }
  534. }
  535. return height;
  536. },
  537. /**
  538. * Helper method to to find the rendered node for the given section,
  539. * if it exists.
  540. *
  541. * @method _findStdModSection
  542. * @private
  543. * @param {String} section The section for which the render Node is to be found. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  544. * @return {Node} The rendered node for the given section, or null if not found.
  545. */
  546. _findStdModSection: function(section) {
  547. return this.get(CONTENT_BOX).one("> ." + StdMod.SECTION_CLASS_NAMES[section]);
  548. },
  549. /**
  550. * Utility method, used by WidgetStdMods HTML_PARSER implementation
  551. * to extract data for each section from markup.
  552. *
  553. * @method _parseStdModHTML
  554. * @private
  555. * @param {String} section
  556. * @return {String} Inner HTML string with the contents of the section
  557. */
  558. _parseStdModHTML : function(section) {
  559. var node = this._findStdModSection(section);
  560. if (node) {
  561. if (!this._stdModParsed) {
  562. this._stdModParsed = {};
  563. Y.before(this._applyStdModParsedConfig, this, APPLY_PARSED_CONFIG);
  564. }
  565. this._stdModParsed[section + CONTENT_SUFFIX] = 1;
  566. return node.get("innerHTML");
  567. }
  568. return null;
  569. },
  570. /**
  571. * This method is injected before the _applyParsedConfig step in
  572. * the application of HTML_PARSER, and sets up the state to
  573. * identify whether or not we should remove the current DOM content
  574. * or not, based on whether or not the current content attribute value
  575. * was extracted from the DOM, or provided by the user configuration
  576. *
  577. * @method _applyStdModParsedConfig
  578. * @private
  579. */
  580. _applyStdModParsedConfig : function(node, cfg, parsedCfg) {
  581. var parsed = this._stdModParsed;
  582. if (parsed) {
  583. parsed[HEADER_CONTENT] = !(HEADER_CONTENT in cfg) && (HEADER_CONTENT in parsed);
  584. parsed[BODY_CONTENT] = !(BODY_CONTENT in cfg) && (BODY_CONTENT in parsed);
  585. parsed[FOOTER_CONTENT] = !(FOOTER_CONTENT in cfg) && (FOOTER_CONTENT in parsed);
  586. }
  587. },
  588. /**
  589. * Retrieves the child nodes (content) of a standard module section
  590. *
  591. * @method _getStdModContent
  592. * @private
  593. * @param {String} section The standard module section whose child nodes are to be retrieved. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  594. * @return {Node} The child node collection of the standard module section.
  595. */
  596. _getStdModContent : function(section) {
  597. return (this[section + NODE_SUFFIX]) ? this[section + NODE_SUFFIX].get(CHILD_NODES) : null;
  598. },
  599. /**
  600. * Updates the body section of the standard module with the content provided (either an HTML string, or node reference).
  601. * <p>
  602. * This method can be used instead of the corresponding section content attribute if you'd like to retain the current content of the section,
  603. * and insert content before or after it, by specifying the <code>where</code> argument.
  604. * </p>
  605. * @method setStdModContent
  606. * @param {String} section The standard module section whose content is to be updated. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  607. * @param {String | Node} content The content to be added, either an HTML string or a Node reference.
  608. * @param {String} where Optional. Either WidgetStdMod.AFTER, WidgetStdMod.BEFORE or WidgetStdMod.REPLACE.
  609. * If not provided, the content will replace existing content in the section.
  610. */
  611. setStdModContent : function(section, content, where) {
  612. //var node = this.getStdModNode(section) || this._renderStdMod(section);
  613. this.set(section + CONTENT_SUFFIX, content, {stdModPosition:where});
  614. //this._addStdModContent(node, content, where);
  615. },
  616. /**
  617. * Returns the node reference for the given section. Note: The DOM is not queried for the node reference. The reference
  618. * stored by the widget instance is returned if set.
  619. *
  620. * @method getStdModNode
  621. * @param {String} section The section whose node reference is required. Either WidgetStdMod.HEADER, WidgetStdMod.BODY or WidgetStdMod.FOOTER.
  622. * @return {Node} The node reference for the section, or null if not set.
  623. */
  624. getStdModNode : function(section) {
  625. return this[section + NODE_SUFFIX] || null;
  626. },
  627. /**
  628. * Sets the height on the provided header, body or footer element to
  629. * fill out the height of the Widget. It determines the height of the
  630. * widgets bounding box, based on it's configured height value, and
  631. * sets the height of the provided section to fill out any
  632. * space remaining after the other standard module section heights
  633. * have been accounted for.
  634. *
  635. * <p><strong>NOTE:</strong> This method is not designed to work if an explicit
  636. * height has not been set on the Widget, since for an "auto" height Widget,
  637. * the heights of the header/body/footer will drive the height of the Widget.</p>
  638. *
  639. * @method fillHeight
  640. * @param {Node} node The node which should be resized to fill out the height
  641. * of the Widget bounding box. Should be a standard module section node which belongs
  642. * to the widget.
  643. */
  644. fillHeight : function(node) {
  645. if (node) {
  646. var contentBox = this.get(CONTENT_BOX),
  647. stdModNodes = [this.headerNode, this.bodyNode, this.footerNode],
  648. stdModNode,
  649. cbContentHeight,
  650. filled = 0,
  651. remaining = 0,
  652. validNode = false;
  653. for (var i = 0, l = stdModNodes.length; i < l; i++) {
  654. stdModNode = stdModNodes[i];
  655. if (stdModNode) {
  656. if (stdModNode !== node) {
  657. filled += this._getPreciseHeight(stdModNode);
  658. } else {
  659. validNode = true;
  660. }
  661. }
  662. }
  663. if (validNode) {
  664. if (UA.ie || UA.opera) {
  665. // Need to set height to 0, to allow height to be reduced
  666. node.set(OFFSET_HEIGHT, 0);
  667. }
  668. cbContentHeight = contentBox.get(OFFSET_HEIGHT) -
  669. parseInt(contentBox.getComputedStyle("paddingTop"), 10) -
  670. parseInt(contentBox.getComputedStyle("paddingBottom"), 10) -
  671. parseInt(contentBox.getComputedStyle("borderBottomWidth"), 10) -
  672. parseInt(contentBox.getComputedStyle("borderTopWidth"), 10);
  673. if (L.isNumber(cbContentHeight)) {
  674. remaining = cbContentHeight - filled;
  675. if (remaining >= 0) {
  676. node.set(OFFSET_HEIGHT, remaining);
  677. }
  678. }
  679. }
  680. }
  681. }
  682. };
  683. Y.WidgetStdMod = StdMod;
  684. }, '3.4.0' ,{requires:['base-build', 'widget']});