summaryrefslogtreecommitdiff
path: root/includes/js/dijit/_base/place.js
diff options
context:
space:
mode:
Diffstat (limited to 'includes/js/dijit/_base/place.js')
-rw-r--r--includes/js/dijit/_base/place.js213
1 files changed, 213 insertions, 0 deletions
diff --git a/includes/js/dijit/_base/place.js b/includes/js/dijit/_base/place.js
new file mode 100644
index 0000000..3165c11
--- /dev/null
+++ b/includes/js/dijit/_base/place.js
@@ -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);
+}
+
+}