diff options
Diffstat (limited to 'lib/dojo/window.js')
-rw-r--r-- | lib/dojo/window.js | 232 |
1 files changed, 131 insertions, 101 deletions
diff --git a/lib/dojo/window.js b/lib/dojo/window.js index e6750dd70..c36eb4c23 100644 --- a/lib/dojo/window.js +++ b/lib/dojo/window.js @@ -5,109 +5,139 @@ */ -if(!dojo._hasResource["dojo.window"]){ -dojo._hasResource["dojo.window"]=true; +if(!dojo._hasResource["dojo.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojo.window"] = true; dojo.provide("dojo.window"); -dojo.window.getBox=function(){ -var _1=(dojo.doc.compatMode=="BackCompat")?dojo.body():dojo.doc.documentElement; -var _2=dojo._docScroll(); -return {w:_1.clientWidth,h:_1.clientHeight,l:_2.x,t:_2.y}; -}; -dojo.window.get=function(_3){ -if(dojo.isIE&&window!==document.parentWindow){ -_3.parentWindow.execScript("document._parentWindow = window;","Javascript"); -var _4=_3._parentWindow; -_3._parentWindow=null; -return _4; -} -return _3.parentWindow||_3.defaultView; + +dojo.window.getBox = function(){ + // summary: + // Returns the dimensions and scroll position of the viewable area of a browser window + + var scrollRoot = (dojo.doc.compatMode == 'BackCompat') ? dojo.body() : dojo.doc.documentElement; + + // get scroll position + var scroll = dojo._docScroll(); // scrollRoot.scrollTop/Left should work + return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y }; }; -dojo.window.scrollIntoView=function(_5,_6){ -try{ -_5=dojo.byId(_5); -var _7=_5.ownerDocument||dojo.doc,_8=_7.body||dojo.body(),_9=_7.documentElement||_8.parentNode,_a=dojo.isIE,_b=dojo.isWebKit; -if((!(dojo.isMoz||_a||_b||dojo.isOpera)||_5==_8||_5==_9)&&(typeof _5.scrollIntoView!="undefined")){ -_5.scrollIntoView(false); -return; -} -var _c=_7.compatMode=="BackCompat",_d=_c?_8:_9,_e=_b?_8:_d,_f=_d.clientWidth,_10=_d.clientHeight,rtl=!dojo._isBodyLtr(),_11=_6||dojo.position(_5),el=_5.parentNode,_12=function(el){ -return ((_a<=6||(_a&&_c))?false:(dojo.style(el,"position").toLowerCase()=="fixed")); + +dojo.window.get = function(doc){ + // summary: + // Get window object associated with document doc + + // In some IE versions (at least 6.0), document.parentWindow does not return a + // reference to the real window object (maybe a copy), so we must fix it as well + // We use IE specific execScript to attach the real window reference to + // document._parentWindow for later use + if(dojo.isIE && window !== document.parentWindow){ + /* + In IE 6, only the variable "window" can be used to connect events (others + may be only copies). + */ + doc.parentWindow.execScript("document._parentWindow = window;", "Javascript"); + //to prevent memory leak, unset it after use + //another possibility is to add an onUnload handler which seems overkill to me (liucougar) + var win = doc._parentWindow; + doc._parentWindow = null; + return win; // Window + } + + return doc.parentWindow || doc.defaultView; // Window }; -if(_12(_5)){ -return; -} -while(el){ -if(el==_8){ -el=_e; -} -var _13=dojo.position(el),_14=_12(el); -if(el==_e){ -_13.w=_f; -_13.h=_10; -if(_e==_9&&_a&&rtl){ -_13.x+=_e.offsetWidth-_13.w; -} -if(_13.x<0||!_a){ -_13.x=0; -} -if(_13.y<0||!_a){ -_13.y=0; -} -}else{ -var pb=dojo._getPadBorderExtents(el); -_13.w-=pb.w; -_13.h-=pb.h; -_13.x+=pb.l; -_13.y+=pb.t; -} -if(el!=_e){ -var _15=el.clientWidth,_16=_13.w-_15; -if(_15>0&&_16>0){ -_13.w=_15; -if(_a&&rtl){ -_13.x+=_16; -} -} -_15=el.clientHeight; -_16=_13.h-_15; -if(_15>0&&_16>0){ -_13.h=_15; -} -} -if(_14){ -if(_13.y<0){ -_13.h+=_13.y; -_13.y=0; -} -if(_13.x<0){ -_13.w+=_13.x; -_13.x=0; -} -if(_13.y+_13.h>_10){ -_13.h=_10-_13.y; -} -if(_13.x+_13.w>_f){ -_13.w=_f-_13.x; -} -} -var l=_11.x-_13.x,t=_11.y-Math.max(_13.y,0),r=l+_11.w-_13.w,bot=t+_11.h-_13.h; -if(r*l>0){ -var s=Math[l<0?"max":"min"](l,r); -_11.x+=el.scrollLeft; -el.scrollLeft+=(_a>=8&&!_c&&rtl)?-s:s; -_11.x-=el.scrollLeft; -} -if(bot*t>0){ -_11.y+=el.scrollTop; -el.scrollTop+=Math[t<0?"max":"min"](t,bot); -_11.y-=el.scrollTop; -} -el=(el!=_e)&&!_14&&el.parentNode; -} -} -catch(error){ -console.error("scrollIntoView: "+error); -_5.scrollIntoView(false); -} + +dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){ + // summary: + // Scroll the passed node into view, if it is not already. + + // don't rely on node.scrollIntoView working just because the function is there + + try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method + node = dojo.byId(node); + var doc = node.ownerDocument || dojo.doc, + body = doc.body || dojo.body(), + html = doc.documentElement || body.parentNode, + isIE = dojo.isIE, isWK = dojo.isWebKit; + // if an untested browser, then use the native method + if((!(dojo.isMoz || isIE || isWK || dojo.isOpera) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){ + node.scrollIntoView(false); // short-circuit to native if possible + return; + } + var backCompat = doc.compatMode == 'BackCompat', + clientAreaRoot = backCompat? body : html, + scrollRoot = isWK ? body : clientAreaRoot, + rootWidth = clientAreaRoot.clientWidth, + rootHeight = clientAreaRoot.clientHeight, + rtl = !dojo._isBodyLtr(), + nodePos = pos || dojo.position(node), + el = node.parentNode, + isFixed = function(el){ + return ((isIE <= 6 || (isIE && backCompat))? false : (dojo.style(el, 'position').toLowerCase() == "fixed")); + }; + if(isFixed(node)){ return; } // nothing to do + + while(el){ + if(el == body){ el = scrollRoot; } + var elPos = dojo.position(el), + fixedPos = isFixed(el); + + if(el == scrollRoot){ + elPos.w = rootWidth; elPos.h = rootHeight; + if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x + if(elPos.x < 0 || !isIE){ elPos.x = 0; } // IE can have values > 0 + if(elPos.y < 0 || !isIE){ elPos.y = 0; } + }else{ + var pb = dojo._getPadBorderExtents(el); + elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t; + } + + if(el != scrollRoot){ // body, html sizes already have the scrollbar removed + var clientSize = el.clientWidth, + scrollBarSize = elPos.w - clientSize; + if(clientSize > 0 && scrollBarSize > 0){ + elPos.w = clientSize; + if(isIE && rtl){ elPos.x += scrollBarSize; } + } + clientSize = el.clientHeight; + scrollBarSize = elPos.h - clientSize; + if(clientSize > 0 && scrollBarSize > 0){ + elPos.h = clientSize; + } + } + if(fixedPos){ // bounded by viewport, not parents + if(elPos.y < 0){ + elPos.h += elPos.y; elPos.y = 0; + } + if(elPos.x < 0){ + elPos.w += elPos.x; elPos.x = 0; + } + if(elPos.y + elPos.h > rootHeight){ + elPos.h = rootHeight - elPos.y; + } + if(elPos.x + elPos.w > rootWidth){ + elPos.w = rootWidth - elPos.x; + } + } + // calculate overflow in all 4 directions + var l = nodePos.x - elPos.x, // beyond left: < 0 + t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0 + r = l + nodePos.w - elPos.w, // beyond right: > 0 + bot = t + nodePos.h - elPos.h; // beyond bottom: > 0 + if(r * l > 0){ + var s = Math[l < 0? "max" : "min"](l, r); + nodePos.x += el.scrollLeft; + el.scrollLeft += (isIE >= 8 && !backCompat && rtl)? -s : s; + nodePos.x -= el.scrollLeft; + } + if(bot * t > 0){ + nodePos.y += el.scrollTop; + el.scrollTop += Math[t < 0? "max" : "min"](t, bot); + nodePos.y -= el.scrollTop; + } + el = (el != scrollRoot) && !fixedPos && el.parentNode; + } + }catch(error){ + console.error('scrollIntoView: ' + error); + node.scrollIntoView(false); + } }; + } |