utils.js.uncompressed.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. define("dijit/layout/utils", [
  2. "dojo/_base/array", // array.filter array.forEach
  3. "dojo/dom-class", // domClass.add domClass.remove
  4. "dojo/dom-geometry", // domGeometry.marginBox
  5. "dojo/dom-style", // domStyle.getComputedStyle
  6. "dojo/_base/lang", // lang.mixin
  7. "../main" // for exporting symbols to dijit, remove in 2.0
  8. ], function(array, domClass, domGeometry, domStyle, lang, dijit){
  9. // module:
  10. // dijit/layout/utils
  11. var layout = lang.getObject("layout", true, dijit);
  12. /*=====
  13. layout = {
  14. // summary:
  15. // marginBox2contentBox() and layoutChildren()
  16. };
  17. =====*/
  18. layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
  19. // summary:
  20. // Given the margin-box size of a node, return its content box size.
  21. // Functions like domGeometry.contentBox() but is more reliable since it doesn't have
  22. // to wait for the browser to compute sizes.
  23. var cs = domStyle.getComputedStyle(node);
  24. var me = domGeometry.getMarginExtents(node, cs);
  25. var pb = domGeometry.getPadBorderExtents(node, cs);
  26. return {
  27. l: domStyle.toPixelValue(node, cs.paddingLeft),
  28. t: domStyle.toPixelValue(node, cs.paddingTop),
  29. w: mb.w - (me.w + pb.w),
  30. h: mb.h - (me.h + pb.h)
  31. };
  32. };
  33. function capitalize(word){
  34. return word.substring(0,1).toUpperCase() + word.substring(1);
  35. }
  36. function size(widget, dim){
  37. // size the child
  38. var newSize = widget.resize ? widget.resize(dim) : domGeometry.setMarginBox(widget.domNode, dim);
  39. // record child's size
  40. if(newSize){
  41. // if the child returned it's new size then use that
  42. lang.mixin(widget, newSize);
  43. }else{
  44. // otherwise, call getMarginBox(), but favor our own numbers when we have them.
  45. // the browser lies sometimes
  46. lang.mixin(widget, domGeometry.getMarginBox(widget.domNode));
  47. lang.mixin(widget, dim);
  48. }
  49. }
  50. layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children,
  51. /*String?*/ changedRegionId, /*Number?*/ changedRegionSize){
  52. // summary:
  53. // Layout a bunch of child dom nodes within a parent dom node
  54. // container:
  55. // parent node
  56. // dim:
  57. // {l, t, w, h} object specifying dimensions of container into which to place children
  58. // children:
  59. // An array of Widgets or at least objects containing:
  60. //
  61. // - domNode: pointer to DOM node to position
  62. // - region or layoutAlign: position to place DOM node
  63. // - resize(): (optional) method to set size of node
  64. // - id: (optional) Id of widgets, referenced from resize object, below.
  65. // changedRegionId:
  66. // If specified, the slider for the region with the specified id has been dragged, and thus
  67. // the region's height or width should be adjusted according to changedRegionSize
  68. // changedRegionSize:
  69. // See changedRegionId.
  70. // copy dim because we are going to modify it
  71. dim = lang.mixin({}, dim);
  72. domClass.add(container, "dijitLayoutContainer");
  73. // Move "client" elements to the end of the array for layout. a11y dictates that the author
  74. // needs to be able to put them in the document in tab-order, but this algorithm requires that
  75. // client be last. TODO: move these lines to LayoutContainer? Unneeded other places I think.
  76. children = array.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; })
  77. .concat(array.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; }));
  78. // set positions/sizes
  79. array.forEach(children, function(child){
  80. var elm = child.domNode,
  81. pos = (child.region || child.layoutAlign);
  82. if(!pos){
  83. throw new Error("No region setting for " + child.id)
  84. }
  85. // set elem to upper left corner of unused space; may move it later
  86. var elmStyle = elm.style;
  87. elmStyle.left = dim.l+"px";
  88. elmStyle.top = dim.t+"px";
  89. elmStyle.position = "absolute";
  90. domClass.add(elm, "dijitAlign" + capitalize(pos));
  91. // Size adjustments to make to this child widget
  92. var sizeSetting = {};
  93. // Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align
  94. // panes and width adjustment for left/right align panes.
  95. if(changedRegionId && changedRegionId == child.id){
  96. sizeSetting[child.region == "top" || child.region == "bottom" ? "h" : "w"] = changedRegionSize;
  97. }
  98. // set size && adjust record of remaining space.
  99. // note that setting the width of a <div> may affect its height.
  100. if(pos == "top" || pos == "bottom"){
  101. sizeSetting.w = dim.w;
  102. size(child, sizeSetting);
  103. dim.h -= child.h;
  104. if(pos == "top"){
  105. dim.t += child.h;
  106. }else{
  107. elmStyle.top = dim.t + dim.h + "px";
  108. }
  109. }else if(pos == "left" || pos == "right"){
  110. sizeSetting.h = dim.h;
  111. size(child, sizeSetting);
  112. dim.w -= child.w;
  113. if(pos == "left"){
  114. dim.l += child.w;
  115. }else{
  116. elmStyle.left = dim.l + dim.w + "px";
  117. }
  118. }else if(pos == "client" || pos == "center"){
  119. size(child, dim);
  120. }
  121. });
  122. };
  123. return {
  124. marginBox2contentBox: layout.marginBox2contentBox,
  125. layoutChildren: layout.layoutChildren
  126. };
  127. });