Component2.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-layout-component-Component'>/**
  19. </span> * This class is intended to be extended or created via the {@link Ext.Component#componentLayout layout}
  20. * configuration property. See {@link Ext.Component#componentLayout} for additional details.
  21. * @private
  22. */
  23. Ext.define('Ext.layout.component.Component', {
  24. /* Begin Definitions */
  25. extend: 'Ext.layout.Layout',
  26. /* End Definitions */
  27. type: 'component',
  28. isComponentLayout: true,
  29. nullBox: {},
  30. usesContentHeight: true,
  31. usesContentWidth: true,
  32. usesHeight: true,
  33. usesWidth: true,
  34. beginLayoutCycle: function (ownerContext, firstCycle) {
  35. var me = this,
  36. owner = me.owner,
  37. ownerCtContext = ownerContext.ownerCtContext,
  38. heightModel = ownerContext.heightModel,
  39. widthModel = ownerContext.widthModel,
  40. body = owner.el.dom === document.body,
  41. lastBox = owner.lastBox || me.nullBox,
  42. lastSize = owner.el.lastBox || me.nullBox,
  43. dirty = !body,
  44. ownerLayout, v, widthName, heightName;
  45. me.callParent(arguments);
  46. if (firstCycle) {
  47. if (me.usesContentWidth) {
  48. ++ownerContext.consumersContentWidth;
  49. }
  50. if (me.usesContentHeight) {
  51. ++ownerContext.consumersContentHeight;
  52. }
  53. if (me.usesWidth) {
  54. ++ownerContext.consumersWidth;
  55. }
  56. if (me.usesHeight) {
  57. ++ownerContext.consumersHeight;
  58. }
  59. if (ownerCtContext &amp;&amp; !ownerCtContext.hasRawContent) {
  60. ownerLayout = owner.ownerLayout;
  61. if (ownerLayout.usesWidth) {
  62. ++ownerContext.consumersWidth;
  63. }
  64. if (ownerLayout.usesHeight) {
  65. ++ownerContext.consumersHeight;
  66. }
  67. }
  68. }
  69. // we want to publish configured dimensions as early as possible and since this is
  70. // a write phase...
  71. if (widthModel.configured) {
  72. // If the owner.el is the body, owner.width is not dirty (we don't want to write
  73. // it to the body el). For other el's, the width may already be correct in the
  74. // DOM (e.g., it is rendered in the markup initially). If the width is not
  75. // correct in the DOM, this is only going to be the case on the first cycle.
  76. widthName = widthModel.names.width;
  77. if (!body) {
  78. dirty = firstCycle ? owner[widthName] !== lastSize.width
  79. : widthModel.constrained;
  80. }
  81. ownerContext.setWidth(owner[widthName], dirty);
  82. } else if (ownerContext.isTopLevel) {
  83. if (widthModel.calculated) {
  84. v = lastBox.width;
  85. ownerContext.setWidth(v, /*dirty=*/v != lastSize.width);
  86. }
  87. v = lastBox.x;
  88. ownerContext.setProp('x', v, /*dirty=*/v != lastSize.x);
  89. }
  90. if (heightModel.configured) {
  91. heightName = heightModel.names.height;
  92. if (!body) {
  93. dirty = firstCycle ? owner[heightName] !== lastSize.height
  94. : heightModel.constrained;
  95. }
  96. ownerContext.setHeight(owner[heightName], dirty);
  97. } else if (ownerContext.isTopLevel) {
  98. if (heightModel.calculated) {
  99. v = lastBox.height;
  100. ownerContext.setHeight(v, v != lastSize.height);
  101. }
  102. v = lastBox.y;
  103. ownerContext.setProp('y', v, /*dirty=*/v != lastSize.y);
  104. }
  105. },
  106. finishedLayout: function(ownerContext) {
  107. var me = this,
  108. elementChildren = ownerContext.children,
  109. owner = me.owner,
  110. len, i, elContext, lastBox, props, v;
  111. // NOTE: In the code below we cannot use getProp because that will generate a layout dependency
  112. // Set lastBox on managed child Elements.
  113. // So that ContextItem.constructor can snag the lastBox for use by its undo method.
  114. if (elementChildren) {
  115. len = elementChildren.length;
  116. for (i = 0; i &lt; len; i++) {
  117. elContext = elementChildren[i];
  118. elContext.el.lastBox = elContext.props;
  119. }
  120. }
  121. // Cache the size from which we are changing so that notifyOwner can notify the owningComponent with all essential information
  122. ownerContext.previousSize = me.lastComponentSize;
  123. // Cache the currently layed out size
  124. me.lastComponentSize = owner.el.lastBox = props = ownerContext.props;
  125. // lastBox is a copy of the defined props to allow save/restore of these (panel
  126. // collapse needs this)
  127. owner.lastBox = lastBox = {};
  128. v = props.x;
  129. if (v !== undefined) {
  130. lastBox.x = v;
  131. }
  132. v = props.y;
  133. if (v !== undefined) {
  134. lastBox.y = v;
  135. }
  136. v = props.width;
  137. if (v !== undefined) {
  138. lastBox.width = v;
  139. }
  140. v = props.height;
  141. if (v !== undefined) {
  142. lastBox.height = v;
  143. }
  144. me.callParent(arguments);
  145. },
  146. notifyOwner: function(ownerContext) {
  147. var me = this,
  148. currentSize = me.lastComponentSize,
  149. prevSize = ownerContext.previousSize,
  150. args = [currentSize.width, currentSize.height];
  151. if (prevSize) {
  152. args.push(prevSize.width, prevSize.height);
  153. }
  154. // Call afterComponentLayout passing new size, and only passing old size if there *was* an old size.
  155. me.owner.afterComponentLayout.apply(me.owner, args);
  156. },
  157. <span id='Ext-layout-component-Component-method-getTarget'> /**
  158. </span> * Returns the owner component's resize element.
  159. * @return {Ext.Element}
  160. */
  161. getTarget : function() {
  162. return this.owner.el;
  163. },
  164. <span id='Ext-layout-component-Component-method-getRenderTarget'> /**
  165. </span> * Returns the element into which rendering must take place. Defaults to the owner Component's encapsulating element.
  166. *
  167. * May be overridden in Component layout managers which implement an inner element.
  168. * @return {Ext.Element}
  169. */
  170. getRenderTarget : function() {
  171. return this.owner.el;
  172. },
  173. cacheTargetInfo: function(ownerContext) {
  174. var me = this,
  175. targetInfo = me.targetInfo,
  176. target;
  177. if (!targetInfo) {
  178. target = ownerContext.getEl('getTarget', me);
  179. me.targetInfo = targetInfo = {
  180. padding: target.getPaddingInfo(),
  181. border: target.getBorderInfo()
  182. };
  183. }
  184. return targetInfo;
  185. },
  186. measureAutoDimensions: function (ownerContext, dimensions) {
  187. // Subtle But Important:
  188. //
  189. // We don't want to call getProp/hasProp et.al. unless we in fact need that value
  190. // for our results! If we call it and don't need it, the layout manager will think
  191. // we depend on it and will schedule us again should it change.
  192. var me = this,
  193. owner = me.owner,
  194. containerLayout = owner.layout,
  195. heightModel = ownerContext.heightModel,
  196. widthModel = ownerContext.widthModel,
  197. boxParent = ownerContext.boxParent,
  198. isBoxParent = ownerContext.isBoxParent,
  199. props = ownerContext.props,
  200. isContainer,
  201. ret = {
  202. gotWidth: false,
  203. gotHeight: false,
  204. isContainer: (isContainer = !ownerContext.hasRawContent)
  205. },
  206. hv = dimensions || 3,
  207. zeroWidth, zeroHeight,
  208. needed = 0,
  209. got = 0,
  210. ready, size, temp;
  211. // Note: this method is called *a lot*, so we have to be careful not to waste any
  212. // time or make useless calls or, especially, read the DOM when we can avoid it.
  213. //---------------------------------------------------------------------
  214. // Width
  215. if (widthModel.shrinkWrap &amp;&amp; ownerContext.consumersContentWidth) {
  216. ++needed;
  217. zeroWidth = !(hv &amp; 1);
  218. if (isContainer) {
  219. // as a componentLayout for a container, we rely on the container layout to
  220. // produce contentWidth...
  221. if (zeroWidth) {
  222. ret.contentWidth = 0;
  223. ret.gotWidth = true;
  224. ++got;
  225. } else if ((ret.contentWidth = ownerContext.getProp('contentWidth')) !== undefined) {
  226. ret.gotWidth = true;
  227. ++got;
  228. }
  229. } else {
  230. size = props.contentWidth;
  231. if (typeof size == 'number') { // if (already determined)
  232. ret.contentWidth = size;
  233. ret.gotWidth = true;
  234. ++got;
  235. } else {
  236. if (zeroWidth) {
  237. ready = true;
  238. } else if (!ownerContext.hasDomProp('containerChildrenDone')) {
  239. ready = false;
  240. } else if (isBoxParent || !boxParent || boxParent.widthModel.shrinkWrap) {
  241. // if we have no boxParent, we are ready, but a shrinkWrap boxParent
  242. // artificially provides width early in the measurement process so
  243. // we are ready to go in that case as well...
  244. ready = true;
  245. } else {
  246. // lastly, we have a boxParent that will be given a width, so we
  247. // can wait for that width to be set in order to properly measure
  248. // whatever is inside...
  249. ready = boxParent.hasDomProp('width');
  250. }
  251. if (ready) {
  252. if (zeroWidth) {
  253. temp = 0;
  254. } else if (containerLayout &amp;&amp; containerLayout.measureContentWidth) {
  255. // Allow the container layout to do the measurement since it
  256. // may have a better idea of how to do it even with no items:
  257. temp = containerLayout.measureContentWidth(ownerContext);
  258. } else {
  259. temp = me.measureContentWidth(ownerContext);
  260. }
  261. if (!isNaN(ret.contentWidth = temp)) {
  262. ownerContext.setContentWidth(temp, true);
  263. ret.gotWidth = true;
  264. ++got;
  265. }
  266. }
  267. }
  268. }
  269. } else if (widthModel.natural &amp;&amp; ownerContext.consumersWidth) {
  270. ++needed;
  271. size = props.width;
  272. // zeroWidth does not apply
  273. if (typeof size == 'number') { // if (already determined)
  274. ret.width = size;
  275. ret.gotWidth = true;
  276. ++got;
  277. } else {
  278. if (isBoxParent || !boxParent) {
  279. ready = true;
  280. } else {
  281. // lastly, we have a boxParent that will be given a width, so we
  282. // can wait for that width to be set in order to properly measure
  283. // whatever is inside...
  284. ready = boxParent.hasDomProp('width');
  285. }
  286. if (ready) {
  287. if (!isNaN(ret.width = me.measureOwnerWidth(ownerContext))) {
  288. ownerContext.setWidth(ret.width, false);
  289. ret.gotWidth = true;
  290. ++got;
  291. }
  292. }
  293. }
  294. }
  295. //---------------------------------------------------------------------
  296. // Height
  297. if (heightModel.shrinkWrap &amp;&amp; ownerContext.consumersContentHeight) {
  298. ++needed;
  299. zeroHeight = !(hv &amp; 2);
  300. if (isContainer) {
  301. // don't ask unless we need to know...
  302. if (zeroHeight) {
  303. ret.contentHeight = 0;
  304. ret.gotHeight = true;
  305. ++got;
  306. } else if ((ret.contentHeight = ownerContext.getProp('contentHeight')) !== undefined) {
  307. ret.gotHeight = true;
  308. ++got;
  309. }
  310. } else {
  311. size = props.contentHeight;
  312. if (typeof size == 'number') { // if (already determined)
  313. ret.contentHeight = size;
  314. ret.gotHeight = true;
  315. ++got;
  316. } else {
  317. if (zeroHeight) {
  318. ready = true;
  319. } else if (!ownerContext.hasDomProp('containerChildrenDone')) {
  320. ready = false;
  321. } else if (owner.noWrap) {
  322. ready = true;
  323. } else if (!widthModel.shrinkWrap) {
  324. // fixed width, so we need the width to determine the height...
  325. ready = (ownerContext.bodyContext || ownerContext).hasDomProp('width');// &amp;&amp; (!ownerContext.bodyContext || ownerContext.bodyContext.hasDomProp('width'));
  326. } else if (isBoxParent || !boxParent || boxParent.widthModel.shrinkWrap) {
  327. // if we have no boxParent, we are ready, but an autoWidth boxParent
  328. // artificially provides width early in the measurement process so
  329. // we are ready to go in that case as well...
  330. ready = true;
  331. } else {
  332. // lastly, we have a boxParent that will be given a width, so we
  333. // can wait for that width to be set in order to properly measure
  334. // whatever is inside...
  335. ready = boxParent.hasDomProp('width');
  336. }
  337. if (ready) {
  338. if (zeroHeight) {
  339. temp = 0;
  340. } else if (containerLayout &amp;&amp; containerLayout.measureContentHeight) {
  341. // Allow the container layout to do the measurement since it
  342. // may have a better idea of how to do it even with no items:
  343. temp = containerLayout.measureContentHeight(ownerContext);
  344. } else {
  345. temp = me.measureContentHeight(ownerContext);
  346. }
  347. if (!isNaN(ret.contentHeight = temp)) {
  348. ownerContext.setContentHeight(temp, true);
  349. ret.gotHeight = true;
  350. ++got;
  351. }
  352. }
  353. }
  354. }
  355. } else if (heightModel.natural &amp;&amp; ownerContext.consumersHeight) {
  356. ++needed;
  357. size = props.height;
  358. // zeroHeight does not apply
  359. if (typeof size == 'number') { // if (already determined)
  360. ret.height = size;
  361. ret.gotHeight = true;
  362. ++got;
  363. } else {
  364. if (isBoxParent || !boxParent) {
  365. ready = true;
  366. } else {
  367. // lastly, we have a boxParent that will be given a width, so we
  368. // can wait for that width to be set in order to properly measure
  369. // whatever is inside...
  370. ready = boxParent.hasDomProp('width');
  371. }
  372. if (ready) {
  373. if (!isNaN(ret.height = me.measureOwnerHeight(ownerContext))) {
  374. ownerContext.setHeight(ret.height, false);
  375. ret.gotHeight = true;
  376. ++got;
  377. }
  378. }
  379. }
  380. }
  381. if (boxParent) {
  382. ownerContext.onBoxMeasured();
  383. }
  384. ret.gotAll = got == needed;
  385. // see if we can avoid calling this method by storing something on ownerContext.
  386. return ret;
  387. },
  388. measureContentWidth: function (ownerContext) {
  389. // contentWidth includes padding, but not border, framing or margins
  390. return ownerContext.el.getWidth() - ownerContext.getFrameInfo().width;
  391. },
  392. measureContentHeight: function (ownerContext) {
  393. // contentHeight includes padding, but not border, framing or margins
  394. return ownerContext.el.getHeight() - ownerContext.getFrameInfo().height;
  395. },
  396. measureOwnerHeight: function (ownerContext) {
  397. return ownerContext.el.getHeight();
  398. },
  399. measureOwnerWidth: function (ownerContext) {
  400. return ownerContext.el.getWidth();
  401. }
  402. });
  403. </pre>
  404. </body>
  405. </html>