Opened 11 years ago

Closed 10 years ago

#8024 closed defect (fixed)

BorderContainer: resize problem on BorderContainer (IE7)

Reported by: yherve Owned by: bill
Priority: high Milestone: 1.3
Component: Dijit Version: 1.2.0
Keywords: BorderContainer Cc:
Blocked By: Blocking:

Description

Hello dojo team,

I have a problem where IE7 breaks with an error popup when we click on the second tab, then try to resize the browser (see attached example)

From the debugger, the faulty line is:

if(leftSplitter){ leftSplitter.style.height = sidebarHeight; }

in function BorderContainer::_layoutChildren

it seems that the library tries to set dimension on hidden components and IE7 does not like that.

Attachments (3)

resizeProblemSnapshot.gif (70.2 KB) - added by yherve 11 years ago.
resizeProblemIE7.html (4.0 KB) - added by yherve 11 years ago.
resizeProblemTab.html (1.4 KB) - added by yherve 11 years ago.

Download all attachments as: .zip

Change History (13)

Changed 11 years ago by yherve

Attachment: resizeProblemSnapshot.gif added

Changed 11 years ago by yherve

Attachment: resizeProblemIE7.html added

Changed 11 years ago by yherve

Attachment: resizeProblemTab.html added

comment:1 Changed 11 years ago by bill

Summary: resize problem with BorderContainer (IE7)BorderContainer: resize problem on BorderContainer (IE7)

To clarify:

So you are resizing the browser window (and thus the BorderContainer) while the BorderContainer is hidden, because it's in an unselected tab?

comment:2 Changed 11 years ago by bill

See also #8042, probably the same cause.

comment:3 Changed 11 years ago by bill

I've looked into this.

The problem is the BorderContainer loaded via href, in the resizeProblemTab.html file. When that inner BorderContainer initializes, it checks whether it's contained by another layout widget, or if it's a "top level" widget. Although the inner BorderContainer is actually contained by the id="configTab" ContentPane, since that ContentPane doesn't have isContainer=true, the BorderContainer thinks it's top level.

Thus the inner BorderContainer attaches to the document resize event, and thus it tries to resize when the document resizes, even though it's inside a hidden tab. That code is in _LayoutWidget:

// If I am a top level widget
if(!this.getParent || !this.getParent()){
	...
	this.connect(dojo.global, 'onresize', 'resize');
}

ContentPane can act as a _Container, or not, depending on it's contents, and it does have code to detec which mode it's in and mark isContainer=true if appropriate:

if(
	// all child nodes are widgets
	childNodes.length == childWidgetNodes.length &&

	// all but one are invisible (like dojo.data)
	candidateWidgets.length == 1
){
	this.isContainer = true;
	this._singleChild = candidateWidgets[0];
}

I guess there's a problem with the order of computations... the ContentPane detection code above executes after the href loads and the BorderContainer widget has been created and started, whereas really it needs to execute after the href has loaded but before we call BorderContainer.startup().

comment:4 Changed 10 years ago by bill

Milestone: tbd1.5

comment:5 Changed 10 years ago by fl0

I'm encountering the same error in a setup without href-loaded ContentPanes?. I've got just a series of nested BorderContainers?, TabContainers?, and ContentPanes? (no external definitions). One BorderContainer? sits within a disabled tab of a TabContainer?. When the page is loaded, the BorderContainer?'s _layoutChildren gets called (indirectly) via the series of startup()- and layout()-invocations initially triggered by the dojo.parser and getting spread through the layout hierarchy (no browser resizing involved!). I assume due to the fact that the troubled BorderContainer? is invisible at that stage, the sidebarWidth is being filled with a negative value which causes IE7 to fail. I'd like to vote for the milestone being adjusted (let's say to 1.3), cause this might turn out as a scenario that happens way more often than the initial use case of this bug.

comment:6 Changed 10 years ago by bill

fl0 - the bug you are seeing is #5672, nothing to do w/this ticket.

comment:7 Changed 10 years ago by fl0

Thanks for the pointer. In my case, however, I don't have a layout issue (I'm resisizing children manually on tab selection), but exactly this "Invalid argument" error in IE7 happening in the same line as in the original bug report. This error blocks the execution of any subsequent code and did not happen in dojo 1.1.1 (since the sidebar calculation was changed as of 1.2). Maybe as a workaround you could prevent assigning negative values for the sidebar dimensions? Something like:

var containerHeight = this._borderBox.h - pe.t - pe.b,
    middleHeight = containerHeight - ( topHeight + topSplitterThickness + bottomHeight + bottomSplitterThickness),
    sidebarHeight = sidebarLayout ? containerHeight : middleHeight;
sidebarHeight = sidebarHeight < 0 ? 0 : sidebarHeight;

var containerWidth = this._borderBox.w - pe.l - pe.r,
    middleWidth = containerWidth - (leftWidth  + leftSplitterThickness + rightWidth + rightSplitterThickness),
    sidebarWidth = sidebarLayout ? middleWidth : containerWidth;
sidebarWidth = sidebarWidth < 0 ? 0 : sidebarWidth;


In my case, IE7 works fine again with this patch.

comment:8 Changed 10 years ago by bill

fl0 - I think now that #5672 is fixed the above calculation will no longer be negative, so you shouldn't have the problem anymore, nor should you need to resize things on pane display either. Let me know if it's working though... if not feel free to file a separate ticket, rather than appending more to this one. (If it turns out to be the same issue I'll close the new ticket and this one together.)

comment:9 Changed 10 years ago by bill

Milestone: 1.51.3
Owner: set to bill
Status: newassigned

I've decided to fix this directly... I.E., to abort the resize operation if we think our size is 0. See #5672 for further commentary.

comment:10 Changed 10 years ago by bill

Resolution: fixed
Status: assignedclosed

(In [15971]) Fixes #8024 !strict: if BorderContainer? is initialized in a hidden div (like an unselected tab) then abort resizing, to avoid getting an exception. The TabContainer? etc. will have to call resize() on me later (to notify me that I am now visible and should do layout).

Also refs #5672.

Note: See TracTickets for help on using tickets.