// if the user passed a function returning a node, evaluate it
n=n();
}
returnn?dojo.byId(n):null;
},
_scrollIntoView:function(/*Node*/n){
// scrolls the passed node into view, scrolling all ancester frames/windows as well.
// Assumes parent iframes can be made fully visible given the current browser window size
vard=dojo,
dr=doh.robot,
p=null;
d.forEach(dr._getWindowChain(n),function(w){
d.withGlobal(w,function(){
// get the position of the node wrt its parent window
// if it is a parent frame, its padding and border extents will get added in
varp2=d.position(n,false),
b=d._getPadBorderExtents(n),
oldp=null;
// if p2 is the position of the original passed node, store the position away as p
// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
if(!p){
p=p2;
}else{
oldp=p;
p={x:p.x+p2.x+b.l,
y:p.y+p2.y+b.t,
w:p.w,
h:p.h};
}
// scroll the parent window so that the node translated into the parent window's coordinate space is in view
dojo.window.scrollIntoView(n,p);
// adjust position for the new scroll offsets
p2=d.position(n,false);
if(!oldp){
p=p2;
}else{
p={x:oldp.x+p2.x+b.l,
y:oldp.y+p2.y+b.t,
w:p.w,
h:p.h};
}
// get the parent iframe so it can be scrolled too
n=w.frameElement;
});
});
},
_position:function(/*Node*/n){
// Returns the dojo.position of the passed node wrt the passed window's viewport,
// following any parent iframes containing the node and clipping the node to each iframe.
// if p2 is the position of the original passed node, store the position away as p
// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
if(!p){
p=p2;
}else{
varview;
d.withGlobal(n.contentWindow,function(){
view=dojo.window.getBox();
});
p2.r=p2.x+view.w;
p2.b=p2.y+view.h;
p={x:M(p.x+p2.x,p2.x)+b.l,// clip left edge of node wrt the iframe
y:M(p.y+p2.y,p2.y)+b.t,// top edge
r:m(p.x+p2.x+p.w,p2.r)+b.l,// right edge (to compute width)