Changeset 13521

Show
Ignore:
Timestamp:
04/30/08 19:59:27 (7 months ago)
Author:
bill
Message:

Fix leak where destroyDescendants() wasn't working on layout widgets.

Problem was that getDescendants() wasn't finding the children (and grandchildren, etc) of widgets which didn't set containerNode, particularly layout widgets with no templates.

Fixes #6604.
!strict

Location:
dijit/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • dijit/trunk/layout/ContentPane.js

    r13472 r13521  
    133133                // TODO: if there are two child widgets (a data store and a TabContainer, for example), 
    134134                //      should still find the TabContainer 
    135                 var childNodes = dojo.query(">", this.containerNode || this.domNode), 
     135                var childNodes = dojo.query(">", this.containerNode), 
    136136                        childWidgets = childNodes.filter("[widgetId]"); 
    137137 
     
    193193                        if(this._singleChild && this._singleChild.resize){ 
    194194                                this._singleChild.startup(); 
    195                                 this._singleChild.resize(this._contentBox || dojo.contentBox(this.containerNode || this.domNode)); 
     195                                this._singleChild.resize(this._contentBox || dojo.contentBox(this.containerNode)); 
    196196                        } 
    197197                } 
     
    227227                // But note that setting the margin box and then immediately querying dimensions may return 
    228228                // inaccurate results, so try not to depend on it. 
    229                 var node = this.containerNode || this.domNode, 
     229                var node = this.containerNode, 
    230230                        mb = dojo.mixin(dojo.marginBox(node), size||{}); 
    231231 
     
    344344 
    345345        _setContent: function(cont){ 
     346                // first get rid of child widgets 
    346347                this.destroyDescendants(); 
    347348 
    348349                try{ 
    349                         var node = this.containerNode || this.domNode; 
     350                        // ... and then get rid of child dom nodes 
     351                        var node = this.containerNode; 
    350352                        while(node.firstChild){ 
    351353                                dojo._destroyElement(node.firstChild); 
     
    395397        _createSubWidgets: function(){ 
    396398                // summary: scan my contents and create subwidgets 
    397                 var rootNode = this.containerNode || this.domNode; 
    398399                try{ 
    399                         dojo.parser.parse(rootNode, true); 
     400                        dojo.parser.parse(this.containerNode, true); 
    400401                }catch(e){ 
    401402                        this._onError('Content', e, "Couldn't create widgets in "+this.id 
  • dijit/trunk/layout/StackContainer.js

    r13089 r13521  
    3636=====*/ 
    3737        postCreate: function(){ 
    38                 dijit.setWaiRole((this.containerNode || this.domNode), "tabpanel"); 
     38                dijit.setWaiRole(this.containerNode, "tabpanel"); 
    3939                this.connect(this.domNode, "onkeypress", this._onKeyPress); 
    4040        }, 
     
    348348                        newButton.focusNode.setAttribute("tabIndex", "0"); 
    349349                        var container = dijit.byId(this.containerId); 
    350                         dijit.setWaiState(container.containerNode || container.domNode, "labelledby", newButton.id); 
     350                        dijit.setWaiState(container.containerNode, "labelledby", newButton.id); 
    351351                }, 
    352352 
  • dijit/trunk/_Container.js

    r12406 r13521  
    5757        { 
    5858                // summary: 
    59                 //              Mixin for widgets that contain a list of children. 
     59                //              Mixin for widgets that contain a set of widget children. 
    6060                // description: 
    61                 //              Use this mixin when the widget needs to know about and 
    62                 //              keep track of it's widget children. Widgets like SplitContainer 
    63                 //              and TabContainer.   
    64  
     61                //              Use this mixin for widgets that needs to know about and 
     62                //              keep track of their widget children. Suitable for widgets like BorderContainer 
     63                //              and TabContainer which contain (only) a set of child widgets. 
     64                // 
     65                //              It's not suitable for widgets like ContentPane 
     66                //              which contains mixed HTML (plain DOM nodes in addition to widgets), 
     67                //              and where contained widgets are not necessarily directly below 
     68                //              this.containerNode.   In that case calls like addChild(node, position) 
     69                //              wouldn't make sense. 
     70 
     71                // isContainer: Boolean 
     72                //              Just a flag indicating that this widget descends from dijit._Container 
    6573                isContainer: true, 
    6674 
     75                buildRendering: function(){ 
     76                        this.inherited(arguments); 
     77                        if(!this.containerNode){ 
     78                                // all widgets with descendants must set containerNode 
     79                                this.containerNode = this.domNode; 
     80                        } 
     81                }, 
     82 
    6783                addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){ 
    6884                        // summary: 
    69                         //              Process the given child widget, inserting it's dom node as 
    70                         //              a child of our dom node 
     85                        //              Makes the given widget a child of this widget. 
     86                        // description: 
     87                        //              Inserts specified child widget's dom node as a child of this widget's 
     88                        //              container node, and possibly does otherprocessing (such as layout). 
    7189 
    7290                        if(insertIndex === undefined){ 
    7391                                insertIndex = "last"; 
    7492                        } 
    75                         var refNode = this.containerNode || this.domNode; 
     93                        var refNode = this.containerNode; 
    7694                        if(insertIndex && typeof insertIndex == "number"){ 
    7795                                var children = dojo.query("> [widgetid]", refNode); 
     
    94112                        // summary: 
    95113                        //              Removes the passed widget instance from this widget but does 
    96                         //              not destroy it 
     114                        //              not destroy it. 
    97115                        var node = widget.domNode; 
    98116                        node.parentNode.removeChild(node);      // detach but don't destroy 
     
    116134                getChildren: function(){ 
    117135                        // summary: 
    118                         //              Returns array of children widgets 
    119                         return dojo.query("> [widgetId]", this.containerNode || this.domNode).map(dijit.byNode); // Array 
     136                        //              Returns array of children widgets. 
     137                        // description: 
     138                        //              Returns the widgets that are directly under this.containerNode. 
     139                        return dojo.query("> [widgetId]", this.containerNode).map(dijit.byNode); // Widget[] 
    120140                }, 
    121141 
    122142                hasChildren: function(){ 
    123143                        // summary: 
    124                         //              Returns true if widget has children 
    125                         var cn = this.containerNode || this.domNode; 
    126                         return !!this._firstElement(cn); // Boolean 
     144                        //              Returns true if widget has children, i.e. if this.containerNode contains something. 
     145                        return !!this._firstElement(this.containerNode); // Boolean 
    127146                }, 
    128147 
  • dijit/trunk/_Templated.js

    r12872 r13521  
    3030                //              declared in markup inside it? false by default. 
    3131                widgetsInTemplate: false, 
    32  
    33                 // containerNode: DomNode 
    34                 //              holds child elements. "containerNode" is generally set via a 
    35                 //              dojoAttachPoint assignment and it designates where children of 
    36                 //              the src dom node will be placed 
    37                 containerNode: null, 
    3832 
    3933                // skipNodeCache: Boolean 
  • dijit/trunk/_Widget.js

    r13274 r13521  
    4747 
    4848        // domNode: DomNode 
    49         //              this is our visible representation of the widget! Other DOM 
     49        //              This is our visible representation of the widget! Other DOM 
    5050        //              Nodes may by assigned to other properties, usually through the 
    51         //              template system's dojoAttachPonit syntax, but the domNode 
     51        //              template system's dojoAttachPoint syntax, but the domNode 
    5252        //              property is the canonical "top level" node in widget UI. 
    5353        domNode: null, 
     54 
     55        // containerNode: DomNode 
     56        //              Designates where children of the source dom node will be placed. 
     57        //              "Children" in this case refers to both dom nodes and widgets. 
     58        //              For example, for myWidget: 
     59        // 
     60        //              |       <div dojoType=myWidget> 
     61        //              |               <b> here's a plain dom node 
     62        //              |               <span dojoType=subWidget>and a widget</span> 
     63        //              |               <i> and another plain dom node </i> 
     64        //              |       </div> 
     65        // 
     66        //              containerNode would point to: 
     67        // 
     68        //              |               <b> here's a plain dom node 
     69        //              |               <span dojoType=subWidget>and a widget</span> 
     70        //              |               <i> and another plain dom node </i> 
     71        // 
     72        //              In templated widgets, "containerNode" is set via a 
     73        //              dojoAttachPoint assignment. 
     74        // 
     75        //              containerNode must be defined for any widget that accepts innerHTML 
     76        //              (like ContentPane or BorderContainer or even Button), and conversely 
     77        //              is null for widgets that don't, like TextBox. 
     78        containerNode: null, 
    5479 
    5580        // attributeMap: Object 
     
    316341        getDescendants: function(){ 
    317342                // summary: 
    318                 //      Returns all the widgets that contained by this, i.e., all widgets underneath this.containerNode. 
     343                //              Returns all the widgets that contained by this, i.e., all widgets underneath this.containerNode. 
     344                // description: 
     345                //              This method is designed to *not* return widgets that are, for example, 
     346                //              used as part of a template, but rather to just return widgets that are defined in the 
     347                //              original markup as descendants of this widget, for example w/this markup: 
     348                // 
     349                //              |       <div dojoType=myWidget> 
     350                //              |               <b> hello world </b> 
     351                //              |               <div> 
     352                //              |                       <span dojoType=subwidget> 
     353                //              |                               <span dojoType=subwidget2>how's it going?</span> 
     354                //              |                       </span> 
     355                //              |               </div> 
     356                //              |       </div> 
     357                // 
     358                //              getDescendants() will return subwidget, but not anything that's part of the template 
     359                //              of myWidget. 
     360 
    319361                if(this.containerNode){ 
    320362                        var list= dojo.query('[widgetId]', this.containerNode);