]> git.pond.sub.org Git - eow/blobdiff - static/dojo-release-1.1.1/dijit/_base/place.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dijit / _base / place.js
diff --git a/static/dojo-release-1.1.1/dijit/_base/place.js b/static/dojo-release-1.1.1/dijit/_base/place.js
new file mode 100644 (file)
index 0000000..3165c11
--- /dev/null
@@ -0,0 +1,213 @@
+if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dijit._base.place"] = true;
+dojo.provide("dijit._base.place");
+
+// ported from dojo.html.util
+
+dijit.getViewport = function(){
+       //      summary
+       //      Returns the dimensions and scroll position of the viewable area of a browser window
+
+       var _window = dojo.global;
+       var _document = dojo.doc;
+
+       // get viewport size
+       var w = 0, h = 0;
+       var de = _document.documentElement;
+       var dew = de.clientWidth, deh = de.clientHeight;
+       if(dojo.isMozilla){
+               // mozilla
+               // _window.innerHeight includes the height taken by the scroll bar
+               // clientHeight is ideal but has DTD issues:
+               // #4539: FF reverses the roles of body.clientHeight/Width and documentElement.clientHeight/Width based on the DTD!
+               // check DTD to see whether body or documentElement returns the viewport dimensions using this algorithm:
+               var minw, minh, maxw, maxh;
+               var dbw = _document.body.clientWidth;
+               if(dbw > dew){
+                       minw = dew;
+                       maxw = dbw;
+               }else{
+                       maxw = dew;
+                       minw = dbw;
+               }
+               var dbh = _document.body.clientHeight;
+               if(dbh > deh){
+                       minh = deh;
+                       maxh = dbh;
+               }else{
+                       maxh = deh;
+                       minh = dbh;
+               }
+               w = (maxw > _window.innerWidth) ? minw : maxw;
+               h = (maxh > _window.innerHeight) ? minh : maxh;
+       }else if(!dojo.isOpera && _window.innerWidth){
+               //in opera9, dojo.body().clientWidth should be used, instead
+               //of window.innerWidth/document.documentElement.clientWidth
+               //so we have to check whether it is opera
+               w = _window.innerWidth;
+               h = _window.innerHeight;
+       }else if(dojo.isIE && de && deh){
+               w = dew;
+               h = deh;
+       }else if(dojo.body().clientWidth){
+               // IE5, Opera
+               w = dojo.body().clientWidth;
+               h = dojo.body().clientHeight;
+       }
+
+       // get scroll position
+       var scroll = dojo._docScroll();
+
+       return { w: w, h: h, l: scroll.x, t: scroll.y };        //      object
+};
+
+dijit.placeOnScreen = function(
+       /* DomNode */   node,
+       /* Object */            pos,
+       /* Object */            corners,
+       /* boolean? */          tryOnly){
+       //      summary:
+       //              Keeps 'node' in the visible area of the screen while trying to
+       //              place closest to pos.x, pos.y. The input coordinates are
+       //              expected to be the desired document position.
+       //
+       //              Set which corner(s) you want to bind to, such as
+       //              
+       //                      placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
+       //              
+       //              The desired x/y will be treated as the topleft(TL)/topright(TR) or
+       //              BottomLeft(BL)/BottomRight(BR) corner of the node. Each corner is tested
+       //              and if a perfect match is found, it will be used. Otherwise, it goes through
+       //              all of the specified corners, and choose the most appropriate one.
+       //              
+       //              NOTE: node is assumed to be absolutely or relatively positioned.
+
+       var choices = dojo.map(corners, function(corner){ return { corner: corner, pos: pos }; });
+
+       return dijit._place(node, choices);
+}
+
+dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
+       // summary:
+       //              Given a list of spots to put node, put it at the first spot where it fits,
+       //              of if it doesn't fit anywhere then the place with the least overflow
+       // choices: Array
+       //              Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
+       //              Above example says to put the top-left corner of the node at (10,20)
+       //      layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+       //              for things like tooltip, they are displayed differently (and have different dimensions)
+       //              based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+
+       // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
+       // viewport over document
+       var view = dijit.getViewport();
+
+       // This won't work if the node is inside a <div style="position: relative">,
+       // so reattach it to dojo.doc.body.   (Otherwise, the positioning will be wrong
+       // and also it might get cutoff)
+       if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
+               dojo.body().appendChild(node);
+       }
+
+       var best = null;
+       dojo.some(choices, function(choice){
+               var corner = choice.corner;
+               var pos = choice.pos;
+
+               // configure node to be displayed in given position relative to button
+               // (need to do this in order to get an accurate size for the node, because
+               // a tooltips size changes based on position, due to triangle)
+               if(layoutNode){
+                       layoutNode(node, choice.aroundCorner, corner);
+               }
+
+               // get node's size
+               var style = node.style;
+               var oldDisplay = style.display;
+               var oldVis = style.visibility;
+               style.visibility = "hidden";
+               style.display = "";
+               var mb = dojo.marginBox(node);
+               style.display = oldDisplay;
+               style.visibility = oldVis;
+
+               // coordinates and size of node with specified corner placed at pos,
+               // and clipped by viewport
+               var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
+                       startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y -  mb.h)),
+                       endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x),
+                       endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y),
+                       width = endX - startX,
+                       height = endY - startY,
+                       overflow = (mb.w - width) + (mb.h - height);
+
+               if(best == null || overflow < best.overflow){
+                       best = {
+                               corner: corner,
+                               aroundCorner: choice.aroundCorner,
+                               x: startX,
+                               y: startY,
+                               w: width,
+                               h: height,
+                               overflow: overflow
+                       };
+               }
+               return !overflow;
+       });
+
+       node.style.left = best.x + "px";
+       node.style.top = best.y + "px";
+       if(best.overflow && layoutNode){
+               layoutNode(node, best.aroundCorner, best.corner);
+       }
+       return best;
+}
+
+dijit.placeOnScreenAroundElement = function(
+       /* DomNode */           node,
+       /* DomNode */           aroundNode,
+       /* Object */            aroundCorners,
+       /* Function */          layoutNode){
+
+       //      summary
+       //      Like placeOnScreen, except it accepts aroundNode instead of x,y
+       //      and attempts to place node around it.  Uses margin box dimensions.
+       //
+       //      aroundCorners
+       //              specify Which corner of aroundNode should be
+       //              used to place the node => which corner(s) of node to use (see the
+       //              corners parameter in dijit.placeOnScreen)
+       //              e.g. {'TL': 'BL', 'BL': 'TL'}
+       //
+       //      layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+       //              for things like tooltip, they are displayed differently (and have different dimensions)
+       //              based on their orientation relative to the parent.   This adjusts the popup based on orientation.
+
+
+       // get coordinates of aroundNode
+       aroundNode = dojo.byId(aroundNode);
+       var oldDisplay = aroundNode.style.display;
+       aroundNode.style.display="";
+       // #3172: use the slightly tighter border box instead of marginBox
+       var aroundNodeW = aroundNode.offsetWidth; //mb.w;
+       var aroundNodeH = aroundNode.offsetHeight; //mb.h;
+       var aroundNodePos = dojo.coords(aroundNode, true);
+       aroundNode.style.display=oldDisplay;
+
+       // Generate list of possible positions for node
+       var choices = [];
+       for(var nodeCorner in aroundCorners){
+               choices.push( {
+                       aroundCorner: nodeCorner,
+                       corner: aroundCorners[nodeCorner],
+                       pos: {
+                               x: aroundNodePos.x + (nodeCorner.charAt(1) == 'L' ? 0 : aroundNodeW),
+                               y: aroundNodePos.y + (nodeCorner.charAt(0) == 'T' ? 0 : aroundNodeH)
+                       }
+               });
+       }
+
+       return dijit._place(node, choices, layoutNode);
+}
+
+}