_Container.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dijit._Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dijit._Container"] = true;
  8. dojo.provide("dijit._Container");
  9. dojo.declare("dijit._Container",
  10. null,
  11. {
  12. // summary:
  13. // Mixin for widgets that contain a set of widget children.
  14. // description:
  15. // Use this mixin for widgets that needs to know about and
  16. // keep track of their widget children. Suitable for widgets like BorderContainer
  17. // and TabContainer which contain (only) a set of child widgets.
  18. //
  19. // It's not suitable for widgets like ContentPane
  20. // which contains mixed HTML (plain DOM nodes in addition to widgets),
  21. // and where contained widgets are not necessarily directly below
  22. // this.containerNode. In that case calls like addChild(node, position)
  23. // wouldn't make sense.
  24. // isContainer: [protected] Boolean
  25. // Indicates that this widget acts as a "parent" to the descendant widgets.
  26. // When the parent is started it will call startup() on the child widgets.
  27. // See also `isLayoutContainer`.
  28. isContainer: true,
  29. buildRendering: function(){
  30. this.inherited(arguments);
  31. if(!this.containerNode){
  32. // all widgets with descendants must set containerNode
  33. this.containerNode = this.domNode;
  34. }
  35. },
  36. addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
  37. // summary:
  38. // Makes the given widget a child of this widget.
  39. // description:
  40. // Inserts specified child widget's dom node as a child of this widget's
  41. // container node, and possibly does other processing (such as layout).
  42. var refNode = this.containerNode;
  43. if(insertIndex && typeof insertIndex == "number"){
  44. var children = this.getChildren();
  45. if(children && children.length >= insertIndex){
  46. refNode = children[insertIndex-1].domNode;
  47. insertIndex = "after";
  48. }
  49. }
  50. dojo.place(widget.domNode, refNode, insertIndex);
  51. // If I've been started but the child widget hasn't been started,
  52. // start it now. Make sure to do this after widget has been
  53. // inserted into the DOM tree, so it can see that it's being controlled by me,
  54. // so it doesn't try to size itself.
  55. if(this._started && !widget._started){
  56. widget.startup();
  57. }
  58. },
  59. removeChild: function(/*Widget or int*/ widget){
  60. // summary:
  61. // Removes the passed widget instance from this widget but does
  62. // not destroy it. You can also pass in an integer indicating
  63. // the index within the container to remove
  64. if(typeof widget == "number"){
  65. widget = this.getChildren()[widget];
  66. }
  67. if(widget){
  68. var node = widget.domNode;
  69. if(node && node.parentNode){
  70. node.parentNode.removeChild(node); // detach but don't destroy
  71. }
  72. }
  73. },
  74. hasChildren: function(){
  75. // summary:
  76. // Returns true if widget has children, i.e. if this.containerNode contains something.
  77. return this.getChildren().length > 0; // Boolean
  78. },
  79. destroyDescendants: function(/*Boolean*/ preserveDom){
  80. // summary:
  81. // Destroys all the widgets inside this.containerNode,
  82. // but not this widget itself
  83. dojo.forEach(this.getChildren(), function(child){ child.destroyRecursive(preserveDom); });
  84. },
  85. _getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){
  86. // summary:
  87. // Get the next or previous widget sibling of child
  88. // dir:
  89. // if 1, get the next sibling
  90. // if -1, get the previous sibling
  91. // tags:
  92. // private
  93. var node = child.domNode,
  94. which = (dir>0 ? "nextSibling" : "previousSibling");
  95. do{
  96. node = node[which];
  97. }while(node && (node.nodeType != 1 || !dijit.byNode(node)));
  98. return node && dijit.byNode(node); // dijit._Widget
  99. },
  100. getIndexOfChild: function(/*dijit._Widget*/ child){
  101. // summary:
  102. // Gets the index of the child in this container or -1 if not found
  103. return dojo.indexOf(this.getChildren(), child); // int
  104. },
  105. startup: function(){
  106. // summary:
  107. // Called after all the widgets have been instantiated and their
  108. // dom nodes have been inserted somewhere under dojo.doc.body.
  109. //
  110. // Widgets should override this method to do any initialization
  111. // dependent on other widgets existing, and then call
  112. // this superclass method to finish things off.
  113. //
  114. // startup() in subclasses shouldn't do anything
  115. // size related because the size of the widget hasn't been set yet.
  116. if(this._started){ return; }
  117. // Startup all children of this widget
  118. dojo.forEach(this.getChildren(), function(child){ child.startup(); });
  119. this.inherited(arguments);
  120. }
  121. }
  122. );
  123. }