source: [view]
if(this._displayed){
var dir = dojo.attr(dojo.body(), "dir");
if(dir){dir = dir.toLowerCase();}
var _ie7zoom;
var scrollers = this._scrollerWidths();
var target = this.target;
//Show the image and make sure the zIndex is set high.
var curStyle = dojo.style(this._centerNode, "display");
dojo.style(this._centerNode, "display", "block");
var box = dojo.position(target, true);
if(target === dojo.body() || target === dojo.doc){
// Target is the whole doc, so scale to viewport.
box = dojo.window.getBox();
box.x = box.l;
box.y = box.t;
}
var cntrIndicator = dojo.marginBox(this._centerNode);
dojo.style(this._centerNode, "display", curStyle);
//IE has a horrible zoom bug. So, we have to try and account for
//it and fix up the scaling.
if(this._ieFixNode){
_ie7zoom = -this._ieFixNode.offsetTop / 1000;
box.x = Math.floor((box.x + 0.9) / _ie7zoom);
box.y = Math.floor((box.y + 0.9) / _ie7zoom);
box.w = Math.floor((box.w + 0.9) / _ie7zoom);
box.h = Math.floor((box.h + 0.9) / _ie7zoom);
}
//Figure out how to zIndex this thing over the target.
var zi = dojo.style(target, "zIndex");
var ziUl = zi;
var ziIn = zi;
if(this.zIndex === "auto"){
if(zi != "auto"){
ziUl = parseInt(ziUl, 10) + 1;
ziIn = parseInt(ziIn, 10) + 2;
}else{
//We need to search up the chain to see if there
//are any parent zIndexs to overlay.
var cNode = target.parentNode;
var oldZi = -100000;
while(cNode && cNode !== dojo.body()){
zi = dojo.style(cNode, "zIndex");
if(!zi || zi === "auto"){
cNode = cNode.parentNode;
}else{
var newZi = parseInt(zi, 10);
if(oldZi < newZi){
oldZi = newZi;
ziUl = newZi + 1;
ziIn = newZi + 2;
}
// Keep looking until we run out, we want the highest zIndex.
cNode = cNode.parentNode;
}
}
}
}else{
ziUl = parseInt(this.zIndex, 10) + 1;
ziIn = parseInt(this.zIndex, 10) + 2;
}
dojo.style(this._centerNode, "zIndex", ziIn);
dojo.style(this._underlayNode, "zIndex", ziUl);
var pn = target.parentNode;
if(pn && pn !== dojo.body() &&
target !== dojo.body() &&
target !== dojo.doc){
// If the parent is the body tag itself,
// we can avoid all this, the body takes
// care of overflow for me. Besides, browser
// weirdness with height and width on body causes
// problems with this sort of intersect testing
// anyway.
var obh = box.h;
var obw = box.w;
var pnBox = dojo.position(pn, true);
//More IE zoom corrections. Grr.
if(this._ieFixNode){
_ie7zoom = -this._ieFixNode.offsetTop / 1000;
pnBox.x = Math.floor((pnBox.x + 0.9) / _ie7zoom);
pnBox.y = Math.floor((pnBox.y + 0.9) / _ie7zoom);
pnBox.w = Math.floor((pnBox.w + 0.9) / _ie7zoom);
pnBox.h = Math.floor((pnBox.h + 0.9) / _ie7zoom);
}
//Shift the parent width/height a bit if scollers are present.
pnBox.w -= pn.scrollHeight > pn.clientHeight &&
pn.clientHeight > 0 ? scrollers.v: 0;
pnBox.h -= pn.scrollWidth > pn.clientWidth &&
pn.clientWidth > 0 ? scrollers.h: 0;
//RTL requires a bit of massaging in some cases
//(and differently depending on browser, ugh!)
//WebKit and others still need work.
if(dir === "rtl"){
if(dojo.isOpera){
box.x += pn.scrollHeight > pn.clientHeight &&
pn.clientHeight > 0 ? scrollers.v: 0;
pnBox.x += pn.scrollHeight > pn.clientHeight &&
pn.clientHeight > 0 ? scrollers.v: 0;
}else if(dojo.isIE){
pnBox.x += pn.scrollHeight > pn.clientHeight &&
pn.clientHeight > 0 ? scrollers.v: 0;
}else if(dojo.isWebKit){
//TODO: FIX THIS!
}
}
//Figure out if we need to adjust the overlay to fit a viewable
//area, then resize it, we saved the original height/width above.
//This is causing issues on IE. Argh!
if(pnBox.w < box.w){
//Scale down the width if necessary.
box.w = box.w - pnBox.w;
}
if(pnBox.h < box.h){
//Scale down the width if necessary.
box.h = box.h - pnBox.h;
}
//Look at the y positions and see if we intersect with the
//viewport borders. Will have to do computations off it.
var vpTop = pnBox.y;
var vpBottom = pnBox.y + pnBox.h;
var bTop = box.y;
var bBottom = box.y + obh;
var vpLeft = pnBox.x;
var vpRight = pnBox.x + pnBox.w;
var bLeft = box.x;
var bRight = box.x + obw;
var delta;
//Adjust the height now
if(bBottom > vpTop &&
bTop < vpTop){
box.y = pnBox.y;
//intersecting top, need to do some shifting.
delta = vpTop - bTop;
var visHeight = obh - delta;
//If the visible height < viewport height,
//We need to shift it.
if(visHeight < pnBox.h){
box.h = visHeight;
}else{
//Deal with horizontal scrollbars if necessary.
box.h -= 2*(pn.scrollWidth > pn.clientWidth &&
pn.clientWidth > 0? scrollers.h: 0);
}
}else if(bTop < vpBottom && bBottom > vpBottom){
//Intersecting bottom, just figure out how much
//overlay to show.
box.h = vpBottom - bTop;
}else if(bBottom <= vpTop || bTop >= vpBottom){
//Outside view, hide it.
box.h = 0;
}
//adjust width
if(bRight > vpLeft && bLeft < vpLeft){
box.x = pnBox.x;
//intersecting left, need to do some shifting.
delta = vpLeft - bLeft;
var visWidth = obw - delta;
//If the visible width < viewport width,
//We need to shift it.
if(visWidth < pnBox.w){
box.w = visWidth;
}else{
//Deal with horizontal scrollbars if necessary.
box.w -= 2*(pn.scrollHeight > pn.clientHeight &&
pn.clientHeight > 0? scrollers.w:0);
}
}else if(bLeft < vpRight && bRight > vpRight){
//Intersecting right, just figure out how much
//overlay to show.
box.w = vpRight - bLeft;
}else if(bRight <= vpLeft || bLeft >= vpRight){
//Outside view, hide it.
box.w = 0;
}
}
if(box.h > 0 && box.w > 0){
//Set position and size of the blocking div overlay.
dojo.style(this._underlayNode, {
display: "block",
width: box.w + "px",
height: box.h + "px",
top: box.y + "px",
left: box.x + "px"
});
var styles = ["borderRadius", "borderTopLeftRadius",
"borderTopRightRadius","borderBottomLeftRadius",
"borderBottomRightRadius"];
this._cloneStyles(styles);
if(!dojo.isIE){
//Browser specific styles to try and clone if non-IE.
styles = ["MozBorderRadius", "MozBorderRadiusTopleft",
"MozBorderRadiusTopright","MozBorderRadiusBottomleft",
"MozBorderRadiusBottomright","WebkitBorderRadius",
"WebkitBorderTopLeftRadius", "WebkitBorderTopRightRadius",
"WebkitBorderBottomLeftRadius","WebkitBorderBottomRightRadius"
];
this._cloneStyles(styles, this);
}
var cntrIndicatorTop = (box.h/2) - (cntrIndicator.h/2);
var cntrIndicatorLeft = (box.w/2) - (cntrIndicator.w/2);
//Only show the image if there is height and width room.
if(box.h >= cntrIndicator.h && box.w >= cntrIndicator.w){
dojo.style(this._centerNode, {
top: (cntrIndicatorTop + box.y) + "px",
left: (cntrIndicatorLeft + box.x) + "px",
display: "block"
});
}else{
dojo.style(this._centerNode, "display", "none");
}
}else{
//Target has no size, display nothing on it!
dojo.style(this._underlayNode, "display", "none");
dojo.style(this._centerNode, "display", "none");
}
if(this._resizeCheck === null){
//Set an interval timer that checks the target size and scales as needed.
//Checking every 10th of a second seems to generate a fairly smooth update.
var self = this;
this._resizeCheck = setInterval(function(){self._size();}, 100);
}
}