hendricd
10-18-2008, 08:04 PM
I've done quit a bit more IE-Sieve testing (especially during ux-testing) and have found these code changes remove almost all IE orphaned references (of targeted Elements). Turns out the Element Cache holds on to quite a few references.
Ext.override( Ext.Element , {
/**
* Removes this element from the DOM and deletes it from the cache
* @param {Boolean} cleanse (optional) Perform a cleanse of immediate childNodes as well.
* @param {Boolean} deep (optional) Perform a targeted, deep cleanse of all nested childNodes as well.
*/
remove : function(cleanse, deep){
if(this.dom){
this.removeAllListeners(); //remove any Ext-defined DOM listeners
if(cleanse){ this.cleanse(true, deep); }
Ext.removeNode(this.dom);
this.dom = null; //clear ANY DOM references
delete this.dom;
}
},
/**
* Deep cleansing childNode Removal
* @param {Boolean} forceReclean (optional) By default the element
* keeps track if it has been cleansed already so
* you can call this over and over. However, if you update the element and
* need to force a reclean, you can pass true.
* @param {Boolean} deep (optional) Perform a deep cleanse of all childNodes as well.
*/
cleanse : function(forceReclean, deep){
if(this.isCleansed && forceReclean !== true){
return this;
}
var d = this.dom, n = d.firstChild, nx;
while(d && n){
nx = n.nextSibling;
if(deep){
Ext.fly(n).cleanse(forceReclean, deep);
}
Ext.removeNode(n);
n = nx;
}
this.isCleansed = true;
return this;
}
});
Ext.removeNode = Ext.isIE ? function(n){
var d = document.createElement('div'); //the original closure held a reference till reload as well.
if(n && n.tagName != 'BODY'){
var d = document.createElement('div');
d.appendChild(n);
//d.innerHTML = ''; //either works equally well
d.removeChild(n);
delete Ext.Element.cache[n.id]; //clear out any Ext reference from the Elcache
d = null; //just dump the scratch DIV reference here.
}
} :
function(n){
if(n && n.parentNode && n.tagName != 'BODY'){
n.parentNode.removeChild(n);
delete Ext.Element.cache[n.id];
}
};
Then, future class destroy methods can handle easy cleanup of high level elements and have the childNodes cleaned up as well (listeners and all) . :-?
onDestroy : function(){
this.body.remove(true, true);
},....
Ext.override( Ext.Element , {
/**
* Removes this element from the DOM and deletes it from the cache
* @param {Boolean} cleanse (optional) Perform a cleanse of immediate childNodes as well.
* @param {Boolean} deep (optional) Perform a targeted, deep cleanse of all nested childNodes as well.
*/
remove : function(cleanse, deep){
if(this.dom){
this.removeAllListeners(); //remove any Ext-defined DOM listeners
if(cleanse){ this.cleanse(true, deep); }
Ext.removeNode(this.dom);
this.dom = null; //clear ANY DOM references
delete this.dom;
}
},
/**
* Deep cleansing childNode Removal
* @param {Boolean} forceReclean (optional) By default the element
* keeps track if it has been cleansed already so
* you can call this over and over. However, if you update the element and
* need to force a reclean, you can pass true.
* @param {Boolean} deep (optional) Perform a deep cleanse of all childNodes as well.
*/
cleanse : function(forceReclean, deep){
if(this.isCleansed && forceReclean !== true){
return this;
}
var d = this.dom, n = d.firstChild, nx;
while(d && n){
nx = n.nextSibling;
if(deep){
Ext.fly(n).cleanse(forceReclean, deep);
}
Ext.removeNode(n);
n = nx;
}
this.isCleansed = true;
return this;
}
});
Ext.removeNode = Ext.isIE ? function(n){
var d = document.createElement('div'); //the original closure held a reference till reload as well.
if(n && n.tagName != 'BODY'){
var d = document.createElement('div');
d.appendChild(n);
//d.innerHTML = ''; //either works equally well
d.removeChild(n);
delete Ext.Element.cache[n.id]; //clear out any Ext reference from the Elcache
d = null; //just dump the scratch DIV reference here.
}
} :
function(n){
if(n && n.parentNode && n.tagName != 'BODY'){
n.parentNode.removeChild(n);
delete Ext.Element.cache[n.id];
}
};
Then, future class destroy methods can handle easy cleanup of high level elements and have the childNodes cleaned up as well (listeners and all) . :-?
onDestroy : function(){
this.body.remove(true, true);
},....