PDA

View Full Version : Closing Tab doesn't complete destroy panel



vtswingkid
18 Jan 2007, 10:15 AM
Here is a simple test file...
Closing the tab via clicking on the 'x' icon does not appear to fully destroy the contentpanel...
Am using latest SVN .40 ... #121 I believe



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<script type='text/javascript' src='yui/build/yahoo/yahoo.js'></script>
<script type='text/javascript' src='yui/build/dom/dom.js'></script>
<script type='text/javascript' src='yui/build/event/event.js'></script>
<script type='text/javascript' src='yui/build/connection/connection.js'></script>
<script type='text/javascript' src='yui/build/animation/animation.js'></script>
<script type='text/javascript' src='yui/build/dragdrop/dragdrop.js'></script>
<script type='text/javascript' src='yui-ext/src/yutil.js'></script>
<script type='text/javascript' src='yui-ext/src/MixedCollection.js'></script>
<script type='text/javascript' src='yui-ext/src/DomHelper.js'></script>
<script type='text/javascript' src='yui-ext/src/Element.js'></script>
<script type='text/javascript' src='yui-ext/src/CompositeElement.js'></script>
<script type='text/javascript' src='yui-ext/src/KeyMap.js'></script>
<script type='text/javascript' src='yui-ext/src/Layer.js'></script>
<script type='text/javascript' src='yui-ext/src/State.js'></script>
<script type='text/javascript' src='yui-ext/src/EventManager.js'></script>
<script type='text/javascript' src='yui-ext/src/widgets/TabPanel.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/LayoutManager.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/BasicLayoutRegion.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/LayoutRegion.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/SplitLayoutRegion.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/BorderLayout.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/BorderLayoutRegions.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/ContentPanels.js'></script>
<script type='text/javascript' src='yui-ext/src/layout/LayoutStateManager.js'></script>


<link rel='stylesheet' type='text/css' href='yui-ext/resources/css/yui-ext.css' />
<script type='text/javascript'>
Main = function(){
var layout;
return{
Init:function(){
layout = new Ext.BorderLayout(document.body,{
west:{
initialSize: 200
},
center:{
tabPosition: 'top',
closeOnTab: true,
alwaysShowTabs: true,
resizeTabs: true
}
});
layout.beginUpdate();
layout.add('west', new Ext.ContentPanel('buttonBoxId',{autoCreate:true}));
layout.endUpdate();
var box=getEl('buttonBoxId');
var but=box.createChild({
tag:'input',
type:'button',
value:'Create Test Tab Panel'
})
but.on('click', this.Test, this);
},
Test:function(){
//debugger;
var e = getEl('testId');
if(e){
alert('The test panel is already created.\nPlease close it first.');
return;
}
layout.beginUpdate();
layout.add('center', new Ext.ContentPanel('testId',{
autoCreate:true,
title:'test',
closable:true
}));
layout.endUpdate();
}
}
}();
Ext.onReady(Main.Init, Main, true);
</script>
</head>
<body>
</body>
</html>

vtswingkid
18 Jan 2007, 12:40 PM
Here are some snap shots of the DOM. The first is before the a tab is created. The second is with the tab. The third is after the tab is closed. The third is not the same as the first.

http://www.zendurl.com/rwilliam/DOMbefore.jpg

http://www.zendurl.com/rwilliam/DOMwith.jpg

http://www.zendurl.com/rwilliam/DOMafter.jpg

vtswingkid
18 Jan 2007, 1:10 PM
Here is the example from above....

http://rwilliam.bravehost.com/test2.html

Animal
19 Jan 2007, 12:31 AM
The Ext.Element is still in the cache even though the HtmlElement has been removed.

I think this is a bug on ContentPanel.destroy.

Add the line



this.el.remove();


to ContentPanel.destroy just before the line



this.el = null;

vtswingkid
19 Jan 2007, 7:02 AM
I added the following override...



YAHOO.ext.ContentPanel.prototype.destroy = function(){
this.el.removeAllListeners();
var tempEl = document.createElement('span');
tempEl.appendChild(this.el.dom);
tempEl.innerHTML = '';
this.el.remove(); //---possible fix???
this.el = null;
};


I am still getting the same result.

Animal
19 Jan 2007, 7:13 AM
Did you step in with Firebug and see what was happening?

Post up your modified page. There's something wrong with it now, Firefox offers to open it like a downloaded attachment!

Animal
19 Jan 2007, 8:01 AM
OK, doing your debugging for you...

There's a bug in Element.remove

If the dom node is not in the document (which it won't be if the TabPanel has been removed without the preserve flag), the Element is not removed from the cache because the first line throws an Exception.

So change Element.remove to be like this:



remove : function(){
try {
this.dom.parentNode.removeChild(this.dom);
} catch (e) {} // Ignore if DOM remove fails.
delete YAHOO.ext.Element.cache[this.dom.id];
},

vtswingkid
19 Jan 2007, 9:13 AM
That does the trick for removing it from catch...
The dom still isn't being cleaned up...

YAHOO.ext.BorderLayout.add is used to add the tab...
but
YAHOO.ext.BorderLayout.remove is not used to remove the tab...

I'll experiment with it.


Ok...this is the test with animals fixes...
There is a second button that can be used to close the tab using the BorderLayout.remove...
Either way the remaining TabPanel is not cleanup if all tabs are remove...Though it doesn't really matter...regenerating the panel now works fine.

http://rwilliam.bravehost.com/test.html

Animal
19 Jan 2007, 9:20 AM
Well the TabPanel is still there - it's set up when the first ContentPanel is added to a Region that is set up in the default way to create tabs from ContentPanels.

The "testId" div, and the associated "testId" Element are gone though, so you should be able to recreate a new ContentPanel of the same name and add it again.

Anyway - home time...

jack.slocum
20 Jan 2007, 5:58 AM
I've added the changes. The only thing I did differently was instead of a try catch I did an if:


if(this.dom.parentNode){
this.dom.parentNode.removeChild(this.dom);
}

Will that work ok?

Animal
20 Jan 2007, 6:19 AM
Yeah, that'll work. It's probably a bit more expensive to set up a try/catch arrangement anyway...

jack.slocum
20 Jan 2007, 6:23 AM
The try/catch itself isn't too bad, but throwing and catching an exception is expensive.