Recently used the cascade methods of data.Node and discovered some odd behaviour with passing additional arguments. If additional arguments are passed, they 'call'ed rather than 'apply'ed, making for a confusing debug session. The arguments you specify are passed as an array of arguments rather than what might be expected elsewhere within the framework (fn.apply(scope,arguments)):

Code:

Ext.override(Ext.data.Node,{
/**
* Bubbles up the tree from this node, calling the specified function with each node. The scope (<i>this</i>) of
* function call will be the scope provided or the current node. The arguments to the function
* will be the args provided or the current node. If the function returns false at any point,
* the bubble is stopped.
* @param {Function} fn The function to call
* @param {Object} scope (optional) The scope of the function (defaults to current node)
* @param {Array} args (optional) The args to call the function with (default to passing the current node)
*/
bubble : function(fn, scope, args){
var p = this;
while(p){
// if(fn.call(scope || p, args || p) === false){ if(fn.apply(scope || p, args || [p]) === false){
break;
}
p = p.parentNode;
}
},
/**
* Cascades down the tree from this node, calling the specified function with each node. The scope (<i>this</i>) of
* function call will be the scope provided or the current node. The arguments to the function
* will be the args provided or the current node. If the function returns false at any point,
* the cascade is stopped on that branch.
* @param {Function} fn The function to call
* @param {Object} scope (optional) The scope of the function (defaults to current node)
* @param {Array} args (optional) The args to call the function with (default to passing the current node)
*/
cascade : function(fn, scope, args){
//if(fn.call(scope || this, args || this) !== false){if(fn.apply(scope || this, args || [this]) !== false){
var cs = this.childNodes;
for(var i = 0, len = cs.length; i < len; i++) {
cs[i].cascade(fn, scope, args);
}
}
},
/**
* Interates the child nodes of this node, calling the specified function with each node. The scope (<i>this</i>) of
* function call will be the scope provided or the current node. The arguments to the function
* will be the args provided or the current node. If the function returns false at any point,
* the iteration stops.
* @param {Function} fn The function to call
* @param {Object} scope (optional) The scope of the function (defaults to current node)
* @param {Array} args (optional) The args to call the function with (default to passing the current node)
*/
eachChild : function(fn, scope, args){
var cs = this.childNodes;
for(var i = 0, len = cs.length; i < len; i++) {
//if(fn.call(scope || this, args || cs[i]) === false){if(fn.apply(scope || this, args || [cs[i]]) === false){
break;
}
}
}
});