Opened 11 years ago

Closed 11 years ago

#8269 closed defect (fixed)

BorderContainer: this_borderBox undefined error

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

Description

See test_ExpandoPane_prog.html and close the left pane.

Gives error in console about this._borderBox.

Possibly related to my recent ContentPane refactors, but not sure.

Attachments (1)

test_BorderContainer.html (2.5 KB) - added by dante 11 years ago.
structured to live in dojox/layout/tests/ - reduction showing error in BorderContainer?

Download all attachments as: .zip

Change History (6)

comment:1 Changed 11 years ago by dante

Owner: changed from dante to bill

This actually isn't related to ExpandoPane?. I've traced it down to a BorderContainer as a child of a TabContainer. If the TabContainer has been .startup()'d, addChild()'ing a newly created BorderContainer fails unless you select that child immediately after adding it. (Seems _borderBox isn't defined until tabs show the widget). Interestingly, it does NOT break if you add the BorderContainer, then children to that, THEN call .startup() on the tabs and entire heirarchy.

Discovered a bug in ExpandoPane though, in the latter case (tabs.startup() last action), the ExpandoPane? renders fine, but mis-calculates it's _titleHeight, and collapses to 0 width. calling tabs.selectChild(bc) allows the ExpandoPane (now visible) to determine his height, and works as expected.

anyway, this gets into Dijit internals and expected behavior of addChild/startup procedures (the expandoPane_prog test is creating tabs in one function, calling startup() and then adding a borderContainer). I've attached a reduced testcase, entirely programatic with additional notes inline comments.

Changed 11 years ago by dante

Attachment: test_BorderContainer.html added

structured to live in dojox/layout/tests/ - reduction showing error in BorderContainer?

comment:2 Changed 11 years ago by bill

Component: DojoxDijit
Summary: ExpandoPane: this_borderBox undefined errorBorderContainer: this_borderBox undefined error

Oh ok, thanks for tracing that down and for the test case. Here's what's happening, I think:

Basically, BorderContainer.addChild() is trying to do layout, even though BorderContainer.resize() has never been called, and the BorderContainer is hidden. Trying to do layout in either of these situations will break things.

Part of the complication is that TabContainer.startup() calls startup() on each of the TabContainer's children, but TabContainer defers calling resize() on a given child until that child is actually displayed.

BorderContainer.addChild() (and also removeChild()) do layout if the BorderContainer has been started. It would be better if the if() condition was based on whether the BorderContainer has been sized (ie, resize() has been called at least once), or in other words, whether this._borderBox is set.

I think this exact bug could be solved by simply changing BorderContainer's layoutChildren() from doing

if(!this._borderBox.h){
	// We are currently hidden.  Abort.
	// Someone will resize us later.
	return;
}

to

if(!this._borderBox || !this._borderBox.h){
	// We are currently hidden.  Abort.
	// Someone will resize us later.
	return;
}

Alternately, this exact bug could be fixed by TabContainer deferring calling startup() on a given child until that child is displayed.

But, even after fixing this bug, there's probably still a bug when the BorderContainer is hidden, like in this sequence of events:

  1. page has TabContainer where one of the children is a BorderContainer
  2. user selects the BorderContainer tab of the TabContainer (now the BorderContainer is both started and sized)
  3. user selects another tab (now the BorderContainer is display:none)
  4. programatically, something calls BorderContainer.addChild()

IIRC this will fail on IE, when the BorderContainer tries to layout it's children, calling dojo.marginBox() on hidden nodes. I guess this is a general issue for whenever addChild()/removeChild() is called on a hidden layout container, but seems like we can address it when the layout container is hidden inside of a StackContainer like TabContainer.

AccordionContainer, or rather, anything extending StackContainer, has the same problem as BorderContainer, that addChild() tries to do layout() when the StackContainer has been started but not sized, and also when the StackContainer is hidden.

comment:3 Changed 11 years ago by bill

Milestone: tbd1.3
Status: newassigned

I broke out the problem list in steps 1 - 4 above into #8519. I'll just use this ticket to fix the problem where a child is added after the BorderContainer has been started but before it's been initially sized.

comment:4 Changed 11 years ago by bill

(In [16497]) Handle case where addChild() is called after startup() but before initialize resize() call, which is for some reason happening with ExpandoPane?. Refs #8269 but doesn't completely fix ExpandoPane?. !strict.

comment:5 Changed 11 years ago by bill

Resolution: fixed
Status: assignedclosed

And the rest of the issues with test_ExpandoPane_prog.html were fixed with [16498].

Note: See TracTickets for help on using tickets.