Plato on Github
Report Home
dojo/window.js
Maintainability
50.23
Lines of code
238
Difficulty
67.24
Estimated Errors
2.80
Function weight
By Complexity
By SLOC
define(["./_base/lang", "./sniff", "./_base/window", "./dom", "./dom-geometry", "./dom-style", "./dom-construct"], function(lang, has, baseWindow, dom, geom, style, domConstruct){ // feature detection /* not needed but included here for future reference has.add("rtl-innerVerticalScrollBar-on-left", function(win, doc){ var body = baseWindow.body(doc), scrollable = domConstruct.create('div', { style: {overflow:'scroll', overflowX:'hidden', direction:'rtl', visibility:'hidden', position:'absolute', left:'0', width:'64px', height:'64px'} }, body, "last"), center = domConstruct.create('center', { style: {overflow:'hidden', direction:'ltr'} }, scrollable, "last"), inner = domConstruct.create('div', { style: {overflow:'visible', display:'inline' } }, center, "last"); inner.innerHTML=" "; var midPoint = Math.max(inner.offsetLeft, geom.position(inner).x); var ret = midPoint >= 32; center.removeChild(inner); scrollable.removeChild(center); body.removeChild(scrollable); return ret; }); */ has.add("rtl-adjust-position-for-verticalScrollBar", function(win, doc){ var body = baseWindow.body(doc), scrollable = domConstruct.create('div', { style: {overflow:'scroll', overflowX:'visible', direction:'rtl', visibility:'hidden', position:'absolute', left:'0', top:'0', width:'64px', height:'64px'} }, body, "last"), div = domConstruct.create('div', { style: {overflow:'hidden', direction:'ltr'} }, scrollable, "last"), ret = geom.position(div).x != 0; scrollable.removeChild(div); body.removeChild(scrollable); return ret; }); has.add("position-fixed-support", function(win, doc){ // IE6, IE7+quirks, and some older mobile browsers don't support position:fixed var body = baseWindow.body(doc), outer = domConstruct.create('span', { style: {visibility:'hidden', position:'fixed', left:'1px', top:'1px'} }, body, "last"), inner = domConstruct.create('span', { style: {position:'fixed', left:'0', top:'0'} }, outer, "last"), ret = geom.position(inner).x != geom.position(outer).x; outer.removeChild(inner); body.removeChild(outer); return ret; }); // module: // dojo/window var window = { // summary: // TODOC getBox: function(/*Document?*/ doc){ // summary: // Returns the dimensions and scroll position of the viewable area of a browser window doc = doc || baseWindow.doc; var scrollRoot = (doc.compatMode == 'BackCompat') ? baseWindow.body(doc) : doc.documentElement, // get scroll position scroll = geom.docScroll(doc), // scrollRoot.scrollTop/Left should work w, h; if(has("touch")){ // if(scrollbars not supported) var uiWindow = window.get(doc); // use UI window, not dojo.global window // on mobile, scrollRoot.clientHeight <= uiWindow.innerHeight <= scrollRoot.offsetHeight, return uiWindow.innerHeight w = uiWindow.innerWidth || scrollRoot.clientWidth; // || scrollRoot.clientXXX probably never evaluated h = uiWindow.innerHeight || scrollRoot.clientHeight; }else{ // on desktops, scrollRoot.clientHeight <= scrollRoot.offsetHeight <= uiWindow.innerHeight, return scrollRoot.clientHeight // uiWindow.innerWidth/Height includes the scrollbar and cannot be used w = scrollRoot.clientWidth; h = scrollRoot.clientHeight; } return { l: scroll.x, t: scroll.y, w: w, h: h }; }, get: function(/*Document*/ doc){ // summary: // Get window object associated with document doc. // doc: // The document to get the associated window for. // 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(has("ie") && 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 }, scrollIntoView: function(/*DomNode*/ node, /*Object?*/ pos){ // summary: // Scroll the passed node into view using minimal movement, if it is not already. // Don't rely on node.scrollIntoView working just because the function is there since // it forces the node to the page's bottom or top (and left or right in IE) without consideration for the minimal movement. // WebKit's node.scrollIntoViewIfNeeded doesn't work either for inner scrollbars in right-to-left mode // and when there's a fixed position scrollable element try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method node = dom.byId(node); var doc = node.ownerDocument || baseWindow.doc, // TODO: why baseWindow.doc? Isn't node.ownerDocument always defined? body = baseWindow.body(doc), html = doc.documentElement || body.parentNode, isIE = has("ie"), isWK = has("webkit"); // if an untested browser, then use the native method if(node == body || node == html){ return; } if(!(has("mozilla") || isIE || isWK || has("opera") || has("trident")) && ("scrollIntoView" in node)){ node.scrollIntoView(false); // short-circuit to native if possible return; } var backCompat = doc.compatMode == 'BackCompat', rootWidth = Math.min(body.clientWidth || html.clientWidth, html.clientWidth || body.clientWidth), rootHeight = Math.min(body.clientHeight || html.clientHeight, html.clientHeight || body.clientHeight), scrollRoot = (isWK || backCompat) ? body : html, nodePos = pos || geom.position(node), el = node.parentNode, isFixed = function(el){ return (isIE <= 6 || (isIE == 7 && backCompat)) ? false : (has("position-fixed-support") && (style.get(el, 'position').toLowerCase() == "fixed")); }, self = this, scrollElementBy = function(el, x, y){ if(el.tagName == "BODY" || el.tagName == "HTML"){ self.get(el.ownerDocument).scrollBy(x, y); }else{ x && (el.scrollLeft += x); y && (el.scrollTop += y); } }; if(isFixed(node)){ return; } // nothing to do while(el){ if(el == body){ el = scrollRoot; } var elPos = geom.position(el), fixedPos = isFixed(el), rtl = style.getComputedStyle(el).direction.toLowerCase() == "rtl"; if(el == scrollRoot){ elPos.w = rootWidth; elPos.h = rootHeight; if(scrollRoot == html && (isIE || has("trident")) && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x if(elPos.x < 0 || !isIE || isIE >= 9 || has("trident")){ elPos.x = 0; } // older IE can have values > 0 if(elPos.y < 0 || !isIE || isIE >= 9 || has("trident")){ elPos.y = 0; } }else{ var pb = geom.getPadBorderExtents(el); elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t; var clientSize = el.clientWidth, scrollBarSize = elPos.w - clientSize; if(clientSize > 0 && scrollBarSize > 0){ if(rtl && has("rtl-adjust-position-for-verticalScrollBar")){ elPos.x += scrollBarSize; } elPos.w = clientSize; } 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 t = nodePos.y - elPos.y, // beyond top: < 0 r = l + nodePos.w - elPos.w, // beyond right: > 0 bot = t + nodePos.h - elPos.h; // beyond bottom: > 0 var s, old; if(r * l > 0 && (!!el.scrollLeft || el == scrollRoot || el.scrollWidth > el.offsetHeight)){ s = Math[l < 0? "max" : "min"](l, r); if(rtl && ((isIE == 8 && !backCompat) || isIE >= 9 || has("trident"))){ s = -s; } old = el.scrollLeft; scrollElementBy(el, s, 0); s = el.scrollLeft - old; nodePos.x -= s; } if(bot * t > 0 && (!!el.scrollTop || el == scrollRoot || el.scrollHeight > el.offsetHeight)){ s = Math.ceil(Math[t < 0? "max" : "min"](t, bot)); old = el.scrollTop; scrollElementBy(el, 0, s); s = el.scrollTop - old; nodePos.y -= s; } el = (el != scrollRoot) && !fixedPos && el.parentNode; } }catch(error){ console.error('scrollIntoView: ' + error); node.scrollIntoView(false); } } }; has("extend-dojo") && lang.setObject("dojo.window", window); return window; });