Changeset 13065

Show
Ignore:
Timestamp:
03/13/08 04:18:34 (8 months ago)
Author:
bill
Message:

Fixes #5859, #6186: problems with initial BorderContainer? sizing on IE.
Setting the size of a node and then immediately querying the size sometimes doesn't work (plus which it's inefficient). Fixed that for IE although not for other browsers. (IE is a separate code path since it doesn't use t/l/b/r four-corners setting for styling.)
!strict

Files:
1 modified

Legend:

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

    r13044 r13065  
    7777 
    7878                        this["_"+region] = child.domNode; 
     79                        this["_"+region+"Widget"] = child; 
    7980 
    8081                        if(child.splitter){ 
     
    119120                this.inherited(arguments); 
    120121                delete this["_"+region]; 
     122                delete this["_" +region+"Widget"]; 
    121123                if(this._started){ 
    122124                        this._layoutChildren(child.region); 
     
    131133 
    132134                var changedSide = /left|right/.test(changedRegion); 
     135 
     136                // TODO: cache the size of each pane so we don't have to keep calling dojo.marginBox() 
     137 
    133138                var layoutSides = !changedRegion || (!changedSide && !sidebarLayout); 
    134139                var layoutTopBottom = !changedRegion || (changedSide && sidebarLayout); 
     
    224229                } 
    225230 
    226                 // TEXTAREA elements in Gecko or Safari don't respond to t/l/b/r 
    227                 var janky = dojo.some(this.getChildren(), function(child){ 
     231                // Nodes in IE respond to t/l/b/r, and TEXTAREA doesn't respond in any browser 
     232                var janky = dojo.isIE || dojo.some(this.getChildren(), function(child){ 
    228233                        return child.domNode.tagName == "TEXTAREA"; 
    229234                }); 
    230                 if(janky || dojo.isIE){ 
     235                if(janky){ 
     236                        // Set the size of the children the old fashioned way, by calling 
     237                        // childNode.resize({h: int, w: int}) for each child node) 
     238 
    231239                        var borderBox = function(n, b){ 
    232240                                n=dojo.byId(n); 
     
    238246                        }; 
    239247 
    240 //TODO: use dim passed in? and make borderBox setBorderBox? 
     248                        var resizeWidget = function(widget, dim){ 
     249                                if(widget){ 
     250                                        widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim); 
     251                                } 
     252                        }; 
     253 
     254                        // TODO: use dim passed in to resize() (see _LayoutWidget.js resize()) 
     255                        // Then can make borderBox setBorderBox(), since no longer need to ever get the borderBox() size 
    241256                        var thisBorderBox = borderBox(this.domNode); 
    242257 
     
    248263                        if(bottomSplitter){ middleHeight -= bottomSplitterThickness; } 
    249264                        var centerDim = { h: middleHeight }; 
    250                         if(layoutSides){ 
    251                                 var sidebarHeight = sidebarLayout ? containerHeight : middleHeight; 
    252                                 if(leftSplitter){ leftSplitter.style.height = sidebarHeight; } 
    253                                 if(rightSplitter){ rightSplitter.style.height = sidebarHeight; } 
    254                                 if(this._left){ borderBox(this._left, {h: sidebarHeight}); } 
    255                                 if(this._right){ borderBox(this._right, {h: sidebarHeight}); } 
    256                         } 
    257  
    258                         if(janky || (dojo.isIE && (dojo.doc.compatMode == "BackCompat" || dojo.isIE < 7))){ 
    259 //TODO: use dojo.marginBox instead of dojo.style? 
    260                                 var containerWidth = thisBorderBox.w; 
    261                                 var middleWidth = containerWidth; 
    262                                 if(this._left){ middleWidth -= leftWidth; } 
    263                                 if(this._right){ middleWidth -= rightWidth; } 
    264                                 if(leftSplitter){ middleWidth -= leftSplitterThickness; } 
    265                                 if(rightSplitter){ middleWidth -= rightSplitterThickness; } 
    266                                 centerDim.w = middleWidth; 
    267                                 if(layoutTopBottom){ 
    268                                         var sidebarWidth = sidebarLayout ? middleWidth : containerWidth; 
    269                                         if(topSplitter){ topSplitter.style.width = sidebarWidth; } 
    270                                         if(bottomSplitter){ bottomSplitter.style.width = sidebarWidth; } 
    271                                         if(this._top){ borderBox(this._top, {w: sidebarWidth}); } 
    272                                         if(this._bottom){ borderBox(this._bottom, {w: sidebarWidth}); } 
     265 
     266                        var sidebarHeight = sidebarLayout ? containerHeight : middleHeight; 
     267                        if(leftSplitter){ leftSplitter.style.height = sidebarHeight; } 
     268                        if(rightSplitter){ rightSplitter.style.height = sidebarHeight; } 
     269                        resizeWidget(this._leftWidget, {h: sidebarHeight, w: leftWidth}); 
     270                        resizeWidget(this._rightWidget, {h: sidebarHeight, w: rightWidth}); 
     271 
     272                        var containerWidth = thisBorderBox.w; 
     273                        var middleWidth = containerWidth; 
     274                        if(this._left){ middleWidth -= leftWidth; } 
     275                        if(this._right){ middleWidth -= rightWidth; } 
     276                        if(leftSplitter){ middleWidth -= leftSplitterThickness; } 
     277                        if(rightSplitter){ middleWidth -= rightSplitterThickness; } 
     278                        centerDim.w = middleWidth; 
     279 
     280                        var sidebarWidth = sidebarLayout ? middleWidth : containerWidth; 
     281                        if(topSplitter){ topSplitter.style.width = sidebarWidth; } 
     282                        if(bottomSplitter){ bottomSplitter.style.width = sidebarWidth; } 
     283                        resizeWidget(this._topWidget, {h: topHeight, w: sidebarWidth}); 
     284                        resizeWidget(this._bottomWidget, {h: bottomHeight, w: sidebarWidth}); 
     285 
     286                        resizeWidget(this._centerWidget, centerDim); 
     287                }else{ 
     288 
     289                        // We've already sized the children by setting style.top/bottom/left/right... 
     290                        // Now just need to call resize() on those children so they can re-layout themselves 
     291 
     292                        // TODO: calling child.resize() without an argument is bad, because it forces 
     293                        // the child to query it's own size (even though this function already knows 
     294                        // the size), plus which querying the size of a node right after setting it 
     295                        // is known to cause problems (incorrect answer or an exception). 
     296                        // This is a setback from older layout widgets, which 
     297                        // don't do that.  See #3399, #2678, #3624 and #2955, #1988 
     298 
     299                        var resizeList = {}; 
     300                        if(changedRegion){ 
     301                                resizeList[changedRegion] = resizeList.center = true; 
     302                                if(/top|bottom/.test(changedRegion) && this.design != "sidebar"){ 
     303                                        resizeList.left = resizeList.right = true; 
     304                                }else if(/left|right/.test(changedRegion) && this.design == "sidebar"){ 
     305                                        resizeList.top = resizeList.bottom = true; 
    273306                                } 
    274307                        } 
    275                         if(this._center){ borderBox(this._center, centerDim); } 
    276                 } 
    277  
    278 //OPT: can this.resize() just do the following resize of children and skip the re-layout portion? 
    279 /* 
    280 TODO bill says: you call child.resize() without an 
    281 argument, which means that right after the BorderContainer sets the size 
    282 of a child widget, the child will have to query it's own size, which was 
    283 known to cause problems (ie, give an incorrect answer or an exception) 
    284 in the past.  This is a setback from the current layout widgets, which 
    285 don't do that.  See #3399, #2678, #3624 and #2955, #1988 
    286 */ 
    287  
    288                 var resizeList = {}; 
    289                 if(changedRegion){ 
    290                         resizeList[changedRegion] = resizeList.center = true; 
    291                         if(/top|bottom/.test(changedRegion) && this.design != "sidebar"){ 
    292                                 resizeList.left = resizeList.right = true; 
    293                         }else if(/left|right/.test(changedRegion) && this.design == "sidebar"){ 
    294                                 resizeList.top = resizeList.bottom = true; 
    295                         } 
    296                 } 
    297  
    298                 dojo.forEach(this.getChildren(), function(child){ 
    299                         if(child.resize && (!changedRegion || child.region in resizeList)){ 
    300 //                              console.log(this.id, ": resizing child id=" + child.id + " (region=" + child.region + "), style before resize is " + 
    301 //                                                                       "{ t: " + child.domNode.style.top + 
    302 //                                                                      ", b: " + child.domNode.style.bottom + 
    303 //                                                                      ", l: " + child.domNode.style.left + 
    304 //                                                                       ", r: " + child.domNode.style.right + 
    305 //                                                                       ", w: " + child.domNode.style.width + 
    306 //                                                                       ", h: " + child.domNode.style.height + 
    307 //                                                                      "}" 
    308 //                                              ); 
    309                                 child.resize(); 
    310 //                              console.log(this.id, ": after resize of child id=" + child.id + " (region=" + child.region + ") " + 
    311 //                                                                       "{ t: " + child.domNode.style.top + 
    312 //                                                                      ", b: " + child.domNode.style.bottom + 
    313 //                                                                      ", l: " + child.domNode.style.left + 
    314 //                                                                       ", r: " + child.domNode.style.right + 
    315 //                                                                       ", w: " + child.domNode.style.width + 
    316 //                                                                       ", h: " + child.domNode.style.height + 
    317 //                                                                      "}" 
    318 //                                              ); 
    319                         } 
    320                 }, this); 
     308 
     309                        dojo.forEach(this.getChildren(), function(child){ 
     310                                if(child.resize && (!changedRegion || child.region in resizeList)){ 
     311        //                              console.log(this.id, ": resizing child id=" + child.id + " (region=" + child.region + "), style before resize is " + 
     312        //                                                                       "{ t: " + child.domNode.style.top + 
     313        //                                                                      ", b: " + child.domNode.style.bottom + 
     314        //                                                                      ", l: " + child.domNode.style.left + 
     315        //                                                                       ", r: " + child.domNode.style.right + 
     316        //                                                                       ", w: " + child.domNode.style.width + 
     317        //                                                                       ", h: " + child.domNode.style.height + 
     318        //                                                                      "}" 
     319        //                                              ); 
     320                                        child.resize(); 
     321        //                              console.log(this.id, ": after resize of child id=" + child.id + " (region=" + child.region + ") " + 
     322        //                                                                       "{ t: " + child.domNode.style.top + 
     323        //                                                                      ", b: " + child.domNode.style.bottom + 
     324        //                                                                      ", l: " + child.domNode.style.left + 
     325        //                                                                       ", r: " + child.domNode.style.right + 
     326        //                                                                       ", w: " + child.domNode.style.width + 
     327        //                                                                       ", h: " + child.domNode.style.height + 
     328        //                                                                      "}" 
     329        //                                              ); 
     330                                } 
     331                        }, this); 
     332                } 
    321333        } 
    322334}); 
     
    433445                                if(resize || forceResize){ 
    434446                                        mb[dim] = boundChildSize; 
     447                                        // TODO: inefficient; we set the marginBox here and then immediately layoutFunc() needs to query it 
    435448                                        dojo.marginBox(childNode, mb); 
    436449                                        layoutFunc(region);