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