145 lines
4.4 KiB
JavaScript
145 lines
4.4 KiB
JavaScript
|
dojo.provide("dijit._Container");
|
||
|
|
||
|
dojo.declare("dijit._Container",
|
||
|
null,
|
||
|
{
|
||
|
// summary:
|
||
|
// Mixin for widgets that contain a set of widget children.
|
||
|
// description:
|
||
|
// Use this mixin for widgets that needs to know about and
|
||
|
// keep track of their widget children. Suitable for widgets like BorderContainer
|
||
|
// and TabContainer which contain (only) a set of child widgets.
|
||
|
//
|
||
|
// It's not suitable for widgets like ContentPane
|
||
|
// which contains mixed HTML (plain DOM nodes in addition to widgets),
|
||
|
// and where contained widgets are not necessarily directly below
|
||
|
// this.containerNode. In that case calls like addChild(node, position)
|
||
|
// wouldn't make sense.
|
||
|
|
||
|
// isContainer: [protected] Boolean
|
||
|
// Just a flag indicating that this widget descends from dijit._Container
|
||
|
isContainer: true,
|
||
|
|
||
|
buildRendering: function(){
|
||
|
this.inherited(arguments);
|
||
|
if(!this.containerNode){
|
||
|
// all widgets with descendants must set containerNode
|
||
|
this.containerNode = this.domNode;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
|
||
|
// summary:
|
||
|
// Makes the given widget a child of this widget.
|
||
|
// description:
|
||
|
// Inserts specified child widget's dom node as a child of this widget's
|
||
|
// container node, and possibly does other processing (such as layout).
|
||
|
|
||
|
var refNode = this.containerNode;
|
||
|
if(insertIndex && typeof insertIndex == "number"){
|
||
|
var children = this.getChildren();
|
||
|
if(children && children.length >= insertIndex){
|
||
|
refNode = children[insertIndex-1].domNode;
|
||
|
insertIndex = "after";
|
||
|
}
|
||
|
}
|
||
|
dojo.place(widget.domNode, refNode, insertIndex);
|
||
|
|
||
|
// If I've been started but the child widget hasn't been started,
|
||
|
// start it now. Make sure to do this after widget has been
|
||
|
// inserted into the DOM tree, so it can see that it's being controlled by me,
|
||
|
// so it doesn't try to size itself.
|
||
|
if(this._started && !widget._started){
|
||
|
widget.startup();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
removeChild: function(/*Widget or int*/ widget){
|
||
|
// summary:
|
||
|
// Removes the passed widget instance from this widget but does
|
||
|
// not destroy it. You can also pass in an integer indicating
|
||
|
// the index within the container to remove
|
||
|
if(typeof widget == "number" && widget > 0){
|
||
|
widget = this.getChildren()[widget];
|
||
|
}
|
||
|
// If we cannot find the widget, just return
|
||
|
if(!widget || !widget.domNode){ return; }
|
||
|
|
||
|
var node = widget.domNode;
|
||
|
node.parentNode.removeChild(node); // detach but don't destroy
|
||
|
},
|
||
|
|
||
|
_nextElement: function(node){
|
||
|
// summary:
|
||
|
// Find the next (non-text, non-comment etc) node
|
||
|
// tags:
|
||
|
// private
|
||
|
do{
|
||
|
node = node.nextSibling;
|
||
|
}while(node && node.nodeType != 1);
|
||
|
return node;
|
||
|
},
|
||
|
|
||
|
_firstElement: function(node){
|
||
|
// summary:
|
||
|
// Find the first (non-text, non-comment etc) node
|
||
|
// tags:
|
||
|
// private
|
||
|
node = node.firstChild;
|
||
|
if(node && node.nodeType != 1){
|
||
|
node = this._nextElement(node);
|
||
|
}
|
||
|
return node;
|
||
|
},
|
||
|
|
||
|
getChildren: function(){
|
||
|
// summary:
|
||
|
// Returns array of children widgets.
|
||
|
// description:
|
||
|
// Returns the widgets that are directly under this.containerNode.
|
||
|
return dojo.query("> [widgetId]", this.containerNode).map(dijit.byNode); // Widget[]
|
||
|
},
|
||
|
|
||
|
hasChildren: function(){
|
||
|
// summary:
|
||
|
// Returns true if widget has children, i.e. if this.containerNode contains something.
|
||
|
return !!this._firstElement(this.containerNode); // Boolean
|
||
|
},
|
||
|
|
||
|
destroyDescendants: function(/*Boolean*/ preserveDom){
|
||
|
// summary:
|
||
|
// Destroys all the widgets inside this.containerNode,
|
||
|
// but not this widget itself
|
||
|
dojo.forEach(this.getChildren(), function(child){ child.destroyRecursive(preserveDom); });
|
||
|
},
|
||
|
|
||
|
_getSiblingOfChild: function(/*Widget*/ child, /*int*/ dir){
|
||
|
// summary:
|
||
|
// Get the next or previous widget sibling of child
|
||
|
// dir:
|
||
|
// if 1, get the next sibling
|
||
|
// if -1, get the previous sibling
|
||
|
// tags:
|
||
|
// private
|
||
|
var node = child.domNode;
|
||
|
var which = (dir>0 ? "nextSibling" : "previousSibling");
|
||
|
do{
|
||
|
node = node[which];
|
||
|
}while(node && (node.nodeType != 1 || !dijit.byNode(node)));
|
||
|
return node ? dijit.byNode(node) : null;
|
||
|
},
|
||
|
|
||
|
getIndexOfChild: function(/*Widget*/ child){
|
||
|
// summary:
|
||
|
// Gets the index of the child in this container or -1 if not found
|
||
|
var children = this.getChildren();
|
||
|
for(var i=0, c; c=children[i]; i++){
|
||
|
if(c == child){
|
||
|
return i; // int
|
||
|
}
|
||
|
}
|
||
|
return -1; // int
|
||
|
}
|
||
|
}
|
||
|
);
|